text:
class LSTMKernelType(object):
    FULL = 0
    BASIC = 1

redpajama_set_name: RedPajamaGithub


text:
package com.netflix.spinnaker.clouddriver.titus.deploy.handlers;

import com.netflix.spinnaker.clouddriver.saga.flow.SagaExceptionHandler;
import com.netflix.spinnaker.clouddriver.titus.TitusException;
import io.grpc.StatusRuntimeException;
import javax.annotation.Nonnull;
import org.springframework.stereotype.Component;

@Component
public class TitusExceptionHandler implements SagaExceptionHandler {

  @Nonnull
  @Override
  public Exception handle(@Nonnull Exception exception) {
    if (exception instanceof StatusRuntimeException) {
      StatusRuntimeException statusRuntimeException = (StatusRuntimeException) exception;
      return new TitusException(statusRuntimeException, isRetryable(statusRuntimeException));
    }

    return exception;
  }

  private boolean isRetryable(StatusRuntimeException statusRuntimeException) {
    switch (statusRuntimeException.getStatus().getCode()) {
      case ABORTED:
      case DEADLINE_EXCEEDED:
      case INTERNAL:
      case RESOURCE_EXHAUSTED:
      case UNAVAILABLE:
      case UNKNOWN:
        return true;
      default:
        return false;
    }
  }
}


text:
<?php

/**
 * Admin controller.
 * Handles all admin requests.
*/
class Controller_Admin extends Controller
{
	public function get_index()
	{
		//  setup admin menus
		//$this->createDefaultMenu();
		$this->loadAdminHandlers();
		Hooks::doAction("admin_menus");

		//  determine which page is being viewed
		$activePanel = Menu::$menus[0];
		$params = Core::$activeRouteInfo->params;
		if (array_key_exists('panel', $params))
		{
		    $searchPanelSlug = $params['panel'];
		    foreach(Menu::$menus as $menu)
		    {
			if ($menu->slug == $searchPanelSlug)
			{
			    $activePanel = $menu;
			    break;
			}
		    }
		}

		$activePage = null;
		for($i = 0; $i < sizeof($activePanel->submenus); $i++)
		{
		    if ($activePanel->submenus[$i]->function != null)
		    {
			$activePage = $activePanel->submenus[$i];
			break;
		    }
		}

		if ($activePage == null)
		    $activePage = $activePanel;

		if (array_key_exists('page', $params))
		{
		    $searchSlug = $params['page'];
		    foreach($activePanel->submenus as $menu)
		    {
			if ($menu->slug == $searchSlug)
			{
			    $activePage = $menu;
			    break;
			}
		    }
		}

		//  check permissions

		//  run
		View::setGlobal('activePanel', $activePanel);
		View::setGlobal('activePage', $activePage);

		$callback = $activePage->function;
		ob_start();
		call_user_func_array($callback, array($this, Core::$activeRouteInfo));
		$html = ob_get_contents();
		ob_end_clean();

		//  show
		View::get('index')->set('output',$html)->render();
	}

	public function loadAdminHandlers()
	{
	    new Admin_Dashboard();
	    new Admin_Products();
	    new Admin_Inventory();
	    new Admin_Orders();
	    new Admin_Logistics();
	    new Admin_SiteSettings();
	    new Admin_Reports();
	    new Admin_CustomerService();
	}
}


text:
module MouseOwnerApp {
    var button: IBobrilComponent = {
        init(ctx: any, me: IBobrilNode): void {
            ctx.backColor = "#f0f0f0";
        },
        render(ctx: any, me: IBobrilNode): void {
            me.tag = "div";
            me.style = b.assign({}, ctx.data.style);
            me.children = ctx.data.children;
            me.style.backgroundColor = ctx.backColor;
        },
        onMouseDown(ctx: any): boolean {
            ctx.backColor = "red";
            b.registerMouseOwner(ctx);
            b.invalidate(ctx);
            return true;
        },
        onMouseUp(ctx: any): boolean {
            ctx.backColor = "#f0f0f0";
            if (b.isMouseOwner(ctx)) {
                b.releaseMouseOwner();
            }
            b.invalidate(ctx);
            return true;
        }
    };

    function twice(obj: any): any[] { return [obj, b.cloneNode(obj)]; }

    b.init(() => {
        return twice({
            tag: "div",
            style: { height: 500, width: 500, border: "solid 1px", position: "relative", cssFloat: "left" },
            children: {
                component: button, data: {
                    style: { width: 120, height: 20, position: "absolute", border: "1px solid #000", left: 190, top: 240 },
                    children: "Click and drag out"
                }
            }
        });
    });
}


text:
NSString* const FIRDigitsSessionAuthTokenKey = @"auth_token";
NSString* const FIRDigitsSessionAuthTokenSecretKey = @"auth_token_secret";
NSString* const FIRDigitsSessionUserIDKey = @"user_id";
NSString* const FIRDigitsSessionPhoneNumberKey = @"phone_number";
NSString* const FIRDigitsSessionEmailAddressKey = @"email_address";
NSString* const FIRDigitsSessionEmailAddressIsVerifiedKey = @"email_address_is_verified";

NSString* const FIRDigitsJWTAuthTokenKey = @"auth_token";
NSString* const FIRDigitsJWTAuthTokenSecretKey = @"auth_token_secret";
NSString* const FIRDigitsJWTUserIDKey = @"id";
NSString* const FIRDigitsJWTPhoneNumberKey = @"phone_number";
NSString* const FIRDigitsJWTEmailAddressKey = @"email_address";
NSString* const FIRDigitsJWTEmailAddressIsVerifiedKey = @"email_address_is_verified";
NSString* const FIRDigitsJWTAppConsumerKey = @"app_consumer_key";
NSString* const FIRDigitsJWTAppConsumerSecret = @"app_consumer_secret";
NSString* const FIRDigitsJWTFabricApiKey = @"fabric_api_key";

@implementation FIRDigitsSession

- (instancetype)initWithAuthToken:(NSString *)authToken
                  authTokenSecret:(NSString *)authTokenSecret
                           userID:(NSString *)userID
                      phoneNumber:(NSString *)phoneNumber
                     emailAddress:(NSString *)emailAddress
           emailAddressIsVerified:(BOOL)emailAddressIsVerified {
  if (self = [super init]) {
    _authToken = [authToken copy];
    _authTokenSecret = [authTokenSecret copy];
    _userID = [userID copy];
    _phoneNumber = [phoneNumber copy];
    _emailAddress = [emailAddress copy];
    _emailAddressIsVerified = emailAddressIsVerified;
  }
    return self;
}

- (instancetype)initWithCoder:(NSCoder *)aDecoder {
  if (self = [super init]) {
    _authToken = [aDecoder decodeObjectForKey:FIRDigitsSessionAuthTokenKey];
    _authTokenSecret = [aDecoder decodeObjectForKey:FIRDigitsSessionAuthTokenSecretKey];
    _userID = [aDecoder decodeObjectForKey:FIRDigitsSessionUserIDKey];
    _phoneNumber = [aDecoder decodeObjectForKey:FIRDigitsSessionPhoneNumberKey];
    _emailAddress = [aDecoder decodeObjectForKey:FIRDigitsSessionEmailAddressKey];
    _emailAddressIsVerified = [aDecoder decodeBoolForKey:FIRDigitsSessionEmailAddressIsVerifiedKey];
  }
  return self;
}

- (void)encodeWithCoder:(NSCoder *)aCoder {
  [aCoder encodeObject:self.authToken forKey:FIRDigitsSessionAuthTokenKey];
  [aCoder encodeObject:self.authTokenSecret forKey:FIRDigitsSessionAuthTokenSecretKey];
  [aCoder encodeObject:self.userID forKey:FIRDigitsSessionUserIDKey];
  [aCoder encodeObject:self.phoneNumber forKey:FIRDigitsSessionPhoneNumberKey];
  [aCoder encodeObject:self.emailAddress forKey:FIRDigitsSessionEmailAddressKey];
  [aCoder encodeBool:self.emailAddressIsVerified forKey:FIRDigitsSessionEmailAddressIsVerifiedKey];
}

- (BOOL)isEqual:(id)other {
  if (other == self) {
    return YES;
  } else if ([other isKindOfClass:[FIRDigitsSession class]]) {
    FIRDigitsSession *otherSession = (FIRDigitsSession *)other;
    return [self.userID isEqualToString:otherSession.userID];
  } else {
    return NO;
  }
}

- (NSUInteger)hash {
  return (self.userID).hash;
}

+ (NSString*)toCustomSignInJWT:(FIRDigitsSession*)session
            withAppConsumerKey:(NSString *)appConsumerKey
         withAppConsumerSecret:(NSString *)appConsumerSecret
              withFabricApiKey:(NSString *)fabricApiKey {
  NSMutableDictionary *payload = [@{
                                    FIRDigitsJWTAuthTokenKey: session.authToken,
                                    FIRDigitsJWTAuthTokenSecretKey: session.authTokenSecret,
                                    FIRDigitsJWTUserIDKey: session.userID,
                                    FIRDigitsJWTPhoneNumberKey: session.phoneNumber,
                                    FIRDigitsJWTAppConsumerKey: appConsumerKey,
                                    FIRDigitsJWTAppConsumerSecret: appConsumerSecret,
                                    FIRDigitsJWTFabricApiKey: fabricApiKey
                                    } mutableCopy];
  if (session.emailAddress) {
    payload[FIRDigitsJWTEmailAddressKey] = session.emailAddress;
    payload[FIRDigitsJWTEmailAddressIsVerifiedKey] = @(session.emailAddressIsVerified);
  }

  id<JWTAlgorithm> algorithm = [JWTAlgorithmFactory algorithmByName:@"none"];
  return [JWTBuilder encodePayload:payload].algorithm(algorithm).encode;
}

+ (NSString *)describe:(FIRDigitsSession*)session {
  return [NSString stringWithFormat: @"FIRDigitsSession: authToken=%@ authTokenSecret=%@ userID=%@ phoneNumber=%@ emailAddress=%@ emailAddressIsVerified=%@", session.authToken, session.authTokenSecret, session.userID, session.phoneNumber, session.emailAddress, session.emailAddressIsVerified?@"true":@"false"];
}

@end


text:
var tableModel = function() {
    var self = {

        tableObj: null,
        selectedTestName: null,
        graphModel: null,

        selectOneRow: function() {
            var testName = $(this).text();
            graphModel.toggleSeries(testName);
        },

        createTable: function(dataModel, graphModel, inputModel) {
            self.graphModel = graphModel;
            var chartData = dataModel.chartData;
            var tableDataSet = graphModel.getSeriesData();
            var i = 0;

            if (tableDataSet == []) {
                return;
            }

            var columns = [ ];
            columns.push({ title : "No" });
            columns.push({
                title : "Test name",
                createdCell: function(cell, cellData, rowData, rowIndex, colIndex) {
                    if (cellData.length > 90) {
                        cell.title = cellData
                        $(cell).tooltip( {
                            delay: 0,
                            track: true
                        })
                    }
                    $(cell).on('click', self.selectOneRow);
                }
            });

            var dataColumns = chartData[0].data;
            for (i = 0; i < dataColumns.length; i++) {
                var columnOptions = {
                    title: "#" + dataColumns[i].xLabel,
                    createdCell: function(cell, cellData, rowData, rowIndex, colIndex) {
                        if (cellData === null || typeof cellData === 'undefined') {
                            return
                        }
                        var cellClassName = '';
                        if (inputModel.relativeToBuild) {
                            var col = dataColumns[colIndex-2];
                            var relativeColumnName = '';
                            if (col != null) {
                                relativeColumnName = col.xLabel;
                            }
                            if (relativeColumnName != inputModel.relativeToBuild) {
                                cellClassName = cellData <= 0 ? 'ttp' : 'ttf'
                            }
                        } else if (dataModel.hasTestTimeThresholdData()) {
                            var testName = rowData[1];
                            var thresholdData = dataModel.testTimeThresholdData[testName];

                            if (!thresholdData) {
                                thresholdData = dataModel.testTimeThresholdData['*'];
                            }
                            if (thresholdData) {
                                if (cellData <= thresholdData.PassedTime) {
                                    cellClassName = 'ttp';
                                } else if (cellData >= thresholdData.FailedTime) {
                                    cellClassName = 'ttf';
                                } else {
                                    cellClassName = 'tti';
                                }
                            }
                        }
                        if (cellClassName) {
                            $(cell).addClass(cellClassName);
                        }
                    },
                    render: function(data, type, row, meta) {
                        if (data == null) {
                            return data;
                        }
                        if (inputModel.graphUnit == GraphUnitEnum.percent && data !== Infinity && data !== -Infinity) {
                            return data + '%';
                        }
                        return data;
                    },
                    type: (inputModel.graphUnit == GraphUnitEnum.percent ? 'num-fmt' : 'num')
                };
                if (dataColumns[i].xLabel == inputModel.relativeToBuild) {
                    columnOptions.className = 'relativeBuildColumn'
                }
                columns.push(columnOptions)
            }

            if (self.tableObj) {
                self.tableObj.fnClearTable();
                self.tableObj.fnDestroy();
            }
            jQuery('#tableContainer').html('

');
            self.tableObj = jQuery('#tableData').dataTable( {
                data: tableDataSet,
                columns: columns,
                searching: false,
                scrollX: true,
                fixedColumns: {
                    leftColumns: 2
                }
            } );
        }
    };
    return self;
}();


text:
<?php

/* VistaBundle:Default:demo.html.twig */
class __TwigTemplate_b2330b975b593717221f11a4bce16726175ac3cd2de0b3f00f0e3de23616a406 extends Twig_Template
{
    public function __construct(Twig_Environment $env)
    {
        parent::__construct($env);

        $this->parent = false;

        $this->blocks = array(
        );
    }

    protected function doDisplay(array $context, array $blocks = array())
    {
        // line 1
        echo "

        <title>Demo</title>

";
    }

    public function getTemplateName()
    {
        return "VistaBundle:Default:demo.html.twig";
    }

    public function getDebugInfo()
    {
        return array (  19 => 1,);
    }
}
/*  */
/* */
/* */
/*      */
/*         <title>Demo</title> */
/*     */
/*     */
/*    */
/*     */
/*         */
/*     */
/* */


text:
import matplotlib.path as mpath
import matplotlib.patches as mpatches
import matplotlib.pyplot as plt
from cStringIO import StringIO
import base64

class Row(object):
    name = None
    arm = None
    weight = None

    def __init__(self, name = None, arm = 0.0, weight = 0.0):
        super(Row, self).__init__()
        self.name = name if name else "unknown"
        self.arm = arm
        self.weight = weight

    @property
    def moment(self):
        return float(self.weight) * float(self.arm)

    def __getitem__(self, key):
        if key == 0:
            key = 'weight'
        elif key == 1:
            key = 'arm'
        elif key == 2:
            key = 'moment'
        elif key == 3:
            key = 'name'
        return getattr(self, key)

    def __setitem__(self, key, value):
        if key == 0:
            key = 'weight'
        elif key == 1:
            key = 'arm'
        elif key == 2:
            raise ValueError("You cannot set moment manually")
        elif key == 3:
            key = 'name'
        setattr(self, key, value)

class Envelope(object):
    name = None
    points = None

    def __init__(self, name):
        super(Envelope, self).__init__()
        self.points = []
        self.name = name

    def addPoint(self, moment, weight):
        self.points.append((moment, weight))

class WeightBalance(object):
    rows = None
    envelopes = None
    weightUnit = None
    mtow = None

    def __init__(self, weightUnit = 'kg', mtow=0):
        super(WeightBalance, self).__init__()
        self.rows = []
        self.envelopes = []
        self.weightUnit = weightUnit
        self.mtow = mtow

    def addEnvelope(self, envelope):
        self.envelopes.append(envelope)

    def addRow(self, arm, weight, name=None):
        self.rows.append(Row(arm=arm, weight=weight, name=name))

    def calculate(self):
        weight = 0
        moment = 0
        for r in self.rows:
            weight += r['weight']
            moment += r['moment']
        return (weight, moment/weight, moment, True if weight <= self.mtow else False)

    def plot(self):
        fig, ax = plt.subplots()

        # Draw current weight and Balance
        x = self.calculate()
        color = 'g' if x[3] else 'r'
        plt.scatter(x[1], x[0], marker="D", s=100, color=color)
        ax.text(x[1], x[0]-(x[0]/100.0*6.0), 'Weight %(w)d%(u)s (%(m)d%(u)s mtow)' % {'w':x[0], 'u':self.weightUnit, 'm':self.mtow}, color=color)

        # Draw envelopes
        for e in self.envelopes:
            path = mpath.Path(e.points)
            patch = mpatches.PathPatch(path, alpha=0.0)
            ax.add_patch(patch)
            x, y = zip(*path.vertices)
            ax.plot(x, y, 'o--', label="%s" % e.name)

        # global parameters for the plot result
        ax.legend()
        plt.xlabel("Arm")
        plt.ylabel("Weight (%s)" % self.weightUnit)
        ax.grid()

        sio = StringIO()
        plt.savefig(sio, format='png')
        sio.seek(0)

        return base64.b64encode(sio.getvalue())

if __name__ == "__main__":
    envelope = Envelope('Normal')
    envelope.addPoint(moment=1.841, weight=350)
    envelope.addPoint(moment=1.841, weight=630)
    envelope.addPoint(moment=1.978, weight=630)
    envelope.addPoint(moment=1.978, weight=350)

    #envelope2 = Envelope('Utility')
    #envelope2.addPoint(moment=1.811, weight=350)
    #envelope2.addPoint(moment=1.811, weight=830)
    #envelope2.addPoint(moment=1.918, weight=830)
    #envelope2.addPoint(moment=1.918, weight=350)

    wb = WeightBalance(mtow=630)
    wb.addEnvelope(envelope)
    #wb.addEnvelope(envelope2)
    wb.addRow(weight=397, arm=1.908)
    wb.addRow(weight=185, arm=1.800)
    wb.addRow(weight=28.8, arm=2.209)
    wb.addRow(weight=15, arm=2.417)

    rawimage = wb.plot()
    with open('wnb.png', 'w') as f:
        f.write(base64.b64decode(rawimage))


text:
import 'vs/css!./media/tree';
import { IDisposable, dispose, Disposable, toDisposable, DisposableStore } from 'vs/base/common/lifecycle';
import { IListOptions, List, IListStyles, MouseController, DefaultKeyboardNavigationDelegate, isInputElement, isMonacoEditor } from 'vs/base/browser/ui/list/listWidget';
import { IListVirtualDelegate, IListRenderer, IListMouseEvent, IListContextMenuEvent, IListDragAndDrop, IListDragOverReaction, IKeyboardNavigationLabelProvider, IIdentityProvider, IKeyboardNavigationDelegate } from 'vs/base/browser/ui/list/list';
import { append, $, getDomNodePagePosition, hasParentWithClass, createStyleSheet, clearNode } from 'vs/base/browser/dom';
import { Event, Relay, Emitter, EventBufferer } from 'vs/base/common/event';
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
import { KeyCode } from 'vs/base/common/keyCodes';
import { ITreeModel, ITreeNode, ITreeRenderer, ITreeEvent, ITreeMouseEvent, ITreeContextMenuEvent, ITreeFilter, ITreeNavigator, ICollapseStateChangeEvent, ITreeDragAndDrop, TreeDragOverBubble, TreeVisibility, TreeFilterResult, ITreeModelSpliceEvent, TreeMouseEventTarget } from 'vs/base/browser/ui/tree/tree';
import { ISpliceable } from 'vs/base/common/sequence';
import { IDragAndDropData, StaticDND, DragAndDropData } from 'vs/base/browser/dnd';
import { range, equals, distinctES6, firstOrDefault } from 'vs/base/common/arrays';
import { ElementsDragAndDropData } from 'vs/base/browser/ui/list/listView';
import { domEvent } from 'vs/base/browser/event';
import { fuzzyScore, FuzzyScore } from 'vs/base/common/filters';
import { getVisibleState, isFilterResult } from 'vs/base/browser/ui/tree/indexTreeModel';
import { localize } from 'vs/nls';
import { disposableTimeout } from 'vs/base/common/async';
import { isMacintosh } from 'vs/base/common/platform';
import { clamp } from 'vs/base/common/numbers';
import { ScrollEvent } from 'vs/base/common/scrollable';
import { SetMap } from 'vs/base/common/collections';
import { treeItemExpandedIcon, treeFilterOnTypeOnIcon, treeFilterOnTypeOffIcon, treeFilterClearIcon } from 'vs/base/browser/ui/tree/treeIcons';

class TreeElementsDragAndDropData<T, TFilterData, TContext> extends ElementsDragAndDropData<T, TContext> {

	override set context(context: TContext | undefined) {
		this.data.context = context;
	}

	override get context(): TContext | undefined {
		return this.data.context;
	}

	constructor(private data: ElementsDragAndDropData<ITreeNode<T, TFilterData>, TContext>) {
		super(data.elements.map(node => node.element));
	}
}

function asTreeDragAndDropData<T, TFilterData>(data: IDragAndDropData): IDragAndDropData {
	if (data instanceof ElementsDragAndDropData) {
		return new TreeElementsDragAndDropData(data);
	}

	return data;
}

class TreeNodeListDragAndDrop<T, TFilterData, TRef> implements IListDragAndDrop<ITreeNode<T, TFilterData>> {

	private autoExpandNode: ITreeNode<T, TFilterData> | undefined;
	private autoExpandDisposable: IDisposable = Disposable.None;

	constructor(private modelProvider: () => ITreeModel<T, TFilterData, TRef>, private dnd: ITreeDragAndDrop<T>) { }

	getDragURI(node: ITreeNode<T, TFilterData>): string | null {
		return this.dnd.getDragURI(node.element);
	}

	getDragLabel(nodes: ITreeNode<T, TFilterData>[], originalEvent: DragEvent): string | undefined {
		if (this.dnd.getDragLabel) {
			return this.dnd.getDragLabel(nodes.map(node => node.element), originalEvent);
		}

		return undefined;
	}

	onDragStart(data: IDragAndDropData, originalEvent: DragEvent): void {
		if (this.dnd.onDragStart) {
			this.dnd.onDragStart(asTreeDragAndDropData(data), originalEvent);
		}
	}

	onDragOver(data: IDragAndDropData, targetNode: ITreeNode<T, TFilterData> | undefined, targetIndex: number | undefined, originalEvent: DragEvent, raw = true): boolean | IListDragOverReaction {
		const result = this.dnd.onDragOver(asTreeDragAndDropData(data), targetNode && targetNode.element, targetIndex, originalEvent);
		const didChangeAutoExpandNode = this.autoExpandNode !== targetNode;

		if (didChangeAutoExpandNode) {
			this.autoExpandDisposable.dispose();
			this.autoExpandNode = targetNode;
		}

		if (typeof targetNode === 'undefined') {
			return result;
		}

		if (didChangeAutoExpandNode && typeof result !== 'boolean' && result.autoExpand) {
			this.autoExpandDisposable = disposableTimeout(() => {
				const model = this.modelProvider();
				const ref = model.getNodeLocation(targetNode);

				if (model.isCollapsed(ref)) {
					model.setCollapsed(ref, false);
				}

				this.autoExpandNode = undefined;
			}, 500);
		}

		if (typeof result === 'boolean' || !result.accept || typeof result.bubble === 'undefined' || result.feedback) {
			if (!raw) {
				const accept = typeof result === 'boolean' ? result : result.accept;
				const effect = typeof result === 'boolean' ? undefined : result.effect;
				return { accept, effect, feedback: [targetIndex!] };
			}

			return result;
		}

		if (result.bubble === TreeDragOverBubble.Up) {
			const model = this.modelProvider();
			const ref = model.getNodeLocation(targetNode);
			const parentRef = model.getParentNodeLocation(ref);
			const parentNode = model.getNode(parentRef);
			const parentIndex = parentRef && model.getListIndex(parentRef);

			return this.onDragOver(data, parentNode, parentIndex, originalEvent, false);
		}

		const model = this.modelProvider();
		const ref = model.getNodeLocation(targetNode);
		const start = model.getListIndex(ref);
		const length = model.getListRenderCount(ref);

		return { ...result, feedback: range(start, start + length) };
	}

	drop(data: IDragAndDropData, targetNode: ITreeNode<T, TFilterData> | undefined, targetIndex: number | undefined, originalEvent: DragEvent): void {
		this.autoExpandDisposable.dispose();
		this.autoExpandNode = undefined;

		this.dnd.drop(asTreeDragAndDropData(data), targetNode && targetNode.element, targetIndex, originalEvent);
	}

	onDragEnd(originalEvent: DragEvent): void {
		if (this.dnd.onDragEnd) {
			this.dnd.onDragEnd(originalEvent);
		}
	}
}

function asListOptions<T, TFilterData, TRef>(modelProvider: () => ITreeModel<T, TFilterData, TRef>, options?: IAbstractTreeOptions<T, TFilterData>): IListOptions<ITreeNode<T, TFilterData>> | undefined {
	return options && {
		...options,
		identityProvider: options.identityProvider && {
			getId(el) {
				return options.identityProvider!.getId(el.element);
			}
		},
		dnd: options.dnd && new TreeNodeListDragAndDrop(modelProvider, options.dnd),
		multipleSelectionController: options.multipleSelectionController && {
			isSelectionSingleChangeEvent(e) {
				return options.multipleSelectionController!.isSelectionSingleChangeEvent({ ...e, element: e.element } as any);
			},
			isSelectionRangeChangeEvent(e) {
				return options.multipleSelectionController!.isSelectionRangeChangeEvent({ ...e, element: e.element } as any);
			}
		},
		accessibilityProvider: options.accessibilityProvider && {
			...options.accessibilityProvider,
			getSetSize(node) {
				const model = modelProvider();
				const ref = model.getNodeLocation(node);
				const parentRef = model.getParentNodeLocation(ref);
				const parentNode = model.getNode(parentRef);

				return parentNode.visibleChildrenCount;
			},
			getPosInSet(node) {
				return node.visibleChildIndex + 1;
			},
			isChecked: options.accessibilityProvider && options.accessibilityProvider.isChecked ? (node) => {
				return options.accessibilityProvider!.isChecked!(node.element);
			} : undefined,
			getRole: options.accessibilityProvider && options.accessibilityProvider.getRole ? (node) => {
				return options.accessibilityProvider!.getRole!(node.element);
			} : () => 'treeitem',
			getAriaLabel(e) {
				return options.accessibilityProvider!.getAriaLabel(e.element);
			},
			getWidgetAriaLabel() {
				return options.accessibilityProvider!.getWidgetAriaLabel();
			},
			getWidgetRole: options.accessibilityProvider && options.accessibilityProvider.getWidgetRole ? () => options.accessibilityProvider!.getWidgetRole!() : () => 'tree',
			getAriaLevel: options.accessibilityProvider && options.accessibilityProvider.getAriaLevel ? (node) => options.accessibilityProvider!.getAriaLevel!(node.element) : (node) => {
				return node.depth;
			},
			getActiveDescendantId: options.accessibilityProvider.getActiveDescendantId && (node => {
				return options.accessibilityProvider!.getActiveDescendantId!(node.element);
			})
		},
		keyboardNavigationLabelProvider: options.keyboardNavigationLabelProvider && {
			...options.keyboardNavigationLabelProvider,
			getKeyboardNavigationLabel(node) {
				return options.keyboardNavigationLabelProvider!.getKeyboardNavigationLabel(node.element);
			}
		},
		enableKeyboardNavigation: options.simpleKeyboardNavigation
	};
}

export class ComposedTreeDelegate<T, N extends { element: T }> implements IListVirtualDelegate<N> {

	constructor(private delegate: IListVirtualDelegate<T>) { }

	getHeight(element: N): number {
		return this.delegate.getHeight(element.element);
	}

	getTemplateId(element: N): string {
		return this.delegate.getTemplateId(element.element);
	}

	hasDynamicHeight(element: N): boolean {
		return !!this.delegate.hasDynamicHeight && this.delegate.hasDynamicHeight(element.element);
	}

	setDynamicHeight(element: N, height: number): void {
		if (this.delegate.setDynamicHeight) {
			this.delegate.setDynamicHeight(element.element, height);
		}
	}
}

interface ITreeListTemplateData<T> {
	readonly container: HTMLElement;
	readonly indent: HTMLElement;
	readonly twistie: HTMLElement;
	indentGuidesDisposable: IDisposable;
	readonly templateData: T;
}

export enum RenderIndentGuides {
	None = 'none',
	OnHover = 'onHover',
	Always = 'always'
}

interface ITreeRendererOptions {
	readonly indent?: number;
	readonly renderIndentGuides?: RenderIndentGuides;
	// TODO@joao replace this with collapsible: boolean | 'ondemand'
	readonly hideTwistiesOfChildlessElements?: boolean;
}

interface IRenderData<TTemplateData> {
	templateData: ITreeListTemplateData<TTemplateData>;
	height: number;
}

interface Collection<T> {
	readonly elements: T[];
	readonly onDidChange: Event<T[]>;
}

class EventCollection<T> implements Collection<T> {

	readonly onDidChange: Event<T[]>;

	get elements(): T[] {
		return this._elements;
	}

	constructor(onDidChange: Event<T[]>, private _elements: T[] = []) {
		this.onDidChange = Event.forEach(onDidChange, elements => this._elements = elements);
	}
}

class TreeRenderer<T, TFilterData, TRef, TTemplateData> implements IListRenderer<ITreeNode<T, TFilterData>, ITreeListTemplateData<TTemplateData>> {

	private static readonly DefaultIndent = 8;

	readonly templateId: string;
	private renderedElements = new Map<T, ITreeNode<T, TFilterData>>();
	private renderedNodes = new Map<ITreeNode<T, TFilterData>, IRenderData<TTemplateData>>();
	private indent: number = TreeRenderer.DefaultIndent;
	private hideTwistiesOfChildlessElements: boolean = false;

	private shouldRenderIndentGuides: boolean = false;
	private renderedIndentGuides = new SetMap<ITreeNode<T, TFilterData>, HTMLDivElement>();
	private activeIndentNodes = new Set<ITreeNode<T, TFilterData>>();
	private indentGuidesDisposable: IDisposable = Disposable.None;

	private readonly disposables = new DisposableStore();

	constructor(
		private renderer: ITreeRenderer<T, TFilterData, TTemplateData>,
		private modelProvider: () => ITreeModel<T, TFilterData, TRef>,
		onDidChangeCollapseState: Event<ICollapseStateChangeEvent<T, TFilterData>>,
		private activeNodes: Collection<ITreeNode<T, TFilterData>>,
		options: ITreeRendererOptions = {}
	) {
		this.templateId = renderer.templateId;
		this.updateOptions(options);

		Event.map(onDidChangeCollapseState, e => e.node)(this.onDidChangeNodeTwistieState, this, this.disposables);

		if (renderer.onDidChangeTwistieState) {
			renderer.onDidChangeTwistieState(this.onDidChangeTwistieState, this, this.disposables);
		}
	}

	updateOptions(options: ITreeRendererOptions = {}): void {
		if (typeof options.indent !== 'undefined') {
			this.indent = clamp(options.indent, 0, 40);
		}

		if (typeof options.renderIndentGuides !== 'undefined') {
			const shouldRenderIndentGuides = options.renderIndentGuides !== RenderIndentGuides.None;

			if (shouldRenderIndentGuides !== this.shouldRenderIndentGuides) {
				this.shouldRenderIndentGuides = shouldRenderIndentGuides;
				this.indentGuidesDisposable.dispose();

				if (shouldRenderIndentGuides) {
					const disposables = new DisposableStore();
					this.activeNodes.onDidChange(this._onDidChangeActiveNodes, this, disposables);
					this.indentGuidesDisposable = disposables;

					this._onDidChangeActiveNodes(this.activeNodes.elements);
				}
			}
		}

		if (typeof options.hideTwistiesOfChildlessElements !== 'undefined') {
			this.hideTwistiesOfChildlessElements = options.hideTwistiesOfChildlessElements;
		}
	}

	renderTemplate(container: HTMLElement): ITreeListTemplateData<TTemplateData> {
		const el = append(container, $('.monaco-tl-row'));
		const indent = append(el, $('.monaco-tl-indent'));
		const twistie = append(el, $('.monaco-tl-twistie'));
		const contents = append(el, $('.monaco-tl-contents'));
		const templateData = this.renderer.renderTemplate(contents);

		return { container, indent, twistie, indentGuidesDisposable: Disposable.None, templateData };
	}

	renderElement(node: ITreeNode<T, TFilterData>, index: number, templateData: ITreeListTemplateData<TTemplateData>, height: number | undefined): void {
		if (typeof height === 'number') {
			this.renderedNodes.set(node, { templateData, height });
			this.renderedElements.set(node.element, node);
		}

		const indent = TreeRenderer.DefaultIndent + (node.depth - 1) * this.indent;
		templateData.twistie.style.paddingLeft = `${indent}px`;
		templateData.indent.style.width = `${indent + this.indent - 16}px`;

		this.renderTwistie(node, templateData);

		if (typeof height === 'number') {
			this.renderIndentGuides(node, templateData);
		}

		this.renderer.renderElement(node, index, templateData.templateData, height);
	}

	disposeElement(node: ITreeNode<T, TFilterData>, index: number, templateData: ITreeListTemplateData<TTemplateData>, height: number | undefined): void {
		templateData.indentGuidesDisposable.dispose();

		if (this.renderer.disposeElement) {
			this.renderer.disposeElement(node, index, templateData.templateData, height);
		}

		if (typeof height === 'number') {
			this.renderedNodes.delete(node);
			this.renderedElements.delete(node.element);
		}
	}

	disposeTemplate(templateData: ITreeListTemplateData<TTemplateData>): void {
		this.renderer.disposeTemplate(templateData.templateData);
	}

	private onDidChangeTwistieState(element: T): void {
		const node = this.renderedElements.get(element);

		if (!node) {
			return;
		}

		this.onDidChangeNodeTwistieState(node);
	}

	private onDidChangeNodeTwistieState(node: ITreeNode<T, TFilterData>): void {
		const data = this.renderedNodes.get(node);

		if (!data) {
			return;
		}

		this.renderTwistie(node, data.templateData);
		this._onDidChangeActiveNodes(this.activeNodes.elements);
		this.renderIndentGuides(node, data.templateData);
	}

	private renderTwistie(node: ITreeNode<T, TFilterData>, templateData: ITreeListTemplateData<TTemplateData>) {
		templateData.twistie.classList.remove(...treeItemExpandedIcon.classNamesArray);

		let twistieRendered = false;

		if (this.renderer.renderTwistie) {
			twistieRendered = this.renderer.renderTwistie(node.element, templateData.twistie);
		}

		if (node.collapsible && (!this.hideTwistiesOfChildlessElements || node.visibleChildrenCount > 0)) {
			if (!twistieRendered) {
				templateData.twistie.classList.add(...treeItemExpandedIcon.classNamesArray);
			}

			templateData.twistie.classList.add('collapsible');
			templateData.twistie.classList.toggle('collapsed', node.collapsed);
		} else {
			templateData.twistie.classList.remove('collapsible', 'collapsed');
		}

		if (node.collapsible) {
			templateData.container.setAttribute('aria-expanded', String(!node.collapsed));
		} else {
			templateData.container.removeAttribute('aria-expanded');
		}
	}

	private renderIndentGuides(target: ITreeNode<T, TFilterData>, templateData: ITreeListTemplateData<TTemplateData>): void {
		clearNode(templateData.indent);
		templateData.indentGuidesDisposable.dispose();

		if (!this.shouldRenderIndentGuides) {
			return;
		}

		const disposableStore = new DisposableStore();
		const model = this.modelProvider();

		let node = target;

		while (true) {
			const ref = model.getNodeLocation(node);
			const parentRef = model.getParentNodeLocation(ref);

			if (!parentRef) {
				break;
			}

			const parent = model.getNode(parentRef);
			const guide = $<HTMLDivElement>('.indent-guide', { style: `width: ${this.indent}px` });

			if (this.activeIndentNodes.has(parent)) {
				guide.classList.add('active');
			}

			if (templateData.indent.childElementCount === 0) {
				templateData.indent.appendChild(guide);
			} else {
				templateData.indent.insertBefore(guide, templateData.indent.firstElementChild);
			}

			this.renderedIndentGuides.add(parent, guide);
			disposableStore.add(toDisposable(() => this.renderedIndentGuides.delete(parent, guide)));

			node = parent;
		}

		templateData.indentGuidesDisposable = disposableStore;
	}

	private _onDidChangeActiveNodes(nodes: ITreeNode<T, TFilterData>[]): void {
		if (!this.shouldRenderIndentGuides) {
			return;
		}

		const set = new Set<ITreeNode<T, TFilterData>>();
		const model = this.modelProvider();

		nodes.forEach(node => {
			const ref = model.getNodeLocation(node);
			try {
				const parentRef = model.getParentNodeLocation(ref);

				if (node.collapsible && node.children.length > 0 && !node.collapsed) {
					set.add(node);
				} else if (parentRef) {
					set.add(model.getNode(parentRef));
				}
			} catch {
				// noop
			}
		});

		this.activeIndentNodes.forEach(node => {
			if (!set.has(node)) {
				this.renderedIndentGuides.forEach(node, line => line.classList.remove('active'));
			}
		});

		set.forEach(node => {
			if (!this.activeIndentNodes.has(node)) {
				this.renderedIndentGuides.forEach(node, line => line.classList.add('active'));
			}
		});

		this.activeIndentNodes = set;
	}

	dispose(): void {
		this.renderedNodes.clear();
		this.renderedElements.clear();
		this.indentGuidesDisposable.dispose();
		dispose(this.disposables);
	}
}

export type LabelFuzzyScore = { label: string; score: FuzzyScore };

class TypeFilter<T> implements ITreeFilter<T, FuzzyScore | LabelFuzzyScore>, IDisposable {
	private _totalCount = 0;
	get totalCount(): number { return this._totalCount; }
	private _matchCount = 0;
	get matchCount(): number { return this._matchCount; }

	private _pattern: string = '';
	private _lowercasePattern: string = '';
	private readonly disposables = new DisposableStore();

	set pattern(pattern: string) {
		this._pattern = pattern;
		this._lowercasePattern = pattern.toLowerCase();
	}

	constructor(
		private tree: AbstractTree<T, any, any>,
		private keyboardNavigationLabelProvider: IKeyboardNavigationLabelProvider<T>,
		private _filter?: ITreeFilter<T, FuzzyScore>
	) {
		tree.onWillRefilter(this.reset, this, this.disposables);
	}

	filter(element: T, parentVisibility: TreeVisibility): TreeFilterResult<FuzzyScore | LabelFuzzyScore> {
		if (this._filter) {
			const result = this._filter.filter(element, parentVisibility);

			if (this.tree.options.simpleKeyboardNavigation) {
				return result;
			}

			let visibility: TreeVisibility;

			if (typeof result === 'boolean') {
				visibility = result ? TreeVisibility.Visible : TreeVisibility.Hidden;
			} else if (isFilterResult(result)) {
				visibility = getVisibleState(result.visibility);
			} else {
				visibility = result;
			}

			if (visibility === TreeVisibility.Hidden) {
				return false;
			}
		}

		this._totalCount++;

		if (this.tree.options.simpleKeyboardNavigation || !this._pattern) {
			this._matchCount++;
			return { data: FuzzyScore.Default, visibility: true };
		}

		const label = this.keyboardNavigationLabelProvider.getKeyboardNavigationLabel(element);
		const labels = Array.isArray(label) ? label : [label];

		for (const l of labels) {
			const labelStr = l && l.toString();
			if (typeof labelStr === 'undefined') {
				return { data: FuzzyScore.Default, visibility: true };
			}

			const score = fuzzyScore(this._pattern, this._lowercasePattern, 0, labelStr, labelStr.toLowerCase(), 0, true);
			if (score) {
				this._matchCount++;
				return labels.length === 1 ?
					{ data: score, visibility: true } :
					{ data: { label: labelStr, score: score }, visibility: true };
			}
		}

		if (this.tree.options.filterOnType) {
			return TreeVisibility.Recurse;
		} else {
			return { data: FuzzyScore.Default, visibility: true };
		}
	}

	private reset(): void {
		this._totalCount = 0;
		this._matchCount = 0;
	}

	dispose(): void {
		dispose(this.disposables);
	}
}

class TypeFilterController<T, TFilterData> implements IDisposable {

	private _enabled = false;
	get enabled(): boolean { return this._enabled; }

	private _pattern = '';
	get pattern(): string { return this._pattern; }

	private _filterOnType: boolean;
	get filterOnType(): boolean { return this._filterOnType; }

	private _empty: boolean = false;
	get empty(): boolean { return this._empty; }

	private readonly _onDidChangeEmptyState = new Emitter<boolean>();
	readonly onDidChangeEmptyState: Event<boolean> = Event.latch(this._onDidChangeEmptyState.event);

	private positionClassName = 'ne';
	private domNode: HTMLElement;
	private messageDomNode: HTMLElement;
	private labelDomNode: HTMLElement;
	private filterOnTypeDomNode: HTMLInputElement;
	private clearDomNode: HTMLElement;
	private keyboardNavigationEventFilter?: IKeyboardNavigationEventFilter;

	private automaticKeyboardNavigation = true;
	private triggered = false;

	private readonly _onDidChangePattern = new Emitter<string>();
	readonly onDidChangePattern = this._onDidChangePattern.event;

	private readonly enabledDisposables = new DisposableStore();
	private readonly disposables = new DisposableStore();

	constructor(
		private tree: AbstractTree<T, TFilterData, any>,
		model: ITreeModel<T, TFilterData, any>,
		private view: List<ITreeNode<T, TFilterData>>,
		private filter: TypeFilter<T>,
		private keyboardNavigationDelegate: IKeyboardNavigationDelegate
	) {
		this.domNode = $(`.monaco-list-type-filter.${this.positionClassName}`);
		this.domNode.draggable = true;
		domEvent(this.domNode, 'dragstart')(this.onDragStart, this, this.disposables);

		this.messageDomNode = append(view.getHTMLElement(), $(`.monaco-list-type-filter-message`));

		this.labelDomNode = append(this.domNode, $('span.label'));
		const controls = append(this.domNode, $('.controls'));

		this._filterOnType = !!tree.options.filterOnType;
		this.filterOnTypeDomNode = append(controls, $<HTMLInputElement>('input.filter'));
		this.filterOnTypeDomNode.type = 'checkbox';
		this.filterOnTypeDomNode.checked = this._filterOnType;
		this.filterOnTypeDomNode.tabIndex = -1;
		this.updateFilterOnTypeTitleAndIcon();
		domEvent(this.filterOnTypeDomNode, 'input')(this.onDidChangeFilterOnType, this, this.disposables);

		this.clearDomNode = append(controls, $<HTMLInputElement>('button.clear' + treeFilterClearIcon.cssSelector));
		this.clearDomNode.tabIndex = -1;
		this.clearDomNode.title = localize('clear', "Clear");

		this.keyboardNavigationEventFilter = tree.options.keyboardNavigationEventFilter;

		model.onDidSplice(this.onDidSpliceModel, this, this.disposables);
		this.updateOptions(tree.options);
	}

	updateOptions(options: IAbstractTreeOptions<T, TFilterData>): void {
		if (options.simpleKeyboardNavigation) {
			this.disable();
		} else {
			this.enable();
		}

		if (typeof options.filterOnType !== 'undefined') {
			this._filterOnType = !!options.filterOnType;
			this.filterOnTypeDomNode.checked = this._filterOnType;
			this.updateFilterOnTypeTitleAndIcon();
		}

		if (typeof options.automaticKeyboardNavigation !== 'undefined') {
			this.automaticKeyboardNavigation = options.automaticKeyboardNavigation;
		}

		this.tree.refilter();
		this.render();

		if (!this.automaticKeyboardNavigation) {
			this.onEventOrInput('');
		}
	}

	toggle(): void {
		this.triggered = !this.triggered;

		if (!this.triggered) {
			this.onEventOrInput('');
		}
	}

	private enable(): void {
		if (this._enabled) {
			return;
		}

		const onKeyDown = Event.chain(domEvent(this.view.getHTMLElement(), 'keydown'))
			.filter(e => !isInputElement(e.target as HTMLElement) || e.target === this.filterOnTypeDomNode)
			.filter(e => e.key !== 'Dead' && !/^Media/.test(e.key))
			.map(e => new StandardKeyboardEvent(e))
			.filter(this.keyboardNavigationEventFilter || (() => true))
			.filter(() => this.automaticKeyboardNavigation || this.triggered)
			.filter(e => (this.keyboardNavigationDelegate.mightProducePrintableCharacter(e) && !(e.keyCode === KeyCode.DownArrow || e.keyCode === KeyCode.UpArrow || e.keyCode === KeyCode.LeftArrow || e.keyCode === KeyCode.RightArrow)) || ((this.pattern.length > 0 || this.triggered) && ((e.keyCode === KeyCode.Escape || e.keyCode === KeyCode.Backspace) && !e.altKey && !e.ctrlKey && !e.metaKey) || (e.keyCode === KeyCode.Backspace && (isMacintosh ? (e.altKey && !e.metaKey) : e.ctrlKey) && !e.shiftKey)))
			.forEach(e => { e.stopPropagation(); e.preventDefault(); })
			.event;

		const onClear = domEvent(this.clearDomNode, 'click');

		Event.chain(Event.any<MouseEvent | StandardKeyboardEvent>(onKeyDown, onClear))
			.event(this.onEventOrInput, this, this.enabledDisposables);

		this.filter.pattern = '';
		this.tree.refilter();
		this.render();
		this._enabled = true;
		this.triggered = false;
	}

	private disable(): void {
		if (!this._enabled) {
			return;
		}

		this.domNode.remove();
		this.enabledDisposables.clear();
		this.tree.refilter();
		this.render();
		this._enabled = false;
		this.triggered = false;
	}

	private onEventOrInput(e: MouseEvent | StandardKeyboardEvent | string): void {
		if (typeof e === 'string') {
			this.onInput(e);
		} else if (e instanceof MouseEvent || e.keyCode === KeyCode.Escape || (e.keyCode === KeyCode.Backspace && (isMacintosh ? e.altKey : e.ctrlKey))) {
			this.onInput('');
		} else if (e.keyCode === KeyCode.Backspace) {
			this.onInput(this.pattern.length === 0 ? '' : this.pattern.substr(0, this.pattern.length - 1));
		} else {
			this.onInput(this.pattern + e.browserEvent.key);
		}
	}

	private onInput(pattern: string): void {
		const container = this.view.getHTMLElement();

		if (pattern && !this.domNode.parentElement) {
			container.append(this.domNode);
		} else if (!pattern && this.domNode.parentElement) {
			this.domNode.remove();
			this.tree.domFocus();
		}

		this._pattern = pattern;
		this._onDidChangePattern.fire(pattern);

		this.filter.pattern = pattern;
		this.tree.refilter();

		if (pattern) {
			this.tree.focusNext(0, true, undefined, node => !FuzzyScore.isDefault(node.filterData as any as FuzzyScore));
		}

		const focus = this.tree.getFocus();

		if (focus.length > 0) {
			const element = focus[0];

			if (this.tree.getRelativeTop(element) === null) {
				this.tree.reveal(element, 0.5);
			}
		}

		this.render();

		if (!pattern) {
			this.triggered = false;
		}
	}

	private onDragStart(): void {
		const container = this.view.getHTMLElement();
		const { left } = getDomNodePagePosition(container);
		const containerWidth = container.clientWidth;
		const midContainerWidth = containerWidth / 2;
		const width = this.domNode.clientWidth;
		const disposables = new DisposableStore();
		let positionClassName = this.positionClassName;

		const updatePosition = () => {
			switch (positionClassName) {
				case 'nw':
					this.domNode.style.top = `4px`;
					this.domNode.style.left = `4px`;
					break;
				case 'ne':
					this.domNode.style.top = `4px`;
					this.domNode.style.left = `${containerWidth - width - 6}px`;
					break;
			}
		};

		const onDragOver = (event: DragEvent) => {
			event.preventDefault(); // needed so that the drop event fires (https://stackoverflow.com/questions/21339924/drop-event-not-firing-in-chrome)

			const x = event.clientX - left;
			if (event.dataTransfer) {
				event.dataTransfer.dropEffect = 'none';
			}

			if (x < midContainerWidth) {
				positionClassName = 'nw';
			} else {
				positionClassName = 'ne';
			}

			updatePosition();
		};

		const onDragEnd = () => {
			this.positionClassName = positionClassName;
			this.domNode.className = `monaco-list-type-filter ${this.positionClassName}`;
			this.domNode.style.top = '';
			this.domNode.style.left = '';

			dispose(disposables);
		};

		updatePosition();
		this.domNode.classList.remove(positionClassName);

		this.domNode.classList.add('dragging');
		disposables.add(toDisposable(() => this.domNode.classList.remove('dragging')));

		domEvent(document, 'dragover')(onDragOver, null, disposables);
		domEvent(this.domNode, 'dragend')(onDragEnd, null, disposables);

		StaticDND.CurrentDragAndDropData = new DragAndDropData('vscode-ui');
		disposables.add(toDisposable(() => StaticDND.CurrentDragAndDropData = undefined));
	}

	private onDidSpliceModel(): void {
		if (!this._enabled || this.pattern.length === 0) {
			return;
		}

		this.tree.refilter();
		this.render();
	}

	private onDidChangeFilterOnType(): void {
		this.tree.updateOptions({ filterOnType: this.filterOnTypeDomNode.checked });
		this.tree.refilter();
		this.tree.domFocus();
		this.render();
		this.updateFilterOnTypeTitleAndIcon();
	}

	private updateFilterOnTypeTitleAndIcon(): void {
		if (this.filterOnType) {
			this.filterOnTypeDomNode.classList.remove(...treeFilterOnTypeOffIcon.classNamesArray);
			this.filterOnTypeDomNode.classList.add(...treeFilterOnTypeOnIcon.classNamesArray);
			this.filterOnTypeDomNode.title = localize('disable filter on type', "Disable Filter on Type");
		} else {
			this.filterOnTypeDomNode.classList.remove(...treeFilterOnTypeOnIcon.classNamesArray);
			this.filterOnTypeDomNode.classList.add(...treeFilterOnTypeOffIcon.classNamesArray);
			this.filterOnTypeDomNode.title = localize('enable filter on type', "Enable Filter on Type");
		}
	}

	private render(): void {
		const noMatches = this.filter.totalCount > 0 && this.filter.matchCount === 0;

		if (this.pattern && this.tree.options.filterOnType && noMatches) {
			this.messageDomNode.textContent = localize('empty', "No elements found");
			this._empty = true;
		} else {
			this.messageDomNode.innerText = '';
			this._empty = false;
		}

		this.domNode.classList.toggle('no-matches', noMatches);
		this.domNode.title = localize('found', "Matched {0} out of {1} elements", this.filter.matchCount, this.filter.totalCount);
		this.labelDomNode.textContent = this.pattern.length > 16 ? '…' + this.pattern.substr(this.pattern.length - 16) : this.pattern;

		this._onDidChangeEmptyState.fire(this._empty);
	}

	shouldAllowFocus(node: ITreeNode<T, TFilterData>): boolean {
		if (!this.enabled || !this.pattern || this.filterOnType) {
			return true;
		}

		if (this.filter.totalCount > 0 && this.filter.matchCount <= 1) {
			return true;
		}

		return !FuzzyScore.isDefault(node.filterData as any as FuzzyScore);
	}

	dispose() {
		if (this._enabled) {
			this.domNode.remove();
			this.enabledDisposables.dispose();
			this._enabled = false;
			this.triggered = false;
		}

		this._onDidChangePattern.dispose();
		dispose(this.disposables);
	}
}

function asTreeMouseEvent<T>(event: IListMouseEvent<ITreeNode<T, any>>): ITreeMouseEvent<T> {
	let target: TreeMouseEventTarget = TreeMouseEventTarget.Unknown;

	if (hasParentWithClass(event.browserEvent.target as HTMLElement, 'monaco-tl-twistie', 'monaco-tl-row')) {
		target = TreeMouseEventTarget.Twistie;
	} else if (hasParentWithClass(event.browserEvent.target as HTMLElement, 'monaco-tl-contents', 'monaco-tl-row')) {
		target = TreeMouseEventTarget.Element;
	}

	return {
		browserEvent: event.browserEvent,
		element: event.element ? event.element.element : null,
		target
	};
}

function asTreeContextMenuEvent<T>(event: IListContextMenuEvent<ITreeNode<T, any>>): ITreeContextMenuEvent<T> {
	return {
		element: event.element ? event.element.element : null,
		browserEvent: event.browserEvent,
		anchor: event.anchor
	};
}

export interface IKeyboardNavigationEventFilter {
	(e: StandardKeyboardEvent): boolean;
}

export interface IAbstractTreeOptionsUpdate extends ITreeRendererOptions {
	readonly automaticKeyboardNavigation?: boolean;
	readonly simpleKeyboardNavigation?: boolean;
	readonly filterOnType?: boolean;
	readonly smoothScrolling?: boolean;
	readonly horizontalScrolling?: boolean;
	readonly expandOnDoubleClick?: boolean;
	readonly expandOnlyOnTwistieClick?: boolean | ((e: any) => boolean); // e is T
}

export interface IAbstractTreeOptions<T, TFilterData = void> extends IAbstractTreeOptionsUpdate, IListOptions<T> {
	readonly collapseByDefault?: boolean; // defaults to false
	readonly filter?: ITreeFilter<T, TFilterData>;
	readonly dnd?: ITreeDragAndDrop<T>;
	readonly keyboardNavigationEventFilter?: IKeyboardNavigationEventFilter;
	readonly additionalScrollHeight?: number;
}

function dfs<T, TFilterData>(node: ITreeNode<T, TFilterData>, fn: (node: ITreeNode<T, TFilterData>) => void): void {
	fn(node);
	node.children.forEach(child => dfs(child, fn));
}

/**
 * The trait concept needs to exist at the tree level, because collapsed
 * tree nodes will not be known by the list.
 */
class Trait<T> {

	private nodes: ITreeNode<T, any>[] = [];
	private elements: T[] | undefined;

	private readonly _onDidChange = new Emitter<ITreeEvent<T>>();
	readonly onDidChange = this._onDidChange.event;

	private _nodeSet: Set<ITreeNode<T, any>> | undefined;
	private get nodeSet(): Set<ITreeNode<T, any>> {
		if (!this._nodeSet) {
			this._nodeSet = this.createNodeSet();
		}

		return this._nodeSet;
	}

	constructor(private identityProvider?: IIdentityProvider<T>) { }

	set(nodes: ITreeNode<T, any>[], browserEvent?: UIEvent): void {
		if (!(browserEvent as any)?.__forceEvent && equals(this.nodes, nodes)) {
			return;
		}

		this._set(nodes, false, browserEvent);
	}

	private _set(nodes: ITreeNode<T, any>[], silent: boolean, browserEvent?: UIEvent): void {
		this.nodes = [...nodes];
		this.elements = undefined;
		this._nodeSet = undefined;

		if (!silent) {
			const that = this;
			this._onDidChange.fire({ get elements() { return that.get(); }, browserEvent });
		}
	}

	get(): T[] {
		if (!this.elements) {
			this.elements = this.nodes.map(node => node.element);
		}

		return [...this.elements];
	}

	getNodes(): readonly ITreeNode<T, any>[] {
		return this.nodes;
	}

	has(node: ITreeNode<T, any>): boolean {
		return this.nodeSet.has(node);
	}

	onDidModelSplice({ insertedNodes, deletedNodes }: ITreeModelSpliceEvent<T, any>): void {
		if (!this.identityProvider) {
			const set = this.createNodeSet();
			const visit = (node: ITreeNode<T, any>) => set.delete(node);
			deletedNodes.forEach(node => dfs(node, visit));
			this.set([...set.values()]);
			return;
		}

		const deletedNodesIdSet = new Set<string>();
		const deletedNodesVisitor = (node: ITreeNode<T, any>) => deletedNodesIdSet.add(this.identityProvider!.getId(node.element).toString());
		deletedNodes.forEach(node => dfs(node, deletedNodesVisitor));

		const insertedNodesMap = new Map<string, ITreeNode<T, any>>();
		const insertedNodesVisitor = (node: ITreeNode<T, any>) => insertedNodesMap.set(this.identityProvider!.getId(node.element).toString(), node);
		insertedNodes.forEach(node => dfs(node, insertedNodesVisitor));

		const nodes: ITreeNode<T, any>[] = [];

		for (const node of this.nodes) {
			const id = this.identityProvider.getId(node.element).toString();
			const wasDeleted = deletedNodesIdSet.has(id);

			if (!wasDeleted) {
				nodes.push(node);
			} else {
				const insertedNode = insertedNodesMap.get(id);

				if (insertedNode) {
					nodes.push(insertedNode);
				}
			}
		}

		this._set(nodes, true);
	}

	private createNodeSet(): Set<ITreeNode<T, any>> {
		const set = new Set<ITreeNode<T, any>>();

		for (const node of this.nodes) {
			set.add(node);
		}

		return set;
	}
}

class TreeNodeListMouseController<T, TFilterData, TRef> extends MouseController<ITreeNode<T, TFilterData>> {

	constructor(list: TreeNodeList<T, TFilterData, TRef>, private tree: AbstractTree<T, TFilterData, TRef>) {
		super(list);
	}

	protected override onViewPointer(e: IListMouseEvent<ITreeNode<T, TFilterData>>): void {
		if (isInputElement(e.browserEvent.target as HTMLElement) || isMonacoEditor(e.browserEvent.target as HTMLElement)) {
			return;
		}

		const node = e.element;

		if (!node) {
			return super.onViewPointer(e);
		}

		if (this.isSelectionRangeChangeEvent(e) || this.isSelectionSingleChangeEvent(e)) {
			return super.onViewPointer(e);
		}

		const target = e.browserEvent.target as HTMLElement;
		const onTwistie = target.classList.contains('monaco-tl-twistie')
			|| (target.classList.contains('monaco-icon-label') && target.classList.contains('folder-icon') && e.browserEvent.offsetX < 16);

		let expandOnlyOnTwistieClick = false;

		if (typeof this.tree.expandOnlyOnTwistieClick === 'function') {
			expandOnlyOnTwistieClick = this.tree.expandOnlyOnTwistieClick(node.element);
		} else {
			expandOnlyOnTwistieClick = !!this.tree.expandOnlyOnTwistieClick;
		}

		if (expandOnlyOnTwistieClick && !onTwistie && e.browserEvent.detail !== 2) {
			return super.onViewPointer(e);
		}

		if (!this.tree.expandOnDoubleClick && e.browserEvent.detail === 2) {
			return super.onViewPointer(e);
		}

		if (node.collapsible) {
			const model = ((this.tree as any).model as ITreeModel<T, TFilterData, TRef>); // internal
			const location = model.getNodeLocation(node);
			const recursive = e.browserEvent.altKey;
			this.tree.setFocus([location]);
			model.setCollapsed(location, undefined, recursive);

			if (expandOnlyOnTwistieClick && onTwistie) {
				return;
			}
		}

		super.onViewPointer(e);
	}

	protected override onDoubleClick(e: IListMouseEvent<ITreeNode<T, TFilterData>>): void {
		const onTwistie = (e.browserEvent.target as HTMLElement).classList.contains('monaco-tl-twistie');

		if (onTwistie || !this.tree.expandOnDoubleClick) {
			return;
		}

		super.onDoubleClick(e);
	}
}

interface ITreeNodeListOptions<T, TFilterData, TRef> extends IListOptions<ITreeNode<T, TFilterData>> {
	readonly tree: AbstractTree<T, TFilterData, TRef>;
}

/**
 * We use this List subclass to restore selection and focus as nodes
 * get rendered in the list, possibly due to a node expand() call.
 */
class TreeNodeList<T, TFilterData, TRef> extends List<ITreeNode<T, TFilterData>> {

	constructor(
		user: string,
		container: HTMLElement,
		virtualDelegate: IListVirtualDelegate<ITreeNode<T, TFilterData>>,
		renderers: IListRenderer<any /* TODO@joao */, any>[],
		private focusTrait: Trait<T>,
		private selectionTrait: Trait<T>,
		private anchorTrait: Trait<T>,
		options: ITreeNodeListOptions<T, TFilterData, TRef>
	) {
		super(user, container, virtualDelegate, renderers, options);
	}

	protected override createMouseController(options: ITreeNodeListOptions<T, TFilterData, TRef>): MouseController<ITreeNode<T, TFilterData>> {
		return new TreeNodeListMouseController(this, options.tree);
	}

	override splice(start: number, deleteCount: number, elements: ITreeNode<T, TFilterData>[] = []): void {
		super.splice(start, deleteCount, elements);

		if (elements.length === 0) {
			return;
		}

		const additionalFocus: number[] = [];
		const additionalSelection: number[] = [];
		let anchor: number | undefined;

		elements.forEach((node, index) => {
			if (this.focusTrait.has(node)) {
				additionalFocus.push(start + index);
			}

			if (this.selectionTrait.has(node)) {
				additionalSelection.push(start + index);
			}

			if (this.anchorTrait.has(node)) {
				anchor = start + index;
			}
		});

		if (additionalFocus.length > 0) {
			super.setFocus(distinctES6([...super.getFocus(), ...additionalFocus]));
		}

		if (additionalSelection.length > 0) {
			super.setSelection(distinctES6([...super.getSelection(), ...additionalSelection]));
		}

		if (typeof anchor === 'number') {
			super.setAnchor(anchor);
		}
	}

	override setFocus(indexes: number[], browserEvent?: UIEvent, fromAPI = false): void {
		super.setFocus(indexes, browserEvent);

		if (!fromAPI) {
			this.focusTrait.set(indexes.map(i => this.element(i)), browserEvent);
		}
	}

	override setSelection(indexes: number[], browserEvent?: UIEvent, fromAPI = false): void {
		super.setSelection(indexes, browserEvent);

		if (!fromAPI) {
			this.selectionTrait.set(indexes.map(i => this.element(i)), browserEvent);
		}
	}

	override setAnchor(index: number | undefined, fromAPI = false): void {
		super.setAnchor(index);

		if (!fromAPI) {
			if (typeof index === 'undefined') {
				this.anchorTrait.set([]);
			} else {
				this.anchorTrait.set([this.element(index)]);
			}
		}
	}
}

export abstract class AbstractTree<T, TFilterData, TRef> implements IDisposable {

	protected view: TreeNodeList<T, TFilterData, TRef>;
	private renderers: TreeRenderer<T, TFilterData, TRef, any>[];
	protected model: ITreeModel<T, TFilterData, TRef>;
	private focus: Trait<T>;
	private selection: Trait<T>;
	private anchor: Trait<T>;
	private eventBufferer = new EventBufferer();
	private typeFilterController?: TypeFilterController<T, TFilterData>;
	private focusNavigationFilter: ((node: ITreeNode<T, TFilterData>) => boolean) | undefined;
	private styleElement: HTMLStyleElement;
	protected readonly disposables = new DisposableStore();

	get onDidScroll(): Event<ScrollEvent> { return this.view.onDidScroll; }

	get onDidChangeFocus(): Event<ITreeEvent<T>> { return this.eventBufferer.wrapEvent(this.focus.onDidChange); }
	get onDidChangeSelection(): Event<ITreeEvent<T>> { return this.eventBufferer.wrapEvent(this.selection.onDidChange); }

	get onMouseClick(): Event<ITreeMouseEvent<T>> { return Event.map(this.view.onMouseClick, asTreeMouseEvent); }
	get onMouseDblClick(): Event<ITreeMouseEvent<T>> { return Event.map(this.view.onMouseDblClick, asTreeMouseEvent); }
	get onContextMenu(): Event<ITreeContextMenuEvent<T>> { return Event.map(this.view.onContextMenu, asTreeContextMenuEvent); }
	get onTap(): Event<ITreeMouseEvent<T>> { return Event.map(this.view.onTap, asTreeMouseEvent); }
	get onPointer(): Event<ITreeMouseEvent<T>> { return Event.map(this.view.onPointer, asTreeMouseEvent); }

	get onKeyDown(): Event<KeyboardEvent> { return this.view.onKeyDown; }
	get onKeyUp(): Event<KeyboardEvent> { return this.view.onKeyUp; }
	get onKeyPress(): Event<KeyboardEvent> { return this.view.onKeyPress; }

	get onDidFocus(): Event<void> { return this.view.onDidFocus; }
	get onDidBlur(): Event<void> { return this.view.onDidBlur; }

	get onDidChangeCollapseState(): Event<ICollapseStateChangeEvent<T, TFilterData>> { return this.model.onDidChangeCollapseState; }
	get onDidChangeRenderNodeCount(): Event<ITreeNode<T, TFilterData>> { return this.model.onDidChangeRenderNodeCount; }

	private readonly _onWillRefilter = new Emitter<void>();
	readonly onWillRefilter: Event<void> = this._onWillRefilter.event;

	get filterOnType(): boolean { return !!this._options.filterOnType; }
	get onDidChangeTypeFilterPattern(): Event<string> { return this.typeFilterController ? this.typeFilterController.onDidChangePattern : Event.None; }

	get expandOnDoubleClick(): boolean { return typeof this._options.expandOnDoubleClick === 'undefined' ? true : this._options.expandOnDoubleClick; }
	get expandOnlyOnTwistieClick(): boolean | ((e: T) => boolean) { return typeof this._options.expandOnlyOnTwistieClick === 'undefined' ? true : this._options.expandOnlyOnTwistieClick; }

	private readonly _onDidUpdateOptions = new Emitter<IAbstractTreeOptions<T, TFilterData>>();
	readonly onDidUpdateOptions: Event<IAbstractTreeOptions<T, TFilterData>> = this._onDidUpdateOptions.event;

	get onDidDispose(): Event<void> { return this.view.onDidDispose; }

	constructor(
		user: string,
		container: HTMLElement,
		delegate: IListVirtualDelegate<T>,
		renderers: ITreeRenderer<T, TFilterData, any>[],
		private _options: IAbstractTreeOptions<T, TFilterData> = {}
	) {
		const treeDelegate = new ComposedTreeDelegate<T, ITreeNode<T, TFilterData>>(delegate);

		const onDidChangeCollapseStateRelay = new Relay<ICollapseStateChangeEvent<T, TFilterData>>();
		const onDidChangeActiveNodes = new Relay<ITreeNode<T, TFilterData>[]>();
		const activeNodes = new EventCollection(onDidChangeActiveNodes.event);
		this.renderers = renderers.map(r => new TreeRenderer<T, TFilterData, TRef, any>(r, () => this.model, onDidChangeCollapseStateRelay.event, activeNodes, _options));
		for (let r of this.renderers) {
			this.disposables.add(r);
		}

		let filter: TypeFilter<T> | undefined;

		if (_options.keyboardNavigationLabelProvider) {
			filter = new TypeFilter(this, _options.keyboardNavigationLabelProvider, _options.filter as any as ITreeFilter<T, FuzzyScore>);
			_options = { ..._options, filter: filter as ITreeFilter<T, TFilterData> }; // TODO need typescript help here
			this.disposables.add(filter);
		}

		this.focus = new Trait(_options.identityProvider);
		this.selection = new Trait(_options.identityProvider);
		this.anchor = new Trait(_options.identityProvider);
		this.view = new TreeNodeList(user, container, treeDelegate, this.renderers, this.focus, this.selection, this.anchor, { ...asListOptions(() => this.model, _options), tree: this });

		this.model = this.createModel(user, this.view, _options);
		onDidChangeCollapseStateRelay.input = this.model.onDidChangeCollapseState;

		const onDidModelSplice = Event.forEach(this.model.onDidSplice, e => {
			this.eventBufferer.bufferEvents(() => {
				this.focus.onDidModelSplice(e);
				this.selection.onDidModelSplice(e);
			});
		});

		// Make sure the `forEach` always runs
		onDidModelSplice(() => null, null, this.disposables);

		// Active nodes can change when the model changes or when focus or selection change.
		// We debounce it with 0 delay since these events may fire in the same stack and we only
		// want to run this once. It also doesn't matter if it runs on the next tick since it's only
		// a nice to have UI feature.
		onDidChangeActiveNodes.input = Event.chain(Event.any<any>(onDidModelSplice, this.focus.onDidChange, this.selection.onDidChange))
			.debounce(() => null, 0)
			.map(() => {
				const set = new Set<ITreeNode<T, TFilterData>>();

				for (const node of this.focus.getNodes()) {
					set.add(node);
				}

				for (const node of this.selection.getNodes()) {
					set.add(node);
				}

				return [...set.values()];
			}).event;

		if (_options.keyboardSupport !== false) {
			const onKeyDown = Event.chain(this.view.onKeyDown)
				.filter(e => !isInputElement(e.target as HTMLElement))
				.map(e => new StandardKeyboardEvent(e));

			onKeyDown.filter(e => e.keyCode === KeyCode.LeftArrow).on(this.onLeftArrow, this, this.disposables);
			onKeyDown.filter(e => e.keyCode === KeyCode.RightArrow).on(this.onRightArrow, this, this.disposables);
			onKeyDown.filter(e => e.keyCode === KeyCode.Space).on(this.onSpace, this, this.disposables);
		}

		if (_options.keyboardNavigationLabelProvider) {
			const delegate = _options.keyboardNavigationDelegate || DefaultKeyboardNavigationDelegate;
			this.typeFilterController = new TypeFilterController(this, this.model, this.view, filter!, delegate);
			this.focusNavigationFilter = node => this.typeFilterController!.shouldAllowFocus(node);
			this.disposables.add(this.typeFilterController!);
		}

		this.styleElement = createStyleSheet(this.view.getHTMLElement());
		this.getHTMLElement().classList.toggle('always', this._options.renderIndentGuides === RenderIndentGuides.Always);
	}

	updateOptions(optionsUpdate: IAbstractTreeOptionsUpdate = {}): void {
		this._options = { ...this._options, ...optionsUpdate };

		for (const renderer of this.renderers) {
			renderer.updateOptions(optionsUpdate);
		}

		this.view.updateOptions({
			enableKeyboardNavigation: this._options.simpleKeyboardNavigation,
			automaticKeyboardNavigation: this._options.automaticKeyboardNavigation,
			smoothScrolling: this._options.smoothScrolling,
			horizontalScrolling: this._options.horizontalScrolling
		});

		if (this.typeFilterController) {
			this.typeFilterController.updateOptions(this._options);
		}

		this._onDidUpdateOptions.fire(this._options);

		this.getHTMLElement().classList.toggle('always', this._options.renderIndentGuides === RenderIndentGuides.Always);
	}

	get options(): IAbstractTreeOptions<T, TFilterData> {
		return this._options;
	}

	updateWidth(element: TRef): void {
		const index = this.model.getListIndex(element);

		if (index === -1) {
			return;
		}

		this.view.updateWidth(index);
	}

	// Widget

	getHTMLElement(): HTMLElement {
		return this.view.getHTMLElement();
	}

	get contentHeight(): number {
		if (this.typeFilterController && this.typeFilterController.filterOnType && this.typeFilterController.empty) {
			return 100;
		}

		return this.view.contentHeight;
	}

	get onDidChangeContentHeight(): Event<number> {
		let result = this.view.onDidChangeContentHeight;

		if (this.typeFilterController) {
			result = Event.any(result, Event.map(this.typeFilterController.onDidChangeEmptyState, () => this.contentHeight));
		}

		return result;
	}

	get scrollTop(): number {
		return this.view.scrollTop;
	}

	set scrollTop(scrollTop: number) {
		this.view.scrollTop = scrollTop;
	}

	get scrollLeft(): number {
		return this.view.scrollLeft;
	}

	set scrollLeft(scrollLeft: number) {
		this.view.scrollLeft = scrollLeft;
	}

	get scrollHeight(): number {
		return this.view.scrollHeight;
	}

	get renderHeight(): number {
		return this.view.renderHeight;
	}

	get firstVisibleElement(): T | undefined {
		const index = this.view.firstVisibleIndex;

		if (index < 0 || index >= this.view.length) {
			return undefined;
		}

		const node = this.view.element(index);
		return node.element;
	}

	get lastVisibleElement(): T {
		const index = this.view.lastVisibleIndex;
		const node = this.view.element(index);
		return node.element;
	}

	get ariaLabel(): string {
		return this.view.ariaLabel;
	}

	set ariaLabel(value: string) {
		this.view.ariaLabel = value;
	}

	domFocus(): void {
		this.view.domFocus();
	}

	isDOMFocused(): boolean {
		return this.getHTMLElement() === document.activeElement;
	}

	layout(height?: number, width?: number): void {
		this.view.layout(height, width);
	}

	style(styles: IListStyles): void {
		const suffix = `.${this.view.domId}`;
		const content: string[] = [];

		if (styles.treeIndentGuidesStroke) {
			content.push(`.monaco-list${suffix}:hover .monaco-tl-indent > .indent-guide, .monaco-list${suffix}.always .monaco-tl-indent > .indent-guide  { border-color: ${styles.treeIndentGuidesStroke.transparent(0.4)}; }`);
			content.push(`.monaco-list${suffix} .monaco-tl-indent > .indent-guide.active { border-color: ${styles.treeIndentGuidesStroke}; }`);
		}

		this.styleElement.textContent = content.join('\n');
		this.view.style(styles);
	}

	// Tree navigation

	getParentElement(location: TRef): T {
		const parentRef = this.model.getParentNodeLocation(location);
		const parentNode = this.model.getNode(parentRef);
		return parentNode.element;
	}

	getFirstElementChild(location: TRef): T | undefined {
		return this.model.getFirstElementChild(location);
	}

	// Tree

	getNode(location?: TRef): ITreeNode<T, TFilterData> {
		return this.model.getNode(location);
	}

	collapse(location: TRef, recursive: boolean = false): boolean {
		return this.model.setCollapsed(location, true, recursive);
	}

	expand(location: TRef, recursive: boolean = false): boolean {
		return this.model.setCollapsed(location, false, recursive);
	}

	toggleCollapsed(location: TRef, recursive: boolean = false): boolean {
		return this.model.setCollapsed(location, undefined, recursive);
	}

	expandAll(): void {
		this.model.setCollapsed(this.model.rootRef, false, true);
	}

	collapseAll(): void {
		this.model.setCollapsed(this.model.rootRef, true, true);
	}

	isCollapsible(location: TRef): boolean {
		return this.model.isCollapsible(location);
	}

	setCollapsible(location: TRef, collapsible?: boolean): boolean {
		return this.model.setCollapsible(location, collapsible);
	}

	isCollapsed(location: TRef): boolean {
		return this.model.isCollapsed(location);
	}

	toggleKeyboardNavigation(): void {
		this.view.toggleKeyboardNavigation();

		if (this.typeFilterController) {
			this.typeFilterController.toggle();
		}
	}

	refilter(): void {
		this._onWillRefilter.fire(undefined);
		this.model.refilter();
	}

	setAnchor(element: TRef | undefined): void {
		if (typeof element === 'undefined') {
			return this.view.setAnchor(undefined);
		}

		const node = this.model.getNode(element);
		this.anchor.set([node]);

		const index = this.model.getListIndex(element);

		if (index > -1) {
			this.view.setAnchor(index, true);
		}
	}

	getAnchor(): T | undefined {
		return firstOrDefault(this.anchor.get(), undefined);
	}

	setSelection(elements: TRef[], browserEvent?: UIEvent): void {
		const nodes = elements.map(e => this.model.getNode(e));
		this.selection.set(nodes, browserEvent);

		const indexes = elements.map(e => this.model.getListIndex(e)).filter(i => i > -1);
		this.view.setSelection(indexes, browserEvent, true);
	}

	getSelection(): T[] {
		return this.selection.get();
	}

	setFocus(elements: TRef[], browserEvent?: UIEvent): void {
		const nodes = elements.map(e => this.model.getNode(e));
		this.focus.set(nodes, browserEvent);

		const indexes = elements.map(e => this.model.getListIndex(e)).filter(i => i > -1);
		this.view.setFocus(indexes, browserEvent, true);
	}

	focusNext(n = 1, loop = false, browserEvent?: UIEvent, filter = this.focusNavigationFilter): void {
		this.view.focusNext(n, loop, browserEvent, filter);
	}

	focusPrevious(n = 1, loop = false, browserEvent?: UIEvent, filter = this.focusNavigationFilter): void {
		this.view.focusPrevious(n, loop, browserEvent, filter);
	}

	focusNextPage(browserEvent?: UIEvent, filter = this.focusNavigationFilter): Promise<void> {
		return this.view.focusNextPage(browserEvent, filter);
	}

	focusPreviousPage(browserEvent?: UIEvent, filter = this.focusNavigationFilter): Promise<void> {
		return this.view.focusPreviousPage(browserEvent, filter);
	}

	focusLast(browserEvent?: UIEvent, filter = this.focusNavigationFilter): void {
		this.view.focusLast(browserEvent, filter);
	}

	focusFirst(browserEvent?: UIEvent, filter = this.focusNavigationFilter): void {
		this.view.focusFirst(browserEvent, filter);
	}

	getFocus(): T[] {
		return this.focus.get();
	}

	reveal(location: TRef, relativeTop?: number): void {
		this.model.expandTo(location);

		const index = this.model.getListIndex(location);

		if (index === -1) {
			return;
		}

		this.view.reveal(index, relativeTop);
	}

	/**
	 * Returns the relative position of an element rendered in the list.
	 * Returns `null` if the element isn't *entirely* in the visible viewport.
	 */
	getRelativeTop(location: TRef): number | null {
		const index = this.model.getListIndex(location);

		if (index === -1) {
			return null;
		}

		return this.view.getRelativeTop(index);
	}

	// List

	private onLeftArrow(e: StandardKeyboardEvent): void {
		e.preventDefault();
		e.stopPropagation();

		const nodes = this.view.getFocusedElements();

		if (nodes.length === 0) {
			return;
		}

		const node = nodes[0];
		const location = this.model.getNodeLocation(node);
		const didChange = this.model.setCollapsed(location, true);

		if (!didChange) {
			const parentLocation = this.model.getParentNodeLocation(location);

			if (!parentLocation) {
				return;
			}

			const parentListIndex = this.model.getListIndex(parentLocation);

			this.view.reveal(parentListIndex);
			this.view.setFocus([parentListIndex]);
		}
	}

	private onRightArrow(e: StandardKeyboardEvent): void {
		e.preventDefault();
		e.stopPropagation();

		const nodes = this.view.getFocusedElements();

		if (nodes.length === 0) {
			return;
		}

		const node = nodes[0];
		const location = this.model.getNodeLocation(node);
		const didChange = this.model.setCollapsed(location, false);

		if (!didChange) {
			if (!node.children.some(child => child.visible)) {
				return;
			}

			const [focusedIndex] = this.view.getFocus();
			const firstChildIndex = focusedIndex + 1;

			this.view.reveal(firstChildIndex);
			this.view.setFocus([firstChildIndex]);
		}
	}

	private onSpace(e: StandardKeyboardEvent): void {
		e.preventDefault();
		e.stopPropagation();

		const nodes = this.view.getFocusedElements();

		if (nodes.length === 0) {
			return;
		}

		const node = nodes[0];
		const location = this.model.getNodeLocation(node);
		const recursive = e.browserEvent.altKey;

		this.model.setCollapsed(location, undefined, recursive);
	}

	protected abstract createModel(user: string, view: ISpliceable<ITreeNode<T, TFilterData>>, options: IAbstractTreeOptions<T, TFilterData>): ITreeModel<T, TFilterData, TRef>;

	navigate(start?: TRef): ITreeNavigator<T> {
		return new TreeNavigator(this.view, this.model, start);
	}

	dispose(): void {
		dispose(this.disposables);
		this.view.dispose();
	}
}

interface ITreeNavigatorView<T extends NonNullable<any>, TFilterData> {
	readonly length: number;
	element(index: number): ITreeNode<T, TFilterData>;
}

class TreeNavigator<T extends NonNullable<any>, TFilterData, TRef> implements ITreeNavigator<T> {

	private index: number;

	constructor(private view: ITreeNavigatorView<T, TFilterData>, private model: ITreeModel<T, TFilterData, TRef>, start?: TRef) {
		if (start) {
			this.index = this.model.getListIndex(start);
		} else {
			this.index = -1;
		}
	}

	current(): T | null {
		if (this.index < 0 || this.index >= this.view.length) {
			return null;
		}

		return this.view.element(this.index).element;
	}

	previous(): T | null {
		this.index--;
		return this.current();
	}

	next(): T | null {
		this.index++;
		return this.current();
	}

	first(): T | null {
		this.index = 0;
		return this.current();
	}

	last(): T | null {
		this.index = this.view.length - 1;
		return this.current();
	}
}


text:
package org.picocontainer.visitors;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.picocontainer.ComponentAdapter;
import org.picocontainer.ComponentFactory;
import org.picocontainer.Parameter;
import org.picocontainer.PicoContainer;
import org.picocontainer.PicoVerificationException;
import org.picocontainer.PicoVisitor;

/**
 * Visitor to verify {@link PicoContainer} instances. The visitor walks down the logical container hierarchy.
 *
 * @author Jörg Schaible
 */
public class VerifyingVisitor extends TraversalCheckingVisitor {

    private final List<RuntimeException> nestedVerificationExceptions;
    private final Set<ComponentAdapter> verifiedComponentAdapters;
    private final Set<ComponentFactory> verifiedComponentFactories;
    private final PicoVisitor componentAdapterCollector;
    private PicoContainer currentPico;

    /**
     * Construct a VerifyingVisitor.
     */
    public VerifyingVisitor() {
        nestedVerificationExceptions = new ArrayList<RuntimeException>();
        verifiedComponentAdapters = new HashSet<ComponentAdapter>();
        verifiedComponentFactories = new HashSet<ComponentFactory>();
        componentAdapterCollector = new ComponentAdapterCollector();
    }

    /**
     * Traverse through all components of the {@link PicoContainer} hierarchy and verify the components.
     *
     * @throws PicoVerificationException if some components could not be verified.
     * @see org.picocontainer.PicoVisitor#traverse(java.lang.Object)
     */
    public Object traverse(Object node) throws PicoVerificationException {
        nestedVerificationExceptions.clear();
        verifiedComponentAdapters.clear();
        try {
            super.traverse(node);
            if (!nestedVerificationExceptions.isEmpty()) {
                throw new PicoVerificationException(new ArrayList<RuntimeException>(nestedVerificationExceptions));
            }
        } finally {
            nestedVerificationExceptions.clear();
            verifiedComponentAdapters.clear();
        }
        return Void.TYPE;
    }

    public boolean visitContainer(PicoContainer pico) {
        super.visitContainer(pico);
        currentPico = pico;
        return CONTINUE_TRAVERSAL;
    }

    public void visitComponentAdapter(ComponentAdapter<?> componentAdapter) {
        super.visitComponentAdapter(componentAdapter);
        if (!verifiedComponentAdapters.contains(componentAdapter)) {
            try {
                componentAdapter.verify(currentPico);
            } catch (RuntimeException e) {
                nestedVerificationExceptions.add(e);
            }
            componentAdapter.accept(componentAdapterCollector);
        }

    }

    public void visitComponentFactory(ComponentFactory componentFactory) {
        super.visitComponentFactory(componentFactory);

        if (!verifiedComponentFactories.contains(componentFactory)) {
            try {
                componentFactory.verify(currentPico);
            } catch (RuntimeException e) {
                nestedVerificationExceptions.add(e);
            }
            componentFactory.accept(componentAdapterCollector);
        }

    }

    private class ComponentAdapterCollector implements PicoVisitor {
        // /CLOVER:OFF
        public Object traverse(Object node) {
            return null;
        }

        public boolean visitContainer(PicoContainer pico) {
            return CONTINUE_TRAVERSAL;
        }

        // /CLOVER:ON

        public void visitComponentAdapter(ComponentAdapter componentAdapter) {
            verifiedComponentAdapters.add(componentAdapter);
        }

        public void visitComponentFactory(ComponentFactory componentFactory) {
            verifiedComponentFactories.add(componentFactory);
        }

        public void visitParameter(Parameter parameter) {

        }
    }
}


text:
package interfaz;

import java.awt.BorderLayout;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;

import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.TargetDataLine;
import javax.swing.JFrame;
import javax.swing.JPanel;

@SuppressWarnings("serial")
public class Inicio extends JFrame{

/**
 * atributo que representa la relacion con la clase Fondo
 */
private Fondo fondo;
/**
 * atributo que representa la relacion con la clase InterfazPrincipal
 */
private InterfazPrincipal principal;
/**
 * atributo que representa la relacion con la clase InterfazOpciones
 */
private InterfazOpciones opciones;
/**
 * atributo que representa la musica
 */
private Clip music;

/**
 * Metodo: Constructor
 * Se encarga de inicializar los atributos de la clase Fondo
 */
public Inicio(){

setTitle("Risk");
setSize(1370,1370);

setLayout(new BorderLayout());
setDefaultCloseOperation(EXIT_ON_CLOSE);

fondo = new Fondo("Sources/Fondo.jpg", this);
add(fondo);

principal = new InterfazPrincipal();
opciones = new InterfazOpciones(this);
music = Sonido();
music.start();
}

/**
 * Metodo:main
 * Se encarga de Crear la Clase y d ehacerla visible
 * @param args
 */
public static void main(String[] args){
	Inicio ventana = new Inicio();
	ventana.setVisible(true);
	//Sonido();

}

/**
 * Metodo: Sonido
 * Se encarga de crear la musica
 * @return Clip con la musica
 */
@SuppressWarnings("resource")
public static Clip Sonido(){
	String sound = "Sources/Sonidos/SonidoInicial.wav";
	Clip musica = null;
	//boolean IT = true;
	try {

		@SuppressWarnings("unused")
		InputStream in = new FileInputStream(sound);
		AudioInputStream audio = AudioSystem.getAudioInputStream(new File("Sources/Sonidos/SonidoInicial.wav"));
		AudioFormat format = audio.getFormat();
		int gr = (int) (format.getFrameSize() * audio.getFrameLength());
		byte[] mySound = new byte[gr];
		DataLine.Info info = new DataLine.Info(Clip.class,format, gr);
		audio.read(mySound,0,gr);

		Clip clip = (Clip) AudioSystem.getLine(info);
		clip.open(format, mySound, 0, gr);
		//clip.start();
		//Thread.sleep(40000);

		//clip.stop();
		//if(Getss()){
		//clip.stop();
		//}
		musica = clip;
	} catch (Exception e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
	return musica;
}

public InterfazPrincipal getJuego(){
	return principal;
}

public InterfazOpciones getOpciones(){
	return opciones;
}

public Clip darSonido(){
	return music;
}
}


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

<title>F-Index</title>
<meta name="date" content="2013-12-26">
<link rel="stylesheet" type="text/css" href="../stylesheet.css" title="Style">

JavaScript is disabled on your browser.

Package

Class

Use

Tree

Deprecated

Index

Help

Prev Letter

Next Letter

Frames

No Frames

All Classes

C F R W

F

FileInputBitStream - Class in com.doetsch.io.bitwise

FileInputBitStream extends the functionality
 of FileInputStream by implementing the ability
 to read file input streams by bits.

FileInputBitStream(File) - Constructor for class com.doetsch.io.bitwise.FileInputBitStream

Instantiates a new FileInputBitStream

FileOutputBitStream - Class in com.doetsch.io.bitwise

FileOutputBitStream extends the functionality
 of FileOutputStream by implementing the ability
 to write out to file streams by bits.

FileOutputBitStream(File) - Constructor for class com.doetsch.io.bitwise.FileOutputBitStream

Instantiates a new FileOutputBitStream.

flush() - Method in class com.doetsch.io.bitwise.FileOutputBitStream

Flushes the output buffer, writing any unwritten
 bits.

C F R W

Package

Class

Use

Tree

Deprecated

Index

Help

Prev Letter

Next Letter

Frames

No Frames

All Classes


text:
<?php

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

class CreateFirmsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('firms', function (Blueprint $table) {
            $table->smallInteger('id', true);
            $table->integer('user_id');
            $table->string('name', 100);
            $table->string('slug')->nullable();
            $table->timestampsTz();
            $table->softDeletes();
            $table->string('logo', 45)->nullable();
            $table->string('website')->nullable();
            $table->string('headline')->nullable();
            $table->text('description')->nullable();
            $table->smallInteger('employees')->nullable();
            $table->smallInteger('founded')->nullable();
            $table->tinyInteger('is_agency')->default(0);
            $table->smallInteger('country_id')->nullable();
            $table->string('city')->nullable();
            $table->string('street')->nullable();
            $table->string('house', 50)->nullable();
            $table->string('postcode', 50)->nullable();
            $table->float('latitude')->nullable();
            $table->float('longitude')->nullable();

            $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
            $table->foreign('country_id')->references('id')->on('countries')->onDelete('no action');
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::drop('firms');
    }
}


text:
use_inline_resources

include Chef::Provider::WindowsFeature::Base
include Chef::Mixin::ShellOut
include Windows::Helper

def install_feature(_name)
  addsource = @new_resource.source ? "/LimitAccess /Source:\"#{@new_resource.source}\"" : ''
  addall = @new_resource.all ? '/All' : ''
  shell_out!("#{dism} /online /enable-feature /featurename:#{@new_resource.feature_name} /norestart #{addsource} #{addall}", returns: [0, 42, 127, 3010])
  # Reload ohai data
  reload_ohai_features_plugin(@new_resource.action, @new_resource.feature_name)
end

def remove_feature(_name)
  shell_out!("#{dism} /online /disable-feature /featurename:#{@new_resource.feature_name} /norestart", returns: [0, 42, 127, 3010])
  # Reload ohai data
  reload_ohai_features_plugin(@new_resource.action, @new_resource.feature_name)
end

def delete_feature(_name)
  if win_version.major_version >= 6 && win_version.minor_version >= 2
    shell_out!("#{dism} /online /disable-feature /featurename:#{@new_resource.feature_name} /Remove /norestart", returns: [0, 42, 127, 3010])
    # Reload ohai data
    reload_ohai_features_plugin(@new_resource.action, @new_resource.feature_name)
  else
    raise Chef::Exceptions::UnsupportedAction, "#{self} :delete action not support on #{win_version.sku}"
  end
end

def installed?
  @installed ||= begin
    install_ohai_plugin unless node['dism_features']

    # Compare against ohai plugin instead of costly dism run
    node['dism_features'].key?(@new_resource.feature_name) && node['dism_features'][@new_resource.feature_name] =~ /Enable/
  end
end

def available?
  @available ||= begin
    install_ohai_plugin unless node['dism_features']

    # Compare against ohai plugin instead of costly dism run
    node['dism_features'].key?(@new_resource.feature_name) && node['dism_features'][@new_resource.feature_name] !~ /with payload removed/
  end
end

def reload_ohai_features_plugin(take_action, feature_name)
  ohai "Reloading Dism_Features Plugin - Action #{take_action} of feature #{feature_name}" do
    action :reload
    plugin 'dism_features'
  end
end

def install_ohai_plugin
  Chef::Log.info("node['dism_features'] data missing. Installing the dism_features Ohai plugin")

  ohai_plugin 'dism_features' do
    compile_time true
    cookbook 'windows'
  end
end

private

# account for File System Redirector
# http://msdn.microsoft.com/en-us/library/aa384187(v=vs.85).aspx
def dism
  @dism ||= begin
    locate_sysnative_cmd('dism.exe')
  end
end


text:
package bibmup;

public class BibLibToMindMup {

	static public void main(String[] args) throws Exception {
		Config config = new Config();

		if(args.length < 2 ){
			System.err.println("Usage: java " + BibTeXLib.class + " <Input file> <Output file> [<Config file>]");

			System.exit(-1);
		}

		if (args.length == 3) {
			config = new Config(args[2]);
		}
		BibTeXLib db = new BibTeXLib(args[0], config);
		db.moreSpecific();
		if (config.prune > 0) {
			db.prune(config.prune);
		}
		MupTree tree = new MupTree(config, db);
		tree.writeMindMup(args[1]);
		System.out.println("done");

	}

}


text:
module MergePullRequest where

import qualified Github.PullRequests as Github
import Github.Auth
import Github.Data

main :: IO ()
main = do
  mergeResult  <- Github.updatePullRequest (OAuth "authtoken") "repoOwner" "repoName" 22 EditPullRequest
    { editPullRequestTitle = Just "Brand new title"
    , editPullRequestBody = Nothing
    , editPullRequestState = Just EditPullRequestStateClosed
    , editPullRequestBase = Nothing
    , editPullRequestMaintainerCanModify = Just True
    }
  case mergeResult of
       (Left err) -> putStrLn $ "Error: " ++ (show err)
       (Right dpr) -> putStrLn . show $ dpr


text:
static NSString *URLProtocolHandledKey = @"URLHasHandle";

@interface DMCustomURLSessionProtocol()<NSURLSessionDelegate,NSURLSessionDataDelegate>

@property (nonatomic,strong) NSURLSession *session;
@property (strong, nonatomic) NSMutableData *imageData;
@property (nonatomic) BOOL beginAppendData;

@end

@implementation DMCustomURLSessionProtocol

#pragma mark 初始化请求

+ (BOOL)canInitWithRequest:(NSURLRequest *)request
{

    //只处理http和https请求
    NSString *scheme = [[request URL] scheme];
    if ( (([scheme caseInsensitiveCompare:@"http"] == NSOrderedSame ||
           [scheme caseInsensitiveCompare:@"https"] == NSOrderedSame)) &&
        ([[request.URL absoluteString] hasSuffix:@"webp"]))
    {
        //看看是否已经处理过了,防止无限循环
        if ([NSURLProtocol propertyForKey:URLProtocolHandledKey inRequest:request]) {
            return NO;
        }
        return YES;
    }
    return NO;
}

+ (NSURLRequest *) canonicalRequestForRequest:(NSURLRequest *)request {
    return request;
}

#pragma mark 通信协议内容实现

- (void)startLoading
{
    NSMutableURLRequest *mutableReqeust = [[self request] mutableCopy];
    [NSURLProtocol setProperty:@YES forKey:URLProtocolHandledKey inRequest:mutableReqeust];

    NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
    self.session = [NSURLSession sessionWithConfiguration:config delegate:self delegateQueue:[NSOperationQueue currentQueue]];
    [[self.session dataTaskWithRequest:mutableReqeust] resume];

}

- (void)stopLoading
{
    [self.session invalidateAndCancel];
}

#pragma mark - dataDelegate
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task willPerformHTTPRedirection:(NSHTTPURLResponse *)response newRequest:(NSURLRequest *)newRequest completionHandler:(void (^)(NSURLRequest *))completionHandler
{
    NSMutableURLRequest *    redirectRequest;

    redirectRequest = [newRequest mutableCopy];
    [[self class] removePropertyForKey:URLProtocolHandledKey inRequest:redirectRequest];

    [[self client] URLProtocol:self wasRedirectedToRequest:redirectRequest redirectResponse:response];

    [self.session invalidateAndCancel];
    [[self client] URLProtocol:self didFailWithError:[NSError errorWithDomain:NSCocoaErrorDomain code:NSUserCancelledError userInfo:nil]];
}

- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition disposition))completionHandler
{
    [self.client URLProtocol:self didReceiveResponse:response cacheStoragePolicy:NSURLCacheStorageNotAllowed];
    NSInteger expected = response.expectedContentLength > 0 ? (NSInteger)response.expectedContentLength : 0;
    self.imageData = [[NSMutableData alloc] initWithCapacity:expected];
    if (completionHandler) {
        completionHandler(NSURLSessionResponseAllow);
    }

}

- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data{

    if ([dataTask.currentRequest.URL.absoluteString hasSuffix:@"webp"]) {
        self.beginAppendData = YES;
        [self.imageData appendData:data];
    }
    if (!_beginAppendData) {
        [self.client URLProtocol:self didLoadData:data];
    }
}

- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(nullable NSError *)error{

    if (error) {

        [self.client URLProtocol:self didFailWithError:error];
    }else{
        if ([task.currentRequest.URL.absoluteString hasSuffix:@"webp"]) {
            NSLog(@"webp---%@",task.currentRequest.URL);

            UIImage *imgData = [UIImage sd_imageWithData:self.imageData];
            NSData *transData = UIImageJPEGRepresentation(imgData, 0.8f);
            self.beginAppendData = NO;
            self.imageData = nil;
            [self.client URLProtocol:self didLoadData:transData];
        }
        [self.client URLProtocolDidFinishLoading:self];
    }

}

@end


text:
//
//  XYSVoicePlayerViewController.m
//  imitationOfBSBDJ
//
//  Created by 徐烨晟 on 16/7/25.
//  Copyright © 2016年 徐烨晟. All rights reserved.
//

#import "XYSVoicePlayerViewController.h"
#import "XYSTopicModel.h"
#import "XYSCircularProgressView.h"
#import <KRVideoPlayerController.h>
#import <UIImageView+WebCache.h>
#import <SVProgressHUD.h>
@interface XYSVoicePlayerViewController ()
@property (weak, nonatomic) IBOutlet UIScrollView *contentScrollView;
/** 显示的图片*/
@property (weak,nonatomic)UIImageView *pictureView;
@property (weak, nonatomic) IBOutlet XYSCircularProgressView *progressView;
@property (strong,nonatomic)KRVideoPlayerController *voicePlayer;
@end

@implementation XYSVoicePlayerViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    SVProgressHUD.minimumDismissTimeInterval = 1.0;

    CGFloat screenW = [UIScreen mainScreen].bounds.size.width;
    CGFloat screenH = [UIScreen mainScreen].bounds.size.height;

    [self.progressView setProgress:self.topicModel.progressPerc animated:YES];
    //显示图片
    UIImageView *imageView = [[UIImageView alloc]init];
    [imageView sd_setImageWithURL:[NSURL URLWithString:self.topicModel.large_image]placeholderImage:nil options:0 progress:^(NSInteger receivedSize, NSInteger expectedSize) {
        self.progressView.hidden = NO;
        self.progressView.roundedCorners = 2.0;
        self.topicModel.progressPerc =1.0 *receivedSize/expectedSize;

        [self.progressView setProgress:self.topicModel.progressPerc animated:NO];
    } completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {
        self.progressView.hidden = YES;
    }];
    [self.contentScrollView addSubview:imageView];
    self.pictureView = imageView;

    CGFloat pictureW = screenW;
    CGFloat pictureH = self.topicModel.height*pictureW/self.topicModel.width;

    self.pictureView.frame = CGRectMake(0, 0, pictureW, pictureH);
    //图片大于屏幕
    if (pictureH > screenH) {
        self.contentScrollView.contentSize = CGSizeMake(0, pictureH);
        self.contentScrollView.minimumZoomScale = 1;
        self.contentScrollView.maximumZoomScale = self.topicModel.width/pictureW;
    }else//小于屏幕,居中
    {
        self.pictureView.xys_centerY = screenH*0.5;
    }

    self.voicePlayer = [[KRVideoPlayerController alloc]initWithFrame:self.pictureView.frame];
    //修改voicePlayer的背景为透明。
    [self.voicePlayer.view setValue:[UIColor clearColor] forKeyPath:@"backgroundColor"];

    self.voicePlayer.contentURL = [NSURL URLWithString:self.topicModel.voiceuri];
    __weak __typeof (self) weakSelf = self;
    [self.voicePlayer setDimissCompleteBlock:^{
        [weakSelf back];
    }];
    [self.voicePlayer showInWindow];

}

- (IBAction)back {
    [self.voicePlayer stop];
    [self.voicePlayer dismiss];
    [self dismissViewControllerAnimated:YES completion:nil];
}

@end


text:
ACCEPTED

#### According to
Index Fungorum

#### Published in
Boln Soc. Venez. Cienc. Nat. 8: 40 (1942)

#### Original name
Cercospora centrosematis Chupp & A.S. Mull.

### Remarks
null