text:
// Type definitions for Leaflet.js 1.2
// Project: https://github.com/Leaflet/Leaflet
// Definitions by: Alejandro Sánchez <https://github.com/alejo90>
//                 Arne Schubert <https://github.com/atd-schubert>
//                 Michael Auer <https://github.com/mcauer>
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
// TypeScript Version: 2.3

export as namespace L;

import * as geojson from 'geojson';

export class Class {
    static extend(props: any): any/* how to return constructor of self extended type ? */;
    static include(props: any): any /* how to return self extended type ? */;
    static mergeOptions(props: any): any /* how to return self extended type ? */;
    static addInitHook(initHookFn: () => void): any/* how to return self extended type ? */;
}

export class Transformation {
    constructor(a: number, b: number, c: number, d: number);
    transform(point: Point, scale?: number): Point;
    untransform(point: Point, scale?: number): Point;
}

export namespace LineUtil {
    function simplify(points: Point[], tolerance: number): Point[];
    function pointToSegmentDistance(p: Point, p1: Point, p2: Point): number;
    function closestPointOnSegment(p: Point, p1: Point, p2: Point): Point;
    function isFlat(latlngs: LatLngExpression[]): boolean;
}

export namespace PolyUtil {
    function clipPolygon(points: Point[], bounds: BoundsExpression, round?: boolean): Point[];
}

export namespace DomUtil {
    /**
     * Get Element by its ID or with the given HTML-Element
     */
    function get(element: string | HTMLElement): HTMLElement | null;
    function getStyle(el: HTMLElement, styleAttrib: string): string | null;
    function create(tagName: string, className?: string, container?: HTMLElement): HTMLElement;
    function remove(el: HTMLElement): void;
    function empty(el: HTMLElement): void;
    function toFront(el: HTMLElement): void;
    function toBack(el: HTMLElement): void;
    function hasClass(el: HTMLElement, name: string): boolean;
    function addClass(el: HTMLElement, name: string): void;
    function removeClass(el: HTMLElement, name: string): void;
    function setClass(el: HTMLElement, name: string): void;
    function getClass(el: HTMLElement): string;
    function setOpacity(el: HTMLElement, opacity: number): void;
    function testProp(props: string[]): string | false;
    function setTransform(el: HTMLElement, offset: Point, scale?: number): void;
    function setPosition(el: HTMLElement, position: Point): void;
    function getPosition(el: HTMLElement): Point;
    function disableTextSelection(): void;
    function enableTextSelection(): void;
    function disableImageDrag(): void;
    function enableImageDrag(): void;
    function preventOutline(el: HTMLElement): void;
    function restoreOutline(): void;

    let TRANSFORM: string;
    let TRANSITION: string;
    let TRANSITION_END: string;
}

export interface CRS {
    latLngToPoint(latlng: LatLngExpression, zoom: number): Point;
    pointToLatLng(point: PointExpression, zoom: number): LatLng;
    project(latlng: LatLng | LatLngLiteral): Point;
    unproject(point: PointExpression): LatLng;
    scale(zoom: number): number;
    zoom(scale: number): number;
    getProjectedBounds(zoom: number): Bounds;
    distance(latlng1: LatLngExpression, latlng2: LatLngExpression): number;
    wrapLatLng(latlng: LatLng | LatLngLiteral): LatLng;

    code?: string;
    wrapLng?: [number, number];
    wrapLat?: [number, number];
    infinite: boolean;
}

export namespace CRS {
    const EPSG3395: CRS;
    const EPSG3857: CRS;
    const EPSG4326: CRS;
    const Earth: CRS;
    const Simple: CRS;
}

export interface Projection {
    project(latlng: LatLng | LatLngLiteral): Point;
    unproject(point: PointExpression): LatLng;

    bounds: Bounds;
}

export namespace Projection {
    const LonLat: Projection;
    const Mercator: Projection;
    const SphericalMercator: Projection;
}

export class LatLng {
    constructor(latitude: number, longitude: number, altitude?: number);
    equals(otherLatLng: LatLngExpression, maxMargin?: number): boolean;
    toString(): string;
    distanceTo(otherLatLng: LatLngExpression): number;
    wrap(): LatLng;
    toBounds(sizeInMeters: number): LatLngBounds;

    lat: number;
    lng: number;
    alt?: number;
}

export interface LatLngLiteral {
    lat: number;
    lng: number;
}

export type LatLngTuple = [number, number];

export type LatLngExpression = LatLng | LatLngLiteral | LatLngTuple;

export function latLng(latitude: number, longitude: number, altitude?: number): LatLng;

export function latLng(coords: LatLngTuple | [number, number, number] | LatLngLiteral | {lat: number, lng: number, alt?: number}): LatLng;

export class LatLngBounds {
    constructor(southWest: LatLngExpression, northEast: LatLngExpression);
    constructor(latlngs: LatLngBoundsLiteral);
    extend(latlngOrBounds: LatLngExpression | LatLngBoundsExpression): this;
    pad(bufferRatio: number): LatLngBounds; // does this modify the current instance or does it return a new one?
    getCenter(): LatLng;
    getSouthWest(): LatLng;
    getNorthEast(): LatLng;
    getNorthWest(): LatLng;
    getSouthEast(): LatLng;
    getWest(): number;
    getSouth(): number;
    getEast(): number;
    getNorth(): number;
    contains(otherBoundsOrLatLng: LatLngBoundsExpression | LatLngExpression): boolean;
    intersects(otherBounds: LatLngBoundsExpression): boolean;
    overlaps(otherBounds: BoundsExpression): boolean; // investigate if this is really bounds and not latlngbounds
    toBBoxString(): string;
    equals(otherBounds: LatLngBoundsExpression): boolean;
    isValid(): boolean;
}

export type LatLngBoundsLiteral = LatLngTuple[]; // Must be [LatLngTuple, LatLngTuple], cant't change because Map.setMaxBounds

export type LatLngBoundsExpression = LatLngBounds | LatLngBoundsLiteral;

export function latLngBounds(southWest: LatLngExpression, northEast: LatLngExpression): LatLngBounds;

export function latLngBounds(latlngs: LatLngExpression[]): LatLngBounds;

export type PointTuple = [number, number];

export class Point {
    constructor(x: number, y: number, round?: boolean);
    clone(): Point;
    add(otherPoint: PointExpression): Point; // non-destructive, returns a new point
    subtract(otherPoint: PointExpression): Point;
    divideBy(num: number): Point;
    multiplyBy(num: number): Point;
    scaleBy(scale: PointExpression): Point;
    unscaleBy(scale: PointExpression): Point;
    round(): Point;
    floor(): Point;
    ceil(): Point;
    distanceTo(otherPoint: PointExpression): number;
    equals(otherPoint: PointExpression): boolean;
    contains(otherPoint: PointExpression): boolean;
    toString(): string;
    x: number;
    y: number;
}

export interface Coords extends Point {
    z: number;
}

export type PointExpression = Point | PointTuple;

export function point(x: number, y: number, round?: boolean): Point;

export function point(coords: PointTuple | {x: number, y: number}): Point;

export type BoundsLiteral = [PointTuple, PointTuple];

export class Bounds {
    constructor(topLeft: PointExpression, bottomRight: PointExpression);
    constructor(points: Point[] | BoundsLiteral);
    extend(point: PointExpression): this;
    getCenter(round?: boolean): Point;
    getBottomLeft(): Point;
    getTopRight(): Point;
    getSize(): Point;
    contains(pointOrBounds: BoundsExpression | PointExpression): boolean;
    intersects(otherBounds: BoundsExpression): boolean;
    overlaps(otherBounds: BoundsExpression): boolean;

    min?: Point;
    max?: Point;
}

export type BoundsExpression = Bounds | BoundsLiteral;

export function bounds(topLeft: PointExpression, bottomRight: PointExpression): Bounds;

export function bounds(points: Point[] | BoundsLiteral): Bounds;

export type LeafletEventHandlerFn = (event: LeafletEvent) => void;

export interface LeafletEventHandlerFnMap {
    [type: string]: LeafletEventHandlerFn;
}

/**
 * A set of methods shared between event-powered classes (like Map and Marker).
 * Generally, events allow you to execute some function when something happens
 * with an object (e.g. the user clicks on the map, causing the map to fire
 * 'click' event).
 */
export abstract class Evented extends Class {
    /**
     * Adds a listener function (fn) to a particular event type of the object.
     * You can optionally specify the context of the listener (object the this
     * keyword will point to). You can also pass several space-separated types
     * (e.g. 'click dblclick').
     */
    on(type: string, fn: LeafletEventHandlerFn, context?: any): this;

    /**
     * Adds a set of type/listener pairs, e.g. {click: onClick, mousemove: onMouseMove}
     */
    on(eventMap: LeafletEventHandlerFnMap): this;

    /**
     * Removes a previously added listener function. If no function is specified,
     * it will remove all the listeners of that particular event from the object.
     * Note that if you passed a custom context to on, you must pass the same context
     * to off in order to remove the listener.
     */
     // With an eventMap there are no additional arguments allowed
    // tslint:disable-next-line:unified-signatures
    off(type: string, fn?: LeafletEventHandlerFn, context?: any): this;

    /**
     * Removes a set of type/listener pairs.
     */
     // With an eventMap there are no additional arguments allowed
    // tslint:disable-next-line:unified-signatures
    off(eventMap: LeafletEventHandlerFnMap): this;
    /**
     * Removes all listeners to all events on the object.
     */
    off(): this;

    /**
     * Fires an event of the specified type. You can optionally provide a data
     * object — the first argument of the listener function will contain its properties.
     * The event might can optionally be propagated to event parents.
     */
    fire(type: string, data?: any, propagate?: boolean): this;

    /**
     * Returns true if a particular event type has any listeners attached to it.
     */
    listens(type: string): boolean;

    /**
     * Behaves as on(...), except the listener will only get fired once and then removed.
     */
    once(type: string, fn: LeafletEventHandlerFn, context?: any): this;

    /**
     * Behaves as on(...), except the listener will only get fired once and then removed.
     */
    once(eventMap: LeafletEventHandlerFnMap): this;

    /**
     * Adds an event parent - an Evented that will receive propagated events
     */
    addEventParent(obj: Evented): this;

    /**
     * Removes an event parent, so it will stop receiving propagated events
     */
    removeEventParent(obj: Evented): this;

    /**
     * Alias for on(...)
     *
     * Adds a listener function (fn) to a particular event type of the object.
     * You can optionally specify the context of the listener (object the this
     * keyword will point to). You can also pass several space-separated types
     * (e.g. 'click dblclick').
     */
    addEventListener(type: string, fn: LeafletEventHandlerFn, context?: any): this;

    /**
     * Alias for on(...)
     *
     * Adds a set of type/listener pairs, e.g. {click: onClick, mousemove: onMouseMove}
     */
    addEventListener(eventMap: LeafletEventHandlerFnMap): this;

    /**
     * Alias for off(...)
     *
     * Removes a previously added listener function. If no function is specified,
     * it will remove all the listeners of that particular event from the object.
     * Note that if you passed a custom context to on, you must pass the same context
     * to off in order to remove the listener.
     */
    removeEventListener(type: string, fn: LeafletEventHandlerFn, context?: any): this;

    /**
     * Alias for off(...)
     *
     * Removes a set of type/listener pairs.
     */
    removeEventListener(eventMap: LeafletEventHandlerFnMap): this;

    /**
     * Alias for off()
     *
     * Removes all listeners to all events on the object.
     */
    clearAllEventListeners(): this;

    /**
     * Alias for once(...)
     *
     * Behaves as on(...), except the listener will only get fired once and then removed.
     */
    addOneTimeEventListener(type: string, fn: LeafletEventHandlerFn, context?: any): this;

    /**
     * Alias for once(...)
     *
     * Behaves as on(...), except the listener will only get fired once and then removed.
     */
    addOneTimeEventListener(eventMap: LeafletEventHandlerFnMap): this;

    /**
     * Alias for fire(...)
     *
     * Fires an event of the specified type. You can optionally provide a data
     * object — the first argument of the listener function will contain its properties.
     * The event might can optionally be propagated to event parents.
     */
    fireEvent(type: string, data?: any, propagate?: boolean): this;

    /**
     * Alias for listens(...)
     *
     * Returns true if a particular event type has any listeners attached to it.
     */
    hasEventListeners(type: string): boolean;
}

/**
 * A class for making DOM elements draggable (including touch support).
 * Used internally for map and marker dragging. Only works for elements
 * that were positioned with [`L.DomUtil.setPosition`](#domutil-setposition).
 */
export class Draggable extends Evented {
    constructor(element: HTMLElement, dragStartTarget?: HTMLElement, preventOutline?: boolean);

    enable(): void;

    disable(): void;

    finishDrag(): void;
}

export interface LayerOptions {
    pane?: string;
    attribution?: string;
}

export interface InteractiveLayerOptions extends LayerOptions {
    interactive?: boolean;
}

export class Layer extends Evented {
    constructor(options?: LayerOptions);
    addTo(map: Map|LayerGroup): this;
    remove(): this;
    removeFrom(map: Map): this;
    getPane(name?: string): HTMLElement | undefined;

    // Popup methods
    bindPopup(content: ((layer: Layer) => Content) | Content | Popup, options?: PopupOptions): this;
    unbindPopup(): this;
    openPopup(latlng?: LatLngExpression): this;
    closePopup(): this;
    togglePopup(): this;
    isPopupOpen(): boolean;
    setPopupContent(content: Content | Popup): this;
    getPopup(): Popup | undefined;

    // Tooltip methods
    bindTooltip(content: ((layer: Layer) => Content) | Tooltip | Content, options?: TooltipOptions): this;
    unbindTooltip(): this;
    openTooltip(latlng?: LatLngExpression): this;
    closeTooltip(): this;
    toggleTooltip(): this;
    isTooltipOpen(): boolean;
    setTooltipContent(content: Content | Tooltip): this;
    getTooltip(): Tooltip | undefined;

    // Extension methods
    onAdd(map: Map): this;
    onRemove(map: Map): this;
    getEvents?(): {[name: string]: (event: LeafletEvent) => void};
    getAttribution?(): string | null;
    beforeAdd?(map: Map): this;

    protected _map: Map;
}

export interface GridLayerOptions {
    tileSize?: number | Point;
    opacity?: number;
    updateWhenIdle?: boolean;
    updateWhenZooming?: boolean;
    updateInterval?: number;
    attribution?: string;
    zIndex?: number;
    bounds?: LatLngBoundsExpression;
    minZoom?: number;
    maxZoom?: number;
    noWrap?: boolean;
    pane?: string;
    className?: string;
    keepBuffer?: number;
}

export type DoneCallback = (error?: Error, tile?: HTMLElement) => void;

export interface InternalTiles {
    [key: string]: {
        active?: boolean,
        coords: Coords,
        current: boolean,
        el: HTMLElement,
        loaded?: Date,
        retain?: boolean,
    };
}

export class GridLayer extends Layer {
    constructor(options?: GridLayerOptions);
    bringToFront(): this;
    bringToBack(): this;
    getContainer(): HTMLElement | null;
    setOpacity(opacity: number): this;
    setZIndex(zIndex: number): this;
    isLoading(): boolean;
    redraw(): this;
    getTileSize(): Point;

    protected createTile(coords: Coords, done: DoneCallback): HTMLElement;
    protected _tileCoordsToKey(coords: Coords): string;

    protected _tiles: InternalTiles;
    protected _tileZoom?: number;
}

export function gridLayer(options?: GridLayerOptions): GridLayer;

export interface TileLayerOptions extends GridLayerOptions {
    minZoom?: number;
    maxZoom?: number;
    maxNativeZoom?: number;
    minNativeZoom?: number;
    subdomains?: string | string[];
    errorTileUrl?: string;
    zoomOffset?: number;
    tms?: boolean;
    zoomReverse?: boolean;
    detectRetina?: boolean;
    crossOrigin?: boolean;
    [name: string]: any;
}

export class TileLayer extends GridLayer {
    constructor(urlTemplate: string, options?: TileLayerOptions);
    setUrl(url: string, noRedraw?: boolean): this;

    protected _abortLoading(): void;
    protected _getZoomForUrl(): number;

    options: TileLayerOptions;
}

export function tileLayer(urlTemplate: string, options?: TileLayerOptions): TileLayer;

export namespace TileLayer {
    class WMS extends TileLayer {
        constructor(baseUrl: string, options: WMSOptions);
        setParams(params: WMSParams, noRedraw?: boolean): this;

        wmsParams: WMSParams;
        options: WMSOptions;
    }
}

export interface WMSOptions extends TileLayerOptions {
    layers?: string;
    styles?: string;
    format?: string;
    transparent?: boolean;
    version?: string;
    crs?: CRS;
    uppercase?: boolean;
}

export interface WMSParams {
    format?: string;
    layers: string;
    request?: string;
    service?: string;
    styles?: string;
    version?: string;
    transparent?: boolean;
    width?: number;
    height?: number;
}

export namespace tileLayer {
    function wms(baseUrl: string, options?: WMSOptions): TileLayer.WMS;
}

export interface ImageOverlayOptions extends LayerOptions {
    opacity?: number;
    alt?: string;
    interactive?: boolean;
    attribution?: string;
    crossOrigin?: boolean;
}

export class ImageOverlay extends Layer {
    constructor(imageUrl: string, bounds: LatLngBoundsExpression, options?: ImageOverlayOptions);
    setOpacity(opacity: number): this;
    bringToFront(): this;
    bringToBack(): this;
    setUrl(url: string): this;

    /** Update the bounds that this ImageOverlay covers */
    setBounds(bounds: LatLngBounds): this;

    /** Get the bounds that this ImageOverlay covers */
    getBounds(): LatLngBounds;

    /** Get the img element that represents the ImageOverlay on the map */
    getElement(): HTMLImageElement | undefined;

    options: ImageOverlayOptions;
}

export function imageOverlay(imageUrl: string, bounds: LatLngBoundsExpression, options?: ImageOverlayOptions): ImageOverlay;

export type LineCapShape = 'butt' | 'round' | 'square' | 'inherit';

export type LineJoinShape = 'miter' | 'round' | 'bevel' | 'inherit';

export type FillRule = 'nonzero' | 'evenodd' | 'inherit';

export interface PathOptions extends InteractiveLayerOptions {
    stroke?: boolean;
    color?: string;
    weight?: number;
    opacity?: number;
    lineCap?: LineCapShape;
    lineJoin?: LineJoinShape;
    dashArray?: string;
    dashOffset?: string;
    fill?: boolean;
    fillColor?: string;
    fillOpacity?: number;
    fillRule?: FillRule;
    renderer?: Renderer;
    className?: string;
}

export abstract class Path extends Layer {
    redraw(): this;
    setStyle(style: PathOptions): this;
    bringToFront(): this;
    bringToBack(): this;
    getElement(): Element | undefined;

    options: PathOptions;
}

export interface PolylineOptions extends PathOptions {
    smoothFactor?: number;
    noClip?: boolean;
}

export class Polyline<T extends geojson.GeometryObject = geojson.LineString | geojson.MultiLineString, P = any> extends Path {
    constructor(latlngs: LatLngExpression[], options?: PolylineOptions);
    toGeoJSON(): geojson.Feature<T, P>;
    getLatLngs(): LatLng[] | LatLng[][] | LatLng[][][];
    setLatLngs(latlngs: LatLngExpression[]): this;
    isEmpty(): boolean;
    getCenter(): LatLng;
    getBounds(): LatLngBounds;
    addLatLng(latlng: LatLngExpression | LatLngExpression[]): this;

    feature?: geojson.Feature<T, P>;
    options: PolylineOptions;
}

export function polyline(latlngs: LatLngExpression[], options?: PolylineOptions): Polyline;

export class Polygon<P = any> extends Polyline<geojson.Polygon | geojson.MultiPolygon, P> {
    constructor(latlngs: LatLngExpression[] | LatLngExpression[][], options?: PolylineOptions);
}

export function polygon(latlngs: LatLngExpression[] | LatLngExpression[][], options?: PolylineOptions): Polygon;

export class Rectangle<P = any> extends Polygon<P> {
    constructor(latLngBounds: LatLngBoundsExpression, options?: PolylineOptions);
    setBounds(latLngBounds: LatLngBoundsExpression): this;
}

export function rectangle(latLngBounds: LatLngBoundsExpression, options?: PolylineOptions): Rectangle;

export interface CircleMarkerOptions extends PathOptions {
    radius?: number;
}

export class CircleMarker<P = any> extends Path {
    constructor(latlng: LatLngExpression, options?: CircleMarkerOptions);
    toGeoJSON(): geojson.Feature<geojson.Point, P>;
    setLatLng(latLng: LatLngExpression): this;
    getLatLng(): LatLng;
    setRadius(radius: number): this;
    getRadius(): number;

    options: CircleMarkerOptions;
    feature?: geojson.Feature<geojson.Point, P>;
}

export function circleMarker(latlng: LatLngExpression, options?: CircleMarkerOptions): CircleMarker;

export class Circle<P = any> extends CircleMarker<P> {
    constructor(latlng: LatLngExpression, options?: CircleMarkerOptions);
    constructor(latlng: LatLngExpression, radius: number, options?: CircleMarkerOptions); // deprecated!
    getBounds(): LatLngBounds;
}

export function circle(latlng: LatLngExpression, options?: CircleMarkerOptions): Circle;
export function circle(latlng: LatLngExpression, radius: number, options?: CircleMarkerOptions): Circle; // deprecated!

export interface RendererOptions extends LayerOptions {
    padding?: number;
}

export class Renderer extends Layer {
    constructor(options?: RendererOptions);

    options: RendererOptions;
}

export class SVG extends Renderer {}

export namespace SVG {
    function create(name: string): SVGElement;

    function pointsToPath(rings: PointExpression[], close: boolean): string;
}

export function svg(options?: RendererOptions): SVG;

export class Canvas extends Renderer {}

export function canvas(options?: RendererOptions): Canvas;

/**
 * Used to group several layers and handle them as one.
 * If you add it to the map, any layers added or removed from the group will be
 * added/removed on the map as well. Extends Layer.
 */
export class LayerGroup<P = any> extends Layer {
    constructor(layers?: Layer[], options?: LayerOptions);

    /**
     * Returns a GeoJSON representation of the layer group (as a GeoJSON GeometryCollection, GeoJSONFeatureCollection or Multipoint).
     */
    toGeoJSON(): geojson.FeatureCollection<geojson.GeometryObject, P> | geojson.Feature<geojson.MultiPoint, P> | geojson.GeometryCollection;

    /**
     * Adds the given layer to the group.
     */
    addLayer(layer: Layer): this;

    /**
     * Removes the layer with the given internal ID or the given layer from the group.
     */
    removeLayer(layer: number | Layer): this;

    /**
     * Returns true if the given layer is currently added to the group.
     */
    hasLayer(layer: Layer): boolean;

    /**
     * Removes all the layers from the group.
     */
    clearLayers(): this;

    /**
     * Calls methodName on every layer contained in this group, passing any additional parameters.
     * Has no effect if the layers contained do not implement methodName.
     */
    invoke(methodName: string, ...params: any[]): this;

    /**
     * Iterates over the layers of the group,
     * optionally specifying context of the iterator function.
     */
    eachLayer(fn: (layer: Layer) => void, context?: any): this;

    /**
     * Returns the layer with the given internal ID.
     */
    getLayer(id: number): Layer | undefined;

    /**
     * Returns an array of all the layers added to the group.
     */
    getLayers(): Layer[];

    /**
     * Calls setZIndex on every layer contained in this group, passing the z-index.
     */
    setZIndex(zIndex: number): this;

    /**
     * Returns the internal ID for a layer
     */
    getLayerId(layer: Layer): number;

    feature?: geojson.FeatureCollection<geojson.GeometryObject, P> | geojson.Feature<geojson.MultiPoint, P> | geojson.GeometryCollection;
}

/**
 * Create a layer group, optionally given an initial set of layers and an `options` object.
 */
export function layerGroup(layers?: Layer[], options?: LayerOptions): LayerGroup;

/**
 * Extended LayerGroup that also has mouse events (propagated from
 * members of the group) and a shared bindPopup method.
 */
export class FeatureGroup<P = any> extends LayerGroup<P> {
    /**
     * Sets the given path options to each layer of the group that has a setStyle method.
     */
    setStyle(style: PathOptions): this;

    /**
     * Brings the layer group to the top of all other layers
     */
    bringToFront(): this;

    /**
     * Brings the layer group to the top [sic] of all other layers
     */
    bringToBack(): this;

    /**
     * Returns the LatLngBounds of the Feature Group (created from
     * bounds and coordinates of its children).
     */
    getBounds(): LatLngBounds;
}

/**
 * Create a feature group, optionally given an initial set of layers.
 */
export function featureGroup(layers?: Layer[]): FeatureGroup;

export type StyleFunction<P = any> = (feature?: geojson.Feature<geojson.GeometryObject, P>) => PathOptions;

export interface GeoJSONOptions<P = any> extends LayerOptions {
    /**
     * A Function defining how GeoJSON points spawn Leaflet layers.
     * It is internally called when data is added, passing the GeoJSON point
     * feature and its LatLng.
     *
     * The default is to spawn a default Marker:
     *
     * ```
     * function(geoJsonPoint, latlng) {
     *     return L.marker(latlng);
     * }
     * ```
     */
    pointToLayer?(geoJsonPoint: geojson.Feature<geojson.Point, P>, latlng: LatLng): Layer; // should import GeoJSON typings

    /**
     * A Function defining the Path options for styling GeoJSON lines and polygons,
     * called internally when data is added.
     *
     * The default value is to not override any defaults:
     *
     * ```
     * function (geoJsonFeature) {
     *     return {}
     * }
     * ```
     */
    style?: StyleFunction<P>;

    /**
     * A Function that will be called once for each created Feature, after it
     * has been created and styled. Useful for attaching events and popups to features.
     *
     * The default is to do nothing with the newly created layers:
     *
     * ```
     * function (feature, layer) {}
     * ```
     */
    onEachFeature?(feature: geojson.Feature<geojson.GeometryObject, P>, layer: Layer): void;

    /**
     * A Function that will be used to decide whether to show a feature or not.
     *
     * The default is to show all features:
     *
     * ```
     * function (geoJsonFeature) {
     *     return true;
     * }
     * ```
     */
    filter?(geoJsonFeature: geojson.Feature<geojson.GeometryObject, P>): boolean;

    /**
     * A Function that will be used for converting GeoJSON coordinates to LatLngs.
     * The default is the coordsToLatLng static method.
     */
    coordsToLatLng?(coords: [number, number] | [number, number, number]): LatLng; // check if LatLng has an altitude property
}

/**
 * Represents a GeoJSON object or an array of GeoJSON objects.
 * Allows you to parse GeoJSON data and display it on the map. Extends FeatureGroup.
 */
export class GeoJSON<P = any> extends FeatureGroup<P> {
    /**
     * Creates a Layer from a given GeoJSON feature. Can use a custom pointToLayer
     * and/or coordsToLatLng functions if provided as options.
     */
    static geometryToLayer<P = any>(featureData: geojson.Feature<geojson.GeometryObject, P>, options?: GeoJSONOptions<P>): Layer;

    /**
     * Creates a LatLng object from an array of 2 numbers (longitude, latitude) or
     * 3 numbers (longitude, latitude, altitude) used in GeoJSON for points.
     */
    static coordsToLatLng(coords: [number, number] | [number, number, number]): LatLng;

    /**
     * Creates a multidimensional array of LatLngs from a GeoJSON coordinates array.
     * levelsDeep specifies the nesting level (0 is for an array of points, 1 for an array of
     * arrays of points, etc., 0 by default).
     * Can use a custom coordsToLatLng function.
     */
    static coordsToLatLngs(
        coords: any[],
        levelsDeep?: number,
        coordsToLatLng?: (coords: [number, number] | [number, number, number]) => LatLng): any[]; // Using any[] to avoid artificially limiting valid calls

    /**
     * Reverse of coordsToLatLng
     */
    static latLngToCoords(latlng: LatLng): [number, number] | [number, number, number];

    /**
     * Reverse of coordsToLatLngs closed determines whether the first point should be
     * appended to the end of the array to close the feature, only used when levelsDeep is 0.
     * False by default.
     */
    static latLngsToCoords(latlngs: any[], levelsDeep?: number, closed?: boolean): any[];  // Using any[] to avoid artificially limiting valid calls

    /**
     * Normalize GeoJSON geometries/features into GeoJSON features.
     */
    static asFeature<P = any>(geojson: geojson.Feature<geojson.GeometryObject, P> | geojson.GeometryObject): geojson.Feature<geojson.GeometryObject, P>;

    constructor(geojson?: geojson.GeoJsonObject, options?: GeoJSONOptions<P>)
    /**
     * Adds a GeoJSON object to the layer.
     */
    addData(data: geojson.GeoJsonObject): Layer;

    /**
     * Resets the given vector layer's style to the original GeoJSON style,
     * useful for resetting style after hover events.
     */
    resetStyle(layer: Layer): Layer;

    options: GeoJSONOptions<P>;
}

/**
 * Creates a GeoJSON layer.
 *
 * Optionally accepts an object in GeoJSON format to display on the
 * map (you can alternatively add it later with addData method) and
 * an options object.
 */
export function geoJSON<P = any>(geojson?: geojson.GeoJsonObject, options?: GeoJSONOptions<P>): GeoJSON<P>;

export type Zoom = boolean | 'center';

export interface MapOptions {
    preferCanvas?: boolean;

    // Control options
    attributionControl?: boolean;
    zoomControl?: boolean;

    // Interaction options
    closePopupOnClick?: boolean;
    zoomSnap?: number;
    zoomDelta?: number;
    trackResize?: boolean;
    boxZoom?: boolean;
    doubleClickZoom?: Zoom;
    dragging?: boolean;

    // Map state options
    crs?: CRS;
    center?: LatLngExpression;
    zoom?: number;
    minZoom?: number;
    maxZoom?: number;
    layers?: Layer[];
    maxBounds?: LatLngBoundsExpression;
    renderer?: Renderer;

    // Animation options
    fadeAnimation?: boolean;
    markerZoomAnimation?: boolean;
    transform3DLimit?: number;
    zoomAnimation?: boolean;
    zoomAnimationThreshold?: number;

    // Panning inertia options
    inertia?: boolean;
    inertiaDeceleration?: number;
    inertiaMaxSpeed?: number;
    easeLinearity?: number;
    worldCopyJump?: boolean;
    maxBoundsViscosity?: number;

    // Keyboard navigation options
    keyboard?: boolean;
    keyboardPanDelta?: number;

    // Mousewheel options
    scrollWheelZoom?: Zoom;
    wheelDebounceTime?: number;
    wheelPxPerZoomLevel?: number;

    // Touch interaction options
    tap?: boolean;
    tapTolerance?: number;
    touchZoom?: Zoom;
    bounceAtZoomLimits?: boolean;
}

export type ControlPosition = 'topleft' | 'topright' | 'bottomleft' | 'bottomright';

export interface ControlOptions {
    position?: ControlPosition;
}

export class Control extends Class {
    constructor(options?: ControlOptions);
    getPosition(): ControlPosition;
    setPosition(position: ControlPosition): this;
    getContainer(): HTMLElement | undefined;
    addTo(map: Map): this;
    remove(): this;

    // Extension methods
    onAdd?(map: Map): HTMLElement;
    onRemove?(map: Map): void;

    options: ControlOptions;
}

export namespace Control {
    interface ZoomOptions extends ControlOptions {
        zoomInText?: string;
        zoomInTitle?: string;
        zoomOutText?: string;
        zoomOutTitle?: string;
    }

    class Zoom extends Control {
        constructor(options?: ZoomOptions);
        options: ZoomOptions;
    }

    interface AttributionOptions extends ControlOptions {
        prefix?: string | boolean;
    }

    class Attribution extends Control {
        constructor(options?: AttributionOptions);
        setPrefix(prefix: string): this;
        addAttribution(text: string): this;
        removeAttribution(text: string): this;
        options: AttributionOptions;
    }

    interface LayersOptions extends ControlOptions {
        collapsed?: boolean;
        autoZIndex?: boolean;
        hideSingleBase?: boolean;
    }

    interface LayersObject {
        [name: string]: Layer;
    }

    class Layers extends Control {
        constructor(baseLayers?: LayersObject, overlays?: LayersObject, options?: LayersOptions);
        addBaseLayer(layer: Layer, name: string): this;
        addOverlay(layer: Layer, name: string): this;
        removeLayer(layer: Layer): this;
        expand(): this;
        collapse(): this;
        options: LayersOptions;
    }

    interface ScaleOptions extends ControlOptions {
        maxWidth?: number;
        metric?: boolean;
        imperial?: boolean;
        updateWhenIdle?: boolean;
    }

    class Scale extends Control {
        constructor(options?: ScaleOptions);
        options: ScaleOptions;
    }
}

export namespace control {
    function zoom(options?: Control.ZoomOptions): Control.Zoom;

    function attribution(options?: Control.AttributionOptions): Control.Attribution;

    function layers(baseLayers?: Control.LayersObject, overlays?: Control.LayersObject, options?: Control.LayersOptions): Control.Layers;

    function scale(options?: Control.ScaleOptions): Control.Scale;
}

export interface DivOverlayOptions {
    offset?: PointExpression;
    zoomAnimation?: boolean;
    className?: string;
    pane?: string;
}

export interface PopupOptions extends DivOverlayOptions {
    maxWidth?: number;
    minWidth?: number;
    maxHeight?: number;
    autoPan?: boolean;
    autoPanPaddingTopLeft?: PointExpression;
    autoPanPaddingBottomRight?: PointExpression;
    autoPanPadding?: PointExpression;
    keepInView?: boolean;
    closeButton?: boolean;
    autoClose?: boolean;
    closeOnClick?: boolean;
}

export type Content = string | HTMLElement;

export class Popup extends Layer {
    constructor(options?: PopupOptions, source?: Layer);
    getLatLng(): LatLng | undefined;
    setLatLng(latlng: LatLngExpression): this;
    getContent(): Content | ((source: Layer) => Content) | undefined;
    setContent(htmlContent: ((source: Layer) => Content) | Content): this;
    getElement(): HTMLElement | undefined;
    update(): void;
    isOpen(): boolean;
    bringToFront(): this;
    bringToBack(): this;
    openOn(map: Map): this;

    options: PopupOptions;
}

export function popup(options?: PopupOptions, source?: Layer): Popup;

export type Direction = 'right' | 'left' | 'top' | 'bottom' | 'center' | 'auto';

export interface TooltipOptions extends DivOverlayOptions {
    pane?: string;
    offset?: PointExpression;
    direction?: Direction;
    permanent?: boolean;
    sticky?: boolean;
    interactive?: boolean;
    opacity?: number;
}

export class Tooltip extends Layer {
    constructor(options?: TooltipOptions, source?: Layer);
    setOpacity(val: number): void;
    getLatLng(): LatLng | undefined;
    setLatLng(latlng: LatLngExpression): this;
    getContent(): Content | undefined;
    setContent(htmlContent: ((source: Layer) => Content) | Content): this;
    getElement(): HTMLElement | undefined;
    update(): void;
    isOpen(): boolean;
    bringToFront(): this;
    bringToBack(): this;

    options: TooltipOptions;
}

export function tooltip(options?: TooltipOptions, source?: Layer): Tooltip;

export interface ZoomOptions {
    animate?: boolean;
}

export interface PanOptions {
    animate?: boolean;
    duration?: number;
    easeLinearity?: number;
    noMoveStart?: boolean;
}

// This is not empty, it extends two interfaces into one...
export interface ZoomPanOptions extends ZoomOptions, PanOptions {}

export interface FitBoundsOptions extends ZoomOptions, PanOptions {
    paddingTopLeft?: PointExpression;
    paddingBottomRight?: PointExpression;
    padding?: PointExpression;
    maxZoom?: number;
}

export interface LocateOptions {
    watch?: boolean;
    setView?: boolean;
    maxZoom?: number;
    timeout?: number;
    maximumAge?: number;
    enableHighAccuracy?: boolean;
}

export class Handler extends Class {
    constructor(map: Map);
    enable(): this;
    disable(): this;
    enabled(): boolean;

    // Extension methods
    addHooks?(): void;
    removeHooks?(): void;
}

export interface LeafletEvent {
    type: string;
    target: any;
}

export interface LeafletMouseEvent extends LeafletEvent {
    latlng: LatLng;
    layerPoint: Point;
    containerPoint: Point;
    originalEvent: MouseEvent;
}

export interface LeafletKeyboardEvent extends LeafletEvent {
    originalEvent: KeyboardEvent;
}

export interface LocationEvent extends LeafletEvent {
    latlng: LatLng;
    bounds: LatLngBounds;
    accuracy: number;
    altitude: number;
    altitudeAccuracy: number;
    heading: number;
    speed: number;
    timestamp: number;
}

export interface ErrorEvent extends LeafletEvent {
    message: string;
    code: number;
}

export interface LayerEvent extends LeafletEvent {
    layer: Layer;
}

export interface LayersControlEvent extends LayerEvent {
    name: string;
}

export interface TileEvent extends LeafletEvent {
    tile: HTMLImageElement;
    coords: Point; // apparently not a normal point, since docs say it has z (zoom)
}

export interface TileErrorEvent extends TileEvent {
    error: Error;
}

export interface ResizeEvent extends LeafletEvent {
    oldSize: Point;
    newSize: Point;
}

export interface GeoJSONEvent extends LeafletEvent {
    layer: Layer;
    properties: any;
    geometryType: string;
    id: string;
}

export interface PopupEvent extends LeafletEvent {
    popup: Popup;
}

export interface TooltipEvent extends LeafletEvent {
    tooltip: Tooltip;
}

export interface DragEndEvent extends LeafletEvent {
    distance: number;
}

export interface ZoomAnimEvent extends LeafletEvent {
    center: LatLng;
    zoom: number;
    noUpdate: boolean;
}

export namespace DomEvent {
    type EventHandlerFn = (event: Event) => void;

    function on(el: HTMLElement, types: string, fn: EventHandlerFn, context?: any): typeof DomEvent;

    function on(el: HTMLElement, eventMap: {[eventName: string]: EventHandlerFn}, context?: any): typeof DomEvent;

    function off(el: HTMLElement, types: string, fn: EventHandlerFn, context?: any): typeof DomEvent;

    function off(el: HTMLElement, eventMap: {[eventName: string]: EventHandlerFn}, context?: any): typeof DomEvent;

    function stopPropagation(ev: Event): typeof DomEvent;

    function disableScrollPropagation(el: HTMLElement): typeof DomEvent;

    function disableClickPropagation(el: HTMLElement): typeof DomEvent;

    function preventDefault(ev: Event): typeof DomEvent;

    function stop(ev: Event): typeof DomEvent;

    function getMousePosition(ev: MouseEvent, container?: HTMLElement): Point;

    function getWheelDelta(ev: Event): number;

    function addListener(el: HTMLElement, types: string, fn: EventHandlerFn, context?: any): typeof DomEvent;

    function addListener(el: HTMLElement, eventMap: {[eventName: string]: EventHandlerFn}, context?: any): typeof DomEvent;

    function removeListener(el: HTMLElement, types: string, fn: EventHandlerFn, context?: any): typeof DomEvent;

    function removeListener(el: HTMLElement, eventMap: {[eventName: string]: EventHandlerFn}, context?: any): typeof DomEvent;
}

export interface DefaultMapPanes {
    mapPane: HTMLElement;
    tilePane: HTMLElement;
    overlayPane: HTMLElement;
    shadowPane: HTMLElement;
    markerPane: HTMLElement;
    tooltipPane: HTMLElement;
    popupPane: HTMLElement;
}

export class Map extends Evented {
    constructor(element: string | HTMLElement, options?: MapOptions);
    getRenderer(layer: Path): Renderer;

    // Methods for layers and controls
    addControl(control: Control): this;
    removeControl(control: Control): this;
    addLayer(layer: Layer): this;
    removeLayer(layer: Layer): this;
    hasLayer(layer: Layer): boolean;
    eachLayer(fn: (layer: Layer) => void, context?: any): this;
    openPopup(popup: Popup): this;
    openPopup(content: Content, latlng: LatLngExpression, options?: PopupOptions): this;
    closePopup(popup?: Popup): this;
    openTooltip(tooltip: Tooltip): this;
    openTooltip(content: Content, latlng: LatLngExpression, options?: TooltipOptions): this;
    closeTooltip(tooltip?: Tooltip): this;

    // Methods for modifying map state
    setView(center: LatLngExpression, zoom: number, options?: ZoomPanOptions): this;
    setZoom(zoom: number, options?: ZoomPanOptions): this;
    zoomIn(delta?: number, options?: ZoomOptions): this;
    zoomOut(delta?: number, options?: ZoomOptions): this;
    setZoomAround(position: Point | LatLngExpression, zoom: number, options?: ZoomOptions): this;
    fitBounds(bounds: LatLngBoundsExpression, options?: FitBoundsOptions): this;
    fitWorld(options?: FitBoundsOptions): this;
    panTo(latlng: LatLngExpression, options?: PanOptions): this;
    panBy(offset: PointExpression): this;
    setMaxBounds(bounds: LatLngBoundsExpression): this;
    setMinZoom(zoom: number): this;
    setMaxZoom(zoom: number): this;
    panInsideBounds(bounds: LatLngBoundsExpression, options?: PanOptions): this;
    /**
     * Boolean for animate or advanced ZoomPanOptions
     */
    invalidateSize(options?: boolean | ZoomPanOptions): this;
    stop(): this;
    flyTo(latlng: LatLngExpression, zoom?: number, options?: ZoomPanOptions): this;
    flyToBounds(bounds: LatLngBoundsExpression, options?: FitBoundsOptions): this;

    // Other methods
    addHandler(name: string, HandlerClass: typeof Handler): this; // Alternatively, HandlerClass: new(map: Map) => Handler
    remove(): this;
    createPane(name: string, container?: HTMLElement): HTMLElement;
    /**
     * Name of the pane or the pane as HTML-Element
     */
    getPane(pane: string | HTMLElement): HTMLElement | undefined;
    getPanes(): {[name: string]: HTMLElement} & DefaultMapPanes;
    getContainer(): HTMLElement;
    whenReady(fn: () => void, context?: any): this;

    // Methods for getting map state
    getCenter(): LatLng;
    getZoom(): number;
    getBounds(): LatLngBounds;
    getMinZoom(): number;
    getMaxZoom(): number;
    getBoundsZoom(bounds: LatLngBoundsExpression, inside?: boolean): number;
    getSize(): Point;
    getPixelBounds(): Bounds;
    getPixelOrigin(): Point;
    getPixelWorldBounds(zoom?: number): Bounds;

    // Conversion methods
    getZoomScale(toZoom: number, fromZoom: number): number;
    getScaleZoom(scale: number, fromZoom: number): number;
    project(latlng: LatLngExpression, zoom: number): Point;
    unproject(point: PointExpression, zoom: number): LatLng;
    layerPointToLatLng(point: PointExpression): LatLng;
    latLngToLayerPoint(latlng: LatLngExpression): Point;
    wrapLatLng(latlng: LatLngExpression): LatLng;
    wrapLatLngBounds(bounds: LatLngBounds): LatLngBounds;
    distance(latlng1: LatLngExpression, latlng2: LatLngExpression): number;
    containerPointToLayerPoint(point: PointExpression): Point;
    containerPointToLatLng(point: PointExpression): LatLng;
    layerPointToContainerPoint(point: PointExpression): Point;
    latLngToContainerPoint(latlng: LatLngExpression): Point;
    mouseEventToContainerPoint(ev: MouseEvent): Point;
    mouseEventToLayerPoint(ev: MouseEvent): Point;
    mouseEventToLatLng(ev: MouseEvent): LatLng;

    // Geolocation methods
    locate(options?: LocateOptions): this;
    stopLocate(): this;

    // Properties
    boxZoom: Handler;
    doubleClickZoom: Handler;
    dragging: Handler;
    keyboard: Handler;
    scrollWheelZoom: Handler;
    tap?: Handler;
    touchZoom: Handler;

    options: MapOptions;
}

/**
 * ID of a HTML-Element as string or the HTML-ELement itself
 */
export function map(element: string | HTMLElement, options?: MapOptions): Map;

export interface BaseIconOptions extends LayerOptions {
    iconUrl?: string;
    iconRetinaUrl?: string;
    iconSize?: PointExpression;
    iconAnchor?: PointExpression;
    popupAnchor?: PointExpression;
    tooltipAnchor?: PointExpression;
    shadowUrl?: string;
    shadowRetinaUrl?: string;
    shadowSize?: PointExpression;
    shadowAnchor?: PointExpression;
    className?: string;
}

export interface IconOptions extends BaseIconOptions {
    iconUrl: string;
}

export class Icon<T extends BaseIconOptions = IconOptions> extends Layer {
    constructor(options: T);
    createIcon(oldIcon?: HTMLElement): HTMLElement;
    createShadow(oldIcon?: HTMLElement): HTMLElement;

    options: T;
}

export namespace Icon {
    interface DefaultIconOptions extends BaseIconOptions {
        imagePath?: string;
    }

    class Default extends Icon<DefaultIconOptions> {
        static imagePath?: string;
        constructor(options?: DefaultIconOptions);
    }
}

export function icon(options: IconOptions): Icon;

export interface DivIconOptions extends BaseIconOptions {
    html?: string | false;
    bgPos?: PointExpression;
    iconSize?: PointExpression;
    iconAnchor?: PointExpression;
    popupAnchor?: PointExpression;
    className?: string;
}

export class DivIcon extends Icon<DivIconOptions> {
    constructor(options?: DivIconOptions);
}

export function divIcon(options?: DivIconOptions): DivIcon;

export interface MarkerOptions extends InteractiveLayerOptions {
    icon?: Icon | DivIcon;
    clickable?: boolean;
    draggable?: boolean;
    keyboard?: boolean;
    title?: string;
    alt?: string;
    zIndexOffset?: number;
    opacity?: number;
    riseOnHover?: boolean;
    riseOffset?: number;
}

export class Marker<P = any> extends Layer {
    constructor(latlng: LatLngExpression, options?: MarkerOptions);
    toGeoJSON(): geojson.Feature<geojson.Point, P>;
    getLatLng(): LatLng;
    setLatLng(latlng: LatLngExpression): this;
    setZIndexOffset(offset: number): this;
    setIcon(icon: Icon | DivIcon): this;
    setOpacity(opacity: number): this;
    getElement(): HTMLElement | undefined;

    // Properties
    options: MarkerOptions;
    dragging?: Handler;
    feature?: geojson.Feature<geojson.Point, P>;
}

export function marker(latlng: LatLngExpression, options?: MarkerOptions): Marker;

export namespace Browser {
    const ie: boolean;
    const ielt9: boolean;
    const edge: boolean;
    const webkit: boolean;
    const gecko: boolean;
    const android: boolean;
    const android23: boolean;
    const chrome: boolean;
    const safari: boolean;
    const win: boolean;
    const ie3d: boolean;
    const webkit3d: boolean;
    const gecko3d: boolean;
    const opera12: boolean;
    const any3d: boolean;
    const mobile: boolean;
    const mobileWebkit: boolean;
    const mobileWebkit3d: boolean;
    const mobileOpera: boolean;
    const mobileGecko: boolean;
    const touch: boolean;
    const msPointer: boolean;
    const pointer: boolean;
    const retina: boolean;
    const canvas: boolean;
    const vml: boolean;
    const svg: boolean;
}

export namespace Util {
    function extend(dest: any, src?: any): any;
    function create(proto: any, properties?: any): any;
    function bind(fn: () => void, ...obj: any[]): () => void;
    function stamp(obj: any): number;
    function throttle(fn: () => void, time: number, context: any): () => void;
    function wrapNum(num: number, range: number[], includeMax?: boolean): number;
    function falseFn(): false;
    function formatNum(num: number, digits?: number): number;
    function trim(str: string): string;
    function splitWords(str: string): string[];
    function setOptions(obj: any, options: any): any;
    function getParamString(obj: any, existingUrl?: string, uppercase?: boolean): string;
    function template(str: string, data: any): string;
    function isArray(obj: any): boolean;
    function indexOf(array: any[], el: any): number;
    function requestAnimFrame(fn: () => void, context?: any, immediate?: boolean): number;
    function cancelAnimFrame(id: number): void;

    let lastId: number;
    let emptyImageUrl: string;
}

redpajama_set_name: RedPajamaGithub


text:
using namespace std;

#if __APPLE__
/// @todo Find macro for demangled function name.
#define FCT_NAME __func__
#else
#define FCT_NAME __FUNCTION__
#endif

// Output exit message in program flow output.
#define DEBUG_EXIT(value, text) m_DEBUG[D_FLOW] << \
								"EXIT : " << text << endl; exit(value)

// Output function name in program flow output.
#define DEBUG_FCT m_DEBUG[D_FLOW] << FCT_NAME << endl;

// Assert function with assert line and messsage.
#define ASSERT(condition, message) \
	if (!(condition)) {cerr << "Assert `" #condition "` failed in " \
		<< __FILE__ << " line " << __LINE__ << ": " << message << endl; \
		assert((condition)); }

// Output a progress bar on stdout.
void CProgressBar(const double& value0_1, const string& msg);

enum CDebugOutputList
{
	D_FLOW,
	D_OUT1,
	D_OUT2
};

class CDebug
{
public:
	CDebug();
	~CDebug();

	ofstream& operator[] (const CDebugOutputList& out);
	void Show();

private:
	ofstream _outs[3];
	bool _show;
};

extern CDebug m_DEBUG;

#endif // DEF_C_DEBUG.


The League of Legends patch 9.8 came out on April 16. This balance update isn't particularly large, however, many of its nerfs and buffs are so drastic that they're almost guaranteed to alter the competitive meta. With that in mind, here's a quick list of the top changes of patch 9.8!
Cassiopeia had the mana cost on her Twin Fang [E] decreased from 40/50/60/70/80 to 40/45/50/55/60. This might not seem like such a huge deal at first glance, however, Cass's E was by the far the most spammable ability in her kit. In the past, this meant that Cassiopeia players had to be very careful about managing their resources, as—for example—using up all your mana to melt Baron would make you useless in the following teamfight. However, patch 9.8 changes give everyone's favorite snake lady way more breathing room in the late game, and that's a very scary prospect to consider.
It's certainly true that Fiora hasn't been that prominent in the top lane. This is likely to change, though, as the stun duration on Riposte [W] was increased from 1.5 seconds to 2 seconds. Moreover, the ability will now deal 20 more damage at all ranks, making it much more rewarding to successfully Riposte enemy spells. If that wasn't enough, the mana cost on Bladework [E] was set at 40 mana at all ranks, so Fiora players will be even more oppressive in prolonged trades on patch 9.8.
That's right, the cooldown on Gnar's… GNAR! [R] was reduced from 120/100/80 to 90/60/30 seconds. Now, obviously Gnar also needs to fill up his rage bar to use it, but the fact that he'll always have such a game-changing spell at his disposal is a massive buff to the prehistoric yordle. And if our read is correct, there's a good chance Gnar will be a contested pick at the upcoming MSI 2019.
Hell, it's about time! Kayle's rework turned her into a Solo Queue monster and a staple competitive pick, but it looks like Riot is finally fed up with this state of affairs. The angelic warrior received patch 9.8 nerfs to her base attack damage (down from 52 to 50), armor (down from 28 to 26), and attack speed ratio (down from 0.695 to 0.667). Moreover, Kayle's ascension is now based on Kayle's level and ultimate rank, so you will no longer get power spikes from Kleptomancy and Elixirs of Skill.
It's no secret that Shadow Assassin Kayn has been phased out by Rhaast. Well, that might no longer be the case, as Shadow Assassin Kayn will have a flat 8-second Shadow Step [E] cooldown at all ranks. This grants Kayn ridiculous amounts of mobility, which, combined with his high burst, makes him a massive threat in the jungle. The only caveat is that he still needs to get to his transformation to stand up to other junglers—and a handicap like that is always a risk in pro play.
The Nautilus buffs just keep on coming! The root duration on his passive was increased by 0.25 seconds at levels 1, 6, and 11. Moreover, the Dredge Line [Q] damage was boosted from 80/120/160/200/240 (+0.75 AP scaling) to 100/145/190/235/280 (+0.90 AP scaling). These are sizeable buffs to the League's anchorman—especially when you consider that mid lane Nautilus has already been making his presence known in the high end of Korean Solo Queue. And while more buffs aren't likely to come, we can't help wondering whether Nautilus is about to become a sleeper OP in pro play.
Ornn's Living Forge passive was buffed! With that, Forgefire Cape will grant 750 health (up from 625) and 100 armor (up from 90), Frozen Fist will provide 125 armor (up from 95), and Infernal Mask will set you up with 750 health (up from 550) and 100 magic resist (up from 90). These are considerable patch 9.8 changes to Ornn's scaling, so pro teams might consider integrating him into their drafts to get some late game insurance. That said, many games are decided by the 20-minute mark, so Ornn will still be a risky pick in competitive.
The Solo Queue terror is back! Well, sort of. Renekton received a string of minor buffs to his base health (up from 572.16 to 575), attack speed growth (up from 2.65% to 2.75%), and armor growth (up from 2.8 to 4). On top of that, Cull the Meek [Q] will now heal for 33% more against champions, which should make the crocodile more durable in trades and skirmishes.
Renekton was already in a decent spot in Solo Queue, but the real question is whether these buffs will make him viable in pro play. The answer is probably not. The stats buffs are insignificant, and while Renekton is a decent lane bully, he's not oppressive enough to make up for his lacking late game.
It looks like Riot has no clue what to do with Zed because most of his 9.4 buffs got reverted! With that, Razor Shuriken [Q] now deals 10 less damage at all ranks, and Living Shadow's [W] cooldown is back at 22/20/18/16/14. The worst thing about this is that Zed is still missing the AD-stealing passive from his ultimate, so he's even weaker than he was prior to the 9.4 changes.
The combine cost (and total cost) of the Bilgewater Cutlass was increased by 100 gold. The Blade of the Ruined King was also affected by this change, and marksman players will have to wait a bit longer before they can hit their power spikes. It's worth noting that Hextech Gunblade remains unaffected, as the combine cost on that item was reduced by 100 gold to make up for the change.
Coup de Grace no longer provides its users with 9 AD or 15 AP for 10 seconds after a champion takedown, making it a much less reliable option on AD carries and other consistent damage dealers. However, this rune will now deal 8% (up from 7%) bonus damage to champions below 40% max health, which still makes it a decent choice on burst mages and assassins.
That's it for the top changes of the League of Legends patch 9.8! You can check the complete patch notes here, and we'll see you on the Summoner's Rift!


A big issue that I found after my injury, was that I did not enjoy "swimming" as much. I don't love trying to do a lot of lengths in a pool, but I do very well either walking in the water or snorkeling. I use a mask and snorkel and small light swimming fins to allow myself to float without straining my body and to also get gentle motion and exercise. Relieving pain in a pool is all about gentle motion. It's not about how many laps you can swim, it's about gently moving your body in 3-D space and allowing it to go through complex ranges of motion. Motion that you may never get on land. Moving my arms and legs in this way, I slowly work out the kinks in my muscles and I often experience a significant amount of pain relief.
I got the idea for using a snorkel in the pool from scuba diving. Taking the same principles and putting them to work in a swimming pool is how I figured out to use a snorkel in a regular pool.
Not only do I use a snorkel, but I also use a thin wetsuit to keep me warm in the pool. I find that if my body is cold that my muscles will get tight and it can undermine the whole point of being in the water. With a wetsuit, it solves my problem. I can stay comfortable and warm and get lots of gentle motion without straining myself by trying to swim laps in order to stay warm.
I also wear a neoprene hood when I snorkel in the pool. While I look ridiculous, I have found that a hood is the most important thing to keep me warm and comfortable. Even a thin ½ mm wetsuit vest in combination with a neoprene hood is comfortable for me (as compared to even a 3mm wetsuit without a hood). I also find that a hood helps with keeping my head more buoyant in the water allowing my neck to stay in a more neutral position. A wetsuit and hood help to keep my spine in a much more neutral position than trying to swim without. This is important if you have any kind of spine or joint pain.
One option for water therapy is called a float tank. You float in a pod like device that is filled with water that has a tremendous amount of Epsom Salts mixed in. This allows you to actually float on your back comfortably in a relatively neutral position. I like to float and do gentle stretching. I find that the Epsom Salt (Magnesium Sulfate) relaxes my muscles and allows me to do stretching that I might find painful on land. It's also an interesting experience being in the dark and floating. It is very relaxing, and I also find it easy to meditate because I am so comfortable.
The only problem is that most float tanks use chlorine. There is at least one company that does not use chlorine called Float Lab. If you find that chlorine bothers you then look to see if there is a float tank that does not use chlorine or other toxic chemicals in your area.
I find exposure to too much chlorine actually can cause me discomfort. I try to avoid getting in a traditional swimming pool more than a few times a week and I especially limit my time in hot tubs. Hot tubs not only have a tremendous amount of chlorine, but the chlorine is also absorbed more efficiently into your body with the warm water.
Whenever I swim in a chlorinated pool, I use detox products to help get rid of the chlorine efficiently from my body. I use both homeopathy and extra nutrients that promote detoxification.
Of course, I much prefer snorkeling or scuba diving in the ocean, but I don't get to do that as often as I might like because the ocean close to me is really cold. Nevertheless, I hope that the knowledge that I have gained from snorkel and scuba diving might benefit you and offer you some relief from any pain you might experience.
You should be able to find a local supplier of scuba equipment if you live in a relatively large city. Otherwise, you can go online to find scuba suppliers. Make sure to purchase from a supplier who will allow you to return your purchase. Wetsuits are especially challenging to fit correctly and so you may need to try a few before you find what works.
Wetsuits can also be purchased at surfing/ water sports stores. You want a suit called a shorty. It has short arms and short legs. You don't want a tri-athlete suit. That does not have coverage over your arms and so your shoulders might get cold unless you swim hard like a tri-athlete.
It's important to get a thin wetsuit, 2-3 mm or less. The wetsuit needs to be made of super stretch neoprene that flexes with your motion. Recently, I had a custom wetsuit made with 2mm super-stretch neoprene. It has short arms and legs and allows me to move comfortably in the pool. Not everyone needs a custom suit, but I have found this 2 mm suit to be the perfect thickness for pool swimming. You can buy 3 mm shorty wetsuits easily online or at a scuba/water sports store, but it is hard to find 2mm suits, which is the reason I had one custom made for me. However, if you don't have access or the resources to get a custom suit then a 3mm shorty works great. It's just a little more buoyant but then it's warmer too so you need to do less exercise to stay warm!
You want to purchase a scuba mask and a simple snorkel. You want the lightest snorkel available and so don't purchase an expensive snorkel with all kinds of features. The simplest snorkel is best. Also, you want to get fins that are specifically made for swimming. I have found that scuba fins simply don't work in a pool. They are too long and cumbersome. You want the lightest and most buoyant type of swimming fins instead.
In terms of a neoprene hood, that can be difficult if you have a bad neck. Most neoprene hoods need to be pulled over your head and, even if they have a zipper, they are a tight fit. I finally had a custom hood made for me that has a zipper on the side and allows my head to easily get into the hood without any discomfort. Not everyone needs a hood but if you really want to stay warm then that is the way to go. They are easily obtained from a scuba store but be warned that you may need to modify the hood by having them add a long zipper to allow your head to get through easily. Not all scuba stores can do these types of modifications, so check before you purchase.
Custom wetsuits and hoods are available from several companies. They usually ask for your measurements and then send a suit and/or a hood to you. A better option is to see if there is anyone in your community who makes custom wetsuits. They can measure you directly and then tailor the suit to ensure the best fit. Unfortunately, it is a very specialized skill to custom make a wetsuit and so you may have to settle for a wetsuit by mail, if you really need a custom suit at all. Fortunately, there are many great wetsuits on the market to choose from and so a custom suit is generally not necessary.
Professional Formulas makes a "pool and spa" formulation. They also make a "simple chlorinated compounds" formulation. I use a few drops of these formulations before and after swimming.
I use a product from Thorne Research called Basic Detox Nutrients to help my body detoxify the chlorine.


Data-driven insights uncover audience needs, enabling you to proactively create communications initiatives.
Listening isn't about going viral or counting media hits, it's about saving brands money and improving results. Business insights from listening to your customers, industry and competitors are driving the communications and brand strategies of the future.


text:
Q: cross apply behaves weird when used with group by I don't understand why the columns correct and incorrect have different values in this case. To be honest - it seems weird this is valid SQL, because the cross apply part is not an aggregation function computed because of the group by.
with Foo as (
    select 1 as id, 'foo_1' as txt from Dual union all
    select 2, 'foo_2' from Dual),
Bar as (
    select 1 as id, 'bar_1' as txt, 1 as foo_id from Dual union all
    select 2, 'bar_2', 1 from Dual union all
    select 3, 'bar_3', 1 from Dual union all
    select 4, 'bar_4', 2 from Dual)
select
    f.id,
    listagg(b.txt, ', ') within group (order by b.id) as correct,
    incorrect
from Foo f
join Bar b on f.id = b.foo_id
cross apply (
    select
        listagg(txt, ', ') within group (order by id) as incorrect
    from Bar
    where foo_id = f.id)
group by f.id
order by f.id;

The result is:
ID  CORRECT                 INCORRECT
1   bar_1, bar_2, bar_3     bar_4
2   bar_4                   bar_4

But when I do remove the group by part, and add the distinct like the following:
with Foo as (
    select 1 as id, 'foo_1' as txt from Dual union all
    select 2, 'foo_2' from Dual),
Bar as (
    select 1 as id, 'bar_1' as txt, 1 as foo_id from Dual union all
    select 2, 'bar_2', 1 from Dual union all
    select 3, 'bar_3', 1 from Dual union all
    select 4, 'bar_4', 2 from Dual)
select distinct
    f.id,
    incorrect_now_correct
from Foo f
join Bar b on f.id = b.foo_id
cross apply (
    select
        listagg(txt, ', ') within group (order by id) as incorrect_now_correct
    from Bar
    where foo_id = f.id)
order by f.id;

I do get the following result:
ID  INCORRECT_NOW_CORRECT
1   bar_1, bar_2, bar_3
2   bar_4

Which is the result I expected from the incorrect column in the first query.
Is the group by clause treated differently when using the group by clause? Until now I only thought it's something more of a intelligent join with a subquery. Adding incorrect to the group by part makes it work like it should, without it the behavior is like described in the result of the first query. It compiles, runs and returns a value which is somewhat random.
Edit: The DB version is Oracle Database 12c Enterprise Edition 12.1.0.2.0

redpajama_set_name: RedPajamaStackExchange


5.3 earthquake hits the Komandorskiye Ostrova region.
5.1 earthquake hits the Andreanof Islands in the Aleutian Islands.
5.0 earthquake hits Seram, Indonesia.
Canada – Authorities remain on high alert for flooding across southern Quebec as waters continue to rise with military on the way to assist in evacuations. A least one death can be attributed to the flooding thus far. A woman was killed early Saturday morning in Pontiac, Que., about 50 kilometres west of Ottawa, when she drove into a massive hole created after floodwaters washed out a road.
Massive steppe wildfires, propelled by strong winds, have destroyed more than a hundred houses in the Siberian region of Trans-Baikal, leaving hundreds of local residents homeless. More than 400 people were affected by the wildfires that got out of control in the remote Russian region on the Mongolian border. At least, 111 houses in 15 villages were lost in the disaster, the governor's office said. The people evacuated in time and there have been no fatalities related to the fires.
An image from NASA Earth Observatory shows a large wildfire burning in a forest located west of Cienega de Escobar in Durango, Mexico. According to news reports, the fire is one of 95 wildfires burning in 18 Mexican states.
A series of wildfires took hold on the north side of the Isle of Bute. The fire service said a large area of moorland and forestry were affected.
Reports from the Republic of the Congo show that the chikungunya epidemic that began Jan. 7 has grown to 8,000 cases. The outbreak has affected eight departments ( Kouilou, Bouenza, Pointe Noire, Plateaux, Pool and Brazaville, Niari, Lékoumu).
With an additional 2,279 people infected with measles during the week ending April 13, the outbreak in Ukraine now stands at 39,549 including 14 fatalities, according to the Center for Public Health of the Ministry of Health of Ukraine. Fifty-four percent of cases have been reported in children.
5.7 earthquake hits Sulawesi, Indonesia.
5.3 earthquake hits Sulawesi, Indonesia.
5.2 earthquake hits the Solomon Islands.
5.0 earthquake hits south of Lombok, Indonesia.
5.0 earthquake hits Sulawesi, Indonesia.
5.0 earthquake hits Tarapaca, Chile.
5.0 earthquake hits offshore Guatemala.
5.0 earthquake hits southeast of Easter Island.
A new study finds that making rooftops a light-reflective colour can reduce heat-related deaths and cool peak daytime temperatures by more than 3 degrees Celsius during heat waves.
Cities store more heat than the surrounding countryside due to the urban heat island effect. This makes cities more susceptible to the increasing number and intensity of heat waves under global warming.
New modelling by the University of Oxford found that introducing cool roofs across a city could prevent about a quarter of heat wave-related deaths and cut the need for air conditioning.
6.1 earthquake hits the western Indian-Antarctic ridge.
5,2 earthquake hits Mindanao in the Philippines.
Two 5.0 earthquakes hit the Nicobar Islands off India.
Canada – Municipalities across southern Quebec are preparing for spring flooding that could be particularly bad, and warning residents to do the same. With heavy rain in the forecast, Laval has already declared a state of emergency, and Rigaud, about an hour from Montreal, has told residents to leave their homes ahead of possible weekend flooding, which could be worse than the 2017 deluge.
The week's hottest temperature was 113 degrees Fahrenheit (45.0 degrees Celsius) in Matam, Senegal.
The week's coldest temperature was minus 74.0 degrees Fahrenheit (minus 58.9 degrees Celsius) at Russia's Vostok base, Antarctica.
The World Health Organization (WHO) reports preliminary global data that shows reported cases rose by 300 percent in the first three months of 2019, compared to the same period in 2018. By region, Africa has recorded a 700% increase, the Americas 60%, Europe 300%, the Eastern Mediterranean 100%, with 40% increases in Southeast Asia and the Western Pacific.
In the current 2018- 2019 season (July 2018 to March 2019), a total of 75 confirmed human cases, including 17 deaths (case fatality rate = 23%), have been reported in Brazil in the states of São Paulo (62), Paraná (12), and Santa Catarina (1).


It is not the people you look at, it the Faith that is displayed in their life. The Faith they have in their Creator God, because they have come to accept Him, love Him and follow Him, no matter where it leads in their lives.
I have been privileged, to enjoy the company of many people, who are like this. One such couple are Pastors of a small church but does such a great work. Pastors in every aspect of their lives, because you can see their calling oozing from their lives.
Pastors Tony and Helen are going through a tough time at the moment, because of an illness Helen is going through, but to speak with them. to share with them, is remarkable, because of their faith and trust in the Lord.
These are not the words of a person under pressure of an illness, they are the words of a wonderful inspiring lady, who has complete faith, in Her Lord, Her Savior and Her Friend.
People of commitment and faith, we are blessed to meet them, where ever we go in life, and I am sure we all know people like this, people who live their Faith in the God they serve.
Amen… Faith raises us above our circumstances and into higher realms with God. Praying for Pastor Helen.


Discover clearance sale on Diamond Pendant - we carry wide range of Diamond Pendant. If there's an Diamond Pendant we don't currently display just write to us and we will take care of the rest.
Shop for Diamond Pendant, offering cheap Diamond Pendant listed today from at huge discounts from Ebay.
14K Yellow Gold Vintage Natural Diamond Emerald Citrine MOM HEART PENDANT 1"
Sterling Silver ~14CTW Diamond Double Heart Infinity Pendant Necklace 18"
14K White Gold ~15C Round Diamond 4 Prong Solitaire Pendant Necklace 18"
Diamond Heart Pendant Necklace 10K Gold Slider Charm Mothers Day w 14K Chain 17"
10K Yellow Gold ~12CTW Diamond Baguette Heart Shape Pendant Necklace 20"
Signed 925 Silver Real Diamond Open Hearts Love Pendant Flat Chain Necklace 17"
14KT GOLD #13 DIAMOND-CUT ROUND PENDANT 34"
10K White Yellow Gold Initial L Pendant w Diamonds 2.7 grams 1"


text:
Posted 2/7/18
Paddling to a Future Forest
For three years, Forterra staff and WCC crew members have waded across the Cedar River to restore a remote part of Ron Regis Park—but in winter when rains swell the river, a new approach to restoration was needed.
The WCC crew awaits their each of their crossings over the fast-moving Cedar River to install willow trees.
Despite being just a few miles from downtown Renton, the isolation of this area, cut off from surrounding neighborhoods by the river to the south and steep cliffs to the north and west, feels a hundred miles away.
The work here is part of a river-wide effort by Forterra, the City of Renton, Seattle Public Utilities, and King County to control invasive knotweed throughout the Cedar River, with the ultimate goal of replacing knotweed stands with healthy forests that improve water quality and provide wildlife habitat. Ron Regis Park has been one of the last major strongholds of the weed where, just a few years ago, it soared above head height and covered almost every square foot of floodplain within the park.
After three years of treatment, only tiny sprouts of knotweed were popping up last summer. This is cause for celebration, but also shows one of the major impacts of knotweed—when knotweed invades an area it out-competes other native plants and prevents understory species or young trees from growing. This part of Ron Regis Park still had its mature trees from years past, but the understory was bare, and there was no younger generation of trees growing up to replace their elders. Years of the infestation had disrupted forest processes, and it was unlikely new native plants would return before another invasive plant took over. We needed to speed up the process.
Crew and staff cross the river with willows in tow.
The season when Pacific Northwest plants most like to be planted is winter—also the season when river flows double, and wading is no longer an option. In the lead-up to the planting day, we searched for possible access points, hiking in from east, north and west, but each time our hopes were dashed when we ended at the top of a cliff or an impassable private property.
Fortunately, a friend of the program and former WCC crew lead, Cary Hofmann, also moonlights as a fishing guide. Early one December morning the WCC crew met Cary down by the river; the crew with bags of willow cuttings, and Cary with his boat. Between the fast-flowing river and the non-motorized boat with only one person to power it, the crew and Forterra staff were skeptical—but, one by one, each person boarded the boat with willows in hand and were safely paddled across the river.
Bags of willow cuttings await installation at Ron Regis Park.
Once safely on the other side, the crew fanned out with hundreds of willow cuttings each, and by the end of the day had installed almost 2,000 willows across the floodplain. Unlike knotweed, willow trees grow deep, strong roots that stabilize soils, and the trunks and branches keep their structure during winter to store and filter flood waters when needed most. These trees also grow extremely quickly. In just a few years, another huge transformation in this landscape can be expected. While the crew and staff will be back next fall to plant conifers and a more diverse mix of shrubs, these willows will fast-track the process of providing habitat, floodwater storage, and filtration to help bring back the functions of this forest.
If you'd like to join in the effort, you can attend an upcoming volunteer restoration event—though there won't be a water-crossing.
The Washington Conservation Corps Crew after a day of installing willow trees.
Jasmin Ka
Jasmin's love of river systems began as a kid in Australia, marveling at how the local creek could burst its banks and flood her backyard deep enough to drive a motor boat. She went on to study environmental management, and worked as an ecologist assessing impacts to biodiversity from large-scale projects in Australia and south-east Asia. In 2016, Jasmin moved to Seattle with her Seattleite partner. As Forterra's Senior Program Manager of Riparian Restoration, she's now combining her love of river systems with a drive to care for her new home partnering with communities, cities, counties and anyone with a connection to waterways, to restore the riparian functions of this region's rivers.
Primates, our mountains and state politics
Gene ruminates on how mountains broaden our perspective. They open our thinking when back at sea level doing our jobs. They make us better stewards of this place.
Empower Happy Hour
What are the most impactful personal and business choices you can make to fight climate change? We recently posed this question to over 50 people at Empower Happy Hour—an event we co-hosted with Green Canopy Homes designed to bring people together and spark conversation about topics that matter in our community.
Making access to healthy food a fact of life
A member of Forterra's Policy Department, Program Manager Becca Meredith, reflects on the work Forterra has done to ensure this region's access to healthy food, while bringing people together in the process.
Harnessing change to ensure a sustainable region
Forterra and Seattle SityClub hosted over 100 people to brainstorm ideas for making our region sustainable. Read more about the animated discussions here.
English ivy: what a creep!
Managing the spread of this invasive can be tricky since its forte is being able to spread over anything in its path: from the tall Douglas fir next to your house to your house itself!
Hugelkultur, have you heard of it? It's like active composting while growing plants. This approach is believed to have originated in Europe as a technique for growing plants in places with harsh climates and short growing seasons. Directly translating to "hill culture," it's not fully known whether the name came from the hill-like garden it creates, or because it originated in the hill-towns of Europe.
Earth Day 2016: Take a "paws" to be inspired
In this 46th year of Earth Day celebration, there has never been a more adorable, fluffy, and slobbery champion. The Conservation Canines team, based out of the University of Washington, spends a lot of time thinking outside of the box to solve complex issues.

redpajama_set_name: RedPajamaCommonCrawl


text:
Search the General Surgery Residency site
Chief Residents
Katherine Bakke, MD, MPH
Ricardo Bello, MD, MPH
Ryan Hendrix, MD, MSCI
Dorothy Liu, MD
Robert McLoughlin, MD, MSCI
Salim Munoz, MD, MBEE
Clark Murray, MD
PGY-4
Kaitlan Ahrens, MD
Daniel Baldor, MD, MPH
Emily Mackey, MD
David Meyer, MD, MSCI
Niti Shahi, MD
Christopher Strader, MD, MPH
Samuel Vazquez, MD
Hannah Buettner, MD
Andrew Gillooly, MD
Max Hazeltine, MD, MSCI
Edward Kim, MD, PhD
Kaye A. Lu, MD, MPH
Larissa Pamen, MD
Giulia Rizzo, MD
Catherine Beauharnais, MD
Bryce Bludevich, MD
Sebastian Chung, MD
Danielle DePalo, MD
Jonathan Durgin, MD
Gazi Rashid, MD
Erin Scott, MD
Qi Wang, MD
Olajumoke "Jummy" Akinsulire, MD
Catherine Bixby, DO
Gabriel De la Cruz Ku, MD
Alanna Hickey, MD
Timothy Jenkel, MD
Alyssa Kalustian, MD
Anupama Singh, MD
Shilpa "Chippy" Sreedharan, MD
James Stevenson, MD
Maggi Ahmed, MBChB, MSc
Zachary Ballinger, MD
Robert Benjamin, MD
Dylan Goehner, MD
Robert Guber, MD
Nicole "Nikki" Hays, MD
Sasank Kalipatnapu, MBBS
Julianna Mustafa, MD
Hayley Reddington, MD
Erica (Stern) Shey, MD
Emily Stroobant, MD
Tracy Zhang, MD
Medical School: University of Michigan Medical School, Ann Arbor, Michigan
Medical School: Universidad Central de Venezuela, Caracas, Venezuela
Medical School: University of Vermont College of Medicine, Burlington, Vermont
Medical School: Warren Alpert Medical School of Brown University, Providence, Rhode Island
Medical School: Rutgers New Jersey Medical School, Newark, New Jersey
Medical School: Universidad Anahuac Mexico, Naucalpan de Juárez, Mexico
Clark Murray, MD, MS
Medical School: University of Miami, Miami, Florida
Postgraduate Year 4
Medical School: University of Toledo College of Medicine, Toledo, Ohio
Medical School: University of Miami Miller School of Medicine, Miami, Florida
Medical School: Tufts University, Boston, Massachusetts
Medical School: University of North Carolina, Chapel Hill, North Carolina
Medical School: Sidney Kimmel Medical College, Philadelphia, Pennsylvania
Medical School: Boston University, Boston, Massachusetts
Medical School: University of Illinois Peoria Campus, Peoria, Illinois
Medical School: Tufts University School of Medicine, Boston, Massachusetts
Medical School: University of Massachusetts Medical School, Worcester, Massachusetts
Medical School: University of Massachustts Medical School, Worcester, Massachusetts
Larissa Pamen, MD, MSc
Medical School: Stony Brook University, Stony Brook, New York
Giulia Rizzo, MD, MBS
Medical School: Tufts Medical School, Boston, Massachusetts
Academic Development Time Residents
Medical School: Stony Brook University School of Medicine, Stony Brook, New York
Medical School: University of Alabama School of Medicine, Birmingham, Alabama
Medical School: Emory University, Atlanta, Georgia
Medical School: Rutgers Robert Wood Johnson Medical School, New Brunswick, New Jersey
Medical School: Rutgers Robert Wood Johnson, New Brunswick, New Jersey
Medical School: Brown University, Providence, Rhode Island
Medical School: University of New England College of Osteopathic Medicine
Medical School: Universidad Cientifica del Sur, Villa EL Salvador, Lima, Peru
Medical School: Albany Medical College, Albany, New York
Medical School: Baylor College of Medicine, Houston, Texas
Shilpa "Chippy" Sreedharan, MD, MSc
Medical School: Medical University of South Carolina, South Carolina
James Stevenson, MD, MS
Medical School: New York Medical, College, Valhalla, New York
Medical School: Sohag University, Sohag, Sohag, Egypt
Medical School: New York Medical, Mount Pleasant, New York
Medical School: University of Buffalo, Buffalo, New York
Medical School: University of South Dakota, Vermillion, South Dakota
Medical School: University of Maryland, College Park, Maryland
Medical School: Christian Medical College, Vellore, Tamil Nadu, India
Medical School: Chicago Medical, North Chicago, Illinois
Medical School: Johns Hopkins, Baltimore, Maryland
Medical School: Sidney Kimmel Medical College- Thomas Jefferson University, Philadelphia, Pennsylvania
Our residency prides itself on welcoming diversity in all of its forms. Some recent highlights are summarized in this table.
Surgery • 55 Lake Ave North, Worcester, MA 01655


text:
Wind: 0mph N
WHAT TO WATCH ON TV
Stream On: Pure cinema—'Koyaanisqatsi'
By Peter Hummers on January 19, 2023
In 1878, Scientific American published a series of pictures depicting a horse in full gallop, along with instructions to view them through the zoetrope, a simple toy that made it possible for a series of pictures to be viewed in rapid succession, creating the illusion of motion.
It wasn't long before a sequential photo projector—the zoogyroscope—was developed, in 1879, followed by the Kinetograph, a primitive motion picture camera, in 1890. These led to modern motion pictures, but throughout the years, movies' subjects have mostly incorporated concepts from the other arts, especially literature and theatre. There are very few examples of movies that use only cinematography to tell their story, a notable one being Koyaanisqatsi.
TL;DR: Koyaanisqatsi is a beautiful visual tone poem using only moving images and music to serve the message that humanity has shifted the balance of nature. "Koyaanisqatsi" is a Hopi word that means "Life out of balance."
KOYAANISQATSI
/Amazon /Streaming /Trailer /1982 /NR
"It's not for lack of love of the language that [this film has] no words. It's because, from my point of view, our language is in a state of vast humiliation. It no longer describes the world in which we live." (Director Godfrey Reggio)
This is another film I learned of from a videocassette tape borrowed from a friend. My mind reeled as its slow-motion, static, and sped-up images succeeded one another, accompanied only by minimalist instrumental and choral music. (The few words that were sung were in the Hopi language, mostly "Koyaanisqatsi" chanted over Phillip Glass' score.)
It doesn't have a traditional narrative, but the visual narrative gradually builds until its message is delivered. And even until then it's a fascinating watch.
After the MGM Lion opens the movie, on the screen appears: Francis Ford Coppola Presents, the word KOYAANISQATSI appears in red on a black background and Phillip Glass' hypnotic score begins playing: bass baritones rhythmically chant the word slowly over a repeating motif. On the screen now are dark humanoid shapes around a larger, crowned one, drawn on a red cave wall. The camera pulls back slowly and flame fills the frame, a slow-motion explosion that resolves to red debris falling from the sky: we see it is the detritus of the launch of a space rocket (Apollo 11).
The chanting continues but the music has raised an octave. The camera lingers over the launch-pad, post-liftoff, which fades to beautiful aerial shots of landscapes, deserts with mountains. The chanting has stopped and the music settles in.
The desert survey looks like drone footage; in 1975 it was shot from airplanes and a helicopter. (Cinematographer Ron Fricke almost passed out; he had never flown in a chopper before.) Director Reggio and Fricke had decided to shoot unscripted footage and edit it into an hour-long film.
Sunset on the desert. Incredible canyons and shadows. Hot springs; steam rising from otherworldly shapes and the chanting resumes. Abstract shapes from corduroy-looking desert dunes and sand blowing like spirits. "Koyaanisatsi…" Time-lapse cloud shadows rolling over red and green desert canyons and mountains with white clouds scudding overhead in blue skies.
Then swarms of bats flying out of caves; then birds. The music shifts to "Cloudscape" and the camera turns straight up to light and dark clouds, all time-lapsed. The sun can be glimpsed. What we often see from airplanes: a floor of clouds, but roiling.
Waterfalls now, and vast oceans, some in rain, sparkling like diamonds. More clouds and the music builds in intensity. High ocean waves that look like molten glass and silver, as we on the Outer Banks often see in surf photography. Musical fanfares.
Aerial films of lush green mountains pass beneath the camera to a river valley. Now the colorful geometric shapes of planted crops. What looks like a fortress stands atop a desert island in a lake in the desert—it's a natural formation.
Then, inexplicably, mountains exploding—until we see in close-up, earth-moving machinery with a red "6" painted on the front. A man climbs aboard and it is covered in black smoke and dust. Hydro-electric dams. High-tension wire towers stand looking like hieroglyphics on the edge of a desert. The music, like the images, is now heavily industrial. A nuclear test from the ground, but miles away: a red and white mushroom cloud erupts from the desert floor and climbs into a deep blue sky before it turns black and then dark blue.
At 23 minutes the music stops and people are lying on a beach. "Vessels," a female chorus, begins and the camera pulls back to reveal a nuclear generating station dominating the horizon, full-frame. Now the shots are filled with people—on highways, in cities, flowing through Grand Central Station like scurrying ants. A glass city skyscraper that seems transparent, because it's reflecting the sky. Taxiing airplanes appear in heat-distorted air and approach the camera before turning onto runways. The music grows frenzied. It appears that humans have overrun the place.
Parking lots with thousands of colorful cars … row upon row of army tanks. Fighter jets. The singers almost seem to be gasping for air. A camouflaged airplane over the painted desert. A bomb drops and explodes. An intercontinental ballistic missile shoots out of the ground. From the air we see a battleship—on the deck is written "E=mc2." Trucks and planes explode in a field. A bomber drops bombs like a seahorse sprays eggs.
Silence, and clouds fly across Manhattan. Ambient street sounds become music. Concrete, brick, and glass blot out the sky. Tenements at street level. Broken street lights. The music resumes the dominant motif of short repeated figures but with brass decorations. Broken windows. Tenements implode and collapse. Oil derricks, buildings, bridges collapse. Neighborhoods collapse and the air is filled with debris.
The second half of Koyaanisqatsi shows people at street level. Walking through New York City in slow motion, time-lapsed crowds surging through stations by the thousand. Individuals posing for the camera (they thought it was a still camera). Waitresses in Las Vegas. "The Grid" plays to shots of skyscrapers at night looking like beehives. Crowds in video game arcades, bowling alleys, malls, a "Twinkies" assembly line, crowds in food courts, all sped up to a frenzy.
After a quiet section in which aerial shots of cities are compared with circuit boards, to "Prophesies," an airy piece of music. We are flying over a spread-out city at night. A baseball stadium. People walk by the camera on city streets and look into it. An old man, apparently looking at the camera, shaves with a disposable razor. A woman taps her lighter after it fails to light her cigarette. EMT's stoop to lift a homeless man onto a stretcher. People pick through rubble after an inner-city fire. The vocalists sing what sounds like a requiem. Ghosts move across the floor of a stock exchange.
White debris again falls from the sky in a tight shot; it's the launch of another rocket, which lifts off majestically, the music climbing with it. The "Koyaanisqatsi" chant returns, the rocket flying upward into the sky—until it explodes silently, to no change in the measured music and chanting. The final eight minutes of the movie tracks the flaming debris back into the atmosphere. We come back to the opening cave with the drawings and this text appears on-screen:
"ko•yaa•nis•qat•si (from the Hopi language), n. 1. crazy life 2. life in turmoil. 3. life out of balance. 4. life disintegrating. 5. a state of life that calls for another way of living."
Director Reggio met Francis Ford Coppola through an associate at Coppola's Zoetrope Studios. Reggio arranged a private viewing after which Coppola said the film needed to be seen. Reggio added Coppola's name to the credits and Coppola helped with the distribution. I don't know and don't care what the critics thought of Koyaanisqatsi; I don't even agree with the film's premise that life is out of balance, but it needs to be seen, and happily it's streaming, free (ad-supported) on several platforms. Take an hour and a half and check it out.
(Pete Hummers is a participant in the Amazon Services LLC Associates Program, an affiliate advertising program designed to earn fees by linking Amazon.com and affiliate sites. This adds nothing to Amazon's prices.)
Click here for more Stream On: What to watch on TV columns by Pete Hummers.