text:
"use strict"

// builtin tooling
const path = require("path")

// placeholder tooling
let sugarss

module.exports = function processContent(
  result,
  content,
  filename,
  options,
  postcss
) {
  const { plugins } = options
  const ext = path.extname(filename)

  const parserList = []

  // SugarSS support:
  if (ext === ".sss") {
    if (!sugarss) {
      try {
        sugarss = require("sugarss")
      } catch {} // Ignore
    }
    if (sugarss)
      return runPostcss(postcss, content, filename, plugins, [sugarss])
  }

  // Syntax support:
  if (result.opts.syntax?.parse) {
    parserList.push(result.opts.syntax.parse)
  }

  // Parser support:
  if (result.opts.parser) parserList.push(result.opts.parser)
  // Try the default as a last resort:
  parserList.push(null)

  return runPostcss(postcss, content, filename, plugins, parserList)
}

function runPostcss(postcss, content, filename, plugins, parsers, index) {
  if (!index) index = 0
  return postcss(plugins)
    .process(content, {
      from: filename,
      parser: parsers[index],
    })
    .catch(err => {
      // If there's an error, try the next parser
      index++
      // If there are no parsers left, throw it
      if (index === parsers.length) throw err
      return runPostcss(postcss, content, filename, plugins, parsers, index)
    })
}


text:
package com.example.cnlcnn.view;

import android.app.Dialog;
import android.content.Context;
import android.view.Gravity;
import android.view.Window;
import android.view.WindowManager;

import com.example.cnlcnn.wallpaper.R;

/*
 *  项目名:  WallPaper
 *  创建者:   LiChuang
 *  创建时间:  2017/5/25
 *  描述:
 */

public class CustomDialog extends Dialog {
    public CustomDialog(Context context, int layout, int style) {
        this(context, WindowManager.LayoutParams.MATCH_PARENT,
                WindowManager.LayoutParams.WRAP_CONTENT, layout, style,
                Gravity.CENTER);
    }

    public CustomDialog(Context context, int width, int height, int layout,
                        int style, int gravity, int anim) {
        super(context, style);

        setContentView(layout);
        Window window = getWindow();
        WindowManager.LayoutParams params = window.getAttributes();
        params.width = WindowManager.LayoutParams.MATCH_PARENT;
        params.height = WindowManager.LayoutParams.WRAP_CONTENT;
        params.gravity = gravity;
        window.setAttributes(params);
        window.setWindowAnimations(anim);
    }

    public CustomDialog(Context context, int width, int height, int layout,
                        int style, int gravity) {
        this(context, width, height, layout, style, gravity,
                R.style.pop_anim_style);
    }
}

redpajama_set_name: RedPajamaGithub


text:
<?php   defined('C5_EXECUTE') or die("Access Denied.");
global $c;
$pageTitle = $c->getCollectionName();
$pageName = $c->getCollectionHandle();
$pagePath = $c->getCollectionPath();

$parent = Page::getByID($c->getCollectionParentID());
$homeURL = $parent->getCollectionPath();

//Check if HOME/EARTH > parent
// or
// HOME/SPN/EARTH > grandparent

//$parent = Page::getByID($c->getCollectionParentID());
$grandParent = Page::getByID($parent->getCollectionParentID());  // Restoration Projects

$parentName = $parent->getCollectionHandle();
$grandParentName = $grandParent->getCollectionHandle();

//$children = $grandParent->getCollectionChildrenArray($intOneLevel = 1);  // Get first-level children of $page object and put in array $children

$multiLang = $_SESSION['firstMessage'];	//$multiLang = 0/1: English/Spanish

//Language check $multiLang = 0/1: English/Spanish
$strLen = strlen($pageName); // count sting length earth=5
$pagePathStart = substr($pagePath, 1, $strLen);  // /spn/earth/plant-animal-id --> spn/e

if ($pageName != $pagePathStart){	// IF earth DOES NOT = spn/e
	$multiLang = 1;					// Spanish
} else {
	$multiLang = 0;					// Use English
}
session_start();
$_SESSION['firstMessage'] = $multiLang;

?>
<!DOCTYPE html>
<html lang="<?php echo LANGUAGE?>">

<?php   Loader::element('header_required'); ?>

<link rel="stylesheet" media="screen" type="text/css" href="<?php  echo $this->getStyleSheet('main.css')?>" />

<link rel="stylesheet" type="text/css" href="<?php echo DIR_REL?>/packages/lightboxed_image/blocks/lightboxed_image/css/theme1/colorbox.css" />

<?php
	$pageName = $c->getCollectionHandle();
	echo '';
?>

CREDITS

Developed for Environmental Volunteers

Allan Berkowitz – Executive Director

Brittany Sabol – Education & Training Director

Touchscreens developed by White Room Partners

Michael Gee – Principal & Lead Developer

Anna McElheny – Art Director & User Experience

			whiteroompartners.com

Exhibition design by Stephanie Scheafer design

Stephanie Scheafer – Principal

		<?php
		$a = new Area('Header Image');
		$a->display($c);
		?>


text:
<!DOCTYPE html>
<title>Canvas tests - 2d.shadow.offset.*</title>
<link rel="stylesheet" href="../frame.css">

[index]

2d.shadow.offset.*

(iframe fallback)(iframe fallback)(iframe fallback)(iframe fallback)


text:
class CreateOrderItems < ActiveRecord::Migration
  def change
    create_table :order_items do |t|
      t.integer     :amount
      t.references  :order,     null: false
      t.references  :delivery,  null: false

      t.timestamps
    end
  end
end


text:
[![Build Status](https://travis-ci.org/georaldc/ResumableJsProcessor.svg?branch=master)](https://travis-ci.org/georaldc/ResumableJsProcessor)

Easily handle [resumable.js](https://github.com/23/resumable.js/) uploads.

Inside target server file for resumable.js, instantiate the ResumableJsProcessor class with your intended upload path specified, pass the appropriate mode (supports 2 modes at the moment, see ResumableJsProcessor constants) and call the process() method.

```php
$resumable = new ResumableJsProcessor('path/to/uploads');
if (isset($_FILES)) {
    $resumable->setMode(ResumableJsProcessor::MODE_UPLOAD_CHUNK);
} else {
    $resumable->setMode(ResumableJsProcessor::MODE_TEST_CHUNK);
}
$fileUploaded = $resumable->process();
if (false !== $fileUploaded) {
  // $fileUploaded will contain the upload path + filename of file that has been uploaded. You may do further processing here
}
```

This file will be called multiple times for every chunk checked and uploaded. Once ResumableJsProcessor::process() returns a string, that will be indication that the chunks have been uploaded and assembled.


text:
var rotationArray = new Array();
var actualRotatingElement = null;
var browser = (navigator.userAgent.toLowerCase().indexOf('chrome') > -1) ? 'chrome':'firefox';
var imageCounter = 0;

/**
 * Method used to create a new image
 *
 * @param url - url to the image
 */
function createImage(url){
	var img = $('<img/>', {
		src: url,
		width: '100px',
	    name: 'test',
	    id: 'image'+ (++tabCounter),
	    tabIndex: tabCounter
	}).load(function() {
		$(this).appendTo("#writing")
		.resizable({
			ghost: true,
			aspectRatio: true,
			autoHide: false,
			start: function(event, ui) {  },
			stop:  function(event, ui) {
				endImageDragOrResize('#image'+ tabCounter);
			}
		})
		.bind({
			click: function(){
				controlRotation(this.parentNode);
			},
			focus: function() {
				controlRotation(this.parentNode);
			}
		})
		.parent()
		.css({"-webkit-transform": "rotate(0deg)", "-moz-transform": "rotate(0deg)"})
		.css("top", 132)
		.css("left", 252)
		.css("position", "absolute")
		.attr("tabindex",tabCounter)
		.attr("id","div"+'image'+ tabCounter)
		.keyup(function(event) {
			keyboardEvents(this, event);
		})
		.mouseup(function(event) {
			mouseEvents(this, event);
		})
		.draggable({
			containment: "#writing",
			scroll: false,
			cursor: 'crosshair',
			start: function(event, ui) {  },
			stop:  function(event, ui) {
				endImageDragOrResize('#image'+ tabCounter);
			}
		});

		tabIndexCalculation();

		logArea("newElement", "image");
	});

	focusedElementId = '#image'+tabCounter;

	console.log('createImage->id:'+'#image'+tabCounter);

	if ($("#dialog-modal").dialog('isOpen')) {
		$("#dialog-modal").dialog('close');
	}

}

/**
 * Method used to iniate a new image
 *
 * @param url - url to the image
 */
function initiateImage(obj){

	if(typeof obj.tabIndex == 'undefined')
		var tabIndex = obj.tabindex;
	else
		var tabIndex = obj.tabIndex;

	var img = $('<img/>', {
		src: obj.value,
		width: obj.width,
		height: obj.height,
	    name: 'test',
	    id: obj.id,
	    tabIndex: tabIndex
	}).load(function() {
		$(this).appendTo("#writing")
		.resizable({
			ghost: true,
			aspectRatio: true,
			autoHide: false,
			start: function(event, ui) {  },
			stop:  function(event, ui) {
				endImageDragOrResize('#'+obj.id);
			}
		})
		.bind({
			click: function(){
				controlRotation(this.parentNode);
			},
			focus: function() {
				controlRotation(this.parentNode);
			}
		})
		.parent()
		.css({"-webkit-transform": "rotate(0deg)", "-moz-transform": "rotate(0deg)"})
		.css("top", obj.top)
		.css("left", obj.left)
		.css("position", "absolute")
		.attr("tabindex",tabIndex)
		.attr("id","div"+obj.id)
		.keyup(function(event) {
			keyboardEvents(this, event);
		})
		.mouseup(function(event) {
			mouseEvents(this, event);
		})
		.draggable({
			containment: "#writing",
			scroll: false,
			cursor: 'crosshair',
			start: function(event, ui) {  },
			stop:  function(event, ui) {
				endImageDragOrResize('#'+obj.id);
			}
		});

	});
}

/**
 * Method used to load a stored image
 *
 * @param url - url to the image
 * @param width
 * @param height
 * @param id
 * @param rotation - only the number (do not include the unit)
 */
function loadImage(url, top, left, width, height, id, rotation, tabIndex){
	if (tabCounter < parseInt(tabIndex))
		tabCounter = parseInt(tabIndex);
	console.log('loadImage->id:'+id);

	var writing = document.getElementById("writing");
	var divImg = document.getElementById(id);

	divImg.style.width = width;
	divImg.style.height = height;

	divImg.parentNode.style.width = width;
	divImg.parentNode.style.height = height;
	divImg.parentNode.style.top = top;
	divImg.parentNode.style.left = left;
	divImg.parentNode.style.tabIndex = parseInt(tabIndex);
	$('#'+id).parent().css({"-webkit-transform": "rotate(" + rotation + "deg)", "-moz-transform": "rotate(" + rotation + "deg)"})

}

 function controlRotation(element) {
	console.log('Método controlRotation');
	if (actualRotatingElement == null || element != actualRotatingElement) {
		actualRotatingElement = element;
	}
 }

 function rotateClockwise() {
	var rotateValue = getRotateValue(actualRotatingElement)+15;

	if (getRotateValue(actualRotatingElement) >= 360) {
		actualRotatingElement.style.webkitTransform = "rotate(0deg)"
		actualRotatingElement.style.MozTransform = "rotate(0deg)";
	}
	actualRotatingElement.style.webkitTransform = 'rotate(' + rotateValue + 'deg)';
	actualRotatingElement.style.MozTransform = 'rotate(' + rotateValue + 'deg)';

	endImageDragOrResize('#image'+ imageCounter);
 }

 function rotateCounterClockwise() {
	var rotateValue = getRotateValue(actualRotatingElement)-15;

	if (getRotateValue(actualRotatingElement) >= 360) {
		actualRotatingElement.style.webkitTransform = "rotate(0deg)";
		actualRotatingElement.style.MozTransform = "rotate(0deg)";
	}
	actualRotatingElement.style.webkitTransform = 'rotate(' + rotateValue + 'deg)';
	actualRotatingElement.style.MozTransform = 'rotate(' + rotateValue + 'deg)';

	endImageDragOrResize('#image'+ imageCounter);
 }

 function getRotateValue(element) {
	var matrix = null;
	switch (browser) {
		case 'chrome': { matrix = window.getComputedStyle(element,null).getPropertyValue("-webkit-transform"); break; }
		case 'firefox': { matrix = window.getComputedStyle(element,null).getPropertyValue("-moz-transform"); break; }
	};

	var values = matrix.split('(')[1].split(')')[0].split(',');
	var a = values[0];
	var b = values[1];
	var angle = Math.round(Math.atan2(b, a) * (180/Math.PI));

	return angle;
 }


text:
ACCEPTED

#### According to
International Plant Names Index

#### Published in
null

#### Original name
Macadamia grandis C.L.Gross & B.Hyland

### Remarks
null


text:
// flowlint ambiguous-object-type:error

'use strict';

const Profiler = require('./GraphQLCompilerProfiler');

const orList = require('../util/orList');
const partitionArray = require('../util/partitionArray');

const {DEFAULT_HANDLE_KEY} = require('../util/DefaultHandleKey');
const {
  createCompilerError,
  createUserError,
  eachWithCombinedError,
} = require('./CompilerError');
const {isExecutableDefinitionAST} = require('./SchemaUtils');
const {getFieldDefinitionLegacy} = require('./getFieldDefinition');
const {parse: parseGraphQL, parseType, print, Source} = require('graphql');

import type {
  Argument,
  ArgumentValue,
  Condition,
  Directive,
  Field,
  Fragment,
  FragmentSpread,
  Handle,
  InlineFragment,
  LocalArgumentDefinition,
  Location,
  Root,
  Selection,
  Variable,
} from './IR';
import type {
  CompositeTypeID,
  Argument as FieldArgument,
  FieldID,
  InputTypeID,
  Schema,
  TypeID,
} from './Schema';
import type {GetFieldDefinitionFn} from './getFieldDefinition';
import type {
  ASTNode,
  ArgumentNode,
  BooleanValueNode,
  DefinitionNode,
  DirectiveLocationEnum,
  DirectiveNode,
  EnumValueNode,
  FieldNode,
  FloatValueNode,
  FragmentDefinitionNode,
  FragmentSpreadNode,
  InlineFragmentNode,
  IntValueNode,
  ListValueNode,
  Location as ASTLocation,
  ObjectValueNode,
  OperationDefinitionNode,
  SelectionSetNode,
  StringValueNode,
  TypeNode,
  ValueNode,
  VariableNode,
} from 'graphql';

type ASTDefinitionNode = FragmentDefinitionNode | OperationDefinitionNode;
type NonNullLiteralValueNode =
  | IntValueNode
  | FloatValueNode
  | StringValueNode
  | BooleanValueNode
  | EnumValueNode
  | ListValueNode
  | ObjectValueNode;

type VariableDefinitions = Map<string, VariableDefinition>;
type VariableDefinition = {|
  ast: ASTNode,
  name: string,
  defaultValue: mixed,
  type: InputTypeID,
  defined: boolean,
|};

type UnknownVariable = {|
  ast: VariableNode,
  type: ?TypeID,
|};

const ARGUMENT_DEFINITIONS = 'argumentDefinitions';
const ARGUMENTS = 'arguments';
const DEPRECATED_UNCHECKED_ARGUMENTS = 'uncheckedArguments_DEPRECATED';
const DIRECTIVE_WHITELIST: $ReadOnlySet<string> = new Set([
  ARGUMENT_DEFINITIONS,
  DEPRECATED_UNCHECKED_ARGUMENTS,
  ARGUMENTS,
]);

/**
 * @internal
 *
 * This directive is not intended for use by developers directly. To set a field
 * handle in product code use a compiler plugin.
 */
const CLIENT_FIELD = '__clientField';
const CLIENT_FIELD_HANDLE = 'handle';
const CLIENT_FIELD_KEY = 'key';
const CLIENT_FIELD_FILTERS = 'filters';

const INCLUDE = 'include';
const SKIP = 'skip';
const IF = 'if';

/**
 * Transforms GraphQL text into Relay Compiler's internal, strongly-typed
 * intermediate representation (IR).
 */
function parse(
  schema: Schema,
  text: string,
  filename?: string,
): $ReadOnlyArray<Root | Fragment> {
  const ast = parseGraphQL(new Source(text, filename));
  const parser = new RelayParser(schema.extend(ast), ast.definitions);
  return parser.transform();
}

/**
 * Transforms untyped GraphQL parse trees (ASTs) into Relay Compiler's
 * internal, strongly-typed intermediate representation (IR).
 */
function transform(
  schema: Schema,
  definitions: $ReadOnlyArray<DefinitionNode>,
): $ReadOnlyArray<Root | Fragment> {
  return Profiler.run('RelayParser.transform', () => {
    const parser = new RelayParser(schema, definitions);
    return parser.transform();
  });
}

/**
 * @private
 */
class RelayParser {
  _definitions: Map<string, ASTDefinitionNode>;
  _getFieldDefinition: GetFieldDefinitionFn;
  +_schema: Schema;

  constructor(schema: Schema, definitions: $ReadOnlyArray<DefinitionNode>) {
    this._definitions = new Map();
    // leaving this configurable to make it easy to experiment w changing later
    this._getFieldDefinition = getFieldDefinitionLegacy;
    this._schema = schema;

    const duplicated = new Set();
    definitions.forEach(def => {
      if (isExecutableDefinitionAST(def)) {
        const name = getName(def);
        if (this._definitions.has(name)) {
          duplicated.add(name);
          return;
        }
        this._definitions.set(name, def);
      }
    });
    if (duplicated.size) {
      throw createUserError(
        'RelayParser: Encountered duplicate definitions for one or more ' +
          'documents: each document must have a unique name. Duplicated documents:\n' +
          Array.from(duplicated, name => `- ${name}`).join('\n'),
      );
    }
  }

  transform(): $ReadOnlyArray<Root | Fragment> {
    const nodes = [];
    const entries = new Map();
    // Construct a mapping of name to definition ast + variable definitions.
    // This allows the subsequent AST -> IR tranformation to reference the
    // defined arguments of referenced fragments.
    eachWithCombinedError(this._definitions, ([name, definition]) => {
      const variableDefinitions = this._buildArgumentDefinitions(definition);
      entries.set(name, {definition, variableDefinitions});
    });
    // Convert the ASTs to IR.
    eachWithCombinedError(
      entries.values(),
      ({definition, variableDefinitions}) => {
        const node = parseDefinition(
          this._schema,
          this._getFieldDefinition,
          entries,
          definition,
          variableDefinitions,
        );
        nodes.push(node);
      },
    );
    return nodes;
  }

  /**
   * Constructs a mapping of variable names to definitions for the given
   * operation/fragment definition.
   */
  _buildArgumentDefinitions(
    definition: ASTDefinitionNode,
  ): VariableDefinitions {
    switch (definition.kind) {
      case 'OperationDefinition':
        return this._buildOperationArgumentDefinitions(definition);
      case 'FragmentDefinition':
        return this._buildFragmentArgumentDefinitions(definition);
      default:
        (definition: empty);
        throw createCompilerError(`Unexpected ast kind '${definition.kind}'.`, [
          definition,
        ]);
    }
  }

  /**
   * Constructs a mapping of variable names to definitions using the
   * variables defined in `@argumentDefinitions`.
   */
  _buildFragmentArgumentDefinitions(
    fragment: FragmentDefinitionNode,
  ): VariableDefinitions {
    const variableDirectives = (fragment.directives || []).filter(
      directive => getName(directive) === ARGUMENT_DEFINITIONS,
    );
    if (!variableDirectives.length) {
      return new Map();
    }
    if (variableDirectives.length !== 1) {
      throw createUserError(
        `Directive @${ARGUMENT_DEFINITIONS} may be defined at most once per ` +
          'fragment.',
        null,
        variableDirectives,
      );
    }
    const variableDirective = variableDirectives[0];
    // work, below accesses all report arguments could still be null/undefined.
    const args = variableDirective.arguments;
    if (variableDirective == null || !Array.isArray(args)) {
      return new Map();
    }
    if (!args.length) {
      throw createUserError(
        `Directive @${ARGUMENT_DEFINITIONS} requires arguments: remove the ` +
          'directive to skip defining local variables for this fragment.',
        null,
        [variableDirective],
      );
    }
    const variables = new Map();
    args.forEach(arg => {
      const argName = getName(arg);
      const previousVariable = variables.get(argName);
      if (previousVariable != null) {
        throw createUserError(
          `Duplicate definition for variable '\$${argName}'.`,
          null,
          [previousVariable.ast, arg],
        );
      }
      if (arg.value.kind !== 'ObjectValue') {
        throw createUserError(
          `Expected definition for variable '\$${argName}' to be an object ` +
            "with the shape: '{type: string, defaultValue?: mixed}.",
          null,
          [arg.value],
        );
      }
      let defaultValueNode;
      let typeString;
      arg.value.fields.forEach(field => {
        const name = getName(field);
        if (name === 'type') {
          typeString = transformLiteralValue(field.value, field);
        } else if (name === 'defaultValue') {
          defaultValueNode = field.value;
        } else {
          throw createUserError(
            `Expected definition for variable '\$${argName}' to be an object ` +
              "with the shape: '{type: string, defaultValue?: mixed}.",
            null,
            [arg.value],
          );
        }
      });
      if (typeof typeString !== 'string') {
        throw createUserError(
          `Expected definition for variable '\$${argName}' to be an object ` +
            "with the shape: '{type: string, defaultValue?: mixed}.",
          null,
          [arg.value],
        );
      }
      const typeFromAST = this._schema.getTypeFromAST(parseType(typeString));
      if (typeFromAST == null) {
        throw createUserError(
          // $FlowFixMe[incompatible-type]
          `Unknown type "${typeString}" referenced in the argument definitions.`,
          null,
          [arg],
        );
      }
      const type = this._schema.asInputType(typeFromAST);
      if (type == null) {
        throw createUserError(
          // $FlowFixMe[incompatible-type]
          `Expected type "${typeString}" to be an input type in the "${arg.name.value}" argument definitions.`,
          null,
          [arg.value],
        );
      }
      const defaultValue =
        defaultValueNode != null
          ? transformValue(
              this._schema,
              defaultValueNode,
              type,
              variableAst => {
                throw createUserError(
                  "Expected 'defaultValue' to be a literal, got a variable.",
                  null,
                  [variableAst],
                );
              },
            )
          : null;
      if (defaultValue != null && defaultValue.kind !== 'Literal') {
        throw createUserError(
          "Expected 'defaultValue' to be a literal, got a variable.",
          [defaultValue.loc],
        );
      }
      variables.set(argName, {
        ast: arg,
        defaultValue: defaultValue?.value ?? null,
        defined: true,
        name: argName,
        type,
      });
    });
    return variables;
  }

  /**
   * Constructs a mapping of variable names to definitions using the
   * standard GraphQL syntax for variable definitions.
   */
  _buildOperationArgumentDefinitions(
    operation: OperationDefinitionNode,
  ): VariableDefinitions {
    const schema = this._schema;
    const variableDefinitions = new Map();
    (operation.variableDefinitions || []).forEach(def => {
      const name = getName(def.variable);
      const typeFromAST = schema.getTypeFromAST(def.type);
      if (typeFromAST == null) {
        throw createUserError(
          `Unknown type: '${getTypeName(def.type)}'.`,
          null,
          [def.type],
        );
      }

      const type = schema.asInputType(typeFromAST);
      if (type == null) {
        throw createUserError(
          `Expected type "${getTypeName(def.type)}" to be an input type.`,
          null,
          [def.type],
        );
      }

      const defaultValue = def.defaultValue
        ? transformLiteralValue(def.defaultValue, def)
        : null;
      const previousDefinition = variableDefinitions.get(name);
      if (previousDefinition != null) {
        throw createUserError(
          `Duplicate definition for variable '\$${name}'.`,
          null,
          [previousDefinition.ast, def],
        );
      }
      variableDefinitions.set(name, {
        ast: def,
        defaultValue,
        defined: true,
        name,
        type,
      });
    });
    return variableDefinitions;
  }
}

/**
 * @private
 */
function parseDefinition(
  schema: Schema,
  getFieldDefinition: GetFieldDefinitionFn,
  entries: Map<
    string,
    {|definition: ASTDefinitionNode, variableDefinitions: VariableDefinitions|},
  >,
  definition: ASTDefinitionNode,
  variableDefinitions: VariableDefinitions,
): Fragment | Root {
  const parser = new GraphQLDefinitionParser(
    schema,
    getFieldDefinition,
    entries,
    definition,
    variableDefinitions,
  );
  return parser.transform();
}

/**
 * @private
 */
class GraphQLDefinitionParser {
  _definition: ASTDefinitionNode;
  _entries: Map<
    string,
    {|
      definition: ASTDefinitionNode,
      variableDefinitions: VariableDefinitions,
    |},
  >;
  _getFieldDefinition: GetFieldDefinitionFn;
  _schema: Schema;
  _variableDefinitions: VariableDefinitions;
  _unknownVariables: Map<string, UnknownVariable>;
  _directiveLocations: ?Map<string, $ReadOnlyArray<DirectiveLocationEnum>>;

  constructor(
    schema: Schema,
    getFieldDefinition: GetFieldDefinitionFn,
    entries: Map<
      string,
      {|
        definition: ASTDefinitionNode,
        variableDefinitions: VariableDefinitions,
      |},
    >,
    definition: ASTDefinitionNode,
    variableDefinitions: VariableDefinitions,
  ): void {
    this._definition = definition;
    this._entries = entries;
    this._getFieldDefinition = getFieldDefinition;
    this._schema = schema;
    this._variableDefinitions = variableDefinitions;
    this._unknownVariables = new Map();
  }

  transform(): Root | Fragment {
    const definition = this._definition;
    switch (definition.kind) {
      case 'OperationDefinition':
        return this._transformOperation(definition);
      case 'FragmentDefinition':
        return this._transformFragment(definition);
      default:
        (definition: empty);
        throw createCompilerError(
          `Unsupported definition type ${definition.kind}`,
          [definition],
        );
    }
  }

  _recordAndVerifyVariableReference(
    variable: VariableNode,
    name: string,
    usedAsType: ?TypeID,
  ): void {
    // Special case for variables used in @arguments where we currently
    // aren't guaranteed to be able to resolve the type.
    if (usedAsType == null) {
      if (
        !this._variableDefinitions.has(name) &&
        !this._unknownVariables.has(name)
      ) {
        this._unknownVariables.set(name, {
          ast: variable,
          type: null,
        });
      }
      return;
    }
    const variableDefinition = this._variableDefinitions.get(name);
    if (variableDefinition != null) {
      // If the variable is defined, all usages must be compatible
      let effectiveType = variableDefinition.type;
      if (variableDefinition.defaultValue != null) {
        // If a default value is defined then it is guaranteed to be used
        // at runtime such that the effective type of the variable is non-null
        effectiveType = this._schema.getNonNullType(
          this._schema.getNullableType(effectiveType),
        );
      }

      if (!this._schema.isTypeSubTypeOf(effectiveType, usedAsType)) {
        throw createUserError(
          `Variable '\$${name}' was defined as type '${String(
            variableDefinition.type,
          )}' but used in a location expecting the type '${String(
            usedAsType,
          )}'`,
          null,
          [variableDefinition.ast, variable],
        );
      }
    } else {
      const previous = this._unknownVariables.get(name);

      if (!previous || !previous.type) {
        // No previous usage, current type is strongest
        this._unknownVariables.set(name, {
          ast: variable,
          type: usedAsType,
        });
      } else {
        const {ast: previousVariable, type: previousType} = previous;
        if (
          !(
            this._schema.isTypeSubTypeOf(usedAsType, previousType) ||
            this._schema.isTypeSubTypeOf(previousType, usedAsType)
          )
        ) {
          throw createUserError(
            `Variable '\$${name}' was used in locations expecting the conflicting types '${String(
              previousType,
            )}' and '${String(usedAsType)}'.`,
            null,
            [previousVariable, variable],
          );
        }

        // If the new used type has stronger requirements, use that type as reference,
        // otherwise keep referencing the previous type
        if (this._schema.isTypeSubTypeOf(usedAsType, previousType)) {
          this._unknownVariables.set(name, {
            ast: variable,
            type: usedAsType,
          });
        }
      }
    }
  }

  _getDirectiveLocations(): Map<string, $ReadOnlyArray<DirectiveLocationEnum>> {
    if (!this._directiveLocations) {
      const directiveDefs = this._schema.getDirectives();
      this._directiveLocations = new Map();
      for (const def of directiveDefs) {
        this._directiveLocations.set(def.name, def.locations);
      }
    }
    return this._directiveLocations;
  }

  _validateDirectivesLocation(
    directives: ?$ReadOnlyArray<DirectiveNode>,
    allowedLocaction: DirectiveLocationEnum,
  ): void {
    if (!directives || !directives.length) {
      return;
    }
    const directiveLocs = this._getDirectiveLocations();
    const mismatches = directives.filter(directive => {
      const name = getName(directive);
      if (DIRECTIVE_WHITELIST.has(name)) {
        return false;
      }
      const locs = directiveLocs.get(name);
      if (locs == null) {
        throw createUserError(`Unknown directive '${name}'.`, null, [
          directive,
        ]);
      }
      return !locs.some(loc => loc === allowedLocaction);
    });
    if (mismatches.length) {
      const invalidDirectives = mismatches
        .map(directive => '@' + getName(directive))
        .join(', ');
      throw createUserError(
        `Invalid directives ${invalidDirectives} found on ${allowedLocaction}.`,
        null,
        mismatches,
      );
    }
  }

  _transformFragment(fragment: FragmentDefinitionNode): Fragment {
    const directives = this._transformDirectives(
      (fragment.directives || []).filter(
        directive => getName(directive) !== ARGUMENT_DEFINITIONS,
      ),
      'FRAGMENT_DEFINITION',
    );

    const typeFromAST = this._schema.getTypeFromAST(fragment.typeCondition);
    if (typeFromAST == null) {
      throw createUserError(
        `Fragment "${fragment.name.value}" cannot condition on unknown ` +
          `type "${String(fragment.typeCondition.name.value)}".`,
        null,
        [fragment.typeCondition],
      );
    }

    const type = this._schema.asCompositeType(typeFromAST);
    if (type == null) {
      throw createUserError(
        `Fragment "${fragment.name.value}" cannot condition on non composite ` +
          `type "${String(type)}".`,
        null,
        [fragment.typeCondition],
      );
    }

    const selections = this._transformSelections(
      fragment.selectionSet,
      type,
      fragment.typeCondition,
    );
    const argumentDefinitions = [
      ...buildArgumentDefinitions(this._variableDefinitions),
    ];
    for (const [name, variableReference] of this._unknownVariables) {
      argumentDefinitions.push({
        kind: 'RootArgumentDefinition',
        loc: buildLocation(variableReference.ast.loc),
        name,
        type: variableReference.type,
      });
    }
    return {
      kind: 'Fragment',
      directives,
      loc: buildLocation(fragment.loc),
      metadata: null,
      name: getName(fragment),
      selections,
      type,
      // $FlowFixMe[incompatible-return] - could be null
      argumentDefinitions,
    };
  }

  _getLocationFromOperation(
    definition: OperationDefinitionNode,
  ): DirectiveLocationEnum {
    switch (definition.operation) {
      case 'query':
        return 'QUERY';
      case 'mutation':
        return 'MUTATION';
      case 'subscription':
        return 'SUBSCRIPTION';
      default:
        (definition.operation: empty);
        throw createCompilerError(
          `Unknown operation type '${definition.operation}'.`,
          null,
          [definition],
        );
    }
  }

  _transformOperation(definition: OperationDefinitionNode): Root {
    const name = getName(definition);
    const directives = this._transformDirectives(
      definition.directives || [],
      this._getLocationFromOperation(definition),
    );
    let type: TypeID;
    let operation;
    const schema = this._schema;
    switch (definition.operation) {
      case 'query':
        operation = 'query';
        type = schema.expectQueryType();
        break;
      case 'mutation':
        operation = 'mutation';
        type = schema.expectMutationType();
        break;
      case 'subscription':
        operation = 'subscription';
        type = schema.expectSubscriptionType();
        break;
      default:
        (definition.operation: empty);
        throw createCompilerError(
          `Unknown operation type '${definition.operation}'.`,
          null,
          [definition],
        );
    }
    if (!definition.selectionSet) {
      throw createUserError('Expected operation to have selections.', null, [
        definition,
      ]);
    }
    const selections = this._transformSelections(definition.selectionSet, type);
    const argumentDefinitions = buildArgumentDefinitions(
      this._variableDefinitions,
    );
    if (this._unknownVariables.size !== 0) {
      throw createUserError(
        `Query '${name}' references undefined variables.`,
        null,
        Array.from(
          this._unknownVariables.values(),
          variableReference => variableReference.ast,
        ),
      );
    }
    return {
      kind: 'Root',
      operation,
      loc: buildLocation(definition.loc),
      metadata: null,
      name,
      argumentDefinitions,
      directives,
      selections,
      // $FlowFixMe[incompatible-return]
      type,
    };
  }

  _transformSelections(
    selectionSet: SelectionSetNode,
    parentType: TypeID,
    parentTypeAST?: TypeNode,
  ): $ReadOnlyArray<Selection> {
    return selectionSet.selections.map(selection => {
      let node;
      if (selection.kind === 'Field') {
        node = this._transformField(selection, parentType);
      } else if (selection.kind === 'FragmentSpread') {
        node = this._transformFragmentSpread(
          selection,
          parentType,
          parentTypeAST,
        );
      } else if (selection.kind === 'InlineFragment') {
        node = this._transformInlineFragment(
          selection,
          parentType,
          parentTypeAST,
        );
      } else {
        (selection.kind: empty);
        throw createCompilerError(`Unknown ast kind '${selection.kind}'.`, [
          selection,
        ]);
      }
      const [conditions, directives] = this._splitConditions(node.directives);
      const conditionalNodes = applyConditions(
        conditions,
        // $FlowFixMe[incompatible-call]
        [{...node, directives}],
      );
      if (conditionalNodes.length !== 1) {
        throw createCompilerError(
          'Expected exactly one condition node.',
          null,
          selection.directives,
        );
      }
      return conditionalNodes[0];
    });
  }

  _transformInlineFragment(
    fragment: InlineFragmentNode,
    parentType: TypeID,
    parentTypeAST: ?TypeNode,
  ): InlineFragment {
    const schema = this._schema;
    let typeCondition =
      fragment.typeCondition != null
        ? schema.getTypeFromAST(fragment.typeCondition)
        : parentType;

    if (typeCondition == null) {
      throw createUserError(
        'Inline fragments can only be on object, interface or union types' +
          `, got unknown type '${getTypeName(fragment.typeCondition)}'.`,
        null,
        [fragment.typeCondition ?? fragment],
      );
    }
    const typeConditionName = schema.getTypeString(typeCondition);
    typeCondition = schema.asCompositeType(typeCondition);
    if (typeCondition == null) {
      throw createUserError(
        'Inline fragments can only be on object, interface or union types' +
          `, got '${typeConditionName}'.`,
        null,
        [fragment.typeCondition ?? fragment],
      );
    }
    const rawParentType = this._schema.assertCompositeType(
      this._schema.getRawType(parentType),
    );

    checkFragmentSpreadTypeCompatibility(
      this._schema,
      typeCondition,
      rawParentType,
      null,
      fragment.typeCondition,
      parentTypeAST,
    );

    const directives = this._transformDirectives(
      fragment.directives || [],
      'INLINE_FRAGMENT',
    );
    const selections = this._transformSelections(
      fragment.selectionSet,
      typeCondition,
      fragment.typeCondition,
    );
    return {
      kind: 'InlineFragment',
      directives,
      loc: buildLocation(fragment.loc),
      metadata: null,
      selections,
      typeCondition,
    };
  }

  _transformFragmentSpread(
    fragmentSpread: FragmentSpreadNode,
    parentType: TypeID,
    parentTypeAST: ?TypeNode,
  ): FragmentSpread {
    const fragmentName = getName(fragmentSpread);
    const [argumentDirectives, otherDirectives] = partitionArray(
      fragmentSpread.directives || [],
      directive => {
        const name = getName(directive);
        return name === ARGUMENTS || name === DEPRECATED_UNCHECKED_ARGUMENTS;
      },
    );
    if (argumentDirectives.length > 1) {
      throw createUserError(
        `Directive @${ARGUMENTS} may be used at most once per a fragment spread.`,
        null,
        argumentDirectives,
      );
    }
    const fragmentDefinition = this._entries.get(fragmentName);
    if (fragmentDefinition == null) {
      throw createUserError(`Unknown fragment '${fragmentName}'.`, null, [
        fragmentSpread.name,
      ]);
    }

    const fragmentTypeNode = getFragmentType(fragmentDefinition.definition);
    const fragmentType = this._schema.assertCompositeType(
      this._schema.expectTypeFromAST(fragmentTypeNode),
    );
    const rawParentType = this._schema.assertCompositeType(
      this._schema.getRawType(parentType),
    );

    checkFragmentSpreadTypeCompatibility(
      this._schema,
      fragmentType,
      rawParentType,
      fragmentSpread.name.value,
      fragmentSpread,
      parentTypeAST,
    );

    const fragmentArgumentDefinitions = fragmentDefinition.variableDefinitions;
    const argumentsDirective = argumentDirectives[0];
    let args;
    if (argumentsDirective != null) {
      const isDeprecatedUncheckedArguments =
        getName(argumentsDirective) === DEPRECATED_UNCHECKED_ARGUMENTS;
      let hasInvalidArgument = false;
      args = (argumentsDirective.arguments || []).map(arg => {
        const argName = getName(arg);
        const argValue = arg.value;
        const argumentDefinition = fragmentArgumentDefinitions.get(argName);
        const argumentType = argumentDefinition?.type ?? null;

        if (argValue.kind === 'Variable') {
          if (argumentDefinition == null && !isDeprecatedUncheckedArguments) {
            throw createUserError(
              `Variable @${ARGUMENTS} values are only supported when the ` +
                `argument is defined with @${ARGUMENT_DEFINITIONS}. Check ` +
                `the definition of fragment '${fragmentName}'.`,
              null,
              [arg.value, fragmentDefinition.definition],
            );
          }
          hasInvalidArgument = hasInvalidArgument || argumentDefinition == null;
          // TODO: check the type of the variable and use the type
          return {
            kind: 'Argument',
            loc: buildLocation(arg.loc),
            name: argName,
            value: this._transformVariable(argValue, null),
            type: null,
          };
        } else {
          if (argumentType == null) {
            throw createUserError(
              `Literal @${ARGUMENTS} values are only supported when the ` +
                `argument is defined with @${ARGUMENT_DEFINITIONS}. Check ` +
                `the definition of fragment '${fragmentName}'.`,
              null,
              [arg.value, fragmentDefinition.definition],
            );
          }
          const value = this._transformValue(argValue, argumentType);
          return {
            kind: 'Argument',
            loc: buildLocation(arg.loc),
            name: argName,
            value,
            type: argumentType,
          };
        }
      });
      if (isDeprecatedUncheckedArguments && !hasInvalidArgument) {
        throw createUserError(
          `Invalid use of @${DEPRECATED_UNCHECKED_ARGUMENTS}: all arguments ` +
            `are defined, use @${ARGUMENTS} instead.`,
          null,
          [argumentsDirective],
        );
      }
    }
    const directives = this._transformDirectives(
      otherDirectives,
      'FRAGMENT_SPREAD',
    );
    return {
      kind: 'FragmentSpread',
      args: args || [],
      metadata: null,
      loc: buildLocation(fragmentSpread.loc),
      name: fragmentName,
      directives,
    };
  }

  _transformField(field: FieldNode, parentType: TypeID): Field {
    const schema = this._schema;
    const name = getName(field);
    const fieldDef = this._getFieldDefinition(schema, parentType, name, field);
    if (fieldDef == null) {
      throw createUserError(
        `Unknown field '${name}' on type '${schema.getTypeString(
          parentType,
        )}'.`,
        null,
        [field],
      );
    }
    const alias = field.alias?.value ?? name;
    const args = this._transformArguments(
      field.arguments || [],
      schema.getFieldArgs(fieldDef),
      fieldDef,
    );
    const [otherDirectives, clientFieldDirectives] = partitionArray(
      field.directives || [],
      directive => getName(directive) !== CLIENT_FIELD,
    );
    const directives = this._transformDirectives(otherDirectives, 'FIELD');
    const type = schema.getFieldType(fieldDef);

    const handles = this._transformHandle(name, args, clientFieldDirectives);
    if (schema.isLeafType(schema.getRawType(type))) {
      if (
        field.selectionSet &&
        field.selectionSet.selections &&
        field.selectionSet.selections.length
      ) {
        throw createUserError(
          `Expected no selections for scalar field '${name}'.`,
          null,
          [field],
        );
      }
      return {
        kind: 'ScalarField',
        alias,
        args,
        directives,
        handles,
        loc: buildLocation(field.loc),
        metadata: null,
        name,
        type: schema.assertScalarFieldType(type),
      };
    } else {
      const selections = field.selectionSet
        ? this._transformSelections(field.selectionSet, type)
        : null;
      if (selections == null || selections.length === 0) {
        throw createUserError(
          `Expected at least one selection for non-scalar field '${name}' on type '${schema.getTypeString(
            type,
          )}'.`,
          null,
          [field],
        );
      }
      return {
        kind: 'LinkedField',
        alias,
        args,
        connection: false,
        directives,
        handles,
        loc: buildLocation(field.loc),
        metadata: null,
        name,
        selections,
        type: schema.assertLinkedFieldType(type),
      };
    }
  }

  _transformHandle(
    fieldName: string,
    fieldArgs: $ReadOnlyArray<Argument>,
    clientFieldDirectives: $ReadOnlyArray<DirectiveNode>,
  ): ?$ReadOnlyArray<Handle> {
    let handles: ?Array<Handle> = null;
    clientFieldDirectives.forEach(clientFieldDirective => {
      const handleArgument = (clientFieldDirective.arguments || []).find(
        arg => getName(arg) === CLIENT_FIELD_HANDLE,
      );
      if (handleArgument) {
        let name = null;
        let key = DEFAULT_HANDLE_KEY;
        let filters = null;
        const maybeHandle = transformLiteralValue(
          handleArgument.value,
          handleArgument,
        );
        if (typeof maybeHandle !== 'string') {
          throw createUserError(
            `Expected a string literal argument for the @${CLIENT_FIELD} directive.`,
            null,
            [handleArgument.value],
          );
        }
        name = maybeHandle;

        const keyArgument = (clientFieldDirective.arguments || []).find(
          arg => getName(arg) === CLIENT_FIELD_KEY,
        );
        if (keyArgument) {
          const maybeKey = transformLiteralValue(
            keyArgument.value,
            keyArgument,
          );
          if (typeof maybeKey !== 'string') {
            throw createUserError(
              `Expected a string literal argument for the @${CLIENT_FIELD} directive.`,
              null,
              [keyArgument.value],
            );
          }
          key = maybeKey;
        }
        const filtersArgument = (clientFieldDirective.arguments || []).find(
          arg => getName(arg) === CLIENT_FIELD_FILTERS,
        );
        if (filtersArgument) {
          const maybeFilters = transformLiteralValue(
            filtersArgument.value,
            filtersArgument,
          );
          if (
            !(
              Array.isArray(maybeFilters) &&
              maybeFilters.every(
                filter =>
                  typeof filter === 'string' &&
                  fieldArgs.some(fieldArg => fieldArg.name === filter),
              )
            )
          ) {
            throw createUserError(
              `Expected an array of argument names on field '${fieldName}'.`,
              null,
              [filtersArgument.value],
            );
          }
          // $FlowFixMe[incompatible-cast]
          filters = (maybeFilters: Array<string>);
        }
        const dynamicKeyArgument = (clientFieldDirective.arguments || []).find(
          arg => getName(arg) === 'dynamicKey_UNSTABLE',
        );
        if (dynamicKeyArgument != null) {
          throw createUserError(
            'Dynamic keys are only supported with @connection.',
            null,
            [dynamicKeyArgument.value],
          );
        }
        handles = handles || [];
        handles.push({name, key, filters, dynamicKey: null});
      }
    });
    return handles;
  }

  _transformDirectives(
    directives: $ReadOnlyArray<DirectiveNode>,
    location: DirectiveLocationEnum,
  ): $ReadOnlyArray<Directive> {
    this._validateDirectivesLocation(directives, location);
    return directives.map(directive => {
      const name = getName(directive);
      const directiveDef = this._schema.getDirective(name);
      if (directiveDef == null) {
        throw createUserError(`Unknown directive '${name}'.`, null, [
          directive,
        ]);
      }
      const args = this._transformArguments(
        directive.arguments || [],
        directiveDef.args.map(item => {
          return {
            name: item.name,
            type: item.type,
            defaultValue: item.defaultValue,
          };
        }),
        null,
        name,
      );
      return {
        kind: 'Directive',
        loc: buildLocation(directive.loc),
        name,
        args,
      };
    });
  }

  _transformArguments(
    args: $ReadOnlyArray<ArgumentNode>,
    argumentDefinitions: $ReadOnlyArray<FieldArgument>,
    field?: ?FieldID,
    directiveName?: ?string,
  ): $ReadOnlyArray<Argument> {
    return args.map(arg => {
      const argName = getName(arg);
      const argDef = argumentDefinitions.find(def => def.name === argName);
      if (argDef == null) {
        const message =
          `Unknown argument '${argName}'` +
          (field
            ? ` on field '${this._schema.getFieldName(field)}'` +
              ` of type '${this._schema.getTypeString(
                this._schema.getFieldParentType(field),
              )}'.`
            : directiveName != null
            ? ` on directive '@${directiveName}'.`
            : '.');

        throw createUserError(message, null, [arg]);
      }

      const value = this._transformValue(arg.value, argDef.type);
      return {
        kind: 'Argument',
        loc: buildLocation(arg.loc),
        name: argName,
        value,
        type: argDef.type,
      };
    });
  }

  _splitConditions(
    mixedDirectives: $ReadOnlyArray<Directive>,
  ): [$ReadOnlyArray<Condition>, $ReadOnlyArray<Directive>] {
    const [conditionDirectives, otherDirectives] = partitionArray(
      mixedDirectives,
      directive => directive.name === INCLUDE || directive.name === SKIP,
    );
    const conditions = conditionDirectives.map(directive => {
      const passingValue = directive.name === INCLUDE;
      const arg = directive.args[0];
      if (arg == null || arg.name !== IF) {
        throw createUserError(
          `Expected an 'if' argument to @${directive.name}.`,
          [directive.loc],
        );
      }
      if (!(arg.value.kind === 'Variable' || arg.value.kind === 'Literal')) {
        throw createUserError(
          `Expected the 'if' argument to @${directive.name} to be a variable or literal.`,
          [directive.loc],
        );
      }
      return {
        kind: 'Condition',
        condition: arg.value,
        loc: directive.loc,
        passingValue,
        selections: [],
      };
    });
    const sortedConditions = conditions.sort((a, b) => {
      if (a.condition.kind === 'Variable' && b.condition.kind === 'Variable') {
        return a.condition.variableName < b.condition.variableName
          ? -1
          : a.condition.variableName > b.condition.variableName
          ? 1
          : 0;
      } else {
        // sort literals earlier, variables later
        return a.condition.kind === 'Variable'
          ? 1
          : b.condition.kind === 'Variable'
          ? -1
          : 0;
      }
    });
    return [sortedConditions, otherDirectives];
  }

  _transformVariable(ast: VariableNode, usedAsType: ?InputTypeID): Variable {
    const variableName = getName(ast);
    this._recordAndVerifyVariableReference(ast, variableName, usedAsType);
    return {
      kind: 'Variable',
      loc: buildLocation(ast.loc),
      variableName,
      type: usedAsType,
    };
  }

  _transformValue(ast: ValueNode, type: InputTypeID): ArgumentValue {
    return transformValue(
      this._schema,
      ast,
      type,
      (variableAst, variableType) =>
        this._transformVariable(variableAst, variableType),
    );
  }
}

/**
 * Transforms and validates argument values according to the expected
 * type.
 */
function transformValue(
  schema: Schema,
  ast: ValueNode,
  type: InputTypeID,
  transformVariable: (
    variableAst: VariableNode,
    variableType: InputTypeID,
  ) => ArgumentValue,
): ArgumentValue {
  if (ast.kind === 'Variable') {
    // Special case variables since there is no value to parse
    return transformVariable(ast, type);
  } else if (ast.kind === 'NullValue') {
    // Special case null literals since there is no value to parse
    if (schema.isNonNull(type)) {
      throw createUserError(
        `Expected a value matching type '${String(type)}'.`,
        null,
        [ast],
      );
    }
    return {
      kind: 'Literal',
      loc: buildLocation(ast.loc),
      value: null,
    };
  } else {
    return transformNonNullLiteral(schema, ast, type, transformVariable);
  }
}

/**
 * Transforms and validates non-null literal (non-variable) values
 * according to the expected type.
 */
function transformNonNullLiteral(
  schema: Schema,
  ast: NonNullLiteralValueNode,
  type: InputTypeID,
  transformVariable: (
    variableAst: VariableNode,
    variableType: InputTypeID,
  ) => ArgumentValue,
): ArgumentValue {
  // Transform the value based on the type without a non-null wrapper.
  // Note that error messages should still use the original `type`
  // since that accurately describes to the user what the expected
  // type is (using nullableType would suggest that `null` is legal
  // even when it may not be, for example).
  const nullableType = schema.getNullableType(type);
  if (schema.isList(nullableType)) {
    if (ast.kind !== 'ListValue') {
      // Parse singular (non-list) values flowing into a list type
      // as scalars, ie without wrapping them in an array.
      if (!schema.isInputType(schema.getListItemType(nullableType))) {
        throw createUserError(
          `Expected type ${schema.getTypeString(
            nullableType,
          )} to be an input type.`,
          null,
          [ast],
        );
      }
      return transformValue(
        schema,
        ast,
        schema.assertInputType(schema.getListItemType(nullableType)),
        transformVariable,
      );
    }
    const itemType = schema.assertInputType(
      schema.getListItemType(nullableType),
    );
    const literalList = [];
    const items = [];
    let areAllItemsScalar = true;
    ast.values.forEach(item => {
      const itemValue = transformValue(
        schema,
        item,
        itemType,
        transformVariable,
      );
      if (itemValue.kind === 'Literal') {
        literalList.push(itemValue.value);
      }
      items.push(itemValue);
      areAllItemsScalar = areAllItemsScalar && itemValue.kind === 'Literal';
    });
    if (areAllItemsScalar) {
      return {
        kind: 'Literal',
        loc: buildLocation(ast.loc),
        value: literalList,
      };
    } else {
      return {
        kind: 'ListValue',
        loc: buildLocation(ast.loc),
        items,
      };
    }
  } else if (schema.isInputObject(nullableType)) {
    if (ast.kind !== 'ObjectValue') {
      throw createUserError(
        `Expected a value matching type '${schema.getTypeString(type)}'.`,
        null,
        [ast],
      );
    }
    const literalObject = {};
    const fields = [];
    let areAllFieldsScalar = true;
    const inputType = schema.assertInputObjectType(nullableType);
    const requiredFieldNames = new Set(
      schema
        .getFields(inputType)
        .filter(field => {
          return schema.isNonNull(schema.getFieldType(field));
        })
        .map(field => schema.getFieldName(field)),
    );

    const seenFields = new Map();
    ast.fields.forEach(field => {
      const fieldName = getName(field);
      const seenField = seenFields.get(fieldName);
      if (seenField) {
        throw createUserError(
          `Duplicated field name '${fieldName}' in the input object.`,
          null,
          [field, seenField],
        );
      }
      const fieldID = schema.getFieldByName(inputType, fieldName);
      if (!fieldID) {
        throw createUserError(
          `Unknown field '${fieldName}' on type '${schema.getTypeString(
            inputType,
          )}'.`,
          null,
          [field],
        );
      }
      const fieldConfig = schema.getFieldConfig(fieldID);
      const fieldType = schema.assertInputType(fieldConfig.type);
      const fieldValue = transformValue(
        schema,
        field.value,
        fieldType,
        transformVariable,
      );
      if (fieldValue.kind === 'Literal') {
        literalObject[field.name.value] = fieldValue.value;
      }
      fields.push({
        kind: 'ObjectFieldValue',
        loc: buildLocation(field.loc),
        name: fieldName,
        value: fieldValue,
      });
      seenFields.set(fieldName, field);
      requiredFieldNames.delete(fieldName);
      areAllFieldsScalar = areAllFieldsScalar && fieldValue.kind === 'Literal';
    });
    if (requiredFieldNames.size > 0) {
      const requiredFieldStr = Array.from(requiredFieldNames)
        .map(item => `'${item}'`)
        .join(', ');
      throw createUserError(
        `Missing non-optional field${
          requiredFieldNames.size > 1 ? 's:' : ''
        } ${requiredFieldStr} for input type '${schema.getTypeString(
          inputType,
        )}'.`,
        null,
        [ast],
      );
    }
    if (areAllFieldsScalar) {
      return {
        kind: 'Literal',
        loc: buildLocation(ast.loc),
        value: literalObject,
      };
    } else {
      return {
        kind: 'ObjectValue',
        loc: buildLocation(ast.loc),
        fields,
      };
    }
  } else if (schema.isId(nullableType)) {
    // GraphQLID's parseLiteral() always returns the string value. However
    // the int/string distinction may be important at runtime, so this
    // transform parses int/string literals into the corresponding JS types.
    if (ast.kind === 'IntValue') {
      return {
        kind: 'Literal',
        loc: buildLocation(ast.loc),
        value: parseInt(ast.value, 10),
      };
    } else if (ast.kind === 'StringValue') {
      return {
        kind: 'Literal',
        loc: buildLocation(ast.loc),
        value: ast.value,
      };
    } else {
      throw createUserError(
        `Invalid value, expected a value matching type '${schema.getTypeString(
          type,
        )}'.`,
        null,
        [ast],
      );
    }
  } else if (schema.isEnum(nullableType)) {
    const enumType = schema.assertEnumType(nullableType);
    const value = schema.parseLiteral(enumType, ast);
    if (value == null) {
      const suggestions = schema.getEnumValues(enumType);

      // parseLiteral() should return a non-null JavaScript value
      // if the ast value is valid for the type.
      throw createUserError(
        `Expected a value matching type '${schema.getTypeString(
          type,
        )}'. Possible values: ${orList(suggestions)}?'`,
        null,
        [ast],
      );
    }
    return {
      kind: 'Literal',
      loc: buildLocation(ast.loc),
      value,
    };
  } else if (schema.isScalar(nullableType)) {
    const value = schema.parseLiteral(
      schema.assertScalarType(nullableType),
      ast,
    );
    if (value == null) {
      // parseLiteral() should return a non-null JavaScript value
      // if the ast value is valid for the type.
      throw createUserError(
        `Expected a value matching type '${schema.getTypeString(type)}'.`,
        null,
        [ast],
      );
    }
    return {
      kind: 'Literal',
      loc: buildLocation(ast.loc),
      value,
    };
  } else {
    throw createCompilerError(
      `Unsupported type '${schema.getTypeString(
        type,
      )}' for input value, expected a GraphQLList, ` +
        'GraphQLInputObjectType, GraphQLEnumType, or GraphQLScalarType.',
      null,
      [ast],
    );
  }
}

/**
 * @private
 */
function transformLiteralValue(ast: ValueNode, context: ASTNode): mixed {
  switch (ast.kind) {
    case 'IntValue':
      return parseInt(ast.value, 10);
    case 'FloatValue':
      return parseFloat(ast.value);
    case 'StringValue':
      return ast.value;
    case 'BooleanValue':
      // Note: duplicated because Flow does not understand fall-through cases
      return ast.value;
    case 'EnumValue':
      // Note: duplicated because Flow does not understand fall-through cases
      return ast.value;
    case 'ListValue':
      return ast.values.map(item => transformLiteralValue(item, context));
    case 'NullValue':
      return null;
    case 'ObjectValue': {
      const objectValue = {};
      ast.fields.forEach(field => {
        const fieldName = getName(field);
        const value = transformLiteralValue(field.value, context);
        objectValue[fieldName] = value;
      });
      return objectValue;
    }
    case 'Variable':
      throw createUserError(
        'Unexpected variable where a literal (static) value is required.',
        null,
        [ast, context],
      );
    default:
      (ast.kind: empty);
      throw createCompilerError(`Unknown ast kind '${ast.kind}'.`, [ast]);
  }
}

/**
 * @private
 */
function buildArgumentDefinitions(
  variables: VariableDefinitions,
): $ReadOnlyArray<LocalArgumentDefinition> {
  return Array.from(variables.values(), ({ast, name, defaultValue, type}) => {
    return {
      kind: 'LocalArgumentDefinition',
      loc: buildLocation(ast.loc),
      name,
      type,
      defaultValue,
    };
  });
}

/**
 * @private
 */
function buildLocation(loc: ?ASTLocation): Location {
  if (loc == null) {
    return {kind: 'Unknown'};
  }
  return {
    kind: 'Source',
    start: loc.start,
    end: loc.end,
    source: loc.source,
  };
}

/**
 * @private
 */
function applyConditions(
  conditions: $ReadOnlyArray<Condition>,
  selections: $ReadOnlyArray<Selection>,
): $ReadOnlyArray<Condition | Selection> {
  let nextSelections = selections;
  conditions.forEach(condition => {
    nextSelections = [
      {
        ...condition,
        selections: nextSelections,
      },
    ];
  });
  return nextSelections;
}

/**
 * @private
 */
function getName(ast): string {
  const name = ast.name?.value;
  if (typeof name !== 'string') {
    throw createCompilerError("Expected ast node to have a 'name'.", null, [
      ast,
    ]);
  }
  return name;
}

function getTypeName(ast: ?TypeNode): string {
  return ast ? print(ast) : 'Undefined Type Name';
}

/**
 * @private
 */
function getFragmentType(ast: ASTDefinitionNode): TypeNode {
  if (ast.kind === 'FragmentDefinition') {
    return ast.typeCondition;
  }
  throw createCompilerError(
    'Expected ast node to be a FragmentDefinition node.',
    null,
    [ast],
  );
}

function checkFragmentSpreadTypeCompatibility(
  schema: Schema,
  fragmentType: CompositeTypeID,
  parentType: TypeID,
  fragmentName: ?string,
  fragmentTypeAST: ?TypeNode | ?FragmentSpreadNode,
  parentTypeAST: ?TypeNode,
) {
  if (
    !schema.doTypesOverlap(fragmentType, schema.assertCompositeType(parentType))
  ) {
    const nodes = [];
    if (parentTypeAST) {
      nodes.push(parentTypeAST);
    }
    if (fragmentTypeAST) {
      nodes.push(fragmentTypeAST);
    }

    const possibleConcreteTypes = schema.isAbstractType(parentType)
      ? Array.from(
          schema.getPossibleTypes(schema.assertAbstractType(parentType)),
        )
      : [];
    let suggestedTypesMessage = '';
    if (possibleConcreteTypes.length !== 0) {
      suggestedTypesMessage = ` Possible concrete types include ${possibleConcreteTypes
        .sort()
        .slice(0, 3)
        .map(type => `'${schema.getTypeString(type)}'`)
        .join(', ')}, etc.`;
    }

    throw createUserError(
      (fragmentName != null
        ? `Fragment '${fragmentName}' cannot be spread here as objects of `
        : 'Fragment cannot be spread here as objects of ') +
        `type '${schema.getTypeString(parentType)}' ` +
        `can never be of type '${schema.getTypeString(fragmentType)}'.` +
        suggestedTypesMessage,
      null,
      nodes,
    );
  }
}

module.exports = {parse, transform};


text:
display information about network interfaces

    ifconfig

display MAC addresses

    ifconfig | grep ether

set a new MAC address to en0

    sudo ifconfig en0 ether aa:bb:cc:dd:ee:ff

display local IP addresses

    ifconfig | grep 'inet ' | grep -v '127.0.0.1' | cut -d' ' -f2

# Basic Usage

Display basic information:

    ifconfig

Set network parameters:

    sudo ifconfig <interface> <family> <new_address>


text:
package com.cc.library.dao;

import java.util.List;

import com.cc.library.domain.PageBean;
import com.cc.library.domain.Reader;
import com.cc.library.domain.ReaderType;

public interface ReaderDao {

	public Reader getReader(Reader reader);

	public Reader updateReaderInfo(Reader reader);

	public boolean addReader(Reader reader);

	public PageBean<Reader> findReaderByPage(int pageCode, int pageSize);

	public Reader getReaderById(Reader reader);

	public boolean deleteReader(Reader reader);

	public PageBean<Reader> queryReader(Reader reader,int pageCode, int pageSize);

	public Reader getReaderBypaperNO(Reader reader);

	public int batchAddReader(List<Reader> readers,List<Reader> failReaders);

	public List<Reader> findAllReaders();

}


text:
@php
    $args = array(
      'post_type' => 'feedback',
      'orderby' => 'menu_order',
      'order' => 'ASC',
      'posts_per_page' => -1
    );
    $query = new WP_Query( $args );
@endphp
@if ($query->have_posts())

          @while ($query->have_posts()) @php($query->the_post())

{!!get_field('client_feedback__message')!!}

                  @php($photo = get_field('client_feedback__photo'))

{{get_field('client_feedback__name')}}

                    {{get_field('client_feedback__role')}}

          @endwhile

@endif @php(wp_reset_query()) @php(wp_reset_postdata())


text:
package com.intellij.ide.util.treeView;

import com.intellij.openapi.util.NamedRunnable;

/**
 * @author Sergey.Malenkov
 */
abstract class TreeRunnable extends NamedRunnable {
  protected TreeRunnable(String name) {
    super(name);
  }

  protected abstract void perform();

  @Override
  public final void run() {
    debug("started");
    perform();
    debug("finished");
  }
}


text:
package com.hn.entrance;

import java.awt.Dimension;
import java.awt.Toolkit;
import java.io.File;

import javax.swing.SwingUtilities;
import javax.swing.UIManager;

//import org.apache.log4j.Logger;

import com.hn.controller.CentralController;
import com.hn.controller.MainController;
import com.hn.controller.MediaController;
import com.hn.util.Global;
import com.hn.view.MainFrame;

/**
 * myDownloader入口类
 * @author Administrator
 *
 */
public class MyDownloader {

	boolean packFrame = false;
//	 Logger logger;

	/**
	 * 构造器,构造一个myDownloader下载器
	 */
	public MyDownloader(){

		/*创建myDownloader的其他组件是否完整,如不完整则创建*/
		this.createEnvironment();

		//	logger = Logger.getLogger(MyDownloader.class);

		/*构造主窗口 */
		MainFrame frame = MainFrame.getInstance();

		/*构造下载主控制器*/
		MainController mainController = new MainController();

		/*构造中央控制器*/
		CentralController centralController = new MediaController(mainController,frame);

		/*在主窗口中添加中央控制器*/
		frame.addCentralContoller(centralController);

		/*初始化主窗口*/
		frame.init();

		/*控制器初始化*/
		centralController.startInit();

		// Validate frames that have preset sizes
		// Pack frames that have useful preferred size info, e.g. from their layout
		if (packFrame) {
			frame.pack();
		} else {
			frame.validate();
		}

		// Center the window
		Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
		Dimension frameSize = frame.getSize();
		if (frameSize.height > screenSize.height) {
			frameSize.height = screenSize.height;
		}
		if (frameSize.width > screenSize.width) {
			frameSize.width = screenSize.width;
		}
		frame.setLocation((screenSize.width - frameSize.width) / 2,
				(screenSize.height - frameSize.height) / 2);
		frame.setVisible(true);

		//  logger.info(" myDownloader启动!");
	}

	/**
	 * 搭建myDownloader的其他运行环境,如,建立主文件夹
	 */
	public void createEnvironment(){

		/*myDownloader主目录*/
		File myDownloaderHome = new File(Global.MYDOWNLOADER_PATH);
		if(!myDownloaderHome.exists()){
			myDownloaderHome.mkdir();
		}

		/*下载中文件夹*/
		File running = new File(Global.RUNNING_TASK_PATH);
		if(!running.exists()){
			running.mkdir();
		}

		/*下载完成文件夹*/
		File complete = new File(Global.COMPLETE_TASK_PATH);
		if(!complete.exists()){
			complete.mkdir();
		}

		/*垃圾箱文件夹*/
		File garbage = new File(Global.GARBAGE_TASK_PATH);
		if(!garbage.exists()){
			garbage.mkdir();
		}

		/*日志文件路径*/
		File log = new File(Global.LOG_PATH);
		if(!log.exists()){
			log.mkdir();
		}
	}

	/**
	 * main函数入口
	 * @param args
	 */
	public static void main(String[] args) {
		System.setProperty("http.proxyHost", "10.3.76.8");
		System.setProperty("http.proxyPort", "80");
//http://central.maven.org/maven2/commons-codec/commons-codec/1.10/commons-codec-1.10.jar
		SwingUtilities.invokeLater(new Runnable() {
			public void run() {
				try {
					UIManager.setLookAndFeel(UIManager.
							getSystemLookAndFeelClassName());
				} catch (Exception exception) {
					exception.printStackTrace();
				}

				new MyDownloader();
			}
		});
	}

}


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.
 */
package com.facebook.presto.operator.aggregation.state;

import com.facebook.presto.operator.aggregation.MultiKeyValuePairs;
import com.facebook.presto.spi.function.AccumulatorState;
import com.facebook.presto.spi.function.AccumulatorStateMetadata;
import com.facebook.presto.spi.type.Type;

@AccumulatorStateMetadata(stateFactoryClass = MultiKeyValuePairsStateFactory.class, stateSerializerClass = MultiKeyValuePairStateSerializer.class)
public interface MultiKeyValuePairsState
        extends AccumulatorState
{
    MultiKeyValuePairs get();

    void set(MultiKeyValuePairs value);

    void addMemoryUsage(long memory);

    Type getKeyType();

    Type getValueType();
}


text:
#import "iPhone5DataModelViewController.h"

@class UILabel;

__attribute__((visibility("hidden")))
@interface iPhone5LessonFailViewController : iPhone5DataModelViewController {
	UILabel* _failLabel;
}
@property(assign, nonatomic) __weak UILabel* failLabel;
- (id)initWithNibName:(id)nibName bundle:(id)bundle;
- (void).cxx_destruct;
- (void)didReceiveMemoryWarning;
- (void)viewDidLoad;
- (void)viewWillAppear:(BOOL)view;
- (void)viewWillDisappear:(BOOL)view;
@end


text:
const createAdmin = require('../index')
const createConsumer = require('../../consumer')

const {
  secureRandom,
  createCluster,
  newLogger,
  createTopic,
  waitForConsumerToJoinGroup,
} = require('testHelpers')

describe('Admin', () => {
  let topicName, groupId, admin, consumer

  beforeEach(async () => {
    topicName = `test-topic-${secureRandom()}`
    groupId = `consumer-group-id-${secureRandom()}`

    await createTopic({ topic: topicName })
  })

  afterEach(async () => {
    admin && (await admin.disconnect())
    consumer && (await consumer.disconnect())
  })

  describe('resetOffsets', () => {
    test('throws an error if the groupId is invalid', async () => {
      admin = createAdmin({ cluster: createCluster(), logger: newLogger() })
      await expect(admin.resetOffsets({ groupId: null })).rejects.toHaveProperty(
        'message',
        'Invalid groupId null'
      )
    })

    test('throws an error if the topic name is not a valid string', async () => {
      admin = createAdmin({ cluster: createCluster(), logger: newLogger() })
      await expect(admin.resetOffsets({ groupId: 'groupId', topic: null })).rejects.toHaveProperty(
        'message',
        'Invalid topic null'
      )
    })

    test('set the consumer group offsets to the latest offsets', async () => {
      const cluster = createCluster()
      admin = createAdmin({ cluster, logger: newLogger() })

      await admin.connect()
      await admin.setOffsets({
        groupId,
        topic: topicName,
        partitions: [{ partition: 0, offset: 13 }],
      })

      await admin.resetOffsets({
        groupId,
        topic: topicName,
      })

      const offsets = await admin.fetchOffsets({
        groupId,
        topics: [topicName],
      })

      expect(offsets).toEqual([
        { topic: topicName, partitions: [{ partition: 0, offset: '-1', metadata: null }] },
      ])
    })

    test('set the consumer group offsets to the earliest offsets', async () => {
      const cluster = createCluster()
      admin = createAdmin({ cluster, logger: newLogger() })

      await admin.connect()
      await admin.setOffsets({
        groupId,
        topic: topicName,
        partitions: [{ partition: 0, offset: 13 }],
      })

      await admin.resetOffsets({
        groupId,
        topic: topicName,
        earliest: true,
      })

      const offsets = await admin.fetchOffsets({
        groupId,
        topics: [topicName],
      })

      expect(offsets).toEqual([
        { topic: topicName, partitions: [{ partition: 0, offset: '-2', metadata: null }] },
      ])
    })

    test('throws an error if the consumer group is running', async () => {
      consumer = createConsumer({ groupId, cluster: createCluster(), logger: newLogger() })
      await consumer.connect()
      await consumer.subscribe({ topic: topicName })
      consumer.run({ eachMessage: () => true })
      await waitForConsumerToJoinGroup(consumer)

      admin = createAdmin({ cluster: createCluster(), logger: newLogger() })

      await admin.connect()
      await expect(
        admin.resetOffsets({
          groupId,
          topic: topicName,
        })
      ).rejects.toHaveProperty(
        'message',
        'The consumer group must have no running instances, current state: Stable'
      )
    })
  })
})


text:
del test.lck
del test.log
del test.data
del test.script

copy test.script.bck test.script


text:
//
//  MMURLConnection.h
//  MMURLpp
//
//  Created by Manuele Maggi on 27/04/14.
//  email: manuele.maggi@gmail.com
//  Copyright (c) 2014 Manuele Maggi. All rights reserved.
//
//  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.
//

#ifndef __MMURLpp__MMURLConnection__
#define __MMURLpp__MMURLConnection__

#include <iostream>
#include <pthread.h>
#include <curl/curl.h>
#include "MMURLRequest.h"
#include "MMURLDataBuffer.h"
#include "MMURLResponse.h"
#include "MMURLConnectionDelegate.h"

class MMURLConnection {

protected:

    static CURLcode _curlGlobalInitCode;
    static CURLcode CurlGlobalInit();

    MMURLRequest _request;
    pthread_t _tid;
    CURL *_curl;
    MMURLDataBuffer *_headerBuffer;
    MMURLDataBuffer *_bodyBuffer;
    MMURLResponse _response;
    MMURLConnectionDelegate *_delegate;

    void SetRequest(const MMURLRequest& request);
    void* Perform();
    static void* PerformHelper(void *context) { return ((MMURLConnection *)context)->Perform(); };

    static size_t HandleResponse(void *ptr, size_t size, size_t nmemb, void *context);
    static size_t HandleBody(void *ptr, size_t size, size_t nmemb, void *context);

    void test(MMURLResponse& response);

public:

    // Create connection

    MMURLConnection(const MMURLRequest& request);
    virtual ~MMURLConnection();

    MMURLRequest Request() { return _request; };

    void SetDelegate(MMURLConnectionDelegate *delegate) { _delegate = delegate; };

    // Manage connection

    void Start();
    void Cancel();
};

void testFp(MMURLResponse& response);

#endif /* defined(__MMURLpp__MMURLConnection__) */


text:
+++
hook = "Splitting and merging in action."
location = "San Francisco"
published_at = 2015-03-19T07:27:45Z
title = "Kinesis Shard Splitting & Merging by Example"
+++

The Kinesis developer guide covers shard [splitting and merging from a high-level](http://docs.aws.amazon.com/kinesis/latest/dev/kinesis-using-sdk-java-resharding.html), but I find that it's occasionally helpful to help solidify these types of advanced topics with examples. Here we'll walk through what the most basic splitting and merging operations look like on a Kinesis stream to get a better feel for the concepts.

First of all, I start out with a stream called `split-merge-test` that has a single shard. It's come online and is in an `ACTIVE` state:

``` sh
$ aws kinesis describe-stream --stream-name split-merge-test
{
    "StreamDescription": {
        "StreamStatus": "ACTIVE",
        "StreamName": "split-merge-test",
        "StreamARN": "arn:aws:kinesis:us-east-1:551639669466:stream/split-merge-test",
        "Shards": [
            {
                "ShardId": "shardId-000000000000",
                "HashKeyRange": {
                    "EndingHashKey": "340282366920938463463374607431768211455",
                    "StartingHashKey": "0"
                },
                "SequenceNumberRange": {
                    "StartingSequenceNumber": "49548859072970256769156879668947671610661756289899560962"
                }
            }
        ]
    }
}
```

Note above that the shard has a `HashKeyRange` assigned to it that starts at zero and ends at `340282366920938463463374607431768211455`. When a record is sent into a Kinesis stream, a basic hash function is applied to its partition key. The result of this function maps the record to one of the stream's shards based on the hash key range that each shard handles. A stream's total capacity is increased by subdividing the hash key range on an existing shard so that it maps to more shards than it did before.

## Splitting (#splitting)

Splitting a shard is a manual process in that an operator must decide how to divide up its total hash space between the new shards that will be created. I've decided to split mine evenly between two new shards, so I perform some basic arithmetic on my `EndingHashKey` to find the halfway point between it and zero:

``` ruby
$ irb
irb(main):001:0> 340282366920938463463374607431768211455 / 2
=> 170141183460469231731687303715884105727
```

Now that we have our answer, let's proceed to perform the split:

``` sh
$ aws kinesis split-shard --stream-name split-merge-test \
  --shard-to-split shardId-000000000000 \
  --new-starting-hash-key 170141183460469231731687303715884105727
```

The stream goes into `UPDATING` status. The shards look as they did before because the work to change their topology is still in-progress:

``` sh
$ aws kinesis describe-stream --stream-name split-merge-test
{
    "StreamDescription": {
        "StreamStatus": "UPDATING",
        "StreamName": "split-merge-test",
        "StreamARN": "arn:aws:kinesis:us-east-1:551639669466:stream/split-merge-test",
        "Shards": [
            {
                "ShardId": "shardId-000000000000",
                "HashKeyRange": {
                    "EndingHashKey": "340282366920938463463374607431768211455",
                    "StartingHashKey": "0"
                },
                "SequenceNumberRange": {
                    "StartingSequenceNumber": "49548859072970256769156879668947671610661756289899560962"
                }
            }
        ]
    }
}
```

A few seconds later, we can see the results of our changes. There are a few key things to note below:

* The hash key range of shards is **immutable**. When we split a shard, our "parent" is still available but has now entered a state called `CLOSED` (`shardId-000000000000` in this example). Its entire hash key range has been taken over by its children, `shardId-000000000001` and `shardId-000000000002`. A `CLOSED` shard is easily identifiable by the presence of an `EndingSequenceNumber`.
* The stream is once again `ACTIVE` now that updates are finished.
* Child shards have a pointer called `ParentShardId` back to the parent that they split from so that some history is maintained.
* The stream's sequence number jumped quite a bit during the split, by about 10^48 in fact. This is slightly less impressive when you take into account that the sequence jumps by about 10^24 between two normal record insertions, but this is quite a bit bigger than even that.

``` sh
$ aws kinesis describe-stream --stream-name split-merge-test
{
    "StreamDescription": {
        "StreamStatus": "ACTIVE",
        "StreamName": "split-merge-test",
        "StreamARN": "arn:aws:kinesis:us-east-1:551639669466:stream/split-merge-test",
        "Shards": [
            {
                "ShardId": "shardId-000000000000",
                "HashKeyRange": {
                    "EndingHashKey": "340282366920938463463374607431768211455",
                    "StartingHashKey": "0"
                },
                "SequenceNumberRange": {
                    "EndingSequenceNumber": "49548859072981407141756144980517230543978492779512725506",
                    "StartingSequenceNumber": "49548859072970256769156879668947671610661756289899560962"
                }
            },
            {
                "ShardId": "shardId-000000000001",
                "HashKeyRange": {
                    "EndingHashKey": "170141183460469231731687303715884105726",
                    "StartingHashKey": "0"
                },
                "ParentShardId": "shardId-000000000000",
                "SequenceNumberRange": {
                    "StartingSequenceNumber": "49548859213219643322715968606065803827347328807764754450"
                }
            },
            {
                "ShardId": "shardId-000000000002",
                "HashKeyRange": {
                    "EndingHashKey": "340282366920938463463374607431768211455",
                    "StartingHashKey": "170141183460469231731687303715884105727"
                },
                "ParentShardId": "shardId-000000000000",
                "SequenceNumberRange": {
                    "StartingSequenceNumber": "49548859213241944067914499229207339545619977169270734882"
                }
            }
        ]
    }
}
```

It may also be worth pointing out that although `shardId-000000000000` is considered to be `CLOSED` now, as the last records that it contains leave Kinesis' retention window it will transition from `CLOSED` to `EXPIRED`. When it does, no further records can ever be retrieved from the shard.

## Merging (#merging)

Now let's see what happens when we merge the two shards back together. A merge operation takes two shards as parameters: (1) the main shard to merge, and (2) the adjacent shard that will be mixed into it. Note that the use of the word "adjacent" here is not an accident; because of the way that Kinesis shards handle hash key ranges, only two shards that handle ranges that are contiguous can be merged back together.

``` sh
$ aws kinesis merge-shards --stream-name split-merge-test \
  --shard-to-merge shardId-000000000001 \
  --adjacent-shard-to-merge shardId-000000000002
```

As before, our stream enters `UPDATING`, but does not yet reflect our changes:

``` sh
$ aws kinesis describe-stream --stream-name split-merge-test
{
    "StreamDescription": {
        "StreamStatus": "UPDATING",
        "StreamName": "split-merge-test",
        "StreamARN": "arn:aws:kinesis:us-east-1:551639669466:stream/split-merge-test",
        "Shards": [
            {
                "ShardId": "shardId-000000000000",
                "HashKeyRange": {
                    "EndingHashKey": "340282366920938463463374607431768211455",
                    "StartingHashKey": "0"
                },
                "SequenceNumberRange": {
                    "EndingSequenceNumber": "49548859072981407141756144980517230543978492779512725506",
                    "StartingSequenceNumber": "49548859072970256769156879668947671610661756289899560962"
                }
            },
            {
                "ShardId": "shardId-000000000001",
                "HashKeyRange": {
                    "EndingHashKey": "170141183460469231731687303715884105726",
                    "StartingHashKey": "0"
                },
                "ParentShardId": "shardId-000000000000",
                "SequenceNumberRange": {
                    "StartingSequenceNumber": "49548859213219643322715968606065803827347328807764754450"
                }
            },
            {
                "ShardId": "shardId-000000000002",
                "HashKeyRange": {
                    "EndingHashKey": "340282366920938463463374607431768211455",
                    "StartingHashKey": "170141183460469231731687303715884105727"
                },
                "ParentShardId": "shardId-000000000000",
                "SequenceNumberRange": {
                    "StartingSequenceNumber": "49548859213241944067914499229207339545619977169270734882"
                }
            }
        ]
    }
}
```

And finally the stream re-enters its `ACTIVE` state with our new merged shard. It's worth pointing out that:

* Like before with our split, closed shards `shardId-000000000001` and `shardId-000000000002` are still around, but now have an `EndingSequenceNumber` to indicate that they are closed.
* The new shard `shardId-000000000003` remembers its history. It points back to its `ParentShardId`, as well as the `AdjacentParentShardID` that also helped to derive it.

``` sh
$ aws kinesis describe-stream --stream-name split-merge-test
{
    "StreamDescription": {
        "StreamStatus": "ACTIVE",
        "StreamName": "split-merge-test",
        "StreamARN": "arn:aws:kinesis:us-east-1:551639669466:stream/split-merge-test",
        "Shards": [
            {
                "ShardId": "shardId-000000000000",
                "HashKeyRange": {
                    "EndingHashKey": "340282366920938463463374607431768211455",
                    "StartingHashKey": "0"
                },
                "SequenceNumberRange": {
                    "EndingSequenceNumber": "49548859072981407141756144980517230543978492779512725506",
                    "StartingSequenceNumber": "49548859072970256769156879668947671610661756289899560962"
                }
            },
            {
                "ShardId": "shardId-000000000001",
                "HashKeyRange": {
                    "EndingHashKey": "170141183460469231731687303715884105726",
                    "StartingHashKey": "0"
                },
                "ParentShardId": "shardId-000000000000",
                "SequenceNumberRange": {
                    "EndingSequenceNumber": "49548859213230793695315233917635362760664090379986927634",
                    "StartingSequenceNumber": "49548859213219643322715968606065803827347328807764754450"
                }
            },
            {
                "ShardId": "shardId-000000000002",
                "HashKeyRange": {
                    "EndingHashKey": "340282366920938463463374607431768211455",
                    "StartingHashKey": "170141183460469231731687303715884105727"
                },
                "ParentShardId": "shardId-000000000000",
                "SequenceNumberRange": {
                    "EndingSequenceNumber": "49548859213253094440513764540776898478936738741492908066",
                    "StartingSequenceNumber": "49548859213241944067914499229207339545619977169270734882"
                }
            },
            {
                "ShardId": "shardId-000000000003",
                "HashKeyRange": {
                    "EndingHashKey": "340282366920938463463374607431768211455",
                    "StartingHashKey": "0"
                },
                "ParentShardId": "shardId-000000000001",
                "AdjacentParentShardId": "shardId-000000000002",
                "SequenceNumberRange": {
                    "StartingSequenceNumber": "49548859483727682580892427312894066474572005964670566450"
                }
            }
        ]
    }
}
```

Further splits and merges will all follow same pattern, leaving behind a trail of dead shards that act as a historical record to follow the lifecycle of the stream. The reason behind this design might not be immediately obvious, but sufficed to say that the immutable property of a shard's hash range is important in helping to guarantee that records can be consumed in-order even across a merge or split. We'll leave a more detailed explanation on this topic to a future article.


text:
@interface TNDRPhoto : _TNDRPhoto
{
}

- (id)bestProcessedPhotoForWidth:(float)arg1;
- (id)imageURLForWidth:(float)arg1;
- (id)imageURLForWidth:(float)arg1 useLargerImageIfAvailable:(BOOL)arg2;

@end