text:
class AddUserToSamples < ActiveRecord::Migration
  def change
    add_reference :samples, :user, index: true
    add_foreign_key :samples, :users
  end
end


text:
"""Train model to predict lightning using scikit-learn.

Copyright Google Inc.
2018 Licensed under the Apache License, Version 2.0 (the "License"); you may
not use this file except in compliance with the License. You may obtain a copy
of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required
by applicable law or agreed to in writing, software distributed under the
License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS
OF ANY KIND, either express or implied. See the License for the specific
language governing permissions and limitations under the License.
"""
from __future__ import division
from __future__ import print_function
import argparse
import copy
import datetime
import logging
import os
import subprocess
import hypertune
import numpy as np
import pandas as pd
from sklearn.ensemble import RandomForestClassifier
from sklearn.externals import joblib
import tensorflow as tf
from tensorflow.python.lib.io import file_io

def read_csv_file(filename):
  """reads CSV file into a Pandas dataframe.

  Args:
    filename (str): Name of CSV file, can be gs:// URLs also

  Returns:
    Pandas dataframe
  """
  with file_io.FileIO(filename, 'r') as f:
    logging.info('Reading %s', filename)
    df = pd.read_csv(
        f,
        header=None,
        names=[
            'cx', 'cy', 'lat', 'lon', 'mean_ref_sm', 'max_ref_sm',
            'mean_ref_big', 'max_ref_big', 'ltg_sm', 'ltg_big', 'has_ltg'
        ])
    df['has_ltg'] = df['has_ltg'].astype(float)
    return df

def read_csv_files(filename_pattern):
  """reads CSV files specified by a pattern into a Pandas dataframe.

  Args:
    filename_pattern (str): Wildcard of CSV files, can be gs:// URLs also

  Returns:
    Pandas dataframe
  """
  filenames = tf.gfile.Glob(filename_pattern)
  dataframes = [read_csv_file(filename) for filename in filenames]
  df = pd.concat(dataframes)
  logging.info('Read in %d examples from %d files matching %s', len(df),
               len(filenames), filename_pattern)
  return df

def input_fn(indf):
  df = copy.deepcopy(indf)
  # features, label
  label = df['has_ltg']
  del df['has_ltg']
  features = df # pd.get_dummies(df)
  return features, label

def train_and_evaluate(params, max_depth=5, n_estimators=100):
  """Main train and evaluate loop.

  Args:
    params (dict): Command-line parameters passed in
    max_depth (int): Maximum depth of a tree in random forest
    n_estimators (int): Number of trees in random forest
  Returns:
    estimator, rmse
  """
  # train
  train_df = read_csv_files(params['train_data'])
  train_x, train_y = input_fn(train_df)
  model = RandomForestClassifier(
      max_depth=max_depth, n_estimators=n_estimators, random_state=0)
  model.fit(train_x, train_y)

  # evaluate
  eval_df = read_csv_files(params['eval_data'])
  eval_x, eval_y = input_fn(eval_df)
  eval_pred = model.predict(eval_x)
  rmserr = np.sqrt(np.mean((eval_pred - eval_y) * (eval_pred - eval_y)))
  logging.info('Eval rmse=%f', rmserr)
  return model, rmserr

def save_model(model_tosave, gcspath, name):  # pylint: disable=unused-argument
  filename = 'model.joblib'
  joblib.dump(model_tosave, filename)
  model_path = os.path.join(
      gcspath,
      datetime.datetime.now().strftime('export_%Y%m%d_%H%M%S'), filename)
  subprocess.check_call(['gsutil', 'cp', filename, model_path])
  return model_path

if __name__ == '__main__':
  parser = argparse.ArgumentParser(
      description='Train scikit-learn model for lightning prediction')
  parser.add_argument(
      '--job-dir', required=True, help='output dir. could be local or on GCS')
  parser.add_argument(
      '--train_data',
      required=True,
      help='Pattern for training data files. could be local or on GCS')
  parser.add_argument(
      '--eval_data',
      required=True,
      help='Pattern for evaluation data files. could be local or on GCS')

  logging.basicConfig(level=getattr(logging, 'INFO', None))
  options = parser.parse_args().__dict__

  # train
  estimator, rmse = train_and_evaluate(options)
  loc = save_model(estimator, options['job_dir'], 'lightning_skl')

  # for hyperparameter tuning
  hpt = hypertune.HyperTune()
  hpt.report_hyperparameter_tuning_metric(
      hyperparameter_metric_tag='rmse', metric_value=rmse, global_step=0)

redpajama_set_name: RedPajamaGithub


text:
from paste.auth.digest import *
from paste.wsgilib import raw_interactive
from paste.httpexceptions import *
from paste.httpheaders import AUTHORIZATION, WWW_AUTHENTICATE, REMOTE_USER
import os
import six

def application(environ, start_response):
    content = REMOTE_USER(environ)
    start_response("200 OK",(('Content-Type', 'text/plain'),
                             ('Content-Length', len(content))))

    if six.PY3:
        content = content.encode('utf8')
    return [content]

realm = "tag:clarkevans.com,2005:testing"

def backwords(environ, realm, username):
    """ dummy password hash, where user password is just reverse """
    password = list(username)
    password.reverse()
    password = "".join(password)
    return digest_password(realm, username, password)

application = AuthDigestHandler(application,realm,backwords)
application = HTTPExceptionHandler(application)

def check(username, password, path="/"):
    """ perform two-stage authentication to verify login """
    (status,headers,content,errors) = \
        raw_interactive(application,path, accept='text/html')
    assert status.startswith("401")
    challenge = WWW_AUTHENTICATE(headers)
    response = AUTHORIZATION(username=username, password=password,
                             challenge=challenge, path=path)
    assert "Digest" in response and username in response
    (status,headers,content,errors) = \
        raw_interactive(application,path,
                        HTTP_AUTHORIZATION=response)
    if status.startswith("200"):
        return content
    if status.startswith("401"):
        return None
    assert False, "Unexpected Status: %s" % status

def test_digest():
    assert b'bing' == check("bing","gnib")
    assert check("bing","bad") is None

#
# The following code uses sockets to test the functionality,
# to enable use:
#
# $ TEST_SOCKET py.test
#

if os.environ.get("TEST_SOCKET",""):
    from six.moves.urllib.error import HTTPError
    from six.moves.urllib.request import build_opener, HTTPDigestAuthHandler
    from paste.debug.testserver import serve
    server = serve(application)

    def authfetch(username,password,path="/",realm=realm):
        server.accept(2)
        import socket
        socket.setdefaulttimeout(5)
        uri = ("http://%s:%s" % server.server_address) + path
        auth = HTTPDigestAuthHandler()
        auth.add_password(realm,uri,username,password)
        opener = build_opener(auth)
        result = opener.open(uri)
        return result.read()

    def test_success():
        assert "bing" == authfetch('bing','gnib')

    def test_failure():
        # urllib tries 5 more times before it gives up
        server.accept(5)
        try:
            authfetch('bing','wrong')
            assert False, "this should raise an exception"
        except HTTPError as e:
            assert e.code == 401

    def test_shutdown():
        server.stop()


text:
//===--- Expr.cpp - Swift Language Expression ASTs ------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
//
//  This file implements the Expr class and subclasses.
//
//===----------------------------------------------------------------------===//

#include "swift/AST/Expr.h"
#include "swift/Basic/Unicode.h"
#include "swift/AST/ASTVisitor.h"
#include "swift/AST/Decl.h" // FIXME: Bad dependency
#include "swift/AST/Stmt.h"
#include "swift/AST/AST.h"
#include "swift/AST/ASTWalker.h"
#include "swift/AST/AvailabilitySpec.h"
#include "swift/AST/PrettyStackTrace.h"
#include "swift/AST/TypeLoc.h"
#include "llvm/ADT/APFloat.h"
#include "llvm/ADT/PointerUnion.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/Twine.h"
using namespace swift;

//===----------------------------------------------------------------------===//
// Expr methods.
//===----------------------------------------------------------------------===//

// Only allow allocation of Stmts using the allocator in ASTContext.
void *Expr::operator new(size_t Bytes, ASTContext &C,
                         unsigned Alignment) {
  return C.Allocate(Bytes, Alignment);
}

StringRef Expr::getKindName(ExprKind K) {
  switch (K) {
#define EXPR(Id, Parent) case ExprKind::Id: return #Id;
#include "swift/AST/ExprNodes.def"
  }
  llvm_unreachable("bad ExprKind");
}

template <class T> static SourceLoc getStartLocImpl(const T *E);
template <class T> static SourceLoc getEndLocImpl(const T *E);
template <class T> static SourceLoc getLocImpl(const T *E);

// Helper functions to check statically whether a method has been
// overridden from its implementation in Expr.  The sort of thing you
// need when you're avoiding v-tables.
namespace {
  template <typename ReturnType, typename Class>
  constexpr bool isOverriddenFromExpr(ReturnType (Class::*)() const) {
    return true;
  }
  template <typename ReturnType>
  constexpr bool isOverriddenFromExpr(ReturnType (Expr::*)() const) {
    return false;
  }

  template <bool IsOverridden> struct Dispatch;

  /// Dispatch down to a concrete override.
  template <> struct Dispatch<true> {
    template <class T> static SourceLoc getStartLoc(const T *E) {
      return E->getStartLoc();
    }
    template <class T> static SourceLoc getEndLoc(const T *E) {
      return E->getEndLoc();
    }
    template <class T> static SourceLoc getLoc(const T *E) {
      return E->getLoc();
    }
    template <class T> static SourceRange getSourceRange(const T *E) {
      return E->getSourceRange();
    }
  };

  /// Default implementations for when a method isn't overridden.
  template <> struct Dispatch<false> {
    template <class T> static SourceLoc getStartLoc(const T *E) {
      return E->getSourceRange().Start;
    }
    template <class T> static SourceLoc getEndLoc(const T *E) {
      return E->getSourceRange().End;
    }
    template <class T> static SourceLoc getLoc(const T *E) {
      return getStartLocImpl(E);
    }
    template <class T> static SourceRange getSourceRange(const T *E) {
      return { E->getStartLoc(), E->getEndLoc() };
    }
  };
}

template <class T> static SourceRange getSourceRangeImpl(const T *E) {
  static_assert(isOverriddenFromExpr(&T::getSourceRange) ||
                (isOverriddenFromExpr(&T::getStartLoc) &&
                 isOverriddenFromExpr(&T::getEndLoc)),
                "Expr subclass must implement either getSourceRange() "
                "or getStartLoc()/getEndLoc()");
  return Dispatch<isOverriddenFromExpr(&T::getSourceRange)>::getSourceRange(E);
}

SourceRange Expr::getSourceRange() const {
  switch (getKind()) {
#define EXPR(ID, PARENT)                                           \
  case ExprKind::ID: return getSourceRangeImpl(cast<ID##Expr>(this));
#include "swift/AST/ExprNodes.def"
  }

  llvm_unreachable("expression type not handled!");
}

template <class T> static SourceLoc getStartLocImpl(const T *E) {
  return Dispatch<isOverriddenFromExpr(&T::getStartLoc)>::getStartLoc(E);
}
SourceLoc Expr::getStartLoc() const {
  switch (getKind()) {
#define EXPR(ID, PARENT)                                           \
  case ExprKind::ID: return getStartLocImpl(cast<ID##Expr>(this));
#include "swift/AST/ExprNodes.def"
  }

  llvm_unreachable("expression type not handled!");
}

template <class T> static SourceLoc getEndLocImpl(const T *E) {
  return Dispatch<isOverriddenFromExpr(&T::getEndLoc)>::getEndLoc(E);
}
SourceLoc Expr::getEndLoc() const {
  switch (getKind()) {
#define EXPR(ID, PARENT)                                           \
  case ExprKind::ID: return getEndLocImpl(cast<ID##Expr>(this));
#include "swift/AST/ExprNodes.def"
  }

  llvm_unreachable("expression type not handled!");
}

template <class T> static SourceLoc getLocImpl(const T *E) {
  return Dispatch<isOverriddenFromExpr(&T::getLoc)>::getLoc(E);
}
SourceLoc Expr::getLoc() const {
  switch (getKind()) {
#define EXPR(ID, PARENT)                                           \
  case ExprKind::ID: return getLocImpl(cast<ID##Expr>(this));
#include "swift/AST/ExprNodes.def"
  }

  llvm_unreachable("expression type not handled!");
}

Expr *Expr::getSemanticsProvidingExpr() {
  if (IdentityExpr *IE = dyn_cast<IdentityExpr>(this))
    return IE->getSubExpr()->getSemanticsProvidingExpr();

  if (TryExpr *TE = dyn_cast<TryExpr>(this))
    return TE->getSubExpr()->getSemanticsProvidingExpr();

  if (DefaultValueExpr *DE = dyn_cast<DefaultValueExpr>(this))
    return DE->getSubExpr()->getSemanticsProvidingExpr();

  return this;
}

Expr *Expr::getValueProvidingExpr() {
  Expr *E = getSemanticsProvidingExpr();

  if (auto TE = dyn_cast<ForceTryExpr>(this))
    return TE->getSubExpr()->getValueProvidingExpr();

  // TODO:
  //   - tuple literal projection, which may become interestingly idiomatic

  return E;
}

/// Propagate l-value use information to children.
void Expr::propagateLValueAccessKind(AccessKind accessKind,
                                     bool allowOverwrite) {
  /// A visitor class which walks an entire l-value expression.
  class PropagateAccessKind
       : public ExprVisitor<PropagateAccessKind, void, AccessKind> {
#ifndef NDEBUG
    bool AllowOverwrite;
#endif
  public:
    PropagateAccessKind(bool allowOverwrite)
#ifndef NDEBUG
      : AllowOverwrite(allowOverwrite)
#endif
    {}

    void visit(Expr *E, AccessKind kind) {
      assert((AllowOverwrite || !E->hasLValueAccessKind()) &&
             "l-value access kind has already been set");

      assert(E->getType()->isAssignableType() &&
             "setting access kind on non-l-value");
      E->setLValueAccessKind(kind);

      // Propagate this to sub-expressions.
      ASTVisitor::visit(E, kind);
    }

#define NON_LVALUE_EXPR(KIND)                                           \
    void visit##KIND##Expr(KIND##Expr *, AccessKind accessKind) {       \
      llvm_unreachable("not an l-value");                               \
    }
#define LEAF_LVALUE_EXPR(KIND)                                          \
    void visit##KIND##Expr(KIND##Expr *E, AccessKind accessKind) {}
#define COMPLETE_PHYSICAL_LVALUE_EXPR(KIND, ACCESSOR)                   \
    void visit##KIND##Expr(KIND##Expr *E, AccessKind accessKind) {      \
      visit(E->ACCESSOR, accessKind);                                   \
    }
#define PARTIAL_PHYSICAL_LVALUE_EXPR(KIND, ACCESSOR)                    \
    void visit##KIND##Expr(KIND##Expr *E, AccessKind accessKind) {      \
      visit(E->ACCESSOR, getPartialAccessKind(accessKind));             \
    }

    void visitMemberRefExpr(MemberRefExpr *E, AccessKind accessKind) {
      if (!E->getBase()->getType()->isLValueType()) return;
      visit(E->getBase(), getBaseAccessKind(E->getMember(), accessKind));
    }
    void visitSubscriptExpr(SubscriptExpr *E, AccessKind accessKind) {
      if (!E->getBase()->getType()->isLValueType()) return;
      visit(E->getBase(), getBaseAccessKind(E->getDecl(), accessKind));
    }

    static AccessKind getPartialAccessKind(AccessKind accessKind) {
      return (accessKind == AccessKind::Read
                ? accessKind : AccessKind::ReadWrite);
    }

    static AccessKind getBaseAccessKind(ConcreteDeclRef member,
                                        AccessKind accessKind) {
      // We assume writes are partial writes, so the result is always
      // either Read or ReadWrite.
      auto memberDecl = cast<AbstractStorageDecl>(member.getDecl());

      // If we're reading and the getter is mutating, or we're writing
      // and the setter is mutating, this is readwrite.
      if ((accessKind != AccessKind::Write &&
           memberDecl->isGetterMutating()) ||
          (accessKind != AccessKind::Read &&
           !memberDecl->isSetterNonMutating())) {
        return AccessKind::ReadWrite;
      }

      return AccessKind::Read;
    }

    void visitTupleExpr(TupleExpr *E, AccessKind accessKind) {
      for (auto elt : E->getElements()) {
        visit(elt, accessKind);
      }
    }

    void visitOpenExistentialExpr(OpenExistentialExpr *E,
                                  AccessKind accessKind) {
      bool opaqueValueHadAK = E->getOpaqueValue()->hasLValueAccessKind();
      AccessKind oldOpaqueValueAK =
        (opaqueValueHadAK ? E->getOpaqueValue()->getLValueAccessKind()
                          : AccessKind::Read);

      visit(E->getSubExpr(), accessKind);

      // Propagate the new access kind from the OVE to the original existential
      // if we just set or changed it on the OVE.
      if (E->getOpaqueValue()->hasLValueAccessKind()) {
        auto newOpaqueValueAK = E->getOpaqueValue()->getLValueAccessKind();
        if (!opaqueValueHadAK || newOpaqueValueAK != oldOpaqueValueAK)
          visit(E->getExistentialValue(), newOpaqueValueAK);
      }
    }

    LEAF_LVALUE_EXPR(DeclRef)
    LEAF_LVALUE_EXPR(DiscardAssignment)
    LEAF_LVALUE_EXPR(DynamicLookup)
    LEAF_LVALUE_EXPR(OpaqueValue)
    LEAF_LVALUE_EXPR(EditorPlaceholder)

    COMPLETE_PHYSICAL_LVALUE_EXPR(AnyTry, getSubExpr())
    PARTIAL_PHYSICAL_LVALUE_EXPR(BindOptional, getSubExpr())
    COMPLETE_PHYSICAL_LVALUE_EXPR(DotSyntaxBaseIgnored, getRHS());
    PARTIAL_PHYSICAL_LVALUE_EXPR(ForceValue, getSubExpr())
    COMPLETE_PHYSICAL_LVALUE_EXPR(Identity, getSubExpr())
    PARTIAL_PHYSICAL_LVALUE_EXPR(TupleElement, getBase())

    NON_LVALUE_EXPR(Error)
    NON_LVALUE_EXPR(Literal)
    NON_LVALUE_EXPR(SuperRef)
    NON_LVALUE_EXPR(Type)
    NON_LVALUE_EXPR(OtherConstructorDeclRef)
    NON_LVALUE_EXPR(Collection)
    NON_LVALUE_EXPR(CaptureList)
    NON_LVALUE_EXPR(AbstractClosure)
    NON_LVALUE_EXPR(InOut)
    NON_LVALUE_EXPR(DynamicType)
    NON_LVALUE_EXPR(RebindSelfInConstructor)
    NON_LVALUE_EXPR(Apply)
    NON_LVALUE_EXPR(ImplicitConversion)
    NON_LVALUE_EXPR(ExplicitCast)
    NON_LVALUE_EXPR(OptionalEvaluation)
    NON_LVALUE_EXPR(If)
    NON_LVALUE_EXPR(Assign)
    NON_LVALUE_EXPR(DefaultValue)
    NON_LVALUE_EXPR(CodeCompletion)
    NON_LVALUE_EXPR(ObjCSelector)
    NON_LVALUE_EXPR(ObjCKeyPath)

#define UNCHECKED_EXPR(KIND, BASE) \
    NON_LVALUE_EXPR(KIND)
#include "swift/AST/ExprNodes.def"

#undef PHYSICAL_LVALUE_EXPR
#undef LEAF_LVALUE_EXPR
#undef NON_LVALUE_EXPR
  };

  PropagateAccessKind(allowOverwrite).visit(this, accessKind);
}

/// Enumerate each immediate child expression of this node, invoking the
/// specific functor on it.  This ignores statements and other non-expression
/// children.
void Expr::
forEachImmediateChildExpr(const std::function<Expr*(Expr*)> &callback) {
  struct ChildWalker : ASTWalker {
    const std::function<Expr*(Expr*)> &callback;
    Expr *ThisNode;

    ChildWalker(const std::function<Expr*(Expr*)> &callback, Expr *ThisNode)
      : callback(callback), ThisNode(ThisNode) {}

    std::pair<bool, Expr *> walkToExprPre(Expr *E) override {
      // When looking at the current node, of course we want to enter it.  We
      // also don't want to enumerate it.
      if (E == ThisNode)
        return { true, E };

      // Otherwise we must be a child of our expression, enumerate it!
      return { false, callback(E) };
    }

    std::pair<bool, Stmt *> walkToStmtPre(Stmt *S) override {
      return { false, S };
    }

    std::pair<bool, Pattern*> walkToPatternPre(Pattern *P) override {
      return { false, P };
    }
    bool walkToDeclPre(Decl *D) override { return false; }
    bool walkToTypeReprPre(TypeRepr *T) override { return false; }
    bool walkToTypeLocPre(TypeLoc &TL) override { return false; }
  };

  this->walk(ChildWalker(callback, this));
}

/// Enumerate each immediate child expression of this node, invoking the
/// specific functor on it.  This ignores statements and other non-expression
/// children.
void Expr::forEachChildExpr(const std::function<Expr*(Expr*)> &callback) {
  struct ChildWalker : ASTWalker {
    const std::function<Expr*(Expr*)> &callback;

    ChildWalker(const std::function<Expr*(Expr*)> &callback)
    : callback(callback) {}

    std::pair<bool, Expr *> walkToExprPre(Expr *E) override {
      // Enumerate the node!
      return { true, callback(E) };
    }

    std::pair<bool, Stmt *> walkToStmtPre(Stmt *S) override {
      return { false, S };
    }

    std::pair<bool, Pattern*> walkToPatternPre(Pattern *P) override {
      return { false, P };
    }
    bool walkToDeclPre(Decl *D) override { return false; }
    bool walkToTypeReprPre(TypeRepr *T) override { return false; }
    bool walkToTypeLocPre(TypeLoc &TL) override { return false; }
  };

  this->walk(ChildWalker(callback));
}

Initializer *Expr::findExistingInitializerContext() {
  struct FindExistingInitializer : ASTWalker {
    Initializer *TheInitializer = nullptr;
    std::pair<bool,Expr*> walkToExprPre(Expr *E) override {
      assert(!TheInitializer && "continuing to walk after finding context?");
      if (auto closure = dyn_cast<AbstractClosureExpr>(E)) {
        TheInitializer = cast<Initializer>(closure->getParent());
        return { false, nullptr };
      }
      return { true, E };
    }
  } finder;
  walk(finder);
  return finder.TheInitializer;
}

bool Expr::isTypeReference() const {
  // If the result isn't a metatype, there's nothing else to do.
  if (!getType()->is<AnyMetatypeType>())
    return false;

  const Expr *expr = this;
  do {
    // Skip syntax.
    expr = expr->getSemanticsProvidingExpr();

    // Direct reference to a type.
    if (auto declRef = dyn_cast<DeclRefExpr>(expr))
      if (isa<TypeDecl>(declRef->getDecl()))
        return true;
    if (isa<TypeExpr>(expr))
      return true;

    // A "." expression that refers to a member.
    if (auto memberRef = dyn_cast<MemberRefExpr>(expr))
      return isa<TypeDecl>(memberRef->getMember().getDecl());

    // When the base of a "." expression is ignored, look at the member.
    if (auto ignoredDot = dyn_cast<DotSyntaxBaseIgnoredExpr>(expr)) {
      expr = ignoredDot->getRHS();
      continue;
    }

    // Anything else is not statically derived.
    return false;
  } while (true);

}

bool Expr::isStaticallyDerivedMetatype() const {
  // The type must first be a type reference.
  if (!isTypeReference())
    return false;

  // Archetypes are never statically derived.
  return !getType()->getAs<AnyMetatypeType>()->getInstanceType()
    ->is<ArchetypeType>();
}

bool Expr::isSuperExpr() const {
  const Expr *expr = this;
  do {
    expr = expr->getSemanticsProvidingExpr();

    if (isa<SuperRefExpr>(expr))
      return true;

    if (auto derivedToBase = dyn_cast<DerivedToBaseExpr>(expr)) {
      expr = derivedToBase->getSubExpr();
      continue;
    }
    if (auto metatypeConversion = dyn_cast<MetatypeConversionExpr>(expr)) {
      expr = metatypeConversion->getSubExpr();
      continue;
    }

    return false;
  } while (true);
}

bool Expr::canAppendCallParentheses() const {
  switch (getKind()) {
  case ExprKind::Error:
  case ExprKind::CodeCompletion:
    return false;

  case ExprKind::NilLiteral:
  case ExprKind::IntegerLiteral:
  case ExprKind::FloatLiteral:
  case ExprKind::BooleanLiteral:
  case ExprKind::StringLiteral:
  case ExprKind::InterpolatedStringLiteral:
  case ExprKind::MagicIdentifierLiteral:
  case ExprKind::ObjCSelector:
  case ExprKind::ObjCKeyPath:
    return true;

  case ExprKind::ObjectLiteral:
    return true;

  case ExprKind::DiscardAssignment:
    // Legal but pointless.
    return true;

  case ExprKind::DeclRef:
    return !cast<DeclRefExpr>(this)->getDecl()->getName().isOperator();

  case ExprKind::SuperRef:
  case ExprKind::Type:
  case ExprKind::OtherConstructorDeclRef:
  case ExprKind::DotSyntaxBaseIgnored:
    return true;

  case ExprKind::OverloadedDeclRef: {
    auto *overloadedExpr = cast<OverloadedDeclRefExpr>(this);
    if (overloadedExpr->getDecls().empty())
      return false;
    return !overloadedExpr->getDecls().front()->getName().isOperator();
  }

  case ExprKind::OverloadedMemberRef:
    return true;

  case ExprKind::UnresolvedDeclRef:
    return cast<UnresolvedDeclRefExpr>(this)->getName().isOperator();

  case ExprKind::MemberRef:
  case ExprKind::DynamicMemberRef:
  case ExprKind::DynamicSubscript:
  case ExprKind::UnresolvedSpecialize:
  case ExprKind::UnresolvedMember:
  case ExprKind::UnresolvedDot:
    return true;

  case ExprKind::Sequence:
    return false;

  case ExprKind::Paren:
  case ExprKind::DotSelf:
  case ExprKind::Tuple:
  case ExprKind::Array:
  case ExprKind::Dictionary:
  case ExprKind::Subscript:
  case ExprKind::TupleElement:
    return true;

  case ExprKind::CaptureList:
  case ExprKind::Closure:
  case ExprKind::AutoClosure:
    return false;

  case ExprKind::DynamicType:
    return true;

  case ExprKind::Try:
  case ExprKind::ForceTry:
  case ExprKind::OptionalTry:
  case ExprKind::InOut:
    return false;

  case ExprKind::RebindSelfInConstructor:
  case ExprKind::OpaqueValue:
  case ExprKind::BindOptional:
  case ExprKind::OptionalEvaluation:
    return false;

  case ExprKind::ForceValue:
    return true;

  case ExprKind::OpenExistential:
    return false;

  case ExprKind::Call:
  case ExprKind::PostfixUnary:
  case ExprKind::DotSyntaxCall:
  case ExprKind::ConstructorRefCall:
    return true;

  case ExprKind::PrefixUnary:
  case ExprKind::Binary:
    return false;

  case ExprKind::Load:
  case ExprKind::TupleShuffle:
  case ExprKind::UnresolvedTypeConversion:
  case ExprKind::FunctionConversion:
  case ExprKind::CovariantFunctionConversion:
  case ExprKind::CovariantReturnConversion:
  case ExprKind::MetatypeConversion:
  case ExprKind::CollectionUpcastConversion:
  case ExprKind::Erasure:
  case ExprKind::DerivedToBase:
  case ExprKind::ArchetypeToSuper:
  case ExprKind::InjectIntoOptional:
  case ExprKind::ClassMetatypeToObject:
  case ExprKind::ExistentialMetatypeToObject:
  case ExprKind::ProtocolMetatypeToObject:
  case ExprKind::InOutToPointer:
  case ExprKind::ArrayToPointer:
  case ExprKind::StringToPointer:
  case ExprKind::PointerToPointer:
  case ExprKind::LValueToPointer:
  case ExprKind::ForeignObjectConversion:
  case ExprKind::UnevaluatedInstance:
    // Implicit conversion nodes have no syntax of their own; defer to the
    // subexpression.
    return cast<ImplicitConversionExpr>(this)->getSubExpr()
      ->canAppendCallParentheses();

  case ExprKind::ForcedCheckedCast:
  case ExprKind::ConditionalCheckedCast:
  case ExprKind::Is:
  case ExprKind::Coerce:
    return false;

  case ExprKind::Arrow:
  case ExprKind::If:
  case ExprKind::Assign:
  case ExprKind::DefaultValue:
  case ExprKind::UnresolvedPattern:
  case ExprKind::EditorPlaceholder:
    return false;
  }
}

llvm::DenseMap<Expr *, Expr *> Expr::getParentMap() {
  class RecordingTraversal : public ASTWalker {
  public:
    llvm::DenseMap<Expr *, Expr *> &ParentMap;

    explicit RecordingTraversal(llvm::DenseMap<Expr *, Expr *> &parentMap)
      : ParentMap(parentMap) { }

    virtual std::pair<bool, Expr *> walkToExprPre(Expr *E) {
      if (auto parent = Parent.getAsExpr())
        ParentMap[E] = parent;

      return { true, E };
    }
  };

  llvm::DenseMap<Expr *, Expr *> parentMap;
  RecordingTraversal traversal(parentMap);
  walk(traversal);
  return parentMap;
}

llvm::DenseMap<Expr *, unsigned> Expr::getDepthMap() {
  class RecordingTraversal : public ASTWalker {
  public:
    llvm::DenseMap<Expr *, unsigned> &DepthMap;
    unsigned Depth = 0;

    explicit RecordingTraversal(llvm::DenseMap<Expr *, unsigned> &depthMap)
      : DepthMap(depthMap) { }

    virtual std::pair<bool, Expr *> walkToExprPre(Expr *E) {
      DepthMap[E] = Depth;
      Depth++;
      return { true, E };
    }

    virtual Expr *walkToExprPost(Expr *E) {
      Depth--;
      return E;
    }
  };

  llvm::DenseMap<Expr *, unsigned> depthMap;
  RecordingTraversal traversal(depthMap);
  walk(traversal);
  return depthMap;
}

llvm::DenseMap<Expr *, unsigned> Expr::getPreorderIndexMap() {
  class RecordingTraversal : public ASTWalker {
  public:
    llvm::DenseMap<Expr *, unsigned> &IndexMap;
    unsigned Index = 0;

    explicit RecordingTraversal(llvm::DenseMap<Expr *, unsigned> &indexMap)
      : IndexMap(indexMap) { }

    virtual std::pair<bool, Expr *> walkToExprPre(Expr *E) {
      IndexMap[E] = Index;
      Index++;
      return { true, E };
    }
  };

  llvm::DenseMap<Expr *, unsigned> indexMap;
  RecordingTraversal traversal(indexMap);
  walk(traversal);
  return indexMap;
}

//===----------------------------------------------------------------------===//
// Support methods for Exprs.
//===----------------------------------------------------------------------===//

static LiteralExpr *shallowCloneImpl(const NilLiteralExpr *E, ASTContext &Ctx) {
  return new (Ctx) NilLiteralExpr(E->getLoc());
}

static LiteralExpr *
shallowCloneImpl(const IntegerLiteralExpr *E, ASTContext &Ctx) {
  auto res = new (Ctx) IntegerLiteralExpr(E->getDigitsText(),
                                          E->getSourceRange().End);
  if (E->isNegative())
    res->setNegative(E->getSourceRange().Start);
  return res;
}

static LiteralExpr *shallowCloneImpl(const FloatLiteralExpr *E, ASTContext &Ctx) {
  auto res = new (Ctx) FloatLiteralExpr(E->getDigitsText(),
                                        E->getSourceRange().End);
  if (E->isNegative())
    res->setNegative(E->getSourceRange().Start);
  return res;
}
static LiteralExpr *
shallowCloneImpl(const BooleanLiteralExpr *E, ASTContext &Ctx) {
  return new (Ctx) BooleanLiteralExpr(E->getValue(), E->getLoc());
}
static LiteralExpr *shallowCloneImpl(const StringLiteralExpr *E, ASTContext &Ctx) {
  auto res = new (Ctx) StringLiteralExpr(E->getValue(), E->getSourceRange());
  res->setEncoding(E->getEncoding());
  return res;
}

static LiteralExpr *
shallowCloneImpl(const InterpolatedStringLiteralExpr *E, ASTContext &Ctx) {
  auto res = new (Ctx) InterpolatedStringLiteralExpr(E->getLoc(),
                const_cast<InterpolatedStringLiteralExpr*>(E)->getSegments());
  res->setSemanticExpr(E->getSemanticExpr());
  return res;
}

static LiteralExpr *
shallowCloneImpl(const MagicIdentifierLiteralExpr *E, ASTContext &Ctx) {
  auto res = new (Ctx) MagicIdentifierLiteralExpr(E->getKind(),
                                                  E->getSourceRange().End);
  if (res->isString())
    res->setStringEncoding(E->getStringEncoding());
  return res;
}

static LiteralExpr *
shallowCloneImpl(const ObjectLiteralExpr *E, ASTContext &Ctx) {
  auto res = new (Ctx) ObjectLiteralExpr(E->getStartLoc(), E->getLiteralKind(),
                                         E->getArg());
  res->setSemanticExpr(E->getSemanticExpr());
  return res;
}

// Make an exact copy of this AST node.
LiteralExpr *LiteralExpr::shallowClone(ASTContext &Ctx) const {
  LiteralExpr *Result = nullptr;
  switch (getKind()) {
  default: llvm_unreachable("Unknown literal type!");
#define DISPATCH_CLONE(KIND) \
  case ExprKind::KIND: \
    Result = shallowCloneImpl(cast<KIND##Expr>(this), Ctx); \
    break;

  DISPATCH_CLONE(NilLiteral)
  DISPATCH_CLONE(IntegerLiteral)
  DISPATCH_CLONE(FloatLiteral)
  DISPATCH_CLONE(BooleanLiteral)
  DISPATCH_CLONE(StringLiteral)
  DISPATCH_CLONE(InterpolatedStringLiteral)
  DISPATCH_CLONE(ObjectLiteral)
  DISPATCH_CLONE(MagicIdentifierLiteral)
#undef DISPATCH_CLONE
  }

  Result->setType(getType());
  Result->setImplicit(isImplicit());
  return Result;
}

static APInt getIntegerLiteralValue(bool IsNegative, StringRef Text,
                                    unsigned BitWidth) {
  llvm::APInt Value(BitWidth, 0);
  // swift encodes octal differently from C
  bool IsCOctal = Text.size() > 1 && Text[0] == '0' && isdigit(Text[1]);
  bool Error = Text.getAsInteger(IsCOctal ? 10 : 0, Value);
  assert(!Error && "Invalid IntegerLiteral formed"); (void)Error;
  if (IsNegative)
    Value = -Value;
  if (Value.getBitWidth() != BitWidth)
    Value = Value.sextOrTrunc(BitWidth);
  return Value;
}

APInt IntegerLiteralExpr::getValue(StringRef Text, unsigned BitWidth) {
  return getIntegerLiteralValue(/*IsNegative=*/false, Text, BitWidth);
}

APInt IntegerLiteralExpr::getValue() const {
  assert(!getType().isNull() && "Semantic analysis has not completed");
  assert(!getType()->is<ErrorType>() && "Should have a valid type");
  return getIntegerLiteralValue(
      isNegative(), getDigitsText(),
      getType()->castTo<BuiltinIntegerType>()->getGreatestWidth());
}

static APFloat getFloatLiteralValue(bool IsNegative, StringRef Text,
                                    const llvm::fltSemantics &Semantics) {
  APFloat Val(Semantics);
  APFloat::opStatus Res =
    Val.convertFromString(Text, llvm::APFloat::rmNearestTiesToEven);
  assert(Res != APFloat::opInvalidOp && "Sema didn't reject invalid number");
  (void)Res;
  if (IsNegative) {
    auto NegVal = APFloat::getZero(Semantics, /*negative*/ true);
    Res = NegVal.subtract(Val, llvm::APFloat::rmNearestTiesToEven);
    assert(Res != APFloat::opInvalidOp && "Sema didn't reject invalid number");
    (void)Res;
    return NegVal;
  }
  return Val;
}

APFloat FloatLiteralExpr::getValue(StringRef Text,
                                   const llvm::fltSemantics &Semantics) {
  return getFloatLiteralValue(/*IsNegative*/false, Text, Semantics);
}

llvm::APFloat FloatLiteralExpr::getValue() const {
  assert(!getType().isNull() && "Semantic analysis has not completed");
  assert(!getType()->is<ErrorType>() && "Should have a valid type");

  return getFloatLiteralValue(isNegative(), getDigitsText(),
                  getType()->castTo<BuiltinFloatType>()->getAPFloatSemantics());
}

StringLiteralExpr::StringLiteralExpr(StringRef Val, SourceRange Range,
                                     bool Implicit)
    : LiteralExpr(ExprKind::StringLiteral, Implicit), Val(Val),
      Range(Range) {
  StringLiteralExprBits.Encoding = static_cast<unsigned>(UTF8);
  StringLiteralExprBits.IsSingleUnicodeScalar =
      unicode::isSingleUnicodeScalar(Val);
  StringLiteralExprBits.IsSingleExtendedGraphemeCluster =
      unicode::isSingleExtendedGraphemeCluster(Val);
}

StringRef ObjectLiteralExpr::getLiteralKindRawName() const {
  switch (LitKind) {
#define POUND_OBJECT_LITERAL(Name, Desc, Proto) case Name: return #Name;
#include "swift/Parse/Tokens.def"
  }
  llvm_unreachable("unspecified literal");
}

StringRef ObjectLiteralExpr::getLiteralKindPlainName() const {
  switch (LitKind) {
#define POUND_OBJECT_LITERAL(Name, Desc, Proto) case Name: return Desc;
#include "swift/Parse/Tokens.def"
  }
  llvm_unreachable("unspecified literal");
}

void DeclRefExpr::setSpecialized() {
  if (isSpecialized())
    return;

  ConcreteDeclRef ref = getDeclRef();
  void *Mem = ref.getDecl()->getASTContext().Allocate(sizeof(SpecializeInfo),
                                                      alignof(SpecializeInfo));
  auto Spec = new (Mem) SpecializeInfo;
  Spec->D = ref;
  DOrSpecialized = Spec;
}

void DeclRefExpr::setGenericArgs(ArrayRef<TypeRepr*> GenericArgs) {
  ValueDecl *D = getDecl();
  assert(D);
  setSpecialized();
  getSpecInfo()->GenericArgs = D->getASTContext().AllocateCopy(GenericArgs);
}

ConstructorDecl *OtherConstructorDeclRefExpr::getDecl() const {
  return cast_or_null<ConstructorDecl>(Ctor.getDecl());
}

MemberRefExpr::MemberRefExpr(Expr *base, SourceLoc dotLoc,
                             ConcreteDeclRef member, DeclNameLoc nameLoc,
                             bool Implicit, AccessSemantics semantics)
  : Expr(ExprKind::MemberRef, Implicit), Base(base),
    Member(member), DotLoc(dotLoc), NameLoc(nameLoc) {

  MemberRefExprBits.Semantics = (unsigned) semantics;
  MemberRefExprBits.IsSuper = false;
}

Type OverloadSetRefExpr::getBaseType() const {
  if (isa<OverloadedDeclRefExpr>(this))
    return Type();
  if (auto *DRE = dyn_cast<OverloadedMemberRefExpr>(this)) {
    return DRE->getBase()->getType()->getRValueType();
  }

  llvm_unreachable("Unhandled overloaded set reference expression");
}

bool OverloadSetRefExpr::hasBaseObject() const {
  if (Type BaseTy = getBaseType())
    return !BaseTy->is<AnyMetatypeType>();

  return false;
}

SequenceExpr *SequenceExpr::create(ASTContext &ctx, ArrayRef<Expr*> elements) {
  assert(elements.size() & 1 && "even number of elements in sequence");
  void *Buffer = ctx.Allocate(sizeof(SequenceExpr) +
                              elements.size() * sizeof(Expr*),
                              alignof(SequenceExpr));
  return ::new(Buffer) SequenceExpr(elements);
}

ParenExpr *ParenExpr::createImplicit(ASTContext &ctx, Expr *expr) {
  ParenExpr *result = new (ctx) ParenExpr(SourceLoc(), expr, SourceLoc(),
                                          /*hasTrailingClosure=*/false,
                                          expr->getType());
  result->setImplicit();
  return result;
}

SourceLoc TupleExpr::getStartLoc() const {
  if (LParenLoc.isValid()) return LParenLoc;
  if (getNumElements() == 0) return SourceLoc();
  return getElement(0)->getStartLoc();
}

SourceLoc TupleExpr::getEndLoc() const {
  if (hasTrailingClosure() || RParenLoc.isInvalid()) {
    if (getNumElements() == 0) return SourceLoc();
    return getElements().back()->getEndLoc();
  }
  return RParenLoc;
}

TupleExpr::TupleExpr(SourceLoc LParenLoc, ArrayRef<Expr *> SubExprs,
                     ArrayRef<Identifier> ElementNames,
                     ArrayRef<SourceLoc> ElementNameLocs,
                     SourceLoc RParenLoc, bool HasTrailingClosure,
                     bool Implicit, Type Ty)
  : Expr(ExprKind::Tuple, Implicit, Ty),
    LParenLoc(LParenLoc), RParenLoc(RParenLoc),
    NumElements(SubExprs.size())
{
  TupleExprBits.HasTrailingClosure = HasTrailingClosure;
  TupleExprBits.HasElementNames = !ElementNames.empty();
  TupleExprBits.HasElementNameLocations = !ElementNameLocs.empty();

  assert(LParenLoc.isValid() == RParenLoc.isValid() &&
         "Mismatched parenthesis location information validity");
  assert(ElementNames.empty() || ElementNames.size() == SubExprs.size());
  assert(ElementNameLocs.empty() ||
         ElementNames.size() == ElementNameLocs.size());

  // Copy elements.
  std::uninitialized_copy(SubExprs.begin(), SubExprs.end(),
                          getTrailingObjects<Expr *>());

  // Copy element names, if provided.
  if (hasElementNames()) {
    std::uninitialized_copy(ElementNames.begin(), ElementNames.end(),
                            getTrailingObjects<Identifier>());
  }

  // Copy element name locations, if provided.
  if (hasElementNameLocs()) {
    std::uninitialized_copy(ElementNameLocs.begin(), ElementNameLocs.end(),
                            getTrailingObjects<SourceLoc>());
  }
}

TupleExpr *TupleExpr::create(ASTContext &ctx,
                             SourceLoc LParenLoc,
                             ArrayRef<Expr *> SubExprs,
                             ArrayRef<Identifier> ElementNames,
                             ArrayRef<SourceLoc> ElementNameLocs,
                             SourceLoc RParenLoc, bool HasTrailingClosure,
                             bool Implicit, Type Ty) {
  size_t size =
      totalSizeToAlloc<Expr *, Identifier, SourceLoc>(SubExprs.size(),
                                                      ElementNames.size(),
                                                      ElementNameLocs.size());
  void *mem = ctx.Allocate(size, alignof(TupleExpr));
  return new (mem) TupleExpr(LParenLoc, SubExprs, ElementNames, ElementNameLocs,
                             RParenLoc, HasTrailingClosure, Implicit, Ty);
}

TupleExpr *TupleExpr::createEmpty(ASTContext &ctx, SourceLoc LParenLoc,
                                  SourceLoc RParenLoc, bool Implicit) {
  return create(ctx, LParenLoc, { }, { }, { }, RParenLoc,
                /*HasTrailingClosure=*/false, Implicit,
                TupleType::getEmpty(ctx));
}

TupleExpr *TupleExpr::createImplicit(ASTContext &ctx, ArrayRef<Expr *> SubExprs,
                                     ArrayRef<Identifier> ElementNames) {
  return create(ctx, SourceLoc(), SubExprs, ElementNames, { }, SourceLoc(),
                /*HasTrailingClosure=*/false, /*Implicit=*/true, Type());
}

ArrayExpr *ArrayExpr::create(ASTContext &C, SourceLoc LBracketLoc,
                             ArrayRef<Expr*> Elements,
                             ArrayRef<SourceLoc> CommaLocs,
                             SourceLoc RBracketLoc, Type Ty) {
  // Copy the element list into the ASTContext.
  auto NewElements = C.AllocateCopy(Elements);
  auto NewCommas = C.AllocateCopy(CommaLocs);
  return new (C) ArrayExpr(LBracketLoc, NewElements, NewCommas, RBracketLoc,Ty);
}

DictionaryExpr *DictionaryExpr::create(ASTContext &C, SourceLoc LBracketLoc,
                             ArrayRef<Expr*> Elements, SourceLoc RBracketLoc,
                             Type Ty) {
  // Copy the element list into the ASTContext.
  auto NewElements = C.AllocateCopy(Elements);
  return new (C) DictionaryExpr(LBracketLoc, NewElements, RBracketLoc, Ty);
}

static ValueDecl *getCalledValue(Expr *E) {
  if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
    return DRE->getDecl();

  Expr *E2 = E->getValueProvidingExpr();
  if (E != E2) return getCalledValue(E2);
  return nullptr;
}

ValueDecl *ApplyExpr::getCalledValue() const {
  return ::getCalledValue(Fn);
}

Expr *CallExpr::getDirectCallee() const {
  auto fn = getFn();
  while (true) {
    fn = fn->getSemanticsProvidingExpr();

    if (auto force = dyn_cast<ForceValueExpr>(fn)) {
      fn = force->getSubExpr();
      continue;
    }

    if (auto bind = dyn_cast<BindOptionalExpr>(fn)) {
      fn = bind->getSubExpr();
      continue;
    }

    return fn;
  }
}

RebindSelfInConstructorExpr::RebindSelfInConstructorExpr(Expr *SubExpr,
                                                         VarDecl *Self)
  : Expr(ExprKind::RebindSelfInConstructor, /*Implicit=*/true,
         TupleType::getEmpty(Self->getASTContext())),
    SubExpr(SubExpr), Self(Self)
{}

OtherConstructorDeclRefExpr *
RebindSelfInConstructorExpr::getCalledConstructor(bool &isChainToSuper) const {
  // Dig out the OtherConstructorRefExpr. Note that this is the reverse
  // of what we do in pre-checking.
  Expr *candidate = getSubExpr();
  while (true) {
    // Look through identity expressions.
    if (auto identity = dyn_cast<IdentityExpr>(candidate)) {
      candidate = identity->getSubExpr();
      continue;
    }

    // Look through force-value expressions.
    if (auto force = dyn_cast<ForceValueExpr>(candidate)) {
      candidate = force->getSubExpr();
      continue;
    }

    // Look through all try expressions.
    if (auto tryExpr = dyn_cast<AnyTryExpr>(candidate)) {
      candidate = tryExpr->getSubExpr();
      continue;
    }

    break;
  }

  // We hit an application, find the constructor reference.
  OtherConstructorDeclRefExpr *otherCtorRef;
  const ApplyExpr *apply;
  do {
    apply = cast<ApplyExpr>(candidate);
    candidate = apply->getFn();
    auto candidateUnwrapped = candidate->getSemanticsProvidingExpr();
    otherCtorRef = dyn_cast<OtherConstructorDeclRefExpr>(candidateUnwrapped);
  } while (!otherCtorRef);

  isChainToSuper = apply->getArg()->isSuperExpr();
  return otherCtorRef;
}

void AbstractClosureExpr::setParameterList(ParameterList *P) {
  parameterList = P;
  // Change the DeclContext of any parameters to be this closure.
  if (P)
    P->setDeclContextOfParamDecls(this);
}

Type AbstractClosureExpr::getResultType() const {
  if (getType()->is<ErrorType>())
    return getType();

  return getType()->castTo<FunctionType>()->getResult();
}

bool AbstractClosureExpr::isBodyThrowing() const {
  if (getType()->is<ErrorType>())
    return false;

  return getType()->castTo<FunctionType>()->getExtInfo().throws();
}

bool AbstractClosureExpr::hasSingleExpressionBody() const {
  if (auto closure = dyn_cast<ClosureExpr>(this))
    return closure->hasSingleExpressionBody();

  return true;
}

#define FORWARD_SOURCE_LOCS_TO(CLASS, NODE) \
  SourceRange CLASS::getSourceRange() const {     \
    return (NODE)->getSourceRange();              \
  }                                               \
  SourceLoc CLASS::getStartLoc() const {          \
    return (NODE)->getStartLoc();                 \
  }                                               \
  SourceLoc CLASS::getEndLoc() const {            \
    return (NODE)->getEndLoc();                   \
  }                                               \
  SourceLoc CLASS::getLoc() const {               \
    return (NODE)->getStartLoc();                 \
  }

FORWARD_SOURCE_LOCS_TO(ClosureExpr, Body.getPointer())

Expr *ClosureExpr::getSingleExpressionBody() const {
  assert(hasSingleExpressionBody() && "Not a single-expression body");
  if (!isVoidConversionClosure()) {
    return cast<ReturnStmt>(getBody()->getElement(0).get<Stmt *>())
             ->getResult();
  } else {
    return getBody()->getElement(0).get<Expr *>();
  }
}

void ClosureExpr::setSingleExpressionBody(Expr *NewBody) {
  assert(hasSingleExpressionBody() && "Not a single-expression body");
  if (!isVoidConversionClosure()) {
    cast<ReturnStmt>(getBody()->getElement(0).get<Stmt *>())
      ->setResult(NewBody);
  } else {
    return getBody()->setElement(0, NewBody);
  }
}

FORWARD_SOURCE_LOCS_TO(AutoClosureExpr, Body)

void AutoClosureExpr::setBody(Expr *E) {
  auto &Context = getASTContext();
  auto *RS = new (Context) ReturnStmt(SourceLoc(), E);
  Body = BraceStmt::create(Context, E->getStartLoc(), { RS }, E->getEndLoc());
}

Expr *AutoClosureExpr::getSingleExpressionBody() const {
  return cast<ReturnStmt>(Body->getElement(0).get<Stmt *>())->getResult();
}

FORWARD_SOURCE_LOCS_TO(UnresolvedPatternExpr, subPattern)

TypeExpr::TypeExpr(TypeLoc TyLoc)
  : Expr(ExprKind::Type, /*implicit*/false), Info(TyLoc) {
  Type Ty = TyLoc.getType();
  if (Ty && Ty->hasCanonicalTypeComputed())
    setType(MetatypeType::get(Ty, Ty->getASTContext()));
}

TypeExpr::TypeExpr(Type Ty)
  : Expr(ExprKind::Type, /*implicit*/true), Info(TypeLoc::withoutLoc(Ty)) {
  if (Ty->hasCanonicalTypeComputed())
    setType(MetatypeType::get(Ty, Ty->getASTContext()));
}

// The type of a TypeExpr is always a metatype type.  Return the instance
// type or null if not set yet.
Type TypeExpr::getInstanceType() const {
  if (!getType() || getType()->is<ErrorType>())
    return Type();

  return getType()->castTo<MetatypeType>()->getInstanceType();
}

/// Return a TypeExpr for a simple identifier and the specified location.
TypeExpr *TypeExpr::createForDecl(SourceLoc Loc, TypeDecl *Decl,
                                  bool isImplicit) {
  ASTContext &C = Decl->getASTContext();
  assert(Loc.isValid());
  auto *Repr = new (C) SimpleIdentTypeRepr(Loc, Decl->getName());
  Repr->setValue(Decl);
  auto result = new (C) TypeExpr(TypeLoc(Repr, Type()));
  if (isImplicit)
    result->setImplicit();
  return result;
}

TypeExpr *TypeExpr::createForSpecializedDecl(SourceLoc Loc, TypeDecl *D,
                                             ArrayRef<TypeRepr*> args,
                                             SourceRange AngleLocs) {
  ASTContext &C = D->getASTContext();
  assert(Loc.isValid());
  auto *Repr = new (C) GenericIdentTypeRepr(Loc, D->getName(),
                                            args, AngleLocs);
  Repr->setValue(D);
  return new (C) TypeExpr(TypeLoc(Repr, Type()));
}

// Create an implicit TypeExpr, with location information even though it
// shouldn't have one.  This is presently used to work around other location
// processing bugs.  If you have an implicit location, use createImplicit.
TypeExpr *TypeExpr::createImplicitHack(SourceLoc Loc, Type Ty, ASTContext &C) {
  // FIXME: This is horrible.
  if (Loc.isInvalid()) return createImplicit(Ty, C);
  auto *Repr = new (C) FixedTypeRepr(Ty, Loc);
  auto *Res = new (C) TypeExpr(TypeLoc(Repr, Ty));
  Res->setImplicit();
  Res->setType(MetatypeType::get(Ty, C));
  return Res;
}

ArchetypeType *OpenExistentialExpr::getOpenedArchetype() const {
  auto type = getOpaqueValue()->getType()->getRValueType();
  while (auto metaTy = type->getAs<MetatypeType>())
    type = metaTy->getInstanceType();
  return type->castTo<ArchetypeType>();
}

ObjCKeyPathExpr::ObjCKeyPathExpr(SourceLoc keywordLoc, SourceLoc lParenLoc,
                         ArrayRef<Identifier> names,
                         ArrayRef<SourceLoc> nameLocs,
                         SourceLoc rParenLoc)
  : Expr(ExprKind::ObjCKeyPath, /*Implicit=*/nameLocs.empty()),
    KeywordLoc(keywordLoc), LParenLoc(lParenLoc), RParenLoc(rParenLoc)
{
  // Copy components (which are all names).
  ObjCKeyPathExprBits.NumComponents = names.size();
  for (auto idx : indices(names))
    getComponentsMutable()[idx] = names[idx];

  assert(nameLocs.empty() || nameLocs.size() == names.size());
  ObjCKeyPathExprBits.HaveSourceLocations = !nameLocs.empty();
  if (ObjCKeyPathExprBits.HaveSourceLocations) {
    memcpy(getNameLocsMutable().data(), nameLocs.data(),
           nameLocs.size() * sizeof(SourceLoc));
  }
}

Identifier ObjCKeyPathExpr::getComponentName(unsigned i) const {
  if (auto decl = getComponentDecl(i))
    return decl->getFullName().getBaseName();

  return getComponents()[i].get<Identifier>();
}

ObjCKeyPathExpr *ObjCKeyPathExpr::create(ASTContext &ctx,
                                 SourceLoc keywordLoc, SourceLoc lParenLoc,
                                 ArrayRef<Identifier> names,
                                 ArrayRef<SourceLoc> nameLocs,
                                 SourceLoc rParenLoc) {
  unsigned size = sizeof(ObjCKeyPathExpr)
    + names.size() * sizeof(Identifier)
    + nameLocs.size() * sizeof(SourceLoc);
  void *mem = ctx.Allocate(size, alignof(ObjCKeyPathExpr));
  return new (mem) ObjCKeyPathExpr(keywordLoc, lParenLoc, names, nameLocs,
                                   rParenLoc);
}


text:
namespace ark {

class ARK_API Bounds : public Block, public Updatable {
public:
//  [[script::bindings::auto]]
    Bounds(const sp<Vec3>& center, const sp<Size>& size);

//  [[script::bindings::auto]]
    bool ptin(const V3& pt) const;
//  [[script::bindings::property]]
    const sp<Vec3>& center() const;

//  [[script::bindings::property]]
    virtual const sp<Size>& size() override;

    virtual bool update(uint64_t timestamp) override;

private:
    sp<Vec3> _center;
    SafePtr<Size> _size;
};

}

#endif


text:
import React from 'react';

module.exports = ({ record }) => {
  let publishText;

  if (record.formatted_publish_at) {
    publishText = Published on {record.formatted_publish_at};
  } else {
    publishText = Not published.;
  }

  return (

        {record.title}

        {publishText}

  );
};


text:
cryptox API Documentation
=======

### Contents
* [Constructor](#constructor)
* [Methods](#methods)
    * [getRate](#getrate)
    * [getTicker](#getticker)
    * [getOrderBook](#getorderbook)
    * [getTrades](#gettrades)
    * [getFee](#getfee)
    * [getTransactions](#gettransactions)
    * [getBalance](#getbalance)
    * [getMarginPositions](#getMarginPositions)
    * [getOpenOrders](#getopenorders)
    * [postSellOrder](#postsellorder)
    * [postBuyOrder](#postbuyorder)
    * [cancelOrder](#cancelorder)
    * [Native API calls](#nativeapicalls)
* [NOTES](#notes)
    * [Currency Symbols](#currency-symbols)
    * [Currency Pairs](#currency-pairs)

## Constructor

Creates an instance of `Cryptox` object type.

```js
Cryptox(exchangeSlug [, options])
```

Depending on the parameters used, two types of objects can be created
1. **public** (without authentication) - can be used for calling public API methods
2. **private** (with authentication) - can be used for calling public and private API methods

#### Examples
```js
var account = new Cryptox("btce", {key: "yourKey", secret: "yourSecret"});
```

```js
var exchange = new Cryptox("btce");
```

#### Arguments

* `exchangeSlug` is required and should have one values in table below
* `options` is used to pass parameters required for authentication, as indicated in table below

|Exchange name        | `exchangeSlug` | Authentication               |
| ---	              |    ---         |    ---                       |
| Bitfinex            | `"bitfinex"`   | `key`, `secret`              |
| Bitstamp            | `"bitstamp"`   | `key`, `secret`, `username`  |
| BitX                | `"bitx"`       | `key`, `secret`              |
| BTC-e               | `"btce"`       | `key`, `secret`              |
| CEX.io              | `"cexio"`      | `key`, `secret`, `username`  |
| Gdax                | `"gdax"`       | `key`, `secret`, `passphrase`|
| Poloniex            | `"poloniex"`   | `key`, `secret`              |
| Open Exchange Rates | `"oxr"`        | `key`                        |

`options` should be used when calling methods that require authentication. Missing or incorrect key/secret causes an error to be returned when calling a method that requires authentication (see [Authentication](#authentication)).

## Methods

#### Examples

```js
getTicker(options, callback);
```

```js
getTicker({pair: "XBT_USD"}, function (err, result) {
    if (!err)
        console.log(result);
});
```

### Arguments

* `options` is a JSON object containing parameters specific for each API call
* `callback` is executed inside the method once the API response is received from the exchange

#### Callbacks

The arguments passed to the callback function for each method are:

* `err` is an error object or `null` if no error occurred.
* `result` is JSON object containing the response.

    Example result:
    ```js
    {
        "timestamp": "2015-02-03T00:01:48+00:00",
        "error": "",
        "data": [
            {
                "pair": "XBT_USD",
                "last": "272.064",
                "bid": "272.064",
                "ask": "273.395",
                "volume": "7087.93047"
            }
         ]
    }
    ```

                |  Type  | Description
     ---     	| ---    | ---
    `timestamp` | string | ISO 8601 date & time
    `error`     | string | error message or `""` if no error
    `data`      | array  | array of one or more JSON objects containig the API result

### Results

The format of API result (see `result` in  [Callbacks](#callbacks)) above for each method is described in this document and it complies with JSON schemas in [jsonSchemas.js](../test/helpers/jsonSchemas.js)

### Authentication

Following methods require authentication

|Method             | Requires authentication
| ---	            |    :-:
|getRate            |     [1]
|getTicker          |
|getOrderBook       |
|getTrades          |
|getFee             |     √ [2]
|getTransactions    |     √
|getBalance         |     √
|getMarginPositions |     √
|getOpenOrders      |     √
|postSellOrder      |     √
|placeBuyOrder      |     √
|cancelOrder        |     √

>1 Open Exchange Rates (OXR) requires authentication
>2 BTC-e and BitX does not require authentication (since the fee is fixed amount)

When calling a method that requires authentication, the object should have been constructed with parameters `key`, `secret` and (optional) `userId`.

### getRate

Returns the exchange rate.

```js
getRate(options, callback);
```

#### Example
```js
exchange.getRate({pair: "EUR_USD"}, function (err, rate) {
    if (!err)
        console.log(rate);
});
```
Example result:
```js
{
  "timestamp": "2016-10-16T15:00:07Z",
  "error": "",
  "data": [
    {
      "pair": "EUR_USD",
      "rate": "1.09727328"
    }
  ]
}
```

#### Arguments

* `options`

Parameter  |  Type  | Required for | Description  |
 ---	   | ---    |   :-:        | ---          |
`pair`     | string |   All        | currency pair|

* `callback` see [Callbacks](#callbacks)

#### Response

Parameter   |  Type   | Description
 ---	    | ---     | ---
`pair`      | String  | currency pair
`rate`      | String  | rate

### getTicker

Returns the latest ticker indicators.

```js
getTicker(options, callback);
```

#### Example
```js
exchange.getTicker({pair: "XBT_USD"}, function (err, ticker) {
    if (!err)
        console.log(ticker);
});
```
Example result:
```js
{
    "timestamp": "2015-02-03T00:01:48+00:00",
    "error": "",
    "data": [
        {
            "pair": "XBT_USD",
            "last": "272.064",
            "bid": "272.064",
            "ask": "273.395",
            "volume": "7087.93047"
        }
     ]
}
```

#### Arguments

* `options`

Parameter  |  Type  | Required for  | Description |
 ---	   | ---    |   :-:         | ---         |
`pair`     | string |BTC-e, Bitfinex| trading pair|

* `callback` see [Callbacks](#callbacks)

#### Response

Parameter   |  Type   | Description
 ---	    | ---     | ---
`pair`      | String  | trading pair
`last`      | String  | the price at which the last order executed
`bid`       | String  | highest buy order
`ask`       | String  | lowest sell order
`volume`    | String  | trading volume of the last 24 hours

Optional response parameters

Parameter / Availability |  Type   | Description
 ---	                 | ---     | ---
`high` [1] [2]       | String  | Highest trade price of the last 24 hours
`low` [1] [2]        | String  | Lowest trade price of the last 24 hours
`vwap` [1]       | String  | last 24 hours [volume weighted average price](http://en.wikipedia.org/wiki/Volume-weighted_average_price)

> [1] Bitstamp
> [2] Bitfinex

### getOrderBook

Returns a list of bids and asks in the order book.
Ask orders are sorted by price ascending. Bid orders are sorted by price descending.
Note that multiple orders at the same price are not necessarily conflated.

```js
cryptox.getOrderBook(options, callback);
```

#### Example

```js
exchange.getOrderBook({pair: "BTC_USD"}, function (err, orderBook) {
    if (!err)
        console.log(orderBook);
});
```
Example result:
```js
{
    "timestamp": ""2015-02-03T00:01:48+00:00"",
    "error": "",
    "data": [
        {
            "pair": "BTC_USD",
            "asks": [{price: "212.962", volume: "0.014"}, {price: "213", volume: "1.46820994"}],
            "bids": [{price: "212.885", volume: "0.014"}, {price: "212.827", volume: "0.00414864"]}
         }
    ]
}
```

#### Arguments

* `options`

    Parameter  |  Type  | Required    | Description |
     ---	   | ---    |   :-:       | ---         |
    `pair`     | string |All exchanges| trading pair|

* `callback` see [Callbacks](#callbacks)

#### Response

Parameter   |  Type   |Required| Description                       |
 ---	    | ---     | :-:    | ---                               |
`pair`      | String  |  Yes   | trading pair                      |
`asks`      | Array   |  Yes   | list of asks in the order book    |
`bids`      | Array   |  Yes   | list of bids in the order book    |

### getTrades

Returns a list of the most recent trades.

```js
cryptox.getTrades(options, callback);
```

#### Example

```js
exchange.getTrades({pair: "BTC_USD"}, function (err, trades) {
    if (!err)
        console.log(trades);
});
```

Example result:
```js
{
  timestamp: "2016-10-09T08:06:30Z",
  error: "",
  data: [
    {
      pair: "BTC_USD",
      trades: [
        {
          timestamp: "2016-10-09T08:05:17Z",
          trade_id: "11298830",
          price: "618.34000000",
          amount: "0.01000000",
          type: "buy"
        },
        {
          timestamp: "2016-10-09T07:31:16Z",
          trade_id: "11298732",
          price: "618.26000000",
          amount: "0.87449356",
          type: "sell"
        }
      ]
    }
  ]
}
```

#### Arguments

* `options`

    Parameter  |  Type  | Required    | Description |
     ---	   | ---    |   :-:       | ---         |
    `pair`     | string |All exchanges| trading pair|

* `callback` see [Callbacks](#callbacks)

#### Response

Parameter   |  Type   |Required| Description                       |
 ---	    | ---     | :-:    | ---                               |
`pair`      | String  |  Yes   | trading pair                      |
`trades`    | Array   |  Yes   | list of asks in the order book    |

### getFee

```js
getFee(options, callback);
```
Returns the fee, which is a float that represents the amount the exchange takes out of the orders.

#### Example

```js
account.getFee({pair: "XBT_USD"}, function (err, fee) {
    if (!err)
	    console.log(fee);
});
```
Example result:
```js
{
	timestamp: "2015-02-01T20:59:53+00:00",
	data: [
	   {
		  pair: "XBT_USD",
		  maker_fee: "0",
		  taker_fee: "0.002"
	   }
	]
}
```

#### Arguments

* `options`

    Parameter  |  Type  | Required    | Description |
     ---	   | ---    |   :-:       | ---         |
    `pair`     | string |All exchanges| trading pair|

* `callback` see [Callbacks](#callbacks)

#### Response

Parameter                     |  Type  |Description                                                    |
 ---	                      | ---    |---                                                            |
`pair`                        | String |the trading pair or `""` if the fee is applicable for all pairs|
`maker_fee` [1] [2]| String |the amount (%) the exchange takes out of limit orders          |
`taker_fee` [1] [2]| String |the amount (%) the exchange takes out of orders that match immediately|

>[1] `"maker"` fees are paid when you add liquidity to the orderbook, by placing a limit order under the ticker price for buy and above the ticker price for sell. `"taker"` fees are paid when you remove liquidity from the orderbook, by placing any order that is executed against an order of the orderbook.  if `type` is `""`, the fee is applicable both for maker and taker
>[2] If an exchange has a fee of 0.2% the fee would be `0.002`

### getTransactions

```js
getTransactions(options, callback);
```
Returns user transaction history. Transactions are returned in descending order (newer transactions first).
> Note: Depending on the exchange used and parameter combination this method can require up to 10 API calls

#### Example

```js
account.getTransactions({limit: 2, sort: "desc"}, function (err, transactions) {
    if (!err)
	    console.log(transactions);
});
```
Example result:
```js
{
    {
    "timestamp": "2015-02-25T22:37:19+00:00",
    "error": "",
    "data": [
        {
            "tx_id": "7624780",
            "datetime": "2015-02-24T12:02:27+00:00",
            "type": "sell",
            "symbol": "XBT_USD",
            "amount_base": "-0.30183411",
            "amount_counter": "72.62",
            "rate": "240.6",
            "fee_base": "0",
            "fee_counter": "0.15",
            "order_id": "58025817",
            "add_info": ""
        },
        {
            "tx_id": "7624695",
            "datetime": "2015-02-24T11:45:26+00:00",
            "type": "deposit",
            "symbol": "XBT",
            "amount_base": "49.04253049",
            "amount_counter": "0",
            "rate": "0",
            "fee_base": "0",
            "fee_counter": "0",
            "order_id": "",
            "add_info": ""
        }
    ]
}
```

#### Arguments

* `options`

    Parameter |  Type  | Required | Description |
     ---	  | ---    |   :-:    | ---         |
    `limit`   | Number |   no     | limit result to that many transactions. Default: `50`|
    `skip`    | Number |   no     | skip that many transactions before beginning to return results|
    `after`   | String |   no     | return only transactions after or at the time specified here (ISO 8601 string)|
    `before`  | String |   no     | return only transactions before or at the time specified here (ISO 8601 string)|
    `type`    | String |   no     | return only transactions of this type [1]. Default return all transactions|
    `symbol`  | String |   no     | return only transactions related to this curency symbol or curency pair |

    >[1] valid values are `"trades"` (for buys or sells) or `"movements"` (for deposits and withdrawals)
    >[2] valid values are currecny symbols (3 characters) or trading pair symbols (6 characters).

* `callback` see [Callbacks](#callbacks)

#### Response

Parameter       | Type | Description|
 ---	        | ---  |---        |
`tx_id`         |String| transaction ID |
`datetime`      |String| ISO 8601 date & time of the transaction |
`type`          |String| transaction type: `"buy"`, `"sell"`, `"deposit"`, `"withdrawal"` |
`symbol`        |String| currency symbol [1] or currency pair [2]|
`amount_base`   |String| currency amount [1] or base currency amount [3] [4]|
`amount_counter`|String| counter currency amount [3] [4]|
`rate`          |String| zero (`0`) [1] or the exchange rate [2] [3]|
`fee_base`      |String| amount of the fees debited |
`fee_counter`   |String| amount of the fees debited |
`order_id`      |String| the id of the parent order of the trade. Can be `""` |
`add_info`      |String| additional info. Can be `""` |

>[1] for single currency transaction (`"deposit"` or `"withdrawal"`)
>[2] for trades / pair transaction (`"buy"` or `"sell"`)
>[3] See [Currency Pairs](#currency-pairs)
>[3] The `amount_base` and `amount_counter` are the amounts that were traded after the fees were deducted. These are the amounts that were credited/debited from your account

### getBalance

```js
getBalance(options, callback);
```
Returns the account balance.

#### Example

```js
account.getBalance({}, function (err, balance) {
    if (!err)
	    console.log(balance);
});
```
Example result:
```js
{
    timestamp: "2015-02-06T17:53:02+00:00",
    error: "",
    data: [
        {
            account_id: "8274332321",
            total: [
                {currency: "XBT", amount: "4.86509177"},
                {currency: "USD", amount: "100.44"}
            ],
            available: [
                {currency: "XBT", amount: "2.86709177"},
            ]
        }
    ]
}
```

#### Arguments

* `options` argument is not used and it is ignored, except for poloniex. For poloniex `{ account: 'all' }` can be used for summing up the balances of all accounts (exchange, margin and lending)

* `callback` see [Callbacks](#callbacks)

#### Response

Parameter   | Type  | Description|
 ---	    | ---   |---        |
`account_id`| String| account ID / name |
`total`     | Array | account balance |
`available` | Array | funds available for trading (balance minus funds reserved in open orders. For margin accounts the leverage is taken into consideration, hence `available` can be higher than `total`)

### getMarginPositions

```js
getMarginPositions(options, callback);
```
Returns the account balance.

#### Example

```js
account.getMarginPositions({pair: BTC_USD}, function (err, marginPositions) {
    if (!err)
	    console.log(balance);
});
```
Example result:
```js
{
    timestamp: "2015-02-06T17:53:02+00:00",
    error: "",
    data: [
        {
        }
    ]
}
```

#### Arguments

* `options`

	Parameter   | Type  | Description|
	 ---	    | ---   |---
	`pair`      | String| trading pair (optional)

* `callback` see [Callbacks](#callbacks)

#### Response

Parameter   | Type  | Description|
 ---	    | ---   |---        |
`pair`| String| account ID / name |
`total`     | Array | account balance |
`available` | Array | funds available for trading (balance minus funds reserved in open orders. For margin accounts the leverage is taken into consideration, hence `available` can be higher than `total`)

### getOpenOrders

```js
getOpenOrders(options, callback);
```
Returns the open orders.

#### Example

```js
account.getOpenOrders({pair: "LTC_USD"}, function (err, openOrders) {
    if (!err)
	    console.log(openOrders);
});
```
Example result:
```js
{
    "timestamp": "2015-02-03T00:03:27+00:00",
    "error": "",
    "data": [
        {
            "order_id": "563489985",
            "pair": "LTC_USD",
            "type": "buy",
            "amount": "1",
            "rate": "0.1",
			"margin": true,
            "created_at": "2015-02-01T19:23:15+00:00",
            "status": "0"

        },
        {
            "order_id": "563612426",
            "pair": "LTC_USD",
            "type": "buy",
            "amount": "2",
            "rate": "0.5",
			"margin": false,
            "created_at": "2015-02-01T20:59:53+00:00",
            "status": "0"

        }
    ]
}
```

#### Arguments

* `options`

* `callback` see [Callbacks](#callbacks)

#### Response

Parameter   | Type  | Description|
 ---	    | ---   |---
`order_id`  | String| order ID
`pair`      | String| trading pair
`type`      | String| order type (`buy`, `sell`)
`amount`    | String| trading amount
`rate`      | String| rate
`margin`    | Boolean| margin trading order
`created_at`| String| date&time when order was created, ISO 8601 string

Optional response parameters

Parameter / Availability |  Type   | Description
 ---	                 | ---     | ---
`status`                 | Number  | order status [1]

> [1] BTC-e API description doesn't clarify what status value means

### postSellOrder
```js
postSellOrder(options, callback);
```
Posts a sell order.

#### Example

```js
account.postSellOrder({pair: "ETH_BTC"}, function (err, order) {
    if (!err)
	    console.log(openOrders);
});
```
Example result:
```js
{
    "timestamp": "2015-02-03T00:03:27+00:00",
    "error": "",
    "data": [
        {
            "order_id": "563489985",
            "created_at": "2015-02-01T19:23:15+00:00",

        }
    ]
}
```

#### Arguments

* `options`

	Parameter   | Type  | Description|
	 ---	    | ---   |---
	`pair`      | String| trading pair
	`amount`    | String| trading amount
	`rate`      | String| rate
	`margin`    | Boolean| margin trading order

* `callback` see [Callbacks](#callbacks)

#### Response

Parameter    |  Type   | Description
---	         | ---     | ---
`order_id`   | String  | order ID
`created_at` | String  | date&time when order was created, ISO 8601 string

### postBuyOrder

Same as for `postSellOrder()` method

### cancelOrder

```js
cancelOrder(options, callback);
```
Posts a sell order.

#### Example

```js
account.cancelOrder({order_id: "123456789"}, function (err, order) {
    if (!err)
	    console.log(openOrders);
});
```
Example result:
```js
{
    "timestamp": "2015-02-03T00:03:27+00:00",
    "error": "",
    "data": []
}
```

#### Arguments

* `options`

    Parameter  |  Type  | Required    | Description |
     ---	   | ---    |   :-:       | ---         |
    `order_id` | string |All exchanges| currecny    |

* `callback` see [Callbacks](#callbacks)

#### Response

Parameter   | Type  | Description|
 ---	    | ---   |---

### getLendBook

Returns the lend book.
Note that multiple asks/bids at the same rate are not necessarily conflated.

```js
cryptox.getOrderBook(options, callback);
```

#### Example

```js

exchange.getLendBook({currency: "USD"}, function (err, orderBook) {
    if (!err)
        console.log(lendBook);
});
```
Example result:
```js
{
	"timestamp": "2015-03-14T16:49:12+00:00",
	"error": "",
	"data": [
		{
			"currency": "USD",
			"asks": [
				{
					"rate": "36.5",
					"amount": "1441.80137112",
					"period": 2,
					"frr": "yes"
					"created_at": "2015-03-14T16:32:17+00:00",
				}
			],
			"bids": [
				{
					"rate": "32.8573",
					"amount": "6163.37130384",
					"period": 30,
					"frr": "no"
					"created_at": "2015-03-14T15:27:38+00:00",
				}

			]
		}
	]
}
```

#### Arguments

* `options`

    Parameter  |  Type  | Required    | Description |
     ---	   | ---    |   :-:       | ---         |
    `currency` | string |All exchanges| currecny    |

* `callback` see [Callbacks](#callbacks)

#### Response

Parameter   | Type |Required| Description                  |
 ---	    | ---  | :-:    | ---                          |
`asks`      |Array |  Yes   | loan offers                  |
`bids`      |Array |  Yes   | loan demands                 |
`rate`      |String|  Yes   | rate in % **per 365 days**   |
`amount`    |String|  Yes   | amount                       |
`period`    |Number|  Yes   | maximum no of days for the loan offers or minimum no of days for the demand offers   |
`frr`       |String|  Yes   | `"yes"` if the offer is at Flash Return Rate, `"no"` if the offer is at fixed rate |
`created_at`|String|  Yes   | date&time when offer was created, ISO 8601 string    |

### getActiveOffers

### postOffer

### cancelOffer

### Native API calls

cryptox supports native API methods.
The parameter and callback results are as described in the follwoing packages:

* Bitfinex: https://github.com/bitfinexcom/bitfinex-api-node
* Bitstamp: https://github.com/askmike/bitstamp
* BitX: https://github.com/bausmeier/node-bitx
* BTC-e: https://github.com/pskupinski/node-btc-e
* Gdax: https://github.com/coinbase/gdax-node
* Poloniex: https://github.com/dutu/poloniex-api-node

#### Example

```js
var btce = new Cryptox("btce");
btce.native.ticker("ltc_btc", function(err, data) {
  console.log(err, data);
});
```

## Notes ##

### Currency Symbols ###
cryptox uses [ISO 4217 currency codes](http://en.wikipedia.org/wiki/ISO_currency_code) for fiat currencies and 3 letter symbols for cryptocurrencies

Currency | Symbol
---------|-------
Auroracoin | AUR
**Bitcoin**	   | **XBT** [1]
BlackCoin  | BLK
Darkcoin   | DRK
Dogecoin   | DGE
Gridcoin   | GRC
Litecoin   | LTC
Mastercoin | MSC
MazaCoin   | MZC
Monero     | XMR
Namecoin   | NMC
Nxt        | NXT
Peercoin   | PPC
PotCoin    | POT
Primecoin  | XPM
Ripple     | XRP
Titcoin    | TIT

> [1] See [FAQ](faq.md)

### Currency Pairs ##

The first currency of a currency pair is called the "base currency", and the second currency is called the "counter currency". The currency pair shows how much of the counter currency is needed to purchase one unit of the base currency.

In example below the last price of the XBT_USD currency pair is 272.064.

```js

    "timestamp": "2015-02-03T00:01:48+00:00",
    "error": "",
    "data": [
        {
            "pair": "XBT_USD",
            "last": 272.064,
            "bid": 272.064,
            "ask": 273.395,
            "volume": 7087.93047
        }
     ]
}

```

This means that 1 Bitcoin was exchanged for 272.006 US dollars.


text:
module BohFoundation.Admin.Spec.Services {
    describe('AdminNotificationService', () => {
        var service;
        var authRequiredRepo, alertHelper;

        beforeEach(() => {
            authRequiredRepo = sinon.stub({
                get:()=>{}
            });

            alertHelper = sinon.stub({
                addDangerAlert:()=>{}
            });

            service = new Admin.Services.AdminNotificationService(authRequiredRepo, alertHelper);
        });

        describe('getNotifications', () => {
            var result;
            var data = 1193;

            beforeEach(() => {
                authRequiredRepo.get.returns(data);
                result = service.getNotifications();
            });

            it('should call authRequiredRepo with /api/admin/notifications.', () => {
                sinon.assert.calledWith(authRequiredRepo.get, '/api/admin/notifications');
            });

            it('should call authRequiredRepo with /api/admin/notifications.', () => {
                expect(result).toBe(data);
            });
        });

        describe('getNotifications', () => {
            describe('error', () => {
                beforeEach(() => {
                    service.resolveNotifications(new Common.Models.ServerResponseModel(null, false));
                });

                it('should call the alert helper danger method.', () => {
                    sinon.assert.calledWith(alertHelper.addDangerAlert, "There was an error getting your admin notifications.");
                });
            });

            describe('success', () => {
                var pendingApplicationEvaluators = 2;
                var totalCount = pendingApplicationEvaluators;

                var dataFromServer = { pendingApplicationEvaluators: pendingApplicationEvaluators, totalCount: totalCount}

                beforeEach(() => {
                    service.resolveNotifications(new Common.Models.ServerResponseModel(dataFromServer, true));
                });

                it('should assign pendingApplicationEvaluators to adminNotificationCounts.', () => {
                    expect(service.adminNotificationCounts.pendingApplicationEvaluators).toBe(pendingApplicationEvaluators);
                });

                it('should assign totalCount to adminNotificationCounts.', () => {
                    expect(service.adminNotificationCounts.totalCount).toBe(totalCount);
                });
            });
        });

        describe('getNumberOfTotalNotifications', () => {
            var totalCounts = 291;

            it('should return 0 is adminNotificationCounts is undefined.', () => {
                service.adminNotificationCounts = undefined;
                expect(service.getNumberOfTotalNotifications()).toBe(0);
            });

            it('should return the total count.', () => {
                service.adminNotificationCounts = new Dtos.Admin.AdminNotificationCounts(totalCounts, null);
                expect(service.getNumberOfTotalNotifications()).toBe(totalCounts);
            });
        });

        describe('getNumberOfPendingApplicationEvaluators', () => {
            var pendingApplicationEvaluators = 29123;

            beforeEach(() => {
                service.adminNotificationCounts = new Dtos.Admin.AdminNotificationCounts(null, pendingApplicationEvaluators);
            });

            it('should return the total count.', () => {
                expect(service.getNumberOfPendingApplicationEvaluators()).toBe(pendingApplicationEvaluators);
            });

            it('should return 0 is adminNotificationCounts is undefined.', () => {
                service.adminNotificationCounts = undefined;
                expect(service.getNumberOfPendingApplicationEvaluators()).toBe(0);
            });
        });
    });
}


text:
//Dark sky key
var secretKey = "0/";

function getQueryStringParameter(urlParameterKey) {
    var params = document.URL.split('?')[1].split('&');
    var strParams = '';
    for (var i = 0; i < params.length; i = i + 1) {
        var singleParam = params[i].split('=');
        if (singleParam[0] == urlParameterKey)
            return decodeURIComponent(singleParam[1]);
    }
}

(function () {
    "use strict";

    $("#perHour").hide();
    $("#minMax").hide();
    $("#details").hide();

    var location = getQueryStringParameter("location");
    var locationUrl = setLocation(location);
    var getUnit = getQueryStringParameter("unit");

    // hämta väderdata från localStorage
    var weatherData = JSON.parse(localStorage.getItem("weatherdata"));

    // om webbläsaren inte har kunnat läsa in väderdata från localstorage
    if (weatherData === null) {
        getWeatherData(getUnit, locationUrl);
    }
    else {
        showDetails(getUnit, weatherData);
        showHourly(getUnit, weatherData);
        showMinMax(getUnit, weatherData);
    }

    // När all data laddats in, visa detaljerna
    $("#details").show();
}());

$("#minMaxTab").click(function () {
    $("#perHour").hide();
    $("#minMax").show();
    $("#details").hide();
});

$("#perHourTab").click(function () {
    $("#perHour").show();
    $("#minMax").hide();
    $("#details").hide();
});

$("#detailsTab").click(function () {
    $("#perHour").hide();
    $("#minMax").hide();
    $("#details").show();
});

//Appens logik

function getCelsius(temp) {
    var celsius = temp;
    return (celsius - 32) / 1.8000;
}

function getTempSymbol(unit) {
    unit = parseInt(unit);

    switch (unit) {
        case 1:
            return "°C";
        default:
            return "°F";
    }
}

// anropa dark sky om det inte finns väderdata sparad i localhost
function getWeatherData(getUnit, locationUrl) {

    var errorMessage = "";
    var weatherData = "";

    $.ajax({
        METHOD: "GET",
        dataType: "jsonp",
        crossDomain: true,
        url: locationUrl,
        success: function (data) {
            weatherData = data;
        },
        failure: function () {
            errorMessage = "Det gick inte att visa väderuppgifterna just nu. Vänligen försök senare";
            $("#errorMessage").text(errorMessage);
        },
        complete: function (weatherTemp) {
            if (errorMessage === "") {
                // visa detaljer
                showDetails(getUnit, weatherData);
                // visa prognos med min/max temperatur
                showMinMax(getUnit, weatherData);
                // visa temperatur / timme för innevarande dygn
                showHourly(getUnit, weatherData);
            }
        }
    });
}

function getWindSymbol(unit) {
    unit = parseInt(unit);

    switch (unit) {
        case 1:
            return "m/s";
        default:
            return "MPH";
    }
}

function setLocation(location) {

    var city = {
        Stockholm: {
            longitude: "18.00",
            latitude: "59.00"
        },
        Gothemburg: {
            longitude: "11.97",
            latitude: "57.7"
        },
        Malmo: {
            longitude: "13",
            latitude: "55.6"
        }
    };
    var locationInt = parseInt(location);

    var forecastURL = "https://api.darksky.net/forecast/" + secretKey;
    var position = "";
    switch (locationInt) {
        case 1: {
            position = forecastURL + city.Stockholm.latitude + "," + city.Stockholm.longitude;
            $("#cityLocation").text("Stockholm");
            break;
        }
        case 2: {
            position = forecastURL + city.Gothemburg.latitude + "," + city.Gothemburg.longitude;
            $("#cityLocation").text("Göteborg");
            break;
        }
        case 3: {
            position = forecastURL + city.Malmo.latitude + "," + city.Malmo.longitude;
            $("#cityLocation").text("Malmö");
            break;
        }
    }
    return position;
}

// visa detaljerna
function showDetails(getUnit, weatherData) {
    "use strict";

    var details = weatherData.currently;
    getUnit = parseInt(getUnit);

    var isCelsius = (getUnit === 1) ? true : false;
    var windDirection = translatewindBearing(details.windBearing);
    var windUnit = getWindSymbol(getUnit);
    var windSpeed = "";
    var temperatur = "";
    var tempUnit = getTempSymbol(getUnit);

    if (isCelsius) {
        temperatur = getCelsius(details.temperature);
        windSpeed = details.windSpeed / 2.236936;
    }
    else {
        temperatur = details.temperature;
        windSpeed = details.windSpeed;
    }

    $("#windSpeedHeadline").text("Vindhastighet " + windUnit);
    $("#temperaturHeadline").html("Temperatur " + tempUnit);

    $('#temp').html(temperatur.toFixed(1));
    $('#ozone').text(details.ozone);
    $('#windSpeed').html(windSpeed.toFixed(0));
    $('#windBearing').html(windDirection);
    $('#humidity').html(details.humidity * 100);
    $('#pressure').html(details.pressure);

    $("#details").show();

}

// visa prognos med kommande 5 dagars max/min-temperatur
function showMinMax(getUnit, weatherData) {
    "use strict";

    var mmt = weatherData.daily.data;
    getUnit = parseInt(getUnit);

    var isCelsius = (getUnit === 1) ? true : false;
    var maxTemp = [];
    var minTemp = [];
    var time = [];

    // börja på 1 = imorgon och fortsätt 5 dagar fram
    for (var index = 1; index <= 5; index++) {
        time.push(moment.unix(mmt[index].time).format("dddd"));

        if (isCelsius) {
            minTemp.push(getCelsius(mmt[index].temperatureMin).toFixed(1));
            maxTemp.push(getCelsius(mmt[index].temperatureMax).toFixed(1));
        }
        else {
            minTemp.push(mmt[index].temperatureMin.toFixed(1));
            maxTemp.push(mmt[index].temperatureMax.toFixed(1));
        }
    }

    var ctx = document.getElementById("minMaxTemp");

    var myChart = new Chart(ctx, {
        type: 'line',
        data: {
            labels: time,
            datasets: [{
                label: 'Lägsta temperatur',
                data: minTemp,
                fill: false,
                borderColor: "lightblue",
                backgroundColor: "lightblue",
                pointBorderColor: "blue",
                pointBackgroundColor: "blue",
                pointBorderWidth: 1
            },
            {
                data: maxTemp,
                label: "Högsta temperatur",
                fill: false,
                borderColor: "coral",
                backgroundColor: "coral",
                pointBorderColor: "tomato",
                pointBackgroundColor: "tomato",
                pointBorderWidth: 1,
                showTooltip: false,
            }]
        }
                ,

        options: {
            responsive: true,
            scales: {
                yAxes: [{
                    ticks: {
                        beginAtZero: true
                    }
                }]
            }
        }
    });
}

function showHourly(getUnit, weatherData) {
    "use strict";

    var phf = weatherData.hourly.data;
    getUnit = parseInt(getUnit);

    var foreCastDay = moment.unix(phf[0].time).format("dddd"); // används med timeNow för att veta när man loopat igenom innevarande dygn
    var isCelsius = (getUnit === 1) ? true : false;
    var index = 0;
    var perHourTemp = [];
    var time = [];
    var timeNow = moment.unix(weatherData.currently.time).format("dddd"); // kontrollera vilken dag det är nu
    var tempSymbol = getTempSymbol(getUnit);

    // hämta temperatur / timme för innevarande dygn
    while (timeNow === foreCastDay) {

        time.push(moment.unix(phf[index].time).format("HH"));

        perHourTemp.push(isCelsius ? getCelsius(phf[index].temperature).toFixed(1) : phf[index].temperature.toFixed(1));

        foreCastDay = moment.unix(phf[index].time).format("dddd");
        index++;
    }

    var ctxPerHour = document.getElementById("perHourChart");

    var myChart = new Chart(ctxPerHour, {
        type: 'line',
        data: {
            labels: time,
            datasets: [{
                label: 'Temperatur per timme under senaste dygnet',
                data: perHourTemp,
                fill: false,
                borderColor: "lightgreen",
                backgroundColor: "lightgreen",
                pointBorderColor: "green",
                pointBackgroundColor: "green",
                pointBorderWidth: 1
            }]
        },
        options: {
            responsive: true,
            scales: {
                yAxes: [{
                    ticks: {
                        beginAtZero: true
                    }
                }]
            }
        }
    });
}

// översätt gradantalet till vindriktning
function translatewindBearing(input) {
    "use strict";

    var value = parseInt(input);

    var windBearing = "";

    if (value === 0) { windBearing = "nordlig"; }
    else if (value > 0 && value <= 45) { windBearing = "nord / nordost"; }
    else if (value > 45 && value < 90) { windBearing = "ost / nordost"; }
    else if (value > 90 && value < 180) { windBearing = "syd / sydost"; }
    else if (value === 180) { windBearing = "sydlig"; }
    else if (value > 180 && value < 270) { windBearing = "syd / sydväst"; }
    else if (value === 270) { windBearing = "västlig"; }
    else if (value > 270 && value < 360) { windBearing = "nord / nordväst"; }
    else { return "vindstilla"; }

    return windBearing;
}


text:
package com.github.sarxos.webcam;

import java.awt.image.BufferedImage;

public interface WebcamImageTransformer {

	BufferedImage transform(BufferedImage image);

}


text:
<?php
//defined('BASEPATH') OR exit('No direct script access allowed');
/**
 * ****************************************************************************************************
 * CLASE NOTIFICATION
 * *****************************************************************************************************
 * HISTORIA: HU021 - 22 - 23 -24 - 25
 * TITULO: Notificacion de usuario Usuario comedor
 * ****************************************************************************************************
 */
class Notification extends CI_Email
{

    // Constantes
    const url_mail      = 'http://localhost/suc_web/login/logout';
    const url_mail_mod  = 'email/notification_changes_user_data.php';
    const url_mail_new  = 'email/notification_new_user.php';
    const sender        = 'suc@no-reply.com';
    const send_des      = 'Sistema ušnico de Comedores';
    const tit_mail_mod  = 'Modificación de datos usuario';

    // Variables
    private $variables;
    private $config;

    // Salida

    /**
     * Constructor - Sets Email Preferences
     *
     * The constructor can be passed an array of config values
     *
     * @param array $config
     *            = array()
     * @return void
     */
    public function __construct ()
    {
        //$this->load->library('email');
        parent::__construct();
    }

    /**
     * _Send_mail - Envio de mail para notificaciones
     *
     * Da formato al envio de mail para notificaciones Usuario
     *
     * @param array $user_mail
     *            = array()
     * @param $type (Tipo
     *            de mail HTML o TEXT)
     * @param $action Alta
     *            baja o modificacion de datos de usuario
     * @return BOOL
     */
    public function _send_mail (
            array $mail_user = array ('mail', 'name', 'alias', 'pass'), $mail_type = 'html', $action, $mail_body)
    {
        // Inicializar Objeto
        $this->clear();
        $this->set_mailtype($mail_type);

        // Valido el Mail, si no valida devuelvo error
        if (! $this->valid_email($user_mail['mail'])) {
            throw new Exception("Verificar el Mail: " . $mail_user['mail']);
        }

        switch ($action) {
            case 'PUT':
                $this->set_mail_modif($mail_user);
                break;
            case 'POST':
                $this->set_mail_new($mail_user);
                break;
            case 'DELETE':
                $this - set_ > mail_del($mail_user);
                break;
            default:
                throw new Exception("Acción erronea");
        }

        //Envio de mail
        $flag_mail = $this->send();

        // Verificación de envio
        if ($flag_mail == TRUE) {
            return $flag_mail;
        } elseif ($flag_mail == FALSE) {
            throw new Exception("Verificar el Mail: " . $mail_user['mail']);
        } else {
            throw new Exception(
                    "Ocurrio un error, verifique la resepcion del mismo.");
        }
    }

    /**
     * set_mail_html_modif - Modificación datos personales
     *
     * Mail por cambio en los datos de usuario
     *
     * @param array $user_mail = array()
     */
    private function set_mail_html_modif (
            array $mail_user = array ('mail', 'name', 'alias', 'pass'), $mail_body)
    {
        $this->subject('Modificación datos personales');
        $body = $mail_body->view(url_mail_mod, $mail_user, TRUE);
        $this->message($body); // adjunto el php al cuerpo del mail
        $this->set_newline("\r\n"); // Sin esta liñea falla el envio
    }

    /**
     * set_mail_html_new - Alta de usuario en sistema
     *
     * Mail que informa el alta en el sistema
     *
     * @param array $user_mail = array()
     */
    private function set_mail_html_new (
            array $mail_user = array ('mail', 'name', 'alias', 'pass'), $mail_body)
    {
        $this->subject('Alta de usuario - Bienvenido');
        $body = $mail_body->view(url_mail_new, $mail_user, TRUE);
        $this->message($body); // adjunto el php al cuerpo del mail
        $this->set_newline("\r\n"); // Sin esta liñea falla el envio
    }

    /**
     * set_mail_html_del - Baja de usuario en sistema
     *
     * Mail que informa la baja en el sistema
     *
     * @param array $user_mail = array()
     */
    private function set_mail_html_del (
            array $mail_user = array ('mail', 'name', 'alias', 'pass'), $mail_body)
    {
        $this->subject('Baja de sistema');
        $body = $mail_body->view(url_mail_del, $mail_user, TRUE);
        $this->message($body); // adjunto el php al cuerpo del mail
        $this->set_newline("\r\n"); // Sin esta liñea falla el envio
    }
}


text:
from django.shortcuts import render, redirect
from django.contrib.auth.decorators import login_required
from django.contrib.auth import authenticate, login, logout
from django.contrib.auth.models import User
from virtenviro.registration.models import UserProfile
from virtenviro.registration.forms import UserForm, UserProfileForm

def signup(request):
    """Регистрация"""
    user = User()
    user_profile = UserProfile()
    if request.method == "POST":
        user_form = UserForm(request.POST, instance=user)
        user_profile_form = UserProfileForm(request.POST, instance=user_profile)
        if user_form.is_valid() and user_profile_form.is_valid():
            user_data = user_form.cleaned_data
            user.username = user_data['email']
            user.first_name = user_data['firstname']
            user.last_name = user_data['lastname']
            user.email = user_data['email']
            user.set_password(user_data['pass1'])
            user.save()

            user_profile = user.get_profile()
            user_profile_data = user_profile_form.cleaned_data
            user_profile.weight = user_profile_data['weight']
            user_profile.save()
            user = authenticate(username=user_data['username'], password=user_data['pass1'] )
            login(request, user)
            return redirect("/accounts/profile/")
    else:
        user_form = UserForm( instance = user )
        user_profile_form = UserProfileForm( instance = user_profile )
    return render(request,
                  "accounts/signup.html",
                  {
                      "user_": user,
                      "user_profile": user_profile,
                      "user_form": user_form,
                      "user_profile_form": user_profile_form})

@login_required
def profile(request):
    """Профиль текущего пользователя"""
    user = request.user
    return render(request,
                  "accounts/card.html",
                  {
                      "user": user})

@login_required
def user_card(request):
    """Профиль текущего пользователя"""
    user = request.user
    return render(request,
                  "accounts/card.html",
                  {"user": user})

@login_required
def logout(request):
    goto = request.GET.get("goto", "/")
    return redirect(goto)


text:
appController.controller('setStoryCategoriesCtrl', ['$scope', '$rootScope', '$state', '$stateParams', '$ionicLoading', '$ionicScrollDelegate', '$ionicModal', '$ionicHistory', '$ionicSlideBoxDelegate', '$timeout', '$filter', 'localStorageService', 'ShareService', 'IonicService', 'Con', 'SectionEvent', 'MsgBox', function($scope, $rootScope, $state, $stateParams, $ionicLoading, $ionicScrollDelegate, $ionicModal, $ionicHistory, $ionicSlideBoxDelegate, $timeout, $filter, localStorageService, ShareService, IonicService, Con, SectionEvent, MsgBox) {
    // $rootScope.menuShow = true;
    // $rootScope.backShow = true;
    // Con.log($stateParams);
    Con.log('预览页面');
    // console.log($stateParams);
    // 用ifarme展示

    $scope.urlParams = JSON.parse($stateParams.storyInfo);
    console.log($scope.urlParams);

    // 三大类类别集合
    $scope.allCategories = JSON.parse($scope.urlParams.storycategories);
    // 品牌故事
    $scope.brandStoryCategories = null;
    $scope.brandStoryCategories = $filter('filter')($scope.allCategories, { "name": "品牌故事" })[0].categories;
    console.log($scope.brandStoryCategories);
    // 热点新闻
    $scope.hotNewsCategories = null;
    $scope.hotNewsCategories = $filter('filter')($scope.allCategories, { "name": "热点新闻" })[0].categories;
    console.log($scope.hotNewsCategories);
    // 生活故事
    $scope.lifeStoryCategories = null;
    $scope.lifeStoryCategories = $filter('filter')($scope.allCategories, { "name": "生活故事" })[0].categories;
    console.log($scope.lifeStoryCategories);
    //选中的类型数组
    $scope.activeCategories = $scope.urlParams.storycategory;
    console.log($scope.activeCategories);
    jQuery.each($scope.activeCategories, function(k, v) {
        $timeout(function() {
            jQuery('.categoriesWrap li[id=' + v.id + ']').addClass('active');
        })
    });
    // 后退历史
    $scope.goBackView = function() {
       var storyInfo = JSON.stringify($scope.urlParams);
        // 跳转到设置页面
        $state.go('tab.setStoryInfo', { storyInfo: storyInfo });
    }

    $scope.toggleClick = function(id) {
            var thisJqObj = jQuery('.categoriesWrap li[id=' + id + ']');
            var selectedLen = thisJqObj.parents('.categoriesWrap').find('li.active').length;
            console.log(thisJqObj.parents('.categoriesWrap').find('li.active'))
            console.log(selectedLen)
            if (thisJqObj.hasClass('active')) {
                thisJqObj.removeClass('active');
            } else {
                if (selectedLen >= 3) {
                    MsgBox.showTexts('每个类型最多只能选3个标签!')
                } else {
                    thisJqObj.addClass('active');
                }
            }
        }
        // $scope.storycategories = JSON.parse($scope.urlParams.storycategories);
        // console.log($scope.storycategories)
    $scope.setCategory = function() {
        var categories = jQuery('.categoriesWrap li.active');
        // console.log(categories);
        var storyCategoryArr = [];
        console.log(categories)
        jQuery.each(categories, function(k, v) {
            var storyCategory = {id:jQuery(v).attr('id'),name:jQuery(v).text()};
            storyCategoryArr.push(storyCategory);
        });
        // console.log(storyCategoryArr)
        // var idStrings = idArr.toString();
        $scope.urlParams.storycategory=storyCategoryArr;
        // console.log($scope.urlParams);
        var storyInfo = JSON.stringify($scope.urlParams);
        // 跳转到设置页面
        $state.go('tab.setStoryInfo', { storyInfo: storyInfo });
        // $scope.storyInfo = {
        //     puburl: $scope.urlParams.puburl,
        //     storyId: $scope.urlParams.storyId,
        //     title: $scope.urlParams.title,
        //     description: $scope.urlParams.description,
        //     logo: $scope.urlParams.logo,
        //     storycategory: data.storycategory,
        //     storycategories: $scope.urlParams.storycategories
        // }
    }
}]);