text:
package jo.sm.plugins.ship.text;

import jo.sm.data.BlockTypes;
import jo.sm.ui.act.plugin.Description;

@Description(displayName="Write Text on Model", shortDescription="Write text along the length of the selection area")
public class TextParameters
{
	@Description(displayName="Ink", shortDescription="Color to use for lettering")
    private short   mInk;
	@Description(displayName="Font", shortDescription="Font from your computer to draw with")
    private String  mFont;
	@Description(displayName="Boldface")
    private boolean mBold;
	@Description(displayName="Italic")
    private boolean mItalic;
	@Description(displayName="Size", shortDescription="Size of font")
    private int     mSize;
	@Description(displayName="Text", shortDescription="The text you want to draw")
    private String  mText;

    public TextParameters()
    {
        mInk = BlockTypes.HULL_COLOR_BLACK_ID;
        mFont = "Dialog";
        mText = "Jo is Awesome";
        mBold = false;
        mItalic = false;
        mSize = 10;
    }

    public short getInk()
    {
        return mInk;
    }

    public void setInk(short ink)
    {
        mInk = ink;
    }

    public String getText()
    {
        return mText;
    }

    public void setText(String text)
    {
        mText = text;
    }

    public String getFont()
    {
        return mFont;
    }

    public void setFont(String font)
    {
        mFont = font;
    }

    public boolean isBold()
    {
        return mBold;
    }

    public void setBold(boolean bold)
    {
        mBold = bold;
    }

    public boolean isItalic()
    {
        return mItalic;
    }

    public void setItalic(boolean italic)
    {
        mItalic = italic;
    }

    public int getSize()
    {
        return mSize;
    }

    public void setSize(int size)
    {
        mSize = size;
    }
}


text:
package com.kotcrab.vis.editor.util.gdx;

import com.badlogic.gdx.graphics.g2d.ParticleEffect;
import com.badlogic.gdx.graphics.g2d.ParticleEmitter;
import com.badlogic.gdx.graphics.g2d.ParticleEmitter.Particle;
import com.badlogic.gdx.math.Rectangle;

import java.lang.reflect.Field;

/**
 * Particle system related utils
 * @author Kotcrab
 */
public class ParticleUtils {

	//TODO add in settings: use additive mode for particles
	public static Rectangle calculateBoundingRectangle (ParticleEffect effect, Rectangle bounds, boolean additive) {
		Rectangle tempBounds = new Rectangle();

		if (additive == false) bounds.set(0, 0, 0, 0);
		for (int i = 0; i < effect.getEmitters().size; i++) {
			calculateBoundingRectangle(effect.getEmitters().get(i), tempBounds);

			if (isZero(tempBounds) == false) {
				if (isZero(bounds))
					bounds.set(tempBounds);
				else
					bounds.merge(tempBounds);
			}
		}

		return bounds;
	}

	private static boolean isZero (Rectangle rect) {
		return (rect.x == 0 && rect.y == 0 && rect.width == 0 && rect.height == 0);
	}

	/**
	 * Uses reflection (yep) to calculate current bounding rectangle for emitter. Should be uses instead of emitter.getBoundingBox() because
	 * it often returns BoundingBox with Infinity as values making it useless.
	 */
	public static Rectangle calculateBoundingRectangle (ParticleEmitter emitter, Rectangle bounds) {
		try {
			Field fieldParticles = emitter.getClass().getDeclaredField("particles");
			fieldParticles.setAccessible(true);

			Field fieldActive = emitter.getClass().getDeclaredField("active");
			fieldActive.setAccessible(true);

			Particle[] particles = (Particle[]) fieldParticles.get(emitter);
			boolean[] active = (boolean[]) fieldActive.get(emitter);

			if (particles.length == 0)
				return bounds.set(0, 0, 0, 0);

			int startIndex = 0;

			//find first active particle and set first bounding box
			for (; startIndex < particles.length; startIndex++) {
				if (active[startIndex]) {
					bounds.set(particles[startIndex].getBoundingRectangle());
					break;
				}

				return bounds.set(0, 0, 0, 0);
			}

			//merge other active particles
			for (int i = startIndex; i < particles.length; i++) {
				if (active[i]) {
					Particle particle = particles[i];
					bounds.merge(particle.getBoundingRectangle());
				}
			}

			return bounds;
		} catch (NoSuchFieldException | IllegalAccessException e) {
			throw new IllegalStateException(e);
		}
	}
}

redpajama_set_name: RedPajamaGithub


text:
require 'aws-sdk-ec2'
require 'aws-sdk-cloudformation'
require 'active_support/core_ext/class/attribute_accessors'
require_relative 'instance/document'
require_relative '../helpers/aws_cloudformation_stack_resource'

module Aws
  module Stack

    %w[name id].tap do |attrs|
      cloudformation_prefix = 'aws:cloudformation:stack-'
      Aws::EC2::Client
              .new(region: Instance::Document.fetch(:region))
              .describe_tags(
                  filters:
                      [
                          {name: 'key', values: attrs.map {|attr| cloudformation_prefix + attr}},
                          {name: 'resource-id', values: [Instance::Document.fetch(:instance_id)]}
                      ]
              )
              .tags
              .each do |tag|
        mattr_reader(tag.key.sub(cloudformation_prefix, '').to_sym) {tag.value}
      end
    end

    mattr_reader :object do
      ::Aws::CloudFormation::Stack.new(name)
    end

    mattr_reader :client do
      object.client
    end

    def self.resource(logical_id: Instance.logical_id)
      object.resource(logical_id)
    end

  end
end


text:
<!DOCTYPE html>

<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>HaBABY</title>
<meta name="description" content="">
<meta name="author" content="">

<link rel="shortcut icon" href="img/favicon.ico" type="image/x-icon">
<link rel="apple-touch-icon" href="img/apple-touch-icon.png">
<link rel="apple-touch-icon" sizes="72x72" href="img/apple-touch-icon-72x72.png">
<link rel="apple-touch-icon" sizes="114x114" href="img/apple-touch-icon-114x114.png">

<link rel="stylesheet" type="text/css"  href="css/bootstrap.css">
<link rel="stylesheet" type="text/css" href="fonts/font-awesome/css/font-awesome.css">

<link href="css/owl.carousel.css" rel="stylesheet" media="screen">
<link href="css/owl.theme.css" rel="stylesheet" media="screen">

<link rel="stylesheet" type="text/css"  href="css/style.css">
<link rel="stylesheet" type="text/css" href="css/animate.min.css">
<link href='http://fonts.googleapis.com/css?family=Lato:400,700,900,300' rel='stylesheet' type='text/css'>
<link href='http://fonts.googleapis.com/css?family=Open+Sans:400,700,800,600,300' rel='stylesheet' type='text/css'>

      <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1"> Toggle navigation    </button>
       HABABY

الصفحة الرئيسية

التطبيق

كيف يعمل

حول

الفريق

الشهادات

اتصل بنا

English

HABABY

    <p class="wow fadeInDown"هو تطبيق يعتمد على شبكة الإنترنت لمراحل ما قبل الولادة، الولادة، والرعاية ما بعد الولادة للنساء اللاجئات.

    كيف يعمل

 التطبيق

يمكن تحميل التطبيق من

يمكن تحميل  شفرة المصدر من

واستنادا إلى شهر الحمل

النصائح تعطى عموما  تبعا للشهر الحالي للحمل.

الأعراض

الاعراض يمكن العثورعليها داخل التطبيق، والإجراءات التي يتعين اتخاذها (ممثلة بشكل صور) و نقترح ايضا ماذا يجب أن تخبري الطبيب.

الدول

بناء على دولة التواجد, التطبيق يقدم المعلومات المتعلقة بامكانية الدعم المجاني, واسماء الادوية العامة.

التعاون

يمكن إعطاء معلومات إضافية بطريقة الممولة من الحشد.

 كيف يعمل

HABABY هو تطبيق على شبكة الإنترنت لمرحلة ما قبل الولادة، الولادة، والرعاية ما بعد الولادة للنساء اللاجئات. يحتوي على  أعراض الحمل، ومعلومات عن الأدوية

وسوف تتواجد المعلومات بلغات متعددة مع التركيز على الاتصال المرئي، امكانية للدردشة المباشرة مع الرعاية الصحية المختصة وكذلك ميزات بدون اتصال.

جميع

الأثلاث

الأعراض

الدول

الأثلاث

               حدد فيها الثلث أنت، والحصول على المشورة

الأعراض

                التعرف على المحن التي تعاني منها واتبع التعليمات

القطرية-

                اختر البلد أنت والحصول على معلومات حول ما هو حر.

خلفية

  وجاء اسم من خلال الجمع بين كلمة حبيبي  وbaby.

 <img src="img/hababy_logo.png"  width="550" height="262"

وبالنسبة للنساء والأطفال اللاجئين

نستهدف كل من اللاجئات الدائمين والمؤقتين وتحديدا من سوريا والعراق،
في كل من لبنان، اليونان، ألمانيا، فرنسا، المملكة المتحدة، السويد، تركيا، المجر.
 تاتي الثقة في المقام الأول داخل المجتمعات المحلية من نفس البلد.
هذه النساء معرضات لخطر كبيرجراء المضاعفات الجسدية والنفسية المتعلقة بالحمل و
الولادة بسبب وضعهم كلاجئات وتزداد هنا مخاطر سوء التغذية والسل، والعيوب الخلقية، وارتفاع معدل وفيات الرضع، على سبيل المثال لا الحصر.

سهل الاستخدام

متعدد اللغات

  بعد التحميل لا حاجة للاتصال بالانترنت

مجاني

  قابل الفريق

Alessandro Crimi

Public Health policy

<ahref="https://twitter.com/Dr_Alex_Crimi" target="_blank">

Sarah Johnson

Demography & Health Knowledge

 Rosie Brigham

Web Developer

Dan Schuster-Beesley

Policy Adviser for International Development

         Ragi Mcfadden / Science teacher   + arabic speaker @RagiMcFadden

         Leah Kenny / Reproductive & Sexual Health Research

         Audrey Henkels / Database and Information Technology Knowledge

يستخدم التطبيق حاليا

 ونحن نعمل مع  لأطباء العالم  لتكييف الأدوات للاجئين المحتاجين في المملكة المتحدة.

الاتصال بنا

Newspeak House

133 Bethnal Green Road

London, England, E2 7DG

hababy@empowerhack.com

+44 782 110 2139

Project Title

Lorem ipsum dolor sit amet consectetur.

Lorem ipsum dolor sit amet, sea essent iisque iudicabit te, pro no justo delicata inimicus, et oblique docendi laboramus eum. Ei minim fabulas pertinacia pro, graeco urbanitas reformidans quo id. Error congue tacimates ei vis, facer facete ius cu, audiam prodesset pri ut. Id semper fuisset vel, has dolorum menandri eu.

Client: John Doe

Category: Web Design

            <button type="button" class="btn btn-primary" data-dismiss="modal"> Close Project</button>

Project Title

Lorem ipsum dolor sit amet consectetur.

Lorem ipsum dolor sit amet, sea essent iisque iudicabit te, pro no justo delicata inimicus, et oblique docendi laboramus eum. Ei minim fabulas pertinacia pro, graeco urbanitas reformidans quo id. Error congue tacimates ei vis, facer facete ius cu, audiam prodesset pri ut. Id semper fuisset vel, has dolorum menandri eu.

Client: John Doe

Category: Web Design

            <button type="button" class="btn btn-primary" data-dismiss="modal"> Close Project</button>

Project Title

Lorem ipsum dolor sit amet consectetur.

Lorem ipsum dolor sit amet, sea essent iisque iudicabit te, pro no justo delicata inimicus, et oblique docendi laboramus eum. Ei minim fabulas pertinacia pro, graeco urbanitas reformidans quo id. Error congue tacimates ei vis, facer facete ius cu, audiam prodesset pri ut. Id semper fuisset vel, has dolorum menandri eu.

Client: John Doe

Category: Web Design

            <button type="button" class="btn btn-primary" data-dismiss="modal"> Close Project</button>

Project Title

Lorem ipsum dolor sit amet consectetur.

Lorem ipsum dolor sit amet, sea essent iisque iudicabit te, pro no justo delicata inimicus, et oblique docendi laboramus eum. Ei minim fabulas pertinacia pro, graeco urbanitas reformidans quo id. Error congue tacimates ei vis, facer facete ius cu, audiam prodesset pri ut. Id semper fuisset vel, has dolorum menandri eu.

Client: John Doe

Category: Web Design

            <button type="button" class="btn btn-primary" data-dismiss="modal"> Close Project</button>

Project Title

Lorem ipsum dolor sit amet consectetur.

Lorem ipsum dolor sit amet, sea essent iisque iudicabit te, pro no justo delicata inimicus, et oblique docendi laboramus eum. Ei minim fabulas pertinacia pro, graeco urbanitas reformidans quo id. Error congue tacimates ei vis, facer facete ius cu, audiam prodesset pri ut. Id semper fuisset vel, has dolorum menandri eu.

Client: John Doe

Category: Web Design

            <button type="button" class="btn btn-primary" data-dismiss="modal"> Close Project</button>

Project Title

Lorem ipsum dolor sit amet consectetur.

Lorem ipsum dolor sit amet, sea essent iisque iudicabit te, pro no justo delicata inimicus, et oblique docendi laboramus eum. Ei minim fabulas pertinacia pro, graeco urbanitas reformidans quo id. Error congue tacimates ei vis, facer facete ius cu, audiam prodesset pri ut. Id semper fuisset vel, has dolorum menandri eu.

Client: John Doe

Category: Web Design

            <button type="button" class="btn btn-primary" data-dismiss="modal"> Close Project</button>

Project Title

Lorem ipsum dolor sit amet consectetur.

Lorem ipsum dolor sit amet, sea essent iisque iudicabit te, pro no justo delicata inimicus, et oblique docendi laboramus eum. Ei minim fabulas pertinacia pro, graeco urbanitas reformidans quo id. Error congue tacimates ei vis, facer facete ius cu, audiam prodesset pri ut. Id semper fuisset vel, has dolorum menandri eu.

Client: John Doe

Category: Web Design

            <button type="button" class="btn btn-primary" data-dismiss="modal"> Close Project</button>

Project Title

Lorem ipsum dolor sit amet consectetur.

Lorem ipsum dolor sit amet, sea essent iisque iudicabit te, pro no justo delicata inimicus, et oblique docendi laboramus eum. Ei minim fabulas pertinacia pro, graeco urbanitas reformidans quo id. Error congue tacimates ei vis, facer facete ius cu, audiam prodesset pri ut. Id semper fuisset vel, has dolorum menandri eu.

Client: John Doe

Category: Web Design

            <button type="button" class="btn btn-primary" data-dismiss="modal"> Close Project</button>


text:
var worker_scripts = [
  "../csvparser.js",
  "../splaytree.js",
  "../codemap.js",
  "../consarray.js",
  "../profile.js",
  "../profile_view.js",
  "../logreader.js",
  "../tickprocessor.js",
  "composer.js",
  "gnuplot-4.6.3-emscripten.js"
];

function plotWorker() {
  var worker = null;

  function initialize() {
    ui.freeze();
    worker = new Worker("worker.js");
    running = false;

    worker.postMessage({ "call" : "load scripts",
                         "args" : worker_scripts });

    worker.addEventListener("message", function(event) {
      var call = delegateList[event.data["call"]];
      call(event.data["args"]);
    });
  }

  function scriptLoaded() {
    ui.thaw();
  }

  // Public methods.
  this.run = function(filename,
                      resx, resy,
                      distortion,
                      range_start, range_end) {
    var args = {
      'file'        : filename,
      'resx'        : resx,
      'resy'        : resy,
      'distortion'  : distortion,
      'range_start' : range_start,
      'range_end'   : range_end
    }
    worker.postMessage({ 'call' : 'run', 'args' : args });
  }

  this.reset = function() {
    if (worker) worker.terminate();
    initialize();
  }

  var delegateList = {
    "log"         : log,
    "error"       : logError,
    "displayplot" : displayplot,
    "displayprof" : displayprof,
    "range"       : setRange,
    "script"      : scriptLoaded,
    "reset"       : this.reset
  }
}

function UIWrapper() {
  var input_elements = ["range_start",
                        "range_end",
                        "distortion",
                        "start",
                        "file"];

  var other_elements = ["log",
                        "plot",
                        "prof",
                        "instructions",
                        "credits",
                        "toggledisplay"];

  for (var i in input_elements) {
    var id = input_elements[i];
    this[id] = document.getElementById(id);
  }

  for (var i in other_elements) {
    var id = other_elements[i];
    this[id] = document.getElementById(id);
  }

  this.freeze = function() {
    this.plot.style.webkitFilter = "grayscale(1)";
    this.prof.style.color = "#bbb";
    for (var i in input_elements) {
      this[input_elements[i]].disabled = true;
    }
  }

  this.thaw = function() {
    this.plot.style.webkitFilter = "";
    this.prof.style.color = "#000";
    for (var i in input_elements) {
      this[input_elements[i]].disabled = false;
    }
  }

  this.reset = function() {
    this.thaw();
    this.log.value = "";
    this.range_start.value = "automatic";
    this.range_end.value = "automatic";
    this.toggle("plot");
    this.plot.src = "";
    this.prof.value = "";
  }

  this.toggle = function(mode) {
    if (mode) this.toggledisplay.next_mode = mode;
    if (this.toggledisplay.next_mode == "plot") {
      this.toggledisplay.next_mode = "prof";
      this.plot.style.display = "block";
      this.prof.style.display = "none";
      this.toggledisplay.innerHTML = "Show profile";
    } else {
      this.toggledisplay.next_mode = "plot";
      this.plot.style.display = "none";
      this.prof.style.display = "block";
      this.toggledisplay.innerHTML = "Show plot";
    }
  }

  this.info = function(field) {
    var down_arrow = "\u25bc";
    var right_arrow = "\u25b6";
    if (field && this[field].style.display != "none") field = null;  // Toggle.
    this.credits.style.display = "none";
    this.instructions.style.display = "none";
    if (!field) return;
    this[field].style.display = "block";
  }
}

function log(text) {
  ui.log.value += text;
  ui.log.scrollTop = ui.log.scrollHeight;
}

function logError(text) {
  if (ui.log.value.length > 0 &&
      ui.log.value[ui.log.value.length-1] != "\n") {
    ui.log.value += "\n";
  }
  ui.log.value += "ERROR: " + text + "\n";
  ui.log.scrollTop = ui.log.scrollHeight;
  error_logged = true;
}

function displayplot(args) {
  if (error_logged) {
    log("Plot failed.\n\n");
  } else {
    log("Displaying plot. Total time: " +
        (Date.now() - timer) / 1000 + "ms.\n\n");
    var blob = new Blob([new Uint8Array(args.contents).buffer],
                        { "type" : "image\/svg+xml" });
    window.URL = window.URL || window.webkitURL;
    ui.plot.src = window.URL.createObjectURL(blob);
  }

  ui.thaw();
  ui.toggle("plot");
}

function displayprof(args) {
  if (error_logged) return;
  ui.prof.value = args;
  this.prof.style.color = "";
  ui.toggle("prof");
}

function start(event) {
  error_logged = false;
  ui.freeze();

  try {
    var file = getSelectedFile();
    var distortion = getDistortion();
    var range = getRange();
  } catch (e) {
    logError(e.message);
    display();
    return;
  }

  timer = Date.now();
  worker.run(file, kResX, kResY, distortion, range[0], range[1]);
}

function getSelectedFile() {
  var file = ui.file.files[0];
  if (!file) throw Error("No valid file selected.");
  return file;
}

function getDistortion() {
  var input_distortion =
      parseInt(ui.distortion.value, 10);
  if (isNaN(input_distortion)) {
    input_distortion = ui.distortion.value = 4500;
  }
  return input_distortion / 1000000;
}

function getRange() {
  var input_start =
      parseInt(ui.range_start.value, 10);
  if (isNaN(input_start)) input_start = undefined;
  var input_end =
      parseInt(ui.range_end.value, 10);
  if (isNaN(input_end)) input_end = undefined;
  return [input_start, input_end];
}

function setRange(args) {
  ui.range_start.value = args.start.toFixed(1);
  ui.range_end.value = args.end.toFixed(1);
}

function onload() {
  kResX = 1200;
  kResY = 600;
  error_logged = false;
  ui = new UIWrapper();
  ui.reset();
  ui.info(null);
  worker = new plotWorker();
  worker.reset();
}

var kResX;
var kResY;
var error_logged;
var ui;
var worker;
var timer;


text:
namespace Dune.Packets.Impl
{
    public class TusUserAreaReadResponseData : DataChunkBase
    {
        public override PacketType Type
        {
            get { return PacketType.TusUserAreaReadResponseData; }
        }
    }
}


text:
1. Graphic primitives
2. Geometric models on the area
3. Building simple surface
4. Plot three kinds of graphics:
  * linear graphic
  * simple histogramm
  * pie diagramm
5. Drawing combined figures (combine figures which have been drawn in `lab1` using figure's layout in `lab2`)

#### Labs requirements:
1. not added.
2. `Microsoft Visual Studio 2012` or later, `.NET framework 4.5` or later.
    __Using technologies:__ _WPF_
3. `python 2.7` or later including `matplotlib`. You will also need to install compatible versions of `setuptools`, `numpy`, `python-dateutil`, `pytz`, `pyparsing` and `six` in addition to _matplotlib_. Prefered option will to install `python 2.7.8+` version, which include `PyPI` (python package manager) and inslall all require packages from it.
    __Installing links:__
    * [python 2.7](https://www.python.org/downloads/)
    * [matplotlib](http://matplotlib.org/users/installing.html)
4. same as __2__ point.
5. same as __2__ point.


text:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN""http://www.w3.org/TR/REC-html40/frameset.dtd">

<meta name="generator" content="JDiff v1.0.9">

<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared.">
<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet">
<TITLE>
org.apache.pig.impl.logicalLayer.LOLoad
</TITLE>
<LINK REL="stylesheet" TYPE="text/css" HREF="../stylesheet-jdiff.css" TITLE="Style">

       <tt>pig 0.7.0</tt>
       Overview
       Package
        Class
       Statistics
       Help

  Generated by
JDiff

 PREV CLASS
 NEXT CLASS

  FRAMES
   NO FRAMES
   DETAIL:
CONSTRUCTORS |
METHODS |
FIELDS

Class org.apache.pig.impl.logicalLayer.<tt>LOLoad</tt>

The superclass changed from org.apache.pig.impl.logicalLayer.LogicalOperator to org.apache.pig.impl.logicalLayer.RelationalOperator.

  Changed Constructors

  <nobr><tt>LOLoad</tt>(LogicalPlan,</nobr> OperatorKey<nobr>,</nobr> FileSpec<nobr>,</nobr> Configuration<nobr><nobr>)  </nobr>

Change in type from (LogicalPlan, OperatorKey, FileSpec, ExecType, DataStorage, boolean) to (LogicalPlan, OperatorKey, FileSpec, Configuration).

  @param plan LogicalPlan this operator is a part of.

  Removed Methods

  <nobr>boolean <tt>isSplittable</tt>()</nobr>

  Added Methods

  <nobr>Configuration <tt>getConfiguration</tt>()</nobr>

  <nobr>List <tt>getRelevantInputs</tt>(int,</nobr> int<nobr><nobr>)</nobr>

  <nobr>RequiredFieldList <tt>getRequiredFieldList</tt>()</nobr>

  <nobr>boolean <tt>pruneColumns</tt>(List)</nobr>

  <nobr>RequiredFieldResponse <tt>pushProjection</tt>(RequiredFieldList)</nobr>

  Changed Methods

  <nobr>void <tt>setAlias</tt>(String)  </nobr>

Method was inherited from <tt>LogicalOperator</tt>, but is now defined locally.

  Removed Fields

  <nobr>boolean <tt>splittable</tt></nobr>

       <tt>pig 0.7.0</tt>
       Overview
       Package
        Class
       Statistics
       Help

 PREV CLASS
 NEXT CLASS

  FRAMES
   NO FRAMES


text:
**Example:** We will load the following table

    $flat = Mage::getModel('colin_database/results')->load(1);

The model calls the Resource model load in between *_beforeSave()* and *_afterSave()*

**Mage_Core_Model_Resource_Db_Abstract->load()**

This does the following:

1. Gets the main field
2. Creates a Varien_Db_Select object for the query with the main field in

      $select = $this->_getLoadSelect($field, $value, $object);

So the query if called the __toString method would be

    SELECT `football_results`.* FROM `football_results` WHERE (`football_results`.`id`=1)

3. Fetches Row from Read Adapter

    $read->fetchRow($select);

## 1.2. EAV

**Example:**

      $eav = Mage::getModel('colin_eav/blog')->load(1);

This does the same and calls the Resource Model load.

**Mage_Eav_Model_Entity_Abstract->load($object, $entityId, $attributes = array())**

1. Loads the main row from "blog_entity".

    $select  = $this->_getLoadRowSelect($object, $entityId);
    $row     = $this->_getReadAdapter()->fetchRow($select);

2. Checks if $attribute is empty. If it is it will load all attributes with *loadAllAttributes* or otherwise loop through the attributes and load each one by *getAttribute($code)*.

3. Loads attributes to the $object with

      $this->_loadModelAttributes($object)

### 1.2.1. loadAllAttributes

This will get an array of attributes with the following code and then load the attribute with *getAttribute($code)*

      $attributeCodes = Mage::getSingleton('eav/config')
          ->getEntityAttributeCodes($this->getEntityType(), $object);

# 2. Save

- Flat tables save to 1 row in **Mage_Core_Model_Resource_Db_Abstract->save($object)**
- EAV tables save to multiple tables with **Mage_Eav_Model_Entity_Abstract->save($object)**


text:
package com.iclockwork.percy.app.jxt.controller;

import com.iclockwork.percy.app.clazz.model.entity.Clazz;
import com.iclockwork.percy.app.clazz.service.ClassService;
import com.iclockwork.percy.app.jxt.commons.model.entity.Parent;
import com.iclockwork.percy.app.jxt.service.ParentService;
import com.iclockwork.percy.app.jxt.service.ParentStudentRpService;
import com.iclockwork.percy.base.common.Constant;
import com.iclockwork.percy.base.contorller.BaseWebAppController;
import com.iclockwork.percy.base.model.entity.User;
import com.iclockwork.percy.commons.data.Result;
import com.iclockwork.percy.framework.data.PageObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

/**
 * ParentController
 *
 * @author: fengwang
 * @date: 2016/8/28 13:48
 * @version: 1.0
 * @since: JDK 1.7
 */
@Controller
@RequestMapping(value = "/a/jxt/m/{classId}/parent/")
public class ParentController extends BaseWebAppController {
    /**
     * 日志
     */
    private static final Logger log = LoggerFactory.getLogger(ParentController.class);

    @Autowired
    private ParentService parentService;

    @Autowired
    private ClassService classService;

    @Autowired
    private ParentStudentRpService parentStudentRpService;

    /**
     * 首页
     *
     * @return ModelAndView
     */
    @RequestMapping(value = "/", method = RequestMethod.GET)
    public ModelAndView index(@PathVariable String classId) throws Exception {
        Map<String, Object> resultMap = new HashMap<String, Object>();
        Clazz clazz = classService.findById(classId);
        resultMap.put("clazz", clazz);
        //是否可以管理
        User user = this.getLoginUser();
        if (Constant.USER_TYPE_ADMIN.equals(user.getUserType())) {
            resultMap.put("isAdmin", true);
        } else {
            if (user.getUserId().equals(clazz.getHeadTeacherUserId())) {
                resultMap.put("isAdmin", true);
            } else {
                resultMap.put("isAdmin", false);
            }
        }
        return new ModelAndView("view.app.jxt.parent.index", resultMap);
    }

    /**
     * 列表
     *
     * @throws IOException
     */
    @RequestMapping(value = "/list", method = RequestMethod.POST)
    @ResponseBody
    public PageObject list(@PathVariable String classId, int start, String keyword, Integer bindStatus) throws Exception {
        return parentService.findAllByPage(start, DEFAULT_PAGE_SIZE, keyword, classId, bindStatus);
    }

    /**
     * 进入新增
     *
     * @return ModelAndView
     */
    @RequestMapping(value = "/new", method = RequestMethod.GET)
    public ModelAndView toAdd(@PathVariable String classId) throws Exception {
        Map<String, Object> resultMap = new HashMap<String, Object>();
        resultMap.put("mode", "new");
        resultMap.put("classId", classId);
        resultMap.put("students", parentStudentRpService.getStudents(null, classId));
        return new ModelAndView("view.app.jxt.parent.edit", resultMap);
    }

    /**
     * 进入更新
     *
     * @return ModelAndView
     */
    @RequestMapping(value = "/{id}/edit", method = RequestMethod.GET)
    public ModelAndView toEdit(@PathVariable String classId, @PathVariable String id) throws Exception {
        Map<String, Object> resultMap = new HashMap<String, Object>();
        Parent parent = parentService.findById(id);
        resultMap.put("mode", "edit");
        resultMap.put("classId", classId);
        resultMap.put("parent", parent);
        resultMap.put("students", parentStudentRpService.getStudents(id, classId));
        return new ModelAndView("view.app.jxt.parent.edit", resultMap);
    }

    /**
     * 保存新增
     *
     * @return ModelAndView
     */
    @RequestMapping(value = "/", method = RequestMethod.POST)
    @ResponseBody
    public Result create(@PathVariable String classId, Parent parent, String[] studentIds) throws IOException {
        Result result = new Result();
        try {
            parentService.insert(parent, studentIds, this.getLoginUser().getUserId());
            result.setReturnCode(Result.RETURN_CODE_SUCC);
        } catch (Exception e) {
            result.setMsg(e.getMessage());
            log.error(e.getMessage());
        }
        return result;
    }

    /**
     * 保存更新
     *
     * @return ModelAndView
     */
    @RequestMapping(value = "/{id}", method = RequestMethod.PUT)
    @ResponseBody
    public Result update(@PathVariable String classId, @PathVariable String id, Parent parent, String[] studentIds) throws IOException {
        Result result = new Result();
        try {
            parentService.update(id, parent, studentIds, this.getLoginUser().getUserId());
            result.setReturnCode(Result.RETURN_CODE_SUCC);
        } catch (Exception e) {
            result.setMsg(e.getMessage());
            log.error(e.getMessage());
        }
        return result;
    }

    /**
     * 删除
     *
     * @return ModelAndView
     */
    @RequestMapping(value = "/{id}", method = RequestMethod.DELETE)
    @ResponseBody
    public Result delete(@PathVariable String classId, @PathVariable String id) throws IOException {
        Result result = new Result();
        try {
            parentService.delete(id, this.getLoginUser().getUserId());
            result.setReturnCode(Result.RETURN_CODE_SUCC);
        } catch (Exception e) {
            result.setMsg(e.getMessage());
            log.error(e.getMessage());
        }
        return result;
    }

    /**
     * 同步
     *
     * @return ModelAndView
     */
    @RequestMapping(value = "/syn", method = RequestMethod.POST)
    @ResponseBody
    public Result syn(@PathVariable String classId) throws IOException {
        Result result = new Result();
        try {
            parentService.syn(classId, this.getLoginUser().getOrganizationId());
            result.setReturnCode(Result.RETURN_CODE_SUCC);
        } catch (Exception e) {
            result.setMsg(e.getMessage());
            log.error(e.getMessage());
        }
        return result;
    }
}


text:
'use strict';
var isA = require("Espresso/oop").isA;
var oop = require("Espresso/oop").oop;
var init = require("Espresso/oop").init;

var trim = require("Espresso/trim").trim;
var isA = require("Espresso/oop").isA;

var oop = require("Espresso/oop").oop;

function ParentNodeInterface(){
	if(typeof this.children !== 'function')
		throw new ImplementationException('children');
	if(typeof this.append !== 'function')
		throw new ImplementationException('append');
	if(typeof this.setBuilder !== 'function')
		throw new ImplementationException('setBuilder');

	oop(this,"Espresso/Config/Definition/Builder/ParentNodeInterface");
}

module.exports = ParentNodeInterface;


text:
description: Learn how to install Docker Universal Control Plane on production
keywords: Universal Control Plane, UCP, install
title: Install UCP for production
---

Docker Universal Control Plane (UCP) is a containerized application that can be
installed on-premise or on a cloud infrastructure.

If you're installing Docker Datacenter on Azure, [follow this guide](https://success.docker.com/?cid=ddc-on-azure).

## Step 1: Validate the system requirements

The first step to installing UCP, is ensuring your
infrastructure has all the [requirements UCP needs to run](system-requirements.md).

## Step 2: Install CS Docker on all nodes

UCP is a containerized application that requires CS Docker Engine 1.12.0 or
above to run. Start by installing CS Docker Engine on all hosts that you want to
manage with UCP.

Make sure you install the same CS Docker Engine version on all the nodes. Also,
if you're creating virtual machine templates with CS Docker Engine  already
installed, make sure the `/etc/docker/key.json` file is not included in the
virtual machine image. When provisioning the virtual machine, restart the Docker
daemon to generate a new `/etc/docker/key.json` file.

## Step 3: Customize named volumes

Skip this step if you want to use the defaults provided by UCP.

Docker UCP uses named volumes to persist data. If you want
to customize the drivers used to manage these volumes, you can create the
volumes before installing UCP. When you install UCP, the installer
will notice that the volumes already exist, and will start using them.
[Learn about the named volumes used by UCP](../architecture.md).

If these volumes don't exist, they'll be automatically created when installing
UCP.

## Step 4: Install UCP

To install UCP you use the `docker/ucp` image, which has commands to install and
manage UCP.

To install UCP:

1. Use ssh to log in into the host where you want to install UCP.

2.  Run the following command:

    ```bash
    # Pull the latest version of UCP
    $ docker pull docker/ucp:latest

    # Install UCP
    $ docker run --rm -it --name ucp \
      -v /var/run/docker.sock:/var/run/docker.sock \
      docker/ucp install \
      --host-address <node-ip-address> \
      --interactive
    ```

    This runs the install command in interactive mode, so that you're
    prompted for any necessary configuration values.
    To find what other options are available in the install command, check the
    [reference documentation](../../reference/cli/install.md).

## Step 5: License your installation

Now that UCP is installed, you need to license it. In your browser, navigate
to the UCP web UI and upload your license.

![](../images/install-production-1.png)

If you don't have a license yet, [learn how to get a free trial license](license.md).

## Step 6: Join manager nodes

Skip this step if you don't want your UCP swarm to be highly available.

To make your UCP swarm fault-tolerant and highly available, you
can join more manager nodes to your it. Manager nodes are the nodes in the
swarm that perform the orchestration and swarm management tasks, and
dispatch tasks for worker nodes to execute.
[Learn more about high-availability](../high-availability/index.md).

To join manager nodes to the swarm, go to the **UCP web UI**, navigate to
the **Resources** page, and go to the **Nodes** section.

![](../images/install-production-2.png)

Click the **Add Node button** to add a new node.

![](../images/install-production-3.png)

Check the 'Add node as a manager' to turn this node into a manager and replicate
UCP for high-availability.
Set the 'Use a custom listen address' option if you want to customize the
network and port where this node will listen for swarm management traffic. By
default the node listens on port 2377.
Set the 'Use a custom advertise address' option if you want to customize the
network and port this node will advertise to other swarm members so that they
can reach it.

For each manager node that you want to join to UCP, login into that
node using ssh, and run the join command that is displayed on UCP.

![](../images/install-production-4.png)

After you run the join command in the node, the node starts being displayed
in UCP.

## Step 7: Join worker nodes

Skip this step if you don't want to add more nodes to run and scale your apps.

To add more computational resources to your swarm, you can join worker nodes.
These nodes execute tasks assigned to them by the manager nodes. For this,
use the same steps as before, but don't check the 'Add node as a manager'
option.

## Where to go next

* [Use externally-signed certificates](../configuration/index.md)
* [Integrate with LDAP](../configuration/integrate-with-ldap.md)


text:
package com.alibaba.jstorm.ui.controller;

import backtype.storm.generated.NotAliveException;
import backtype.storm.generated.TopologyInfo;
import backtype.storm.utils.NimbusClient;
import com.alibaba.jstorm.client.ConfigExtension;
import com.alibaba.jstorm.cluster.Common;
import com.alibaba.jstorm.ui.model.Response;
import com.alibaba.jstorm.ui.model.UIWorkerMetric;
import com.alibaba.jstorm.ui.utils.NimbusClientManager;
import com.alibaba.jstorm.ui.utils.UIMetricUtils;
import com.alibaba.jstorm.ui.utils.UIUtils;
import com.alibaba.jstorm.utils.JStormServerUtils;
import com.alibaba.jstorm.utils.JStormUtils;
import org.apache.commons.lang.StringEscapeUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.http.Header;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;

import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.*;
import java.util.concurrent.*;

/**
 * @author Jark (wuchong.wc@alibaba-inc.com)
 */
@Controller
public class LogController {
    private static final Logger LOG = LoggerFactory.getLogger(LogController.class);

    private static final long MAX_DOWNLOAD_SIZE = 10 * 1024 * 1024; //10MB
    private static final int BLOCK_DOWNLOAD_SIZE = 1024 * 1024;     //block size of every download request 1M
    private static final int KEY_WORD_MIN_LENGTH = 2;

    private static ThreadPoolExecutor _backround = new ThreadPoolExecutor(0,Integer.MAX_VALUE, 60L,TimeUnit.SECONDS, new SynchronousQueue<Runnable>());

    @RequestMapping(value = "/log", method = RequestMethod.GET)
    public String show(@RequestParam(value = "cluster", required = true) String clusterName,
                       @RequestParam(value = "host", required = true) String host,
                       @RequestParam(value = "port", required = false) String logServerPort,
                       @RequestParam(value = "dir", required = false) String dir,
                       @RequestParam(value = "wport", required = false) String workerPort,
                       @RequestParam(value = "file", required = false) String logName,
                       @RequestParam(value = "tid", required = false) String topologyId,
                       @RequestParam(value = "pos", required = false) String pos,
                       ModelMap model) {
        if (UIUtils.isValidSupervisorHost(clusterName, host)) {
            UIUtils.addErrorAttribute(model, new RuntimeException("Not a valid host: " + host));
            return "log";
        }

        clusterName = StringEscapeUtils.escapeHtml(clusterName);
        topologyId = StringEscapeUtils.escapeHtml(topologyId);
        if (StringUtils.isBlank(dir)) {
            dir = ".";
        }
        Map conf = UIUtils.getNimbusConf(clusterName);
        Event event = new Event(clusterName, host, logServerPort, logName, topologyId, workerPort, pos, dir, conf);

        try {
            requestLog(event, model);
        } catch (IOException e) {
            e.printStackTrace();
        }

        model.addAttribute("logName", event.logName);
        model.addAttribute("host", host);
        model.addAttribute("dir", event.dir);
        model.addAttribute("clusterName", clusterName);
        model.addAttribute("logServerPort", logServerPort);
        model.addAttribute("topologyId", topologyId);
        model.addAttribute("fullFile", getFullFile(event.dir, event.logName));
        model.addAttribute("workerPort", workerPort);
        return "log";
    }

    @RequestMapping(value = "/logSearch", method = RequestMethod.GET)
    public String search(@RequestParam(value = "cluster", required = true) String clusterName,
                         @RequestParam(value = "host", required = true) String host,
                         @RequestParam(value = "port", required = true) String logServerPort,
                         @RequestParam(value = "dir", required = true) String dir,
                         @RequestParam(value = "file", required = true) String logName,
                         @RequestParam(value = "key", required = false) String keyword,
                         @RequestParam(value = "workerPort", required = false) String workerPort,
                         @RequestParam(value = "tid", required = false) String topologyId,
                         @RequestParam(value = "pos", required = false) String pos,
                         @RequestParam(value = "caseIgnore", required = false) String caseIgnore,
                         ModelMap model) {

        if (UIUtils.isValidSupervisorHost(clusterName, host)) {
            UIUtils.addErrorAttribute(model, new RuntimeException("Not a valid host: " + host));
            return "logSearch";
        }

        clusterName = StringEscapeUtils.escapeHtml(clusterName);
        topologyId = StringEscapeUtils.escapeHtml(topologyId);
        if (StringUtils.isBlank(dir)) {
            dir = ".";
        }
        String fullFile = getFullFile(dir, logName);
        boolean _caseIgnore = !StringUtils.isBlank(caseIgnore);
        model.addAttribute("keyword", keyword);
        try {
            keyword = URLEncoder.encode(keyword, "UTF-8");      // encode space and url characters
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
            LOG.error(e.getMessage(), e);
            UIUtils.addErrorAttribute(model, e);
        }
        String url = String.format("http://%s:%s/logview?cmd=searchLog&file=%s&key=%s&offset=%s&case_ignore=%s",
                host, logServerPort, fullFile, keyword, JStormUtils.parseLong(pos, 0), _caseIgnore);

        if (filterKeyword(model, keyword)) {
            try {
                HttpResponse httpResponse = httpGet(url);
                String data = EntityUtils.toString(httpResponse.getEntity());
                Map result = (Map) JStormUtils.from_json(data);
                if (result == null) {
                    model.addAttribute("tip", data);
                } else if (result.get("error") != null) {
                    model.addAttribute("tip", result.get("msg"));
                } else {
                    model.addAttribute("matchResults", result.get("match_results"));
                    model.addAttribute("nextOffset", result.get("next_offset"));
                    model.addAttribute("numMatch", result.get("num_match"));
                }
            } catch (IOException e) {
                e.printStackTrace();
                model.addAttribute("tip", "Internal Error, can't get response from logview");
            }
        }

        model.addAttribute("host", host);
        model.addAttribute("clusterName", clusterName);
        model.addAttribute("logServerPort", logServerPort);
        model.addAttribute("topologyId", topologyId);
        model.addAttribute("workerPort", workerPort);
        model.addAttribute("dir", dir);
        model.addAttribute("file", logName);
        model.addAttribute("caseIgnore", _caseIgnore);
        UIUtils.addTitleAttribute(model, "LogSearch");
        return "logSearch";
    }

    class SearchRequest implements Callable<Void> {

        private String url;
        private String host;
        private String port;
        private String dir;
        private String file;
        private ConcurrentLinkedQueue<Map> result;

        public SearchRequest(String url, String host, String port, String dir, String file, ConcurrentLinkedQueue<Map> result) {
            this.url = url;
            this.host = host;
            this.port = port;
            this.dir = dir;
            this.file = file;
            this.result = result;
        }

        @Override
        public Void call() throws Exception {
            try {
                HttpResponse httpResponse = httpGet(url);
                String data = EntityUtils.toString(httpResponse.getEntity());
                Map matchResult = (Map) JStormUtils.from_json(data);
                Map<String, Object> res = new HashMap<>();
                if (matchResult != null && matchResult.get("error") == null){
                    res.put("match", matchResult.get("match_results"));
                    res.put("host", host);
                    res.put("port", port);
                    res.put("dir", dir);
                    res.put("file", file);

                }
                result.add(res);

            } catch (IOException e) {
                e.printStackTrace();
            }
            return null;
        }
    }

    @RequestMapping(value = "/deepSearch", method = RequestMethod.GET)
    public String deepSearch(@RequestParam(value = "cluster", required = true) String clusterName,
                             @RequestParam(value = "tid", required = true) String topologyId,
                             @RequestParam(value = "key", required = false) String keyword,
                             @RequestParam(value = "caseIgnore", required = false) String caseIgnore,
                             ModelMap model) {
        clusterName = StringEscapeUtils.escapeHtml(clusterName);
        topologyId = StringEscapeUtils.escapeHtml(topologyId);
        boolean _caseIgnore = !StringUtils.isBlank(caseIgnore);
        int port = UIUtils.getSupervisorPort(clusterName);
        model.addAttribute("keyword", keyword);
        List<Future<?>> futures = new ArrayList<>();
        ConcurrentLinkedQueue<Map> result = new ConcurrentLinkedQueue<>();

        if (filterKeyword(model, keyword)) {
            NimbusClient client = null;
            try {
                keyword = URLEncoder.encode(keyword, "UTF-8");      // encode space and url characters
                client = NimbusClientManager.getNimbusClient(clusterName);
                TopologyInfo info = client.getClient().getTopologyInfo(topologyId);
                String topologyName = info.get_topology().get_name();
                List<UIWorkerMetric> workerData = UIMetricUtils.getWorkerMetrics(info.get_metrics().get_workerMetric(), topologyId, 60);
                String dir = "." + File.separator +  topologyName;
                for (UIWorkerMetric metric : workerData){
                    String logFile = topologyName + "-worker-" + metric.getPort() + ".log";
                    String url = String.format("http://%s:%s/logview?cmd=searchLog&file=%s&key=%s&offset=%s&case_ignore=%s",
                            metric.getHost(), port, getFullFile(dir, logFile), keyword, 0, _caseIgnore);
                    futures.add(_backround.submit(new SearchRequest(url, metric.getHost(), metric.getPort(), dir, logFile, result)));
                }

                JStormServerUtils.checkFutures(futures);

                model.addAttribute("result", result);

            } catch (NotAliveException nae) {
                model.addAttribute("tip", String.format("The topology: %s is dead.", topologyId));
            } catch (Exception e) {
                NimbusClientManager.removeClient(clusterName);
                LOG.error(e.getMessage(), e);
                UIUtils.addErrorAttribute(model, e);
            }
        }

        model.addAttribute("clusterName", clusterName);
        model.addAttribute("topologyId", topologyId);
        model.addAttribute("logServerPort", port);
        model.addAttribute("caseIgnore", _caseIgnore);
        UIUtils.addTitleAttribute(model, "DeepSearch");

        return "deepSearch";
    }

    private boolean filterKeyword(ModelMap model, String keyword) {
        if (!StringUtils.isBlank(keyword)) {
            if (keyword.length() > KEY_WORD_MIN_LENGTH) {
                return true;
            } else {
                model.addAttribute("tip", "The keyword length must larger than 2");
                return false;
            }
        }
        // skip search for empty keyword
        return false;
    }

    @RequestMapping(value = "/download", method = RequestMethod.GET)
    public void download(@RequestParam(value = "cluster", required = true) String clusterName,
                         @RequestParam(value = "host", required = true) String host,
                         @RequestParam(value = "port", required = false) String logServerPort,
                         @RequestParam(value = "dir", required = false) String dir,
                         @RequestParam(value = "file", required = false) final String filename,
                         HttpServletResponse response) {

        if (UIUtils.isValidSupervisorHost(clusterName, host)) {
            return;
        }

        if (StringUtils.isBlank(dir)) {
            dir = ".";
        }

        String fullFile = getFullFile(dir, filename);

        response.setContentType("application/octet-stream");
        response.setHeader("Content-Disposition", "attachment; filename=" + filename);  //popup download file dialog

        String downloadUrl = String.format("http://%s:%s/logview?cmd=download&log=%s&size=%s", host, logServerPort, fullFile, BLOCK_DOWNLOAD_SIZE);
        String sizeUrl = String.format("http://%s:%s/logview?cmd=showLog&log=%s&pos=0&size=0", host, logServerPort, fullFile);

        try {
            long position = 0;
            long fileSize;
            HttpResponse httpResponse = httpGet(sizeUrl);
            if (httpResponse != null && httpResponse.getStatusLine().getStatusCode() == 200) {
                byte[] size = new byte[16];
                httpResponse.getEntity().getContent().read(size);
                fileSize = JStormUtils.parseLong(new String(size).trim(), MAX_DOWNLOAD_SIZE);
                // make sure download file size is less than max size
                if (fileSize - position > MAX_DOWNLOAD_SIZE) {
                    position = fileSize - MAX_DOWNLOAD_SIZE;
                }
            } else {
                handlFailure(response, "Bad request, can not read the file");
                return;
            }

            response.setContentLength((int) (fileSize - position));
            OutputStream os = response.getOutputStream();

            do {
                httpResponse = httpGet(downloadUrl + "&pos=" + position);
                int status = httpResponse.getStatusLine().getStatusCode();
                if (status == 200) {
                    httpResponse.getEntity().writeTo(os);
                    Header[] header = httpResponse.getHeaders("Content-Length");
                    int contentLength = JStormUtils.parseInt(header[0].getValue(), BLOCK_DOWNLOAD_SIZE);
                    position += contentLength;
                } else {
                    break;
                }
            } while (position < fileSize);

            os.flush();
            os.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private String getFullFile(String dir, String filename) {
        if (StringUtils.isBlank(dir)) {
            dir = ".";
        }
        String fullFile;
        if (StringUtils.isBlank(dir)) {
            fullFile = filename;
        } else {
            fullFile = dir + File.separator + filename;
        }
        return fullFile;
    }

    private void handlFailure(HttpServletResponse response, String errorMsg) throws IOException {
        LOG.error(errorMsg);

        byte[] data = errorMsg.getBytes();
        response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
        response.setContentLength(data.length);
        OutputStream os = response.getOutputStream();
        os.write(data);
        os.close();
    }

    private HttpResponse httpGet(String url) throws IOException {
        HttpGet get = new HttpGet(url);
        HttpClient httpclient = HttpClientBuilder.create().build();
        return httpclient.execute(get);
    }

    private long getCurrentPageIndex(Event e, long totalSize, int pageSize) {
        long currentPos = totalSize;
        if (e.pos >= 0) {
            currentPos = e.pos;
        }

        return currentPos / pageSize;
    }

    private Pagination createPage(Event e, long index, int pageSize, String text,
                                  boolean isDisable, boolean isActive) {
        long pos = index * pageSize;
        String url = String.format("log?cluster=%s&host=%s&port=%s&file=%s&pos=%s&dir=%s",
                e.clusterName, e.host, e.logServerPort, e.logName, pos, e.dir);

        Pagination page = new Pagination();
        page.url = url;
        page.text = text;
        if (isDisable) {
            page.status = "disabled";
        } else if (isActive) {
            page.status = "active";
        }
        return page;
    }

    private List<Pagination> genPageUrl(Event e, String sizeStr) {
        long totalSize = Long.valueOf(sizeStr);
        int pageSize = e.logPageSize;

        long pageNum = (totalSize + pageSize - 1) / pageSize;
        long currentPageIndex = getCurrentPageIndex(e, totalSize, pageSize);

        List<Pagination> pages = new ArrayList<>();
        if (pageNum <= 10) {
            for (long i = pageNum - 1; i >= 0; i--) {
                pages.add(createPage(e, i, pageSize, String.valueOf(i + 1), false, i == currentPageIndex));
            }
            return pages;
        }

        if (pageNum - currentPageIndex < 5) {
            for (long i = pageNum - 1; i >= currentPageIndex; i--) {
                pages.add(createPage(e, i, pageSize, String.valueOf(i + 1), false, i == currentPageIndex));
            }
        } else {
            pages.add(createPage(e, pageNum - 1, pageSize, "End", false, pageNum - 1 == currentPageIndex));
            pages.add(createPage(e, currentPageIndex + 4, pageSize, "...", false, false));
            for (long i = currentPageIndex + 3; i >= currentPageIndex; i--) {
                pages.add(createPage(e, i, pageSize, String.valueOf(i + 1), false, i == currentPageIndex));
            }
        }

        if (currentPageIndex < 5) {
            for (long i = currentPageIndex - 1; i > 0; i--) {
                pages.add(createPage(e, i, pageSize, String.valueOf(i + 1), false, i == currentPageIndex));
            }
        } else {
            for (long i = currentPageIndex - 1; i >= currentPageIndex - 3; i--) {
                pages.add(createPage(e, i, pageSize, String.valueOf(i + 1), false, i == currentPageIndex));
            }
            pages.add(createPage(e, currentPageIndex - 4, pageSize, "...", false, false));
            pages.add(createPage(e, 0, pageSize, "Begin", false, 0 == currentPageIndex));
        }
        return pages;
    }

    private void requestLog(Event e, ModelMap model) throws IOException {
        String fullPath;
        if (e.dir == null || e.dir.equals(".")) {
            fullPath = e.logName;
        } else {
            fullPath = e.dir + File.separator + e.logName;
        }
        String summary = null;
        String log = null;
        if (fullPath.contains("/..") || fullPath.contains("../")) {
            summary = "File Path can't contains ..
";
        } else {
            Response res = UIUtils.getLog(e.host, e.logServerPort, fullPath, e.pos);

            if (res.getStatus() != -1) {
                if (res.getStatus() == 200) {
                    String sizeStr = res.getData().substring(0, 16);
                    model.addAttribute("pages", genPageUrl(e, sizeStr));
                    log = res.getData().substring(17);
                } else {
                    summary = "The log file " + e.logName + " isn't exist
 " + res.getData();
                }
            } else {
                summary = "Failed to get log file " + e.logName + "
" + res.getData();
            }
        }
        model.addAttribute("log", log);
        model.addAttribute("summary", summary);
        UIUtils.addTitleAttribute(model, "Log");
    }

    public class Event {

        public String clusterName;
        public String host;
        public int logServerPort;
        public String logName;
        public String topologyId;
        public String workerPort;
        public long pos;
        public String dir;
        public int logPageSize;
        public String logEncoding;

        public Event(String _clusterName, String _host, String _logServerPort, String _logName,
                     String _topologyId, String _workerPort, String _pos, String _dir, Map conf) {
            this.clusterName = _clusterName;
            this.host = _host;
            this.logServerPort = JStormUtils.parseInt(_logServerPort, 0);
            this.logName = _logName;
            this.topologyId = _topologyId;
            this.workerPort = _workerPort;
            this.pos = JStormUtils.parseLong(_pos, -1);
            this.dir = _dir;

            logPageSize = ConfigExtension.getLogPageSize(conf);
            logEncoding = ConfigExtension.getLogViewEncoding(conf);

            if (host == null) {
                throw new IllegalArgumentException("Please set host");
            } else if (logServerPort == 0) {
                throw new IllegalArgumentException(
                        "Please set log server's port");
            }

            if (!StringUtils.isBlank(logName)) {
                return;
            }

            if (topologyId == null || workerPort == null) {
                throw new IllegalArgumentException(
                        "Please set log fileName or topologyId-workerPort");
            }

            String topologyName;
            try {
                topologyName = Common.topologyIdToName(topologyId);
            } catch (Exception e) {
                throw new IllegalArgumentException(
                        "Please set log fileName or topologyId-workerPort");
            }
            dir = "." + File.separator + topologyName;
            logName = topologyName + "-worker-" + workerPort + ".log";
        }
    }

    public class Pagination {
        public String status;
        public String url;
        public String text;

        public Pagination(String status, String url, String text) {
            this.status = status;
            this.url = url;
            this.text = text;
        }

        public Pagination() {
        }

        public String getStatus() {
            return status;
        }

        public String getUrl() {
            return url;
        }

        public String getText() {
            return text;
        }
    }
}


text:
import { Meteor} from 'meteor/meteor';
import { Mongo } from 'meteor/mongo';
import { EJSON } from 'meteor/ejson';
import { JSONStream } from 'JSONStream';
//import { extPoly } from '../ui/gMap.js';
export const Cases = new Mongo.Collection('cases');

if (Meteor.isServer) {
    // This code only runs on the server
    // Only publish tasks that are public or belong to the current user
//    console.error("Entered isServer function");
    Meteor.publish('cases', function casesPublication(extPoly) {
//        return Cases.find({}); // find everything
        // todo: See if we can return only the visible polygons
        if (typeof extPoly !== 'undefined' && extPoly !== null) {
            console.error("Finding polygons within " + extPoly.toString());
            var result = Cases.find({
                        geometry: {
                            $geoWithin: {
                                $geometry: {
                                    type: "Polygon",
                                    coordinates: extPoly
                                }
                            }
                        }
                    });
            console.error("Found polygons:\n" + result.map(function(u) {return u._id + "\n\t"}) + "\n");
        } else {
            console.error("extPoly is null, return nothing");
            return this.ready();
//            result = Cases.find({});
//            console.error("Looked up all polygons - extPoly is null");
        }
        return result;
    });

    Meteor.startup(function () {
        "use strict";
        // code to run on server at startup
        // 1. Create a Mongo collection of properties (CASE_NUMBE's) by address from the GeoJSON file.
        // 2. Build a Mongo collection of documents for each property
        //     These are stored in https://www-static.bouldercolorado.gov/docs/PDS/Plans/<CASE_NUMBE>/ folder
        // 3. Build a Mongo collection of features for each CASE_NUMBE

        function getAssetPath() {
            var meteor_root = require('fs').realpathSync(process.cwd() + '/../');

//            console.error(meteor_root);

//            var assets_folder = __meteor_bootstrap__.serverDir + '/assets/app';

            // /meteor/containers/b98c25e5-4e38-5531-cc67-85a5a29c68dc/bundle/programs/server/boot.js:229:5

            var application_root = require('fs').realpathSync(meteor_root + '/../');
            // if running on dev mode
            if (require('path').basename(require('fs').realpathSync(meteor_root + '/../../../')) == '.meteor') {
                application_root = require('fs').realpathSync(meteor_root + '/../../../../');
                var assets_folder = meteor_root + '/server/assets/' + require('path').basename( application_root );
            }

            var assets_folder = meteor_root + '/server/assets/app';
            //var assets_folder = meteor_root + '/server/assets/' + require('path').basename( application_root );
//            console.error(assets_folder);
            return assets_folder;
        }

        // read and process

        var assetPath = getAssetPath();

        var fs = require('fs');
        var jsonFilePath = './assets/app/DevelopmentReview.GeoJSON.json';
        var geoJsonFile = fs.readFileSync(jsonFilePath, 'utf-8');
        var geoJson = JSON.parse(geoJsonFile)

        // require will read in and parse only if extension is ".json"

        //geoJson = Assets.getText('DevelopmentReview.GeoJSON.json');

        // geoJson = Assets.getText('public/DevelopmentReview.GeoJSON.json');
        // geoJson = require(assetPath + '/DevelopmentReview.GeoJSON.json');

            var caseNum = "";
            console.log("oooooo", geoJson);
            console.error(geoJson.features.length);
            for (var caseInd in geoJson.features) {
                var devCase = geoJson.features[caseInd];
                caseNum = devCase.properties['CASE_NUMBE'];
                    if(Cases.findOne({'_id': caseNum}) == null) {
                        devCase['_id'] = caseNum;
                        devCase['id'] = caseNum;
                        Cases.insert(devCase);
                    };
            }
        Cases._ensureIndex({'loc.coordinates':'2dsphere'});
    });
}


text:
<?php

namespace Loco\Utils\Swizzle;

use GuzzleHttp\Command\Guzzle\Description;
use GuzzleHttp\Command\Guzzle\Operation;
use GuzzleHttp\Command\Guzzle\Parameter;
use Monolog\Handler\StreamHandler;
use Monolog\Logger;

/**
 * Models Swagger API declarations and converts to Guzzle service descriptions.
 */
class Swizzle
{

    /**
     * Monolog logger for debug output
     * @var Logger
     */
    private $logger;

    /**
     * Expected swagger spec version
     * @var string
     */
    const SWAGGER_VERSION = '1.2';

    /**
     * Initial parameters to pass to ServiceDescription constructor
     * @var array
     */
    private $init;

    /**
     * @var Description
     */
    private $serviceDescription;

    /**
     * Default response serialization type
     * @var string xml|json
     */
    private $responseType = 'json';

    /**
     * Default request body serialization type
     * @var string xml|json
     */
    private $requestType = 'json';

    /**
     * Registry of custom response classes, mapped by method command name
     * @var array
     */
    private $responseClasses = [];

    /**
     * Delay between HTTP requests in microseconds
     * @var int
     */
    private $delay = 200000;

    /**
     * @var array[]
     */
    private $models = [];

    /**
     * @var true[]
     */
    private $exposedModels = [];

    /**
     * @var Operation[]
     */
    private $operations = [];

    /**
     * Construct with minimum mandatory parameters
     *
     * @param string $name Name of the API
     * @param string $description Summary of the API
     * @param string $apiVersion API version
     *
     * @throws \Exception
     */
    public function __construct($name, $description = null, $apiVersion = null)
    {
        $this->init = compact('name', 'description', 'apiVersion');
        $this->logger = new Logger('swizzle');
        // if we don't add a handler we get debug messages by default.
        $this->logger->pushHandler(new StreamHandler('php://stderr', Logger::ERROR));
    }

    /**
     * Reset generated models, operations and current service Description
     */
    public function reset()
    {
        $this->models = [];
        $this->operations = [];
        $this->serviceDescription = null;
    }

    /**
     * Enable debug logging to show build progress
     *
     * @param string|resource
     *
     * @return Swizzle
     *
     * @throws \Exception
     */
    public function verbose($resource)
    {
        $this->logger->pushHandler(new StreamHandler($resource, Logger::DEBUG));
        return $this;
    }

    /**
     * @internal Log debug events in verbose mode
     *
     * @param string $message
     */
    private function debug($message)
    {
        if (1 < func_num_args()) {
            $message = call_user_func_array('sprintf', func_get_args());
        }
        $this->logger->addDebug($message);
    }

    /**
     * Set delay between HTTP requests
     *
     * @param int delay in microseconds
     *
     * @return Swizzle
     */
    public function setDelay($microseconds)
    {
        $this->delay = (int)$microseconds;
        return $this;
    }

    /**
     * Set an initial value to be passed to ServiceDescription constructor.
     *
     * @param string $key
     * @param mixed $value
     *
     * @return Swizzle
     *
     * @throws \RuntimeException
     */
    private function setInitValue($key, $value)
    {
        if ($this->serviceDescription !== null) {
            throw new \RuntimeException('Too late to set "'.$key.'"');
        }
        $this->init[$key] = $value;

        return $this;
    }

    /**
     * Set base URL
     *
     * @param string base url common to all api calls
     *
     * @return string
     *
     * @throws \RuntimeException
     */
    public function setBaseUri($baseUri)
    {
        return $this->setInitValue('baseUri', $baseUri);
    }

    /**
     * Set API version string
     *
     * @param string api version
     *
     * @return Swizzle
     *
     * @throws \RuntimeException
     */
    public function setApiVersion($apiVersion)
    {
        return $this->setInitValue('apiVersion', $apiVersion);
    }

    /**
     * Get compiled Guzzle service description
     *
     * @return Description
     *
     * @throws \InvalidArgumentException
     */
    public function getServiceDescription()
    {
        if ($this->serviceDescription === null) {
            $this->serviceDescription = new Description($this->init);
        }
        return $this->serviceDescription;
    }

    /**
     * Apply a bespoke responseClass to a given method
     *
     * @param string name of command returning this response class
     * @param string full class name for responseClass field
     *
     * @return Swizzle
     *
     * @throws \LogicException
     * @throws \InvalidArgumentException
     */
    public function registerResponseClass($name, $class)
    {
        $this->responseClasses[$name] = $class;
        // set retrospectively if method already encountered
        if ($this->serviceDescription !== null
            && $this->hasOperation($name) === true
        ) {
            throw new \LogicException(
                "Too late to add new response class, {$name} operation has already been defined. "
                .'If you want to add a new response class, call reset() method first, add new response class '
                .'and run build again.'
            );
        }
        return $this;
    }

    /**
     * Fetch the responseClass returned for a given method.
     * Clients may default to a generic class like `GuzzleHttp\Command\Result` when empty
     *
     * @param string name of command
     *
     * @return string
     */
    public function getResponseClass($name)
    {
        return isset($this->responseClasses[$name]) ? $this->responseClasses[$name] : '';
    }

    /**
     * Build from a live endpoint
     *
     * @param string Swagger compliant JSON endpoint for resource listing
     *
     * @throws \Exception
     * @return Swizzle
     */
    public function build($baseUri)
    {
        $this->serviceDescription = null;
        $client = SwaggerClient::factory(['base_uri' => $baseUri]);
        $this->debug('Fetching resource listing from %s', $baseUri);
        $listing = $client->getResources();

        // check this looks like a resource listing
        if (!$listing->isSwagger()) {
            throw new \RuntimeException("This doesn't look like a Swagger spec");
        }
        if (!$listing->getApis()) {
            $this->logger->addAlert("Resource listing doesn't define any APIs");
        }
        // check swagger version
        if (self::SWAGGER_VERSION !== $listing->getSwaggerVersion()) {
            throw new \RuntimeException('Unsupported Swagger version, Swizzle expects '.self::SWAGGER_VERSION);
        }
        // Declared version overrides anything we've set
        if ($version = $listing->getApiVersion()) {
            $this->debug('+ set apiVersion %s', $version);
            $this->setApiVersion($version);
        }
        // Set description if missing from constructor
        if (empty($this->init['description'])) {
            $info = $listing->getInfo();
            $this->init['description'] = $info['description'] ?: $this->init['title'];
        }
        // set base path from docs location if not provided
        if (empty($this->init['baseUri'])) {
            $this->init['baseUri'] = self::mergeUrl('/', $baseUri);
        }
        // no more configs allowed now, Guzzle service gets constructed
        $service = $this->getServiceDescription();
        // ready to pull each api declaration
        foreach ($listing->getApiPaths() as $path) {
            if ($this->delay) {
                usleep($this->delay);
            }
            // TODO proper path resolution allowing a cross-domain spec.
            $path = rtrim(parse_url($baseUri)['path'], '/').'/'.ltrim($path, '/');
            $this->debug('pulling %s ...', $path);
            $apiDeclaration = $client->getDeclaration(compact('path'));
            // Models must be registered before processing operations that use them
            foreach ($apiDeclaration->getModels() as $model) {
                $this->addModel($model);
            }
            // Ensure a fully qualified base url for this api
            $baseUrl = self::mergeUrl($apiDeclaration->getBasePath(), $service->getBaseUri());
            // add each api against required base url
            foreach ($apiDeclaration->getApis() as $api) {
                $this->addApi($api, $baseUrl);
            }
        }
        $this->debug('finished');
        return $this;
    }

    /**
     * Create a Swagger model definition
     *
     * @param array $model
     * @param string location where parameters will be found in request or response
     *
     * @return Parameter model resolved against service description but not added
     *
     * @throws \Exception
     */
    private function createModel(array $model, $location)
    {
        $name = null;
        if (isset($model['id']) === true) {
            // if model id is set, us it as a name
            $name = trim($model['id']);
        } elseif (isset($model['type']) === true && $model['type'] === 'array') {
            // if model is of array type
            if (isset($model['items']['$ref']) === true) {
                // E. g. if it's an array of 'Tag' models, call this model 'TagList'.
                $name = $model['items']['$ref'].'List';
            } elseif (isset($model['nickname']) === true) {
                // Fallback generate name from operation nickname (e.g. getTags -> TagList)
                $found = preg_match('/[A-Z]/', $model['nickname'], $matches, PREG_OFFSET_CAPTURE);
                if ($found === 1) {
                    $name = rtrim(substr($model['nickname'], $matches[0][1]), 's').'List';
                }
            }
        } elseif (isset($model['nickname']) === true) {
            $name = $model['nickname'];
        }

        // if none of above worked to create a model name, hash model array
        if ($name === null) {
            $name = $model['id'] = 'anon_'.self::hashArray($model);
        }

        //

        // a model is basically a parameter, but has name property added
        $defaults = [
            'name' => $name,
            'type' => 'object',
        ];
        /** @noinspection AdditionOperationOnArraysInspection */
        $data = $this->transformSchema($model + $defaults);
        if ('object' === $data['type']) {
            $data['additionalProperties'] = false;
            // an object that defines properties is expected to be immutable
            if (isset($data['properties']) && 0 !== count($data['properties'])) {
                // model must have top level properties specified as serialized response type, but no response type itself
                foreach ($data['properties'] as $key => $property) {
                    $data['properties'][$key]['location'] = $location;
                }
            }
            // else vanilla "object" type if thus named will have dynamic properties
            elseif ('object' ===  $name) {
                $data['additionalProperties'] = ['location'=>$this->responseType];
            }
            // else no point having a completely empty model
            else {
                $this->debug('! object model '.$name.' has empty properties');
                $data['properties'] = [];
            }
        } elseif ('array' === $data['type']) {
            $data['location'] = $location;
        }

        // result class override has moved to operation loop
        if (isset($this->responseClasses[$name])) {
            throw new \Exception('Response classes should be handled only at top-level of an operation');
        }

        // required makes no sense at root of model
        unset($data['required']);

        return new Parameter($data, ['description' => $this->getServiceDescription()]);
    }

    /**
     * Add a response model
     *
     * @param array model structure from Swagger
     *
     * @return Parameter model added to service description
     *
     * @throws \Exception
     */
    public function addModel(array $modelData)
    {
        // swagger only has locations for requests, so we can safely default to our response serializer.
        $model = $this->createModel($modelData, $this->responseType);
        $modelData = $model->toArray();
        if ($modelData['type'] === 'array' && isset($modelData['name'])) {
            unset($modelData['name']);
        }
        $name = $model->getName();
        if (! isset($this->models[$name])) {
            $this->debug('+ adding model %s', $name);
            $this->models[$name] = $modelData;
        }
        return $model;
    }

    /**
     * @param string $name
     */
    private function exposeModel($name)
    {
        if ($this->hasModel($name) && ! isset($this->exposedModels[$name])) {
            // $this->debug('~ model %s will be exposed', $name);
            $this->exposedModels[$name] = 1;
        }
    }

    /**
     * Add a Swagger Api declaration which may consist of multiple operations
     *
     * @param array $api consisting of path, description and array of operations
     * @param string $baseUri URL inferring the base location for api path
     *
     * @return Swizzle
     *
     * @throws \Exception
     */
    public function addApi(array $api, $baseUri = null)
    {
        $service = $this->getServiceDescription();
        if ($baseUri === null) {
            $baseUri = $service->getBaseUri()->__toString();
        }
        // resolve URL relative to base path for all operations
        $uri = implode('/', [rtrim($baseUri, '/'), ltrim($api['path'], '/')]);
        // keep domain only if not under service base path
        if ($baseUri !== '' && strpos($uri, $baseUri) === 0) {
            $uri = preg_replace('!^https?://[^/]+!', '', $uri);
        }
        $this->debug('+ adding api %s ...', $uri);

        // no need for full url if relative to current
        // operation keys common to both swagger and guzzle
        static $common = [
            'summary' => 1,
        ];
        // translate swagger -> guzzle
        static $trans = [
            'type' => 'responseType',
            'notes' => 'responseNotes',
            'method' => 'httpMethod',
        ];
        static $defaults = [
            'httpMethod' => 'GET',
        ];
        /** @var array[][] $api */
        foreach ($api['operations'] as $operationData) {
            /** @noinspection AdditionOperationOnArraysInspection */
            $config = $this->transformArray($operationData, $common, $trans) + $defaults;
            $config['uri'] = $uri;
            // command must have a name, and must be unique across methods
            if (isset($operationData['nickname'])) {
                $id = $config['name'] = $operationData['nickname'];
            } // generate naff nickname if not specified
            else {
                $method = strtolower($config['httpMethod']);
                $id = $config['name'] = $method.'_'.str_replace('/', '_', trim($uri, '/'));
            }

            // handle response type if defined
            if (isset($config['responseType'])) {
                $responseType = $config['responseType'];
                $simpleType = $this->transformSimpleType($responseType);
                unset($config['responseType']);
                // Custom response classes override all and are registered by nickname of operation
                if (isset($this->responseClasses[$id])) {
                    $class = $this->responseClasses[$id];
                    // use naked class name unless another conflicting model exists.
                    $ns = explode('\\', $class);
                    $name = end($ns);
                    if (isset($this->models[$name]) && $this->models[$name]['class'] !== $class) {
                        $name = md5($class);
                        $this->debug('! class name conflict on %s, hashing to %s', $class, $name);
                    }
                    if (!isset($this->models[$name])) {
                        $this->debug('+ adding custom response type %s', $name);
                        $this->models[$name] = ['name' => $name, 'type' => 'class', 'class' => $class, 'description' => 'Custom response class'];
                    }
                    $responseModel = $name;
                // Response may be a registered model
                } elseif ($this->hasModel($responseType)) {
                    $responseModel = $responseType;
                // Response may be a primitive type, like "string" but still required representing by a model
                // This may also be a "array" in which case items->$ref will be resolved to a registered model
                } elseif ($simpleType && $simpleType !== 'null') {
                    $responseModel = $this->addModel($operationData)->getName();
                // else model was not registered via api declaration which occurs before operations added
                } else {
                    throw new \RuntimeException(
                        "Response model {$responseType} required by operation {$id} is not registered."
                    );
                }
                // mark model as being required in export so Guzzle can resolve $ref
                $config['responseModel'] = $responseModel;
                $this->exposeModel($responseModel);
            }

            // handle parameters
            if (isset($operationData['parameters'])) {
                $config['parameters'] = $this->transformParams($operationData['parameters']);
            } else {
                $config['parameters'] = [];
            }

            // handle responseMessages -> errorResponses
            if (isset($operationData['responseMessages'])) {
                $config['errorResponses'] = $this->transformResponseMessages($operationData['responseMessages']);
            } else {
                $config['errorResponses'] = [];
            }

            // @todo how to deny additional parameters in command calls?
            // $config['additionalParameters'] = false;
            // models can't be set on service description except on construction, but they are required to validate $ref fields
            $service = new Description(['models'=>$this->models]);
            $operation = new Operation($config, $service);
            $this->operations[$operation->getName()] = $operation->toArray();
        }
        return $this;
    }

    /**
     * Transform a swagger parameter to a Guzzle one
     *
     * @param array $params
     *
     * @return array
     * @throws \Exception
     */
    private function transformParams(array $params)
    {
        $locations = [];
        $namespace = [];
        foreach ($params as $name => $param) {
            if (isset($param['name'])) {
                $name = $param['name'];
            } else {
                $param['name'] = $name;
            }
            $param = $this->transformSchema($param);
            $location = isset($param['location']) ? $param['location'] : '';
            // resolve parameter of a model type
            if (isset($param['$ref'])) {
                $ref = $param['$ref'];
                if (! $this->hasModel($ref)) {
                    throw new \RuntimeException('Referenced '.$ref.' in parameter but model not registered');
                }
                // guzzle can resolve the $ref, but not when its properties are the root of the body
                if ('body' === $location) {
                    $param += $this->models[$ref];
                    unset($param['$ref']);
                }
                // else model must exposed to be resolvable
                else {
                    $this->exposeModel($ref);
                }
            }
            // handle paramType -> location mapping.
            if ($location) {
                $location = $param['location'] = $this->transformLocation($location);
                // swagger doesn't allow optional path params
                if (!isset($param['required'])) {
                    $param['required'] = 'uri' === $location;
                }
            }
            // handle serialization in request body.
            if ('body' === $location) {
                $location = $this->requestType;
                // object properties must be moved into parent namespace or Guzzle will wrap them.
                // ie. if the root of the body is {"foo":"bar"} we have a body property called "foo".
                if (isset($param['properties'])) {
                    foreach ($param['properties'] as $propertyName => $property) {
                        $property['location'] = $location;
                        $locations[$location][$propertyName] = $property;
                        $namespace[$propertyName][$location] = 1;
                    }
                    continue;
                }
            }
            // else add single parameter by name
            $locations[$location][$name] = $param;
            $namespace[$name][$location] = 1;
        }
        // resolve all locations to single namespace
        // conflict can occur due to differences in swagger/guzzle modelling of complex params
        $target = [];
        /**
         * @var string $location
         * @var array[] $parameters
         */
        foreach ($locations as $location => $parameters) {
            foreach ($parameters as $name => $param) {
                unset($namespace[$name][$location]);
                if ($conflicts = array_keys($namespace[$name])) {
                    $alias = $name.'_'.$location;
                    $this->debug('! %s parameter "%s" conflicts with %s, address as "%s"', $location, $name, implode(' and ', $conflicts), $alias);
                    // namespace this property at our end ensuring it's sent to the API as expected.
                    $param['sentAs'] = $name;
                    $name = $param['name'] = $alias;
                }
                // add to namespace with unique key
                $target[$name] = $param;
            }
        }
        return $target;
    }

    /**
     * Transform a Swagger request paramType to a Guzzle location.
     * Note that Guzzle has response locations too.
     *
     * @param string Swagger paramType request field (path|query|body|header|form)
     *
     * @return string Guzzle location field (uri|query|body|header|postField|xml|json)
     */
    private function transformLocation($paramType)
    {
        // Guzzle request locations: (statusCode|reasonPhrase|header|body|json|xml)
        // Guzzle response locations: (uri|query|header|body|formParam|multipart|json|xml|responseBody)
        static $valid = [
            'uri' => 1,
            'xml' => 1,
            'json' => 1,
            'body' => 1,
            'query' => 1,
            'header' => 1,
            'formParam' => 1,
        ];
        // may be already transformed and just passing through
        if (isset($valid[$paramType])) {
            return $paramType;
        }
        static $aliases = [
            'path' => 'uri',
            'body' => 'body',
            'form' => 'formParam',
            'query' => 'query',
            'header' => 'header',
        ];
        // return alias, defaulting to empty
        return isset($aliases[$paramType]) ? $aliases[$paramType] : '';
    }

    /**
     * Transform an object holding a Swagger data type into a Guzzle one
     *
     * @param array Swagger schema
     *
     * @return array Guzzle schema
     *
     * @throws \Exception
     */
    private function transformSchema(array $source)
    {
        $name = isset($source['name']) ? $source['name'] : 'anon';
        // keys common to both swagger and guzzle
        static $common = [
            '$ref' => 1,
            'type' => 1,
            'name' => 1,
            'enum' => 1,
            'items' => 1,
            'format' => 1,
            'minimum' => 1,
            'maximum' => 1,
            'required' => 1,
            'minLength' => 1,
            'maxLength' => 1,
            'properties' => 1,
            'description' => 1,

        ];
        // keys requiring translation
        static $trans = [
            'paramType' => 'location',
            'defaultValue' => 'default',
        ];
        // initial translation
        $target = $this->transformArray($source, $common, $trans) + ['type' => ''];

        // validate Swagger refs now. Resolve later as appropriate.
        if (isset($target['$ref'])) {
            if ($this->hasModel($target['$ref']) === false) {
                throw new \RuntimeException('Encountered $ref to "'.$target['$ref'].'" in '.$name.' but model not registered');
            }
            unset($target['type']);
            return $target;
        }

        // Validate data type
        $type = null;

        // handle array of types entities
        if (isset($target['items'])) {
            $type = 'array';
            if ($type !== $target['type']) {
                $this->debug('! %s %s declares items, coercing to "%s"', $target['type'] ?: 'untyped', $name, $type);
                $target['type'] = $type;
            }
            // resolve model reference ensuring model exists
            if (isset($target['items']['$ref'])) {
                $ref = $target['items']['$ref'];
                if ($this->hasModel($ref) === false) {
                    throw new \RuntimeException('"'.$ref.'" encountered as items $ref but not defined as a model');
                }
            }
            // Else define a literal model definition on the fly.
            // Guzzle will resolve back to literals on output, but it helps us resolve typed arrays and such
            else {
                if (isset($target['items']['type']) && $this->transformSimpleType($target['items']['type']) !== null) {
                    $target['items'] = $this->transformSchema($target['items']);
                } else {
                    $model = $this->addModel($target['items']);
                    $target['items'] = [
                        '$ref' => $model->getName(),
                    ];
                }
            }
            // expose items/$ref
            if (isset($target['items']['$ref'])) {
                $this->exposeModel($target['items']['$ref']);
            }
        }

        // Recurse into object properties
        if (isset($source['properties'])) {
            $type = 'object';
            if ($type !== $target['type']) {
                $this->debug('! %s %s declares properties, coercing to "%s"', $target['type'] ?: 'untyped', $name, $type);
                $target['type'] = $type;
            }
            $target['properties'] = $this->transformParams($source['properties']);
            // required params are an external array in Swagger, but applied individually as boolean in Guzzle
            if (isset($source['required']) && is_array($source['required'])) {
                foreach ($source['required'] as $prop) {
                    if (isset($target['properties'][$prop])) {
                        $target['properties'][$prop]['required'] = true;
                    }
                }
            }
        }

        if ($type === null) {
            $originalType = $target['type'];
            if ($originalType && $this->hasModel($originalType)) {
                // param type is registered model
                $target['$ref'] = $originalType;
                unset($target['type']);
                return $target;
            }
            // else handle as primitive type
            $frmt = isset($target['format']) ? $target['format'] : null;
            $type = $this->transformSimpleType($originalType, $frmt);
            // else fall back to a sensible default
            if (!$type) {
                $this->debug('! type "%s" unknown, defaulting to null', $originalType);
                $type = 'null';
            }
            $target['type'] = $type;
        }

        // Guzzle and swagger have minimal format overlap
        if (isset($target['format'])) {
            $target['format'] = $this->transformTypeFormat($target['format']);
        }

        return $target;
    }

    /**
     * Transform Swagger simple type to valid JSON Schema type. (which it should be anyway).
     *
     * @see http://tools.ietf.org/id/draft-zyp-json-schema-04.html#rfc.section.3.5
     *
     * @param string type specified in swagger field
     * @param string $format optional format specified in format field
     *
     * @return string|null One of: array, boolean, integer, number, null, object, string
     * or NULL if unable to match type.
     */
    private function transformSimpleType($type, $format = null)
    {
        static $aliases = [
            '' => 'null',
            'null' => 'null',
            'void' => 'null',
            'number' => 'number',
            'numeric' => 'number',
            'float' => 'number',
            'double' => 'number',
            'int' => 'integer',
            'int32' => 'integer',
            'int64' => 'integer',
            'integer' => 'integer',
            'bool' => 'boolean',
            'boolean' => 'boolean',
            'array' => 'array',
            'object' => 'object',
            'string' => 'string',
            'byte' => 'string',
            'date' => 'string',
            'date-time' => 'string',
        ];

        $type = isset($aliases[$type]) ? $aliases[$type] : null;
        if ($type === null && $format !== null) {
            $type = isset($aliases[$format]) ? $aliases[$format] : null;
        }

        return $type;
    }

    /**
     * Transform Swagger's datatype format hinting to Guzzle's
     *
     * @param string Swagger's format field
     *
     * @return string one of "date-time", "date" or ""
     */
    private function transformTypeFormat($format)
    {
        static $aliases = [
            'date' => 'date',
            'date-time' => 'date-time',
        ];
        // Guzzle supports also time, timestamp, date-time-http but Swagger has no equivalent
        return isset($aliases[$format]) ? $aliases[$format] : '';
    }

    /**
     * Transform Swagger responseMessages to Guzzle errorResponses.
     * @todo support registration of 'class' property?
     *
     * @param array containing code and message
     *
     * @return array containing code and phrase
     */
    private function transformResponseMessages(array $responseMessages)
    {
        static $common = [
            'code' => 1,
        ],
        $trans = [
            'message' => 'phrase',
        ];
        $errorResponses = [];
        foreach ($responseMessages as $message) {
            $errorResponses[] = $this->transformArray($message, $common, $trans);
        }
        return $errorResponses;
    }

    /**
     * Utility transform an array based on similarities and differences between the two formats.
     *
     * @param array $swagger source format (swagger)
     * @param array $common Keys common to both formats, { key: '', ... }
     * @param array $trans key translation mappings, { keya: keyb, ... }
     *
     * @return array target format (guzzle)
     */
    private function transformArray(array $swagger, array $common, array $trans)
    {
        // initialize with common array keys
        $guzzle = array_intersect_key($swagger, $common);
        // translate other naming differences
        foreach ($trans as $source => $target) {
            if (isset($swagger[$source])) {
                $guzzle[$target] = $swagger[$source];
            }
        }

        return $guzzle;
    }

    /**
     * Utility, hashes an array into something human readable if less than 32 chars.
     * Example: Use for creating anonymous model names, such as type_string
     *
     * @param array $arr
     * @param array $words
     * @param bool $recursion
     *
     * @return array|string
     */
    private static function hashArray(array $arr, array $words = [], $recursion = false)
    {
        foreach ($arr as $key => $val) {
            $words[] = $key;
            if (is_array($val)) {
                $words = self::hashArray($val, $words, true);
            } else {
                $words[] = (string)$val;
            }
        }
        if ($recursion) {
            return $words;
        }
        $hash = implode('_', $words);
        if (isset($hash{32})) {
            return md5($hash);
        }
        return $hash;
    }

    /**
     * Utility for merging any URI into a fully qualified one
     *
     * @param string URI that may be a /path or http://address
     * @param string full base URL that may or may not be on same domain
     *
     * @return string
     */
    private static function mergeUrl($uri, $baseUrl)
    {
        $href = parse_url($uri);
        $base = parse_url($baseUrl);
        $full = $href + $base + parse_url('http://localhost/');
        return $full['scheme'].'://'.$full['host'].$full['path'];
    }

    /**
     * Export service description to JSON
     *
     * @return string
     */
    public function toJson()
    {
        return json_encode($this->toArray(), JSON_PRETTY_PRINT);
    }

    /**
     * Export service description to JSON
     *
     * @return array
     */
    public function toArray()
    {
        $result = [
            'name' => $this->init['name'],
            'apiVersion' => $this->init['apiVersion'],
            'baseUri' => isset($this->init['baseUri']) ? $this->init['baseUri'] : '',
            'description' => $this->init['description'],
        ];
        $result['operations'] = $this->operations;
        if (!empty($this->exposedModels)) {
            $result['models'] = array_intersect_key($this->models, $this->exposedModels);
        }

        return array_filter($result);
    }

    /**
     * Check if the service description has a model by name.
     *
     * @param string $id Name/ID of the model to check
     *
     * @return bool
     */
    public function hasModel($id)
    {
        return isset($this->models[$id]);
    }

    /**
     * Check if the service description has an operation by name.
     *
     * @param string $id Name/ID of the operation to check
     *
     * @return bool
     */
    public function hasOperation($id)
    {
        return isset($this->operations[$id]);
    }
}