text:
package org.elasticsearch.cluster.metadata;

import com.carrotsearch.hppc.cursors.ObjectCursor;
import com.carrotsearch.hppc.cursors.ObjectObjectCursor;
import com.google.common.base.Charsets;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.apache.lucene.util.CollectionUtil;
import org.apache.lucene.util.IOUtils;
import org.elasticsearch.ElasticsearchException;
import org.elasticsearch.Version;
import org.elasticsearch.action.admin.indices.alias.Alias;
import org.elasticsearch.action.admin.indices.create.CreateIndexClusterStateUpdateRequest;
import org.elasticsearch.cluster.AckedClusterStateUpdateTask;
import org.elasticsearch.cluster.ClusterService;
import org.elasticsearch.cluster.ClusterState;
import org.elasticsearch.cluster.ack.ClusterStateUpdateListener;
import org.elasticsearch.cluster.ack.ClusterStateUpdateResponse;
import org.elasticsearch.cluster.block.ClusterBlock;
import org.elasticsearch.cluster.block.ClusterBlocks;
import org.elasticsearch.cluster.node.DiscoveryNode;
import org.elasticsearch.cluster.routing.RoutingTable;
import org.elasticsearch.cluster.routing.allocation.AllocationService;
import org.elasticsearch.cluster.routing.allocation.RoutingAllocation;
import org.elasticsearch.common.Nullable;
import org.elasticsearch.common.Priority;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.component.AbstractComponent;
import org.elasticsearch.common.compress.CompressedString;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.io.Streams;
import org.elasticsearch.common.regex.Regex;
import org.elasticsearch.common.settings.ImmutableSettings;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.common.xcontent.XContentHelper;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.env.Environment;
import org.elasticsearch.index.Index;
import org.elasticsearch.index.mapper.DocumentMapper;
import org.elasticsearch.index.mapper.MapperParsingException;
import org.elasticsearch.index.mapper.MapperService;
import org.elasticsearch.index.query.IndexQueryParserService;
import org.elasticsearch.index.service.IndexService;
import org.elasticsearch.indices.IndexAlreadyExistsException;
import org.elasticsearch.indices.IndicesService;
import org.elasticsearch.indices.InvalidIndexNameException;
import org.elasticsearch.river.RiverIndexName;
import org.elasticsearch.threadpool.ThreadPool;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.util.Comparator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;

import static org.elasticsearch.cluster.metadata.IndexMetaData.*;
import static org.elasticsearch.common.settings.ImmutableSettings.settingsBuilder;

/**
 * Service responsible for submitting create index requests
 */
public class MetaDataCreateIndexService extends AbstractComponent {

    private final Environment environment;
    private final ThreadPool threadPool;
    private final ClusterService clusterService;
    private final IndicesService indicesService;
    private final AllocationService allocationService;
    private final MetaDataService metaDataService;
    private final Version version;
    private final String riverIndexName;
    private final AliasValidator aliasValidator;

    @Inject
    public MetaDataCreateIndexService(Settings settings, Environment environment, ThreadPool threadPool, ClusterService clusterService, IndicesService indicesService,
                                      AllocationService allocationService, MetaDataService metaDataService, Version version, @RiverIndexName String riverIndexName,
                                      AliasValidator aliasValidator) {
        super(settings);
        this.environment = environment;
        this.threadPool = threadPool;
        this.clusterService = clusterService;
        this.indicesService = indicesService;
        this.allocationService = allocationService;
        this.metaDataService = metaDataService;
        this.version = version;
        this.riverIndexName = riverIndexName;
        this.aliasValidator = aliasValidator;
    }

    public void createIndex(final CreateIndexClusterStateUpdateRequest request, final ClusterStateUpdateListener listener) {
        ImmutableSettings.Builder updatedSettingsBuilder = ImmutableSettings.settingsBuilder();
        for (Map.Entry<String, String> entry : request.settings().getAsMap().entrySet()) {
            if (!entry.getKey().startsWith("index.")) {
                updatedSettingsBuilder.put("index." + entry.getKey(), entry.getValue());
            } else {
                updatedSettingsBuilder.put(entry.getKey(), entry.getValue());
            }
        }
        request.settings(updatedSettingsBuilder.build());

        // we lock here, and not within the cluster service callback since we don't want to
        // block the whole cluster state handling
        final Semaphore mdLock = metaDataService.indexMetaDataLock(request.index());

        // quick check to see if we can acquire a lock, otherwise spawn to a thread pool
        if (mdLock.tryAcquire()) {
            createIndex(request, listener, mdLock);
            return;
        }

        threadPool.executor(ThreadPool.Names.MANAGEMENT).execute(new Runnable() {
            @Override
            public void run() {
                try {
                    if (!mdLock.tryAcquire(request.masterNodeTimeout().nanos(), TimeUnit.NANOSECONDS)) {
                        listener.onFailure(new ProcessClusterEventTimeoutException(request.masterNodeTimeout(), "acquire index lock"));
                        return;
                    }
                } catch (InterruptedException e) {
                    Thread.interrupted();
                    listener.onFailure(e);
                    return;
                }

                createIndex(request, listener, mdLock);
            }
        });
    }

    public void validateIndexName(String index, ClusterState state) throws ElasticsearchException {
        if (state.routingTable().hasIndex(index)) {
            throw new IndexAlreadyExistsException(new Index(index));
        }
        if (state.metaData().hasIndex(index)) {
            throw new IndexAlreadyExistsException(new Index(index));
        }
        if (!Strings.validFileName(index)) {
            throw new InvalidIndexNameException(new Index(index), index, "must not contain the following characters " + Strings.INVALID_FILENAME_CHARS);
        }
        if (index.contains("#")) {
            throw new InvalidIndexNameException(new Index(index), index, "must not contain '#'");
        }
        if (!index.equals(riverIndexName) && index.charAt(0) == '_') {
            throw new InvalidIndexNameException(new Index(index), index, "must not start with '_'");
        }
        if (!index.toLowerCase(Locale.ROOT).equals(index)) {
            throw new InvalidIndexNameException(new Index(index), index, "must be lowercase");
        }
        if (state.metaData().aliases().containsKey(index)) {
            throw new InvalidIndexNameException(new Index(index), index, "already exists as alias");
        }
    }

    private void createIndex(final CreateIndexClusterStateUpdateRequest request, final ClusterStateUpdateListener listener, final Semaphore mdLock) {
        clusterService.submitStateUpdateTask("create-index [" + request.index() + "], cause [" + request.cause() + "]", Priority.URGENT, new AckedClusterStateUpdateTask() {

            @Override
            public boolean mustAck(DiscoveryNode discoveryNode) {
                return true;
            }

            @Override
            public void onAllNodesAcked(@Nullable Throwable t) {
                mdLock.release();
                listener.onResponse(new ClusterStateUpdateResponse(true));
            }

            @Override
            public void onAckTimeout() {
                mdLock.release();
                listener.onResponse(new ClusterStateUpdateResponse(false));
            }

            @Override
            public TimeValue ackTimeout() {
                return request.ackTimeout();
            }

            @Override
            public TimeValue timeout() {
                return request.masterNodeTimeout();
            }

            @Override
            public void onFailure(String source, Throwable t) {
                mdLock.release();
                listener.onFailure(t);
            }

            @Override
            public ClusterState execute(ClusterState currentState) throws Exception {
                boolean indexCreated = false;
                String failureReason = null;
                try {
                    validate(request, currentState);

                    for (Alias alias : request.aliases()) {
                        aliasValidator.validateAlias(alias, request.index(), currentState.metaData());
                    }

                    // we only find a template when its an API call (a new index)
                    // find templates, highest order are better matching
                    List<IndexTemplateMetaData> templates = findTemplates(request, currentState);

                    Map<String, Custom> customs = Maps.newHashMap();

                    // add the request mapping
                    Map<String, Map<String, Object>> mappings = Maps.newHashMap();

                    Map<String, AliasMetaData> templatesAliases = Maps.newHashMap();

                    for (Map.Entry<String, String> entry : request.mappings().entrySet()) {
                        mappings.put(entry.getKey(), parseMapping(entry.getValue()));
                    }

                    for (Map.Entry<String, Custom> entry : request.customs().entrySet()) {
                        customs.put(entry.getKey(), entry.getValue());
                    }

                    // apply templates, merging the mappings into the request mapping if exists
                    for (IndexTemplateMetaData template : templates) {
                        for (ObjectObjectCursor<String, CompressedString> cursor : template.mappings()) {
                            if (mappings.containsKey(cursor.key)) {
                                XContentHelper.mergeDefaults(mappings.get(cursor.key), parseMapping(cursor.value.string()));
                            } else {
                                mappings.put(cursor.key, parseMapping(cursor.value.string()));
                            }
                        }
                        // handle custom
                        for (ObjectObjectCursor<String, Custom> cursor : template.customs()) {
                            String type = cursor.key;
                            IndexMetaData.Custom custom = cursor.value;
                            IndexMetaData.Custom existing = customs.get(type);
                            if (existing == null) {
                                customs.put(type, custom);
                            } else {
                                IndexMetaData.Custom merged = IndexMetaData.lookupFactorySafe(type).merge(existing, custom);
                                customs.put(type, merged);
                            }
                        }
                        //handle aliases
                        for (ObjectObjectCursor<String, AliasMetaData> cursor : template.aliases()) {
                            AliasMetaData aliasMetaData = cursor.value;
                            //if an alias with same name came with the create index request itself,
                            // ignore this one taken from the index template
                            if (request.aliases().contains(new Alias(aliasMetaData.alias()))) {
                                continue;
                            }
                            //if an alias with same name was already processed, ignore this one
                            if (templatesAliases.containsKey(cursor.key)) {
                                continue;
                            }

                            //Allow templatesAliases to be templated by replacing a token with the name of the index that we are applying it to
                            if (aliasMetaData.alias().contains("{index}")) {
                                String templatedAlias = aliasMetaData.alias().replace("{index}", request.index());
                                aliasMetaData = AliasMetaData.newAliasMetaData(aliasMetaData, templatedAlias);
                            }

                            aliasValidator.validateAliasMetaData(aliasMetaData, request.index(), currentState.metaData());
                            templatesAliases.put(aliasMetaData.alias(), aliasMetaData);
                        }
                    }

                    // now add config level mappings
                    File mappingsDir = new File(environment.configFile(), "mappings");
                    if (mappingsDir.exists() && mappingsDir.isDirectory()) {
                        // first index level
                        File indexMappingsDir = new File(mappingsDir, request.index());
                        if (indexMappingsDir.exists() && indexMappingsDir.isDirectory()) {
                            addMappings(mappings, indexMappingsDir);
                        }

                        // second is the _default mapping
                        File defaultMappingsDir = new File(mappingsDir, "_default");
                        if (defaultMappingsDir.exists() && defaultMappingsDir.isDirectory()) {
                            addMappings(mappings, defaultMappingsDir);
                        }
                    }

                    ImmutableSettings.Builder indexSettingsBuilder = settingsBuilder();
                    // apply templates, here, in reverse order, since first ones are better matching
                    for (int i = templates.size() - 1; i >= 0; i--) {
                        indexSettingsBuilder.put(templates.get(i).settings());
                    }
                    // now, put the request settings, so they override templates
                    indexSettingsBuilder.put(request.settings());

                    if (indexSettingsBuilder.get(SETTING_NUMBER_OF_SHARDS) == null) {
                        if (request.index().equals(riverIndexName)) {
                            indexSettingsBuilder.put(SETTING_NUMBER_OF_SHARDS, settings.getAsInt(SETTING_NUMBER_OF_SHARDS, 1));
                        } else {
                            indexSettingsBuilder.put(SETTING_NUMBER_OF_SHARDS, settings.getAsInt(SETTING_NUMBER_OF_SHARDS, 5));
                        }
                    }
                    if (indexSettingsBuilder.get(SETTING_NUMBER_OF_REPLICAS) == null) {
                        if (request.index().equals(riverIndexName)) {
                            indexSettingsBuilder.put(SETTING_NUMBER_OF_REPLICAS, settings.getAsInt(SETTING_NUMBER_OF_REPLICAS, 1));
                        } else {
                            indexSettingsBuilder.put(SETTING_NUMBER_OF_REPLICAS, settings.getAsInt(SETTING_NUMBER_OF_REPLICAS, 1));
                        }
                    }

                    if (settings.get(SETTING_AUTO_EXPAND_REPLICAS) != null && indexSettingsBuilder.get(SETTING_AUTO_EXPAND_REPLICAS) == null) {
                        indexSettingsBuilder.put(SETTING_AUTO_EXPAND_REPLICAS, settings.get(SETTING_AUTO_EXPAND_REPLICAS));
                    }

                    if (indexSettingsBuilder.get(SETTING_VERSION_CREATED) == null) {
                        indexSettingsBuilder.put(SETTING_VERSION_CREATED, version);
                    }
                    indexSettingsBuilder.put(SETTING_UUID, Strings.randomBase64UUID());

                    Settings actualIndexSettings = indexSettingsBuilder.build();

                    // Set up everything, now locally create the index to see that things are ok, and apply

                    // create the index here (on the master) to validate it can be created, as well as adding the mapping
                    indicesService.createIndex(request.index(), actualIndexSettings, clusterService.localNode().id());
                    indexCreated = true;
                    // now add the mappings
                    IndexService indexService = indicesService.indexServiceSafe(request.index());
                    MapperService mapperService = indexService.mapperService();
                    // first, add the default mapping
                    if (mappings.containsKey(MapperService.DEFAULT_MAPPING)) {
                        try {
                            mapperService.merge(MapperService.DEFAULT_MAPPING, new CompressedString(XContentFactory.jsonBuilder().map(mappings.get(MapperService.DEFAULT_MAPPING)).string()), false);
                        } catch (Exception e) {
                            failureReason = "failed on parsing default mapping on index creation";
                            throw new MapperParsingException("mapping [" + MapperService.DEFAULT_MAPPING + "]", e);
                        }
                    }
                    for (Map.Entry<String, Map<String, Object>> entry : mappings.entrySet()) {
                        if (entry.getKey().equals(MapperService.DEFAULT_MAPPING)) {
                            continue;
                        }
                        try {
                            // apply the default here, its the first time we parse it
                            mapperService.merge(entry.getKey(), new CompressedString(XContentFactory.jsonBuilder().map(entry.getValue()).string()), true);
                        } catch (Exception e) {
                            failureReason = "failed on parsing mappings on index creation";
                            throw new MapperParsingException("mapping [" + entry.getKey() + "]", e);
                        }
                    }

                    IndexQueryParserService indexQueryParserService = indexService.queryParserService();
                    for (Alias alias : request.aliases()) {
                        if (Strings.hasLength(alias.filter())) {
                            aliasValidator.validateAliasFilter(alias.name(), alias.filter(), indexQueryParserService);
                        }
                    }
                    for (AliasMetaData aliasMetaData : templatesAliases.values()) {
                        if (aliasMetaData.filter() != null) {
                            aliasValidator.validateAliasFilter(aliasMetaData.alias(), aliasMetaData.filter().uncompressed(), indexQueryParserService);
                        }
                    }

                    // now, update the mappings with the actual source
                    Map<String, MappingMetaData> mappingsMetaData = Maps.newHashMap();
                    for (DocumentMapper mapper : mapperService) {
                        MappingMetaData mappingMd = new MappingMetaData(mapper);
                        mappingsMetaData.put(mapper.type(), mappingMd);
                    }

                    final IndexMetaData.Builder indexMetaDataBuilder = IndexMetaData.builder(request.index()).settings(actualIndexSettings);
                    for (MappingMetaData mappingMd : mappingsMetaData.values()) {
                        indexMetaDataBuilder.putMapping(mappingMd);
                    }

                    for (AliasMetaData aliasMetaData : templatesAliases.values()) {
                        indexMetaDataBuilder.putAlias(aliasMetaData);
                    }
                    for (Alias alias : request.aliases()) {
                        AliasMetaData aliasMetaData = AliasMetaData.builder(alias.name()).filter(alias.filter())
                                .indexRouting(alias.indexRouting()).searchRouting(alias.searchRouting()).build();
                        indexMetaDataBuilder.putAlias(aliasMetaData);
                    }

                    for (Map.Entry<String, Custom> customEntry : customs.entrySet()) {
                        indexMetaDataBuilder.putCustom(customEntry.getKey(), customEntry.getValue());
                    }

                    indexMetaDataBuilder.state(request.state());

                    final IndexMetaData indexMetaData;
                    try {
                        indexMetaData = indexMetaDataBuilder.build();
                    } catch (Exception e) {
                        failureReason = "failed to build index metadata";
                        throw e;
                    }

                    MetaData newMetaData = MetaData.builder(currentState.metaData())
                            .put(indexMetaData, false)
                            .build();

                    logger.info("[{}] creating index, cause [{}], shards [{}]/[{}], mappings {}", request.index(), request.cause(), indexMetaData.numberOfShards(), indexMetaData.numberOfReplicas(), mappings.keySet());

                    ClusterBlocks.Builder blocks = ClusterBlocks.builder().blocks(currentState.blocks());
                    if (!request.blocks().isEmpty()) {
                        for (ClusterBlock block : request.blocks()) {
                            blocks.addIndexBlock(request.index(), block);
                        }
                    }
                    if (request.state() == State.CLOSE) {
                        blocks.addIndexBlock(request.index(), MetaDataIndexStateService.INDEX_CLOSED_BLOCK);
                    }

                    ClusterState updatedState = ClusterState.builder(currentState).blocks(blocks).metaData(newMetaData).build();

                    if (request.state() == State.OPEN) {
                        RoutingTable.Builder routingTableBuilder = RoutingTable.builder(updatedState.routingTable())
                                .addAsNew(updatedState.metaData().index(request.index()));
                        RoutingAllocation.Result routingResult = allocationService.reroute(ClusterState.builder(updatedState).routingTable(routingTableBuilder).build());
                        updatedState = ClusterState.builder(updatedState).routingResult(routingResult).build();
                    }
                    return updatedState;
                } finally {
                    if (indexCreated) {
                        // Index was already partially created - need to clean up
                        indicesService.removeIndex(request.index(), failureReason != null ? failureReason : "failed to create index");
                    }
                }
            }

            @Override
            public void clusterStateProcessed(String source, ClusterState oldState, ClusterState newState) {
            }
        });
    }

    private Map<String, Object> parseMapping(String mappingSource) throws Exception {
        return XContentFactory.xContent(mappingSource).createParser(mappingSource).mapAndClose();
    }

    private void addMappings(Map<String, Map<String, Object>> mappings, File mappingsDir) {
        File[] mappingsFiles = mappingsDir.listFiles();
        for (File mappingFile : mappingsFiles) {
            if (mappingFile.isHidden()) {
                continue;
            }
            int lastDotIndex = mappingFile.getName().lastIndexOf('.');
            String mappingType = lastDotIndex != -1 ? mappingFile.getName().substring(0, lastDotIndex) : mappingFile.getName();
            try {
                String mappingSource = Streams.copyToString(new InputStreamReader(new FileInputStream(mappingFile), Charsets.UTF_8));
                if (mappings.containsKey(mappingType)) {
                    XContentHelper.mergeDefaults(mappings.get(mappingType), parseMapping(mappingSource));
                } else {
                    mappings.put(mappingType, parseMapping(mappingSource));
                }
            } catch (Exception e) {
                logger.warn("failed to read / parse mapping [" + mappingType + "] from location [" + mappingFile + "], ignoring...", e);
            }
        }
    }

    private List<IndexTemplateMetaData> findTemplates(CreateIndexClusterStateUpdateRequest request, ClusterState state) {
        List<IndexTemplateMetaData> templates = Lists.newArrayList();
        for (ObjectCursor<IndexTemplateMetaData> cursor : state.metaData().templates().values()) {
            IndexTemplateMetaData template = cursor.value;
            if (Regex.simpleMatch(template.template(), request.index())) {
                templates.add(template);
            }
        }

        // see if we have templates defined under config
        File templatesDir = new File(environment.configFile(), "templates");
        if (templatesDir.exists() && templatesDir.isDirectory()) {
            File[] templatesFiles = templatesDir.listFiles();
            if (templatesFiles != null) {
                for (File templatesFile : templatesFiles) {
                    XContentParser parser = null;
                    try {
                        byte[] templatesData = Streams.copyToByteArray(templatesFile);
                        parser = XContentHelper.createParser(templatesData, 0, templatesData.length);
                        IndexTemplateMetaData template = IndexTemplateMetaData.Builder.fromXContent(parser);
                        if (Regex.simpleMatch(template.template(), request.index())) {
                            templates.add(template);
                        }
                    } catch (Exception e) {
                        logger.warn("[{}] failed to read template [{}] from config", e, request.index(), templatesFile.getAbsolutePath());
                    } finally {
                        IOUtils.closeWhileHandlingException(parser);
                    }
                }
            }
        }

        CollectionUtil.timSort(templates, new Comparator<IndexTemplateMetaData>() {
            @Override
            public int compare(IndexTemplateMetaData o1, IndexTemplateMetaData o2) {
                return o2.order() - o1.order();
            }
        });
        return templates;
    }

    private void validate(CreateIndexClusterStateUpdateRequest request, ClusterState state) throws ElasticsearchException {
        validateIndexName(request.index(), state);
    }
}


text:
<?xml version="1.0" encoding="ascii"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
          "DTD/xhtml1-transitional.dtd">

  <title>Identifier Index</title>
  <link rel="stylesheet" href="epydoc.css" type="text/css" />

         Trees

         Indices

         Help

LLDB python API

[hide private]

[frames] | no frames]

Identifier Index

[
 A
 B
 C
 D
 E
 F
 G
 H
 I
 J
 K
 L
 M
 N
 O
 P
 Q
 R
 S
 T
 U
 V
 W
 X
  Y
  Z
 _
]

P

parent

(in SBBlock)
platform

(in SBTarget)
process

(in SBThread)

parent

(in SBFrame)
platform_file

(in SBModule)
process

(in SBValue)

parent

(in stdmap_iterator_node)
Print()

(in SBCommandReturnObject)
process

(in lldb)

parent()

(in StdMapSynthProvider)
Print()

(in SBInstruction)
prologue_size

(in SBFunction)

ParentProcessIDIsValid()

(in SBAttachInfo)
Print()

(in SBInstructionList)
prologue_size

(in SBSymbol)

path

(in SBValue)
Print()

(in SBStream)
Put()

(in SBPlatform)

pattern

(in re_compile_type)
print_module_section()

(in lldb.utils.symbolication)
PutCString()

(in SBCommandReturnObject)

pc

(in SBFrame)
print_module_section_data()

(in lldb.utils.symbolication)
PutError()

(in SBCommandReturnObject)

PeekAtNextEvent()

(in SBListener)
print_module_sections()

(in lldb.utils.symbolication)
PutOutput()

(in SBCommandReturnObject)

PeekAtNextEventForBroadcaster()

(in SBListener)
print_module_symbols()

(in lldb.utils.symbolication)
PutSTDIN()

(in SBProcess)

PeekAtNextEventForBroadcasterWithType()

(in SBListener)
process

(in SBExecutionContext)
PythonObjectSyntheticChildProvider

(in lldb.formatters.synth)

Persist()

(in SBValue)
process

(in SBTarget)

         Trees

         Indices

         Help

LLDB python API

    Generated by Epydoc 3.0.1 on Fri Oct 14 13:55:20 2016

      http://epydoc.sourceforge.net

redpajama_set_name: RedPajamaGithub


text:
layout: leaf-node
title: "MIT OCW: The Nature of Constructionist Learning"
title-url: "https://ocw.mit.edu/courses/media-arts-and-sciences/mas-962-the-nature-of-constructionist-learning-spring-2003/"
author: "Bakhtiar Mikhak"
groups: pedagogical-styles
categories: constructionism
topics: online-courses-and-textbooks
summary: >
    From the course description: ""This course examines the philosophical and theoretical
    foundations of constructionism as a paradigm for formulating and evaluating new theories
    for learning and approaches to education. One of the goals of this course is to help new
    learning researchers situate their work within the constructionist framework through
    readings and projects that will focus on the rich interplay between the process of knowledge
    construction and the development and co-evolution of ideas, learners, tools, and contexts.""
cite: >
    Mikhak, B. (2017).  MIT OCW: The Nature of Constructionist Learning. Massachusetts Institute
    of Technology (MIT) Open Course Ware (OCW). Retrieved April 19, 2017
    from: https://ocw.mit.edu/courses/media-arts-and-sciences/mas-962-the-nature-of-constructionist-learning-spring-2003/
pub-date: 2017-04-19
added-date: 2017-04-19
resource-type: external-page
---


text:
module TZInfo
  module Data
    module Definitions
      module America
        module Rosario
          include TimezoneDefinition

          linked_timezone 'America/Rosario', 'America/Argentina/Cordoba'
        end
      end
    end
  end
end


text:
package de.upb.s2cx.event;

public class ElementEvent implements IBufferedEvent {
	private String name;
	private boolean start;

	public ElementEvent(String name, boolean start) {
		super();
		this.name = name;
		this.start = start;
	}

	@Override
	public void fire(IEventHandler exec) {
		exec.onElement(name, start);
	}

}


text:
<?php

namespace app\models;

use Yii;
use yii\base\Model;
use yii\data\ActiveDataProvider;
use app\models\Subproyectos;

/**
 * SubproyectosSearch represents the model behind the search form about `app\models\Subproyectos`.
 */
class SubproyectosSearch extends Subproyectos
{
    /**
     * @inheritdoc
     */
    public function rules()
    {
        return [
            [['id', 'id_proyecto'], 'integer'],
            [['evidencias', 'fecha_inicio', 'fecha_fin'], 'safe'],
        ];
    }

    /**
     * @inheritdoc
     */
    public function scenarios()
    {
        // bypass scenarios() implementation in the parent class
        return Model::scenarios();
    }

    /**
     * Creates data provider instance with search query applied
     *
     * @param array $params
     *
     * @return ActiveDataProvider
     */
    public function search($params)
    {
        $query = Subproyectos::find();

        $dataProvider = new ActiveDataProvider([
            'query' => $query,
        ]);

        $this->load($params);

        if (!$this->validate()) {
            // uncomment the following line if you do not want to return any records when validation fails
            // $query->where('0=1');
            return $dataProvider;
        }

        $query->andFilterWhere([
            'id' => $this->id,
            'id_proyecto' => $this->id_proyecto,
        ]);
        if (!empty($this->fecha_inicio)) {
            $query->andFilterWhere(['between', 'fecha_inicio', $this->fecha_inicio . '-01-01', $this->fecha_inicio . '-12-31']);
        }
        if (!empty($this->fecha_fin)) {
            $query->andFilterWhere(['between', 'fecha_fin', $this->fecha_fin . '-01-01', $this->fecha_fin . '-12-31']);
        }

        $query->andFilterWhere(['like', 'evidencias', $this->evidencias]);

        return $dataProvider;
    }
}


text:
..
..
.. Licensed under the Apache License, Version 2.0 (the "License");
.. you may not use this file except in compliance with the License.
.. You may obtain a copy of the License at
..
..     http://www.apache.org/licenses/LICENSE-2.0
..
.. Unless required by applicable law or agreed to in writing, software
.. distributed under the License is distributed on an "AS IS" BASIS,
.. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
.. See the License for the specific language governing permissions and
.. limitations under the License.
..

*****************************
Traffic Server Administration
*****************************
Installing Traffic Server
=========================

#.  Get the Traffic Server RPM and the astats RPM.

    Sample command: ::

        wget http://traffic-control-cdn.net/downloads/1.7.0/RELEASE-1.7.0/trafficserver-5.3.2-759.ee14bbe.el6.x86_64.rpm
        wget http://traffic-control-cdn.net/downloads/1.6.1/RELEASE-1.6.1/astats_over_http-1.2-8.el6.x86_64.rpm

    (astats was not released as part of 1.7, so in this examples 1.6.1 was used)
#.  Install Traffic Server and astats: ::

        sudo yum -y install trafficserver-*.rpm astats_over_http*.rpm

#.  Add the server using the Traffic Ops web interface:

    #. Select **Servers**.
    #. Scroll to the bottom of the page and click **Add Server**.
    #. Complete the "Required Info:" section:
        * Set 'Interface Name' to the name of the interface from which traffic server delivers content.
        * Set 'Type' to 'MID' or 'EDGE'.

    #. Click **Submit**.
    #. Click **Save**.
    #. Click **Online Server**.
    #. Verify that the server status is now listed as **Reported**

#.  Install the ORT script and run it in 'badass' mode to create the initial configuration, see :ref:`reference-traffic-ops-ort`

#.  Start the service: ``sudo service trafficserver start``

#.  Configure traffic server to start automatically: ``sudo chkconfig trafficserver on``

#.  Verify that the installation is good:

    #. Make sure that the service is running: ``sudo service trafficserver status``

    #. Assuming a traffic monitor is already installed, browse to it, and verify that the traffic server appears in the "Cahce States" table, in white.

.. _reference-traffic-ops-ort:

Configuring Traffic Server
==========================
All of the Traffic Server application configuration files are generated by Traffic Ops and installed by way of the traffic_ops_ort.pl script.
The traffic_ops_ort.pl should be installed on all caches (by puppet or other non Traffic Ops means), usually in /opt/ort. It is used to do the initial install of the config files when the cache is being deployed, and to keep the config files up to date when the cache is already in service.  The usage message of the script is shown below: ::

    $ sudo /opt/ort/traffic_ops_ort.pl
    Thu May 26 15:52:11 UTC 2016
    ====-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-====
    Usage: ./traffic_ops_ort.pl <Mode> <Log_Level> <Traffic_Ops_URL> <Traffic_Ops_Login> [optional flags]
      <Mode> = interactive - asks questions during config process.
      <Mode> = report - prints config differences and exits.
      <Mode> = badass - attempts to fix all config differences that it can.
      <Mode> = syncds - syncs delivery services with what is configured in Traffic Ops.

      <Log_Level> => ALL, TRACE, DEBUG, INFO, WARN, ERROR, FATAL, NONE

      <Traffic_Ops_URL> = URL to Traffic Ops host. Example: https://trafficops.company.net

      <Traffic_Ops_Login> => Example: 'username:password'

      [optional flags]:
        dispersion=<time>      => wait a random number between 0 and <time> before starting. Default = 300.
        retries=<number>       => retry connection to Traffic Ops URL <number> times. Default = 3.
        wait_for_parents=<0|1> => do not update if parent_pending = 1 in the update json. Default = 1, wait for parents.
    ====-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-====
    $

Installing the ORT script
--------------------------

#.  The ORT script is not a part of the traffic server distribution. In this sample session, we get it manually from github: ::

        sudo mkdir /opt/ort
        sudo wget -P /opt/ort https://raw.githubusercontent.com/apache/incubator-trafficcontrol/1.7.x/traffic_ops/bin/traffic_ops_ort.pl
        sudo chmod +x /opt/ort/traffic_ops_ort.pl

#.  Install modules required by ORT: ``sudo yum -y install perl-JSON perl-Crypt-SSLeay``

#.  For initial configuration or when major changes (like a Profile change) need to be made, run the script in "badass mode". All required rpm packages
    will be installed, all Traffic Server config files will be fetched and installed, and (if needed) the Traffic Server application will be restarted.

    Example run below: ::

        $ sudo /opt/ort/traffic_ops_ort.pl --dispersion=0 badass warn https://ops.$tcDomain admin:admin123

    .. Note:: First run gives a lot of state errors that are expected. The "badass" mode fixes these issue s. Run it a second time, this should be cleaner.
       Also, note that many ERROR messages emitted by ORT are actually information messages. Do not panic.

#.  Create a cron entry for running ort in 'syncds' mode every 15 minutes.
    This makes traffic control check periodically if 'Queue Updates' was run on Traffic Ops, and it so, get the updated configuration.

    Run ``sudo crontab -e`` and add the following line ::

  	  	*/15 * * * * /opt/ort/traffic_ops_ort.pl syncds warn https://traffops.kabletown.net admin:password > /tmp/ort/syncds.log 2>&1

    .. Note:: By default, running ort on an edge traffic server waits for it's parent (mid) servers to download their configuration before
       it downloads it's own configuration. Because of this, scheduling ort for running every 15 minutes (with 5 minutes default dispersion) means
       that it might take up to ~35 minutes for a "Queue Updates" operation to affect all traffic servers.

    .. Note:: In 'syncds' mode, the ort script updates only configurations that might be changed as part of normal operations, such as:

        * Delivery Services
        * SSL certificates
        * Traffic Monitor IP addresses
        * Logging configuration
        * More stuff <To be completed>


text:
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <!-- Button labels -->
    <string name="yes">是</string>
    <string name="no">否</string>
    <string name="cancel">取消</string>
    <string name="cont">继续</string>
    <string name="login">登录</string>
    <string name="logout">断开</string>
    <!-- Home menu items -->
    <string name="menu_exit">退出</string>
    <string name="menu_about">关于</string>
    <string name="menu_help">帮助</string>
    <string name="menu_new_bookmark">新建连接</string>
    <string name="menu_app_settings">设置</string>
    <!-- Bookmark menu items -->
    <string name="menu_title_bookmark">操作</string>
    <string name="menu_connect">连接</string>
    <string name="menu_edit">编辑</string>
    <string name="menu_delete">删除</string>
    <!-- Session menu items -->
    <string name="menu_sys_keyboard">键盘</string>
    <string name="menu_ext_keyboard">功能键</string>
    <string name="menu_touch_pointer">触控鼠标</string>
    <string name="menu_home">主目录</string>
    <string name="menu_disconnect">断开连接</string>
    <!-- List section headers -->
    <string name="section_bookmarks">手动连接</string>
    <string name="section_active_sessions">活动会话数</string>
    <!-- Search strings -->
    <string name="search_hint">搜索</string>
    <!-- List placeholder labels -->
    <string name="list_placeholder_login">登录</string>
    <string name="list_placeholder_no_servers">没有服务</string>
    <string name="list_placeholder_connecting">连接中 …</string>
    <string name="list_placeholder_disconnecting">正在断开连接 …</string>
    <string name="list_placeholder_connection_error">连接丢失</string>
    <string name="list_placeholder_wrong_password">密码错误</string>
    <string name="list_placeholder_invalid_username">用户名错误</string>
    <string name="list_placeholder_add_bookmark">新建连接</string>
    <!-- Bookmark settings strings -->
    <string name="settings_cat_host">主机信息</string>
    <string name="settings_label">标签*</string>
    <string name="settings_hostname">远程主机ip或域名</string>
    <string name="settings_port">端口</string>
    <string name="settings_cat_credentials">登录信息</string>
    <string name="settings_credentials">登录信息</string>
    <string name="settings_username">用户名</string>
    <string name="settings_password">密码</string>
    <string name="settings_domain">域</string>
    <string name="settings_cat_settings">设置</string>
    <string name="settings_screen">显示</string>
    <string name="settings_cat_screen">显示设置</string>
    <string name="settings_colors">颜色深度</string>
    <string-array name="colors_array">
        <item>High Color (16 Bit)</item>
        <item>True Color (24 Bit)</item>
        <item>Highest Quality (32 Bit)</item>
    </string-array>
    <string name="settings_resolution">分辨率</string>
    <string name="resolution_automatic">自动</string>
    <string name="resolution_fit">全屏</string>
    <string name="resolution_custom">自定义</string>
    <string-array name="resolutions_array">
        <item>自动</item>
        <item>全屏</item>
        <item>自定义</item>
        <item>640x480</item>
        <item>720x480</item>
        <item>800x600</item>
        <item>1024x768</item>
        <item>1280x1024</item>
        <item>1440x900</item>
        <item>1920x1080</item>
        <item>1920x1200</item>
    </string-array>
    <string name="settings_width">宽度</string>
    <string name="settings_height">高度</string>
    <string name="settings_performance">连接性能</string>
    <string name="settings_cat_performance">性能设置</string>
    <string name="settings_perf_remotefx">RemoteFX</string>
    <string name="settings_perf_wallpaper">桌面背景</string>
    <string name="settings_perf_font_smoothing">字体平滑</string>
    <string name="settings_perf_desktop_composition">桌面拼合</string>
    <string name="settings_perf_full_window_drag">拖动是显示窗口内容</string>
    <string name="settings_perf_menu_animation">菜单动画效果</string>
    <string name="settings_perf_theming">视觉样式</string>
    <string name="settings_advanced">高级</string>
    <string name="settings_cat_advanced">高级设置</string>
    <string name="settings_enable_3g_settings">3G设置</string>
    <string name="settings_screen_3g">使用3G网络时的显示设置</string>
    <string name="settings_performance_3g">使用3G网络时的连接性能</string>
    <string name="settings_cat_gateway">路由</string>
    <string name="settings_enable_gateway_settings">使用路由</string>
    <string name="settings_gateway_settings">路由设置</string>
    <string name="settings_redirect_sdcard">SDCard 重定向</string>
		<string name="settings_redirect_sound">音频重定向</string>
    <string-array name="redirect_sound_array">
        <item>不要播放</item>
        <item>在远程主机播放</item>
        <item>在此设备上播放</item>
    </string-array>
    <string name="settings_redirect_microphone">麦克风重定向</string>
    <string name="settings_security">连接协议</string>
    <string-array name="security_array">
        <item>自动</item>
        <item>RDP</item>
        <item>TLS</item>
        <item>NLA</item>
    </string-array>
    <string name="settings_remote_program">远程程序</string>
    <string name="settings_work_dir">工作目录</string>
    <string name="settings_async_channel">Async channel</string>
    <string name="settings_async_transport">Async transport</string>
    <string name="settings_async_input">Async input</string>
    <string name="settings_async_update">Async update</string>
    <string name="settings_console_mode">控制台模式</string>
    <!-- App settings strings -->
    <string name="settings_password_present">*******</string>
    <string name="settings_password_empty">未设置</string>
    <string name="settings_cat_ui">用户界面</string>
    <string name="settings_ui_hide_status_bar">隐藏状态栏</string>
    <string name="settings_ui_hide_zoom_controls">隐藏缩放控件</string>
    <string name="settings_ui_swap_mouse_buttons">交换鼠标左右键</string>
    <string name="settings_ui_invert_scrolling">翻转滚动</string>
    <string name="settings_ui_auto_scroll_touchpointer">触摸指针自动滚屏</string>
    <string name="settings_ui_ask_on_exit">退出时确认是否退出</string>
    <string name="settings_cat_power">省电设计</string>
    <string name="settings_power_disconnect_timeout">关闭空闲连接</string>
    <string name="settings_cat_security">安全</string>
    <string name="settings_security_accept_certificates">接受所有证书</string>
    <string name="settings_security_clear_certificate_cache">清除证书缓存</string>
    <string name="settings_description_after_minutes">%1$d 秒后</string>
    <string name="settings_description_disabled">Disabled</string>
    <!-- Activity titles -->
    <string name="title_bookmark_settings">连接设置</string>
    <string name="title_application_settings">设置</string>
    <string name="title_home">aFreeRDP - FreeRDP for Android</string>
    <string name="title_create_shortcut">RDP Connections</string>
    <string name="title_help">帮助</string>
    <string name="title_about">关于</string>
    <!-- Error message strings -->
    <string name="error_bookmark_incomplete_title">不保存即退出?</string>
    <string name="error_bookmark_incomplete">点击 "继续" 继续编辑,点击 "取消" 放弃当前更改</string>
    <string name="error_connection_failure">建立连接失败!</string>
    <!-- Info message strings -->
    <string name="info_capabilities_changed">由于主机不支持您的设置所以显示设置已经修改为适应主机的设置!</string>
    <string name="info_reset_success">清除证书缓存成功!</string>
    <string name="info_reset_failed">清楚证书缓存失败!</string>
    <!-- Dialog strings -->
    <string name="dlg_title_verify_certificate">证书验证</string>
    <string name="dlg_msg_verify_certificate">未能验证远程主机证书的安全性,是否连接?</string>
    <string name="dlg_title_credentials">请输入您的证书</string>
    <string name="dlg_title_create_shortcut">创建快捷方式</string>
    <string name="dlg_msg_create_shortcut">快捷方式名称:</string>
    <string name="dlg_msg_connecting">连接中 …</string>
    <string name="dlg_msg_logging_in">正在登录 …</string>
    <string name="dlg_title_about">关于aFreeRDP</string>
    <string name="dlg_title_create_bookmark_after_qc">是否保存连接设置?</string>
    <string name="dlg_msg_create_bookmark_after_qc">连接设置还没保存! 是否保存?</string>
    <string name="dlg_title_save_bookmark">保存?</string>
    <string name="dlg_save_bookmark">是否保存更改?</string>
    <string name="dlg_dont_show_again">不再提示</string>
    <string name="dlg_title_exit">退出?</string>
    <string name="dlg_msg_exit">是否退出?</string>
    <string name="dlg_title_clear_cert_cache">清除证书缓存?</string>
    <string name="dlg_msg_clear_cert_cache">是否清除所有的证书缓存?</string>
    <string name="debug_level">Debug Level</string>
    <string name="settings_debug">Debug Settings</string>
</resources>


text:
/// @file Move_command.hpp
/// @brief Do ergodic moves using the Command pattern
/// @author Adam Getchell

#ifndef CDT_PLUSPLUS_MOVECOMMAND_HPP
#define CDT_PLUSPLUS_MOVECOMMAND_HPP

#include "Apply_move.hpp"
#include "Ergodic_moves_3.hpp"

template <typename ManifoldType,
          typename ExpectedType = tl::expected<ManifoldType, std::string>,
          typename FunctionType = tl::function_ref<ExpectedType(ManifoldType&)>>
class MoveCommand
{
  using Queue   = std::deque<move_tracker::move_type>;
  using Counter = move_tracker::MoveTracker<ManifoldType>;

  /// @brief The Manifold on which to make the move
  ManifoldType m_manifold;

  /// @brief The queue of moves to make
  Queue m_moves;

  /// @brief The queue of moves to retry
  Queue m_moves_to_retry;

  /// @brief Track attempted moves
  Counter m_attempted;

  /// @brief Track successful moves
  Counter m_succeeded;

  /// @brief Track failed moves
  Counter m_failed;

 public:
  /// @brief No default ctor
  MoveCommand() = delete;

  /// @brief MoveCommand ctor
  /// @details The manifold to be moved should be copied by value into the
  /// MoveCommand to ensure moves are done atomically and either succeed
  /// or fail and can be discarded without affecting the original.
  /// @param t_manifold The manifold to perform moves upon
  explicit MoveCommand(ManifoldType t_manifold)
      : m_manifold{std::move(t_manifold)}
  {}

  /// @return A read-only reference to the manifold
  auto get_const_results() const -> ManifoldType const&
  {
    return std::cref(m_manifold);
  }  // get_const_results

  /// @return The results of the moves invoked by MoveCommand
  [[nodiscard]] auto get_results() -> ManifoldType& { return m_manifold; }

  /// @return Attempted moves by MoveCommand
  [[nodiscard]] auto get_attempted() const -> Counter const&
  {
    return m_attempted;
  }  // get_attempts

  /// @return Successful moves by MoveCommand
  [[nodiscard]] auto get_succeeded() const
  {
    return m_succeeded;
  }  // get_succeeded

  /// @return Failed moves by MoveCommand
  [[nodiscard]] auto get_failed() const -> Counter const&
  {
    return m_failed;
  }  // get_errors

  /// @brief Reset the counters
  void reset_counters()
  {
    m_attempted.reset();
    m_succeeded.reset();
    m_failed.reset();
  }

  /// @brief Push a Pachner move onto the move queue
  /// @param t_move The move function object to do on the manifold
  void enqueue(move_tracker::move_type t_move) { m_moves.push_front(t_move); }

  auto size() const { return m_moves.size(); }

  /// Execute all moves in the queue on the manifold
  void execute()
  {
#ifndef NDEBUG
    fmt::print("=== Executing: Before moves ===\n");
    m_manifold.print_details();
    fmt::print("===============================\n");
#endif

    while (!m_moves.empty())
    {
      auto move_type = m_moves.back();
      // Record attempted move
      m_attempted[move_tracker::as_integer(move_type)]++;
      // Convert move_type to function
      auto move_function = as_move_function(move_type);
      // Execute move
      if (auto result = apply_move(m_manifold, move_function); result)
      {
        result->update();
        swap(result.value(), m_manifold);
        m_succeeded[move_tracker::as_integer(move_type)]++;
      }
      else
      {
        fmt::print("{}\n", result.error());
        // Track failed moves
        m_failed[move_tracker::as_integer(move_type)]++;
        m_moves_to_retry.push_front(move_type);
      }
      // Remove move from queue
      m_moves.pop_back();
    }
#ifndef NDEBUG
    fmt::print("=== After moves ===\n");
    print_attempts();
    print_errors();
    m_manifold.print_details();
    fmt::print("===================\n");
#endif
  }  // execute

  auto as_move_function(move_tracker::move_type move) -> FunctionType
  {
    switch (move)
    {
      case move_tracker::move_type::TWO_THREE: return ergodic_moves::do_23_move;
      case move_tracker::move_type::THREE_TWO: return ergodic_moves::do_32_move;
      case move_tracker::move_type::TWO_SIX: return ergodic_moves::do_26_move;
      case move_tracker::move_type::SIX_TWO: return ergodic_moves::do_62_move;
      default: return ergodic_moves::do_44_move;
    }
  }  // move_function

  /// @brief Print attempted moves
  void print_attempts() const
  {
    if (ManifoldType::dimension == 3)
    {
      fmt::print(
          "There were {} attempted (2,3) moves and {} attempted (3,2) moves "
          "and {} "
          "attempted (2,6) moves and {} attempted (6,2) moves and {} attempted "
          "(4,4) "
          "moves.\n",
          m_attempted.two_three_moves(), m_attempted.three_two_moves(),
          m_attempted.two_six_moves(), m_attempted.six_two_moves(),
          m_attempted.four_four_moves());
    }
    else
    {
      // 4D
      fmt::print(
          "There were {} attempted (2,4) moves and {} attempted (4,2) moves "
          "and {} "
          "attempted (3,3) moves and {} attempted (4,6) moves and {} attempted "
          "(6,4) "
          "moves and {} attempted (2,8) moves and {} attempted (8,2) moves.\n",
          m_attempted.two_four_moves(), m_attempted.four_two_moves(),
          m_attempted.three_three_moves(), m_attempted.four_six_moves(),
          m_attempted.six_four_moves(), m_attempted.two_eight_moves(),
          m_attempted.eight_two_moves());
    }
  }

  /// @brief Print successful moves
  void print_successful() const
  {
    if (ManifoldType::dimension == 3)
    {
      fmt::print(
          "There were {} successful (2,3) moves and {} successful (3,2) moves "
          "and {} "
          "successful (2,6) moves and {} successful (6,2) moves and {} "
          "successful "
          "(4,4) "
          "moves.\n",
          m_succeeded.two_three_moves(), m_succeeded.three_two_moves(),
          m_succeeded.two_six_moves(), m_succeeded.six_two_moves(),
          m_succeeded.four_four_moves());
    }
    else
    {
      // 4D
      fmt::print(
          "There were {} successful (2,4) moves and {} successful (4,2) moves "
          "and {} "
          "successful (3,3) moves and {} successful (4,6) moves and {} "
          "successful "
          "(6,4) "
          "moves and {} successful (2,8) moves and {} successful (8,2) "
          "moves.\n",
          m_succeeded.two_four_moves(), m_succeeded.four_two_moves(),
          m_succeeded.three_three_moves(), m_succeeded.four_six_moves(),
          m_succeeded.six_four_moves(), m_succeeded.two_eight_moves(),
          m_succeeded.eight_two_moves());
    }
  }

  /// @brief Print Move errors
  void print_errors() const
  {
    if (std::all_of(m_failed.moves_view().begin(), m_failed.moves_view().end(),
                    [](auto const& value) { return value == 0; }))
    {
      fmt::print("There were no failed moves.\n");
    }
    else
    {
      if (ManifoldType::dimension == 3)
      {
        fmt::print(
            "There were {} failed (2,3) moves and {} failed (3,2) moves and {} "
            "failed (2,6) moves and {} failed (6,2) moves and {} failed (4,4) "
            "moves.\n",
            m_failed.two_three_moves(), m_failed.three_two_moves(),
            m_failed.two_six_moves(), m_failed.six_two_moves(),
            m_failed.four_four_moves());
      }
      else
      {
        // 4D
        fmt::print(
            "There were {} failed (2,4) moves and {} failed (4,2) moves and {} "
            "failed (3,3) moves and {} failed (4,6) moves and {} failed (6,4) "
            "moves and {} failed (2,8) moves and {} failed (8,2) moves.\n",
            m_failed.two_four_moves(), m_failed.four_two_moves(),
            m_failed.three_three_moves(), m_failed.four_six_moves(),
            m_failed.six_four_moves(), m_failed.two_eight_moves(),
            m_failed.eight_two_moves());
      }
    }
  }
};

#endif  // CDT_PLUSPLUS_MOVECOMMAND_HPP


text:
package xyz.randomcode.dropwizard_morphia;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.BeforeClass;
import org.junit.Test;

import java.io.InputStream;

import static org.assertj.core.api.Assertions.assertThat;

public class UriMongoConfigurationTest {

    private static ObjectMapper mapper;

    @BeforeClass
    public static void setUpAll() throws Exception {
        mapper = new ObjectMapper();
    }

    @Test
    public void deserialize() throws Exception {
        InputStream stream = getClass().getClassLoader().getResourceAsStream("fixtures/uri_mongo_configuration.yml");

        MongoConfiguration actual = mapper.readValue(stream, UriMongoConfiguration.class);
        assertThat(actual).isNotNull().isInstanceOf(UriMongoConfiguration.class);

        UriMongoConfiguration configuration = (UriMongoConfiguration) actual;
        assertThat(configuration)
                .hasFieldOrPropertyWithValue("dbName", "test")
                .hasFieldOrPropertyWithValue("storeNulls", false)
                .hasFieldOrPropertyWithValue("storeEmpties", false)
                .hasFieldOrPropertyWithValue("ignoreFinals", false)
                .hasFieldOrPropertyWithValue("useLowerCaseCollectionNames", true)
                .hasFieldOrPropertyWithValue("enableValidationExtension", true);

        assertThat(configuration.getUri().getURI()).isNotEmpty().isEqualTo("mongodb://localhost:1337");
    }
}


text:
// Copyright (c) All contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

namespace PInvoke
{
    using System;
    using System.Runtime.InteropServices;

#pragma warning disable SA1401 // Fields must be private

    /// <content>
    /// Contains the <see cref="SECURITY_ATTRIBUTES"/> nested type.
    /// </content>
    public partial class Kernel32
    {
        /// <summary>
        /// The SECURITY_ATTRIBUTES structure contains the security descriptor for an object and specifies whether the handle retrieved by specifying this structure is inheritable. This structure provides security settings for objects created by various functions, such as CreateFile, CreatePipe, CreateProcess, RegCreateKeyEx, or RegSaveKeyEx.
        /// </summary>
        [StructLayout(LayoutKind.Sequential)]
        public struct SECURITY_ATTRIBUTES
        {
            /// <summary>
            /// The size, in bytes, of this structure.
            /// This value is set by the constructor to the size of the <see cref="SECURITY_ATTRIBUTES"/> structure.
            /// </summary>
            public int nLength;

            /// <summary>
            /// A pointer to a <see cref="SECURITY_DESCRIPTOR"/> structure that controls access to the object. If the value of this member is NULL, the object is assigned the default security descriptor associated with the access token of the calling process. This is not the same as granting access to everyone by assigning a NULL discretionary access control list (DACL). By default, the default DACL in the access token of a process allows access only to the user represented by the access token.
            /// For information about creating a security descriptor, see Creating a Security Descriptor.
            /// </summary>
            public IntPtr lpSecurityDescriptor;

            /// <summary>
            /// A Boolean value that specifies whether the returned handle is inherited when a new process is created. If this member is TRUE, the new process inherits the handle.
            /// </summary>
            public int bInheritHandle;

            /// <summary>
            /// Gets a value indicating whether the returned handle is inherited when a new process is created. If this member is TRUE, the new process inherits the handle.
            /// </summary>
            public bool InheritHandle => this.bInheritHandle != 0;

            /// <summary>
            /// Initializes a new instance of the <see cref="SECURITY_ATTRIBUTES"/> struct.
            /// </summary>
            /// <returns>A new instance of <see cref="SECURITY_ATTRIBUTES"/>.</returns>
            public static SECURITY_ATTRIBUTES Create()
            {
                return new SECURITY_ATTRIBUTES
                {
#if NETSTANDARD1_3_ORLATER || NETFX_CORE
                    nLength = Marshal.SizeOf<SECURITY_ATTRIBUTES>(),
#else
                    nLength = Marshal.SizeOf(typeof(SECURITY_ATTRIBUTES)),
#endif
                };
            }
        }
    }
}


text:
package org.jetbrains.plugins.groovy.lang.resolve.processors;

import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiType;
import org.jetbrains.plugins.groovy.lang.psi.GrReferenceElement;

import java.util.EnumSet;

import static org.jetbrains.plugins.groovy.lang.resolve.processors.ClassHint.RESOLVE_KINDS_CLASS;

/**
 * @author ven
 */
public class ClassResolverProcessor extends ResolverProcessorImpl {
  public ClassResolverProcessor(String refName, GrReferenceElement ref, EnumSet<DeclarationKind> kinds) {
    super(refName, kinds, ref, ref.getTypeArguments());
  }

  public ClassResolverProcessor(String refName, PsiElement place) {
    super(refName, RESOLVE_KINDS_CLASS, place, PsiType.EMPTY_ARRAY);
  }
}


text:
package org.apache.zeppelin.helium;

import com.google.common.annotations.VisibleForTesting;
import com.google.gson.Gson;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.inject.Inject;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.zeppelin.conf.ZeppelinConfiguration;
import org.apache.zeppelin.conf.ZeppelinConfiguration.ConfVars;
import org.apache.zeppelin.interpreter.Interpreter;
import org.apache.zeppelin.interpreter.InterpreterNotFoundException;
import org.apache.zeppelin.interpreter.InterpreterSettingManager;
import org.apache.zeppelin.interpreter.ManagedInterpreterGroup;
import org.apache.zeppelin.interpreter.remote.RemoteInterpreterProcess;
import org.apache.zeppelin.interpreter.thrift.RemoteInterpreterService;
import org.apache.zeppelin.notebook.Paragraph;
import org.apache.zeppelin.resource.DistributedResourcePool;
import org.apache.zeppelin.resource.Resource;
import org.apache.zeppelin.resource.ResourcePool;
import org.apache.zeppelin.resource.ResourceSet;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Manages helium packages
 */
public class Helium {
  private Logger logger = LoggerFactory.getLogger(Helium.class);
  private List<HeliumRegistry> registry = new LinkedList<>();

  private HeliumConf heliumConf;
  private Map<String, List<HeliumPackageSearchResult>> allPackages = new HashMap<>();

  private final String heliumConfPath;
  private final String registryPaths;
  private final File registryCacheDir;

  private final HeliumBundleFactory bundleFactory;
  private final HeliumApplicationFactory applicationFactory;
  private final InterpreterSettingManager interpreterSettingManager;

  @Inject
  public Helium(
      ZeppelinConfiguration conf,
      HeliumBundleFactory heliumBundleFactory,
      HeliumApplicationFactory heliumApplicationFactory,
      InterpreterSettingManager interpreterSettingManager) throws IOException {
    this(
        conf.getHeliumConfPath(),
        conf.getHeliumRegistry(),
        new File(conf.getRelativeDir(ConfVars.ZEPPELIN_DEP_LOCALREPO), "helium-registry-cache"),
        heliumBundleFactory,
        heliumApplicationFactory,
        interpreterSettingManager);
  }

  @VisibleForTesting
  public Helium(
      String heliumConfPath,
      String registryPaths,
      File registryCacheDir,
      HeliumBundleFactory bundleFactory,
      HeliumApplicationFactory applicationFactory,
      InterpreterSettingManager interpreterSettingManager)
      throws IOException {
    this.heliumConfPath = heliumConfPath;
    this.registryPaths = registryPaths;
    this.registryCacheDir = registryCacheDir;
    this.bundleFactory = bundleFactory;
    this.applicationFactory = applicationFactory;
    this.interpreterSettingManager = interpreterSettingManager;
    heliumConf = loadConf(heliumConfPath);
    allPackages = getAllPackageInfo();

    // TODO(jl): Refactor it
    try {
      bundleFactory.buildAllPackages(getBundlePackagesToBundle());
    } catch (Exception e) {
      logger.error(e.getMessage(), e);
    }
  }

  /**
   * Add HeliumRegistry
   *
   * @param registry
   */
  public void addRegistry(HeliumRegistry registry) {
    synchronized (this.registry) {
      this.registry.add(registry);
    }
  }

  public void clear() {
    this.registry.clear();
    this.heliumConf = new HeliumConf();
    this.allPackages = new HashMap<>();
  }

  public HeliumApplicationFactory getApplicationFactory() {
    return applicationFactory;
  }

  private synchronized HeliumConf loadConf(String path) throws IOException {
    // add registry
    if (registryPaths != null && !registryPaths.isEmpty()) {
      String[] paths = registryPaths.split(",");
      for (String uri : paths) {
        if (uri.startsWith("http://") || uri.startsWith("https://")) {
          logger.info("Add helium online registry {}", uri);
          registry.add(new HeliumOnlineRegistry(uri, uri, registryCacheDir));
        } else {
          logger.info("Add helium local registry {}", uri);
          registry.add(new HeliumLocalRegistry(uri, uri));
        }
      }
    }

    File heliumConfFile = new File(path);
    if (!heliumConfFile.isFile()) {
      logger.warn("{} does not exists", path);
      return new HeliumConf();
    } else {
      String jsonString = FileUtils.readFileToString(heliumConfFile);
      return HeliumConf.fromJson(jsonString);
    }
  }

  public synchronized void saveConfig() throws IOException {
    String jsonString;
    synchronized (registry) {
      clearNotExistsPackages();
      jsonString = heliumConf.toJson();
    }

    File heliumConfFile = new File(heliumConfPath);
    if (!heliumConfFile.exists()) {
      heliumConfFile.createNewFile();
    }

    FileUtils.writeStringToFile(heliumConfFile, jsonString);
  }

  private void clearNotExistsPackages() {
    // clear visualization display order
    List<String> packageOrder = heliumConf.getBundleDisplayOrder();
    List<String> clearedOrder = new LinkedList<>();
    for (String pkgName : packageOrder) {
      if (allPackages.containsKey(pkgName)) {
        clearedOrder.add(pkgName);
      }
    }
    heliumConf.setBundleDisplayOrder(clearedOrder);

    // clear enabled package
    Map<String, String> enabledPackages = heliumConf.getEnabledPackages();
    for (String pkgName : enabledPackages.keySet()) {
      if (!allPackages.containsKey(pkgName)) {
        heliumConf.disablePackage(pkgName);
      }
    }
  }

  public Map<String, List<HeliumPackageSearchResult>> getAllPackageInfo() {
    return getAllPackageInfo(true, null);
  }

  /**
   * @param refresh
   * @param packageName
   */
  public Map<String, List<HeliumPackageSearchResult>> getAllPackageInfo(boolean refresh,
                                                                        String packageName) {
    Map<String, String> enabledPackageInfo = heliumConf.getEnabledPackages();

    synchronized (registry) {
      if (refresh || !allPackages.containsKey(packageName)) {
        for (HeliumRegistry r : registry) {
          try {
            for (HeliumPackage pkg : r.getAll()) {
              String name = pkg.getName();

              if (!StringUtils.isEmpty(packageName) &&
                  !name.equals(packageName)) {
                continue;
              }

              if (allPackages.containsKey(name)) {
                allPackages.remove(name);
              }
              allPackages.put(name, new LinkedList<HeliumPackageSearchResult>());
              boolean enabled = enabledPackageInfo.containsKey(pkg.getName());
              allPackages.get(name).add(new HeliumPackageSearchResult(r.name(), pkg, enabled));
            }
          } catch (IOException e) {
            logger.error(e.getMessage(), e);
          }
        }
      } else {
        for (String name : allPackages.keySet()) {
          if (!StringUtils.isEmpty(packageName) &&
              !name.equals(packageName)) {
            continue;
          }

          List<HeliumPackageSearchResult> pkgs = allPackages.get(name);
          LinkedList<HeliumPackageSearchResult> newResults = new LinkedList<>();

          for (HeliumPackageSearchResult pkg : pkgs) {
            boolean enabled = enabledPackageInfo.containsKey(pkg.getPkg().getName());
            newResults.add(new HeliumPackageSearchResult(pkg.getRegistry(), pkg.getPkg(), enabled));
          }

          allPackages.put(name, newResults);
        }
      }

      // sort version (artifact)
      for (String name : allPackages.keySet()) {
        List<HeliumPackageSearchResult> packages = allPackages.get(name);
        Collections.sort(packages, new Comparator<HeliumPackageSearchResult>() {
          @Override
          public int compare(HeliumPackageSearchResult o1, HeliumPackageSearchResult o2) {
            return o2.getPkg().getArtifact().compareTo(o1.getPkg().getArtifact());
          }
        });
      }
      return allPackages;
    }
  }

  public List<HeliumPackageSearchResult> getAllEnabledPackages() {
    Map<String, String> enabledInfo = heliumConf.getEnabledPackages();
    List<HeliumPackageSearchResult> enabledPackages = new ArrayList<>();

    for (List<HeliumPackageSearchResult> versionedPackages : allPackages.values()) {
      for (HeliumPackageSearchResult psr : versionedPackages) {
        if (enabledInfo.containsKey(psr.getPkg().getName())) {
          enabledPackages.add(psr);
          break;
        }
      }
    }
    return enabledPackages;
  }

  public List<HeliumPackageSearchResult> getSinglePackageInfo(String packageName) {
    Map<String, List<HeliumPackageSearchResult>> result = getAllPackageInfo(true, packageName);

    if (!result.containsKey(packageName)) {
      return new ArrayList<>();
    }
    return result.get(packageName);
  }

  private HeliumPackageSearchResult getEnabledPackageInfo(String packageName) {
    List<HeliumPackageSearchResult> packages = allPackages.get(packageName);

    for (HeliumPackageSearchResult pkgSearchResult : packages) {
      if (pkgSearchResult.isEnabled()) {
        return pkgSearchResult;
      }
    }

    return null;
  }

  private HeliumPackageSearchResult getPackageInfo(String pkgName, String artifact) {
    Map<String, List<HeliumPackageSearchResult>> infos = getAllPackageInfo(false, pkgName);
    List<HeliumPackageSearchResult> packages = infos.get(pkgName);
    if (StringUtils.isBlank(artifact)) {
      return packages.get(0); /** return the FIRST package */
    } else {
      for (HeliumPackageSearchResult pkg : packages) {
        if (pkg.getPkg().getArtifact().equals(artifact)) {
          return pkg;
        }
      }
    }
    return null;
  }

  public File getBundle(HeliumPackage pkg, boolean rebuild) throws IOException {
    return bundleFactory.buildPackage(pkg, rebuild, true);
  }

  public boolean enable(String name, String artifact) throws IOException {
    HeliumPackageSearchResult pkgInfo = getPackageInfo(name, artifact);

    if (pkgInfo == null) {
      logger.info("Package {} not found", name);
      return false;
    }

    // if package is bundle, rebuild bundle
    if (HeliumPackage.isBundleType(pkgInfo.getPkg().getType())) {
      bundleFactory.buildPackage(pkgInfo.getPkg(), true, true);
    }

    // set `enable` field
    heliumConf.enablePackage(name, artifact);
    // set display order
    if (pkgInfo.getPkg().getType() == HeliumType.VISUALIZATION) {
      List<String> currentDisplayOrder = heliumConf.getBundleDisplayOrder();
      if (!currentDisplayOrder.contains(name)) {
        currentDisplayOrder.add(name);
      }
    }

    saveConfig();
    return true;
  }

  public boolean disable(String name) throws IOException {
    String pkg = heliumConf.getEnabledPackages().get(name);

    if (pkg == null) {
      logger.info("Package {} not found", name);
      return false;
    }

    HeliumPackageSearchResult pkgInfo = getPackageInfo(name, pkg);

    // set `enable` field
    heliumConf.disablePackage(name);
    if (pkgInfo.getPkg().getType() == HeliumType.VISUALIZATION) {
      List<String> currentDisplayOrder = heliumConf.getBundleDisplayOrder();
      if (currentDisplayOrder.contains(name)) {
        currentDisplayOrder.remove(name);
      }
    }
    saveConfig();
    return true;
  }

  public void updatePackageConfig(String artifact, Map<String, Object> pkgConfig)
      throws IOException {

    heliumConf.updatePackageConfig(artifact, pkgConfig);
    saveConfig();
  }

  public Map<String, Map<String, Object>> getAllPackageConfig() {
    return heliumConf.getAllPackageConfigs();
  }

  private Map<String, Object> getPackagePersistedConfig(String artifact) {
    return heliumConf.getPackagePersistedConfig(artifact);
  }

  public HeliumPackageSuggestion suggestApp(Paragraph paragraph) {
    HeliumPackageSuggestion suggestion = new HeliumPackageSuggestion();

    Interpreter intp = null;
    try {
      intp = paragraph.getBindedInterpreter();
    } catch (InterpreterNotFoundException e) {
      return suggestion;
    }

    ResourcePool resourcePool = intp.getInterpreterGroup().getResourcePool();
    ResourceSet allResources;

    if (resourcePool != null) {
      if (resourcePool instanceof DistributedResourcePool) {
        allResources = ((DistributedResourcePool) resourcePool).getAll(true);
      } else {
        allResources = resourcePool.getAll();
      }
    } else {
      allResources = interpreterSettingManager.getAllResources();
    }

    for (List<HeliumPackageSearchResult> pkgs : allPackages.values()) {
      for (HeliumPackageSearchResult pkg : pkgs) {
        if (pkg.getPkg().getType() == HeliumType.APPLICATION && pkg.isEnabled()) {
          ResourceSet resources = ApplicationLoader.findRequiredResourceSet(
              pkg.getPkg().getResources(),
              paragraph.getNote().getId(),
              paragraph.getId(),
              allResources);
          if (resources == null) {
            continue;
          } else {
            suggestion.addAvailablePackage(pkg);
          }
          break;
        }
      }
    }

    suggestion.sort();
    return suggestion;
  }

  /**
   * Get enabled buildBundle packages
   *
   * @return ordered list of enabled buildBundle package
   */
  public List<HeliumPackage> getBundlePackagesToBundle() {
    List<String> visOrder = heliumConf.getBundleDisplayOrder();

    Set<HeliumPackage> orderedBundlePackages = new HashSet<>();
    List<HeliumPackage> output = new LinkedList<>();

    // add enabled packages in visOrder
    for (String name : visOrder) {
      List<HeliumPackageSearchResult> versions = allPackages.get(name);
      if (versions == null) {
        continue;
      }
      for (HeliumPackageSearchResult pkgInfo : versions) {
        if (canBundle(pkgInfo)) {
          orderedBundlePackages.add(pkgInfo.getPkg());
          break;
        }
      }
    }

    // add enabled packages not in visOrder
    for (List<HeliumPackageSearchResult> pkgInfos : allPackages.values()) {
      for (HeliumPackageSearchResult pkgInfo : pkgInfos) {
        if (canBundle(pkgInfo)) {
          orderedBundlePackages.add(pkgInfo.getPkg());
          break;
        }
      }
    }
    output.addAll(orderedBundlePackages);
    return output;
  }

  private boolean canBundle(HeliumPackageSearchResult pkgInfo) {
    return (pkgInfo.isEnabled() &&
        HeliumPackage.isBundleType(pkgInfo.getPkg().getType()));
  }

  /**
   * Get enabled package list in order
   * @return
   */
  public List<String> getVisualizationPackageOrder() {
    return heliumConf.getBundleDisplayOrder();
  }

  public void setVisualizationPackageOrder(List<String> orderedPackageList)
      throws IOException {
    heliumConf.setBundleDisplayOrder(orderedPackageList);
    saveConfig();
  }

  /**
   * @param packageName
   * @return { "confPersisted", "confSpec" } or return null if failed to found enabled package
   */
  public Map<String, Map<String, Object>> getSpellConfig(String packageName) {
    HeliumPackageSearchResult result = getEnabledPackageInfo(packageName);

    if (result == null) {
      return null;
    }

    HeliumPackage enabledPackage = result.getPkg();

    Map<String, Object> configSpec = enabledPackage.getConfig();
    Map<String, Object> configPersisted =
        getPackagePersistedConfig(enabledPackage.getArtifact());

    return createMixedConfig(configPersisted, configSpec);
  }

  public Map<String, Map<String, Object>> getPackageConfig(String pkgName,
                                                           String artifact) {

    HeliumPackageSearchResult result = getPackageInfo(pkgName, artifact);

    if (result == null) {
      return null;
    }

    HeliumPackage requestedPackage = result.getPkg();

    Map<String, Object> configSpec = requestedPackage.getConfig();
    Map<String, Object> configPersisted =
        getPackagePersistedConfig(artifact);

    return createMixedConfig(configPersisted, configSpec);
  }

  private static Map<String, Map<String, Object>> createMixedConfig(Map<String, Object> persisted,
                                                                   Map<String, Object> spec) {
    Map<String, Map<String, Object>> mixed = new HashMap<>();
    mixed.put("confPersisted", persisted);
    mixed.put("confSpec", spec);

    return mixed;
  }

  public ResourceSet getAllResources() {
    return getAllResourcesExcept(null);
  }

  private ResourceSet getAllResourcesExcept(String interpreterGroupExcludsion) {
    ResourceSet resourceSet = new ResourceSet();
    for (ManagedInterpreterGroup intpGroup : interpreterSettingManager.getAllInterpreterGroup()) {
      if (interpreterGroupExcludsion != null &&
          intpGroup.getId().equals(interpreterGroupExcludsion)) {
        continue;
      }

      RemoteInterpreterProcess remoteInterpreterProcess = intpGroup.getRemoteInterpreterProcess();
      if (remoteInterpreterProcess == null) {
        ResourcePool localPool = intpGroup.getResourcePool();
        if (localPool != null) {
          resourceSet.addAll(localPool.getAll());
        }
      } else if (remoteInterpreterProcess.isRunning()) {
        List<String> resourceList = remoteInterpreterProcess.callRemoteFunction(
            new RemoteInterpreterProcess.RemoteFunction<List<String>>() {
              @Override
              public List<String> call(RemoteInterpreterService.Client client) throws Exception {
                return client.resourcePoolGetAll();
              }
            }
        );
        Gson gson = new Gson();
        for (String res : resourceList) {
          resourceSet.add(gson.fromJson(res, Resource.class));
        }
      }
    }
    return resourceSet;
  }
}


text:
import express from 'express';

const router = express.Router({
  caseSensitive: false,
  mergeParams: true,
  strict: false,
});

router.get('/', (req, res) => {
  res.json({msg: 'Hello, world!'});
  res.end();
});

export default router;


text:
/**
 * PngEncoder takes a pixel data byte array and creates a byte string which can be saved as a PNG file.
 *
 *
Thanks to Jay Denny at KeyPoint Software
 *    http://www.keypoint.com/
 * who let me develop this code on company time.

 *
 *
You may contact me with (probably very-much-needed) improvements,
 * comments, and bug fixes at:

 *
 *
david@catcode.com

 *
 *
This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.

 *
 *
This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.

 *
 *
You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 * A copy of the GNU LGPL may be found at
 * http://www.gnu.org/copyleft/lesser.html

 *
 * @author J. David Eisenberg
 * @version 1.5, 19 Oct 2003
 *
 * CHANGES:
 * --------
 * 19-Nov-2002 : CODING STYLE CHANGES ONLY (by David Gilbert for Object Refinery Limited);
 * 19-Sep-2003 : Fix for platforms using EBCDIC (contributed by Paulo Soares);
 * 19-Oct-2003 : Change private fields to protected fields so that
 *               PngEncoderB can inherit them (JDE)
 *				 Fixed bug with calculation of nRows
 * 2009-12-22  : Ported Java version over to C#.
 */

using System;
using System.IO;

namespace Plupload.PngEncoder {
	public class PngEncoder {
		/** Constant specifying that alpha channel should be encoded. */
		public const bool ENCODE_ALPHA = true;

		/** Constant specifying that alpha channel should not be encoded. */
		public const bool NO_ALPHA = false;

		/** Constants for filter (NONE) */
		public const int FILTER_NONE = 0;

		/** Constants for filter (SUB) */
		public const int FILTER_SUB = 1;

		/** Constants for filter (UP) */
		public const int FILTER_UP = 2;

		/** Constants for filter (LAST) */
		public const int FILTER_LAST = 2;

		/** IHDR tag. */
		protected static byte[] IHDR = new byte[] { 73, 72, 68, 82 };

		/** IDAT tag. */
		protected static byte[] IDAT = new byte[] { 73, 68, 65, 84 };

		/** IEND tag. */
		protected static byte[] IEND = new byte[] { 73, 69, 78, 68 };

		/** The png bytes. */
		protected byte[] pngBytes;

		/** The prior row. */
		protected byte[] priorRow;

		/** The left bytes. */
		protected byte[] leftBytes;

		/** The width. */
		protected int width, height;

		/** The byte position. */
		protected int bytePos, maxPos;

		/** CRC. */
		protected Crc32 crc = new Crc32();

		/** The CRC value. */
		protected long crcValue;

		/** Encode alpha? */
		protected bool encodeAlpha;

		/** The filter type. */
		protected int filter;

		/** The bytes-per-pixel. */
		protected int bytesPerPixel;

		/** The compression level. */
		protected int compressionLevel;

		/** PixelData array to encode */
		protected int[] pixelData;

		/**
		 * Class constructor specifying Image source to encode, whether to encode alpha, filter to use,
		 * and compression level.
		 *
		 * @param pixel_data A Java Image object
		 * @param encodeAlpha Encode the alpha channel? false=no; true=yes
		 * @param whichFilter 0=none, 1=sub, 2=up
		 * @param compLevel 0..9
		 * @see java.awt.Image
		 */
		public PngEncoder(int[] pixel_data, int width, int height, bool encodeAlpha, int whichFilter, int compLevel) {
			this.pixelData = pixel_data;
			this.width = width;
			this.height = height;
			this.encodeAlpha = encodeAlpha;

			this.filter = FILTER_NONE;
			if (whichFilter <= FILTER_LAST) {
				this.filter = whichFilter;
			}

			if (compLevel >= 0 && compLevel <= 9) {
				this.compressionLevel = compLevel;
			}
		}

		/**
		 * Creates an array of bytes that is the PNG equivalent of the current image, specifying
		 * whether to encode alpha or not.
		 *
		 * @param encodeAlpha boolean false=no alpha, true=encode alpha
		 * @return an array of bytes, or null if there was a problem
		 */
		public byte[] Encode(bool encodeAlpha) {
			byte[] pngIdBytes = { 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A };

			/*
			 * start with an array that is big enough to hold all the pixels
			 * (plus filter bytes), and an extra 200 bytes for header info
			 */
			pngBytes = new byte[((width + 1) * height * 3) + 200];

			/*
			 * keep track of largest byte written to the array
			 */
			maxPos = 0;

			bytePos = WriteBytes(pngIdBytes, 0);
			//hdrPos = bytePos;
			writeHeader();
			//dataPos = bytePos;
			if (WriteImageData()) {
				writeEnd();
				pngBytes = ResizeByteArray(pngBytes, maxPos);
			} else {
				pngBytes = null;
			}
			return pngBytes;
		}

		/**
		 * Creates an array of bytes that is the PNG equivalent of the current image.
		 * Alpha encoding is determined by its setting in the constructor.
		 *
		 * @return an array of bytes, or null if there was a problem
		 */
		public byte[] pngEncode() {
			return Encode(encodeAlpha);
		}

		/**
		 * Increase or decrease the length of a byte array.
		 *
		 * @param array The original array.
		 * @param newLength The length you wish the new array to have.
		 * @return Array of newly desired length. If shorter than the
		 *         original, the trailing elements are truncated.
		 */
		protected byte[] ResizeByteArray(byte[] array, int newLength) {
			byte[] newArray = new byte[newLength];
			int oldLength = array.Length;

			Array.Copy(array, 0, newArray, 0, Math.Min(oldLength, newLength));
			return newArray;
		}

		/**
		 * Write an array of bytes into the pngBytes array.
		 * Note: This routine has the side effect of updating
		 * maxPos, the largest element written in the array.
		 * The array is resized by 1000 bytes or the length
		 * of the data to be written, whichever is larger.
		 *
		 * @param data The data to be written into pngBytes.
		 * @param offset The starting point to write to.
		 * @return The next place to be written to in the pngBytes array.
		 */
		protected int WriteBytes(byte[] data, int offset) {
			maxPos = Math.Max(maxPos, offset + data.Length);
			if (data.Length + offset > pngBytes.Length)
				pngBytes = ResizeByteArray(pngBytes, pngBytes.Length + Math.Max(1000, data.Length));

			Array.Copy(data, 0, pngBytes, offset, data.Length);
			return offset + data.Length;
		}

		/**
		 * Write an array of bytes into the pngBytes array, specifying number of bytes to write.
		 * Note: This routine has the side effect of updating
		 * maxPos, the largest element written in the array.
		 * The array is resized by 1000 bytes or the length
		 * of the data to be written, whichever is larger.
		 *
		 * @param data The data to be written into pngBytes.
		 * @param nBytes The number of bytes to be written.
		 * @param offset The starting point to write to.
		 * @return The next place to be written to in the pngBytes array.
		 */
		protected int WriteBytes(byte[] data, int nBytes, int offset) {
			maxPos = Math.Max(maxPos, offset + nBytes);
			if (nBytes + offset > pngBytes.Length)
				pngBytes = ResizeByteArray(pngBytes, pngBytes.Length + Math.Max(1000, nBytes));

			Array.Copy(data, 0, pngBytes, offset, nBytes);
			return offset + nBytes;
		}

		/**
		 * Write a two-byte integer into the pngBytes array at a given position.
		 *
		 * @param n The integer to be written into pngBytes.
		 * @param offset The starting point to write to.
		 * @return The next place to be written to in the pngBytes array.
		 */
		protected int WriteInt2(int n, int offset) {
			byte[] temp = { (byte) ((n >> 8) & 0xff), (byte) (n & 0xff) };

			return WriteBytes(temp, offset);
		}

		/**
		 * Write a four-byte integer into the pngBytes array at a given position.
		 *
		 * @param n The integer to be written into pngBytes.
		 * @param offset The starting point to write to.
		 * @return The next place to be written to in the pngBytes array.
		 */
		protected int WriteInt4(int n, int offset) {
			byte[] temp = {(byte) ((n >> 24) & 0xff),
                       (byte) ((n >> 16) & 0xff),
                       (byte) ((n >> 8) & 0xff),
                       (byte) (n & 0xff)};

			return WriteBytes(temp, offset);
		}

		/**
		 * Write a single byte into the pngBytes array at a given position.
		 *
		 * @param b The integer to be written into pngBytes.
		 * @param offset The starting point to write to.
		 * @return The next place to be written to in the pngBytes array.
		 */
		protected int WriteByte(int b, int offset) {
			byte[] temp = { (byte) b };

			return WriteBytes(temp, offset);
		}

		/**
		 * Write a PNG "IHDR" chunk into the pngBytes array.
		 */
		protected void writeHeader() {
			int startPos;

			startPos = bytePos = WriteInt4(13, bytePos);

			bytePos = WriteBytes(IHDR, bytePos);
			bytePos = WriteInt4(width, bytePos);
			bytePos = WriteInt4(height, bytePos);
			bytePos = WriteByte(8, bytePos); // bit depth
			bytePos = WriteByte((encodeAlpha) ? 6 : 2, bytePos); // direct model
			bytePos = WriteByte(0, bytePos); // compression method
			bytePos = WriteByte(0, bytePos); // filter method
			bytePos = WriteByte(0, bytePos); // no interlace

			crc.Reset();
			crc.Update(pngBytes, startPos, bytePos - startPos);
			crcValue = crc.Value;

			bytePos = WriteInt4((int) crcValue, bytePos);
		}

		/**
		 * Perform "sub" filtering on the given row.
		 * Uses temporary array leftBytes to store the original values
		 * of the previous pixels.  The array is 16 bytes long, which
		 * will easily hold two-byte samples plus two-byte alpha.
		 *
		 * @param pixels The array holding the scan lines being built
		 * @param startPos Starting position within pixels of bytes to be filtered.
		 * @param width Width of a scanline in pixels.
		 */
		protected void FilterSub(byte[] pixels, int startPos, int width) {
			int i;
			int offset = bytesPerPixel;
			int actualStart = startPos + offset;
			int nBytes = width * bytesPerPixel;
			int leftInsert = offset;
			int leftExtract = 0;

			for (i = actualStart; i < startPos + nBytes; i++) {
				leftBytes[leftInsert] = pixels[i];
				pixels[i] = (byte) ((pixels[i] - leftBytes[leftExtract]) % 256);
				leftInsert = (leftInsert + 1) % 0x0f;
				leftExtract = (leftExtract + 1) % 0x0f;
			}
		}

		/**
		 * Perform "up" filtering on the given row.
		 * Side effect: refills the prior row with current row
		 *
		 * @param pixels The array holding the scan lines being built
		 * @param startPos Starting position within pixels of bytes to be filtered.
		 * @param width Width of a scanline in pixels.
		 */
		protected void FilterUp(byte[] pixels, int startPos, int width) {
			int i, nBytes;
			byte currentByte;

			nBytes = width * bytesPerPixel;

			for (i = 0; i < nBytes; i++) {
				currentByte = pixels[startPos + i];
				pixels[startPos + i] = (byte) ((pixels[startPos + i] - priorRow[i]) % 256);
				priorRow[i] = currentByte;
			}
		}

		/**
		 * Write the image data into the pngBytes array.
		 * This will write one or more PNG "IDAT" chunks. In order
		 * to conserve memory, this method grabs as many rows as will
		 * fit into 32K bytes, or the whole image; whichever is less.
		 *
		 *
		 * @return true if no errors; false if error grabbing pixels
		 */
		protected bool WriteImageData() {
			int rowsLeft = height;  // number of rows remaining to write
			int startRow = 0;       // starting row to process this time through
			int nRows;              // how many rows to grab at a time

			byte[] scanLines;       // the scan lines to be compressed
			int scanPos;            // where we are in the scan lines
			int startPos;           // where this line's actual pixels start (used for filtering)

			byte[] compressedLines; // the resultant compressed lines
			int nCompressed;        // how big is the compressed area?

			//int depth;              // color depth ( handle only 8 or 32 )

			bytesPerPixel = (encodeAlpha) ? 4 : 3;

			Deflater scrunch = new Deflater(compressionLevel);
			MemoryStream outBytes = new MemoryStream(1024);

			DeflaterOutputStream compBytes = new DeflaterOutputStream(outBytes, scrunch);
			try {
				while (rowsLeft > 0) {
					nRows = Math.Min(32767 / (width * (bytesPerPixel + 1)), rowsLeft);
					nRows = Math.Max(nRows, 1);

					int[] pixels = new int[width * nRows];
					Array.Copy(this.pixelData, width * startRow, pixels, 0, width * nRows);

					/*
					 * Create a data chunk. scanLines adds "nRows" for
					 * the filter bytes.
					 */
					scanLines = new byte[width * nRows * bytesPerPixel + nRows];

					if (filter == FILTER_SUB) {
						leftBytes = new byte[16];
					}
					if (filter == FILTER_UP) {
						priorRow = new byte[width * bytesPerPixel];
					}

					scanPos = 0;
					startPos = 1;
					for (int i = 0; i < width * nRows; i++) {
						if (i % width == 0) {
							scanLines[scanPos++] = (byte) filter;
							startPos = scanPos;
						}
						scanLines[scanPos++] = (byte) ((pixels[i] >> 16) & 0xff);
						scanLines[scanPos++] = (byte) ((pixels[i] >> 8) & 0xff);
						scanLines[scanPos++] = (byte) ((pixels[i]) & 0xff);
						if (encodeAlpha) {
							scanLines[scanPos++] = (byte) ((pixels[i] >> 24) & 0xff);
						}
						if ((i % width == width - 1) && (filter != FILTER_NONE)) {
							if (filter == FILTER_SUB) {
								FilterSub(scanLines, startPos, width);
							}
							if (filter == FILTER_UP) {
								FilterUp(scanLines, startPos, width);
							}
						}
					}

					/*
					 * Write these lines to the output area
					 */
					compBytes.Write(scanLines, 0, scanPos);

					startRow += nRows;
					rowsLeft -= nRows;
				}
				compBytes.Close();

				/*
				 * Write the compressed bytes
				 */
				compressedLines = outBytes.ToArray();
				nCompressed = compressedLines.Length;

				crc.Reset();
				bytePos = WriteInt4(nCompressed, bytePos);
				bytePos = WriteBytes(IDAT, bytePos);
				crc.Update(IDAT);
				bytePos = WriteBytes(compressedLines, nCompressed, bytePos);
				crc.Update(compressedLines, 0, nCompressed);

				crcValue = crc.Value;
				bytePos = WriteInt4((int) crcValue, bytePos);
				scrunch.Finish();
				return true;
			} catch {
				return false;
			}
		}

		/**
		 * Write a PNG "IEND" chunk into the pngBytes array.
		 */
		protected void writeEnd() {
			bytePos = WriteInt4(0, bytePos);
			bytePos = WriteBytes(IEND, bytePos);
			crc.Reset();
			crc.Update(IEND);
			crcValue = crc.Value;
			bytePos = WriteInt4((int) crcValue, bytePos);
		}
	}
}