/*******************************************************************************
 * Mission Control Technologies, Copyright (c) 2009-2012, United States Government
 * as represented by the Administrator of the National Aeronautics and Space
 * Administration. All rights reserved.
 *
 * The MCT platform is licensed under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * http://www.apache.org/licenses/LICENSE-2.0.
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 *
 * MCT includes source code licensed under additional open source licenses. See
 * the MCT Open Source Licenses file included with this distribution or the About
 * MCT Licenses dialog available at runtime from the MCT Help menu for additional
 * information.
 *******************************************************************************/
package gov.nasa.arc.mct.util.ext.commands;

import gov.nasa.arc.mct.util.ext.commands.CmdProcessBuilder;

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

import org.testng.Assert;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;

public class TestCmdProcessBuilder {

	private CmdProcessBuilder cmdProcessBuilder;

	@BeforeMethod
	void setup() {
	    cmdProcessBuilder = new CmdProcessBuilder();

		System.setProperty("ExecLimitManagerPath", "src/test/resources/");
		System.setProperty("ExecLimitManagerScript", "launchLimitMgrTest.sh");
	}

	@Test
	public void testOSPlatformSupported() {

		Assert.assertNotNull(cmdProcessBuilder.checkOSPlatform());

		if (cmdProcessBuilder.isWindows()) {
		    cmdProcessBuilder.setOSPlatform("Windows XP");
		    Assert.assertTrue(cmdProcessBuilder.isWindows());
		}

		if (cmdProcessBuilder.isMacOS()) {
		    cmdProcessBuilder.setOSPlatform("Mac OS X");
		    Assert.assertTrue(cmdProcessBuilder.isMacOS());
		}

		if (cmdProcessBuilder.isUNIXLinux()) {
		    cmdProcessBuilder.setOSPlatform("Linux");
		    Assert.assertTrue(cmdProcessBuilder.isUNIXLinux());
		}

	}

	@Test(dependsOnMethods="testOSPlatformSupported")
	public void testCmdExecSuccessful() {
		final String PUI = "TESTCOMMANDPUI";
		final List<String> commandList = new ArrayList<String>();

		if (cmdProcessBuilder.isMacOS()) {
		    Assert.assertEquals(cmdProcessBuilder.checkOSPlatform(), "Mac OS X");
		    commandList.add(System.getProperty("ExecLimitManagerScript") + " " + PUI);
		} else if (cmdProcessBuilder.isUNIXLinux()) {
		    commandList.add(System.getProperty("ExecLimitManagerScript") + " " + PUI);
		}

		if (cmdProcessBuilder.isMacOS() || cmdProcessBuilder.isUNIXLinux()) {
		    Assert.assertTrue(cmdProcessBuilder.execMultipleCommands(System.getProperty("ExecLimitManagerPath"), commandList));
		}
	}

	@Test(dependsOnMethods="testOSPlatformSupported")
	public void testCmdExecFailed() {
		final String PUI = "XYZ123abc456";
		final List<String> commandList = new ArrayList<String>();

		if (cmdProcessBuilder.isUNIXLinux()) {
		    Assert.assertEquals(cmdProcessBuilder.checkOSPlatform(), "Linux");
		    commandList.add(System.getProperty("ExecLimitManagerScript") + " " + PUI);
		} else if (cmdProcessBuilder.isMacOS()) {
		    commandList.add(System.getProperty("ExecLimitManagerScript") + " " + PUI);
		}

		if (cmdProcessBuilder.isMacOS() || cmdProcessBuilder.isUNIXLinux()) {
		    Assert.assertFalse(cmdProcessBuilder.execMultipleCommands("/wrong/path/", commandList));
		}
	}

}


//! \file examples/Arrangement_on_surface_2/ex_vertical_ray_shooting.cpp
// Answering vertical ray-shooting queries.

#include <CGAL/Cartesian.h>
#include <CGAL/MP_Float.h>
#include <CGAL/Arr_segment_traits_2.h>
#include <CGAL/Arrangement_2.h>
#include <CGAL/Arr_walk_along_line_point_location.h>
#include <CGAL/Arr_trapezoid_ric_point_location.h>

#include "point_location_utils.h"

typedef CGAL::MP_Float                                          Number_type;
typedef CGAL::Cartesian<Number_type>                            Kernel;
typedef CGAL::Arr_segment_traits_2<Kernel>                      Traits_2;
typedef Traits_2::Point_2                                       Point_2;
typedef CGAL::Arrangement_2<Traits_2>                           Arrangement_2;
typedef CGAL::Arr_walk_along_line_point_location<Arrangement_2> Walk_pl;
typedef CGAL::Arr_trapezoid_ric_point_location<Arrangement_2>   Trap_pl;

int main ()
{
  // Construct the arrangement.
  Arrangement_2    arr;
  Walk_pl          walk_pl (arr);
  Trap_pl          trap_pl;

  construct_segments_arr (arr);

  // Perform some vertical ray-shooting queries using the walk strategy.
  Point_2          q1 (1, 4);
  Point_2          q2 (4, 3);
  Point_2          q3 (6, 3);

  vertical_ray_shooting_query (walk_pl, q1);
  vertical_ray_shooting_query (walk_pl, q2);
  vertical_ray_shooting_query (walk_pl, q3);

  // Attach the trapezoid-RIC object to the arrangement and perform queries.
  Point_2          q4 (3, 2);
  Point_2          q5 (5, 2);
  Point_2          q6 (1, 0);

  trap_pl.attach (arr);
  vertical_ray_shooting_query (trap_pl, q4);
  vertical_ray_shooting_query (trap_pl, q5);
  vertical_ray_shooting_query (trap_pl, q6);

  return 0;
}


#include "fm_envelope_set_edit_dialog.hpp"
#include "ui_fm_envelope_set_edit_dialog.h"
#include <QTreeWidgetItem>

FMEnvelopeSetEditDialog::FMEnvelopeSetEditDialog(std::vector<FMEnvelopeTextType> set, QWidget *parent) :
	QDialog(parent),
	ui(new Ui::FMEnvelopeSetEditDialog)
{
	ui->setupUi(this);

	setWindowFlags(windowFlags() ^ Qt::WindowContextHelpButtonHint);

	for (size_t i = 0; i < set.size(); ++i) {
		insertRow(static_cast<int>(i), set.at(i));
	}
}

FMEnvelopeSetEditDialog::~FMEnvelopeSetEditDialog()
{
	delete ui;
}

std::vector<FMEnvelopeTextType> FMEnvelopeSetEditDialog::getSet()
{
	std::vector<FMEnvelopeTextType> set;
	for (int i = 0; i < ui->treeWidget->topLevelItemCount(); ++i) {
		set.push_back(static_cast<FMEnvelopeTextType>(
						  qobject_cast<QComboBox*>(ui->treeWidget->itemWidget(
													   ui->treeWidget->topLevelItem(i), 1))->currentData().toInt()));
	}
	return set;
}

void FMEnvelopeSetEditDialog::swapset(int aboveRow, int belowRow)
{
	auto* tree = ui->treeWidget;
	QComboBox* belowBox = makeCombobox();
	belowBox->setCurrentIndex(qobject_cast<QComboBox*>(tree->itemWidget(tree->topLevelItem(belowRow), 1))->currentIndex());
	QTreeWidgetItem* below = tree->takeTopLevelItem(belowRow);
	if (tree->topLevelItemCount() > 2) {
		QComboBox* aboveBox = makeCombobox();
		aboveBox->setCurrentIndex(qobject_cast<QComboBox*>(tree->itemWidget(tree->topLevelItem(aboveRow), 1))->currentIndex());
		QTreeWidgetItem* above = tree->takeTopLevelItem(aboveRow);
		tree->insertTopLevelItem(aboveRow, below);
		tree->insertTopLevelItem(belowRow, above);
		tree->setItemWidget(below, 1, belowBox);
		tree->setItemWidget(above, 1, aboveBox);
	}
	else {
		tree->insertTopLevelItem(aboveRow, below);
		tree->setItemWidget(below, 1, belowBox);
	}

	if (!aboveRow || !belowRow) alignTreeOn1stItemChanged();	// Dummy set and delete to align

	for (int i = aboveRow; i < ui->treeWidget->topLevelItemCount(); ++i) {
		ui->treeWidget->topLevelItem(i)->setText(0, QString::number(i));
	}
}

void FMEnvelopeSetEditDialog::insertRow(int row, FMEnvelopeTextType type)
{
	if (row == -1) row = 0;
	auto item = new QTreeWidgetItem();
	item->setText(0, QString::number(row));
	QComboBox* box = makeCombobox();
	for (int i = 0; i < box->count(); ++i) {
		if (static_cast<FMEnvelopeTextType>(box->itemData(i).toInt()) == type) {
			box->setCurrentIndex(i);
			break;
		}
	}
	ui->treeWidget->insertTopLevelItem(row, item);
	ui->treeWidget->setItemWidget(item, 1, box);

	if (!row) alignTreeOn1stItemChanged();	// Dummy set and delete to align

	for (int i = row + 1; i < ui->treeWidget->topLevelItemCount(); ++i) {
		ui->treeWidget->topLevelItem(i)->setText(0, QString::number(i));
	}
}

QComboBox* FMEnvelopeSetEditDialog::makeCombobox()
{
	auto box = new QComboBox();
	box->addItem(tr("Skip"), static_cast<int>(FMEnvelopeTextType::Skip));
	box->addItem("AL", static_cast<int>(FMEnvelopeTextType::AL));
	box->addItem("FB", static_cast<int>(FMEnvelopeTextType::FB));
	box->addItem("AR1", static_cast<int>(FMEnvelopeTextType::AR1));
	box->addItem("DR1", static_cast<int>(FMEnvelopeTextType::DR1));
	box->addItem("SR1", static_cast<int>(FMEnvelopeTextType::SR1));
	box->addItem("RR1", static_cast<int>(FMEnvelopeTextType::RR1));
	box->addItem("SL1", static_cast<int>(FMEnvelopeTextType::SL1));
	box->addItem("TL1", static_cast<int>(FMEnvelopeTextType::TL1));
	box->addItem("KS1", static_cast<int>(FMEnvelopeTextType::KS1));
	box->addItem("ML1", static_cast<int>(FMEnvelopeTextType::ML1));
	box->addItem("DT1", static_cast<int>(FMEnvelopeTextType::DT1));
	box->addItem("AR2", static_cast<int>(FMEnvelopeTextType::AR2));
	box->addItem("DR2", static_cast<int>(FMEnvelopeTextType::DR2));
	box->addItem("SR2", static_cast<int>(FMEnvelopeTextType::SR2));
	box->addItem("RR2", static_cast<int>(FMEnvelopeTextType::RR2));
	box->addItem("SL2", static_cast<int>(FMEnvelopeTextType::SL2));
	box->addItem("TL2", static_cast<int>(FMEnvelopeTextType::TL2));
	box->addItem("KS2", static_cast<int>(FMEnvelopeTextType::KS2));
	box->addItem("ML2", static_cast<int>(FMEnvelopeTextType::ML2));
	box->addItem("DT2", static_cast<int>(FMEnvelopeTextType::DT2));
	box->addItem("AR3", static_cast<int>(FMEnvelopeTextType::AR3));
	box->addItem("DR3", static_cast<int>(FMEnvelopeTextType::DR3));
	box->addItem("SR3", static_cast<int>(FMEnvelopeTextType::SR3));
	box->addItem("RR3", static_cast<int>(FMEnvelopeTextType::RR3));
	box->addItem("SL3", static_cast<int>(FMEnvelopeTextType::SL3));
	box->addItem("TL3", static_cast<int>(FMEnvelopeTextType::TL3));
	box->addItem("KS3", static_cast<int>(FMEnvelopeTextType::KS3));
	box->addItem("ML3", static_cast<int>(FMEnvelopeTextType::ML3));
	box->addItem("DT3", static_cast<int>(FMEnvelopeTextType::DT3));
	box->addItem("AR4", static_cast<int>(FMEnvelopeTextType::AR4));
	box->addItem("DR4", static_cast<int>(FMEnvelopeTextType::DR4));
	box->addItem("SR4", static_cast<int>(FMEnvelopeTextType::SR4));
	box->addItem("RR4", static_cast<int>(FMEnvelopeTextType::RR4));
	box->addItem("SL4", static_cast<int>(FMEnvelopeTextType::SL4));
	box->addItem("TL4", static_cast<int>(FMEnvelopeTextType::TL4));
	box->addItem("KS4", static_cast<int>(FMEnvelopeTextType::KS4));
	box->addItem("ML4", static_cast<int>(FMEnvelopeTextType::ML4));
	box->addItem("DT4", static_cast<int>(FMEnvelopeTextType::DT4));
	return box;
}

/// Dummy set and delete to align
void FMEnvelopeSetEditDialog::alignTreeOn1stItemChanged()
{
	auto tmp = new QTreeWidgetItem();
	ui->treeWidget->insertTopLevelItem(1, tmp);
	delete ui->treeWidget->takeTopLevelItem(1);
}

void FMEnvelopeSetEditDialog::on_upToolButton_clicked()
{
	int curRow = ui->treeWidget->currentIndex().row();
	if (!curRow) return;

	swapset(curRow - 1, curRow);
	ui->treeWidget->setCurrentItem(ui->treeWidget->topLevelItem(curRow - 1));
}

void FMEnvelopeSetEditDialog::on_downToolButton_clicked()
{
	int curRow = ui->treeWidget->currentIndex().row();
	if (curRow == ui->treeWidget->topLevelItemCount() - 1) return;

	swapset(curRow, curRow + 1);
	ui->treeWidget->setCurrentItem(ui->treeWidget->topLevelItem(curRow + 1));
}

void FMEnvelopeSetEditDialog::on_addPushButton_clicked()
{
	int row = ui->treeWidget->currentIndex().row();
	insertRow(row, FMEnvelopeTextType::Skip);

	ui->treeWidget->setCurrentItem(ui->treeWidget->topLevelItem((row == -1) ? 0 : row));
	ui->upToolButton->setEnabled(true);
	ui->downToolButton->setEnabled(true);
	ui->removePushButton->setEnabled(true);
}

void FMEnvelopeSetEditDialog::on_removePushButton_clicked()
{
	int row = ui->treeWidget->currentIndex().row();
	delete ui->treeWidget->takeTopLevelItem(row);

	for (int i = row; i < ui->treeWidget->topLevelItemCount(); ++i) {
		ui->treeWidget->topLevelItem(i)->setText(0, QString::number(i));
	}

	if (!ui->treeWidget->topLevelItemCount()) {
		ui->upToolButton->setEnabled(false);
		ui->downToolButton->setEnabled(false);
		ui->removePushButton->setEnabled(false);
	}
}

void FMEnvelopeSetEditDialog::on_treeWidget_itemSelectionChanged()
{
	if (ui->treeWidget->currentIndex().row() == -1) {
		ui->upToolButton->setEnabled(false);
		ui->downToolButton->setEnabled(false);
		ui->removePushButton->setEnabled(false);
	}
	else {
		ui->upToolButton->setEnabled(true);
		ui->downToolButton->setEnabled(true);
		ui->removePushButton->setEnabled(true);
	}
}


// Copyright © Microsoft Open Technologies, Inc.
//
// All Rights Reserved
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS
// OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
// ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A
// PARTICULAR PURPOSE, MERCHANTABILITY OR NON-INFRINGEMENT.
//
// See the Apache License, Version 2.0 for the specific language
// governing permissions and limitations under the License.

/*! The class contains an incrementally expanding list of errors */
typedef enum
{
    /*! No error occurred. The value is added to make easier usage of functions that take error code,
     but no error condition occurred.*/
    AD_ERROR_SUCCEEDED = 0,

    /*! The user has cancelled the applicable UI prompts */
    AD_ERROR_USER_CANCEL = 1,

    /*! The method call contains one or more invalid arguments */
    AD_ERROR_INVALID_ARGUMENT = 2,

    /*! HTTP 401 (Unauthorized) response does not contain the OAUTH2 required header */
    AD_ERROR_MISSING_AUTHENTICATE_HEADER = 3,

    /*! HTTP 401 (Unauthorized) response's authentication header is in invalid format
     or does not contain expected values. */
    AD_ERROR_AUTHENTICATE_HEADER_BAD_FORMAT = 4,

    /*! An internal error occurs when the library did not receive
     a response from the server */
    AD_ERROR_CONNECTION_MISSING_RESPONSE = 5,

    /*! The logic expects the server to return HTTP_UNAUTHORIZED */
    AD_ERROR_UNAUTHORIZED_CODE_EXPECTED = 6,

    /*! The refresh token cannot be used for extracting an access token. */
    AD_ERROR_INVALID_REFRESH_TOKEN = 7,

    /*! An unexpected internal error occurred. */
    AD_ERROR_UNEXPECTED = 8,

    /*! Access tokens for multiple users exist in the token cache. Please specify the userId. */
    AD_ERROR_MULTIPLE_USERS = 9,

    /*! User needs to re-authorize resource usage. This error is raised when access token cannot
     be obtained without user explicitly re-authorizing, but the developer has called
     acquireTokenSilentWithResource method. To obtain the token, the application will need to call
     acquireTokenWithResource after this error to allow the library to give user abitlity
     to re-authorize (with web UI involved). */
    AD_ERROR_USER_INPUT_NEEDED = 10,

    /*! The cache store cannot be persisted to the specified location. This error is raised only if
     the application called explicitly to persist the cache. Else, the errors are only logged
     as warnings. */
    AD_ERROR_CACHE_PERSISTENCE = 11,

    /*! An issue occurred while attempting to read the persisted token cache store. */
    AD_ERROR_BAD_CACHE_FORMAT = 12,

    /*! The user is currently prompted for another authentication. The library chose to raise this
     error instead of waiting to avoid multiple sequential prompts. It is up to the application
     developer to chose to retry later. */
    AD_ERROR_USER_PROMPTED = 13,

    /*! This type of error occurs when something went wrong with the application stack, e.g.
     the resource bundle cannot be loaded. */
    AD_ERROR_APPLICATION = 14,

    /*! A generic error code for all of the authentication errors. */
    AD_ERROR_AUTHENTICATION = 15,

    /*! An error was raised during the process of validating the authorization authority. */
    AD_ERROR_AUTHORITY_VALIDATION = 16,

    /*! Failed to extract the main view controller of the application. Make sure that the application
     has UI elements.*/
    AD_ERROR_NO_MAIN_VIEW_CONTROLLER = 17,

    /*! Failed to extract the framework resources (e.g. storyboards). Please read the readme and documentation
     for the library on how to link the ADAL library with its resources to your project.*/
    AD_ERROR_MISSING_RESOURCES = 18,

    /*! Token requested for user A, but obtained for user B. This can happen if the user explicitly authenticated
     as user B in the login UI, or if cookies for user B are already present.*/
    AD_ERROR_WRONG_USER = 19,

    /*! When client authentication is requested by TLS, the library attempts to extract the authentication
     certificate. The error is generated if more than one certificate is found in the keychain. */
    AD_ERROR_MULTIPLE_TLS_CERTIFICATES = 20,

    /*! When the hash of the decrypted broker response does not match the hash returned from broker. */
    AD_ERROR_BROKER_RESPONSE_HASH_MISMATCH = 21,

    /*! When the application waiting for broker is activated without broker response. */
    AD_ERROR_BROKER_RESPONSE_NOT_RECEIVED = 22,

    /*! When work place join is required by the service. */
    AD_ERROR_WPJ_REQUIRED = 23,

    /*! The redirect URI cannot be used for invoking broker. */
    AD_ERROR_INVALID_REDIRECT_URI = 23,

    /*! The error code was not sent to us due to an older version of the broker */
    AD_ERROR_BROKER_UNKNOWN = 24,

    /*! Server redirects authentication process to a non-https url */
    AD_ERROR_NON_HTTPS_REDIRECT = 25

} ADErrorCode;

/* HTTP status codes used by the library */
typedef enum
{
    HTTP_UNAUTHORIZED = 401,
} HTTPStatusCodes;


#!/bin/bash

#
# OpenTravelData (OPTD) utility
# Git repository:
#   https://github.com/opentraveldata/opentraveldata/tree/master/tools
#

#
# Four parameters are optional for this script:
# - the Geonames data dump file, only for its geographical coordinates
# - the OPTD-maintained list of "best known" POR (points of reference)
# - the OPTD-maintained list of POR importance (i.e., PageRank) figures
# - the minimal distance (in km) triggering a difference
#

##
# GNU tools, including on MacOS
source setGnuTools.sh || exit -1

##
# Directories
source setDirs.sh "$0" || exit -1

##
# Log level
LOG_LEVEL=3

##
# Data path
OPTD_DIR="${EXEC_PATH}../"
DATA_DIR="${OPTD_DIR}opentraveldata/"

##
# Geonames data dump file
GEONAME_FILE_RAW_FILENAME="dump_from_geonames.csv"
GEONAME_FILENAME="wpk_${GEONAME_FILE_RAW_FILENAME}"
GEONAME_FILE_SORTED="sorted_${GEONAME_FILENAME}"
GEONAME_FILE_SORTED_CUT="cut_${GEONAME_FILE_SORTED}"
#
GEONAME_FILE_RAW="${TMP_DIR}${GEONAME_FILE_RAW_FILENAME}"
GEONAME_FILE="${TMP_DIR}${GEONAME_FILENAME}"

##
# OPTD-maintained list of "best known" POR (points of reference)
OPTD_BEST_FILENAME="optd_por_best_known_so_far.csv"
#
OPTD_BEST_FILE="${DATA_DIR}${OPTD_BEST_FILENAME}"

##
# OPTD-maintained list of POR importance (i.e., PageRank) figures
AIRPORT_PR_FILENAME="ref_airport_pageranked.csv"
AIRPORT_PR_SORTED="sorted_${AIRPORT_PR_FILENAME}"
AIRPORT_PR_SORTED_CUT="cut_sorted_${AIRPORT_PR_FILENAME}"
#
AIRPORT_PR_FILE="${DATA_DIR}${AIRPORT_PR_FILENAME}"

##
# Comparison files
POR_MAIN_DIFF_FILENAME="optd_por_diff_w_geonames.csv"
#
POR_MAIN_DIFF="${DATA_DIR}${POR_MAIN_DIFF_FILENAME}"

# Minimal distance triggering a difference (in km)
COMP_MIN_DIST=10

##
# Missing POR
GEONAME_FILE_MISSING="${GEONAME_FILE}.missing"
OPTD_BEST_FILE_MISSING="${OPTD_BEST_FILE}.missing"

##
# Temporary files
OPTD_BEST_WITH_NOHD="${TMP_DIR}${OPTD_BEST_FILENAME}.wohd"
GEO_COMBINED_TMP_FILE="geo_combined_file.csv.tmp"

##
# Usage helper
#
if [ "$1" = "-h" -o "$1" = "--help" ]
then
	echo
	echo "Usage: $0 [<Geonames data dump file> [<OPTD file of best known coordinates> [<PageRanked POR file>] [<minimum distance>]]]]"
	echo " - Default name for the Geonames data dump file: '${GEONAME_FILE_RAW}'"
	echo " - Default name for the OPTD-maintained file of best known coordinates: '${OPTD_BEST_FILE}'"
	echo " - Default name for the PageRanked POR file: '${AIRPORT_PR_FILE}'"
	echo " - Default minimum distance (in km) triggering a difference: '${COMP_MIN_DIST}'"
	echo
	exit
fi

##
# Cleaning
#
if [ "$1" = "--clean" ]
then
	if [ "${TMP_DIR}" = "/tmp/por/" ]
	then
		\rm -rf ${TMP_DIR}
	else
		\rm -f ${GEONAME_FILE_MISSING} ${OPTD_BEST_FILE_MISSING} \
			${OPTD_BEST_FILE_HEADER} ${OPTD_BEST_WITH_NOHD} \
			${GEONAME_FILE} ${GEONAME_FILE_SORTED} ${GEONAME_FILE_SORTED_CUT} \
			${AIRPORT_PR_SORTED} ${AIRPORT_PR_SORTED_CUT}
	fi
	exit
fi

##
# Local helper scripts
PREPARE_EXEC="bash ${EXEC_PATH}prepare_geonames_dump_file.sh"
PREPARE_POP_EXEC="bash ${EXEC_PATH}prepare_popularity.sh"
PREPARE_PR_EXEC="bash ${EXEC_PATH}prepare_pagerank.sh"
COMPARE_EXEC="bash ${EXEC_PATH}compare_geo_files.sh"

##
# Geonames data dump file
if [ "$1" != "" ]
then
	GEONAME_FILE_RAW=$1
	GEONAME_FILE_RAW_FILENAME=`basename ${GEONAME_FILE_RAW}`
	GEONAME_FILENAME=wpk_${GEONAME_FILE_RAW_FILENAME}
	GEONAME_FILE_SORTED=sorted_${GEONAME_FILENAME}
	GEONAME_FILE_SORTED_CUT=cut_${GEONAME_FILE_SORTED}
	if [ "${GEONAME_FILE_RAW}" = "${GEONAME_FILE_RAW_FILENAME}" ]
	then
		GEONAME_FILE_RAW="${TMP_DIR}${GEONAME_FILE_RAW_FILENAME}"
	fi
fi
GEONAME_FILE="${TMP_DIR}${GEONAME_FILENAME}"
GEONAME_FILE_SORTED="${TMP_DIR}${GEONAME_FILE_SORTED}"
GEONAME_FILE_SORTED_CUT="${TMP_DIR}${GEONAME_FILE_SORTED_CUT}"

if [ ! -f "${GEONAME_FILE_RAW}" ]
then
	echo
	echo "[$0:$LINENO] The '${GEONAME_FILE_RAW}' file does not exist."
	if [ "$1" = "" ];
	then
		${PREPARE_EXEC} --geonames
		echo "The default name of the Geonames data dump copy is '${GEONAME_FILE_RAW}'."
		echo
	fi
	exit -1
fi

##
# Prepare the Geonames dump file, downloaded from Geonames and pre-processed.
# Basically, a primary key is added and the coordinates are extracted,
# in order to keep a data file with only four fields/columns:
#  * The primary key (IATA code - location type)
#  * The airport/city code
#  * The geographical coordinates.
${PREPARE_EXEC} ${OPTD_DIR} ${LOG_LEVEL}

# OPTD-maintained list of "best known" geographical coordinates
if [ "$2" != "" ]
then
	OPTD_BEST_FILE="$2"
fi

if [ ! -f "${OPTD_BEST_FILE}" ]
then
	echo
	echo "[$0:$LINENO] The '${OPTD_BEST_FILE}' file does not exist."
	if [ "$2" = "" ]
	then
		echo
		echo "Hint:"
		echo "\cp -f ${EXEC_PATH}../OPTD/${OPTD_BEST_FILENAME} ${TMP_DIR}"
		echo
	fi
	exit -1
fi

##
# Data file of PageRanked POR
if [ "$3" != "" ]
then
	AIRPORT_PR_FILE=$3
	AIRPORT_PR_FILENAME=`basename ${AIRPORT_PR_FILE}`
	AIRPORT_PR_SORTED=sorted_${AIRPORT_PR_FILENAME}
	AIRPORT_PR_SORTED_CUT=cut_${AIRPORT_PR_SORTED}
	if [ "${AIRPORT_PR_FILE}" = "${AIRPORT_PR_FILENAME}" ]
	then
		AIRPORT_PR_FILE="${TMP_DIR}${AIRPORT_PR_FILENAME}"
	fi
fi
AIRPORT_PR_SORTED=${TMP_DIR}${AIRPORT_PR_SORTED}
AIRPORT_PR_SORTED_CUT=${TMP_DIR}${AIRPORT_PR_SORTED_CUT}

if [ ! -f "${AIRPORT_PR_FILE}" ]
then
	echo
	echo "[$0:$LINENO] The '${AIRPORT_PR_FILE}' file does not exist."
	if [ "$3" = "" ]
	then
		${PREPARE_PR_EXEC} --popularity
		echo "The default name of the airport popularity copy is '${AIRPORT_PR_FILE}'."
		echo
	fi
	exit -1
fi

##
# Prepare the OPTD-maintained airport popularity dump file. Basically, the file
# is sorted by IATA code. Then, only two columns/fields are kept in that
# version of the file: the airport/city IATA code and the airport popularity.
${PREPARE_PR_EXEC} ${AIRPORT_PR_FILE}

##
# Minimal distance (in km) triggering a difference
if [ "$4" != "" ]
then
	COMP_MIN_DIST=$4
fi

##
# Extract the header into a temporary file
OPTD_BEST_FILE_HEADER=${OPTD_BEST_FILE}.tmp.hdr
grep -E "^pk(.+)" ${OPTD_BEST_FILE} > ${OPTD_BEST_FILE_HEADER}

# Remove the header
${SED_TOOL} -E "s/^pk(.+)//g" ${OPTD_BEST_FILE} > ${OPTD_BEST_WITH_NOHD}
${SED_TOOL} -i"" -E "/^$/d" ${OPTD_BEST_WITH_NOHD}

##
# The two files contain only four fields (the primary key, the IATA code and
# both coordinates).
#
# Note that the ${PREPARE_EXEC} (e.g., prepare_geonames_dump_file.sh) script
# prepares such a file for Geonames (named ${GEONAME_FILE_SORTED_CUT}, e.g.,
# cut_sorted_wpk_dump_from_geonames.csv) from the data dump (named
# ${GEONAME_FILE}, e.g., wpk_dump_from_geonames.csv).
#
# The 'join' command aggregates:
#  * The four fields of the (stripped) Geonames dump file.
#    That is the file #1 for the join command.
#  * The five fields of the file of best known coordinates (the primary key has
#    been stripped by the join command), i.e.:
#    * the IATA codes of both the POR and its served city
#    * the two geographical coordinates.
#    * the effective date (when empty, it means the POR has always existed).
#
# The 'join' command takes all the rows from the file #1 (Geonames dump file).
# When there is no corresponding entry in the file of best coordinates, only
# the four (extracted) fields of the Geonames dump file are kept.
# Hence, lines may have:
#  * 9 fields: the primary key, IATA code and both coordinates of the Geonames
#    dump file, followed by the IATA codes of the POR and its served city,
#    as well as the best coordinates, ended by the from validity date.
#  * 4 fields: the primary key, IATA code and both coordinates of the Geonames
#    dump file.
#
GEONAME_MASTER="${GEO_COMBINED_TMP_FILE}.geomst"
join -t'^' -a 1 -1 1 -2 1 -e NULL \
	${GEONAME_FILE_SORTED_CUT} ${OPTD_BEST_WITH_NOHD} > ${GEONAME_MASTER}
#echo "head -3 ${GEONAME_FILE_SORTED_CUT} ${OPTD_BEST_WITH_NOHD} ${GEONAME_MASTER}"

##
# Sanity check: calculate the minimal number of fields on the resulting file
#
MIN_FIELD_NB=`awk -F'^' 'BEGIN{n=10} {if (NF<n) {n=NF}} END{print n}' ${GEONAME_MASTER} | uniq | sort | uniq`

if [ "${MIN_FIELD_NB}" != "9" -a "${MIN_FIELD_NB}" != "4" ]
then
	echo
	echo "Sanity check"
	echo "------------"
	echo "[$0:$LINENO] Error! The file aggregating all the geographical coordinates should have a specific number of fields (that is, either 4 or 9). It is ${MIN_FIELD_NB}"
	echo "Check that file (${GEONAME_MASTER}), which is a join of the coordinates from ${GEONAME_FILE_SORTED_CUT} and from ${OPTD_BEST_FILE}."
	echo "That error generally indicates that the format of one of the files (i.e., ${GEONAME_FILENAME} and/or ${OPTD_BEST_FILE}) has changed, and that this script ($0) is not aware of it."
	echo
  exit -1
fi

##
# Operate the same way as above, except that, this time, the points of reference
# with the best known coordinates have the precedence over those of Geonames.
# Note that, however, when they exist, the Geonames coordinates themselves
# (not the point of reference) have the precedence over the "best known" ones.
#
# Therefore, the 'join' command aggregates:
#  * The six fields of the file of best known coordinates, i.e.:
#    * the IATA codes of both the POR and its served city
#    * the two geographical coordinates.
#    * the effective date (when empty, it means the POR has always existed).
#    That is the file #1 for the join command.
#  * The three fields of the Geonames dump file (the primary key has been
#    stripped by the join command.
#    That is the file #2 for the join command.
#
# The 'join' command takes all the rows from the file #1 (file of best known
# coordinates).
# When there is no corresponding entry in the file of best coordinates, only
# the six (extracted) fields of the file of best known coordinates are kept.
# Hence, lines may have:
#  * 9 fields: the primary key, IATA code and both coordinates of the file of
#    best known coordinates, followed by the IATA code of its served city,
#    ended by the from validity date, as well as the Geonames coordinates.
#  * 6 fields: the primary key, IATA code and both coordinates of the file of
#    best known coordinates, followed by the IATA code of its served city,
#    ended by the from validity date.
#
OPTD_BEST_MASTER="${GEO_COMBINED_TMP_FILE}.bstmst"
join -t'^' -a 2 -1 1 -2 1 -e NULL \
	${GEONAME_FILE_SORTED_CUT} ${OPTD_BEST_WITH_NOHD} > ${OPTD_BEST_MASTER}
#echo "head -3 ${GEONAME_FILE_SORTED_CUT} ${OPTD_BEST_WITH_NOHD} ${OPTD_BEST_MASTER}"

##
# Sanity check: calculate the minimal number of fields on the resulting file
#
MIN_FIELD_NB=`awk -F'^' 'BEGIN{n=10} {if (NF<n) {n=NF}} END{print n}' ${OPTD_BEST_MASTER} | uniq | sort | uniq`

if [ "${MIN_FIELD_NB}" != "9" -a "${MIN_FIELD_NB}" != "6" ]
then
	echo
	echo "Sanity check"
	echo "------------"
	echo "[$0:$LINENO] Error! The file aggregating all the geographical coordinates should have a specific number of fields (that is, either 6 or 9). It is ${MIN_FIELD_NB}"
	echo "Check that file (${OPTD_BEST_MASTER}), which is a join of the coordinates from ${GEONAME_FILE_SORTED_CUT} and from ${OPTD_BEST_FILE}."
	echo "That error generally indicates that the format of one of the files (i.e., ${GEONAME_FILENAME} and/or ${OPTD_BEST_FILE}) has changed, and that this script ($0) is not aware of it."
	echo
  exit -1
fi

##
# Keep only the first 4 fields in each file:
#  * The primary key, IATA code and both coordinates of the Geonames dump file,
#    when they exist.
#  * The primary key, IATA code and the best coordinates, when no entry exists
#    in the Geonames dump file.
#
cut -d'^' -f 1-4 ${GEONAME_MASTER} > ${GEONAME_MASTER}.dup
#echo "head -3 ${GEONAME_MASTER} ${GEONAME_MASTER}.dup"
\mv -f ${GEONAME_MASTER}.dup ${GEONAME_MASTER}
cut -d'^' -f 1-4 ${OPTD_BEST_MASTER} > ${OPTD_BEST_MASTER}.dup
#echo "head -3 ${OPTD_BEST_MASTER} ${OPTD_BEST_MASTER}.dup"
\mv -f ${OPTD_BEST_MASTER}.dup ${OPTD_BEST_MASTER}

##
# Re-sort the files. Indeed, when there are duplicates (e.g., DUR/Durham),
# the duplicated lines may not be in the sorting order, due to the coordinates
sort ${GEONAME_MASTER} > ${GEONAME_MASTER}.dup
\mv -f ${GEONAME_MASTER}.dup ${GEONAME_MASTER}
sort ${OPTD_BEST_MASTER} > ${OPTD_BEST_MASTER}.dup
\mv -f ${OPTD_BEST_MASTER}.dup ${OPTD_BEST_MASTER}

##
# Do some reporting
#
# Reminder:
#  * ${GEONAME_MASTER} (e.g., geo_combined_file.csv.tmp.geomst) has got all
#    the entries of the Geonames dump file (./wpk_dump_from_geonames.csv)
#  * ${OPTD_BEST_MASTER} (e.g., geo_combined_file.csv.tmp.bstmst) has got all
#    the entries of the OPTD-maintained list of best known geographical
#    coordinates (optd_por_best_known_so_far.csv)
#
#echo "comm -12 ${GEONAME_MASTER} ${OPTD_BEST_MASTER} | less"
#echo "comm -23 ${GEONAME_MASTER} ${OPTD_BEST_MASTER} | less"
#echo "comm -13 ${GEONAME_MASTER} ${OPTD_BEST_MASTER} | less"
POR_NB_COMMON="$(comm -12 ${GEONAME_MASTER} ${OPTD_BEST_MASTER} | ${WC_TOOL} -l)"
POR_NB_FILE1="$(comm -23 ${GEONAME_MASTER} ${OPTD_BEST_MASTER} | ${WC_TOOL} -l)"
POR_NB_FILE2="$(comm -13 ${GEONAME_MASTER} ${OPTD_BEST_MASTER} | ${WC_TOOL} -l)"
echo
echo "Reporting step"
echo "--------------"
echo "'${GEONAME_FILE}' and '${OPTD_BEST_FILE}' have got ${POR_NB_COMMON} common lines."
echo "'${GEONAME_FILE}' has got ${POR_NB_FILE1} POR, missing from '${OPTD_BEST_FILE}'"
echo "'${OPTD_BEST_FILE}' has got ${POR_NB_FILE2} POR, missing from '${GEONAME_FILE}'"
echo

if [ ${POR_NB_FILE2} -gt 0 ]
then
	comm -13 ${GEONAME_MASTER} ${OPTD_BEST_MASTER} > ${GEONAME_FILE_MISSING}
	POR_MISSING_GEONAMES_NB="$(${WC_TOOL} -l ${GEONAME_FILE_MISSING} | cut -d' ' -f1)"
	echo
	echo "Suggestion step"
	echo "---------------"
	echo "${POR_MISSING_GEONAMES_NB} points of reference (POR) are missing from Geonames ('${GEONAME_FILE}')."
	echo "They can be displayed with: less ${GEONAME_FILE_MISSING}"
	echo "You may also want to launch the following script:"
	echo "./generate_por_lists_for_geonames.sh"
	echo
fi

if [ ${POR_NB_FILE1} -gt 0 ]
then
	comm -23 ${GEONAME_MASTER} ${OPTD_BEST_MASTER} > ${OPTD_BEST_FILE_MISSING}
	POR_MISSING_BEST_NB="$(${WC_TOOL} -l ${OPTD_BEST_FILE_MISSING} | cut -d' ' -f1)"
	echo
	echo "Suggestion step"
	echo "---------------"
	echo "${POR_MISSING_BEST_NB} points of reference (POR) are missing from the file of best coordinates ('${OPTD_BEST_FILE}' => '${OPTD_BEST_WITH_NOHD}')."
	echo "To incorporate the missing POR into '${OPTD_BEST_FILE}', just do:"
	echo "cat ${OPTD_BEST_WITH_NOHD} ${OPTD_BEST_FILE_MISSING} | sort -t'^' -k1,1 > ${OPTD_BEST_FILE}.tmp && \mv -f ${OPTD_BEST_FILE}.tmp ${OPTD_BEST_FILE} && \rm -f ${OPTD_BEST_FILE_MISSING}"
	echo
fi

##
# Compare the Geonames coordinates to the best known ones (until now).
# It generates a data file (${POR_MAIN_DIFF}, e.g., optd_por_diff_w_geonames.csv)
# containing the greatest distances (in km), for each airport/city, between
# both sets of coordinates (Geonames and best known ones).
${COMPARE_EXEC} ${GEONAME_FILE_SORTED_CUT} ${OPTD_BEST_WITH_NOHD} \
	${AIRPORT_PR_FILE} ${COMP_MIN_DIST}
# ${AIRPORT_PR_SORTED_CUT}

##
# Cleaning of temporary files
#
if [ "${TMP_DIR}" != "/tmp/por/" ]
then
	\rm -f ${JOINED_COORD} ${JOINED_COORD_FULL}
	\rm -f ${OPTD_BEST_FILE_HEADER}
	\rm -f ${GEONAME_MASTER} ${OPTD_BEST_MASTER}
	\rm -f ${GEONAME_FILE_SORTED} ${GEONAME_FILE_SORTED_CUT}
fi


// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using System;
using System.Collections.Generic;

namespace NuGet.Frameworks
{
#if NUGET_FRAMEWORKS_INTERNAL
    internal
#else
    public
#endif
    static class FrameworkConstants
    {
        public static readonly Version EmptyVersion = new Version(0, 0, 0, 0);
        public static readonly Version MaxVersion = new Version(int.MaxValue, 0, 0, 0);
        public static readonly Version Version5 = new Version(5, 0, 0, 0);
        public static readonly Version Version10 = new Version(10, 0, 0, 0);
        public static readonly FrameworkRange DotNetAll = new FrameworkRange(
                        new NuGetFramework(FrameworkIdentifiers.NetPlatform, FrameworkConstants.EmptyVersion),
                        new NuGetFramework(FrameworkIdentifiers.NetPlatform, FrameworkConstants.MaxVersion));

        public static class SpecialIdentifiers
        {
            public const string Any = "Any";
            public const string Agnostic = "Agnostic";
            public const string Unsupported = "Unsupported";
        }

        public static class PlatformIdentifiers
        {
            public const string WindowsPhone = "WindowsPhone";
            public const string Windows = "Windows";
        }

        public static class FrameworkIdentifiers
        {
            public const string NetCoreApp = ".NETCoreApp";
            public const string NetStandardApp = ".NETStandardApp";
            public const string NetStandard = ".NETStandard";
            public const string NetPlatform = ".NETPlatform";
            public const string DotNet = "dotnet";
            public const string Net = ".NETFramework";
            public const string NetCore = ".NETCore";
            public const string WinRT = "WinRT"; // deprecated
            public const string NetMicro = ".NETMicroFramework";
            public const string Portable = ".NETPortable";
            public const string WindowsPhone = "WindowsPhone";
            public const string Windows = "Windows";
            public const string WindowsPhoneApp = "WindowsPhoneApp";
            public const string Dnx = "DNX";
            public const string DnxCore = "DNXCore";
            public const string AspNet = "ASP.NET";
            public const string AspNetCore = "ASP.NETCore";
            public const string Silverlight = "Silverlight";
            public const string Native = "native";
            public const string MonoAndroid = "MonoAndroid";
            public const string MonoTouch = "MonoTouch";
            public const string MonoMac = "MonoMac";
            public const string XamarinIOs = "Xamarin.iOS";
            public const string XamarinMac = "Xamarin.Mac";
            public const string XamarinPlayStation3 = "Xamarin.PlayStation3";
            public const string XamarinPlayStation4 = "Xamarin.PlayStation4";
            public const string XamarinPlayStationVita = "Xamarin.PlayStationVita";
            public const string XamarinWatchOS = "Xamarin.WatchOS";
            public const string XamarinTVOS = "Xamarin.TVOS";
            public const string XamarinXbox360 = "Xamarin.Xbox360";
            public const string XamarinXboxOne = "Xamarin.XboxOne";
            public const string UAP = "UAP";
            public const string Tizen = "Tizen";
        }

        /// <summary>
        /// Interned frameworks that are commonly used in NuGet
        /// </summary>
        public static class CommonFrameworks
        {
            public static readonly NuGetFramework Net11 = new NuGetFramework(FrameworkIdentifiers.Net, new Version(1, 1, 0, 0));
            public static readonly NuGetFramework Net2 = new NuGetFramework(FrameworkIdentifiers.Net, new Version(2, 0, 0, 0));
            public static readonly NuGetFramework Net35 = new NuGetFramework(FrameworkIdentifiers.Net, new Version(3, 5, 0, 0));
            public static readonly NuGetFramework Net4 = new NuGetFramework(FrameworkIdentifiers.Net, new Version(4, 0, 0, 0));
            public static readonly NuGetFramework Net403 = new NuGetFramework(FrameworkIdentifiers.Net, new Version(4, 0, 3, 0));
            public static readonly NuGetFramework Net45 = new NuGetFramework(FrameworkIdentifiers.Net, new Version(4, 5, 0, 0));
            public static readonly NuGetFramework Net451 = new NuGetFramework(FrameworkIdentifiers.Net, new Version(4, 5, 1, 0));
            public static readonly NuGetFramework Net452 = new NuGetFramework(FrameworkIdentifiers.Net, new Version(4, 5, 2, 0));
            public static readonly NuGetFramework Net46 = new NuGetFramework(FrameworkIdentifiers.Net, new Version(4, 6, 0, 0));
            public static readonly NuGetFramework Net461 = new NuGetFramework(FrameworkIdentifiers.Net, new Version(4, 6, 1, 0));
            public static readonly NuGetFramework Net462 = new NuGetFramework(FrameworkIdentifiers.Net, new Version(4, 6, 2, 0));
            public static readonly NuGetFramework Net463 = new NuGetFramework(FrameworkIdentifiers.Net, new Version(4, 6, 3, 0));

            public static readonly NuGetFramework NetCore45 = new NuGetFramework(FrameworkIdentifiers.NetCore, new Version(4, 5, 0, 0));
            public static readonly NuGetFramework NetCore451 = new NuGetFramework(FrameworkIdentifiers.NetCore, new Version(4, 5, 1, 0));
            public static readonly NuGetFramework NetCore50 = new NuGetFramework(FrameworkIdentifiers.NetCore, new Version(5, 0, 0, 0));

            public static readonly NuGetFramework Win8 = new NuGetFramework(FrameworkIdentifiers.Windows, new Version(8, 0, 0, 0));
            public static readonly NuGetFramework Win81 = new NuGetFramework(FrameworkIdentifiers.Windows, new Version(8, 1, 0, 0));
            public static readonly NuGetFramework Win10 = new NuGetFramework(FrameworkIdentifiers.Windows, new Version(10, 0, 0, 0));

            public static readonly NuGetFramework SL4 = new NuGetFramework(FrameworkIdentifiers.Silverlight, new Version(4, 0, 0, 0));
            public static readonly NuGetFramework SL5 = new NuGetFramework(FrameworkIdentifiers.Silverlight, new Version(5, 0, 0, 0));

            public static readonly NuGetFramework WP7 = new NuGetFramework(FrameworkIdentifiers.WindowsPhone, new Version(7, 0, 0, 0));
            public static readonly NuGetFramework WP75 = new NuGetFramework(FrameworkIdentifiers.WindowsPhone, new Version(7, 5, 0, 0));
            public static readonly NuGetFramework WP8 = new NuGetFramework(FrameworkIdentifiers.WindowsPhone, new Version(8, 0, 0, 0));
            public static readonly NuGetFramework WP81 = new NuGetFramework(FrameworkIdentifiers.WindowsPhone, new Version(8, 1, 0, 0));
            public static readonly NuGetFramework WPA81 = new NuGetFramework(FrameworkIdentifiers.WindowsPhoneApp, new Version(8, 1, 0, 0));

            public static readonly NuGetFramework Tizen3 = new NuGetFramework(FrameworkIdentifiers.Tizen, new Version(3, 0, 0, 0));
            public static readonly NuGetFramework Tizen4 = new NuGetFramework(FrameworkIdentifiers.Tizen, new Version(4, 0, 0, 0));
            public static readonly NuGetFramework Tizen6 = new NuGetFramework(FrameworkIdentifiers.Tizen, new Version(6, 0, 0, 0));

            public static readonly NuGetFramework AspNet = new NuGetFramework(FrameworkIdentifiers.AspNet, EmptyVersion);
            public static readonly NuGetFramework AspNetCore = new NuGetFramework(FrameworkIdentifiers.AspNetCore, EmptyVersion);
            public static readonly NuGetFramework AspNet50 = new NuGetFramework(FrameworkIdentifiers.AspNet, Version5);
            public static readonly NuGetFramework AspNetCore50 = new NuGetFramework(FrameworkIdentifiers.AspNetCore, Version5);

            public static readonly NuGetFramework Dnx = new NuGetFramework(FrameworkIdentifiers.Dnx, EmptyVersion);
            public static readonly NuGetFramework Dnx45 = new NuGetFramework(FrameworkIdentifiers.Dnx, new Version(4, 5, 0, 0));
            public static readonly NuGetFramework Dnx451 = new NuGetFramework(FrameworkIdentifiers.Dnx, new Version(4, 5, 1, 0));
            public static readonly NuGetFramework Dnx452 = new NuGetFramework(FrameworkIdentifiers.Dnx, new Version(4, 5, 2, 0));
            public static readonly NuGetFramework DnxCore = new NuGetFramework(FrameworkIdentifiers.DnxCore, EmptyVersion);
            public static readonly NuGetFramework DnxCore50 = new NuGetFramework(FrameworkIdentifiers.DnxCore, Version5);

            public static readonly NuGetFramework DotNet
                = new NuGetFramework(FrameworkIdentifiers.NetPlatform, EmptyVersion);
            public static readonly NuGetFramework DotNet50
                = new NuGetFramework(FrameworkIdentifiers.NetPlatform, Version5);
            public static readonly NuGetFramework DotNet51
                = new NuGetFramework(FrameworkIdentifiers.NetPlatform, new Version(5, 1, 0, 0));
            public static readonly NuGetFramework DotNet52
                = new NuGetFramework(FrameworkIdentifiers.NetPlatform, new Version(5, 2, 0, 0));
            public static readonly NuGetFramework DotNet53
                = new NuGetFramework(FrameworkIdentifiers.NetPlatform, new Version(5, 3, 0, 0));
            public static readonly NuGetFramework DotNet54
                = new NuGetFramework(FrameworkIdentifiers.NetPlatform, new Version(5, 4, 0, 0));
            public static readonly NuGetFramework DotNet55
                = new NuGetFramework(FrameworkIdentifiers.NetPlatform, new Version(5, 5, 0, 0));
            public static readonly NuGetFramework DotNet56
                = new NuGetFramework(FrameworkIdentifiers.NetPlatform, new Version(5, 6, 0, 0));

            public static readonly NuGetFramework NetStandard
                = new NuGetFramework(FrameworkIdentifiers.NetStandard, EmptyVersion);
            public static readonly NuGetFramework NetStandard10
                = new NuGetFramework(FrameworkIdentifiers.NetStandard, new Version(1, 0, 0, 0));
            public static readonly NuGetFramework NetStandard11
                = new NuGetFramework(FrameworkIdentifiers.NetStandard, new Version(1, 1, 0, 0));
            public static readonly NuGetFramework NetStandard12
                = new NuGetFramework(FrameworkIdentifiers.NetStandard, new Version(1, 2, 0, 0));
            public static readonly NuGetFramework NetStandard13
                = new NuGetFramework(FrameworkIdentifiers.NetStandard, new Version(1, 3, 0, 0));
            public static readonly NuGetFramework NetStandard14
                = new NuGetFramework(FrameworkIdentifiers.NetStandard, new Version(1, 4, 0, 0));
            public static readonly NuGetFramework NetStandard15
                = new NuGetFramework(FrameworkIdentifiers.NetStandard, new Version(1, 5, 0, 0));
            public static readonly NuGetFramework NetStandard16
                = new NuGetFramework(FrameworkIdentifiers.NetStandard, new Version(1, 6, 0, 0));
            public static readonly NuGetFramework NetStandard17
                = new NuGetFramework(FrameworkIdentifiers.NetStandard, new Version(1, 7, 0, 0));
            public static readonly NuGetFramework NetStandard20
                = new NuGetFramework(FrameworkIdentifiers.NetStandard, new Version(2, 0, 0, 0));
            public static readonly NuGetFramework NetStandard21
                = new NuGetFramework(FrameworkIdentifiers.NetStandard, new Version(2, 1, 0, 0));

            public static readonly NuGetFramework NetStandardApp15
                = new NuGetFramework(FrameworkIdentifiers.NetStandardApp, new Version(1, 5, 0, 0));

            public static readonly NuGetFramework UAP10
                = new NuGetFramework(FrameworkIdentifiers.UAP, Version10);

            public static readonly NuGetFramework NetCoreApp10
                = new NuGetFramework(FrameworkIdentifiers.NetCoreApp, new Version(1, 0, 0, 0));
            public static readonly NuGetFramework NetCoreApp11
                = new NuGetFramework(FrameworkIdentifiers.NetCoreApp, new Version(1, 1, 0, 0));
            public static readonly NuGetFramework NetCoreApp20
                = new NuGetFramework(FrameworkIdentifiers.NetCoreApp, new Version(2, 0, 0, 0));
            public static readonly NuGetFramework NetCoreApp21
                = new NuGetFramework(FrameworkIdentifiers.NetCoreApp, new Version(2, 1, 0, 0));
            public static readonly NuGetFramework NetCoreApp22
                = new NuGetFramework(FrameworkIdentifiers.NetCoreApp, new Version(2, 2, 0, 0));
            public static readonly NuGetFramework NetCoreApp30
                = new NuGetFramework(FrameworkIdentifiers.NetCoreApp, new Version(3, 0, 0, 0));
            public static readonly NuGetFramework NetCoreApp31
                = new NuGetFramework(FrameworkIdentifiers.NetCoreApp, new Version(3, 1, 0, 0));

            // .NET 5.0 and later has NetCoreApp identifier
            public static readonly NuGetFramework Net50 = new NuGetFramework(FrameworkIdentifiers.NetCoreApp, Version5);
        }
    }
}


/*=============================================================================
    Copyright (c) 2001-2011 Joel de Guzman
    Copyright (c) 2001-2011 Hartmut Kaiser
    Copyright (c)      2011 Thomas Heller

    Distributed under the Boost Software License, Version 1.0. (See accompanying
    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
==============================================================================*/
#if !defined(BOOST_SPIRIT_CONTEXT_OCTOBER_31_2008_0654PM)
#define BOOST_SPIRIT_CONTEXT_OCTOBER_31_2008_0654PM

#if defined(_MSC_VER)
#pragma once
#endif

#include <boost/preprocessor/repetition/repeat_from_to.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/home/support/nonterminal/expand_arg.hpp>
#include <boost/spirit/home/support/assert_msg.hpp>
#include <boost/spirit/home/support/argument.hpp>
#include <boost/spirit/home/support/limits.hpp>
#include <boost/fusion/include/at.hpp>
#include <boost/fusion/include/size.hpp>
#include <boost/fusion/include/as_list.hpp>
#include <boost/fusion/include/transform.hpp>
#include <boost/mpl/size.hpp>
#include <boost/mpl/at.hpp>

///////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS

#define SPIRIT_DECLARE_ATTRIBUTE(z, n, data)                                   \
    typedef phoenix::actor<attribute<n> >                                      \
        BOOST_PP_CAT(BOOST_PP_CAT(_r, n), _type);                              \
    phoenix::actor<attribute<n> > const                                        \
        BOOST_PP_CAT(_r, n) = BOOST_PP_CAT(BOOST_PP_CAT(_r, n), _type)();
    /***/
#define SPIRIT_USING_ATTRIBUTE(z, n, data)                                     \
    using spirit::BOOST_PP_CAT(BOOST_PP_CAT(_r, n), _type);                    \
    using spirit::BOOST_PP_CAT(_r, n);                                         \
    /***/

#else

#define SPIRIT_DECLARE_ATTRIBUTE(z, n, data)                                   \
    typedef phoenix::actor<attribute<n> >                                      \
        BOOST_PP_CAT(BOOST_PP_CAT(_r, n), _type);                              \
    /***/
#define SPIRIT_USING_ATTRIBUTE(z, n, data)                                     \
    using spirit::BOOST_PP_CAT(BOOST_PP_CAT(_r, n), _type);                    \
    /***/

#endif

namespace boost { namespace spirit
{
    template <int>
    struct attribute;

    template <int>
    struct local_variable;
}}

BOOST_PHOENIX_DEFINE_CUSTOM_TERMINAL(
    template <int N>
  , boost::spirit::attribute<N>
  , mpl::false_                 // is not nullary
  , v2_eval(
        proto::make<
            boost::spirit::attribute<N>()
        >
      , proto::call<
            functional::env(proto::_state)
        >
    )
)

BOOST_PHOENIX_DEFINE_CUSTOM_TERMINAL(
    template <int N>
  , boost::spirit::local_variable<N>
  , mpl::false_                 // is not nullary
  , v2_eval(
        proto::make<
            boost::spirit::local_variable<N>()
        >
      , proto::call<
            functional::env(proto::_state)
        >
    )
)

namespace boost { namespace spirit
{
    template <typename Attributes, typename Locals>
    struct context
    {
        typedef Attributes attributes_type;
        typedef Locals locals_type;

        context(typename Attributes::car_type attribute)
          : attributes(attribute, fusion::nil()), locals() {}

        template <typename Args, typename Context>
        context(
            typename Attributes::car_type attribute
          , Args const& args
          , Context& caller_context
        ) : attributes(
                attribute
              , fusion::as_list(
                    fusion::transform(
                        args
                      , detail::expand_arg<Context>(caller_context)
                    )
                )
            )
          , locals() {}

        context(Attributes const& attributes)
          : attributes(attributes), locals() {}

        Attributes attributes;  // The attributes
        Locals locals;          // Local variables
    };

    template <typename Context>
    struct attributes_of
    {
        typedef typename Context::attributes_type type;
    };

    template <typename Context>
    struct attributes_of<Context const>
    {
        typedef typename Context::attributes_type const type;
    };

    template <typename Context>
    struct attributes_of<Context &>
      : attributes_of<Context>
    {};

    template <typename Context>
    struct locals_of
    {
        typedef typename Context::locals_type type;
    };

    template <typename Context>
    struct locals_of<Context const>
    {
        typedef typename Context::locals_type const type;
    };

    template <typename Context>
    struct locals_of<Context &>
    {
        typedef typename Context::locals_type type;
    };

    template <int N>
    struct attribute
    {
        typedef mpl::true_ no_nullary;

        template <typename Env>
        struct result
        {
            typedef typename
                attributes_of<typename
                    mpl::at_c<typename Env::args_type, 1>::type
                >::type
            attributes_type;

            typedef typename
                fusion::result_of::size<attributes_type>::type
            attributes_size;

            // report invalid argument not found (N is out of bounds)
            BOOST_SPIRIT_ASSERT_MSG(
                (N < attributes_size::value),
                index_is_out_of_bounds, ());

            typedef typename
                fusion::result_of::at_c<attributes_type, N>::type
            type;
        };

        template <typename Env>
        typename result<Env>::type
        eval(Env const& env) const
        {
            return fusion::at_c<N>((fusion::at_c<1>(env.args())).attributes);
        }
    };

    template <int N>
    struct local_variable
    {
        typedef mpl::true_ no_nullary;

        template <typename Env>
        struct result
        {
            typedef typename
                locals_of<typename
                    mpl::at_c<typename Env::args_type, 1>::type
                >::type
            locals_type;

            typedef typename
                fusion::result_of::size<locals_type>::type
            locals_size;

            // report invalid argument not found (N is out of bounds)
            BOOST_SPIRIT_ASSERT_MSG(
                (N < locals_size::value),
                index_is_out_of_bounds, ());

            typedef typename
                fusion::result_of::at_c<locals_type, N>::type
            type;
        };

        template <typename Env>
        typename result<Env>::type
        eval(Env const& env) const
        {
            return get_arg<N>((fusion::at_c<1>(env.args())).locals);
        }
    };

    typedef phoenix::actor<attribute<0> > _val_type;
    typedef phoenix::actor<attribute<0> > _r0_type;
    typedef phoenix::actor<attribute<1> > _r1_type;
    typedef phoenix::actor<attribute<2> > _r2_type;

#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
    // _val refers to the 'return' value of a rule (same as _r0)
    // _r1, _r2, ... refer to the rule arguments
    _val_type const _val = _val_type();
    _r0_type const _r0 = _r0_type();
    _r1_type const _r1 = _r1_type();
    _r2_type const _r2 = _r2_type();
#endif

    //  Bring in the rest of the attributes (_r4 .. _rN+1), using PP
    BOOST_PP_REPEAT_FROM_TO(
        3, SPIRIT_ATTRIBUTES_LIMIT, SPIRIT_DECLARE_ATTRIBUTE, _)

    typedef phoenix::actor<local_variable<0> > _a_type;
    typedef phoenix::actor<local_variable<1> > _b_type;
    typedef phoenix::actor<local_variable<2> > _c_type;
    typedef phoenix::actor<local_variable<3> > _d_type;
    typedef phoenix::actor<local_variable<4> > _e_type;
    typedef phoenix::actor<local_variable<5> > _f_type;
    typedef phoenix::actor<local_variable<6> > _g_type;
    typedef phoenix::actor<local_variable<7> > _h_type;
    typedef phoenix::actor<local_variable<8> > _i_type;
    typedef phoenix::actor<local_variable<9> > _j_type;

#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
    // _a, _b, ... refer to the local variables of a rule
    _a_type const _a = _a_type();
    _b_type const _b = _b_type();
    _c_type const _c = _c_type();
    _d_type const _d = _d_type();
    _e_type const _e = _e_type();
    _f_type const _f = _f_type();
    _g_type const _g = _g_type();
    _h_type const _h = _h_type();
    _i_type const _i = _i_type();
    _j_type const _j = _j_type();
#endif

    // You can bring these in with the using directive
    // without worrying about bringing in too much.
    namespace labels
    {
        BOOST_PP_REPEAT(SPIRIT_ARGUMENTS_LIMIT, SPIRIT_USING_ARGUMENT, _)
        BOOST_PP_REPEAT(SPIRIT_ATTRIBUTES_LIMIT, SPIRIT_USING_ATTRIBUTE, _)

#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
        using spirit::_val;
        using spirit::_a;
        using spirit::_b;
        using spirit::_c;
        using spirit::_d;
        using spirit::_e;
        using spirit::_f;
        using spirit::_g;
        using spirit::_h;
        using spirit::_i;
        using spirit::_j;
#endif
    }
}}

#endif


/*
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

use super::{read_to_string, WatchmanFile};
use crate::errors::{Error, Result};
use common::SourceLocationKey;
use graphql_syntax::GraphQLSource;
use std::{fs, path::Path};
use watchman_client::prelude::*;

/// Reads and extracts `graphql` tagged literals from a file.
pub fn extract_graphql_strings_from_file(
    resolved_root: &ResolvedRoot,
    file: &WatchmanFile,
) -> Result<Vec<GraphQLSource>> {
    let contents = read_to_string(resolved_root, file)?;
    extract_graphql_strings_from_string(&contents)
}

pub fn source_for_location(
    root_dir: &Path,
    source_location: SourceLocationKey,
) -> Option<GraphQLSource> {
    match source_location {
        SourceLocationKey::Embedded { path, index } => {
            let absolute_path = root_dir.join(path.lookup());
            let contents = fs::read_to_string(&absolute_path).ok()?;
            let file_sources = extract_graphql_strings_from_string(&contents).ok()?;
            file_sources.into_iter().nth(index)
        }
        SourceLocationKey::Standalone { path } => {
            let absolute_path = root_dir.join(path.lookup());
            Some(GraphQLSource {
                text: fs::read_to_string(&absolute_path).ok()?,
                line_index: 0,
                column_index: 0,
            })
        }
        SourceLocationKey::Generated => None,
    }
}

/// Reads and extracts `graphql` tagged literals from a string.
fn extract_graphql_strings_from_string(contents: &str) -> Result<Vec<GraphQLSource>> {
    extract_graphql::parse_chunks(&contents).map_err(|err| Error::Syntax { error: err })
}


## DESCRIPTION
## Linear Algebra
## ENDDESCRIPTION

## Tagged by tda2d

## DBsubject(Linear algebra)
## DBchapter(Matrices)
## DBsection(Matrix algebra)
## Date(July 2013)
## Institution(TCNJ and Hope College)
## Author(Paul Pearson)
## MLT(matrix_mult)
## Level(2)
## MO(1)
## TitleText1('Linear Algebra with Applications')
## AuthorText1('Jeffrey Holt')
## EditionText1('1')
## Section1('3.2')
## Problem1('')
## KEYWORDS('matrix' 'product')

DOCUMENT();

loadMacros(
  "PGstandard.pl",
  "MathObjects.pl",
  "PGcourse.pl"
);

TEXT(beginproblem());
$showPartialCorrectAnswers = 1;

Context('Matrix');

$A = Matrix([
[non_zero_random(-9,9,1),non_zero_random(-9,9,1)],
[non_zero_random(-9,9,1),non_zero_random(-9,9,1)],
]);

$B = Matrix([
[non_zero_random(-9,9,1),non_zero_random(-9,9,1)],
[non_zero_random(-9,9,1),non_zero_random(-9,9,1)],
]);

$B1 = $B->column(1);
$B2 = $B->column(2);

$ans[1] = $A * $B1;
$ans[2] = $A * $B2;
$ans[3] = $A * $B;

Context()->texStrings;
BEGIN_TEXT
Compute the following products.
$BR
$BR
\( $A $B1 = \) \{ $ans[1]->ans_array(15) \}
$BR
$BR
\( $A $B2 = \) \{ $ans[2]->ans_array(15) \}
$BR
$BR
\( $A $B = \) \{ $ans[3]->ans_array(15) \}
END_TEXT
Context()->normalStrings;

foreach my $i (1..3) {
ANS($ans[$i]->cmp);
}
;
ENDDOCUMENT();


#!/usr/bin/env python
"""This file is automatically generated by generate_version_info
It uses the current working tree to determine the revision.
So don't edit it. :)
"""

version_info = {'branch_nick': 'python-daemon.devel',
 'build_date': '2009-05-22 19:50:06 +1000',
 'clean': None,
 'date': '2009-05-22 19:47:30 +1000',
 'revision_id': 'ben+python@benfinney.id.au-20090522094730-p4vsa0reh7ktt4e1',
 'revno': 145}

revisions = {}

file_revisions = {}

if __name__ == '__main__':
    print('revision: %(revno)d' % version_info)
    print('nick: %(branch_nick)s' % version_info)
    print('revision id: %(revision_id)s' % version_info)