text:
package org.apache.calcite.interpreter;

import org.apache.calcite.DataContext;
import org.apache.calcite.adapter.enumerable.AggImplementor;
import org.apache.calcite.adapter.enumerable.RexImpTable;
import org.apache.calcite.linq4j.Enumerable;
import org.apache.calcite.plan.Convention;
import org.apache.calcite.plan.RelOptCluster;
import org.apache.calcite.plan.RelOptCost;
import org.apache.calcite.plan.RelOptPlanner;
import org.apache.calcite.plan.RelOptRule;
import org.apache.calcite.plan.RelOptRuleCall;
import org.apache.calcite.plan.RelOptTable;
import org.apache.calcite.plan.RelRule;
import org.apache.calcite.plan.RelTraitSet;
import org.apache.calcite.rel.InvalidRelException;
import org.apache.calcite.rel.RelCollation;
import org.apache.calcite.rel.RelCollationTraitDef;
import org.apache.calcite.rel.RelNode;
import org.apache.calcite.rel.RelWriter;
import org.apache.calcite.rel.convert.ConverterRule;
import org.apache.calcite.rel.core.Aggregate;
import org.apache.calcite.rel.core.AggregateCall;
import org.apache.calcite.rel.core.CorrelationId;
import org.apache.calcite.rel.core.Filter;
import org.apache.calcite.rel.core.Intersect;
import org.apache.calcite.rel.core.Join;
import org.apache.calcite.rel.core.JoinRelType;
import org.apache.calcite.rel.core.Match;
import org.apache.calcite.rel.core.Minus;
import org.apache.calcite.rel.core.Project;
import org.apache.calcite.rel.core.SetOp;
import org.apache.calcite.rel.core.Sort;
import org.apache.calcite.rel.core.TableScan;
import org.apache.calcite.rel.core.Union;
import org.apache.calcite.rel.core.Values;
import org.apache.calcite.rel.core.Window;
import org.apache.calcite.rel.logical.LogicalAggregate;
import org.apache.calcite.rel.logical.LogicalFilter;
import org.apache.calcite.rel.logical.LogicalIntersect;
import org.apache.calcite.rel.logical.LogicalJoin;
import org.apache.calcite.rel.logical.LogicalMatch;
import org.apache.calcite.rel.logical.LogicalProject;
import org.apache.calcite.rel.logical.LogicalTableScan;
import org.apache.calcite.rel.logical.LogicalUnion;
import org.apache.calcite.rel.logical.LogicalValues;
import org.apache.calcite.rel.logical.LogicalWindow;
import org.apache.calcite.rel.metadata.RelMdCollation;
import org.apache.calcite.rel.metadata.RelMetadataQuery;
import org.apache.calcite.rel.type.RelDataType;
import org.apache.calcite.rel.type.RelDataTypeFactory;
import org.apache.calcite.rel.type.RelDataTypeField;
import org.apache.calcite.rex.RexLiteral;
import org.apache.calcite.rex.RexNode;
import org.apache.calcite.schema.FilterableTable;
import org.apache.calcite.schema.ProjectableFilterableTable;
import org.apache.calcite.schema.ScannableTable;
import org.apache.calcite.schema.Table;
import org.apache.calcite.tools.RelBuilderFactory;
import org.apache.calcite.util.ImmutableBitSet;
import org.apache.calcite.util.ImmutableIntList;

import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;

import org.checkerframework.checker.nullness.qual.Nullable;

import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.SortedSet;

/**
 * Utilities pertaining to {@link BindableRel} and {@link BindableConvention}.
 */
public class Bindables {
  private Bindables() {}

  public static final RelOptRule BINDABLE_TABLE_SCAN_RULE =
      BindableTableScanRule.Config.DEFAULT.toRule();

  public static final RelOptRule BINDABLE_FILTER_RULE =
      BindableFilterRule.DEFAULT_CONFIG.toRule(BindableFilterRule.class);

  public static final RelOptRule BINDABLE_PROJECT_RULE =
      BindableProjectRule.DEFAULT_CONFIG.toRule(BindableProjectRule.class);

  public static final RelOptRule BINDABLE_SORT_RULE =
      BindableSortRule.DEFAULT_CONFIG.toRule(BindableSortRule.class);

  public static final RelOptRule BINDABLE_JOIN_RULE =
      BindableJoinRule.DEFAULT_CONFIG.toRule(BindableJoinRule.class);

  public static final RelOptRule BINDABLE_SET_OP_RULE =
      BindableSetOpRule.DEFAULT_CONFIG.toRule(BindableSetOpRule.class);

  // CHECKSTYLE: IGNORE 1
  /** @deprecated Use {@link #BINDABLE_SET_OP_RULE}. */
  @SuppressWarnings("MissingSummary")
  public static final RelOptRule BINDABLE_SETOP_RULE =
      BINDABLE_SET_OP_RULE;

  public static final RelOptRule BINDABLE_VALUES_RULE =
      BindableValuesRule.DEFAULT_CONFIG.toRule(BindableValuesRule.class);

  public static final RelOptRule BINDABLE_AGGREGATE_RULE =
      BindableAggregateRule.DEFAULT_CONFIG.toRule(BindableAggregateRule.class);

  public static final RelOptRule BINDABLE_WINDOW_RULE =
      BindableWindowRule.DEFAULT_CONFIG.toRule(BindableWindowRule.class);

  public static final RelOptRule BINDABLE_MATCH_RULE =
      BindableMatchRule.DEFAULT_CONFIG.toRule(BindableMatchRule.class);

  /** Rule that converts a relational expression from
   * {@link org.apache.calcite.plan.Convention#NONE}
   * to {@link org.apache.calcite.interpreter.BindableConvention}. */
  public static final NoneToBindableConverterRule FROM_NONE_RULE =
      NoneToBindableConverterRule.DEFAULT_CONFIG
          .toRule(NoneToBindableConverterRule.class);

  /** All rules that convert logical relational expression to bindable. */
  public static final ImmutableList<RelOptRule> RULES =
      ImmutableList.of(FROM_NONE_RULE,
          BINDABLE_TABLE_SCAN_RULE,
          BINDABLE_FILTER_RULE,
          BINDABLE_PROJECT_RULE,
          BINDABLE_SORT_RULE,
          BINDABLE_JOIN_RULE,
          BINDABLE_SET_OP_RULE,
          BINDABLE_VALUES_RULE,
          BINDABLE_AGGREGATE_RULE,
          BINDABLE_WINDOW_RULE,
          BINDABLE_MATCH_RULE);

  /** Helper method that converts a bindable relational expression into a
   * record iterator.
   *
   *
Any bindable can be compiled; if its input is also bindable, it becomes
   * part of the same compilation unit.
   */
  private static Enumerable<@Nullable Object[]> help(DataContext dataContext,
      BindableRel rel) {
    return new Interpreter(dataContext, rel);
  }

  /** Rule that converts a {@link org.apache.calcite.rel.core.TableScan}
   * to bindable convention.
   *
   * @see #BINDABLE_TABLE_SCAN_RULE */
  public static class BindableTableScanRule
      extends RelRule<BindableTableScanRule.Config> {
    /** Called from Config. */
    protected BindableTableScanRule(Config config) {
      super(config);
    }

    @Deprecated // to be removed before 2.0
    public BindableTableScanRule(RelBuilderFactory relBuilderFactory) {
      this(Config.DEFAULT.withRelBuilderFactory(relBuilderFactory)
          .as(Config.class));
    }

    @Override public void onMatch(RelOptRuleCall call) {
      final LogicalTableScan scan = call.rel(0);
      final RelOptTable table = scan.getTable();
      if (BindableTableScan.canHandle(table)) {
        call.transformTo(
            BindableTableScan.create(scan.getCluster(), table));
      }
    }

    /** Rule configuration. */
    public interface Config extends RelRule.Config {
      Config DEFAULT = EMPTY
          .withOperandSupplier(b ->
              b.operand(LogicalTableScan.class).noInputs())
          .as(Config.class);

      @Override default BindableTableScanRule toRule() {
        return new BindableTableScanRule(this);
      }
    }
  }

  /** Scan of a table that implements {@link ScannableTable} and therefore can
   * be converted into an {@link Enumerable}. */
  public static class BindableTableScan
      extends TableScan implements BindableRel {
    public final ImmutableList<RexNode> filters;
    public final ImmutableIntList projects;

    /** Creates a BindableTableScan.
     *
     *
Use {@link #create} unless you know what you are doing. */
    BindableTableScan(RelOptCluster cluster, RelTraitSet traitSet,
        RelOptTable table, ImmutableList<RexNode> filters,
        ImmutableIntList projects) {
      super(cluster, traitSet, ImmutableList.of(), table);
      this.filters = Objects.requireNonNull(filters, "filters");
      this.projects = Objects.requireNonNull(projects, "projects");
      Preconditions.checkArgument(canHandle(table));
    }

    /** Creates a BindableTableScan. */
    public static BindableTableScan create(RelOptCluster cluster,
        RelOptTable relOptTable) {
      return create(cluster, relOptTable, ImmutableList.of(),
          identity(relOptTable));
    }

    /** Creates a BindableTableScan. */
    public static BindableTableScan create(RelOptCluster cluster,
        RelOptTable relOptTable, List<RexNode> filters,
        List<Integer> projects) {
      final Table table = relOptTable.unwrap(Table.class);
      final RelTraitSet traitSet =
          cluster.traitSetOf(BindableConvention.INSTANCE)
              .replaceIfs(RelCollationTraitDef.INSTANCE, () -> {
                if (table != null) {
                  return table.getStatistic().getCollations();
                }
                return ImmutableList.of();
              });
      return new BindableTableScan(cluster, traitSet, relOptTable,
          ImmutableList.copyOf(filters), ImmutableIntList.copyOf(projects));
    }

    @Override public RelDataType deriveRowType() {
      final RelDataTypeFactory.Builder builder =
          getCluster().getTypeFactory().builder();
      final List<RelDataTypeField> fieldList =
          table.getRowType().getFieldList();
      for (int project : projects) {
        builder.add(fieldList.get(project));
      }
      return builder.build();
    }

    @Override public Class<Object[]> getElementType() {
      return Object[].class;
    }

    @Override public RelWriter explainTerms(RelWriter pw) {
      return super.explainTerms(pw)
          .itemIf("filters", filters, !filters.isEmpty())
          .itemIf("projects", projects, !projects.equals(identity()));
    }

    @Override public @Nullable RelOptCost computeSelfCost(RelOptPlanner planner,
        RelMetadataQuery mq) {
      boolean noPushing = filters.isEmpty()
              && projects.size() == table.getRowType().getFieldCount();
      RelOptCost cost = super.computeSelfCost(planner, mq);
      if (noPushing || cost == null) {
        return cost;
      }
      // Cost factor for pushing filters
      double f = filters.isEmpty() ? 1d : 0.5d;

      // Cost factor for pushing fields
      // The "+ 2d" on top and bottom keeps the function fairly smooth.
      double p = ((double) projects.size() + 2d)
          / ((double) table.getRowType().getFieldCount() + 2d);

      // Multiply the cost by a factor that makes a scan more attractive if
      // filters and projects are pushed to the table scan
      return cost.multiplyBy(f * p * 0.01d);
    }

    public static boolean canHandle(RelOptTable table) {
      return table.maybeUnwrap(ScannableTable.class).isPresent()
          || table.maybeUnwrap(FilterableTable.class).isPresent()
          || table.maybeUnwrap(ProjectableFilterableTable.class).isPresent();
    }

    @Override public Enumerable<@Nullable Object[]> bind(DataContext dataContext) {
      return help(dataContext, this);
    }

    @Override public Node implement(InterpreterImplementor implementor) {
      throw new UnsupportedOperationException(); // TODO:
    }
  }

  /** Rule that converts a {@link Filter} to bindable convention.
   *
   * @see #BINDABLE_FILTER_RULE */
  public static class BindableFilterRule extends ConverterRule {
    /** Default configuration. */
    public static final Config DEFAULT_CONFIG = Config.INSTANCE
        .withConversion(LogicalFilter.class, f -> !f.containsOver(),
            Convention.NONE, BindableConvention.INSTANCE,
            "BindableFilterRule")
        .withRuleFactory(BindableFilterRule::new);

    /** Called from the Config. */
    protected BindableFilterRule(Config config) {
      super(config);
    }

    @Override public RelNode convert(RelNode rel) {
      final LogicalFilter filter = (LogicalFilter) rel;
      return BindableFilter.create(
          convert(filter.getInput(),
              filter.getInput().getTraitSet()
                  .replace(BindableConvention.INSTANCE)),
          filter.getCondition());
    }
  }

  /** Implementation of {@link org.apache.calcite.rel.core.Filter}
   * in bindable convention. */
  public static class BindableFilter extends Filter implements BindableRel {
    public BindableFilter(RelOptCluster cluster, RelTraitSet traitSet,
        RelNode input, RexNode condition) {
      super(cluster, traitSet, input, condition);
      assert getConvention() instanceof BindableConvention;
    }

    /** Creates a BindableFilter. */
    public static BindableFilter create(final RelNode input,
        RexNode condition) {
      final RelOptCluster cluster = input.getCluster();
      final RelMetadataQuery mq = cluster.getMetadataQuery();
      final RelTraitSet traitSet =
          cluster.traitSetOf(BindableConvention.INSTANCE)
              .replaceIfs(RelCollationTraitDef.INSTANCE,
                  () -> RelMdCollation.filter(mq, input));
      return new BindableFilter(cluster, traitSet, input, condition);
    }

    @Override public BindableFilter copy(RelTraitSet traitSet, RelNode input,
        RexNode condition) {
      return new BindableFilter(getCluster(), traitSet, input, condition);
    }

    @Override public Class<Object[]> getElementType() {
      return Object[].class;
    }

    @Override public Enumerable<@Nullable Object[]> bind(DataContext dataContext) {
      return help(dataContext, this);
    }

    @Override public Node implement(InterpreterImplementor implementor) {
      return new FilterNode(implementor.compiler, this);
    }
  }

  /**
   * Rule to convert a {@link org.apache.calcite.rel.logical.LogicalProject}
   * to a {@link BindableProject}.
   *
   * @see #BINDABLE_PROJECT_RULE
   */
  public static class BindableProjectRule extends ConverterRule {
    /** Default configuration. */
    public static final Config DEFAULT_CONFIG = Config.INSTANCE
        .withConversion(LogicalProject.class, p -> !p.containsOver(),
            Convention.NONE, BindableConvention.INSTANCE,
            "BindableProjectRule")
        .withRuleFactory(BindableProjectRule::new);

    /** Called from the Config. */
    protected BindableProjectRule(Config config) {
      super(config);
    }

    @Override public RelNode convert(RelNode rel) {
      final LogicalProject project = (LogicalProject) rel;
      return new BindableProject(rel.getCluster(),
          rel.getTraitSet().replace(BindableConvention.INSTANCE),
          convert(project.getInput(),
              project.getInput().getTraitSet()
                  .replace(BindableConvention.INSTANCE)),
          project.getProjects(),
          project.getRowType());
    }
  }

  /** Implementation of {@link org.apache.calcite.rel.core.Project} in
   * bindable calling convention. */
  public static class BindableProject extends Project implements BindableRel {
    public BindableProject(RelOptCluster cluster, RelTraitSet traitSet,
        RelNode input, List<? extends RexNode> projects, RelDataType rowType) {
      super(cluster, traitSet, ImmutableList.of(), input, projects, rowType);
      assert getConvention() instanceof BindableConvention;
    }

    @Override public BindableProject copy(RelTraitSet traitSet, RelNode input,
        List<RexNode> projects, RelDataType rowType) {
      return new BindableProject(getCluster(), traitSet, input,
          projects, rowType);
    }

    @Override public Class<Object[]> getElementType() {
      return Object[].class;
    }

    @Override public Enumerable<@Nullable Object[]> bind(DataContext dataContext) {
      return help(dataContext, this);
    }

    @Override public Node implement(InterpreterImplementor implementor) {
      return new ProjectNode(implementor.compiler, this);
    }
  }

  /**
   * Rule to convert an {@link org.apache.calcite.rel.core.Sort} to a
   * {@link org.apache.calcite.interpreter.Bindables.BindableSort}.
   *
   * @see #BINDABLE_SORT_RULE
   */
  public static class BindableSortRule extends ConverterRule {
    /** Default configuration. */
    public static final Config DEFAULT_CONFIG = Config.INSTANCE
        .withConversion(Sort.class, Convention.NONE,
            BindableConvention.INSTANCE, "BindableSortRule")
        .withRuleFactory(BindableSortRule::new);

    /** Called from the Config. */
    protected BindableSortRule(Config config) {
      super(config);
    }

    @Override public RelNode convert(RelNode rel) {
      final Sort sort = (Sort) rel;
      final RelTraitSet traitSet =
          sort.getTraitSet().replace(BindableConvention.INSTANCE);
      final RelNode input = sort.getInput();
      return new BindableSort(rel.getCluster(), traitSet,
          convert(input,
              input.getTraitSet().replace(BindableConvention.INSTANCE)),
          sort.getCollation(), sort.offset, sort.fetch);
    }
  }

  /** Implementation of {@link org.apache.calcite.rel.core.Sort}
   * bindable calling convention. */
  public static class BindableSort extends Sort implements BindableRel {
    public BindableSort(RelOptCluster cluster, RelTraitSet traitSet,
        RelNode input, RelCollation collation, @Nullable RexNode offset, @Nullable RexNode fetch) {
      super(cluster, traitSet, input, collation, offset, fetch);
      assert getConvention() instanceof BindableConvention;
    }

    @Override public BindableSort copy(RelTraitSet traitSet, RelNode newInput,
        RelCollation newCollation, @Nullable RexNode offset, @Nullable RexNode fetch) {
      return new BindableSort(getCluster(), traitSet, newInput, newCollation,
          offset, fetch);
    }

    @Override public Class<Object[]> getElementType() {
      return Object[].class;
    }

    @Override public Enumerable<@Nullable Object[]> bind(DataContext dataContext) {
      return help(dataContext, this);
    }

    @Override public Node implement(InterpreterImplementor implementor) {
      return new SortNode(implementor.compiler, this);
    }
  }

  /**
   * Rule to convert a {@link org.apache.calcite.rel.logical.LogicalJoin}
   * to a {@link BindableJoin}.
   *
   * @see #BINDABLE_JOIN_RULE
   */
  public static class BindableJoinRule extends ConverterRule {
    /** Default configuration. */
    public static final Config DEFAULT_CONFIG = Config.INSTANCE
        .withConversion(LogicalJoin.class, Convention.NONE,
            BindableConvention.INSTANCE, "BindableJoinRule")
        .withRuleFactory(BindableJoinRule::new);

    /** Called from the Config. */
    protected BindableJoinRule(Config config) {
      super(config);
    }

    @Override public RelNode convert(RelNode rel) {
      final LogicalJoin join = (LogicalJoin) rel;
      final BindableConvention out = BindableConvention.INSTANCE;
      final RelTraitSet traitSet = join.getTraitSet().replace(out);
      return new BindableJoin(rel.getCluster(), traitSet,
          convert(join.getLeft(),
              join.getLeft().getTraitSet()
                  .replace(BindableConvention.INSTANCE)),
          convert(join.getRight(),
              join.getRight().getTraitSet()
                  .replace(BindableConvention.INSTANCE)),
          join.getCondition(), join.getVariablesSet(), join.getJoinType());
    }
  }

  /** Implementation of {@link org.apache.calcite.rel.core.Join} in
   * bindable calling convention. */
  public static class BindableJoin extends Join implements BindableRel {
    /** Creates a BindableJoin. */
    protected BindableJoin(RelOptCluster cluster, RelTraitSet traitSet,
        RelNode left, RelNode right, RexNode condition,
        Set<CorrelationId> variablesSet, JoinRelType joinType) {
      super(cluster, traitSet, ImmutableList.of(), left, right,
          condition, variablesSet, joinType);
    }

    @Deprecated // to be removed before 2.0
    protected BindableJoin(RelOptCluster cluster, RelTraitSet traitSet,
        RelNode left, RelNode right, RexNode condition, JoinRelType joinType,
        Set<String> variablesStopped) {
      this(cluster, traitSet, left, right, condition,
          CorrelationId.setOf(variablesStopped), joinType);
    }

    @Override public BindableJoin copy(RelTraitSet traitSet, RexNode conditionExpr,
        RelNode left, RelNode right, JoinRelType joinType,
        boolean semiJoinDone) {
      return new BindableJoin(getCluster(), traitSet, left, right,
          conditionExpr, variablesSet, joinType);
    }

    @Override public Class<Object[]> getElementType() {
      return Object[].class;
    }

    @Override public Enumerable<@Nullable Object[]> bind(DataContext dataContext) {
      return help(dataContext, this);
    }

    @Override public Node implement(InterpreterImplementor implementor) {
      return new JoinNode(implementor.compiler, this);
    }
  }

  /**
   * Rule to convert an {@link SetOp} to a {@link BindableUnion}
   * or {@link BindableIntersect} or {@link BindableMinus}.
   *
   * @see #BINDABLE_SET_OP_RULE
   */
  public static class BindableSetOpRule extends ConverterRule {
    /** Default configuration. */
    public static final Config DEFAULT_CONFIG = Config.INSTANCE
        .withConversion(SetOp.class, Convention.NONE,
            BindableConvention.INSTANCE, "BindableSetOpRule")
        .withRuleFactory(BindableSetOpRule::new);

    /** Called from the Config. */
    protected BindableSetOpRule(Config config) {
      super(config);
    }

    @Override public RelNode convert(RelNode rel) {
      final SetOp setOp = (SetOp) rel;
      final BindableConvention out = BindableConvention.INSTANCE;
      final RelTraitSet traitSet = setOp.getTraitSet().replace(out);
      if (setOp instanceof LogicalUnion) {
        return new BindableUnion(rel.getCluster(), traitSet,
            convertList(setOp.getInputs(), out), setOp.all);
      } else if (setOp instanceof LogicalIntersect) {
        return new BindableIntersect(rel.getCluster(), traitSet,
            convertList(setOp.getInputs(), out), setOp.all);
      } else {
        return new BindableMinus(rel.getCluster(), traitSet,
            convertList(setOp.getInputs(), out), setOp.all);
      }
    }
  }

  /** Implementation of {@link org.apache.calcite.rel.core.Union} in
   * bindable calling convention. */
  public static class BindableUnion extends Union implements BindableRel {
    public BindableUnion(RelOptCluster cluster, RelTraitSet traitSet,
        List<RelNode> inputs, boolean all) {
      super(cluster, traitSet, inputs, all);
    }

    @Override public BindableUnion copy(RelTraitSet traitSet, List<RelNode> inputs,
        boolean all) {
      return new BindableUnion(getCluster(), traitSet, inputs, all);
    }

    @Override public Class<Object[]> getElementType() {
      return Object[].class;
    }

    @Override public Enumerable<@Nullable Object[]> bind(DataContext dataContext) {
      return help(dataContext, this);
    }

    @Override public Node implement(InterpreterImplementor implementor) {
      return new SetOpNode(implementor.compiler, this);
    }
  }

  /** Implementation of {@link org.apache.calcite.rel.core.Intersect} in
   * bindable calling convention. */
  public static class BindableIntersect extends Intersect implements BindableRel {
    public BindableIntersect(RelOptCluster cluster, RelTraitSet traitSet,
        List<RelNode> inputs, boolean all) {
      super(cluster, traitSet, inputs, all);
    }

    @Override public BindableIntersect copy(RelTraitSet traitSet, List<RelNode> inputs,
        boolean all) {
      return new BindableIntersect(getCluster(), traitSet, inputs, all);
    }

    @Override public Class<Object[]> getElementType() {
      return Object[].class;
    }

    @Override public Enumerable<@Nullable Object[]> bind(DataContext dataContext) {
      return help(dataContext, this);
    }

    @Override public Node implement(InterpreterImplementor implementor) {
      return new SetOpNode(implementor.compiler, this);
    }
  }

  /** Implementation of {@link org.apache.calcite.rel.core.Minus} in
   * bindable calling convention. */
  public static class BindableMinus extends Minus implements BindableRel {
    public BindableMinus(RelOptCluster cluster, RelTraitSet traitSet,
        List<RelNode> inputs, boolean all) {
      super(cluster, traitSet, inputs, all);
    }

    @Override public BindableMinus copy(RelTraitSet traitSet, List<RelNode> inputs, boolean all) {
      return new BindableMinus(getCluster(), traitSet, inputs, all);
    }

    @Override public Class<Object[]> getElementType() {
      return Object[].class;
    }

    @Override public Enumerable<@Nullable Object[]> bind(DataContext dataContext) {
      return help(dataContext, this);
    }

    @Override public Node implement(InterpreterImplementor implementor) {
      return new SetOpNode(implementor.compiler, this);
    }
  }

  /** Implementation of {@link org.apache.calcite.rel.core.Values}
   * in bindable calling convention. */
  public static class BindableValues extends Values implements BindableRel {
    BindableValues(RelOptCluster cluster, RelDataType rowType,
        ImmutableList<ImmutableList<RexLiteral>> tuples, RelTraitSet traitSet) {
      super(cluster, rowType, tuples, traitSet);
    }

    @Override public RelNode copy(RelTraitSet traitSet, List<RelNode> inputs) {
      assert inputs.isEmpty();
      return new BindableValues(getCluster(), getRowType(), tuples, traitSet);
    }

    @Override public Class<Object[]> getElementType() {
      return Object[].class;
    }

    @Override public Enumerable<@Nullable Object[]> bind(DataContext dataContext) {
      return help(dataContext, this);
    }

    @Override public Node implement(InterpreterImplementor implementor) {
      return new ValuesNode(implementor.compiler, this);
    }
  }

  /** Rule that converts a {@link Values} to bindable convention.
   *
   * @see #BINDABLE_VALUES_RULE */
  public static class BindableValuesRule extends ConverterRule {
    /** Default configuration. */
    public static final Config DEFAULT_CONFIG = Config.INSTANCE
        .withConversion(LogicalValues.class, Convention.NONE,
            BindableConvention.INSTANCE, "BindableValuesRule")
        .withRuleFactory(BindableValuesRule::new);

    /** Called from the Config. */
    protected BindableValuesRule(Config config) {
      super(config);
    }

    @Override public RelNode convert(RelNode rel) {
      LogicalValues values = (LogicalValues) rel;
      return new BindableValues(values.getCluster(), values.getRowType(),
          values.getTuples(),
          values.getTraitSet().replace(BindableConvention.INSTANCE));
    }
  }

  /** Implementation of {@link org.apache.calcite.rel.core.Aggregate}
   * in bindable calling convention. */
  public static class BindableAggregate extends Aggregate
      implements BindableRel {
    public BindableAggregate(
        RelOptCluster cluster,
        RelTraitSet traitSet,
        RelNode input,
        ImmutableBitSet groupSet,
        @Nullable List<ImmutableBitSet> groupSets,
        List<AggregateCall> aggCalls)
        throws InvalidRelException {
      super(cluster, traitSet, ImmutableList.of(), input, groupSet, groupSets, aggCalls);
      assert getConvention() instanceof BindableConvention;

      for (AggregateCall aggCall : aggCalls) {
        if (aggCall.isDistinct()) {
          throw new InvalidRelException(
              "distinct aggregation not supported");
        }
        if (aggCall.distinctKeys != null) {
          throw new InvalidRelException(
              "within-distinct aggregation not supported");
        }
        AggImplementor implementor2 =
            RexImpTable.INSTANCE.get(aggCall.getAggregation(), false);
        if (implementor2 == null) {
          throw new InvalidRelException(
              "aggregation " + aggCall.getAggregation() + " not supported");
        }
      }
    }

    @Deprecated // to be removed before 2.0
    public BindableAggregate(RelOptCluster cluster, RelTraitSet traitSet,
        RelNode input, boolean indicator, ImmutableBitSet groupSet,
        List<ImmutableBitSet> groupSets, List<AggregateCall> aggCalls)
        throws InvalidRelException {
      this(cluster, traitSet, input, groupSet, groupSets, aggCalls);
      checkIndicator(indicator);
    }

    @Override public BindableAggregate copy(RelTraitSet traitSet, RelNode input,
        ImmutableBitSet groupSet,
        @Nullable List<ImmutableBitSet> groupSets, List<AggregateCall> aggCalls) {
      try {
        return new BindableAggregate(getCluster(), traitSet, input,
            groupSet, groupSets, aggCalls);
      } catch (InvalidRelException e) {
        // Semantic error not possible. Must be a bug. Convert to
        // internal error.
        throw new AssertionError(e);
      }
    }

    @Override public Class<Object[]> getElementType() {
      return Object[].class;
    }

    @Override public Enumerable<@Nullable Object[]> bind(DataContext dataContext) {
      return help(dataContext, this);
    }

    @Override public Node implement(InterpreterImplementor implementor) {
      return new AggregateNode(implementor.compiler, this);
    }
  }

  /** Rule that converts an {@link Aggregate} to bindable convention.
   *
   * @see #BINDABLE_AGGREGATE_RULE */
  public static class BindableAggregateRule extends ConverterRule {
    /** Default configuration. */
    public static final Config DEFAULT_CONFIG = Config.INSTANCE
        .withConversion(LogicalAggregate.class, Convention.NONE,
            BindableConvention.INSTANCE, "BindableAggregateRule")
        .withRuleFactory(BindableAggregateRule::new);

    /** Called from the Config. */
    protected BindableAggregateRule(Config config) {
      super(config);
    }

    @Override public @Nullable RelNode convert(RelNode rel) {
      final LogicalAggregate agg = (LogicalAggregate) rel;
      final RelTraitSet traitSet =
          agg.getTraitSet().replace(BindableConvention.INSTANCE);
      try {
        return new BindableAggregate(rel.getCluster(), traitSet,
            convert(agg.getInput(), traitSet), false, agg.getGroupSet(),
            agg.getGroupSets(), agg.getAggCallList());
      } catch (InvalidRelException e) {
        RelOptPlanner.LOGGER.debug(e.toString());
        return null;
      }
    }
  }

  /** Implementation of {@link org.apache.calcite.rel.core.Window}
   * in bindable convention. */
  public static class BindableWindow extends Window implements BindableRel {
    /** Creates a BindableWindow. */
    BindableWindow(RelOptCluster cluster, RelTraitSet traitSet, RelNode input,
        List<RexLiteral> constants, RelDataType rowType, List<Group> groups) {
      super(cluster, traitSet, input, constants, rowType, groups);
    }

    @Override public RelNode copy(RelTraitSet traitSet, List<RelNode> inputs) {
      return new BindableWindow(getCluster(), traitSet, sole(inputs),
          constants, getRowType(), groups);
    }

    @Override public @Nullable RelOptCost computeSelfCost(RelOptPlanner planner,
        RelMetadataQuery mq) {
      RelOptCost cost = super.computeSelfCost(planner, mq);
      if (cost == null) {
        return null;
      }
      return cost.multiplyBy(BindableConvention.COST_MULTIPLIER);
    }

    @Override public Class<Object[]> getElementType() {
      return Object[].class;
    }

    @Override public Enumerable<@Nullable Object[]> bind(DataContext dataContext) {
      return help(dataContext, this);
    }

    @Override public Node implement(InterpreterImplementor implementor) {
      return new WindowNode(implementor.compiler, this);
    }
  }

  /** Rule to convert a {@link org.apache.calcite.rel.logical.LogicalWindow}
   * to a {@link BindableWindow}.
   *
   * @see #BINDABLE_WINDOW_RULE */
  public static class BindableWindowRule extends ConverterRule {
    /** Default configuration. */
    public static final Config DEFAULT_CONFIG = Config.INSTANCE
        .withConversion(LogicalWindow.class, Convention.NONE,
            BindableConvention.INSTANCE, "BindableWindowRule")
        .withRuleFactory(BindableWindowRule::new);

    /** Called from the Config. */
    protected BindableWindowRule(Config config) {
      super(config);
    }

    @Override public RelNode convert(RelNode rel) {
      final LogicalWindow winAgg = (LogicalWindow) rel;
      final RelTraitSet traitSet =
          winAgg.getTraitSet().replace(BindableConvention.INSTANCE);
      final RelNode input = winAgg.getInput();
      final RelNode convertedInput =
          convert(input,
              input.getTraitSet().replace(BindableConvention.INSTANCE));
      return new BindableWindow(rel.getCluster(), traitSet, convertedInput,
          winAgg.getConstants(), winAgg.getRowType(), winAgg.groups);
    }
  }

  /** Implementation of {@link org.apache.calcite.rel.core.Match}
   * in bindable convention. */
  public static class BindableMatch extends Match implements BindableRel {
    /** Singleton instance of BindableMatch. */
    BindableMatch(RelOptCluster cluster, RelTraitSet traitSet, RelNode input,
        RelDataType rowType, RexNode pattern, boolean strictStart,
        boolean strictEnd, Map<String, RexNode> patternDefinitions,
        Map<String, RexNode> measures, RexNode after,
        Map<String, ? extends SortedSet<String>> subsets, boolean allRows,
        ImmutableBitSet partitionKeys, RelCollation orderKeys,
        @Nullable RexNode interval) {
      super(cluster, traitSet, input, rowType, pattern, strictStart, strictEnd,
          patternDefinitions, measures, after, subsets, allRows, partitionKeys,
          orderKeys, interval);
    }

    @Override public RelNode copy(RelTraitSet traitSet, List<RelNode> inputs) {
      return new BindableMatch(getCluster(), traitSet, inputs.get(0), getRowType(),
          pattern, strictStart, strictEnd, patternDefinitions, measures, after,
          subsets, allRows, partitionKeys, orderKeys, interval);
    }

    @Override public Class<Object[]> getElementType() {
      return Object[].class;
    }

    @Override public Enumerable<@Nullable Object[]> bind(DataContext dataContext) {
      return help(dataContext, this);
    }

    @Override public Node implement(InterpreterImplementor implementor) {
      return new MatchNode(implementor.compiler, this);
    }
  }

  /**
   * Rule to convert a {@link org.apache.calcite.rel.logical.LogicalMatch}
   * to a {@link BindableMatch}.
   *
   * @see #BINDABLE_MATCH_RULE
   */
  public static class BindableMatchRule extends ConverterRule {
    /** Default configuration. */
    public static final Config DEFAULT_CONFIG = Config.INSTANCE
        .withConversion(LogicalMatch.class, Convention.NONE,
            BindableConvention.INSTANCE, "BindableMatchRule")
        .withRuleFactory(BindableMatchRule::new);

    /** Called from the Config. */
    protected BindableMatchRule(Config config) {
      super(config);
    }

    @Override public RelNode convert(RelNode rel) {
      final LogicalMatch match = (LogicalMatch) rel;
      final RelTraitSet traitSet =
          match.getTraitSet().replace(BindableConvention.INSTANCE);
      final RelNode input = match.getInput();
      final RelNode convertedInput =
          convert(input,
              input.getTraitSet().replace(BindableConvention.INSTANCE));
      return new BindableMatch(rel.getCluster(), traitSet, convertedInput,
          match.getRowType(), match.getPattern(), match.isStrictStart(),
          match.isStrictEnd(), match.getPatternDefinitions(),
          match.getMeasures(), match.getAfter(), match.getSubsets(),
          match.isAllRows(), match.getPartitionKeys(), match.getOrderKeys(),
          match.getInterval());
    }
  }

}


text:
package native

import (
	"github.com/go-delve/delve/pkg/proc"
	"github.com/go-delve/delve/pkg/proc/winutil"
)

func newContext() *winutil.ARM64CONTEXT {
	return winutil.NewARM64CONTEXT()
}

func registers(t *nativeThread) (proc.Registers, error) {
	context := newContext()

	context.SetFlags(_CONTEXT_ALL)
	err := t.getContext(context)
	if err != nil {
		return nil, err
	}

	return winutil.NewARM64Registers(context, t.dbp.iscgo), nil
}

func newRegisters(context *winutil.ARM64CONTEXT, TebBaseAddress uint64, iscgo bool) *winutil.ARM64Registers {
	return winutil.NewARM64Registers(context, iscgo)
}

func (t *nativeThread) setContext(context *winutil.ARM64CONTEXT) error {
	return _SetThreadContext(t.os.hThread, context)
}

func (t *nativeThread) getContext(context *winutil.ARM64CONTEXT) error {
	return _GetThreadContext(t.os.hThread, context)
}

func (t *nativeThread) restoreRegisters(savedRegs proc.Registers) error {
	return t.setContext(savedRegs.(*winutil.ARM64Registers).Context)
}

redpajama_set_name: RedPajamaGithub


text:
---
title: Storm State Management
layout: documentation
documentation: true
---
# State support in core storm
Storm core has abstractions for bolts to save and retrieve the state of its operations. There is a default in-memory
based state implementation and also a Redis backed implementation that provides state persistence.

## State management
Bolts that requires its state to be managed and persisted by the framework should implement the `IStatefulBolt` interface or
extend the `BaseStatefulBolt` and implement `void initState(T state)` method. The `initState` method is invoked by the framework
during the bolt initialization with the previously saved state of the bolt. This is invoked after prepare but before the bolt starts
processing any tuples.

Currently the only kind of `State` implementation that is supported is `KeyValueState` which provides key-value mapping.

For example a word count bolt could use the key value state abstraction for the word counts as follows.

1. Extend the BaseStatefulBolt and type parameterize it with KeyValueState which would store the mapping of word to count.
2. The bolt gets initialized with its previously saved state in the init method. This will contain the word counts
last committed by the framework during the previous run.
3. In the execute method, update the word count.

 ```java
 public class WordCountBolt extends BaseStatefulBolt<KeyValueState<String, Long>> {
 private KeyValueState<String, Long> wordCounts;
 private OutputCollector collector;
 ...
     @Override
     public void prepare(Map stormConf, TopologyContext context, OutputCollector collector) {
       this.collector = collector;
     }
     @Override
     public void initState(KeyValueState<String, Long> state) {
       wordCounts = state;
     }
     @Override
     public void execute(Tuple tuple) {
       String word = tuple.getString(0);
       Integer count = wordCounts.get(word, 0);
       count++;
       wordCounts.put(word, count);
       collector.emit(tuple, new Values(word, count));
       collector.ack(tuple);
     }
 ...
 }
 ```
4. The framework periodically checkpoints the state of the bolt (default every second). The frequency
can be changed by setting the storm config `topology.state.checkpoint.interval.ms`
5. For state persistence, use a state provider that supports persistence by setting the `topology.state.provider` in the
storm config. E.g. for using Redis based key-value state implementation set `topology.state.provider: org.apache.storm.redis.state.RedisKeyValueStateProvider`
in storm.yaml. The provider implementation jar should be in the class path, which in this case means putting the `storm-redis-*.jar`
in the extlib directory.
6. The state provider properties can be overridden by setting `topology.state.provider.config`. For Redis state this is a
json config with the following properties.

 ```
 {
   "keyClass": "Optional fully qualified class name of the Key type.",
   "valueClass": "Optional fully qualified class name of the Value type.",
   "keySerializerClass": "Optional Key serializer implementation class.",
   "valueSerializerClass": "Optional Value Serializer implementation class.",
   "jedisPoolConfig": {
     "host": "localhost",
     "port": 6379,
     "timeout": 2000,
     "database": 0,
     "password": "xyz"
     }
 }
 ```

## Checkpoint mechanism
Checkpoint is triggered by an internal checkpoint spout at the specified `topology.state.checkpoint.interval.ms`. If there is
at-least one `IStatefulBolt` in the topology, the checkpoint spout is automatically added by the topology builder . For stateful topologies,
the topology builder wraps the `IStatefulBolt` in a `StatefulBoltExecutor` which handles the state commits on receiving the checkpoint tuples.
The non stateful bolts are wrapped in a `CheckpointTupleForwarder` which just forwards the checkpoint tuples so that the checkpoint tuples
can flow through the topology DAG. The checkpoint tuples flow through a separate internal stream namely `$checkpoint`. The topology builder
wires the checkpoint stream across the whole topology with the checkpoint spout at the root.

```
              default                         default               default
[spout1]   ---------------> [statefulbolt1] ----------> [bolt1] --------------> [statefulbolt2]
                          |                 ---------->         -------------->
                          |                   ($chpt)               ($chpt)
                          |
[$checkpointspout] _______| ($chpt)
```

At checkpoint intervals the checkpoint tuples are emitted by the checkpoint spout. On receiving a checkpoint tuple, the state of the bolt
is saved and then the checkpoint tuple is forwarded to the next component. Each bolt waits for the checkpoint to arrive on all its input
streams before it saves its state so that the state represents a consistent state across the topology. Once the checkpoint spout receives
ACK from all the bolts, the state commit is complete and the transaction is recorded as committed by the checkpoint spout.

The state checkpointing does not currently checkpoint the state of the spout. Yet, once the state of all bolts are checkpointed, and once the checkpoint tuples are acked, the tuples emitted by the spout are also acked.
It also implies that `topology.state.checkpoint.interval.ms` is lower than `topology.message.timeout.secs`.

The state commit works like a three phase commit protocol with a prepare and commit phase so that the state across the topology is saved
in a consistent and atomic manner.

### Recovery
The recovery phase is triggered when the topology is started for the first time. If the previous transaction was not successfully
prepared, a `rollback` message is sent across the topology so that if a bolt has some prepared transactions it can be discarded.
If the previous transaction was prepared successfully but not committed, a `commit` message is sent across the topology so that
the prepared transactions can be committed. After these steps are complete, the bolts are initialized with the state.

The recovery is also triggered if one of the bolts fails to acknowledge the checkpoint message or say a worker crashed in
the middle. Thus when the worker is restarted by the supervisor, the checkpoint mechanism makes sure that the bolt gets
initialized with its previous state and the checkpointing continues from the point where it left off.

### Guarantee
Storm relies on the acking mechanism to replay tuples in case of failures. It is possible that the state is committed
but the worker crashes before acking the tuples. In this case the tuples are replayed causing duplicate state updates.
Also currently the StatefulBoltExecutor continues to process the tuples from a stream after it has received a checkpoint
tuple on one stream while waiting for checkpoint to arrive on other input streams for saving the state. This can also cause
duplicate state updates during recovery.

The state abstraction does not eliminate duplicate evaluations and currently provides only at-least once guarantee.

In order to provide the at-least once guarantee, all bolts in a stateful topology are expected to anchor the tuples while emitting and ack the input tuples once its processed. For non-stateful bolts, the anchoring/acking can be automatically managed by extending the `BaseBasicBolt`. Stateful bolts are expected to anchor tuples while emitting and ack the tuple after processing like in the `WordCountBolt` example in the State management section above.

### IStateful bolt hooks
IStateful bolt interface provides hook methods where in the stateful bolts could implement some custom actions.
```java
    /**
     * This is a hook for the component to perform some actions just before the
     * framework commits its state.
     */
    void preCommit(long txid);

    /**
     * This is a hook for the component to perform some actions just before the
     * framework prepares its state.
     */
    void prePrepare(long txid);

    /**
     * This is a hook for the component to perform some actions just before the
     * framework rolls back the prepared state.
     */
    void preRollback();
```
This is optional and stateful bolts are not expected to provide any implementation. This is provided so that other
system level components can be built on top of the stateful abstractions where we might want to take some actions before the
stateful bolt's state is prepared, committed or rolled back.

## Providing custom state implementations
Currently the only kind of `State` implementation supported is `KeyValueState` which provides key-value mapping.

Custom state implementations should provide implementations for the methods defined in the `org.apache.storm.State` interface.
These are the `void prepareCommit(long txid)`, `void commit(long txid)`, `rollback()` methods. `commit()` method is optional
and is useful if the bolt manages the state on its own. This is currently used only by the internal system bolts,
for e.g. the CheckpointSpout to save its state.

`KeyValueState` implementation should also implement the methods defined in the `org.apache.storm.state.KeyValueState` interface.

### State provider
The framework instantiates the state via the corresponding `StateProvider` implementation. A custom state should also provide
a `StateProvider` implementation which can load and return the state based on the namespace. Each state belongs to a unique namespace.
The namespace is typically unique per task so that each task can have its own state. The StateProvider and the corresponding
State implementation should be available in the class path of Storm (by placing them in the extlib directory).


text:
import { CommercialFinancing_01 } from "../../";

export = CommercialFinancing_01;


text:
package com.serphacker.serposcope.models.google;

import static com.serphacker.serposcope.models.google.GoogleTarget.PatternType.DOMAIN;
import static com.serphacker.serposcope.models.google.GoogleTarget.PatternType.SUBDOMAIN;
import java.util.Objects;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;

public class GoogleTarget {

    public enum PatternType {
        DOMAIN,
        SUBDOMAIN,
        REGEX
    };

    protected final static Pattern PATTERN_DOMAIN = Pattern.compile("^[a-zA-Z0-9-.]{1,61}\\.[a-zA-Z]{2,}$");

    int id;
    int groupId;
    String name;
    PatternType type;
    String pattern;

    Pattern compiledPattern;

    public GoogleTarget(int groupId, String name, PatternType type, String pattern) {
        this.groupId = groupId;
        this.name = name;
        setPattern(type, pattern);
    }

    public GoogleTarget(int id, int groupId, String name, PatternType type, String pattern) {
        this(groupId, name, type, pattern);
        this.id = id;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public int getGroupId() {
        return groupId;
    }

    public void setGroupId(int groupId) {
        this.groupId = groupId;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public boolean match(String url){
        return compiledPattern.matcher(url).find();
    }

    public final void setPattern(PatternType type, String pattern) throws PatternSyntaxException {
        this.type = type;
        this.pattern = pattern;
        this.compiledPattern = GoogleTarget.compile(type, pattern);
    }

    public static boolean isValidPattern(PatternType type, String pattern){
        if(pattern == null || pattern.isEmpty()){
            return false;
        }

        if(DOMAIN.equals(type) || SUBDOMAIN.equals(type)){
            return PATTERN_DOMAIN.matcher(pattern).find();
        }

        try {
            if(Pattern.compile(pattern) != null){
                return true;
            }
        } catch(Exception ex){
        }

        return false;
    }

    public static Pattern compile(PatternType type, String pattern) throws PatternSyntaxException {
        switch(type){
            case DOMAIN:
                return Pattern.compile("^https?://" + Pattern.quote(pattern) + "(/|$)");
            case SUBDOMAIN:
                return Pattern.compile("^https?://([^/]+\\.)?" + Pattern.quote(pattern) + "(/|$)");
            default:
                return Pattern.compile(pattern);
        }
    }

    public PatternType getType() {
        return type;
    }

    public String getPattern() {
        return pattern;
    }

    @Override
    public int hashCode() {
        int hash = 5;
        hash = 53 * hash + this.id;
        hash = 53 * hash + this.groupId;
        hash = 53 * hash + Objects.hashCode(this.name);
        hash = 53 * hash + Objects.hashCode(this.type);
        hash = 53 * hash + Objects.hashCode(this.pattern);
        return hash;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final GoogleTarget other = (GoogleTarget) obj;
        if (this.id != other.id) {
            return false;
        }
        if (this.groupId != other.groupId) {
            return false;
        }
        if (!Objects.equals(this.name, other.name)) {
            return false;
        }
        if (!Objects.equals(this.pattern, other.pattern)) {
            return false;
        }
        if (this.type != other.type) {
            return false;
        }
        return true;
    }

}


text:
BoxParser.SampleGroupEntry.prototype.parse = function(stream, length) {
	Log.warn("BoxParser", "Unknown Sample Group type: "+this.grouping_type);
	this.data =  stream.readUint8Array(length);
}


text:
package thredds.catalog.dl;

import java.nio.charset.StandardCharsets;
import thredds.catalog.*;
import thredds.catalog.crawl.CatalogCrawler;
import ucar.nc2.units.DateRange;
import ucar.nc2.units.DateType;
import org.jdom2.*;
import org.jdom2.output.*;
import java.io.*;
import java.util.*;
import java.net.URI;
import ucar.nc2.units.TimeDuration;
import ucar.unidata.geoloc.*;
import ucar.unidata.util.StringUtil2;

public class DIFWriter {
  private static org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(DIFWriter.class);

  private static final Namespace defNS = Namespace.getNamespace("http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/");
  private static String schemaLocation = "http://gcmd.nasa.gov/Aboutus/xml/dif/dif.xsd";

  private String fileDir;
  private StringBuilder messBuffer;
  private boolean debug = false;

  public DIFWriter() {}

  /**
   * Write all harvestable datasets to DIF records that have at least the minimum metadata.
   * Call isDatasetUseable() to find out.
   *
   * @param cat harvest the datasets starting from here
   * @param fileDir write records to this directory. The dataset id is used as the filename, appending "dif.xml"
   * @param mess status messages are appended here
   */
  public void writeDatasetEntries(InvCatalogImpl cat, String fileDir, StringBuilder mess) {
    this.fileDir = fileDir;
    this.messBuffer = mess;

    File dir = new File(fileDir);
    if (!dir.exists()) {
      boolean ret = dir.mkdirs();
      assert ret;
    }

    CatalogCrawler.Listener listener = new CatalogCrawler.Listener() {
      public void getDataset(InvDataset ds, Object context) {
        doOneDataset(ds);
      }

      public boolean getCatalogRef(InvCatalogRef dd, Object context) {
        return true;
      }

    };

    ByteArrayOutputStream bis = new ByteArrayOutputStream();
    PrintWriter pw = new PrintWriter(new OutputStreamWriter(bis, StandardCharsets.UTF_8));
    CatalogCrawler crawler = new CatalogCrawler(CatalogCrawler.USE_ALL, true, listener);
    crawler.crawl(cat, null, pw, null);
    mess.append("\n*********************\n");
    mess.append(new String(bis.toByteArray(), StandardCharsets.UTF_8));
  }

  /**
   * Write a DIF record for a specific dataset
   *
   * @param ds use this dataset
   */
  public void doOneDataset(InvDataset ds) {
    if (debug)
      System.out.println("doDataset " + ds.getName());

    if (isDatasetUseable(ds, messBuffer)) {
      String id = StringUtil2.replace(ds.getID(), "/", "-");
      String fileOutName = fileDir + "/" + id + ".dif.xml";
      try {
        OutputStream out = new BufferedOutputStream(new FileOutputStream(fileOutName));
        // writeOneEntry(ds, System.out, mess);
        writeOneEntry(ds, out, messBuffer);
        out.close();
        messBuffer.append(" OK on Write\n");
      } catch (IOException ioe) {
        messBuffer.append("DIFWriter failed on write " + ioe.getMessage() + "\n");
        log.error("DIFWriter failed on write " + ioe.getMessage(), ioe);
      }
    }
  }

  /**
   * Write a DIF record for a specific dataset
   *
   * @param ds use this dataset
   * @param fileDir write records to this directory. The dataset id is used as the filename, appending "dif.xml"
   * @param mess status messages are appended here
   */
  public void doOneDataset(InvDataset ds, String fileDir, StringBuilder mess) {
    if (debug)
      System.out.println("doDataset " + ds.getName());

    if (isDatasetUseable(ds, mess)) {
      String id = StringUtil2.replace(ds.getID(), "/", "-");
      String fileOutName = fileDir + "/" + id + ".dif.xml";
      try {
        OutputStream out = new BufferedOutputStream(new FileOutputStream(fileOutName));
        // writeOneEntry(ds, System.out, mess);
        writeOneEntry(ds, out, mess);
        out.close();
        mess.append(" OK on Write\n");
      } catch (IOException ioe) {
        mess.append("DIFWriter failed on write " + ioe.getMessage() + "\n");
        log.error("DIFWriter failed on write " + ioe.getMessage(), ioe);
      }
    }
  }

  /**
   * See if a dataset is harvestable to a DIF record.
   *
   * @param ds check this dataset.
   * @param sbuff put status messages here.
   * @return true if a DIF record can be written
   */
  public boolean isDatasetUseable(InvDataset ds, StringBuilder sbuff) {
    boolean ok = true;
    sbuff.append("Dataset " + ds.getName() + " id = " + ds.getID() + ": ");

    if (!ds.isHarvest()) {
      ok = false;
      sbuff.append("Dataset " + ds.getName() + " id = " + ds.getID() + " has harvest = false\n");
    }

    if (ds.getName() == null) {
      ok = false;
      sbuff.append(" missing Name field\n");
    }

    if (ds.getUniqueID() == null) {
      ok = false;
      sbuff.append(" missing ID field\n");
    }

    ThreddsMetadata.Variables vs = ds.getVariables("DIF");
    if ((vs == null) || (vs.getVariableList().size() == 0))
      vs = ds.getVariables("GRIB-1");
    if ((vs == null) || (vs.getVariableList().size() == 0))
      vs = ds.getVariables("GRIB-2");
    if ((vs == null) || (vs.getVariableList().size() == 0)) {
      ok = false;
      sbuff.append(" missing Variables with DIF or GRIB compatible vocabulary\n");
    }

    List list = ds.getPublishers();
    if ((list == null) || (list.size() == 0)) {
      ok = false;
      sbuff.append(" must have publisher element that defines the data center\n");
    }

    String summary = ds.getDocumentation("summary");
    if (summary == null) {
      ok = false;
      sbuff.append(" must have documentation element of type summary\n");
    }

    sbuff.append(" useable= " + ok + "\n");
    return ok;
  }

  private void writeOneEntry(InvDataset ds, OutputStream out, StringBuilder mess) throws IOException {
    Element rootElem = new Element("DIF", defNS);
    Document doc = new Document(rootElem);
    writeDataset(ds, rootElem, mess);
    rootElem.addNamespaceDeclaration(defNS);
    rootElem.addNamespaceDeclaration(XMLEntityResolver.xsiNS);
    rootElem.setAttribute("schemaLocation", defNS.getURI() + " " + schemaLocation, XMLEntityResolver.xsiNS);

    // Output the document, use standard formatter
    XMLOutputter fmt = new XMLOutputter(Format.getPrettyFormat());
    fmt.output(doc, out);
  }

  private Iterator translateGribVocabulary(ThreddsMetadata.Variables vs, boolean isGrib1, StringBuilder mess) {
    if (vs == null)
      return null;

    VocabTranslator vt;
    try {
      vt = isGrib1 ? (VocabTranslator) Grib1toDIF.getInstance() : (VocabTranslator) Grib2toDIF.getInstance();
    } catch (IOException e) {
      log.error("DIFWriter failed opening GribtoDIF VocabTranslator ", e);
      return null;
    }

    // hash on DIF names to eliminate duplicates
    Map<String, ThreddsMetadata.Variable> hash = new HashMap<String, ThreddsMetadata.Variable>(100);
    for (ThreddsMetadata.Variable v : vs.getVariableList()) {
      String fromVocabId = v.getVocabularyId();
      if (fromVocabId == null) {
        mess.append("** no id for " + v.getName() + "\n");
        continue;
      }

      String toVocabName = vt.translate(fromVocabId);
      if (toVocabName == null) {
        mess.append("** no translation for " + fromVocabId + " == " + v.getVocabularyName() + "\n");
        continue;
      }

      // do we already have it ?
      if (hash.get(toVocabName) == null) {
        ThreddsMetadata.Variable transV =
            new ThreddsMetadata.Variable(v.getName(), v.getDescription(), toVocabName, v.getUnits(), fromVocabId);
        hash.put(toVocabName, transV);
      }
    }
    return hash.values().iterator();
  }

  private void writeDataset(InvDataset ds, Element rootElem, StringBuilder mess) {
    String entryId = StringUtil2.allow(ds.getUniqueID(), "_-.", '-');
    rootElem.addContent(new Element("Entry_ID", defNS).addContent(entryId));
    rootElem.addContent(new Element("Entry_Title", defNS).addContent(ds.getFullName()));

    // parameters : look for DIF
    ThreddsMetadata.Variables vs = ds.getVariables("DIF");
    boolean hasVocab = (vs != null) && (vs.getVariableList().size() != 0);
    if (hasVocab) {
      for (ThreddsMetadata.Variable v : vs.getVariableList()) {
        writeVariable(rootElem, v);
      }
    } else {
      // look for GRIB-1
      vs = ds.getVariables("GRIB-1");
      if ((vs != null) && (vs.getVariableList().size() != 0)) {
        Iterator iter = translateGribVocabulary(vs, true, mess);
        while (iter.hasNext()) {
          ThreddsMetadata.Variable v = (ThreddsMetadata.Variable) iter.next();
          writeVariable(rootElem, v);
        }
      } else {
        // look for GRIB-2
        vs = ds.getVariables("GRIB-2");
        if ((vs != null) && (vs.getVariableList().size() != 0)) {
          Iterator iter = translateGribVocabulary(vs, false, mess);
          while ((iter != null) && iter.hasNext()) {
            ThreddsMetadata.Variable v = (ThreddsMetadata.Variable) iter.next();
            writeVariable(rootElem, v);
          }
        }
      }
    }

    // keywords
    List<ThreddsMetadata.Vocab> list = ds.getKeywords();
    if (list.size() > 0) {
      for (int i = 0; i < list.size(); i++) {
        ThreddsMetadata.Vocab k = list.get(i);
        rootElem.addContent(new Element("Keyword", defNS).addContent(k.getText()));
      }
    }

    // temporal
    DateRange tm = ds.getTimeCoverage();
    if (tm != null) {
      DateType end = tm.getEnd();
      if (end.isPresent()) {
        TimeDuration duration = tm.getDuration();
        double ndays = duration.getValue("days");
        if (ndays > 0) {
          String relativeTime = "RELATIVE_START_DATE: " + ((int) -ndays);
          rootElem.addContent(new Element("Keyword", defNS).addContent(relativeTime));
        }
      }
    }

    // LOOK KLUDGE - these need to be added to the catalog !! see http://gcmd.nasa.gov/Resources/valids/sources.html
    Element platform = new Element("Source_Name", defNS);
    rootElem.addContent(platform);
    platform.addContent(new Element("Short_Name", defNS).addContent("MODELS"));

    if (tm != null) {
      Element tmElem = new Element("Temporal_Coverage", defNS);
      rootElem.addContent(tmElem);

      tmElem.addContent(new Element("Start_Date", defNS).addContent(tm.getStart().toString()));
      tmElem.addContent(new Element("Stop_Date", defNS).addContent(tm.getEnd().toString()));
    }

    // geospatial
    ThreddsMetadata.GeospatialCoverage geo = ds.getGeospatialCoverage();
    if (geo != null) {
      Element geoElem = new Element("Spatial_Coverage", defNS);
      rootElem.addContent(geoElem);

      double eastNormal = LatLonPointImpl.lonNormal(geo.getLonEast());
      double westNormal = LatLonPointImpl.lonNormal(geo.getLonWest());

      geoElem.addContent(new Element("Southernmost_Latitude", defNS).addContent(Double.toString(geo.getLatSouth())));
      geoElem.addContent(new Element("Northernmost_Latitude", defNS).addContent(Double.toString(geo.getLatNorth())));
      geoElem.addContent(new Element("Westernmost_Longitude", defNS).addContent(Double.toString(westNormal)));
      geoElem.addContent(new Element("Easternmost_Longitude", defNS).addContent(Double.toString(eastNormal)));
    }

    /*
     * LOOK
     * "<Data_Resolution>\n" +
     * "    <Latitude_Resolution>12 Km</Latitude_Resolution>\n" +
     * "    <Longitude_Resolution>12 Km</Longitude_Resolution>\n" +
     * "    <Horizontal_Resolution_Range>10 km - < 50 km or approximately .09 degree - < .5 degree</Horizontal_Resolution_Range>\n"
     * +
     * "    <Temporal_Resolution>6 Hours</Temporal_Resolution>\n" +
     * "    <Temporal_Resolution_Range>Hourly - < Daily</Temporal_Resolution_Range>\n" +
     * "  </Data_Resolution> "
     */

    String rights = ds.getDocumentation("rights");
    if (rights != null)
      rootElem.addContent(new Element("Use_Constraints", defNS).addContent(rights));

    // data center
    List<ThreddsMetadata.Source> plist = ds.getPublishers();
    if (plist.size() > 0) {
      for (ThreddsMetadata.Source p : plist) {
        if (p.getNameVocab().getVocabulary().equalsIgnoreCase("DIF")) {
          Element dataCenter = new Element("Data_Center", defNS);
          rootElem.addContent(dataCenter);
          writeDataCenter(p, dataCenter);
          break;
        }
      }
    }

    String summary = ds.getDocumentation("summary");
    if (summary != null) {
      String summaryLines = StringUtil2.breakTextAtWords(summary, "\n", 80);
      rootElem.addContent(new Element("Summary", defNS).addContent(summaryLines));
    }

    URI uri;
    String href;
    if (ds instanceof InvCatalogRef) { // LOOK !!
      InvCatalogRef catref = (InvCatalogRef) ds;
      uri = catref.getURI();
      href = uri.toString();
      int pos = href.lastIndexOf('.');
      href = href.substring(0, pos) + ".html";

    } else {
      InvCatalogImpl cat = (InvCatalogImpl) ds.getParentCatalog();
      uri = cat.getBaseURI();
      String catURL = uri.toString();
      int pos = catURL.lastIndexOf('.');
      href = catURL.substring(0, pos) + ".html";
      if (ds.hasAccess())
        href = href + "?dataset=" + ds.getID();
    }

    rootElem.addContent(makeRelatedURL("GET DATA", "THREDDS CATALOG", uri.toString()));
    rootElem.addContent(makeRelatedURL("GET DATA", "THREDDS DIRECTORY", href));

    InvAccess access;
    if (null != (access = ds.getAccess(ServiceType.OPENDAP))) {
      rootElem.addContent(makeRelatedURL("GET DATA", "OPENDAP DATA", access.getStandardUrlName()));
    }
    if (null != (access = ds.getAccess(ServiceType.DAP4))) {
      rootElem.addContent(makeRelatedURL("GET DATA", "DAP4 DATA", access.getStandardUrlName()));
    }

    rootElem.addContent(new Element("Metadata_Name", defNS).addContent("CEOS IDN DIF"));
    rootElem.addContent(new Element("Metadata_Version", defNS).addContent("9.4"));
    DateType today = new DateType(false, new Date());
    rootElem.addContent(new Element("DIF_Creation_Date", defNS).addContent(today.toDateTimeStringISO()));
  }

  private Element makeRelatedURL(String type, String subtype, String url) {
    Element elem = new Element("Related_URL", defNS);
    Element uctElem = new Element("URL_Content_Type", defNS);
    elem.addContent(uctElem);
    uctElem.addContent(new Element("Type", defNS).addContent(type));
    uctElem.addContent(new Element("Subtype", defNS).addContent(subtype));
    elem.addContent(new Element("URL", defNS).addContent(url));
    return elem;
  }

  private void writeDataCenter(ThreddsMetadata.Source p, Element dataCenter) {
    Element name = new Element("Data_Center_Name", defNS);
    dataCenter.addContent(name);
    // dorky
    StringTokenizer stoker = new StringTokenizer(p.getName(), ">");
    int n = stoker.countTokens();
    if (n == 2) {
      name.addContent(new Element("Short_Name", defNS).addContent(stoker.nextToken().trim()));
      name.addContent(new Element("Long_Name", defNS).addContent(stoker.nextToken().trim()));
    } else {
      name.addContent(new Element("Short_Name", defNS).addContent(p.getName()));
    }

    if ((p.getUrl() != null) && p.getUrl().length() > 0)
      dataCenter.addContent(new Element("Data_Center_URL", defNS).addContent(p.getUrl()));

    Element person = new Element("Personnel", defNS);
    dataCenter.addContent(person);
    person.addContent(new Element("Role", defNS).addContent("DATA CENTER CONTACT"));
    person.addContent(new Element("Last_Name", defNS).addContent("Any"));
    person.addContent(new Element("Email", defNS).addContent(p.getEmail()));
  }

  private void writeVariable(Element rootElem, ThreddsMetadata.Variable v) {
    String vname = v.getVocabularyName();
    StringTokenizer stoker = new StringTokenizer(vname, ">");
    int n = stoker.countTokens();
    if (n < 3)
      return; // gottta have the first 3

    Element param = new Element("Parameters", defNS);
    rootElem.addContent(param);

    if (stoker.hasMoreTokens())
      param.addContent(new Element("Category", defNS).addContent(stoker.nextToken().trim()));
    if (stoker.hasMoreTokens())
      param.addContent(new Element("Topic", defNS).addContent(stoker.nextToken().trim()));
    if (stoker.hasMoreTokens())
      param.addContent(new Element("Term", defNS).addContent(stoker.nextToken().trim()));
    if (stoker.hasMoreTokens())
      param.addContent(new Element("Variable", defNS).addContent(stoker.nextToken().trim()));
    if (stoker.hasMoreTokens())
      param.addContent(new Element("Detailed_Variable", defNS).addContent(stoker.nextToken().trim()));
  }

  // test
  private static void doCatalog(InvCatalogFactory fac, String url) {
    System.out.println("***read " + url);
    try {
      InvCatalogImpl cat = fac.readXML(url);
      StringBuilder buff = new StringBuilder();
      boolean isValid = cat.check(buff, false);
      System.out.println("catalog <" + cat.getName() + "> " + (isValid ? "is" : "is not") + " valid");
      System.out.println(" validation output=\n" + buff);
      System.out.println(" catalog=\n" + fac.writeXML(cat));

      DIFWriter w = new DIFWriter();
      StringBuilder sbuff = new StringBuilder();
      w.writeDatasetEntries(cat, "C:/temp/dif2", sbuff);
      System.out.println(" messages=\n" + sbuff);
    } catch (Exception e) {
      e.printStackTrace();
    }

  }

  /** testing */
  public static void main(String[] args) throws Exception {
    InvCatalogFactory catFactory = InvCatalogFactory.getDefaultFactory(true);

    doCatalog(catFactory, "http://thredds.ucar.edu:9080/thredds/idd/models.xml");
  }

}


text:
Live Photos is a feature of iOS 9 that allows users to capture and relive their favorite moments with richer context than traditional photos. When the user presses the shutter button, the Camera app captures much more content along with the regular photo, including audio and additional frames before and after the photo. When browsing through these photos, users can interact with them and play back all the captured content, making the photos come to life.

iOS 9.1 introduces APIs that allow apps to incorporate playback of Live Photos, as well as export the data for sharing. The Photos framework includes support to fetch a PHLivePhoto object from the PHImageManager object, which is used to represent all the data that comprises a Live Photo. You can use a PHLivePhotoView object (defined in the PhotosUI framework) to display the contents of a Live Photo. The PHLivePhotoView view takes care of displaying the image, handling all user interaction, and applying the visual treatments to play back the content.

You can also use PHAssetResource to access the data of a PHLivePhoto object for sharing purposes. You can request a PHLivePhoto object for an asset in the user's photo library by using PHImageManager or UIImagePickerController. If you have a sharing extension, you can also get PHLivePhoto objects by using NSItemProvider. On the receiving side of a share, you can recreate a PHLivePhoto object from the set of files originally exported by the sender.

The data of a Live Photo is exported as a set of files in a PHAssetResource object. The set of files must be preserved as a unit when you upload them to a server. When you rebuild a PHLivePhoto with these files on the receiver side, the files are validated; loading fails if the files don't come from the same asset.

To learn how to give users a great experience with Live Photos in your app, see .

Live Photos是iOS 9的一项功能,可让用户通过比传统照片更丰富的内容来捕捉和重温自己喜爱的时刻。当用户按下快门按钮时,相机应用程序会捕获更多内容以及常规照片,包括照片前后的音频和附加帧。浏览这些照片时,用户可以与他们进行互动并播放所有捕获的内容,使照片变得生动。

iOS 9.1引入了API,允许应用程序包含实时照片的播放,以及导出数据进行共享。照片框架包括从PHImageManager对象获取PHLivePhoto对象的支持,该对象用于表示包含实时照片的所有数据。您可以使用PHLivePhotoView对象(在PhotosUI框架中定义)来显示实时照片的内容。 PHLivePhotoView视图负责显示图像,处理所有用户交互,并应用视觉效果来播放内容。

您还可以使用PHAssetResource访问PHLivePhoto对象的数据以进行共享。您可以使用PHImageManager或UIImagePickerController为用户照片库中的资产请求PHLivePhoto对象。如果您有一个共享扩展名,您还可以使用NSItemProvider获取PHLivePhoto对象。在共享的接收端,您可以从发件人最初导出的文件集中重新创建一个PHLivePhoto对象。

Live Photo的数据作为一组文件导出到PHAssetResource对象中。当您将它们上传到服务器时,该文件集必须作为一个单元保留。当您在接收方重建这些文件的PHLivePhoto时,文件将被验证;如果文件不是来自同一资产,则加载失败。

要了解如何让用户在您的应用中使用Live Photos享受很好的体验,请参阅。

## 2.Support for Apple Pencil

iOS 9.1 introduces APIs that help you use coalesced and predictive touches that can be produced by Apple Pencil on supported devices. Specifically, the UITouch class includes:

The preciseLocationInView: and precisePreviousLocationInView: methods, which give you the precise location for a touch (when available)

The altitudeAngle property and the azimuthAngleInView: and azimuthUnitVectorInView: methods, which help you determine the altitude and azimuth of the stylus

The estimatedProperties and estimatedPropertiesExpectingUpdates properties, which help you prepare to update touches that are estimated

The UITouchTypeStylus constant that's used to represent a touch received from a stylus.

For an example of some ways to take advantage of these APIs in your app, see the sample project TouchCanvas: Using UITouch efficiently and effectively.

iOS 9.1引入了API,可帮助您使用Apple Pencil在支持的设备上生成的合并和预测触摸。 具体来说,UITouch类包括:

precisionLocationInView:和precisePreviousLocationInView:方法,它为您提供触摸的确切位置(如果可用)

altitudeAngle属性和azimuthAngleInView:和azimuthUnitVectorInView:方法,可帮助您确定触控笔的高度和方位角

estimateProperties和estimatedPropertiesExpectingUpdates属性,可帮助您准备更新估计的触摸

UITouchTypeStylus常量,用于表示从触控笔接收到的触摸。

有关在应用程序中使用这些API的一些方法的示例,请参阅示例项目TouchCanvas:高效,高效地使用UITouch。


text:
import * as React               from 'react';

import { connect }              from 'react-redux';
import { Dispatch }             from 'redux';

import { Cell, Content, Drawer, Grid, Header, Layout, Navigation } from 'react-mdl';

import { MentionCounter }       from '../';
import { LogoBox }              from '../';
import { QueryClearButton }     from '../';
import { QueryBuildButton }     from '../';
import { Searchbox }            from '../';
import { ClearAllQueriesDialog }from '../';
import { RebuildDatabaseDialog }from '../';

import { Tree }                         from '../';
import { openClearAllQueriesDialog }    from '../../actions';
import { openRebuildDatabaseDialog }    from '../../actions';
import { GenericAction }                from '../../types';

//Only need this for the 'generic' solution, which we do not use now
// import { collections }                  from '../../config';

import './MenuBar.css';

interface IMenuBarDispatchProps {
    openClearAllDialog: () => void;
    openRebuildDialog: () => void;
}

export interface IMenuBar {
    buttonActive: boolean;
}

export class UnconnectedMenuBar extends React.Component<IMenuBar & IMenuBarDispatchProps, { }> {
    constructor() {
        super();

        this.onClickClearAll = this.onClickClearAll.bind(this);
        this.onClickRebuild = this.onClickRebuild.bind(this);
    }

    static mapStateToProps() {
        return {
        };
    }

    static mapDispatchToProps(dispatch: Dispatch<GenericAction>) {
        return {
            openClearAllDialog: () => {
                dispatch(openClearAllQueriesDialog());
            },
            openRebuildDialog: () => {
                dispatch(openRebuildDatabaseDialog());
            }
        };
    }

    public onClickClearAll() {
        this.props.openClearAllDialog();
    }

    public onClickRebuild() {
        this.props.openRebuildDialog();
    }

    render() {
        //Generic Solution
        /*const colwidth = 3; //Math.floor(12 / collections.length);
        const trees = collections.map((collection: string, indexOf: number) => {
            return (
                <Cell key={indexOf} col={colwidth}>

{collection}

                    <Tree collection={collection}/>
                </Cell>
                );
        });*/

        return (

                <Layout fixedHeader>
                    <Header title={Storyteller Query-Builder}>
                        <Navigation>
                            <LogoBox />
                            <Searchbox />
                            <MentionCounter />
                            <QueryClearButton />
                            <QueryBuildButton />
                        </Navigation>

                    <Drawer title="DANGER Zone">
                        <Navigation>
                            {/*Rebuild Database*/}
                            Clear all queries
                        </Navigation>
                    </Drawer>

                    <ClearAllQueriesDialog />
                    <RebuildDatabaseDialog />

                    <Content>
                        <Grid>
                            {/*generic solution*/}
                            {/*{trees}*/}

                            {/* custom solution */}
                            <Cell key={0} col={3}>

{'light entities'}

                                <Tree collection={'light'}/>

{'dark entities'}

                                <Tree collection={'dark'}/>

{'concepts'}

                                <Tree collection={'concepts'}/>
                            </Cell>
                            <Cell key={1} col={3}>

{'events'}

                                <Tree collection={'events'}/>
                            </Cell>
                            <Cell key={2} col={3}>

{'authors'}

                                <Tree collection={'authors'}/>

{'cited'}

                                <Tree collection={'cited'}/>

{'perspectives'}

                                <Tree collection={'perspectives'}/>
                            </Cell>
                            <Cell key={3} col={3}>

{'topics'}

                                <Tree collection={'topics'}/>
                            </Cell>
                        </Grid>
                    </Content>
                </Layout>

        );
    }
}

// Export just the connected component
export const MenuBar = connect(UnconnectedMenuBar.mapStateToProps,
                               UnconnectedMenuBar.mapDispatchToProps)(UnconnectedMenuBar);


text:
module Data.Expenses.ToCSV
  ( recordsFromEntries
  )
where

import           Text.CSV                      as CSV

import           Text.Printf                    ( printf )

import           Data.Expenses.Parse.Megaparsec.Entry
                                                ( Entry
                                                , entryDate
                                                , entryPrice
                                                , entryRemark
                                                )

recordFromEntry :: Entry -> CSV.Record
recordFromEntry entry = [date, price, cur, remark]
 where
  (y, m, d)      = entryDate entry
  date           = printf "%4d-%02d-%02d" y m d
  (amount', cur) = entryPrice entry
  price          = show amount'
  remark         = entryRemark entry

recordsFromEntries :: [Entry] -> [CSV.Record]
recordsFromEntries = map recordFromEntry


text:
I created this image to make it easier to develop on the device or qemu virtual machine. Includes the abality for collaboration.
Run on the device as soon as the code is complete instead of having to push | pull | ftp your code over to the device.

Once your code is as you want you can take advantage of the "qbain service" ~/init.sh and run your scripts when the system start/boots.

### qbian cli install
You can create your own using the qbain cli tools set :
Installs NVM (node version magager) with iojs as the default alias :
Package pre-installed : forever , node-gyp , bower
Python2.7 , minicom etc. Please view the Provision script for more info

```bash
& qbian --create-default # run the qemu provision & optional the device provision $ /root/Provision.sh
$ qbian --create-img qbian-c9 "-redir tcp:8080::8080 -redir tcp:1374::1374" 2G default
# this will create the image usable with the qbain cli - when complete
$ qbian --run-img qbian-c9 5522
# note that the image will run the provision script and installed whats needed
# Provisioning will auto run
# When launched you log in and install c9 sdk | ide
$ qbian --ssh "qbain@127.0.0.1 -p 5522"
$ ~/bin/c9-install
# note that this will take a while depending on internet speeds - or not because it is has a lot to do
# Finally enjoy
## Installer other common software : docker , wifi drivers , pi-blaster : optionals
$ docker-install
$ piblaster-install
$ wifi-install
# Files to edit:
# /etc/network/interface.static : add your network info
# /etc/network/interface.wifi : add your network info
# /etc/wpa_supplicant/wpa_supplicant : add your network's wifi info
# Enable $ cat /etc/network/interface.wifi > /etc/network/interface && sudo service networking restart
# Or you can leave it as dynamic & use ethernet

# To enable strict SSH access
# $ sudo unlink /etc/ssh/sshd_config && sudo mv /etc/ssh/_sshd_config /etc/ssh/sshd_config && reboot
```

### Download the alread configure image
* Download zip from from my aws bucket <https://s3-eu-west-1.amazonaws.com/qbain-images/qbian-cloud9.zip>
* extract files
* dump the 2015-02-18-wheezy-minibian.img onto a 4GB+ sd card
* insert into your device and start
* Go to your devices IP addr and port 8080 : e.g 192.168.0.1:8080
* you now have access to the cloud 9 IDE. Your sudo permission etc
* enjoy :)

note - you might want to do an update on ~/Server. Just for some examples
```bash
$ cd ~/Server && git pull origin master
```

![Cloud 9 IDE](https://raw.githubusercontent.com/trojanspike/qbian/images/qbian-c9ide.png?raw=true "C9 ide on qemu")
![Node running task](https://raw.githubusercontent.com/trojanspike/qbian/images/qbian-noderun.png?raw=true "node tasks")


text:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using OPCAutomation;
namespace OPC
{
    public partial class Form1 : Form
    {
        OPCServer ObjOPCServer;
        OPCGroups ObjOPCGroups;
        OPCGroup ObjOPCGroup;
        string OPCServerName;
        public Form1()
        {
            try
            {
                InitializeComponent();
                OPCServerName = "{Here comes your OPC server's name}";
                ObjOPCServer = new OPCServer();
                ObjOPCServer.Connect(OPCServerName, "";);
                ObjOPCGroups = ObjOPCServer.OPCGroups;
                ObjOPCGroup = ObjOPCGroups.Add("OPCGroup1");
                ObjOPCGroup.DataChange += new DIOPCGroupEvent_DataChangeEventHandler(ObjOPCGroup_DataChange);
                ObjOPCGroup.OPCItems.AddItem("{tag name or address (like {plc name on server}!%mw0)}", 1);
                ObjOPCGroup.UpdateRate = 10;
                ObjOPCGroup.IsActive = true;
                ObjOPCGroup.IsSubscribed = true;
            }
            catch (Exception e){
                MessageBox.Show(e.ToString());
            }
        }

        private void button1_Click(object sender, EventArgs e)
        {
        }

        private void ObjOPCGroup_DataChange(int TransactionID, int NumItems, ref Array ClientHandles, ref Array ItemValues, ref Array Qualities, ref Array TimeStamps)
        {
            for (int i = 1; i <= NumItems; i++)
            {
                if ((Convert.ToInt32(ClientHandles.GetValue(i)) == 1))
                {
                    textBox1.Text =  ItemValues.GetValue(i).ToString();
                }
            }
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            OPCServerClass GlobalOPCServer = new OPCServerClass();
            Array ServerList = (Array)GlobalOPCServer.GetOPCServers("");
            for (int i = 1; i <= ServerList.Length; i++)
            {
                comboBox1.Items.Add(ServerList.GetValue(i).ToString());
            }
        }
    }
}


text:
@interface HBMyRouteQuestionCell : UITableViewCell
+ (instancetype)cellWithTableView:(UITableView *)tableView;

@end


text:
/*
 * Created by IntelliJ IDEA.
 * User: mike
 * Date: Sep 30, 2002
 * Time: 8:55:08 PM
 * To change template for new class use
 * Code Style | Class Templates options (Tools | IDE Options).
 */
package com.intellij.xml.impl.schema;

import com.intellij.psi.PsiElement;
import com.intellij.psi.xml.XmlAttribute;
import com.intellij.psi.xml.XmlTag;
import com.intellij.util.ArrayUtil;
import com.intellij.xml.XmlAttributeDescriptor;
import com.intellij.xml.XmlElementDescriptor;
import com.intellij.xml.XmlElementsGroup;
import com.intellij.xml.XmlNSDescriptor;

public  class AnyXmlElementDescriptor implements XmlElementDescriptor {
  private final XmlElementDescriptor myParentDescriptor;
  private final XmlNSDescriptor myXmlNSDescriptor;

  public AnyXmlElementDescriptor(XmlElementDescriptor parentDescriptor, XmlNSDescriptor xmlNSDescriptor) {
    myParentDescriptor = parentDescriptor == null ? NullElementDescriptor.getInstance() : parentDescriptor;
    myXmlNSDescriptor = xmlNSDescriptor;
  }

  @Override
  public XmlNSDescriptor getNSDescriptor() {
    return myXmlNSDescriptor;
  }

  @Override
  public XmlElementsGroup getTopGroup() {
    return null;
  }

  @Override
  public PsiElement getDeclaration(){
    return null;
  }

  @Override
  public String getName(PsiElement context){
    return getName();
  }

  @Override
  public String getName() {
    return myParentDescriptor.getName();
  }

  @Override
  public void init(PsiElement element){
  }

  @Override
  public Object[] getDependences(){
    return ArrayUtil.EMPTY_OBJECT_ARRAY;
  }

  @Override
  public String getQualifiedName() {
    return myParentDescriptor.getQualifiedName();
  }

  @Override
  public String getDefaultName() {
    return myParentDescriptor.getDefaultName();
  }

  @Override
  public XmlElementDescriptor[] getElementsDescriptors(XmlTag context) {
    return myParentDescriptor.getElementsDescriptors(context);
  }

  @Override
  public XmlElementDescriptor getElementDescriptor(XmlTag tag, XmlTag contextTag){
    return new AnyXmlElementDescriptor(this, myXmlNSDescriptor);
  }

  @Override
  public XmlAttributeDescriptor[] getAttributesDescriptors(final XmlTag context) {
    return XmlAttributeDescriptor.EMPTY;
  }

  @Override
  public XmlAttributeDescriptor getAttributeDescriptor(final String attributeName, final XmlTag context) {
    return new AnyXmlAttributeDescriptor(attributeName);
  }

  @Override
  public XmlAttributeDescriptor getAttributeDescriptor(XmlAttribute attr){
    return myParentDescriptor.getAttributeDescriptor(attr);
  }

  @Override
  public int getContentType() {
    return CONTENT_TYPE_UNKNOWN;
  }

  @Override
  public String getDefaultValue() {
    return null;
  }
}


text:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.example.jobservicedemo.MainActivity">

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/btn_schedule_job"
        android:textAllCaps="false"
        android:text="Schedule job"
        android:layout_marginRight="8dp"
        app:layout_constraintRight_toRightOf="parent"
        android:layout_marginLeft="8dp"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        android:layout_marginTop="8dp"/>
    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/btn_cancel_job"
        android:textAllCaps="false"
        android:text="Cancel job"
        android:layout_marginLeft="8dp"
        app:layout_constraintLeft_toLeftOf="@+id/btn_schedule_job"
        android:layout_marginRight="8dp"
        app:layout_constraintRight_toRightOf="@+id/btn_schedule_job"
        android:layout_marginTop="8dp"
        app:layout_constraintTop_toBottomOf="@+id/btn_schedule_job"/>
</android.support.constraint.ConstraintLayout>


text:
namespace Google.Cloud.Deploy.V1.Snippets
{
    // [START clouddeploy_v1_generated_CloudDeploy_ListJobRuns_sync]
    using Google.Api.Gax;
    using Google.Cloud.Deploy.V1;
    using System;

    public sealed partial class GeneratedCloudDeployClientSnippets
    {
        /// <summary>Snippet for ListJobRuns</summary>
        /// <remarks>
        /// This snippet has been automatically generated and should be regarded as a code template only.
        /// It will require modifications to work:
        /// - It may require correct/in-range values for request initialization.
        /// - It may require specifying regional endpoints when creating the service client as shown in
        ///   https://cloud.google.com/dotnet/docs/reference/help/client-configuration#endpoint.
        /// </remarks>
        public void ListJobRunsRequestObject()
        {
            // Create client
            CloudDeployClient cloudDeployClient = CloudDeployClient.Create();
            // Initialize request argument(s)
            ListJobRunsRequest request = new ListJobRunsRequest
            {
                ParentAsRolloutName = RolloutName.FromProjectLocationDeliveryPipelineReleaseRollout("[PROJECT]", "[LOCATION]", "[DELIVERY_PIPELINE]", "[RELEASE]", "[ROLLOUT]"),
                Filter = "",
                OrderBy = "",
            };
            // Make the request
            PagedEnumerable<ListJobRunsResponse, JobRun> response = cloudDeployClient.ListJobRuns(request);

            // Iterate over all response items, lazily performing RPCs as required
            foreach (JobRun item in response)
            {
                // Do something with each item
                Console.WriteLine(item);
            }

            // Or iterate over pages (of server-defined size), performing one RPC per page
            foreach (ListJobRunsResponse page in response.AsRawResponses())
            {
                // Do something with each page of items
                Console.WriteLine("A page of results:");
                foreach (JobRun item in page)
                {
                    // Do something with each item
                    Console.WriteLine(item);
                }
            }

            // Or retrieve a single page of known size (unless it's the final page), performing as many RPCs as required
            int pageSize = 10;
            Page<JobRun> singlePage = response.ReadPage(pageSize);
            // Do something with the page of items
            Console.WriteLine($"A page of {pageSize} results (unless it's the final page):");
            foreach (JobRun item in singlePage)
            {
                // Do something with each item
                Console.WriteLine(item);
            }
            // Store the pageToken, for when the next page is required.
            string nextPageToken = singlePage.NextPageToken;
        }
    }
    // [END clouddeploy_v1_generated_CloudDeploy_ListJobRuns_sync]
}


text:
namespace RawNet.Jpeg
{
    /*
    * The following structure stores basic information about one component.
    */
    public struct JpegComponentInfo
    {
        /*
        * These values are fixed over the whole image.
        * They are read from the SOF marker.
        */
        public uint componentId;     /* identifier for this component (0..255) */
        public uint componentIndex;  /* its index in SOF or cPtr.compInfo[]   */

        /*
        * Huffman table selector (0..3). The value may vary
        * between scans. It is read from the SOS marker.
        */
        public uint dcTblNo;
        public uint superH; // Horizontal Supersampling
        public uint superV; // Vertical Supersampling

        public override string ToString()
        {
            return "id:" + componentId + " index:" + componentIndex + " table:" + dcTblNo + " subH:" + superH + " subV:" + superV;
        }
    };
}


text:
![Icon](http://velneo.es/files/2012/10/logo-js.png)

Esta aplicación es un analizador sintáctico descendente predictivo recursivo. Las operaciones se parentizan a izquierdas. Se incluyen varios ficheros de prueba, y usted puede importar sus propios archivos.
También se incluye un enlace a las pruebas de funcionamiento de la página.

Trata de corresponder con una pequeña parte del lenguaje [PL/0][PL0].

####Enlace a la web

[http://whispering-mesa-1729.herokuapp.com/][page]

####Autores

* Alejandro Hernández Hernández ([GitHub][Ale])
* Eliasib J. García Martín ([GitHub][Eli])

####Licencia

MIT

##Nota
Los commits se han realizado desde un solo ordenador, dado que uno de los compañeros del grupo ha tenido problemas con su equipo.

[PL0]: http://en.wikipedia.org/wiki/PL/0
[page]: http://whispering-mesa-1729.herokuapp.com/
[Ale]: https://github.com/alu0100699715
[Eli]: https://github.com/alu0100698121