text:
// Copyright 2019 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "services/image_annotation/annotator.h"

#include <algorithm>
#include <tuple>
#include <utility>

#include "base/base64.h"
#include "base/bind.h"
#include "base/containers/contains.h"
#include "base/containers/cxx20_erase.h"
#include "base/feature_list.h"
#include "base/json/json_reader.h"
#include "base/json/json_writer.h"
#include "base/location.h"
#include "base/logging.h"
#include "base/no_destructor.h"
#include "base/strings/string_split.h"
#include "components/google/core/common/google_util.h"
#include "net/base/load_flags.h"
#include "net/base/net_errors.h"
#include "net/traffic_annotation/network_traffic_annotation.h"
#include "services/image_annotation/image_annotation_metrics.h"
#include "services/network/public/cpp/resource_request.h"
#include "services/network/public/mojom/url_response_head.mojom.h"
#include "url/gurl.h"

namespace image_annotation {

namespace {

constexpr size_t kImageAnnotationMaxResponseSize = 1024 * 1024;  // 1MB.
constexpr size_t kServerLangsMaxResponseSize = 1024;             // 1KB.

// For a given source ID and requested description language, returns the unique
// image ID string that can be used to look up results from a server response.
std::string MakeImageId(const std::string& source_id,
                        const std::string& desc_lang_tag) {
  return source_id + (desc_lang_tag.empty() ? "" : " " + desc_lang_tag);
}

std::string NormalizeLanguageCode(std::string language) {
  // Remove anything after a comma, in case we got more than one language
  // like "de,de-DE".
  language = language.substr(0, language.find(','));

  // Split based on underscore or dash so that we catch both
  // "zh_CN" and "zh-CN".
  const std::vector<std::string> tokens = base::SplitString(
      language, "-_", base::KEEP_WHITESPACE, base::SPLIT_WANT_NONEMPTY);

  if (tokens.size() == 0)
    return "";

  // Normalize the language portion to lowercase.
  const std::string language_only = base::ToLowerASCII(tokens[0]);

  // For every language other than "zh" (Chinese), return only the language
  // and strip the locale. Image descriptions don't changed based on locale,
  // but zh-CN and zh-TW use different character sets.
  if (tokens.size() == 1 || language_only != "zh") {
    // For the case of Hebrew, Chrome uses "he" but vss uses "iw" internally.
    // For Norwegian, vss uses "no" for all variants.
    if (language_only == "he") {
      return "iw";
    } else if (language_only == "nb" || language_only == "nn") {
      return "no";
    }
    return language_only;
  }

  // Normalize the locale to uppercase.
  std::string locale_only = base::ToUpperASCII(tokens[1]);

  // Map several Chinese locales to the two most common ones used for
  // Simplified and Traditional.
  if (locale_only == "CN" || locale_only == "HANS" || locale_only == "SG") {
    return "zh-CN";
  } else if (locale_only == "TW" || locale_only == "HANT" ||
             locale_only == "MO" || locale_only == "HK") {
    return "zh-TW";
  }

  return "zh";
}

// The server returns separate OCR results for each region of the image; we
// naively concatenate these into one response string.
//
// Returns a null pointer if there is any unexpected structure to the
// annotations message.
mojom::AnnotationPtr ParseJsonOcrAnnotation(const base::Value& ocr_engine,
                                            const double min_ocr_confidence) {
  if (!ocr_engine.is_dict())
    return mojom::AnnotationPtr(nullptr);

  // No OCR regions is valid - it just means there is no text.
  const base::Value* const ocr_regions = ocr_engine.FindKey("ocrRegions");
  if (!ocr_regions) {
    ReportOcrAnnotation(1.0 /* confidence */, true /* empty */);
    return mojom::Annotation::New(mojom::AnnotationType::kOcr, 1.0 /* score */,
                                  std::string() /* text */);
  }

  if (!ocr_regions->is_list())
    return mojom::AnnotationPtr(nullptr);

  std::string all_ocr_text;
  int word_count = 0;
  double word_confidence_sum = 0.0;
  for (const base::Value& ocr_region : ocr_regions->GetListDeprecated()) {
    if (!ocr_region.is_dict())
      continue;

    const base::Value* const words = ocr_region.FindKey("words");
    if (!words || !words->is_list())
      continue;

    std::string region_ocr_text;
    for (const base::Value& word : words->GetListDeprecated()) {
      if (!word.is_dict())
        continue;

      const base::Value* const detected_text = word.FindKey("detectedText");
      if (!detected_text || !detected_text->is_string())
        continue;

      // A confidence value of 0 or 1 is interpreted as an int and not a double.
      const base::Value* const confidence = word.FindKey("confidenceScore");
      if (!confidence || (!confidence->is_double() && !confidence->is_int()) ||
          confidence->GetDouble() < 0.0 || confidence->GetDouble() > 1.0)
        continue;

      if (confidence->GetDouble() < min_ocr_confidence)
        continue;

      const std::string& detected_text_str = detected_text->GetString();

      if (detected_text_str.empty())
        continue;

      if (!region_ocr_text.empty())
        region_ocr_text += " ";

      region_ocr_text += detected_text_str;
      ++word_count;
      word_confidence_sum += confidence->GetDouble();
    }

    if (!all_ocr_text.empty() && !region_ocr_text.empty())
      all_ocr_text += "\n";
    all_ocr_text += region_ocr_text;
  }

  const double all_ocr_confidence =
      word_count == 0 ? 1.0 : word_confidence_sum / word_count;
  ReportOcrAnnotation(all_ocr_confidence, all_ocr_text.empty());
  return mojom::Annotation::New(mojom::AnnotationType::kOcr, all_ocr_confidence,
                                all_ocr_text);
}

// Extracts annotations from the given description engine result into the second
// element of the return tuple.
//
// The first element of the return tuple will be true if the image was
// classified as containing adult content.
std::tuple<bool, std::vector<mojom::AnnotationPtr>> ParseJsonDescAnnotations(
    const base::Value& desc_engine) {
  static const base::NoDestructor<std::map<std::string, mojom::AnnotationType>>
      kAnnotationTypes({{"OCR", mojom::AnnotationType::kOcr},
                        {"CAPTION", mojom::AnnotationType::kCaption},
                        {"LABEL", mojom::AnnotationType::kLabel}});

  bool adult = false;
  std::vector<mojom::AnnotationPtr> results;

  if (!desc_engine.is_dict())
    return {adult, std::move(results)};

  // If there is a failure reason, log it and track whether it is due to adult
  // content.
  const base::Value* const failure_reason_value =
      desc_engine.FindKey("failureReason");
  if (failure_reason_value && failure_reason_value->is_string()) {
    const DescFailureReason failure_reason =
        ParseDescFailureReason(failure_reason_value->GetString());
    ReportDescFailure(failure_reason);
    adult = failure_reason == DescFailureReason::kAdult;
  }

  const base::Value* const desc_list_dict =
      desc_engine.FindKey("descriptionList");
  if (!desc_list_dict || !desc_list_dict->is_dict())
    return {adult, std::move(results)};

  const base::Value* const desc_list = desc_list_dict->FindKey("descriptions");
  if (!desc_list || !desc_list->is_list())
    return {adult, std::move(results)};

  for (const base::Value& desc : desc_list->GetListDeprecated()) {
    if (!desc.is_dict())
      continue;

    const base::Value* const type = desc.FindKey("type");
    if (!type || !type->is_string())
      continue;

    const auto type_lookup = kAnnotationTypes->find(type->GetString());
    if (type_lookup == kAnnotationTypes->end())
      continue;

    const base::Value* const score = desc.FindKey("score");
    if (!score || (!score->is_double() && !score->is_int()))
      continue;

    const base::Value* const text = desc.FindKey("text");
    if (!text || !text->is_string())
      continue;

    ReportDescAnnotation(type_lookup->second, score->GetDouble(),
                         text->GetString().empty());

    // For OCR, we allow empty text and unusual scores; at the time of writing,
    // a score of -1 is always returned for OCR.
    //
    // For other annotation types, we do not allow these cases.
    if (type_lookup->second != mojom::AnnotationType::kOcr &&
        (text->GetString().empty() || score->GetDouble() < 0.0 ||
         score->GetDouble() > 1.0))
      continue;

    results.push_back(mojom::Annotation::New(
        type_lookup->second, score->GetDouble(), text->GetString()));
  }

  return {adult, std::move(results)};
}

// Extracts annotations from the given icon engine result.
mojom::AnnotationPtr ParseJsonIconAnnotations(const base::Value& icon_engine) {
  mojom::AnnotationPtr result;
  if (!icon_engine.is_dict())
    return {};

  const base::Value* const icon_list = icon_engine.FindKey("icon");
  if (!icon_list || !icon_list->is_list())
    return {};

  for (const base::Value& icon : icon_list->GetListDeprecated()) {
    if (!icon.is_dict())
      continue;

    const base::Value* const icon_type = icon.FindKey("iconType");
    if (!icon_type || !icon_type->is_string())
      continue;

    std::string icon_type_value = icon_type->GetString();

    const base::Value* const score = icon.FindKey("score");
    if (!score || (!score->is_double() && !score->is_int()))
      continue;

    // Only return the first matching icon.
    auto type = mojom::AnnotationType::kIcon;
    return mojom::Annotation::New(type, score->GetDouble(), icon_type_value);
  }

  return {};
}

// Returns the integer status code for this engine, or -1 if no status can be
// extracted.
int ExtractStatusCode(const base::Value* const status_dict) {
  if (!status_dict || !status_dict->is_dict())
    return -1;

  const base::Value* const code_value = status_dict->FindKey("code");

  // A missing code is the same as a default (i.e. OK) code.
  if (!code_value)
    return 0;

  if (!code_value->is_int())
    return -1;
  const int code = code_value->GetInt();

#ifndef NDEBUG
  // Also log error status messages (which are helpful for debugging).
  const base::Value* const message = status_dict->FindKey("message");
  if (code != 0 && message && message->is_string())
    DVLOG(1) << "Engine failed with status " << code << " and message '"
             << message->GetString() << "'";
#endif

  return code;
}

// Attempts to extract annotation results from the server response, returning a
// map from each image ID to its annotations (if successfully extracted).
std::map<std::string, mojom::AnnotateImageResultPtr> UnpackJsonResponse(
    const base::Value& json_data,
    const double min_ocr_confidence) {
  if (!json_data.is_dict())
    return {};

  const base::Value* const results = json_data.FindKey("results");
  if (!results || !results->is_list())
    return {};

  std::map<std::string, mojom::AnnotateImageResultPtr> out;
  for (const base::Value& result : results->GetListDeprecated()) {
    if (!result.is_dict())
      continue;

    const base::Value* const image_id = result.FindKey("imageId");
    if (!image_id || !image_id->is_string())
      continue;

    const base::Value* const engine_results = result.FindKey("engineResults");
    if (!engine_results || !engine_results->is_list())
      continue;

    // We expect the engine result list to have exactly two results: one for OCR
    // and one for image descriptions. However, we "robustly" handle missing
    // engines, unknown engines (by skipping them) and repetitions (by
    // overwriting data).
    bool adult = false;
    std::vector<mojom::AnnotationPtr> annotations;
    mojom::AnnotationPtr ocr_annotation;
    mojom::AnnotationPtr icon_annotation;
    for (const base::Value& engine_result :
         engine_results->GetListDeprecated()) {
      if (!engine_result.is_dict())
        continue;

      // A non-zero status code means the following:
      //  -1:                       The status dict could not be parsed. We
      //                            still try to parse an engine result in this
      //                            case to be robust.
      //  any other non-zero value: The status dict was parsed and contains a
      //                            known failure. We always report an error
      //                            in this case.
      const int status_code =
          ExtractStatusCode(engine_result.FindKey("status"));

      const base::Value* const desc_engine =
          engine_result.FindKey("descriptionEngine");
      const base::Value* const ocr_engine = engine_result.FindKey("ocrEngine");
      const base::Value* const icon_engine =
          engine_result.FindKey("iconEngine");

      if (desc_engine) {
        // Add description annotations and update the adult image flag.
        ReportDescStatus(status_code);

        if (status_code <= 0) {
          std::tie(adult, annotations) = ParseJsonDescAnnotations(*desc_engine);
        }
      } else if (ocr_engine) {
        // Update the specialized OCR annotations.
        ReportOcrStatus(status_code);

        if (status_code <= 0) {
          ocr_annotation =
              ParseJsonOcrAnnotation(*ocr_engine, min_ocr_confidence);
        }
      } else if (icon_engine) {
        if (status_code <= 0) {
          icon_annotation = ParseJsonIconAnnotations(*icon_engine);
        }
      }

      ReportEngineKnown(ocr_engine || desc_engine);
    }

    // Remove any description OCR data (which is lower quality) if we have
    // specialized OCR results.
    if (!ocr_annotation.is_null()) {
      base::EraseIf(annotations, [](const mojom::AnnotationPtr& a) {
        return a->type == mojom::AnnotationType::kOcr;
      });
      annotations.push_back(std::move(ocr_annotation));
    }

    // Remove labels and captions if the image is detected
    // as an icon. Don't remove OCR as any text in the icon might
    // be useful.
    // TODO(accessibility): consider filtering some icon types here e.g.
    // information.
    if (!icon_annotation.is_null()) {
      base::EraseIf(annotations, [](const mojom::AnnotationPtr& a) {
        return a->type == mojom::AnnotationType::kLabel ||
               a->type == mojom::AnnotationType::kCaption;
      });
      annotations.push_back(std::move(icon_annotation));
    }

    if (adult) {
      out[image_id->GetString()] = mojom::AnnotateImageResult::NewErrorCode(
          mojom::AnnotateImageError::kAdult);
    } else if (!annotations.empty()) {
      out[image_id->GetString()] =
          mojom::AnnotateImageResult::NewAnnotations(std::move(annotations));
    }
  }

  return out;
}

}  // namespace

constexpr char Annotator::kGoogApiKeyHeader[];

static_assert(Annotator::kDescMinDimension > 0,
              "Description engine must accept images of some sizes.");
static_assert(Annotator::kDescMaxAspectRatio > 0.0,
              "Description engine must accept images of some aspect ratios.");
static_assert(Annotator::kIconMinDimension > 0,
              "Icon engine must accept images of some sizes.");

Annotator::ClientRequestInfo::ClientRequestInfo(
    mojo::PendingRemote<mojom::ImageProcessor> in_image_processor,
    AnnotateImageCallback in_callback)
    : image_processor(std::move(in_image_processor)),
      callback(std::move(in_callback)) {}

Annotator::ClientRequestInfo::~ClientRequestInfo() = default;

Annotator::ServerRequestInfo::ServerRequestInfo(
    const std::string& in_source_id,
    const bool in_desc_requested,
    const bool in_icon_requested,
    const std::string& in_desc_lang_tag,
    const std::vector<uint8_t>& in_image_bytes)
    : source_id(in_source_id),
      desc_requested(in_desc_requested),
      icon_requested(in_icon_requested),
      desc_lang_tag(in_desc_lang_tag),
      image_bytes(in_image_bytes) {}

Annotator::ServerRequestInfo& Annotator::ServerRequestInfo::operator=(
    ServerRequestInfo&& other) = default;

Annotator::ServerRequestInfo::~ServerRequestInfo() = default;

Annotator::Annotator(
    GURL pixels_server_url,
    GURL langs_server_url,
    std::string api_key,
    const base::TimeDelta throttle,
    const int batch_size,
    const double min_ocr_confidence,
    scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
    std::unique_ptr<Client> client)
    : client_(std::move(client)),
      url_loader_factory_(std::move(url_loader_factory)),
      pixels_server_url_(std::move(pixels_server_url)),
      langs_server_url_(std::move(langs_server_url)),
      api_key_(std::move(api_key)),
      batch_size_(batch_size),
      min_ocr_confidence_(min_ocr_confidence),
      server_languages_({"cs", "de", "en", "es", "fi", "fr", "hi", "hr", "id",
                         "it", "iw", "nl", "no", "pt", "ru", "sv", "tr"}) {
  server_request_timer_ = std::make_unique<base::RepeatingTimer>(
      FROM_HERE, throttle,
      base::BindRepeating(&Annotator::SendRequestBatchToServer,
                          weak_factory_.GetWeakPtr()));
  FetchServerLanguages();
}

Annotator::~Annotator() {
  // Report any clients still connected at service shutdown.
  for (const auto& request_info_kv : request_infos_) {
    for ([[maybe_unused]] const auto& unused : request_info_kv.second) {
      ReportClientResult(ClientResult::kShutdown);
    }
  }
}

void Annotator::BindReceiver(mojo::PendingReceiver<mojom::Annotator> receiver) {
  receivers_.Add(this, std::move(receiver));
}

void Annotator::AnnotateImage(
    const std::string& source_id,
    const std::string& page_language,
    mojo::PendingRemote<mojom::ImageProcessor> image_processor,
    AnnotateImageCallback callback) {
  // Compute the desired language for the description result, based on the
  // page language, the accept languages, the top languages, and the
  // server languages.
  const std::string preferred_language =
      ComputePreferredLanguage(page_language);
  client_->RecordLanguageMetrics(page_language, preferred_language);

  const RequestKey request_key(source_id, preferred_language);

  // Return cached results if they exist.
  const auto cache_lookup = cached_results_.find(request_key);
  ReportCacheHit(cache_lookup != cached_results_.end());
  if (cache_lookup != cached_results_.end()) {
    std::move(callback).Run(cache_lookup->second.Clone());
    return;
  }

  // Register the ImageProcessor and callback to be used for this request.
  std::list<ClientRequestInfo>& request_info_list = request_infos_[request_key];
  request_info_list.emplace_back(std::move(image_processor),
                                 std::move(callback));

  // If the image processor dies: automatically delete the request info and
  // reassign local processing (for other interested clients) if the dead image
  // processor was responsible for some ongoing work.
  request_info_list.back().image_processor.set_disconnect_handler(
      base::BindOnce(&Annotator::RemoveRequestInfo, weak_factory_.GetWeakPtr(),
                     request_key, --request_info_list.end(),
                     true /* canceled */));

  // Don't start local work if it would duplicate some already-ongoing work.
  if (base::Contains(local_processors_, request_key) ||
      base::Contains(pending_requests_, request_key))
    return;

  local_processors_.insert(
      {request_key, &request_info_list.back().image_processor});

  // TODO(crbug.com/916420): first query the public result cache by URL to
  // improve latency.

  request_info_list.back().image_processor->GetJpgImageData(base::BindOnce(
      &Annotator::OnJpgImageDataReceived, weak_factory_.GetWeakPtr(),
      request_key, --request_info_list.end()));
}

// static
bool Annotator::IsWithinDescPolicy(const int32_t width, const int32_t height) {
  if (width < kDescMinDimension || height < kDescMinDimension)
    return false;

  // Can't be 0 or inf because |kDescMinDimension| is guaranteed positive (via a
  // static_assert).
  const double aspect_ratio = static_cast<double>(width) / height;
  if (aspect_ratio < 1.0 / kDescMaxAspectRatio ||
      aspect_ratio > kDescMaxAspectRatio)
    return false;

  return true;
}

// static
bool Annotator::IsWithinIconPolicy(const int32_t width, const int32_t height) {
  if (width < kIconMinDimension || height < kIconMinDimension ||
      width > kIconMaxDimension || height > kIconMaxDimension) {
    return false;
  }

  // Can't be 0 or inf because |kIconMinDimension| is guaranteed positive (via a
  // static_assert).
  const double aspect_ratio = static_cast<double>(width) / height;
  if (aspect_ratio < 1.0 / kIconMaxAspectRatio ||
      aspect_ratio > kIconMaxAspectRatio)
    return false;

  return true;
}

// static
std::string Annotator::FormatJsonRequest(
    const std::deque<ServerRequestInfo>::iterator begin,
    const std::deque<ServerRequestInfo>::iterator end) {
  base::Value image_request_list(base::Value::Type::LIST);
  for (std::deque<ServerRequestInfo>::iterator it = begin; it != end; ++it) {
    // Re-encode image bytes into base64, which can be represented in JSON.
    std::string base64_data;
    base::Base64Encode(
        base::StringPiece(reinterpret_cast<const char*>(it->image_bytes.data()),
                          it->image_bytes.size()),
        &base64_data);

    // TODO(crbug.com/916420): accept and propagate page language info to
    //                         improve OCR accuracy.
    base::Value ocr_engine_params(base::Value::Type::DICTIONARY);
    ocr_engine_params.SetKey("ocrParameters",
                             base::Value(base::Value::Type::DICTIONARY));

    base::Value engine_params_list(base::Value::Type::LIST);
    engine_params_list.Append(std::move(ocr_engine_params));

    // Also add a description annotations request if the image is within model
    // policy.
    if (it->desc_requested) {
      base::Value desc_params(base::Value::Type::DICTIONARY);

      // Add preferred description language if it has been specified.
      if (!it->desc_lang_tag.empty()) {
        base::Value desc_lang_list(base::Value::Type::LIST);
        desc_lang_list.Append(base::Value(it->desc_lang_tag));

        desc_params.SetKey("preferredLanguages", std::move(desc_lang_list));
      }

      base::Value engine_params(base::Value::Type::DICTIONARY);
      engine_params.SetKey("descriptionParameters", std::move(desc_params));

      engine_params_list.Append(std::move(engine_params));
    }
    ReportImageRequestIncludesDesc(it->desc_requested);

    // Request icon classification.
    // TODO(accessibility): Maybe only do this for certain
    // file sizes?
    if (it->icon_requested) {
      base::Value icon_params(base::Value::Type::DICTIONARY);
      base::Value engine_params(base::Value::Type::DICTIONARY);
      engine_params.SetKey("iconParameters", std::move(icon_params));
      engine_params_list.Append(std::move(engine_params));
    }
    ReportImageRequestIncludesIcon(it->icon_requested);

    base::Value image_request(base::Value::Type::DICTIONARY);
    image_request.SetKey(
        "imageId", base::Value(MakeImageId(it->source_id, it->desc_lang_tag)));
    image_request.SetKey("imageBytes", base::Value(std::move(base64_data)));
    image_request.SetKey("engineParameters", std::move(engine_params_list));

    image_request_list.Append(std::move(image_request));
  }

  base::Value request(base::Value::Type::DICTIONARY);
  request.SetKey("imageRequests", std::move(image_request_list));

  std::string json_request;
  base::JSONWriter::Write(request, &json_request);

  ReportServerRequestSizeKB(json_request.size() / 1024);

  return json_request;
}

// static
std::unique_ptr<network::SimpleURLLoader> Annotator::MakeRequestLoader(
    const GURL& server_url,
    const std::string& api_key) {
  auto resource_request = std::make_unique<network::ResourceRequest>();
  resource_request->method = "POST";

  resource_request->url = server_url;

  resource_request->credentials_mode = network::mojom::CredentialsMode::kOmit;

  // Put API key in request's header if a key exists, and the endpoint is
  // trusted by Google.
  if (!api_key.empty() && server_url.SchemeIs(url::kHttpsScheme) &&
      google_util::IsGoogleAssociatedDomainUrl(server_url)) {
    resource_request->headers.SetHeader(kGoogApiKeyHeader, api_key);
  }

  const net::NetworkTrafficAnnotationTag traffic_annotation =
      net::DefineNetworkTrafficAnnotation("image_annotation", R"(
        semantics {
          sender: "Get Image Descriptions from Google"
          description:
            "Chrome can provide image labels (which include detected objects, "
            "extracted text and generated captions) to screen readers (for "
            "visually-impaired users) by sending images to Google's servers. "
            "If image labeling is enabled for a page, Chrome will send the "
            "URLs and pixels of all images on the page to Google's servers, "
            "which will return labels for content identified inside the "
            "images. This content is made accessible to screen reading "
            "software. Chrome fetches the list of supported languages from "
            "the servers and uses that to determine what language to request "
            "descriptions in."
          trigger: "A page containing images is loaded for a user who has "
                   "automatic image labeling enabled. At most once per day, "
                   "Chrome fetches the list of supported languages as a "
                   "separate network request."
          data: "Image pixels and URLs. No user identifier is sent along with "
                "the data."
          destination: GOOGLE_OWNED_SERVICE
        }
        policy {
          cookies_allowed: NO
          setting:
            "You can enable or disable this feature via the context menu "
            "for images, or via 'Get Image Descriptions' in Chrome's "
            "settings under Accessibility. This feature is disabled by default."
          chrome_policy {
            AccessibilityImageLabelsEnabled {
              AccessibilityImageLabelsEnabled: false
            }
          }
        })");

  return network::SimpleURLLoader::Create(std::move(resource_request),
                                          traffic_annotation);
}

void Annotator::OnJpgImageDataReceived(
    const RequestKey& request_key,
    const std::list<ClientRequestInfo>::iterator request_info_it,
    const std::vector<uint8_t>& image_bytes,
    const int32_t width,
    const int32_t height) {
  const std::string& source_id = request_key.first;
  const std::string& request_language = request_key.second;

  ReportPixelFetchSuccess(!image_bytes.empty());

  // Failed to retrieve bytes from local processor; remove dead processor and
  // reschedule processing.
  if (image_bytes.empty()) {
    RemoveRequestInfo(request_key, request_info_it, false /* canceled */);
    return;
  }

  // Local processing is no longer ongoing.
  local_processors_.erase(request_key);

  // Schedule a server request for this image.
  server_request_queue_.emplace_front(
      source_id, IsWithinDescPolicy(width, height),
      IsWithinIconPolicy(width, height), request_language, image_bytes);
  pending_requests_.insert(request_key);

  // Start sending batches to the server.
  if (!server_request_timer_->IsRunning())
    server_request_timer_->Reset();
}

void Annotator::SendRequestBatchToServer() {
  if (server_request_queue_.empty()) {
    server_request_timer_->Stop();
    return;
  }

  // Take last n elements (or all elements if there are less than n).
  const auto begin =
      server_request_queue_.end() -
      std::min<size_t>(server_request_queue_.size(), batch_size_);
  const auto end = server_request_queue_.end();

  // The set of (source ID, desc lang) pairs relevant for this request.
  std::set<RequestKey> request_keys;
  for (std::deque<ServerRequestInfo>::iterator it = begin; it != end; it++) {
    request_keys.insert({it->source_id, it->desc_lang_tag});
  }

  // Kick off server communication.
  std::unique_ptr<network::SimpleURLLoader> url_loader =
      MakeRequestLoader(pixels_server_url_, api_key_);
  url_loader->AttachStringForUpload(FormatJsonRequest(begin, end),
                                    "application/json");
  ongoing_server_requests_.push_back(std::move(url_loader));
  ongoing_server_requests_.back()->DownloadToString(
      url_loader_factory_.get(),
      base::BindOnce(&Annotator::OnServerResponseReceived,
                     weak_factory_.GetWeakPtr(), request_keys,
                     --ongoing_server_requests_.end()),
      kImageAnnotationMaxResponseSize);

  server_request_queue_.erase(begin, end);
}

void Annotator::OnServerResponseReceived(
    const std::set<RequestKey>& request_keys,
    const UrlLoaderList::iterator server_request_it,
    const std::unique_ptr<std::string> json_response) {
  ReportServerNetError(server_request_it->get()->NetError());

  if (const network::mojom::URLResponseHead* const response_info =
          server_request_it->get()->ResponseInfo()) {
    ReportServerResponseCode(response_info->headers->response_code());
    ReportServerLatency(response_info->response_time -
                        response_info->request_time);
  }

  ongoing_server_requests_.erase(server_request_it);

  if (!json_response) {
    DVLOG(1) << "HTTP request to image annotation server failed.";
    ProcessResults(request_keys, {});
    return;
  }

  ReportServerResponseSizeBytes(json_response->size());

  // Send JSON string to a dedicated service for safe parsing.
  GetJsonParser()->Parse(
      *json_response, base::JSON_PARSE_RFC,
      base::BindOnce(&Annotator::OnResponseJsonParsed,
                     weak_factory_.GetWeakPtr(), request_keys));
}

void Annotator::OnResponseJsonParsed(
    const std::set<RequestKey>& request_keys,
    const absl::optional<base::Value> json_data,
    const absl::optional<std::string>& error) {
  const bool success = json_data.has_value() && !error.has_value();
  ReportJsonParseSuccess(success);

  // Extract annotation results for each request key with valid results.
  if (success) {
    ProcessResults(request_keys,
                   UnpackJsonResponse(*json_data, min_ocr_confidence_));
  } else {
    DVLOG(1) << "Parsing server response JSON failed with error: "
             << error.value_or("No reason reported.");
    ProcessResults(request_keys, {});
  }
}

void Annotator::ProcessResults(
    const std::set<RequestKey>& request_keys,
    const std::map<std::string, mojom::AnnotateImageResultPtr>& results) {
  // Process each request key for which we expect to have results.
  for (const RequestKey& request_key : request_keys) {
    pending_requests_.erase(request_key);

    // The lookup will be successful if there is a valid result (i.e. not an
    // error and not a malformed result) for this (source ID, desc lang) pair.
    const auto result_lookup =
        results.find(MakeImageId(request_key.first, request_key.second));

    // Populate the result struct for this image and copy it into the cache if
    // necessary.
    if (result_lookup != results.end())
      cached_results_.insert(
          std::make_pair(request_key, result_lookup->second.Clone()));

    // This should not happen, since only this method removes entries of
    // |request_infos_|, and this method should only execute once per request
    // key.
    const auto request_info_it = request_infos_.find(request_key);
    if (request_info_it == request_infos_.end()) {
      LOG(ERROR) << "Could not find request key in request_infos_: "
                 << request_key.first << "," << request_key.second;
      continue;
    }

    const auto image_result = result_lookup != results.end()
                                  ? result_lookup->second.Clone()
                                  : mojom::AnnotateImageResult::NewErrorCode(
                                        mojom::AnnotateImageError::kFailure);
    const auto client_result = result_lookup != results.end()
                                   ? ClientResult::kSucceeded
                                   : ClientResult::kFailed;

    // Notify clients of success or failure.
    // TODO(crbug.com/916420): explore server retry strategies.
    for (auto& info : request_info_it->second) {
      std::move(info.callback).Run(image_result.Clone());
      ReportClientResult(client_result);
    }
    request_infos_.erase(request_info_it);
  }
}

data_decoder::mojom::JsonParser* Annotator::GetJsonParser() {
  if (!json_parser_) {
    client_->BindJsonParser(json_parser_.BindNewPipeAndPassReceiver());
    json_parser_.reset_on_disconnect();
  }

  return json_parser_.get();
}

void Annotator::RemoveRequestInfo(
    const RequestKey& request_key,
    const std::list<ClientRequestInfo>::iterator request_info_it,
    const bool canceled) {
  // Check whether we are deleting the ImageProcessor responsible for current
  // local processing.
  auto local_processor_lookup = local_processors_.find(request_key);
  const bool should_reassign =
      local_processor_lookup != local_processors_.end() &&
      local_processor_lookup->second == &request_info_it->image_processor;

  // Notify client of cancellation / failure.
  ReportClientResult(canceled ? ClientResult::kCanceled
                              : ClientResult::kFailed);
  std::move(request_info_it->callback)
      .Run(mojom::AnnotateImageResult::NewErrorCode(
          canceled ? mojom::AnnotateImageError::kCanceled
                   : mojom::AnnotateImageError::kFailure));

  // Delete the specified ImageProcessor.
  std::list<ClientRequestInfo>& request_info_list = request_infos_[request_key];
  request_info_list.erase(request_info_it);

  // If necessary, reassign local processing.
  if (should_reassign) {
    if (request_info_list.empty()) {
      local_processors_.erase(local_processor_lookup);
    } else {
      local_processor_lookup->second =
          &request_info_list.front().image_processor;

      request_info_list.front().image_processor->GetJpgImageData(base::BindOnce(
          &Annotator::OnJpgImageDataReceived, weak_factory_.GetWeakPtr(),
          request_key, request_info_list.begin()));
    }
  }
}

std::string Annotator::ComputePreferredLanguage(
    const std::string& in_page_language) const {
  DCHECK(!server_languages_.empty());
  if (in_page_language.empty())
    return "";

  std::string page_language = NormalizeLanguageCode(in_page_language);
  std::vector<std::string> accept_languages = client_->GetAcceptLanguages();
  std::transform(accept_languages.begin(), accept_languages.end(),
                 accept_languages.begin(), NormalizeLanguageCode);
  std::vector<std::string> top_languages = client_->GetTopLanguages();
  std::transform(top_languages.begin(), top_languages.end(),
                 top_languages.begin(), NormalizeLanguageCode);

  // If the page language is a server language and it's in the list of accept
  // languages or top languages for this user, return that.
  if (base::Contains(server_languages_, page_language) &&
      (base::Contains(accept_languages, page_language) ||
       base::Contains(top_languages, page_language))) {
    return page_language;
  }

  // Otherwise, ignore the page language and compute the best language
  // for this user. The accept languages are the ones the user can
  // explicitly choose, so pick the first accept language that's a
  // top language and a server language.
  if (!top_languages.empty()) {
    for (const std::string& accept_language : accept_languages) {
      if (base::Contains(server_languages_, accept_language) &&
          base::Contains(top_languages, accept_language)) {
        return accept_language;
      }
    }
  }

  // Sometimes the top languages are empty. Try any accept language that's
  // a server language.
  for (const std::string& accept_language : accept_languages) {
    if (base::Contains(server_languages_, accept_language))
      return accept_language;
  }

  // If that still fails, try any top language that's a server language.
  for (const std::string& top_language : top_languages) {
    if (base::Contains(server_languages_, top_language))
      return top_language;
  }

  // If all else fails, return the first accept language. The server can
  // still do OCR and it can log this language request.
  if (!accept_languages.empty())
    return accept_languages[0];

  // If that fails, return the page language. The server can
  // still do OCR and it can log this language request.
  return page_language;
}

void Annotator::FetchServerLanguages() {
  if (langs_server_url_.is_empty())
    return;

  langs_url_loader_ = MakeRequestLoader(langs_server_url_, api_key_);
  langs_url_loader_->AttachStringForUpload("", "application/json");
  langs_url_loader_->DownloadToString(
      url_loader_factory_.get(),
      base::BindOnce(&Annotator::OnServerLangsResponseReceived,
                     weak_factory_.GetWeakPtr()),
      kServerLangsMaxResponseSize);
}

void Annotator::OnServerLangsResponseReceived(
    const std::unique_ptr<std::string> json_response) {
  if (!json_response) {
    DVLOG(1) << "Failed to get languages from the server.";
    return;
  }

  GetJsonParser()->Parse(
      *json_response, base::JSON_PARSE_RFC,
      base::BindOnce(&Annotator::OnServerLangsResponseJsonParsed,
                     weak_factory_.GetWeakPtr()));
}

void Annotator::OnServerLangsResponseJsonParsed(
    absl::optional<base::Value> json_data,
    const absl::optional<std::string>& error) {
  if (!json_data.has_value() || error.has_value()) {
    DVLOG(1) << "Parsing server langs response JSON failed with error: "
             << error.value_or("No reason reported.");
    return;
  }

  const base::Value* const langs = json_data->FindKey("langs");
  if (!langs || !langs->is_list()) {
    DVLOG(1) << "No langs in response JSON";
    return;
  }

  std::vector<std::string> new_server_languages;
  for (const base::Value& lang : langs->GetListDeprecated()) {
    if (!lang.is_string()) {
      DVLOG(1) << "Lang in response JSON is not a string";
      return;
    }
    new_server_languages.push_back(lang.GetString());
  }

  if (!base::Contains(new_server_languages, "en")) {
    DVLOG(1) << "Server langs don't even include 'en', rejecting";
    return;
  }

  // Only swap in the new languages at the end, if all of the other
  // checks passed.
  server_languages_.swap(new_server_languages);
}

}  // namespace image_annotation


text:
import unittest

class Test_get_metadata(unittest.TestCase):

    def _callFUT(self, path, metadata_version=None):
        from pkginfo.utils import get_metadata
        if metadata_version is not None:
            return get_metadata(path, metadata_version)
        return get_metadata(path)

    def _checkMyPackage(self, dist, filename):
        self.assertEqual(dist.filename, filename)
        self.assertEqual(dist.name, 'mypackage')
        self.assertEqual(dist.version, '0.1')
        self.assertEqual(dist.keywords, None)
        self.assertEqual(list(dist.supported_platforms), [])

    def _checkClassifiers(self, dist):
        self.assertEqual(list(dist.classifiers),
                         ['Development Status :: 4 - Beta',
                          'Environment :: Console (Text Based)',
                         ])

    def test_w_gztar(self):
        import os
        d, _ = os.path.split(__file__)
        filename = '%s/../../docs/examples/mypackage-0.1.tar.gz' % d
        dist = self._callFUT(filename)
        self.assertEqual(dist.metadata_version, '1.0')
        self._checkMyPackage(dist, filename)

    def test_w_gztar_and_metadata_version(self):
        import os
        d, _ = os.path.split(__file__)
        filename = '%s/../../docs/examples/mypackage-0.1.tar.gz' % d
        dist = self._callFUT(filename, metadata_version='1.1')
        self.assertEqual(dist.metadata_version, '1.1')
        self._checkMyPackage(dist, filename)
        self._checkClassifiers(dist)

    def test_w_bztar(self):
        import os
        d, _ = os.path.split(__file__)
        filename = '%s/../../docs/examples/mypackage-0.1.tar.bz2' % d
        dist = self._callFUT(filename)
        self.assertEqual(dist.metadata_version, '1.0')
        self._checkMyPackage(dist, filename)

    def test_w_bztar_and_metadata_version(self):
        import os
        d, _ = os.path.split(__file__)
        filename = '%s/../../docs/examples/mypackage-0.1.tar.bz2' % d
        dist = self._callFUT(filename, metadata_version='1.1')
        self.assertEqual(dist.metadata_version, '1.1')
        self._checkMyPackage(dist, filename)
        self._checkClassifiers(dist)

    def test_w_zip(self):
        import os
        d, _ = os.path.split(__file__)
        filename = '%s/../../docs/examples/mypackage-0.1.zip' % d
        dist = self._callFUT(filename)
        self.assertEqual(dist.metadata_version, '1.0')
        self._checkMyPackage(dist, filename)

    def test_w_zip_and_metadata_version(self):
        import os
        d, _ = os.path.split(__file__)
        filename = '%s/../../docs/examples/mypackage-0.1.zip' % d
        dist = self._callFUT(filename, metadata_version='1.1')
        self.assertEqual(dist.metadata_version, '1.1')
        self._checkMyPackage(dist, filename)
        self._checkClassifiers(dist)

    def test_w_egg(self):
        import os
        d, _ = os.path.split(__file__)
        filename = '%s/../../docs/examples/mypackage-0.1-py2.6.egg' % d
        dist = self._callFUT(filename)
        self.assertEqual(dist.metadata_version, '1.0')
        self._checkMyPackage(dist, filename)

    def test_w_egg_and_metadata_version(self):
        import os
        d, _ = os.path.split(__file__)
        filename = '%s/../../docs/examples/mypackage-0.1-py2.6.egg' % d
        dist = self._callFUT(filename, metadata_version='1.1')
        self.assertEqual(dist.metadata_version, '1.1')
        self._checkMyPackage(dist, filename)
        self._checkClassifiers(dist)

    def test_w_wheel(self):
        import os
        d, _ = os.path.split(__file__)
        filename = ('%s/../../docs/examples/'
                    'mypackage-0.1-cp26-none-linux_x86_64.whl') % d
        dist = self._callFUT(filename)
        self.assertEqual(dist.metadata_version, '2.0')
        self._checkMyPackage(dist, filename)

    def test_w_wheel_and_metadata_version(self):
        import os
        d, _ = os.path.split(__file__)
        filename = ('%s/../../docs/examples/'
                    'mypackage-0.1-cp26-none-linux_x86_64.whl') % d
        dist = self._callFUT(filename, metadata_version='1.1')
        self.assertEqual(dist.metadata_version, '1.1')
        self._checkMyPackage(dist, filename)
        self._checkClassifiers(dist)

    def test_w_module(self):
        from pkginfo.tests import _defaultMetadataVersion
        EXPECTED =  _defaultMetadataVersion()
        import pkginfo
        from pkginfo.tests import _checkSample
        dist = self._callFUT(pkginfo)
        self.assertEqual(dist.metadata_version, EXPECTED)
        _checkSample(self, dist)

    def test_w_module_and_metadata_version(self):
        import pkginfo
        from pkginfo.tests import _checkSample
        from pkginfo.tests import _checkClassifiers
        dist = self._callFUT(pkginfo, metadata_version='1.2')
        self.assertEqual(dist.metadata_version, '1.2')
        _checkSample(self, dist)
        _checkClassifiers(self, dist)

    def test_w_package_name(self):
        from pkginfo.tests import _defaultMetadataVersion
        EXPECTED =  _defaultMetadataVersion()
        from pkginfo.tests import _checkSample
        dist = self._callFUT('pkginfo')
        self.assertEqual(dist.metadata_version, EXPECTED)
        _checkSample(self, dist)

    def test_w_package_name_and_metadata_version(self):
        from pkginfo.tests import _checkSample
        from pkginfo.tests import _checkClassifiers
        dist = self._callFUT('pkginfo', metadata_version='1.2')
        self.assertEqual(dist.metadata_version, '1.2')
        _checkSample(self, dist)
        _checkClassifiers(self, dist)

    def test_w_directory_no_EGG_INFO(self):
        import os
        import warnings
        dir, name = os.path.split(__file__)
        subdir = os.path.join(dir, 'funny')
        old_filters = warnings.filters[:]
        warnings.filterwarnings('ignore')
        try:
            dist = self._callFUT(subdir)
            self.assertEqual(dist.path, subdir)
            self.assertEqual(dist.name, None)
            self.assertEqual(dist.version, None)
        finally:
            warnings.filters[:] = old_filters

    def test_w_directory(self):
        import os
        dir, name = os.path.split(__file__)
        subdir = os.path.join(dir, 'silly')
        dist = self._callFUT(subdir)
        self.assertEqual(dist.metadata_version, '1.0')
        self.assertEqual(dist.name, 'silly')
        self.assertEqual(dist.version, '0.1')

    def test_w_directory_and_metadata_version(self):
        import os
        dir, name = os.path.split(__file__)
        subdir = os.path.join(dir, 'silly')
        dist = self._callFUT(subdir, metadata_version='1.2')
        self.assertEqual(dist.metadata_version, '1.2')
        self.assertEqual(dist.name, 'silly')
        self.assertEqual(dist.version, '0.1')

redpajama_set_name: RedPajamaGithub


text:
<?php
error_reporting(error_reporting() & ~E_NOTICE);
$config = include('../config.php');
require_once('priv_utils.php');
require_once('logging.php');
require_once('../lisk-php/main.php');
$thread_file = "php ".realpath(dirname(__FILE__))."/wthread.php";
$threads = ((int)shell_exec("cat /proc/cpuinfo | grep processor | wc -l")*2)-1;
$payout_threshold = floatval($config['payout_threshold']);
$withdraw_interval_in_sec = $config['withdraw_interval_in_sec'];
$delegate = $config['delegate_address'];
$secret1 = $config['secret'];
$secret2 = $config['secondSecret'];
$fancy_secret = $config['fancy_withdraw_hub'];
$protocol = $config['protocol'];
$public_directory = $config['public_directory'];
$payout_threshold = LSK_BASE * $payout_threshold;
$payout_threshold = new Math_BigInteger($payout_threshold);
$lsk = new Math_BigInteger(LSK_BASE);

while(1){
	$m = new Memcached();
  	$m->addServer('localhost', 11211);
  	$server = getCurrentServer($m);
  	clog("Current server set to: ".$server,'withdraw');
	$mysqli=mysqli_connect($config['host'], $config['username'], $config['password'], $config['bdd']) or die("Database Error");
	$withdraw_array = array();
	$required_balance = new Math_BigInteger('0');
	if (IsBalanceOkToWithdraw($mysqli,$server,$delegate,false)) {
  		$json = AccountForAddress($delegate,$server);
  		$publicKey = $json['data'][0]['publicKey'];
		$existQuery = "SELECT address,balance FROM miners WHERE balance!='0'";
		$existResult = mysqli_query($mysqli,$existQuery)or die("Database Error");
		while ($row=mysqli_fetch_row($existResult)){
			$payer_adr = $row[0];
			$balance = new Math_BigInteger($row[1]);
			list($balance_quotient, $balance_reminder) = $balance->divide($lsk);
			$balanceinlsk = $balance_quotient->toString();
			$valueAsFloat = floatval($balance_quotient->toString().".".$balance_reminder->toString());
			if ($balance->compare($payout_threshold) > 0) {
				clog("Address:".$payer_adr." - Adding to withdraw queue ".$valueAsFloat." LSK",'withdraw');
				$withdraw_array[$payer_adr] = $balance->toString();
				$required_balance = $required_balance->add($balance);
			} else {
				clog("Address:".$payer_adr." - Not exceeded threshold ".$balance->toString()."/".$payout_threshold->toString(),'withdraw');
			}
		}
		$wcount = count($withdraw_array);
		$txleft = $wcount;
		clog($wcount." eligible for withdraw",'withdraw');
		list($total_balance_quotient, $total_balance_reminder) = $required_balance->divide($lsk);
		$required_balance_float = floatval($total_balance_quotient->toString().".".$total_balance_reminder->toString());
		clog($required_balance_float." required for withdraw",'withdraw');
		if ($fancy_secret && $required_balance->toString() != "0") {
			$output = getKeysFromSecret($fancy_secret,true);
			$fancy_address = getAddressFromPublicKey($output['public']);
			$OneBdd = new Math_BigInteger('1');
			$required_balance = $required_balance->add($lsk);
			list($totalPlusOne_balance_quotient, $totalPlusOne_balance_reminder) = $required_balance->divide($lsk);
			$required_balance_floatPlusOne = floatval($totalPlusOne_balance_quotient->toString().".".$totalPlusOne_balance_reminder->toString());
			clog("Transfering:".$required_balance_floatPlusOne."LSK for withdraw to fancy hub: ".$fancy_address,'withdraw');
			$fancy_withdraw_hub_balance = new Math_BigInteger(AccountForAddress($fancy_address,$server)["data"][0]["balance"]);
			$topup_balance = $required_balance->subtract($fancy_withdraw_hub_balance);
			clog("Top up in Beddows:".$topup_balance->toString(),'withdraw');
			if ($topup_balance->compare($OneBdd) > 0) {
				if ($required_balance->toString() != "0") {
					list($topup_balance_quotient, $topup_balance_reminder) = $topup_balance->divide($lsk);
					$topupFloatVal = floatval($topup_balance_quotient->toString().".".$topup_balance_reminder->toString());
					clog("Top up:".$topupFloatVal."LSK",'withdraw');
					if (!$secret2) {
						$tx = CreateTransaction($fancy_address, $topup_balance->toString(), $secret1, false, false, -10);
					} else {
						$tx = CreateTransaction($fancy_address, $topup_balance->toString(), $secret1, $secret2, false, -10);
					}
					$tx_resp = json_encode(SendTransaction(json_encode($tx),$server));
					clog("Sleeping for: 120 sec, waiting for hub transfer ".$tx['id']." with status[".$tx_resp."] to settle",'withdraw');
					csleep(120);
				} else {
					clog("Amount on fancy hub correct! 1",'withdraw');
					csleep(2);
				}
			} else {
				clog("Amount on fancy hub correct! 2",'withdraw');
				csleep(2);
			}
		}
		$pipes = array();
		foreach ($withdraw_array as $recipient => $balanceinlsk) {
			$pcount = count($pipes);
			if ($pcount < $threads || $txleft < $threads) {
				clog("[".$pcount."]Creating withdraw thread for ".$recipient."->".$balanceinlsk,'withdraw');
				$pipes[$pcount] = popen($thread_file." ".$recipient." ".$balanceinlsk, 'r');
			} else {
				clog("[".$pcount."]Creating withdraw thread for ".$recipient."->".$balanceinlsk,'withdraw');
				$pipes[$pcount] = popen($thread_file." ".$recipient." ".$balanceinlsk, 'r');
				for ($j=0; $j<$threads+1; ++$j) {
					$response = stream_get_contents($pipes[$j]);
					pclose($pipes[$j]);
					clog("[".$j."]".$response,'withdraw');
				}
				if ($txleft < $threads) {
					$btxleft = $txleft;
					$txleft = $txleft - $txleft;
				} else {
					$btxleft = $threads+1;
					$txleft = $txleft - ($threads+1);
				}
				clog("Txleft:".$txleft.", sent:".$btxleft,'withdraw');
				$pipes = array();
			}
		}
		if ($wcount > 0) {
			for ($j=0; $j<$txleft; ++$j) {
				$response = stream_get_contents($pipes[$j]);
				pclose($pipes[$j]);
				clog("[".$j."]".$response,'withdraw');
			}
			$btxleft = $txleft;
			$txleft = $txleft - $txleft;
			clog("Txleft:".$txleft.", sent:".$btxleft,'withdraw');
		} else {
			clog("No withdraws has been made",'withdraw');
		}
		clog("Sleeping for:".$withdraw_interval_in_sec." sec",'withdraw');
		csleep($withdraw_interval_in_sec);
	} else {
		clog("\n!!! Incorrect - balance invalid !!!",'withdraw');
		clog("!!! Can't withdraw, retrying after 30min !!!\n\n",'withdraw');
		csleep(1800);
	}
}
?>


text:
package org.geomajas.sld;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import org.geomajas.annotation.Api;

/**
 *
 A FeatureTypeStyle contains styling information specific to one feature type.
 * This is the SLD level that separates the 'layer' handling from the 'feature'
 * handling.
 *
 *
 * Schema fragment(s) for this class:...
 *
 * <pre>
 * <xs:element
 *
 * xmlns:ns="http://www.opengis.net/sld"
 *
 * xmlns:xs="http://www.w3.org/2001/XMLSchema" name="FeatureTypeStyle">
 *   <xs:complexType>
 *     <xs:sequence>
 *       <xs:element ref="ns:Name" minOccurs="0"/>
 *       <xs:element ref="ns:Title" minOccurs="0"/>
 *       <xs:element ref="ns:Abstract" minOccurs="0"/>
 *       <xs:element ref="ns:FeatureTypeName" minOccurs="0"/>
 *       <xs:element ref="ns:SemanticTypeIdentifier" minOccurs="0" maxOccurs="unbounded"/>
 *       <xs:element ref="ns:Transformation" minOccurs="0"/>
 *       <xs:element ref="ns:Rule" maxOccurs="unbounded"/>
 *     </xs:sequence>
 *   </xs:complexType>
 * </xs:element>
 * </pre>
 *
 * @author Jan De Moerloose
 * @since 1.0.0
 */

@Api(allMethods = true)
public class FeatureTypeStyleInfo implements Serializable {

	private static final long serialVersionUID = 100;

	private String name;

	private String title;

	private AbstractInfo aAbstract;

	private FeatureTypeNameInfo featureTypeName;

	private List<SemanticTypeIdentifierInfo> semanticTypeIdentifierList = new ArrayList<SemanticTypeIdentifierInfo>();

	private TransformationInfo transformation;

	private List<RuleInfo> ruleList = new ArrayList<RuleInfo>();

	/**
	 * Get the 'Name' element value.
	 *
	 * @return value
	 */
	public String getName() {
		return name;
	}

	/**
	 * Set the 'Name' element value.
	 *
	 * @param name
	 */
	public void setName(String name) {
		this.name = name;
	}

	/**
	 * Get the 'Title' element value.
	 *
	 * @return value
	 */
	public String getTitle() {
		return title;
	}

	/**
	 * Set the 'Title' element value.
	 *
	 * @param title
	 */
	public void setTitle(String title) {
		this.title = title;
	}

	/**
	 * Get the 'Abstract' element value.
	 *
	 * @return value
	 */
	public AbstractInfo getAbstract() {
		return aAbstract;
	}

	/**
	 * Set the 'Abstract' element value.
	 *
	 * @param _abstract
	 */
	public void setAbstract(AbstractInfo aAbstract) {
		this.aAbstract = aAbstract;
	}

	/**
	 * Get the 'FeatureTypeName' element value.
	 *
	 * @return value
	 */
	public FeatureTypeNameInfo getFeatureTypeName() {
		return featureTypeName;
	}

	/**
	 * Set the 'FeatureTypeName' element value.
	 *
	 * @param featureTypeName
	 */
	public void setFeatureTypeName(FeatureTypeNameInfo featureTypeName) {
		this.featureTypeName = featureTypeName;
	}

	/**
	 * Get the list of 'SemanticTypeIdentifier' element items.
	 *
	 * @return list
	 */
	public List<SemanticTypeIdentifierInfo> getSemanticTypeIdentifierList() {
		return semanticTypeIdentifierList;
	}

	/**
	 * Set the list of 'SemanticTypeIdentifier' element items.
	 *
	 * @param list
	 */
	public void setSemanticTypeIdentifierList(
			List<SemanticTypeIdentifierInfo> list) {
		semanticTypeIdentifierList = list;
	}

	/**
	 * Get the 'Transformation' element value.
	 *
	 * @return value
	 * @since 1.2.0
	 */
	public TransformationInfo getTransformation() {
		return transformation;
	}

	/**
	 * Set the 'Transformation' element value.
	 *
	 * @param transformation
	 * @since 1.2.0
	 */
	public void setTransformation(TransformationInfo transformation) {
		this.transformation = transformation;
	}

	/**
	 * Get the list of 'Rule' element items.
	 *
	 * @return list
	 */
	public List<RuleInfo> getRuleList() {
		return ruleList;
	}

	/**
	 * Set the list of 'Rule' element items.
	 *
	 * @param list
	 */
	public void setRuleList(List<RuleInfo> list) {
		ruleList = list;
	}

	@Override
	@java.lang.SuppressWarnings("all")
	public java.lang.String toString() {
		return "FeatureTypeStyleInfo(name=" + this.getName() + ", title="
				+ this.getTitle() + ", aAbstract=" + this.aAbstract
				+ ", featureTypeName=" + this.getFeatureTypeName()
				+ ", semanticTypeIdentifierList="
				+ this.getSemanticTypeIdentifierList() + ", transformation="
				+ this.getTransformation() + ", ruleList=" + this.getRuleList()
				+ ")";
	}

	@Override
	@java.lang.SuppressWarnings("all")
	public boolean equals(final java.lang.Object o) {
		if (o == this) {
			return true;
		}
		if (!(o instanceof FeatureTypeStyleInfo)) {
			return false;
		}
		final FeatureTypeStyleInfo other = (FeatureTypeStyleInfo) o;
		if (!other.canEqual((java.lang.Object) this)) {
			return false;
		}
		if (this.getName() == null ? other.getName() != null : !this.getName()
				.equals((java.lang.Object) other.getName())) {
			return false;
		}
		if (this.getTitle() == null ? other.getTitle() != null : !this
				.getTitle().equals((java.lang.Object) other.getTitle())) {
			return false;
		}
		if (this.aAbstract == null ? other.aAbstract != null : !this.aAbstract
				.equals((java.lang.Object) other.aAbstract)) {
			return false;
		}
		if (this.getFeatureTypeName() == null ? other.getFeatureTypeName() != null
				: !this.getFeatureTypeName().equals(
						(java.lang.Object) other.getFeatureTypeName())) {
			return false;
		}
		if (this.getSemanticTypeIdentifierList() == null ? other
				.getSemanticTypeIdentifierList() != null : !this
				.getSemanticTypeIdentifierList().equals(
						(java.lang.Object) other
								.getSemanticTypeIdentifierList())) {
			return false;
		}
		if (this.getTransformation() == null ? other.getTransformation() != null
				: !this.getTransformation().equals(
						(java.lang.Object) other.getTransformation())) {
			return false;
		}
		if (this.getRuleList() == null ? other.getRuleList() != null : !this
				.getRuleList().equals((java.lang.Object) other.getRuleList())) {
			return false;
		}
		return true;
	}

	/**
	 * Is there a chance that the object are equal? Verifies that the other
	 * object has a comparable type.
	 *
	 * @param other
	 *            other object
	 * @return true when other is an instance of this type
	 */
	public boolean canEqual(final java.lang.Object other) {
		return other instanceof FeatureTypeStyleInfo;
	}

	@Override
	@java.lang.SuppressWarnings("all")
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = result * prime
				+ (this.getName() == null ? 0 : this.getName().hashCode());
		result = result * prime
				+ (this.getTitle() == null ? 0 : this.getTitle().hashCode());
		result = result * prime
				+ (this.aAbstract == null ? 0 : this.aAbstract.hashCode());
		result = result
				* prime
				+ (this.getFeatureTypeName() == null ? 0 : this
						.getFeatureTypeName().hashCode());
		result = result
				* prime
				+ (this.getSemanticTypeIdentifierList() == null ? 0 : this
						.getSemanticTypeIdentifierList().hashCode());
		result = result
				* prime
				+ (this.getTransformation() == null ? 0 : this
						.getTransformation().hashCode());
		result = result
				* prime
				+ (this.getRuleList() == null ? 0 : this.getRuleList()
						.hashCode());
		return result;
	}
}


text:
Item 1

Item 2

Item 3


text:
@implementation RYURLShort

MJLogAllIvars

@end


text:
"""Tests for distutils.extension."""
import os
import warnings

from distutils.extension import read_setup_file, Extension

from .py38compat import check_warnings
import pytest

class TestExtension:
    def test_read_setup_file(self):
        # trying to read a Setup file
        # (sample extracted from the PyGame project)
        setup = os.path.join(os.path.dirname(__file__), 'Setup.sample')

        exts = read_setup_file(setup)
        names = [ext.name for ext in exts]
        names.sort()

        # here are the extensions read_setup_file should have created
        # out of the file
        wanted = [
            '_arraysurfarray',
            '_camera',
            '_numericsndarray',
            '_numericsurfarray',
            'base',
            'bufferproxy',
            'cdrom',
            'color',
            'constants',
            'display',
            'draw',
            'event',
            'fastevent',
            'font',
            'gfxdraw',
            'image',
            'imageext',
            'joystick',
            'key',
            'mask',
            'mixer',
            'mixer_music',
            'mouse',
            'movie',
            'overlay',
            'pixelarray',
            'pypm',
            'rect',
            'rwobject',
            'scrap',
            'surface',
            'surflock',
            'time',
            'transform',
        ]

        assert names == wanted

    def test_extension_init(self):
        # the first argument, which is the name, must be a string
        with pytest.raises(AssertionError):
            Extension(1, [])
        ext = Extension('name', [])
        assert ext.name == 'name'

        # the second argument, which is the list of files, must
        # be a list of strings
        with pytest.raises(AssertionError):
            Extension('name', 'file')
        with pytest.raises(AssertionError):
            Extension('name', ['file', 1])
        ext = Extension('name', ['file1', 'file2'])
        assert ext.sources == ['file1', 'file2']

        # others arguments have defaults
        for attr in (
            'include_dirs',
            'define_macros',
            'undef_macros',
            'library_dirs',
            'libraries',
            'runtime_library_dirs',
            'extra_objects',
            'extra_compile_args',
            'extra_link_args',
            'export_symbols',
            'swig_opts',
            'depends',
        ):
            assert getattr(ext, attr) == []

        assert ext.language is None
        assert ext.optional is None

        # if there are unknown keyword options, warn about them
        with check_warnings() as w:
            warnings.simplefilter('always')
            ext = Extension('name', ['file1', 'file2'], chic=True)

        assert len(w.warnings) == 1
        assert str(w.warnings[0].message) == "Unknown Extension options: 'chic'"


text:
```
object(PowerEcommerce\Pattern\Creational\Builder\Product)[4]
  public 'part' => string 'Builder' (length=7)
```


text:
'''Public section, including homepage and signup.'''
from flask import (
	Blueprint,
	request,
	render_template,
	flash,
	url_for,
	redirect,
	session,
	)
from flask.ext.login import (
	login_user,
	login_required,
	logout_user,
	)
from  sqlalchemy.sql.expression import func

from wordup.extensions import login_manager
from wordup.user.models import User
from wordup.public.forms import LoginForm
from wordup.user.forms import RegisterForm
from wordup.utils import flash_errors
from wordup.database import db
from wordup.word.models import (
	Word,
	Prompt,
	Audio,
	Definition,
	)
from wordup.word.forms import SpellTry

blueprint = Blueprint('words', __name__, static_folder="../static")

@blueprint.route('/word')
def getword(word=None):
	form = SpellTry
	myword = Word.query.order_by(func.random()).first()
	return render_template('word/word.html', word=myword, myword=myword, spelltry_form=form)

# @blueprint.route('/word/<word>')
# def getword(word=None):
# 	myword = Word.query.filter_by(word=word).first()
# 	return render_template('word/word.html', word=word, myword=myword)
#


text:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>PacketCollector.Configuration (smack-core 4.2.0-beta3-SNAPSHOT API)</title>
<meta name="date" content="2016-08-29">
<link rel="stylesheet" type="text/css" href="../../../stylesheet.css" title="Style">

JavaScript is disabled on your browser.

Skip navigation links

Overview

Package

Class

Tree

Deprecated

Index

Help

Prev Class

Next Class

Frames

No Frames

All Classes

Summary:

Nested |

Field |

Constr |

Method

Detail:

Field |

Constr |

Method

org.jivesoftware.smack

Class PacketCollector.Configuration

java.lang.Object

org.jivesoftware.smack.PacketCollector.Configuration

Enclosing class:

PacketCollector

public static final class PacketCollector.Configuration
extends java.lang.Object

Method Summary

All Methods Instance Methods Concrete Methods Deprecated Methods

Modifier and Type
Method and Description

PacketCollector.Configuration
setCollectorToReset(PacketCollector collector)

Set the collector which timeout for the next result is reset once this collector collects
 a packet.

PacketCollector.Configuration
setPacketFilter(StanzaFilter packetFilter)

Deprecated.

use setStanzaFilter(StanzaFilter) instead.

PacketCollector.Configuration
setSize(int size)

Set the maximum size of this collector, i.e.

PacketCollector.Configuration
setStanzaFilter(StanzaFilter stanzaFilter)

Set the stanza filter used by this collector.

Methods inherited from class java.lang.Object

clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait

Method Detail

setPacketFilter

@Deprecated
public PacketCollector.Configuration setPacketFilter(StanzaFilter packetFilter)

Deprecated. use setStanzaFilter(StanzaFilter) instead.

Set the stanza(/packet) filter used by this collector. If null, then all packets will
 get collected by this collector.

Parameters:

packetFilter -

Returns:

a reference to this configuration.

setStanzaFilter

public PacketCollector.Configuration setStanzaFilter(StanzaFilter stanzaFilter)

Set the stanza filter used by this collector. If null, then all stanzas will
 get collected by this collector.

Parameters:

stanzaFilter -

Returns:

a reference to this configuration.

setSize

public PacketCollector.Configuration setSize(int size)

Set the maximum size of this collector, i.e. how many stanzas this collector will collect
 before dropping old ones.

Parameters:

size -

Returns:

a reference to this configuration.

setCollectorToReset

public PacketCollector.Configuration setCollectorToReset(PacketCollector collector)

Set the collector which timeout for the next result is reset once this collector collects
 a packet.

Parameters:

collector -

Returns:

a reference to this configuration.

Skip navigation links

Overview

Package

Class

Tree

Deprecated

Index

Help

Prev Class

Next Class

Frames

No Frames

All Classes

Summary:

Nested |

Field |

Constr |

Method

Detail:

Field |

Constr |

Method


text:
package com.vladsch.flexmark.experimental.util.sequence.managed;

import com.vladsch.flexmark.util.sequence.BasedSequence;
import org.junit.Test;

import static org.junit.Assert.*;

public class BaseSequenceEntryTest {
    @Test
    public void test_basic() {
        String input1 = "0123456789";
        String input2 = "0123456789";
        String input3 = "0123456789";
        String input4 = "012345678";
        String input5 = "1234567890";

        // NOTE: can use BasedSequence.of() since management is not implemented by default
        BasedSequence sequence1 = BasedSequence.of(input1);
        BasedSequence sequence2 = BasedSequence.of(input2);
        BasedSequence sequence3 = BasedSequence.of(input3);
        BasedSequence sequence4 = BasedSequence.of(input4);
        BasedSequence sequence5 = BasedSequence.of(input5);

        BaseSequenceEntry entry = new BaseSequenceEntry();

        // getEqualsCall(): 0 - quick class and/or length, 1 - hash, 2 - quick lookup, 3 - content
        int[] equalsCall = { 0 };
        assertTrue(entry.testEquals(sequence1, input1, equalsCall));
        assertEquals(0, equalsCall[0]);

        assertTrue(entry.testEquals(sequence1, input2, equalsCall));
        assertEquals(0, equalsCall[0]);
        assertTrue(entry.testEquals(sequence1, input3, equalsCall));
        assertEquals(0, equalsCall[0]);
        assertFalse(entry.testEquals(sequence1, input4, equalsCall));
        assertEquals(0, equalsCall[0]);
        assertFalse(entry.testEquals(sequence1, input5, equalsCall));
        assertEquals(1, equalsCall[0]);
        assertTrue(entry.testEquals(sequence1, sequence1, equalsCall));
        assertEquals(0, equalsCall[0]);

        // first time around expensive content comparison, second time hash map lookup i
        assertTrue(entry.testEquals(sequence1, sequence2, equalsCall));
        assertEquals(3, equalsCall[0]);
        assertTrue(entry.testEquals(sequence1, sequence2, equalsCall));
        assertEquals(2, equalsCall[0]);

        sequence2 = null;

        // should release weak hash map ref to sequence2
        System.gc();

        sequence2 = BasedSequence.of(input2);

        // first time around expensive content comparison, second time hash map lookup i
        assertTrue(entry.testEquals(sequence1, sequence2, equalsCall));
        assertEquals(3, equalsCall[0]);
        assertTrue(entry.testEquals(sequence1, sequence2, equalsCall));
        assertEquals(2, equalsCall[0]);

        assertTrue(entry.testEquals(sequence1, sequence3, equalsCall));
        assertEquals(2, equalsCall[0]);

        assertFalse(entry.testEquals(sequence1, sequence4, equalsCall));
        assertEquals(0, equalsCall[0]);

        assertFalse(entry.testEquals(sequence1, sequence5, equalsCall));
        assertEquals(1, equalsCall[0]);
    }
}


text:
external help file: AutomatedLab-help.xml
Module Name: AutomatedLab
online version: https://automatedlab.org/en/latest/AutomatedLab/en-us/Disable-LabTelemetry
schema: 2.0.0
---

# Disable-LabTelemetry

## SYNOPSIS
Disable the transmission of telemetry

## SYNTAX

```
Disable-LabTelemetry [<CommonParameters>]
```

## DESCRIPTION
Disable the transmission of telemetry by setting the environment variable AUTOMATEDLAB_TELEMETRY_OPTOUT to 1

## EXAMPLES

### Example 1
```powershell
PS C:\> Disable-LabTelemetry
```

Disable telemetry until Enable-LabTelemetry is used.

## PARAMETERS

### CommonParameters
This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216).

## INPUTS

### None
## OUTPUTS

### System.Object
## NOTES

## RELATED LINKS


text:
<?php

/**
 * Adminhtml grid item renderer datetime
 *
 * @category   Mage
 * @package    Mage_Adminhtml
 * @author     Magento Core Team <core@magentocommerce.com>
 */

class Mage_Adminhtml_Block_Widget_Grid_Column_Renderer_Datetime
    extends Mage_Adminhtml_Block_Widget_Grid_Column_Renderer_Abstract
{
    /**
     * Date format string
     */
    protected static $_format = null;

    /**
     * Retrieve datetime format
     *
     * @return unknown
     */
    protected function _getFormat()
    {
        $format = $this->getColumn()->getFormat();
        if (!$format) {
            if (is_null(self::$_format)) {
                try {
                    self::$_format = Mage::app()->getLocale()->getDateTimeFormat(
                        Mage_Core_Model_Locale::FORMAT_TYPE_MEDIUM
                    );
                }
                catch (Exception $e) {
                    Mage::logException($e);
                }
            }
            $format = self::$_format;
        }
        return $format;
    }

    /**
     * Renders grid column
     *
     * @param   Varien_Object $row
     * @return  string
     */
    public function render(Varien_Object $row)
    {
        if ($data = $this->_getValue($row)) {
            $format = $this->_getFormat();
            try {
                $data = Mage::app()->getLocale()
                    ->date($data, Varien_Date::DATETIME_INTERNAL_FORMAT)->toString($format);
            }
            catch (Exception $e)
            {
                $data = Mage::app()->getLocale()
                    ->date($data, Varien_Date::DATETIME_INTERNAL_FORMAT)->toString($format);
            }
            return $data;
        }
        return $this->getColumn()->getDefault();
    }
}


text:
/* this file has been autogenerated by vtkNodeJsWrap */
/* editing this might proof futile */

#define VTK_WRAPPING_CXX
#define VTK_STREAMS_FWD_ONLY
#include <nan.h>

#include "vtkObjectWrap.h"
#include "vtkInputStreamWrap.h"
#include "../../plus/plus.h"

using namespace v8;

extern Nan::Persistent<v8::Object> vtkNodeJsNoWrap;
Nan::Persistent<v8::FunctionTemplate> VtkInputStreamWrap::ptpl;

VtkInputStreamWrap::VtkInputStreamWrap()
{ }

VtkInputStreamWrap::VtkInputStreamWrap(vtkSmartPointer<vtkInputStream> _native)
{ native = _native; }

VtkInputStreamWrap::~VtkInputStreamWrap()
{ }

void VtkInputStreamWrap::Init(v8::Local<v8::Object> exports)
{
	Nan::SetAccessor(exports, Nan::New("vtkInputStream").ToLocalChecked(), ConstructorGetter);
	Nan::SetAccessor(exports, Nan::New("InputStream").ToLocalChecked(), ConstructorGetter);
}

void VtkInputStreamWrap::ConstructorGetter(
	v8::Local<v8::String> property,
	const Nan::PropertyCallbackInfo<v8::Value>& info)
{
	InitPtpl();
	info.GetReturnValue().Set(Nan::New(ptpl)->GetFunction());
}

void VtkInputStreamWrap::InitPtpl()
{
	if (!ptpl.IsEmpty()) return;
	v8::Local<v8::FunctionTemplate> tpl = Nan::New<v8::FunctionTemplate>(New);
	VtkObjectWrap::InitPtpl( );
	tpl->Inherit(Nan::New<FunctionTemplate>(VtkObjectWrap::ptpl));
	tpl->SetClassName(Nan::New("VtkInputStreamWrap").ToLocalChecked());
	tpl->InstanceTemplate()->SetInternalFieldCount(1);

	Nan::SetPrototypeMethod(tpl, "EndReading", EndReading);
	Nan::SetPrototypeMethod(tpl, "endReading", EndReading);

	Nan::SetPrototypeMethod(tpl, "GetClassName", GetClassName);
	Nan::SetPrototypeMethod(tpl, "getClassName", GetClassName);

	Nan::SetPrototypeMethod(tpl, "IsA", IsA);
	Nan::SetPrototypeMethod(tpl, "isA", IsA);

	Nan::SetPrototypeMethod(tpl, "NewInstance", NewInstance);
	Nan::SetPrototypeMethod(tpl, "newInstance", NewInstance);

	Nan::SetPrototypeMethod(tpl, "SafeDownCast", SafeDownCast);
	Nan::SetPrototypeMethod(tpl, "safeDownCast", SafeDownCast);

	Nan::SetPrototypeMethod(tpl, "StartReading", StartReading);
	Nan::SetPrototypeMethod(tpl, "startReading", StartReading);

#ifdef VTK_NODE_PLUS_VTKINPUTSTREAMWRAP_INITPTPL
	VTK_NODE_PLUS_VTKINPUTSTREAMWRAP_INITPTPL
#endif
	ptpl.Reset( tpl );
}

void VtkInputStreamWrap::New(const Nan::FunctionCallbackInfo<v8::Value>& info)
{
	if(!info.IsConstructCall())
	{
		Nan::ThrowError("Constructor not called in a construct call.");
		return;
	}

	if(info.Length() == 0)
	{
		vtkSmartPointer<vtkInputStream> native = vtkSmartPointer<vtkInputStream>::New();
		VtkInputStreamWrap* obj = new VtkInputStreamWrap(native);
		obj->Wrap(info.This());
	}
	else
	{
		if(info[0]->ToObject() != vtkNodeJsNoWrap )
		{
			Nan::ThrowError("Parameter Error");
			return;
		}
	}

	info.GetReturnValue().Set(info.This());
}

void VtkInputStreamWrap::EndReading(const Nan::FunctionCallbackInfo<v8::Value>& info)
{
	VtkInputStreamWrap *wrapper = ObjectWrap::Unwrap<VtkInputStreamWrap>(info.Holder());
	vtkInputStream *native = (vtkInputStream *)wrapper->native.GetPointer();
		if(info.Length() != 0)
	{
		Nan::ThrowError("Too many parameters.");
		return;
	}
	native->EndReading();
}

void VtkInputStreamWrap::GetClassName(const Nan::FunctionCallbackInfo<v8::Value>& info)
{
	VtkInputStreamWrap *wrapper = ObjectWrap::Unwrap<VtkInputStreamWrap>(info.Holder());
	vtkInputStream *native = (vtkInputStream *)wrapper->native.GetPointer();
	char const * r;
	if(info.Length() != 0)
	{
		Nan::ThrowError("Too many parameters.");
		return;
	}
	r = native->GetClassName();
	info.GetReturnValue().Set(Nan::New(r).ToLocalChecked());
}

void VtkInputStreamWrap::IsA(const Nan::FunctionCallbackInfo<v8::Value>& info)
{
	VtkInputStreamWrap *wrapper = ObjectWrap::Unwrap<VtkInputStreamWrap>(info.Holder());
	vtkInputStream *native = (vtkInputStream *)wrapper->native.GetPointer();
	if(info.Length() > 0 && info[0]->IsString())
	{
		Nan::Utf8String a0(info[0]);
		int r;
		if(info.Length() != 1)
		{
			Nan::ThrowError("Too many parameters.");
			return;
		}
		r = native->IsA(
			*a0
		);
		info.GetReturnValue().Set(Nan::New(r));
		return;
	}
	Nan::ThrowError("Parameter mismatch");
}

void VtkInputStreamWrap::NewInstance(const Nan::FunctionCallbackInfo<v8::Value>& info)
{
	VtkInputStreamWrap *wrapper = ObjectWrap::Unwrap<VtkInputStreamWrap>(info.Holder());
	vtkInputStream *native = (vtkInputStream *)wrapper->native.GetPointer();
	vtkInputStream * r;
	if(info.Length() != 0)
	{
		Nan::ThrowError("Too many parameters.");
		return;
	}
	r = native->NewInstance();
	VtkInputStreamWrap::InitPtpl();
	v8::Local<v8::Value> argv[1] =
		{ Nan::New(vtkNodeJsNoWrap) };
	v8::Local<v8::Function> cons =
		Nan::New<v8::FunctionTemplate>(VtkInputStreamWrap::ptpl)->GetFunction();
	v8::Local<v8::Object> wo = cons->NewInstance(1, argv);
	VtkInputStreamWrap *w = new VtkInputStreamWrap();
	w->native = r;
	w->Wrap(wo);
	info.GetReturnValue().Set(wo);
}

void VtkInputStreamWrap::SafeDownCast(const Nan::FunctionCallbackInfo<v8::Value>& info)
{
	VtkInputStreamWrap *wrapper = ObjectWrap::Unwrap<VtkInputStreamWrap>(info.Holder());
	vtkInputStream *native = (vtkInputStream *)wrapper->native.GetPointer();
	if(info.Length() > 0 && info[0]->IsObject() && (Nan::New(VtkObjectWrap::ptpl))->HasInstance(info[0]))
	{
		VtkObjectWrap *a0 = ObjectWrap::Unwrap<VtkObjectWrap>(info[0]->ToObject());
		vtkInputStream * r;
		if(info.Length() != 1)
		{
			Nan::ThrowError("Too many parameters.");
			return;
		}
		r = native->SafeDownCast(
			(vtkObject *) a0->native.GetPointer()
		);
		VtkInputStreamWrap::InitPtpl();
		v8::Local<v8::Value> argv[1] =
			{ Nan::New(vtkNodeJsNoWrap) };
		v8::Local<v8::Function> cons =
			Nan::New<v8::FunctionTemplate>(VtkInputStreamWrap::ptpl)->GetFunction();
		v8::Local<v8::Object> wo = cons->NewInstance(1, argv);
		VtkInputStreamWrap *w = new VtkInputStreamWrap();
		w->native = r;
		w->Wrap(wo);
		info.GetReturnValue().Set(wo);
		return;
	}
	Nan::ThrowError("Parameter mismatch");
}

void VtkInputStreamWrap::StartReading(const Nan::FunctionCallbackInfo<v8::Value>& info)
{
	VtkInputStreamWrap *wrapper = ObjectWrap::Unwrap<VtkInputStreamWrap>(info.Holder());
	vtkInputStream *native = (vtkInputStream *)wrapper->native.GetPointer();
		if(info.Length() != 0)
	{
		Nan::ThrowError("Too many parameters.");
		return;
	}
	native->StartReading();
}


text:
package holon.util.collection;

import java.util.ArrayList;
import java.util.List;

public class Iterables
{
    public static <T> List<T> toList( Iterable<T> iterable )
    {
        ArrayList<T> ts = new ArrayList<>();
        iterable.forEach( ts::add );
        return ts;
    }
}


text:
const gulp = require('gulp');
const browserify = require('browserify');
const babelify = require('babelify');
const source = require('vinyl-source-stream');
const sourcemaps = require('gulp-sourcemaps');
const buffer = require('vinyl-buffer');
const rename = require('gulp-rename');

module.exports = () => {
  return browserify('app/js/main.js', { debug: true }).transform(babelify, { presets: ['es2017'], sourceMaps: true })
    .bundle()
    .pipe(source('app/js/main.js'))
    .pipe(buffer())
    .pipe(rename({
      dirname: '',
      basename: 'main',
      extname: '.js',
    }))
    .pipe(sourcemaps.init({ loadMaps: true }))
    .pipe(sourcemaps.write('./'))
    .pipe(gulp.dest('public/js'));
};


text:
layout: default
title: Installation
---

# Prerequisites

`node.js` (`npm` included) required, please follow the installation guide:

* https://nodejs.org/en/download/package-manager/
* https://nodejs.org/en/download/

You might wanna choose the latest stable release on the list.

Then verify the result:

	$ node -v
	$ npm -v

# Installation

Choose one of the following ways to install leetcode-cli:

### From npm

This will install the latest stable release, but not include the latest development version.

    $ npm install -g leetcode-cli

### From GitHub

This will install the latest development version on GitHub.

	$ npm install -g skygragon/leetcode-cli

### From local source

Similar with above, while you can introduce your changes as you like.

    $ git clone http://github.com/skygragon/leetcode-cli
    $ cd leetcode-cli && ./bin/install

Then verify the result:

	$ leetcode version


text:
const defaultResponse = {
  // `data` is the response that was provided by the server
  data: {},

  // `status` is the HTTP status code from the server response
  status: 200,

  // `statusText` is the HTTP status message from the server response
  statusText: 'OK',

  // `headers` the headers that the server responded with
  // All header names are lower cased
  headers: {},

  // `config` is the config that was provided to `axios` for the request
  config: {},

  // `request` is the request that generated this response
  // It is the last ClientRequest instance in node.js (in redirects)
  // and an XMLHttpRequest instance in the browser
  request: {},
};

const resolve = (options = {}) => {
  return Promise.resolve({
    defaultResponse,
    ...options,
  });
};

const client = {
  get: jest.fn(resolve),
  post: jest.fn(resolve),
  put: jest.fn(resolve),
  patch: jest.fn(resolve),
  delete: jest.fn(resolve),
};

client.__setResponse = (method, options) => {
  client[method.toLowerCase()].mockImplementationOnce(() => resolve(options));
};

export default client;


text:
package org.apache.eagle.storage.hbase.query.coprocessor.impl;

import org.apache.eagle.log.entity.meta.EntityDefinition;
import org.apache.eagle.query.aggregate.AggregateFunctionType;
import org.apache.eagle.storage.hbase.query.coprocessor.generated.AggregateProtos;
import org.apache.eagle.storage.hbase.query.coprocessor.*;
import org.apache.hadoop.hbase.client.HTableInterface;
import org.apache.hadoop.hbase.client.Scan;
import org.apache.hadoop.hbase.client.coprocessor.Batch;
import org.apache.hadoop.hbase.ipc.BlockingRpcCallback;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * Not thread safe
 *
 * @since : 11/2/14,2014
 */
public class AggregateClientImpl implements AggregateClient {
	private final static Logger LOG = LoggerFactory.getLogger(AggregateClient.class);
	private AggregateResultCallback callback;

	private void checkNotNull(Object obj,String name) {
		if(obj==null) throw new NullPointerException(name+" is null");
	}

	@Override
	public AggregateResult aggregate(final HTableInterface table,
	                                       final EntityDefinition entityDefinition,
	                                       final Scan scan,
	                                       final List<String> groupbyFields,
	                                       final List<AggregateFunctionType> aggregateFuncTypes,
	                                       final List<String> aggregatedFields,
	                                       final boolean timeSeries,
	                                       final long startTime,
	                                       final long endTime,
	                                       final long intervalMin) throws IOException {
		checkNotNull(entityDefinition,"entityDefinition");
		final List<AggregateFunctionType> _aggregateFuncTypes = convertToCoprocessorAggregateFunc(aggregateFuncTypes);
		final List<byte[]> _aggregateFuncTypesBytes = AggregateFunctionType.toBytesList(_aggregateFuncTypes);
//		if(timeSeries) TimeSeriesAggregator.validateTimeRange(startTime,endTime,intervalMin);
		callback = new AggregateResultCallbackImpl(aggregateFuncTypes);
		try{
			if(!LOG.isDebugEnabled()){
				LOG.info("Going to exec coprocessor: "+AggregateProtocol.class.getSimpleName());
			}else{
				LOG.debug("Going to exec coprocessor: "+AggregateProtocol.class.getName());
			}

//			table.coprocessorExec(AggregateProtocol.class,scan.getStartRow(),scan.getStopRow(),new Batch.Call<AggregateProtocol, AggregateResult>(){
//				@Override
//				public AggregateResult call(AggregateProtocol instance) throws IOException {
//					if(timeSeries){
//						return instance.aggregate(entityDefinition, scan, groupbyFields, _aggregateFuncTypesBytes, aggregatedFields,startTime,endTime,intervalMin);
//					}else{
//						return instance.aggregate(entityDefinition, scan, groupbyFields, _aggregateFuncTypesBytes, aggregatedFields);
//					}
//				}
//			},callback);

          table.coprocessorService(AggregateProtos.AggregateProtocol.class, scan.getStartRow(), scan.getStopRow(), new Batch.Call<AggregateProtos.AggregateProtocol, AggregateProtos.AggregateResult>() {
              @Override
              public AggregateProtos.AggregateResult call(AggregateProtos.AggregateProtocol instance) throws IOException {
                  BlockingRpcCallback<AggregateProtos.AggregateResult> rpcCallback = new BlockingRpcCallback<AggregateProtos.AggregateResult>();
                  if(timeSeries){
                      AggregateProtos.TimeSeriesAggregateRequest timeSeriesAggregateRequest = ProtoBufConverter
                              .toPBTimeSeriesRequest(
                                      entityDefinition,
                                      scan,
                                      groupbyFields,
                                      _aggregateFuncTypesBytes,
                                      aggregatedFields,
                                      startTime,
                                      endTime,
                                      intervalMin);
                      instance.timeseriesAggregate(null, timeSeriesAggregateRequest, rpcCallback);
                      return rpcCallback.get();
					}else{
                      AggregateProtos.AggregateRequest aggregateRequest = ProtoBufConverter.toPBRequest(
                                      entityDefinition, scan, groupbyFields, _aggregateFuncTypesBytes, aggregatedFields);
                      instance.aggregate(null, aggregateRequest, rpcCallback);
                      return rpcCallback.get();
					}
              }
          }, callback);
		} catch (Throwable t){
			LOG.error(t.getMessage(),t);
			throw new IOException(t);
		}
		return callback.result();
	}

//	@Override
//	public void result(final GroupbyKeyValueCreationListener[] listeners) {
//		callback.asyncRead(Arrays.asList(listeners));
//	}

	@Override
	public AggregateResult  aggregate(HTableInterface table, EntityDefinition entityDefinition, Scan scan, List<String> groupbyFields, List<AggregateFunctionType> aggregateFuncTypes, List<String> aggregatedFields) throws IOException {
		return this.aggregate(table,entityDefinition,scan,groupbyFields,aggregateFuncTypes,aggregatedFields,false,0,0,0);
	}

	/**
	 *
	 *

	 *   Convert client side funcs to server side funcs, especially for avg
	 *

	 *

	 *
avg:
	 *    Coprocessor[ <sum,count>] => Callback[(sum1+sum2+...+sumn)/(count1+count2+...+countn)]
	 *

	 *

	 * @param funcs List<AggregateFunctionType>
	 * @return
	 */
	private List<AggregateFunctionType> convertToCoprocessorAggregateFunc(List<AggregateFunctionType> funcs){
		List<AggregateFunctionType> copy = new ArrayList<AggregateFunctionType>(funcs);
		for(int i=0;i<funcs.size();i++){
			AggregateFunctionType func = copy.get(i);
			if(AggregateFunctionType.avg.equals(func)){
				copy.set(i,AggregateFunctionType.sum);
			}
		}
		return copy;
	}
}


text:
<?php

namespace cs\h;
use
	nazarpc\BananaHTML,
	cs\Config,
	cs\Language,
	cs\Page,
	cs\Session;
/**
 * Class for HTML code rendering in accordance with the standards of HTML5, and with useful syntax extensions for simpler usage
 */
abstract class Base extends BananaHTML {
	/**
	 * Special processing for URLs with hash
	 *
	 * @static
	 *
	 * @param string $url
	 *
	 * @return string
	 */
	protected static function url_with_hash ($url) {
		/**
		 * @var \cs\_SERVER $_SERVER
		 */
		return $_SERVER->request_uri.$url;
	}
	/**
	 * Convert relative URL to absolute
	 *
	 * @static
	 *
	 * @param string $url
	 *
	 * @return string
	 */
	protected static function absolute_url ($url) {
		/**
		 * If Config not initialized yet - method will return `false`, which will be interpreted as empty string
		 */
		return Config::instance(true)->base_url()."/$url";
	}
	/**
	 * Allows to add something to inner of form, for example, hidden session input to prevent CSRF
	 *
	 * @static
	 *
	 * @return string
	 */
	protected static function form_csrf () {
		if (
			class_exists('\\cs\\Session', false) &&
			$Session = Session::instance(true)
		) {
			return static::input(
				[
					'value' => $Session->get_id(),
					'type'  => 'hidden',
					'name'  => 'session'
				]
			);
		}
		return '';
	}
	/**
	 * CleverStyle CMS-specific processing of attributes
	 *
	 * @static
	 *
	 * @param array $attributes
	 */
	protected static function pre_processing (&$attributes) {
		if (isset($attributes['data-title']) && $attributes['data-title'] !== false) {
			$attributes['title'] = static::prepare_attr_value($attributes['data-title']);
			unset($attributes['data-title']);
			$attributes['data-uk-tooltip'] = '{animation:true,delay:200}';
		}
	}
	/**
	 * Sometimes HTML code can be intended
	 *
	 * This function allows to store inner text of tags, that are sensitive to this operation (textarea, pre, code), and return some identifier.
	 * Later, at page generation, this identifier will be replaced by original text again.
	 *
	 * @param string $text
	 *
	 * @return string
	 */
	protected static function indentation_protection ($text) {
		$uniqid = uniqid('html_replace_');
		Page::instance()->replace($uniqid, $text);
		return $uniqid;
	}
	/**
	 * Pseudo tag for labels with tooltips, specified input is translation item of $L object,
	 * input_into item of $L is content of tooltip
	 *
	 * @static
	 *
	 * @param array|string $in
	 * @param array        $data
	 *
	 * @return mixed
	 */
	static function info ($in = '', $data = []) {
		if (isset($in['insert']) || isset($data['insert'])) {
			return static::__callStatic(__FUNCTION__, func_get_args());
		}
		if ($in === false) {
			return '';
		} elseif (is_array($in)) {
			return static::__callStatic(__FUNCTION__, [$in, $data]);
		}
		$L = Language::instance();
		if (Config::instance(true)->core['show_tooltips']) {
			return static::span($L->$in, array_merge(['data-title' => $L->{$in.'_info'}], $data));
		} else {
			return static::span($L->$in, $data);
		}
	}
	/**
	 * Pseudo tag for inserting of icons
	 *
	 * @static
	 *
	 * @param string $class Icon name in jQuery UI CSS Framework, fow example, gear, note
	 * @param array  $data
	 *
	 * @return mixed
	 */
	static function icon ($class, $data = []) {
		if (isset($in['insert']) || isset($data['insert'])) {
			return static::__callStatic(__FUNCTION__, func_get_args());
		}
		if ($class === false) {
			return '';
		}
		@$data['class'] .= " uk-icon-$class";
		$data['level'] = 0;
		return static::span($data).' ';
	}
	/**
	 * Rendering of input[type=checkbox] with automatic adding labels and necessary classes
	 *
	 * @static
	 *
	 * @param array|string $in
	 * @param array        $data
	 *
	 * @return string
	 */
	static function checkbox ($in = [], $data = []) {
		if (self::common_checkbox_radio_pre($in, $data, __FUNCTION__, $return) !== false) {
			return $return;
		}
		if (@is_array($in['name']) || @is_array($in['id'])) {
			$items  = self::array_flip_3d($in);
			$return = '';
			foreach ($items as $item) {
				$return .= static::checkbox($item);
			}
			return $return;
		} else {
			self::common_checkbox_radio_post($in, $button_class);
			return static::span(
				static::label(
					static::u_wrap($in),
					[
						'for'        => $in['id'],
						'data-title' => isset($in['data-title']) ? $in['data-title'] : false,
						'class'      => $button_class
					]
				),
				[
					'data-uk-button-checkbox' => ''
				]
			);
		}
	}
	/**
	 * Rendering of input[type=radio] with automatic adding labels and necessary classes
	 *
	 * @static
	 *
	 * @param array|string $in
	 * @param array        $data
	 *
	 * @return string
	 */
	static function radio ($in = [], $data = []) {
		if (self::common_checkbox_radio_pre($in, $data, __FUNCTION__, $return) !== false) {
			return $return;
		}
		if (!isset($in['checked'])) {
			$in['checked'] = $in['value'][0];
		}
		$items   = self::array_flip_3d($in);
		$content = '';
		foreach ($items as $item) {
			self::common_checkbox_radio_post($item, $button_class);
			$content .= static::label(
				static::u_wrap($item),
				[
					'for'        => $item['id'],
					'data-title' => isset($item['data-title']) ? $item['data-title'] : false,
					'class'      => $button_class
				]
			);
		}
		return static::span(
			$content,
			[
				'class'                => 'uk-button-group',
				'data-uk-button-radio' => ''
			]
		);
	}
	/**
	 * @static
	 *
	 * @param array|string $in
	 * @param array        $data
	 * @param string       $type
	 * @param string       $return
	 *
	 * @return bool|string
	 */
	protected static function common_checkbox_radio_pre (&$in, $data, $type, &$return) {
		if (isset($in['insert']) || isset($data['insert'])) {
			return static::__callStatic($type, func_get_args());
		}
		if ($in === false) {
			return '';
		}
		$in = static::input_merge($in, $data);
		/** @noinspection NotOptimalIfConditionsInspection */
		if (is_array_indexed($in) && is_array($in[0])) {
			return static::__callStatic($type, [$in, $data]);
		}
		$in['type'] = $type;
		return false;
	}
	/**
	 * @static
	 *
	 * @param array  $item
	 * @param string $button_class
	 */
	protected static function common_checkbox_radio_post (&$item, &$button_class) {
		$item['tag']  = 'input';
		$button_class = 'uk-button';
		if (!isset($item['id'])) {
			$item['id'] = uniqid('input_');
		}
		if (isset($item['value'], $item['checked'])) {
			$item['checked'] = $item['value'] == $item['checked'];
			if ($item['checked']) {
				$button_class .= ' uk-active';
			}
		}
		if (isset($item['value'])) {
			$item['value'] = self::prepare_attr_value($item['value']);
		}
		if (isset($item['class'])) {
			$button_class .= " $item[class]";
		}
	}
}


text:
% LABEL_DIFFUSION simple label diffusion transformation.
%
% This function performs a simple label diffusion transformation
% for use in propagation_kernel.m. Here the features are
% discrete distributions and these distributions are propagated
% along the edges of a graph.
%
% For use in propagation_kernel.m, a closure would be created
% containing the adjacency matrix A, e.g.:
%
%   transformation = @(features) label_diffusion(features, A);
%
% Usage:
%
%   features = label_diffusion(features, A)
%
% Inputs:
%
%   features: an (n x k) matrix of features, where n is the number of
%             nodes in all graphs and k is the dimension of the
%             features.
%          A: an (n x n) block diagonal matrix containing the
%             adjacency matrices for all graphs.
%
% Outputs:
%
%   features: an (n x k) matrix containing the updated features.
%
% See also PROPAGATION_KERNEL, LABEL_PROPAGATION.

% Copyright (c) Roman Garnett, 2012--2014.

function features = label_diffusion(features, A)

  features = A * features;

end


text:
package tournamentRunner;
/*
 * Represents a bracket using a tree data structure
 */
public class Match {
	private Match left, right, parent;
	private Person lPer, rPer, wPer;
	private String note;
	private int val;
	private boolean leaf;
	public static final String DEFAULT_WINNER_NAME = "No Winner", DEFAULT_WINNER_SCHOOL = "No School", DEFAULT_BLANK_NAME = "TBD", DEFAULT_BLANK_SCHOOL = "TBD";
	public Match(int size, Match parent, int i){		//Create a new Match with the parent match [parent], recursively call with [size] divided by 2 and [i] increased according to heap convention
		val=i;
		lPer = new Person(DEFAULT_BLANK_NAME, DEFAULT_BLANK_SCHOOL);
		rPer = new Person(DEFAULT_BLANK_NAME, DEFAULT_BLANK_SCHOOL);
		wPer = new Person(DEFAULT_WINNER_NAME,DEFAULT_WINNER_SCHOOL);
		note = "No information availible yet";
		this.parent = parent;
		if(size<=2){
			leaf = true;
			return;
		}
		left = new Match(size/2, this,i*2);
		right = new Match(size/2, this,i*2+1);
	}
	/*
	 * Add a new Person to the bracket, with the given seed.
	 * Returns true if no the seed exists and is empty, otherwise false
	 *
	 * Use the following algorithm to calculate seeds: the top receives the parent passed seed (starting with one),
	 * and the bottom receives the size of the bracket at that level, plus one, minus the top seed, performed recursively
	 */
	public boolean addPerson(Person person, int seed, int curLoc, int size){

		if(leaf && (seed==curLoc || seed == (size+1)-curLoc)){
			if(lPer.getName().equals("TBD") && seed == curLoc){lPer = person; return true;}
			else if(rPer.getName().equals("TBD") && seed == (size+1)-curLoc){rPer = person; return true;}
			return false;
		}
		if(!leaf && right.addPerson(person,seed,curLoc,size*2))	return true;
		else if(!leaf && left.addPerson(person,seed,(size+1)-curLoc,size*2))	return true;
		return false;
	}

	/*
	 * Attempt to advance the given person one match in the bracket.
	 * Find the match with a contestant that .equals() the submitted person, then:
	 * 			Move that person to the "winner" slot in the match
	 * 			Advance that person, if possible, to the next round of competition
	 * 			Set the match notes to the submitted notes string
	 */
	public boolean advancePerson(Person person, String notes, int matchID){
		if(matchID == val){
			if(lPer.equals(person))
				return promoteWinner(person, notes);
			else if(rPer.equals(person))
				return promoteWinner(person, notes);
			else
				return false;
		}
		return (!leaf && left.advancePerson(person, notes, matchID))?
				true: (!leaf && right.advancePerson(person, notes, matchID));
	}
	private boolean promoteWinner(Person per, String notes) {
		note = notes;
		wPer = per;
		if(parent!=null){
			parent.setPerson(per, val);
		}
		return true;
	}
	private void setPerson(Person per, int childVal){
		if(val*2 == childVal)
			rPer = per;
		else
			lPer = per;
	}
	/*
	 * Return a string containing the information for this bracket in postfix notation in the given format:
	 * 			Name/school of the left, right, and winner, followed by match notes and the value of the match, all comma separated
	 * 			One match per line, with children having values val*2 and val*2+1
	 */
	public String getInfo(){
		String result = "";
		if(!leaf){
			result += left.getInfo() + "\n";
			result += right.getInfo() + "\n";
		}
		result += lPer.getName() + "/" + lPer.getSchool() + ","
			+ rPer.getName() + "/" + rPer.getSchool() + ","
			+ wPer.getName() + "/" + wPer.getSchool() + "," + note + "," + val;
		return result;
	}
	/*
	 * Given a Match toString, recursively determine if the given match is equal to the current,
	 * 			then load information into the Match using the format specified in getInfo
	 */
	public void restoreState(String[] data) {
		if(Integer.parseInt(data[4])==val){
			lPer = new Person(data[0].substring(0,data[0].indexOf('/')),data[0].substring(data[0].indexOf('/')+1));
			rPer = new Person(data[1].substring(0,data[1].indexOf('/')),data[1].substring(data[1].indexOf('/')+1));
			wPer = new Person(data[2].substring(0,data[2].indexOf('/')),data[2].substring(data[2].indexOf('/')+1));
			note = data[3];
			return;
		}
		else{
			if(!leaf){
				left.restoreState(data);
				right.restoreState(data);
			}
		}

	}
	public void setMatch(Person left2, Person right2, Person winner, String notes, int index) {
		if(val==index){
			lPer= left2;
			rPer = right2;
			wPer = winner;
			note = notes;
			return;
		}
		if(!leaf){
			left.setMatch(left2, right2, winner, notes, index);
			right.setMatch(left2, right2, winner, notes, index);
		}
	}

	public void promoteByes(boolean fill){
		if(left != null)
			left.promoteByes(fill);
		if(right !=null)
			right.promoteByes(fill);
		if(fill){
		if(lPer.getName().equals(DEFAULT_BLANK_NAME))
			lPer = new Bye();
		if(rPer.getName().equals(DEFAULT_BLANK_NAME))
			rPer = new Bye();
		}
		if(lPer instanceof Bye) promoteWinner(rPer,"Bye");
		else if(rPer instanceof Bye) promoteWinner(lPer, "Bye");
	}
	public Person getLoser(int matchID) {
		if(matchID == val){
			if(wPer == lPer) return rPer;
			else return lPer;
		}
		Person per = left.getLoser(matchID);
		if(per!=null) return per;
		return right.getLoser(matchID);
	}
}


text: class OracleTablePresenter < TablePresenter; end