From 443b3157e0784e1a7fe800e5af4dd63f1290f7cd Mon Sep 17 00:00:00 2001 From: yanlend Date: Fri, 10 Apr 2015 14:57:31 +0200 Subject: [PATCH 01/31] Fix win32 search for same bitness executable find_package(PythonInterp) calls find_program(PYTHON_EXECUTABLE), i.e. without version number. For the Win32-search before to be effective, the same variable has to be used. --- cmake/OpenCVDetectPython.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/OpenCVDetectPython.cmake b/cmake/OpenCVDetectPython.cmake index ed75698210..f883525c80 100644 --- a/cmake/OpenCVDetectPython.cmake +++ b/cmake/OpenCVDetectPython.cmake @@ -37,7 +37,7 @@ function(find_python preferred_version min_version library_env include_dir_env # standard FindPythonInterp always prefers executable from system path # this is really important because we are using the interpreter for numpy search and for choosing the install location foreach(_CURRENT_VERSION ${Python_ADDITIONAL_VERSIONS} "${preferred_version}" "${min_version}") - find_host_program(executable + find_host_program(PYTHON_EXECUTABLE NAMES python${_CURRENT_VERSION} python PATHS [HKEY_LOCAL_MACHINE\\\\SOFTWARE\\\\Python\\\\PythonCore\\\\${_CURRENT_VERSION}\\\\InstallPath] From f39d351d0490747ed3eb4a758f6ddd88263de111 Mon Sep 17 00:00:00 2001 From: AfterEight Date: Mon, 2 Feb 2015 14:59:52 +0100 Subject: [PATCH 02/31] Modified resetCvImage() in cap_ximea.cpp, so that the IplImage* frame is also updated after the resolution has changed via set(CV_CAP_PROP_FRAME_WIDTH, value)/set(CV_CAP_PROP_XI_DOWNSAMPLING, value) Conflicts: modules/highgui/src/cap_ximea.cpp --- modules/videoio/src/cap_ximea.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/videoio/src/cap_ximea.cpp b/modules/videoio/src/cap_ximea.cpp index ccf49e45b5..b876995f0c 100644 --- a/modules/videoio/src/cap_ximea.cpp +++ b/modules/videoio/src/cap_ximea.cpp @@ -221,7 +221,7 @@ void CvCaptureCAM_XIMEA::resetCvImage() xiGetParamInt( hmv, XI_PRM_HEIGHT, &height); xiGetParamInt( hmv, XI_PRM_IMAGE_DATA_FORMAT, &format); - if( (int)image.width != width || (int)image.height != height || image.frm != (XI_IMG_FORMAT)format) + if( (int)image.width != frame->width || (int)image.height != frame->height || image.frm != (XI_IMG_FORMAT)format) { if(frame) cvReleaseImage(&frame); frame = NULL; From b73894b27197c98e341571666c1e4852e31961f7 Mon Sep 17 00:00:00 2001 From: lujia Date: Tue, 21 Apr 2015 02:32:27 -0400 Subject: [PATCH 03/31] bugfix_for_hog_detectMultiScale_with_weights --- modules/objdetect/src/hog.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/objdetect/src/hog.cpp b/modules/objdetect/src/hog.cpp index 32a6a21b92..bbdc0beb2a 100644 --- a/modules/objdetect/src/hog.cpp +++ b/modules/objdetect/src/hog.cpp @@ -1453,6 +1453,7 @@ void HOGDescriptor::detect(const Mat& img, Size winStride, Size padding, const std::vector& locations) const { hits.clear(); + weights.clear(); if( svmDetector.empty() ) return; From f148eaace9597ee09a6103742455505ddab30ae7 Mon Sep 17 00:00:00 2001 From: Ruslan Baratov Date: Fri, 1 May 2015 21:29:20 +0200 Subject: [PATCH 04/31] Fix errors while compiling with c++11 flag Fix errors in file cap_avfoundation.mm. Compiled with Xcode 6.2, iOS SDK 8.2 Example: cap_avfoundation.mm:543:54: error: cannot initialize a parameter of type 'AVCaptureFocusMode' with an rvalue of type 'int' if ([mCaptureDevice isFocusModeSupported:(int)value]){ ^~~~~~~~~~ --- modules/videoio/src/cap_avfoundation.mm | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/modules/videoio/src/cap_avfoundation.mm b/modules/videoio/src/cap_avfoundation.mm index 60aff674af..d5c7401f2e 100644 --- a/modules/videoio/src/cap_avfoundation.mm +++ b/modules/videoio/src/cap_avfoundation.mm @@ -540,11 +540,11 @@ bool CvCaptureCAM::setProperty(int property_id, double value) { return true; case CV_CAP_PROP_IOS_DEVICE_FOCUS: - if ([mCaptureDevice isFocusModeSupported:(int)value]){ + if ([mCaptureDevice isFocusModeSupported:(AVCaptureFocusMode)value]){ NSError* error = nil; [mCaptureDevice lockForConfiguration:&error]; if (error) return false; - [mCaptureDevice setFocusMode:(int)value]; + [mCaptureDevice setFocusMode:(AVCaptureFocusMode)value]; [mCaptureDevice unlockForConfiguration]; //NSLog(@"Focus set"); return true; @@ -553,11 +553,11 @@ bool CvCaptureCAM::setProperty(int property_id, double value) { } case CV_CAP_PROP_IOS_DEVICE_EXPOSURE: - if ([mCaptureDevice isExposureModeSupported:(int)value]){ + if ([mCaptureDevice isExposureModeSupported:(AVCaptureExposureMode)value]){ NSError* error = nil; [mCaptureDevice lockForConfiguration:&error]; if (error) return false; - [mCaptureDevice setExposureMode:(int)value]; + [mCaptureDevice setExposureMode:(AVCaptureExposureMode)value]; [mCaptureDevice unlockForConfiguration]; //NSLog(@"Exposure set"); return true; @@ -566,11 +566,11 @@ bool CvCaptureCAM::setProperty(int property_id, double value) { } case CV_CAP_PROP_IOS_DEVICE_FLASH: - if ( [mCaptureDevice hasFlash] && [mCaptureDevice isFlashModeSupported:(int)value]){ + if ( [mCaptureDevice hasFlash] && [mCaptureDevice isFlashModeSupported:(AVCaptureFlashMode)value]){ NSError* error = nil; [mCaptureDevice lockForConfiguration:&error]; if (error) return false; - [mCaptureDevice setFlashMode:(int)value]; + [mCaptureDevice setFlashMode:(AVCaptureFlashMode)value]; [mCaptureDevice unlockForConfiguration]; //NSLog(@"Flash mode set"); return true; @@ -579,11 +579,11 @@ bool CvCaptureCAM::setProperty(int property_id, double value) { } case CV_CAP_PROP_IOS_DEVICE_WHITEBALANCE: - if ([mCaptureDevice isWhiteBalanceModeSupported:(int)value]){ + if ([mCaptureDevice isWhiteBalanceModeSupported:(AVCaptureWhiteBalanceMode)value]){ NSError* error = nil; [mCaptureDevice lockForConfiguration:&error]; if (error) return false; - [mCaptureDevice setWhiteBalanceMode:(int)value]; + [mCaptureDevice setWhiteBalanceMode:(AVCaptureWhiteBalanceMode)value]; [mCaptureDevice unlockForConfiguration]; //NSLog(@"White balance set"); return true; @@ -592,11 +592,11 @@ bool CvCaptureCAM::setProperty(int property_id, double value) { } case CV_CAP_PROP_IOS_DEVICE_TORCH: - if ([mCaptureDevice hasFlash] && [mCaptureDevice isTorchModeSupported:(int)value]){ + if ([mCaptureDevice hasFlash] && [mCaptureDevice isTorchModeSupported:(AVCaptureTorchMode)value]){ NSError* error = nil; [mCaptureDevice lockForConfiguration:&error]; if (error) return false; - [mCaptureDevice setTorchMode:(int)value]; + [mCaptureDevice setTorchMode:(AVCaptureTorchMode)value]; [mCaptureDevice unlockForConfiguration]; //NSLog(@"Torch mode set"); return true; From 40b765b7c2de94b6535a4e9fd07780153e6badae Mon Sep 17 00:00:00 2001 From: Patrik Huber Date: Sat, 2 May 2015 15:24:14 +0100 Subject: [PATCH 05/31] Add VS2015 compatibility to CMake scripts --- cmake/OpenCVConfig.cmake | 2 ++ cmake/OpenCVDetectCXXCompiler.cmake | 2 ++ 2 files changed, 4 insertions(+) diff --git a/cmake/OpenCVConfig.cmake b/cmake/OpenCVConfig.cmake index 09174b02fe..83bcb39fe7 100644 --- a/cmake/OpenCVConfig.cmake +++ b/cmake/OpenCVConfig.cmake @@ -82,6 +82,8 @@ if(MSVC) set(OpenCV_RUNTIME vc11) elseif(MSVC_VERSION EQUAL 1800) set(OpenCV_RUNTIME vc12) + elseif(MSVC_VERSION EQUAL 1900) + set(OpenCV_RUNTIME vc14) endif() elseif(MINGW) set(OpenCV_RUNTIME mingw) diff --git a/cmake/OpenCVDetectCXXCompiler.cmake b/cmake/OpenCVDetectCXXCompiler.cmake index c8484dca3f..49413467d0 100644 --- a/cmake/OpenCVDetectCXXCompiler.cmake +++ b/cmake/OpenCVDetectCXXCompiler.cmake @@ -143,6 +143,8 @@ if(MSVC) set(OpenCV_RUNTIME vc11) elseif(MSVC_VERSION EQUAL 1800) set(OpenCV_RUNTIME vc12) + elseif(MSVC_VERSION EQUAL 1900) + set(OpenCV_RUNTIME vc14) endif() elseif(MINGW) set(OpenCV_RUNTIME mingw) From 441f93d58ddf648e502c7470681b52fcd8e4b02a Mon Sep 17 00:00:00 2001 From: Ruslan Baratov Date: Sat, 2 May 2015 23:44:19 +0200 Subject: [PATCH 06/31] Unify iOS platform check There is only one place that use condition `CMAKE_SYSTEM_NAME STREQUAL iOS`. All other `if` command use just IOS. --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a02b71a8bb..c7258144cb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -488,7 +488,7 @@ include(cmake/OpenCVModule.cmake) # Detect endianness of build platform # ---------------------------------------------------------------------------- -if(CMAKE_SYSTEM_NAME STREQUAL iOS) +if(IOS) # test_big_endian needs try_compile, which doesn't work for iOS # http://public.kitware.com/Bug/view.php?id=12288 set(WORDS_BIGENDIAN 0) From a94fdbe0f0434d1cbc4e8c19c60c8137a45352f5 Mon Sep 17 00:00:00 2001 From: laurentBerger Date: Mon, 11 May 2015 13:13:20 +0200 Subject: [PATCH 07/31] Example about BLOB with a new image in data folder --- data/example_blob.bmp | Bin 0 -> 414518 bytes samples/cpp/exampleBLOB.cpp | 210 ++++++++++++++++++++++++++++++++++++ 2 files changed, 210 insertions(+) create mode 100644 data/example_blob.bmp create mode 100644 samples/cpp/exampleBLOB.cpp diff --git a/data/example_blob.bmp b/data/example_blob.bmp new file mode 100644 index 0000000000000000000000000000000000000000..a974ef2c20a35c06ed06ccd08dd495cb096fa286 GIT binary patch literal 414518 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 +#include +#include +#include + +using namespace std; +using namespace cv; + + +static void help() +{ + cout << "\n This program demonstrates how to use BLOB and MSER to detect region \n" + "Usage: \n" + " ./BLOB_MSER \n" + "Press a key when image window is active to change descriptor"; +} + + +String Legende(SimpleBlobDetector::Params &pAct) +{ + String s = ""; + if (pAct.filterByArea) + { + String inf = static_cast(&(ostringstream() << pAct.minArea))->str(); + String sup = static_cast(&(ostringstream() << pAct.maxArea))->str(); + s = " Area range [" + inf + " to " + sup + "]"; + } + if (pAct.filterByCircularity) + { + String inf = static_cast(&(ostringstream() << pAct.minCircularity))->str(); + String sup = static_cast(&(ostringstream() << pAct.maxCircularity))->str(); + if (s.length() == 0) + s = " Circularity range [" + inf + " to " + sup + "]"; + else + s += " AND Circularity range [" + inf + " to " + sup + "]"; + } + if (pAct.filterByColor) + { + String inf = static_cast(&(ostringstream() << (int)pAct.blobColor))->str(); + if (s.length() == 0) + s = " Blob color " + inf; + else + s += " AND Blob color " + inf; + } + if (pAct.filterByConvexity) + { + String inf = static_cast(&(ostringstream() << pAct.minConvexity))->str(); + String sup = static_cast(&(ostringstream() << pAct.maxConvexity))->str(); + if (s.length() == 0) + s = " Convexity range[" + inf + " to " + sup + "]"; + else + s += " AND Convexity range[" + inf + " to " + sup + "]"; + } + if (pAct.filterByInertia) + { + String inf = static_cast(&(ostringstream() << pAct.minInertiaRatio))->str(); + String sup = static_cast(&(ostringstream() << pAct.maxInertiaRatio))->str(); + if (s.length() == 0) + s = " Inertia ratio range [" + inf + " to " + sup + "]"; + else + s += " AND Inertia ratio range [" + inf + " to " + sup + "]"; + } + return s; +} + + + +int main(int argc, char *argv[]) +{ + vector fileName; + Mat img(600, 800, CV_8UC1); + if (argc == 1) + { + fileName.push_back("../data/example_blob.bmp"); + } + else if (argc == 2) + { + fileName.push_back(argv[1]); + } + else + { + help(); + return(0); + } + img = imread(fileName[0], IMREAD_UNCHANGED); + if (img.rows*img.cols <= 0) + { + cout << "Image " << fileName[0] << " is empty or cannot be found\n"; + return(0); + } + + SimpleBlobDetector::Params pDefaultBLOB; + // This is default parameters for SimpleBlobDetector + pDefaultBLOB.thresholdStep = 10; + pDefaultBLOB.minThreshold = 10; + pDefaultBLOB.maxThreshold = 220; + pDefaultBLOB.minRepeatability = 2; + pDefaultBLOB.minDistBetweenBlobs = 10; + pDefaultBLOB.filterByColor = false; + pDefaultBLOB.blobColor = 0; + pDefaultBLOB.filterByArea = false; + pDefaultBLOB.minArea = 25; + pDefaultBLOB.maxArea = 5000; + pDefaultBLOB.filterByCircularity = false; + pDefaultBLOB.minCircularity = 0.9f; + pDefaultBLOB.maxCircularity = std::numeric_limits::max(); + pDefaultBLOB.filterByInertia = false; + pDefaultBLOB.minInertiaRatio = 0.1f; + pDefaultBLOB.maxInertiaRatio = std::numeric_limits::max(); + pDefaultBLOB.filterByConvexity = false; + pDefaultBLOB.minConvexity = 0.95f; + pDefaultBLOB.maxConvexity = std::numeric_limits::max(); + // Descriptor array (BLOB or MSER) + vector typeDesc; + // Param array for BLOB + vector pBLOB; + vector::iterator itBLOB; + // Param array for MSER + + // Color palette + vector< Vec3b > palette; + for (int i = 0; i<65536; i++) + { + palette.push_back(Vec3b((uchar)rand(), (uchar)rand(), (uchar)rand())); + } + help(); + + typeDesc.push_back("BLOB"); + pBLOB.push_back(pDefaultBLOB); + pBLOB.back().filterByColor = true; + pBLOB.back().blobColor = 0; + + // This descriptor are going to be detect and compute BLOBS with 5 differents params + // Param for first BLOB detector we want all + typeDesc.push_back("BLOB"); // see http://docs.opencv.org/trunk/d0/d7a/classcv_1_1SimpleBlobDetector.html + pBLOB.push_back(pDefaultBLOB); + pBLOB.back().filterByArea = true; + pBLOB.back().minArea = 1; + pBLOB.back().maxArea = float(img.rows*img.cols); + // Param for second BLOB detector we want area between 500 and 2900 pixels + typeDesc.push_back("BLOB"); + pBLOB.push_back(pDefaultBLOB); + pBLOB.back().filterByArea = true; + pBLOB.back().minArea = 500; + pBLOB.back().maxArea = 2900; + // Param for third BLOB detector we want only circular object + typeDesc.push_back("BLOB"); + pBLOB.push_back(pDefaultBLOB); + pBLOB.back().filterByCircularity = true; + // Param for Fourth BLOB detector we want ratio inertia + typeDesc.push_back("BLOB"); + pBLOB.push_back(pDefaultBLOB); + pBLOB.back().filterByInertia = true; + pBLOB.back().minInertiaRatio = 0; + pBLOB.back().maxInertiaRatio = (float)0.2; + // Param for Fourth BLOB detector we want ratio inertia + typeDesc.push_back("BLOB"); + pBLOB.push_back(pDefaultBLOB); + pBLOB.back().filterByConvexity = true; + pBLOB.back().minConvexity = 0.; + pBLOB.back().maxConvexity = (float)0.9; + + itBLOB = pBLOB.begin(); + vector desMethCmp; + Ptr b; + String label; + // Descriptor loop + vector::iterator itDesc; + for (itDesc = typeDesc.begin(); itDesc != typeDesc.end(); itDesc++) + { + vector keyImg1; + if (*itDesc == "BLOB") + { + b = SimpleBlobDetector::create(*itBLOB); + label = Legende(*itBLOB); + itBLOB++; + } + try + { + // We can detect keypoint with detect method + vector keyImg; + vector zone; + vector> region; + Mat desc, result(img.rows, img.cols, CV_8UC3); + if (b.dynamicCast() != NULL) + { + Ptr sbd = b.dynamicCast(); + sbd->detect(img, keyImg, Mat()); + drawKeypoints(img, keyImg, result); + int i = 0; + for (vector::iterator k = keyImg.begin(); k != keyImg.end(); k++, i++) + circle(result, k->pt, (int)k->size, palette[i % 65536]); + } + namedWindow(*itDesc + label, WINDOW_AUTOSIZE); + imshow(*itDesc + label, result); + imshow("Original", img); + waitKey(); + } + catch (Exception& e) + { + cout << "Feature : " << *itDesc << "\n"; + cout << e.msg << endl; + } + } + return 0; +} + + + + From 05bc7621e62865815b0988f98d8edf814ea560a6 Mon Sep 17 00:00:00 2001 From: laurentBerger Date: Mon, 11 May 2015 13:20:52 +0200 Subject: [PATCH 08/31] trailing whitespace --- samples/cpp/exampleBLOB.cpp | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/samples/cpp/exampleBLOB.cpp b/samples/cpp/exampleBLOB.cpp index 25a575540f..de6f0c6077 100644 --- a/samples/cpp/exampleBLOB.cpp +++ b/samples/cpp/exampleBLOB.cpp @@ -175,7 +175,7 @@ int main(int argc, char *argv[]) label = Legende(*itBLOB); itBLOB++; } - try + try { // We can detect keypoint with detect method vector keyImg; @@ -204,7 +204,3 @@ int main(int argc, char *argv[]) } return 0; } - - - - From dfc508bb15821d1c83211657881601e42af9f62f Mon Sep 17 00:00:00 2001 From: laurentBerger Date: Mon, 11 May 2015 13:45:08 +0200 Subject: [PATCH 09/31] problem float constant and position of > in vector --- samples/cpp/exampleBLOB.cpp | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/samples/cpp/exampleBLOB.cpp b/samples/cpp/exampleBLOB.cpp index de6f0c6077..a1a020f06c 100644 --- a/samples/cpp/exampleBLOB.cpp +++ b/samples/cpp/exampleBLOB.cpp @@ -16,7 +16,7 @@ static void help() } -String Legende(SimpleBlobDetector::Params &pAct) +static String Legende(SimpleBlobDetector::Params &pAct) { String s = ""; if (pAct.filterByArea) @@ -103,13 +103,13 @@ int main(int argc, char *argv[]) pDefaultBLOB.maxArea = 5000; pDefaultBLOB.filterByCircularity = false; pDefaultBLOB.minCircularity = 0.9f; - pDefaultBLOB.maxCircularity = std::numeric_limits::max(); + pDefaultBLOB.maxCircularity = (float)1e37; pDefaultBLOB.filterByInertia = false; pDefaultBLOB.minInertiaRatio = 0.1f; - pDefaultBLOB.maxInertiaRatio = std::numeric_limits::max(); + pDefaultBLOB.maxInertiaRatio = (float)1e37; pDefaultBLOB.filterByConvexity = false; pDefaultBLOB.minConvexity = 0.95f; - pDefaultBLOB.maxConvexity = std::numeric_limits::max(); + pDefaultBLOB.maxConvexity = (float)1e37; // Descriptor array (BLOB or MSER) vector typeDesc; // Param array for BLOB @@ -125,12 +125,8 @@ int main(int argc, char *argv[]) } help(); - typeDesc.push_back("BLOB"); - pBLOB.push_back(pDefaultBLOB); - pBLOB.back().filterByColor = true; - pBLOB.back().blobColor = 0; - // This descriptor are going to be detect and compute BLOBS with 5 differents params + // This descriptor are going to be detect and compute BLOBS with 6 differents params // Param for first BLOB detector we want all typeDesc.push_back("BLOB"); // see http://docs.opencv.org/trunk/d0/d7a/classcv_1_1SimpleBlobDetector.html pBLOB.push_back(pDefaultBLOB); @@ -153,12 +149,17 @@ int main(int argc, char *argv[]) pBLOB.back().filterByInertia = true; pBLOB.back().minInertiaRatio = 0; pBLOB.back().maxInertiaRatio = (float)0.2; - // Param for Fourth BLOB detector we want ratio inertia + // Param for fifth BLOB detector we want ratio inertia typeDesc.push_back("BLOB"); pBLOB.push_back(pDefaultBLOB); pBLOB.back().filterByConvexity = true; pBLOB.back().minConvexity = 0.; pBLOB.back().maxConvexity = (float)0.9; + // Param for six BLOB detector we want blob with gravity center color equal to 0 bug #4321 must be fixed + typeDesc.push_back("BLOB"); + pBLOB.push_back(pDefaultBLOB); + pBLOB.back().filterByColor = true; + pBLOB.back().blobColor = 0; itBLOB = pBLOB.begin(); vector desMethCmp; @@ -180,7 +181,7 @@ int main(int argc, char *argv[]) // We can detect keypoint with detect method vector keyImg; vector zone; - vector> region; + vector > region; Mat desc, result(img.rows, img.cols, CV_8UC3); if (b.dynamicCast() != NULL) { From 780f4ae7c5f57a0e6382b78937a123c43d617719 Mon Sep 17 00:00:00 2001 From: laurentBerger Date: Tue, 12 May 2015 19:01:05 +0200 Subject: [PATCH 10/31] try to implement remark included in message --- data/detect_blob.png | Bin 0 -> 34115 bytes .../cpp/{exampleBLOB.cpp => detect_blob.cpp} | 12 +++++------- 2 files changed, 5 insertions(+), 7 deletions(-) create mode 100644 data/detect_blob.png rename samples/cpp/{exampleBLOB.cpp => detect_blob.cpp} (95%) diff --git a/data/detect_blob.png b/data/detect_blob.png new file mode 100644 index 0000000000000000000000000000000000000000..fe8537ab0fe1511232e07d7ce1769e959136397e GIT binary patch literal 34115 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%0DHR1k=8F4g0692y=UTFTh#zXqgrUzV!tO2|; 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
  • xr~OpRXqwGl}ahui3V?Wn2VzLz<9O0@;Kb49)@N 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 bJG`NPnMy;Nx4?}~d-mv{4YUe1?uPs?@I4cQ literal 0 HcmV?d00001 diff --git a/samples/cpp/exampleBLOB.cpp b/samples/cpp/detect_blob.cpp similarity index 95% rename from samples/cpp/exampleBLOB.cpp rename to samples/cpp/detect_blob.cpp index a1a020f06c..badbaaa416 100644 --- a/samples/cpp/exampleBLOB.cpp +++ b/samples/cpp/detect_blob.cpp @@ -9,9 +9,9 @@ using namespace cv; static void help() { - cout << "\n This program demonstrates how to use BLOB and MSER to detect region \n" + cout << "\n This program demonstrates how to use BLOB to detect and filter region \n" "Usage: \n" - " ./BLOB_MSER \n" + " ./detect_blob \n" "Press a key when image window is active to change descriptor"; } @@ -71,7 +71,7 @@ int main(int argc, char *argv[]) Mat img(600, 800, CV_8UC1); if (argc == 1) { - fileName.push_back("../data/example_blob.bmp"); + fileName.push_back("../data/detect_blob.png"); } else if (argc == 2) { @@ -82,7 +82,7 @@ int main(int argc, char *argv[]) help(); return(0); } - img = imread(fileName[0], IMREAD_UNCHANGED); + img = imread(fileName[0], IMREAD_COLOR); if (img.rows*img.cols <= 0) { cout << "Image " << fileName[0] << " is empty or cannot be found\n"; @@ -110,13 +110,11 @@ int main(int argc, char *argv[]) pDefaultBLOB.filterByConvexity = false; pDefaultBLOB.minConvexity = 0.95f; pDefaultBLOB.maxConvexity = (float)1e37; - // Descriptor array (BLOB or MSER) + // Descriptor array for BLOB vector typeDesc; // Param array for BLOB vector pBLOB; vector::iterator itBLOB; - // Param array for MSER - // Color palette vector< Vec3b > palette; for (int i = 0; i<65536; i++) From 6425ac3b13445a5629854b67696bfd7b35024e59 Mon Sep 17 00:00:00 2001 From: Christian Richardt Date: Wed, 13 May 2015 17:34:14 +0200 Subject: [PATCH 11/31] Added color map similar to Matlab's new default color map 'parula'. --- .../doc/pics/colormaps/colorscale_parula.jpg | Bin 0 -> 1433 bytes modules/imgproc/include/opencv2/imgproc.hpp | 3 ++- modules/imgproc/src/colormap.cpp | 25 ++++++++++++++++++ 3 files changed, 27 insertions(+), 1 deletion(-) create mode 100644 modules/imgproc/doc/pics/colormaps/colorscale_parula.jpg diff --git a/modules/imgproc/doc/pics/colormaps/colorscale_parula.jpg b/modules/imgproc/doc/pics/colormaps/colorscale_parula.jpg new file mode 100644 index 0000000000000000000000000000000000000000..2e79a8b70c658b4aee6956919821ee8bd5ed4944 GIT binary patch literal 1433 zcmbV~eKcEl7{_nkZV20?Ep1twQ?0F&`J-yJr6Y%Ktl2pn^-|)j4kk$GM!jrER6Dxb zTI)I#$JET&52WbKej!;^Lx(oyU%m)`F`&A zw>`4`1hQfIoc4imI0(Xl1#LfsPCag2?0|jb*{gUGfk2{=VX|rDKc($9h-v{H#6bj{BZQ~o2vpp5Cqx4}NhWzf z?6bh(2}BZ11~RO`fW!vKClG*W5>O1L`JfLGsia+pj(Nem10uf< zJu|2|ay%;ek|o7%@4o%^PA|QD^c82f*G{;<{s!aJTW|aLzH^!t7!(|GHZ+VK{eBE5 zHZGofAtf~}{iBaFE`O4ncjeQo`Cs1rs<5c|R!QkMRo_;BS5y1_5B1^(iL~*jJ5B8! zoxgN-|Ju_#B$E#-lp`wj_{7uS|CpSbo|#?#b49CLU0c^1FfNSK9RJ8g1zdQ{12V>i z!>5Bypb|-kj={UU0?3g`yB%F~EcSTcs1)6^Jbe6&#x^Q>kYablZQN-YLo<>6JFrXt zi);t%Z!R@tO~3*32vmp(ZO+LA1|vP)Z$T?`abH4*8dDY@v$kZtYrbvEWVL(BR@Gd1 zQ}&o`ZjFw{9+hor(82naE90A9tJmt7KhvWg)EX2X6=SxdSUI0J&~;vr?a`k}YoT+x z8xzwt_?WFv;LJ~cJy}@erK?*V_Lki?3~zAtLcjTCQTe;la+C>XLRDpkvSxzrjU~^W>S@xbzdZSRUT&k87NPq|$`S|o zbe0UsIuRq^V8Pdbe&nQ|q$GZT&-0TZg3J<~N9lp*PBO<49-~LRWv>vU7yHsU`;h)j z&&xAxX+@?+SZA)#oWAtf{s}3wn7?C0`;I%P;S1o&3e$#PmF_?5DQT`Tj)$_d19ZqJ zbBSVfpic{EowPW$c%xnVs-XahRvE{`?fAZmyVjhksg*}c(Z+-{A(PLu?_SDRi57Hd zQP=tV@r&{76dJoVG027S0umubOFI`IIP8}<0|c(IHKM)N)c!!JK`TI~xGU97I2ZC8 z@I1Jjt4amGt4~&|;UI-vm6pcptw+KEO+-1TOg#G`=dRg`D6>0fCsnP1+Ba`jO3YS- zO3m)*uP4fl7o4WKY~3a)LIM!ImFN>^BMO|q*sWuR^fLA$83M-!7m&mY=Bma0fZXVN zbUH3Pg~l3cm=Q{6|XcLe<5uwNiR_s`VGU)3V0s(c7xO03@H8D*ylh literal 0 HcmV?d00001 diff --git a/modules/imgproc/include/opencv2/imgproc.hpp b/modules/imgproc/include/opencv2/imgproc.hpp index ac93e45809..5c18545bce 100644 --- a/modules/imgproc/include/opencv2/imgproc.hpp +++ b/modules/imgproc/include/opencv2/imgproc.hpp @@ -3741,7 +3741,8 @@ enum ColormapTypes COLORMAP_COOL = 8, //!< ![cool](pics/colormaps/colorscale_cool.jpg) COLORMAP_HSV = 9, //!< ![HSV](pics/colormaps/colorscale_hsv.jpg) COLORMAP_PINK = 10, //!< ![pink](pics/colormaps/colorscale_pink.jpg) - COLORMAP_HOT = 11 //!< ![hot](pics/colormaps/colorscale_hot.jpg) + COLORMAP_HOT = 11, //!< ![hot](pics/colormaps/colorscale_hot.jpg) + COLORMAP_PARULA = 12 //!< ![hot](pics/colormaps/colorscale_parula.jpg) }; /** @brief Applies a GNU Octave/MATLAB equivalent colormap on a given image. diff --git a/modules/imgproc/src/colormap.cpp b/modules/imgproc/src/colormap.cpp index 86d8679e6f..8e5236ce46 100644 --- a/modules/imgproc/src/colormap.cpp +++ b/modules/imgproc/src/colormap.cpp @@ -469,6 +469,30 @@ namespace colormap } }; + // Colormap similar to MATLAB's "parula". + class Parula : public ColorMap { + public: + Parula() : ColorMap() { + init(256); + } + + Parula(int n) : ColorMap() { + init(n); + } + + void init(int n) { + float r[] = { 0.2078, 0.0118, 0.0784, 0.0235, 0.2196, 0.5725, 0.8510, 0.9882, 0.9765 }; + float g[] = { 0.1647, 0.3882, 0.5216, 0.6549, 0.7255, 0.7490, 0.7294, 0.8078, 0.9843 }; + float b[] = { 0.5294, 0.8824, 0.8314, 0.7765, 0.6196, 0.4510, 0.3373, 0.1804, 0.0549 }; + Mat X = linspace(0, 1, 9); + this->_lut = ColorMap::linear_colormap(X, + Mat(9, 1, CV_32FC1, r).clone(), // red + Mat(9, 1, CV_32FC1, g).clone(), // green + Mat(9, 1, CV_32FC1, b).clone(), // blue + n); // number of sample points + } + }; + void ColorMap::operator()(InputArray _src, OutputArray _dst) const { if(_lut.total() != 256) @@ -513,6 +537,7 @@ namespace colormap colormap == COLORMAP_HSV ? (colormap::ColorMap*)(new colormap::HSV) : colormap == COLORMAP_JET ? (colormap::ColorMap*)(new colormap::Jet) : colormap == COLORMAP_OCEAN ? (colormap::ColorMap*)(new colormap::Ocean) : + colormap == COLORMAP_PARULA ? (colormap::ColorMap*)(new colormap::Parula) : colormap == COLORMAP_PINK ? (colormap::ColorMap*)(new colormap::Pink) : colormap == COLORMAP_RAINBOW ? (colormap::ColorMap*)(new colormap::Rainbow) : colormap == COLORMAP_SPRING ? (colormap::ColorMap*)(new colormap::Spring) : From 31ef944176134b4cb8d93b3bdd4200ed2e1feadc Mon Sep 17 00:00:00 2001 From: laurentBerger Date: Wed, 13 May 2015 18:06:26 +0200 Subject: [PATCH 12/31] remove example_blob.bmp --- data/example_blob.bmp | Bin 414518 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 data/example_blob.bmp diff --git a/data/example_blob.bmp b/data/example_blob.bmp deleted file mode 100644 index a974ef2c20a35c06ed06ccd08dd495cb096fa286..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 414518 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 Date: Wed, 13 May 2015 22:00:02 +0300 Subject: [PATCH 13/31] some fixes from http://code.opencv.org/issues/3733 --- modules/imgproc/src/filter.cpp | 27 ++++++++++----------------- 1 file changed, 10 insertions(+), 17 deletions(-) diff --git a/modules/imgproc/src/filter.cpp b/modules/imgproc/src/filter.cpp index fb43eee0a1..f0b7ee79e5 100644 --- a/modules/imgproc/src/filter.cpp +++ b/modules/imgproc/src/filter.cpp @@ -3455,7 +3455,7 @@ struct SymmColumnSmallFilter : public SymmColumnFilter bool symmetrical = (this->symmetryType & KERNEL_SYMMETRICAL) != 0; bool is_1_2_1 = ky[0] == 2 && ky[1] == 1; bool is_1_m2_1 = ky[0] == -2 && ky[1] == 1; - bool is_m1_0_1 = ky[1] == 1 || ky[1] == -1; + bool is_m1_0_1 = ky[0] == 0 && (ky[1] == 1 || ky[1] == -1); ST f0 = ky[0], f1 = ky[1]; ST _delta = this->delta; CastOp castOp = this->castOp0; @@ -3486,13 +3486,12 @@ struct SymmColumnSmallFilter : public SymmColumnFilter D[i+2] = castOp(s0); D[i+3] = castOp(s1); } - #else + #endif for( ; i < width; i ++ ) { ST s0 = S0[i] + S1[i]*2 + S2[i] + _delta; D[i] = castOp(s0); } - #endif } else if( is_1_m2_1 ) { @@ -3509,17 +3508,16 @@ struct SymmColumnSmallFilter : public SymmColumnFilter D[i+2] = castOp(s0); D[i+3] = castOp(s1); } - #else + #endif for( ; i < width; i ++ ) { ST s0 = S0[i] - S1[i]*2 + S2[i] + _delta; D[i] = castOp(s0); } - #endif } else { - #if CV_ENABLE_UNROLLED + #if CV_ENABLE_UNROLLED for( ; i <= width - 4; i += 4 ) { ST s0 = (S0[i] + S2[i])*f1 + S1[i]*f0 + _delta; @@ -3532,16 +3530,13 @@ struct SymmColumnSmallFilter : public SymmColumnFilter D[i+2] = castOp(s0); D[i+3] = castOp(s1); } - #else + #endif for( ; i < width; i ++ ) { ST s0 = (S0[i] + S2[i])*f1 + S1[i]*f0 + _delta; D[i] = castOp(s0); } - #endif } - for( ; i < width; i++ ) - D[i] = castOp((S0[i] + S2[i])*f1 + S1[i]*f0 + _delta); } else { @@ -3549,7 +3544,7 @@ struct SymmColumnSmallFilter : public SymmColumnFilter { if( f1 < 0 ) std::swap(S0, S2); - #if CV_ENABLE_UNROLLED + #if CV_ENABLE_UNROLLED for( ; i <= width - 4; i += 4 ) { ST s0 = S2[i] - S0[i] + _delta; @@ -3562,19 +3557,18 @@ struct SymmColumnSmallFilter : public SymmColumnFilter D[i+2] = castOp(s0); D[i+3] = castOp(s1); } - #else + #endif for( ; i < width; i ++ ) { ST s0 = S2[i] - S0[i] + _delta; D[i] = castOp(s0); } - #endif if( f1 < 0 ) std::swap(S0, S2); } else { - #if CV_ENABLE_UNROLLED + #if CV_ENABLE_UNROLLED for( ; i <= width - 4; i += 4 ) { ST s0 = (S2[i] - S0[i])*f1 + _delta; @@ -3588,10 +3582,9 @@ struct SymmColumnSmallFilter : public SymmColumnFilter D[i+3] = castOp(s1); } #endif + for( ; i < width; i++ ) + D[i] = castOp((S2[i] - S0[i])*f1 + _delta); } - - for( ; i < width; i++ ) - D[i] = castOp((S2[i] - S0[i])*f1 + _delta); } } } From d3b0cb878a14430013fe00a8198f2bf9f486062d Mon Sep 17 00:00:00 2001 From: Vadim Pisarevsky Date: Wed, 13 May 2015 22:16:35 +0300 Subject: [PATCH 14/31] added test for http://code.opencv.org/issues/2736 --- modules/imgproc/test/test_filter.cpp | 34 ++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/modules/imgproc/test/test_filter.cpp b/modules/imgproc/test/test_filter.cpp index a203e60f5c..9253132186 100644 --- a/modules/imgproc/test/test_filter.cpp +++ b/modules/imgproc/test/test_filter.cpp @@ -1918,3 +1918,37 @@ TEST(Imgproc_Blur, borderTypes) EXPECT_EQ(expected_dst.size(), dst.size()); EXPECT_DOUBLE_EQ(0.0, cvtest::norm(expected_dst, dst, NORM_INF)); } + +TEST(Imgproc_Morphology, iterated) +{ + RNG& rng = theRNG(); + for( int iter = 0; iter < 30; iter++ ) + { + int width = rng.uniform(5, 33); + int height = rng.uniform(5, 33); + int cn = rng.uniform(1, 5); + int iterations = rng.uniform(1, 11); + int op = rng.uniform(0, 2); + Mat src(height, width, CV_8UC(cn)), dst0, dst1, dst2; + + randu(src, 0, 256); + if( op == 0 ) + dilate(src, dst0, Mat(), Point(-1,-1), iterations); + else + erode(src, dst0, Mat(), Point(-1,-1), iterations); + + for( int i = 0; i < iterations; i++ ) + if( op == 0 ) + dilate(i == 0 ? src : dst1, dst1, Mat(), Point(-1,-1), 1); + else + erode(i == 0 ? src : dst1, dst1, Mat(), Point(-1,-1), 1); + + Mat kern = getStructuringElement(MORPH_RECT, Size(3,3)); + if( op == 0 ) + dilate(src, dst2, kern, Point(-1,-1), iterations); + else + erode(src, dst2, kern, Point(-1,-1), iterations); + ASSERT_EQ(0.0, norm(dst0, dst1, NORM_INF)); + ASSERT_EQ(0.0, norm(dst0, dst2, NORM_INF)); + } +} From 2e7e754032e41830f591e45217c8db29fcdfdc79 Mon Sep 17 00:00:00 2001 From: Vadim Pisarevsky Date: Thu, 14 May 2015 08:06:46 +0300 Subject: [PATCH 15/31] added support for n-channel (n>4) images in warpAffine/warpPerspective/remap: http://code.opencv.org/issues/4190 --- modules/imgproc/src/imgwarp.cpp | 26 +++++++++++++++++++------- modules/imgproc/test/test_imgwarp.cpp | 22 ++++++++++++++++++++++ 2 files changed, 41 insertions(+), 7 deletions(-) diff --git a/modules/imgproc/src/imgwarp.cpp b/modules/imgproc/src/imgwarp.cpp index 8a11515389..792ba1d959 100644 --- a/modules/imgproc/src/imgwarp.cpp +++ b/modules/imgproc/src/imgwarp.cpp @@ -3805,20 +3805,20 @@ static void remapBilinear( const Mat& _src, Mat& _dst, const Mat& _xy, typedef typename CastOp::rtype T; typedef typename CastOp::type1 WT; Size ssize = _src.size(), dsize = _dst.size(); - int cn = _src.channels(); + int k, cn = _src.channels(); const AT* wtab = (const AT*)_wtab; const T* S0 = _src.ptr(); size_t sstep = _src.step/sizeof(S0[0]); - Scalar_ cval(saturate_cast(_borderValue[0]), - saturate_cast(_borderValue[1]), - saturate_cast(_borderValue[2]), - saturate_cast(_borderValue[3])); + T cval[CV_CN_MAX]; int dx, dy; CastOp castOp; VecOp vecOp; + for( k = 0; k < cn; k++ ) + cval[k] = saturate_cast(_borderValue[k & 3]); + unsigned width1 = std::max(ssize.width-1, 0), height1 = std::max(ssize.height-1, 0); - CV_Assert( cn <= 4 && ssize.area() > 0 ); + CV_Assert( ssize.area() > 0 ); #if CV_SSE2 if( _src.type() == CV_8UC3 ) width1 = std::max(ssize.width-2, 0); @@ -3882,7 +3882,7 @@ static void remapBilinear( const Mat& _src, Mat& _dst, const Mat& _xy, WT t2 = S[2]*w[0] + S[5]*w[1] + S[sstep+2]*w[2] + S[sstep+5]*w[3]; D[0] = castOp(t0); D[1] = castOp(t1); D[2] = castOp(t2); } - else + else if( cn == 4 ) for( ; dx < X1; dx++, D += 4 ) { int sx = XY[dx*2], sy = XY[dx*2+1]; @@ -3895,6 +3895,18 @@ static void remapBilinear( const Mat& _src, Mat& _dst, const Mat& _xy, t1 = S[3]*w[0] + S[7]*w[1] + S[sstep+3]*w[2] + S[sstep+7]*w[3]; D[2] = castOp(t0); D[3] = castOp(t1); } + else + for( ; dx < X1; dx++, D += cn ) + { + int sx = XY[dx*2], sy = XY[dx*2+1]; + const AT* w = wtab + FXY[dx]*4; + const T* S = S0 + sy*sstep + sx*cn; + for( k = 0; k < cn; k++ ) + { + WT t0 = S[k]*w[0] + S[k+cn]*w[1] + S[sstep+k]*w[2] + S[sstep+k+cn]*w[3]; + D[k] = castOp(t0); + } + } } else { diff --git a/modules/imgproc/test/test_imgwarp.cpp b/modules/imgproc/test/test_imgwarp.cpp index 176c9907f3..9fa48de007 100644 --- a/modules/imgproc/test/test_imgwarp.cpp +++ b/modules/imgproc/test/test_imgwarp.cpp @@ -1632,4 +1632,26 @@ TEST(Resize, Area_half) } } +TEST(Imgproc_Warp, multichannel) +{ + RNG& rng = theRNG(); + for( int iter = 0; iter < 30; iter++ ) + { + int width = rng.uniform(3, 333); + int height = rng.uniform(3, 333); + int cn = rng.uniform(1, 10); + Mat src(height, width, CV_8UC(cn)), dst; + //randu(src, 0, 256); + src.setTo(0.); + + Mat rot = getRotationMatrix2D(Point2f(0.f, 0.f), 1, 1); + warpAffine(src, dst, rot, src.size()); + ASSERT_EQ(0.0, norm(dst, NORM_INF)); + Mat rot2 = Mat::eye(3, 3, rot.type()); + rot.copyTo(rot2.rowRange(0, 2)); + warpPerspective(src, dst, rot2, src.size()); + ASSERT_EQ(0.0, norm(dst, NORM_INF)); + } +} + /* End of file. */ From feb5b6aa93a12859ba0fa9d99eff5d0b1cccb08f Mon Sep 17 00:00:00 2001 From: Vadim Pisarevsky Date: Thu, 14 May 2015 10:42:55 +0300 Subject: [PATCH 16/31] increased singularity epsilon in LU decomposition. This solved singular case from http://code.opencv.org/issues/3305. Added the respective test. --- modules/hal/src/matrix.cpp | 8 ++++---- modules/imgproc/test/test_imgwarp.cpp | 14 ++++++++++++++ 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/modules/hal/src/matrix.cpp b/modules/hal/src/matrix.cpp index 9506aaf478..921b7783f7 100644 --- a/modules/hal/src/matrix.cpp +++ b/modules/hal/src/matrix.cpp @@ -49,7 +49,7 @@ namespace cv { namespace hal { \****************************************************************************************/ template static inline int -LUImpl(_Tp* A, size_t astep, int m, _Tp* b, size_t bstep, int n) +LUImpl(_Tp* A, size_t astep, int m, _Tp* b, size_t bstep, int n, _Tp eps) { int i, j, k, p = 1; astep /= sizeof(A[0]); @@ -63,7 +63,7 @@ LUImpl(_Tp* A, size_t astep, int m, _Tp* b, size_t bstep, int n) if( std::abs(A[j*astep + i]) > std::abs(A[k*astep + i]) ) k = j; - if( std::abs(A[k*astep + i]) < std::numeric_limits<_Tp>::epsilon() ) + if( std::abs(A[k*astep + i]) < eps ) return 0; if( k != i ) @@ -111,13 +111,13 @@ LUImpl(_Tp* A, size_t astep, int m, _Tp* b, size_t bstep, int n) int LU(float* A, size_t astep, int m, float* b, size_t bstep, int n) { - return LUImpl(A, astep, m, b, bstep, n); + return LUImpl(A, astep, m, b, bstep, n, FLT_EPSILON*10); } int LU(double* A, size_t astep, int m, double* b, size_t bstep, int n) { - return LUImpl(A, astep, m, b, bstep, n); + return LUImpl(A, astep, m, b, bstep, n, DBL_EPSILON*100); } diff --git a/modules/imgproc/test/test_imgwarp.cpp b/modules/imgproc/test/test_imgwarp.cpp index 9fa48de007..d15f72e409 100644 --- a/modules/imgproc/test/test_imgwarp.cpp +++ b/modules/imgproc/test/test_imgwarp.cpp @@ -1654,4 +1654,18 @@ TEST(Imgproc_Warp, multichannel) } } +TEST(Imgproc_GetAffineTransform, singularity) +{ + Point2f A_sample[3]; + A_sample[0] = cv::Point2f(8, 9); + A_sample[1] = cv::Point2f(40, 41); + A_sample[2] = cv::Point2f(47, 48); + Point2f B_sample[3]; + B_sample[0] = cv::Point2f(7.37465, 11.8295); + B_sample[1] = cv::Point2f(15.0113, 12.8994); + B_sample[2] = cv::Point2f(38.9943, 9.56297); + Mat trans = cv::getAffineTransform(A_sample, B_sample); + ASSERT_EQ(0.0, norm(trans, NORM_INF)); +} + /* End of file. */ From b37aaa8303129dfeb6f2e7b151493055a0ea9ee6 Mon Sep 17 00:00:00 2001 From: Vadim Pisarevsky Date: Thu, 14 May 2015 15:39:42 +0300 Subject: [PATCH 17/31] significantly improved parallel non-local means by using granularity parameter in parallel_for_ loop. Because the algorithm deals with sliding sums, it's essential that each thread has enough work to do, otherwise the algorithm gets higher theoretical complexity and thus there is no speedup comparing to 1-thread code (at best). --- modules/photo/src/denoising.cpp | 44 ++++++++++++++++++--------- modules/photo/test/test_denoising.cpp | 11 +++++++ 2 files changed, 41 insertions(+), 14 deletions(-) diff --git a/modules/photo/src/denoising.cpp b/modules/photo/src/denoising.cpp index c68d09b925..93d4b4ebbe 100644 --- a/modules/photo/src/denoising.cpp +++ b/modules/photo/src/denoising.cpp @@ -50,42 +50,50 @@ static void fastNlMeansDenoising_( const Mat& src, Mat& dst, const std::vector( - src, dst, templateWindowSize, searchWindowSize, &h[0])); + src, dst, templateWindowSize, searchWindowSize, &h[0]), + granularity); break; case 2: if (hn == 1) parallel_for_(cv::Range(0, src.rows), FastNlMeansDenoisingInvoker, IT, UIT, D, int>( - src, dst, templateWindowSize, searchWindowSize, &h[0])); + src, dst, templateWindowSize, searchWindowSize, &h[0]), + granularity); else parallel_for_(cv::Range(0, src.rows), FastNlMeansDenoisingInvoker, IT, UIT, D, Vec2i>( - src, dst, templateWindowSize, searchWindowSize, &h[0])); + src, dst, templateWindowSize, searchWindowSize, &h[0]), + granularity); break; case 3: if (hn == 1) parallel_for_(cv::Range(0, src.rows), FastNlMeansDenoisingInvoker, IT, UIT, D, int>( - src, dst, templateWindowSize, searchWindowSize, &h[0])); + src, dst, templateWindowSize, searchWindowSize, &h[0]), + granularity); else parallel_for_(cv::Range(0, src.rows), FastNlMeansDenoisingInvoker, IT, UIT, D, Vec3i>( - src, dst, templateWindowSize, searchWindowSize, &h[0])); + src, dst, templateWindowSize, searchWindowSize, &h[0]), + granularity); break; case 4: if (hn == 1) parallel_for_(cv::Range(0, src.rows), FastNlMeansDenoisingInvoker, IT, UIT, D, int>( - src, dst, templateWindowSize, searchWindowSize, &h[0])); + src, dst, templateWindowSize, searchWindowSize, &h[0]), + granularity); else parallel_for_(cv::Range(0, src.rows), FastNlMeansDenoisingInvoker, IT, UIT, D, Vec4i>( - src, dst, templateWindowSize, searchWindowSize, &h[0])); + src, dst, templateWindowSize, searchWindowSize, &h[0]), + granularity); break; default: CV_Error(Error::StsBadArg, @@ -237,6 +245,7 @@ static void fastNlMeansDenoisingMulti_( const std::vector& srcImgs, Mat& ds int templateWindowSize, int searchWindowSize) { int hn = (int)h.size(); + double granularity = (double)std::max(1., (double)dst.total()/(1 << 16)); switch (srcImgs[0].type()) { @@ -244,43 +253,50 @@ static void fastNlMeansDenoisingMulti_( const std::vector& srcImgs, Mat& ds parallel_for_(cv::Range(0, srcImgs[0].rows), FastNlMeansMultiDenoisingInvoker( srcImgs, imgToDenoiseIndex, temporalWindowSize, - dst, templateWindowSize, searchWindowSize, &h[0])); + dst, templateWindowSize, searchWindowSize, &h[0]), + granularity); break; case CV_8UC2: if (hn == 1) parallel_for_(cv::Range(0, srcImgs[0].rows), FastNlMeansMultiDenoisingInvoker, IT, UIT, D, int>( srcImgs, imgToDenoiseIndex, temporalWindowSize, - dst, templateWindowSize, searchWindowSize, &h[0])); + dst, templateWindowSize, searchWindowSize, &h[0]), + granularity); else parallel_for_(cv::Range(0, srcImgs[0].rows), FastNlMeansMultiDenoisingInvoker, IT, UIT, D, Vec2i>( srcImgs, imgToDenoiseIndex, temporalWindowSize, - dst, templateWindowSize, searchWindowSize, &h[0])); + dst, templateWindowSize, searchWindowSize, &h[0]), + granularity); break; case CV_8UC3: if (hn == 1) parallel_for_(cv::Range(0, srcImgs[0].rows), FastNlMeansMultiDenoisingInvoker, IT, UIT, D, int>( srcImgs, imgToDenoiseIndex, temporalWindowSize, - dst, templateWindowSize, searchWindowSize, &h[0])); + dst, templateWindowSize, searchWindowSize, &h[0]), + granularity); else parallel_for_(cv::Range(0, srcImgs[0].rows), FastNlMeansMultiDenoisingInvoker, IT, UIT, D, Vec3i>( srcImgs, imgToDenoiseIndex, temporalWindowSize, - dst, templateWindowSize, searchWindowSize, &h[0])); + dst, templateWindowSize, searchWindowSize, &h[0]), + granularity); break; case CV_8UC4: if (hn == 1) parallel_for_(cv::Range(0, srcImgs[0].rows), FastNlMeansMultiDenoisingInvoker, IT, UIT, D, int>( srcImgs, imgToDenoiseIndex, temporalWindowSize, - dst, templateWindowSize, searchWindowSize, &h[0])); + dst, templateWindowSize, searchWindowSize, &h[0]), + granularity); else parallel_for_(cv::Range(0, srcImgs[0].rows), FastNlMeansMultiDenoisingInvoker, IT, UIT, D, Vec4i>( srcImgs, imgToDenoiseIndex, temporalWindowSize, - dst, templateWindowSize, searchWindowSize, &h[0])); + dst, templateWindowSize, searchWindowSize, &h[0]), + granularity); break; default: CV_Error(Error::StsBadArg, diff --git a/modules/photo/test/test_denoising.cpp b/modules/photo/test/test_denoising.cpp index 9808e9cddc..c3a69a2f76 100644 --- a/modules/photo/test/test_denoising.cpp +++ b/modules/photo/test/test_denoising.cpp @@ -156,3 +156,14 @@ TEST(Photo_White, issue_2646) ASSERT_EQ(0, nonWhitePixelsCount); } + +TEST(Photo_Denoising, speed) +{ + string imgname = string(cvtest::TS::ptr()->get_data_path()) + "shared/5MP.png"; + Mat src = imread(imgname, 0), dst; + + double t = (double)getTickCount(); + fastNlMeansDenoising(src, dst, 5, 7, 21); + t = (double)getTickCount() - t; + printf("execution time: %gms\n", t*1000./getTickFrequency()); +} From 05d888316a1f8ae93a15ba804a942b2d6d2f6bfd Mon Sep 17 00:00:00 2001 From: Vadim Pisarevsky Date: Thu, 14 May 2015 16:25:18 +0300 Subject: [PATCH 18/31] added test for http://code.opencv.org/issues/2957 --- modules/imgproc/test/test_contours.cpp | 61 ++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/modules/imgproc/test/test_contours.cpp b/modules/imgproc/test/test_contours.cpp index b0b8c4fbb5..b94408d3b8 100644 --- a/modules/imgproc/test/test_contours.cpp +++ b/modules/imgproc/test/test_contours.cpp @@ -40,6 +40,7 @@ //M*/ #include "test_precomp.hpp" +#include "opencv2/highgui.hpp" using namespace cv; using namespace std; @@ -429,4 +430,64 @@ TEST(Core_Drawing, polylines) int cnt = countNonZero(img); ASSERT_EQ(cnt, 21); } + +//rotate/flip a quadrant appropriately +static void rot(int n, int *x, int *y, int rx, int ry) +{ + if (ry == 0) { + if (rx == 1) { + *x = n-1 - *x; + *y = n-1 - *y; + } + + //Swap x and y + int t = *x; + *x = *y; + *y = t; + } +} + +static void d2xy(int n, int d, int *x, int *y) +{ + int rx, ry, s, t=d; + *x = *y = 0; + for (s=1; s > contours; + findContours(img, contours, noArray(), RETR_LIST, CHAIN_APPROX_SIMPLE); + printf("ncontours = %d, contour[0].npoints=%d\n", (int)contours.size(), (int)contours[0].size()); + img.setTo(Scalar::all(0)); + + drawContours(img, contours, 0, Scalar::all(255), 1); + //imshow("hilbert", img); + //waitKey(); + ASSERT_EQ(1, (int)contours.size()); + ASSERT_EQ(9832, (int)contours[0].size()); +} + /* End of file. */ From ca90667723648f9f27cc3badfcd12d49b44cc12c Mon Sep 17 00:00:00 2001 From: Vadim Pisarevsky Date: Thu, 14 May 2015 16:42:51 +0300 Subject: [PATCH 19/31] fixed compile warnings on Linux and Windows --- modules/imgproc/src/imgwarp.cpp | 2 +- modules/imgproc/test/test_imgwarp.cpp | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/modules/imgproc/src/imgwarp.cpp b/modules/imgproc/src/imgwarp.cpp index 792ba1d959..760f3fb0a2 100644 --- a/modules/imgproc/src/imgwarp.cpp +++ b/modules/imgproc/src/imgwarp.cpp @@ -3960,7 +3960,7 @@ static void remapBilinear( const Mat& _src, Mat& _dst, const Mat& _xy, else for( ; dx < X1; dx++, D += cn ) { - int sx = XY[dx*2], sy = XY[dx*2+1], k; + int sx = XY[dx*2], sy = XY[dx*2+1]; if( borderType == BORDER_CONSTANT && (sx >= ssize.width || sx+1 < 0 || sy >= ssize.height || sy+1 < 0) ) diff --git a/modules/imgproc/test/test_imgwarp.cpp b/modules/imgproc/test/test_imgwarp.cpp index d15f72e409..bf3f6b3c4c 100644 --- a/modules/imgproc/test/test_imgwarp.cpp +++ b/modules/imgproc/test/test_imgwarp.cpp @@ -1657,14 +1657,14 @@ TEST(Imgproc_Warp, multichannel) TEST(Imgproc_GetAffineTransform, singularity) { Point2f A_sample[3]; - A_sample[0] = cv::Point2f(8, 9); - A_sample[1] = cv::Point2f(40, 41); - A_sample[2] = cv::Point2f(47, 48); + A_sample[0] = Point2f(8.f, 9.f); + A_sample[1] = Point2f(40.f, 41.f); + A_sample[2] = Point2f(47.f, 48.f); Point2f B_sample[3]; - B_sample[0] = cv::Point2f(7.37465, 11.8295); - B_sample[1] = cv::Point2f(15.0113, 12.8994); - B_sample[2] = cv::Point2f(38.9943, 9.56297); - Mat trans = cv::getAffineTransform(A_sample, B_sample); + B_sample[0] = Point2f(7.37465f, 11.8295f); + B_sample[1] = Point2f(15.0113f, 12.8994f); + B_sample[2] = Point2f(38.9943f, 9.56297f); + Mat trans = getAffineTransform(A_sample, B_sample); ASSERT_EQ(0.0, norm(trans, NORM_INF)); } From ffabbfa77868089853617948ed41c7a57c0dd359 Mon Sep 17 00:00:00 2001 From: Vadim Pisarevsky Date: Thu, 14 May 2015 18:21:26 +0300 Subject: [PATCH 20/31] added test to prove that remap does not leak memory (http://code.opencv.org/issues/2502). disabled the test for now to save execution time. --- modules/imgproc/test/test_imgwarp.cpp | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/modules/imgproc/test/test_imgwarp.cpp b/modules/imgproc/test/test_imgwarp.cpp index bf3f6b3c4c..4ffd50b41a 100644 --- a/modules/imgproc/test/test_imgwarp.cpp +++ b/modules/imgproc/test/test_imgwarp.cpp @@ -1668,4 +1668,28 @@ TEST(Imgproc_GetAffineTransform, singularity) ASSERT_EQ(0.0, norm(trans, NORM_INF)); } +TEST(Imgproc_Remap, DISABLED_memleak) +{ + Mat src; + const int N = 400; + src.create(N, N, CV_8U); + randu(src, 0, 256); + Mat map_x, map_y, dst; + dst.create( src.size(), src.type() ); + map_x.create( src.size(), CV_32FC1 ); + map_y.create( src.size(), CV_32FC1 ); + randu(map_x, 0., N+0.); + randu(map_y, 0., N+0.); + + for( int iter = 0; iter < 10000; iter++ ) + { + if(iter % 100 == 0) + { + putchar('.'); + fflush(stdout); + } + remap(src, dst, map_x, map_y, CV_INTER_LINEAR); + } +} + /* End of file. */ From 3c7f7de477eb20debed0cb43dc0e7f10a3218ef0 Mon Sep 17 00:00:00 2001 From: Vadim Pisarevsky Date: Thu, 14 May 2015 19:32:25 +0300 Subject: [PATCH 21/31] avoid possible problems with zero values in tone mapping algorithms (http://code.opencv.org/issues/4020) --- modules/photo/src/tonemap.cpp | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/modules/photo/src/tonemap.cpp b/modules/photo/src/tonemap.cpp index af930abb35..e475482d66 100644 --- a/modules/photo/src/tonemap.cpp +++ b/modules/photo/src/tonemap.cpp @@ -47,6 +47,12 @@ namespace cv { +inline void log_(const Mat& src, Mat& dst) +{ + max(src, Scalar::all(1e-4), dst); + log(dst, dst); +} + class TonemapImpl : public Tonemap { public: @@ -122,7 +128,7 @@ public: Mat gray_img; cvtColor(img, gray_img, COLOR_RGB2GRAY); Mat log_img; - log(gray_img, log_img); + log_(gray_img, log_img); float mean = expf(static_cast(sum(log_img)[0]) / log_img.total()); gray_img /= mean; log_img.release(); @@ -205,7 +211,7 @@ public: Mat gray_img; cvtColor(img, gray_img, COLOR_RGB2GRAY); Mat log_img; - log(gray_img, log_img); + log_(gray_img, log_img); Mat map_img; bilateralFilter(log_img, map_img, -1, sigma_color, sigma_space); @@ -289,7 +295,7 @@ public: Mat gray_img; cvtColor(img, gray_img, COLOR_RGB2GRAY); Mat log_img; - log(gray_img, log_img); + log_(gray_img, log_img); float log_mean = static_cast(sum(log_img)[0] / log_img.total()); double log_min, log_max; @@ -383,7 +389,7 @@ public: Mat gray_img; cvtColor(img, gray_img, COLOR_RGB2GRAY); Mat log_img; - log(gray_img, log_img); + log_(gray_img, log_img); std::vector x_contrast, y_contrast; getContrast(log_img, x_contrast, y_contrast); From 3c769edea0c51f7a74693f1ac747dfe9bcb7670e Mon Sep 17 00:00:00 2001 From: Vadim Pisarevsky Date: Thu, 14 May 2015 19:54:48 +0300 Subject: [PATCH 22/31] added extra check in CalibrateDebevec to make sure the points are within the image: http://code.opencv.org/issues/4124 --- modules/photo/src/calibrate.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/modules/photo/src/calibrate.cpp b/modules/photo/src/calibrate.cpp index eda3e1265b..63f1818e47 100644 --- a/modules/photo/src/calibrate.cpp +++ b/modules/photo/src/calibrate.cpp @@ -90,7 +90,9 @@ public: for(int i = 0, x = step_x / 2; i < x_points; i++, x += step_x) { for(int j = 0, y = step_y / 2; j < y_points; j++, y += step_y) { - sample_points.push_back(Point(x, y)); + if( 0 <= x && x < images[0].cols && + 0 <= y && y < images[0].rows ) + sample_points.push_back(Point(x, y)); } } } From 7dd67f4997ad871029dd73653945df0cfd6ebcee Mon Sep 17 00:00:00 2001 From: Vadim Pisarevsky Date: Thu, 14 May 2015 20:33:53 +0300 Subject: [PATCH 23/31] use _mm_sad_epu8 instead of _mm_movemask_epi8 in countNonZero. Therefore, we do not need any popcount table and this solves http://code.opencv.org/issues/4333 --- modules/core/src/stat.cpp | 105 ++++++++------------------------------ 1 file changed, 20 insertions(+), 85 deletions(-) diff --git a/modules/core/src/stat.cpp b/modules/core/src/stat.cpp index 8a6bd54721..81f9a2484e 100644 --- a/modules/core/src/stat.cpp +++ b/modules/core/src/stat.cpp @@ -504,54 +504,21 @@ static int countNonZero_(const T* src, int len ) return nz; } -#if CV_SSE2 - -static const uchar * initPopcountTable() -{ - static uchar tab[256]; - static volatile bool initialized = false; - if( !initialized ) - { - // we compute inverse popcount table, - // since we pass (img[x] == 0) mask as index in the table. - unsigned int j = 0u; -#if CV_POPCNT - if (checkHardwareSupport(CV_CPU_POPCNT)) - { - for( ; j < 256u; j++ ) - tab[j] = (uchar)(8 - _mm_popcnt_u32(j)); - } -#endif - for( ; j < 256u; j++ ) - { - int val = 0; - for( int mask = 1; mask < 256; mask += mask ) - val += (j & mask) == 0; - tab[j] = (uchar)val; - } - initialized = true; - } - - return tab; -} - -#endif - static int countNonZero8u( const uchar* src, int len ) { int i=0, nz = 0; #if CV_SSE2 if(USE_SSE2)//5x-6x { - __m128i pattern = _mm_setzero_si128 (); - static const uchar * tab = initPopcountTable(); + __m128i v_zero = _mm_setzero_si128(); + __m128i sum = _mm_setzero_si128(); for (; i<=len-16; i+=16) { __m128i r0 = _mm_loadu_si128((const __m128i*)(src+i)); - int val = _mm_movemask_epi8(_mm_cmpeq_epi8(r0, pattern)); - nz += tab[val & 255] + tab[val >> 8]; + sum = _mm_add_epi32(sum, _mm_sad_epu8(_mm_sub_epi8(v_zero, _mm_cmpeq_epi8(r0, v_zero)), v_zero)); } + nz = i - _mm_cvtsi128_si32(_mm_add_epi32(sum, _mm_unpackhi_epi64(sum, sum))); } #elif CV_NEON int len0 = len & -16, blockSize1 = (1 << 8) - 16, blockSize0 = blockSize1 << 6; @@ -598,15 +565,15 @@ static int countNonZero16u( const ushort* src, int len ) if (USE_SSE2) { __m128i v_zero = _mm_setzero_si128 (); - static const uchar * tab = initPopcountTable(); + __m128i sum = _mm_setzero_si128(); for ( ; i <= len - 8; i += 8) { - __m128i v_src = _mm_loadu_si128((const __m128i*)(src + i)); - int val = _mm_movemask_epi8(_mm_packs_epi16(_mm_cmpeq_epi16(v_src, v_zero), v_zero)); - nz += tab[val]; + __m128i r0 = _mm_loadu_si128((const __m128i*)(src + i)); + sum = _mm_add_epi32(sum, _mm_sad_epu8(_mm_sub_epi8(v_zero, _mm_cmpeq_epi16(r0, v_zero)), v_zero)); } + nz = i - (_mm_cvtsi128_si32(_mm_add_epi32(sum, _mm_unpackhi_epi64(sum, sum))) >> 1); src += i; } #elif CV_NEON @@ -649,20 +616,15 @@ static int countNonZero32s( const int* src, int len ) if (USE_SSE2) { __m128i v_zero = _mm_setzero_si128 (); - static const uchar * tab = initPopcountTable(); + __m128i sum = _mm_setzero_si128(); - for ( ; i <= len - 8; i += 8) + for ( ; i <= len - 4; i += 4) { - __m128i v_src = _mm_loadu_si128((const __m128i*)(src + i)); - __m128i v_dst0 = _mm_cmpeq_epi32(v_src, v_zero); - - v_src = _mm_loadu_si128((const __m128i*)(src + i + 4)); - __m128i v_dst1 = _mm_cmpeq_epi32(v_src, v_zero); - - int val = _mm_movemask_epi8(_mm_packs_epi16(_mm_packs_epi32(v_dst0, v_dst1), v_zero)); - nz += tab[val]; + __m128i r0 = _mm_loadu_si128((const __m128i*)(src + i)); + sum = _mm_add_epi32(sum, _mm_sad_epu8(_mm_sub_epi8(v_zero, _mm_cmpeq_epi32(r0, v_zero)), v_zero)); } + nz = i - (_mm_cvtsi128_si32(_mm_add_epi32(sum, _mm_unpackhi_epi64(sum, sum))) >> 2); src += i; } #elif CV_NEON @@ -706,19 +668,17 @@ static int countNonZero32f( const float* src, int len ) #if CV_SSE2 if (USE_SSE2) { - __m128i v_zero_i = _mm_setzero_si128(); __m128 v_zero_f = _mm_setzero_ps(); - static const uchar * tab = initPopcountTable(); + __m128i v_zero = _mm_setzero_si128 (); + __m128i sum = _mm_setzero_si128(); - for ( ; i <= len - 8; i += 8) + for ( ; i <= len - 4; i += 4) { - __m128i v_dst0 = _mm_castps_si128(_mm_cmpeq_ps(_mm_loadu_ps(src + i), v_zero_f)); - __m128i v_dst1 = _mm_castps_si128(_mm_cmpeq_ps(_mm_loadu_ps(src + i + 4), v_zero_f)); - - int val = _mm_movemask_epi8(_mm_packs_epi16(_mm_packs_epi32(v_dst0, v_dst1), v_zero_i)); - nz += tab[val]; + __m128 r0 = _mm_loadu_ps(src + i); + sum = _mm_add_epi32(sum, _mm_sad_epu8(_mm_sub_epi8(v_zero, _mm_castps_si128(_mm_cmpeq_ps(r0, v_zero_f))), v_zero)); } + nz = i - (_mm_cvtsi128_si32(_mm_add_epi32(sum, _mm_unpackhi_epi64(sum, sum))) >> 2); src += i; } #elif CV_NEON @@ -758,32 +718,7 @@ static int countNonZero32f( const float* src, int len ) static int countNonZero64f( const double* src, int len ) { - int i = 0, nz = 0; -#if CV_SSE2 - if (USE_SSE2) - { - __m128i v_zero_i = _mm_setzero_si128(); - __m128d v_zero_d = _mm_setzero_pd(); - static const uchar * tab = initPopcountTable(); - - for ( ; i <= len - 8; i += 8) - { - __m128i v_dst0 = _mm_castpd_si128(_mm_cmpeq_pd(_mm_loadu_pd(src + i), v_zero_d)); - __m128i v_dst1 = _mm_castpd_si128(_mm_cmpeq_pd(_mm_loadu_pd(src + i + 2), v_zero_d)); - __m128i v_dst2 = _mm_castpd_si128(_mm_cmpeq_pd(_mm_loadu_pd(src + i + 4), v_zero_d)); - __m128i v_dst3 = _mm_castpd_si128(_mm_cmpeq_pd(_mm_loadu_pd(src + i + 6), v_zero_d)); - - v_dst0 = _mm_packs_epi32(v_dst0, v_dst1); - v_dst1 = _mm_packs_epi32(v_dst2, v_dst3); - - int val = _mm_movemask_epi8(_mm_packs_epi16(_mm_packs_epi32(v_dst0, v_dst1), v_zero_i)); - nz += tab[val]; - } - - src += i; - } -#endif - return nz + countNonZero_(src, len - i); + return countNonZero_(src, len); } typedef int (*CountNonZeroFunc)(const uchar*, int); From 66eb270cf72d555e7078b1d279f2c4c1d7f0111c Mon Sep 17 00:00:00 2001 From: Vadim Pisarevsky Date: Thu, 14 May 2015 23:29:09 +0300 Subject: [PATCH 24/31] significantly reduced sparse matrix footprint: http://code.opencv.org/issues/2206, http://code.opencv.org/issues/2924 --- modules/core/src/matrix.cpp | 7 ++++--- modules/core/test/test_mat.cpp | 24 ++++++++++++++++++++++++ 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/modules/core/src/matrix.cpp b/modules/core/src/matrix.cpp index 9b77a4cf2c..42b271f1eb 100644 --- a/modules/core/src/matrix.cpp +++ b/modules/core/src/matrix.cpp @@ -4714,8 +4714,8 @@ SparseMat::Hdr::Hdr( int _dims, const int* _sizes, int _type ) refcount = 1; dims = _dims; - valueOffset = (int)alignSize(sizeof(SparseMat::Node) + - sizeof(int)*std::max(dims - CV_MAX_DIM, 0), CV_ELEM_SIZE1(_type)); + valueOffset = (int)alignSize(sizeof(SparseMat::Node) - MAX_DIM*sizeof(int) + + dims*sizeof(int), CV_ELEM_SIZE1(_type)); nodeSize = alignSize(valueOffset + CV_ELEM_SIZE(_type), (int)sizeof(size_t)); @@ -5114,7 +5114,8 @@ uchar* SparseMat::newNode(const int* idx, size_t hashval) if( !hdr->freeList ) { size_t i, nsz = hdr->nodeSize, psize = hdr->pool.size(), - newpsize = std::max(psize*2, 8*nsz); + newpsize = std::max(psize*3/2, 8*nsz); + newpsize = (newpsize/nsz)*nsz; hdr->pool.resize(newpsize); uchar* pool = &hdr->pool[0]; hdr->freeList = std::max(psize, nsz); diff --git a/modules/core/test/test_mat.cpp b/modules/core/test/test_mat.cpp index 102bd99764..897ac40a43 100644 --- a/modules/core/test/test_mat.cpp +++ b/modules/core/test/test_mat.cpp @@ -1248,3 +1248,27 @@ TEST(Core_SVD, orthogonality) ASSERT_LT(norm(mat_U, Mat::eye(2, 2, type), NORM_INF), 1e-5); } } + + +TEST(Core_SparseMat, footprint) +{ + int n = 1000000; + int sz[] = { n, n }; + SparseMat m(2, sz, CV_64F); + + int nodeSize0 = (int)m.hdr->nodeSize; + double dataSize0 = ((double)m.hdr->pool.size() + (double)m.hdr->hashtab.size()*sizeof(size_t))*1e-6; + printf("before: node size=%d bytes, data size=%.0f Mbytes\n", nodeSize0, dataSize0); + + for (int i = 0; i < n; i++) + { + m.ref(i, i) = 1; + } + + double dataSize1 = ((double)m.hdr->pool.size() + (double)m.hdr->hashtab.size()*sizeof(size_t))*1e-6; + double threshold = (n*nodeSize0*1.6 + n*2.*sizeof(size_t))*1e-6; + printf("after: data size=%.0f Mbytes, threshold=%.0f MBytes\n", dataSize1, threshold); + + ASSERT_LE((int)m.hdr->nodeSize, 32); + ASSERT_LE(dataSize1, threshold); +} From 4a9b24457779352581c7878ed2734b31f103e00a Mon Sep 17 00:00:00 2001 From: Vadim Pisarevsky Date: Fri, 15 May 2015 16:15:10 +0300 Subject: [PATCH 25/31] hopefully, fixed crash in sparse mat test --- modules/core/src/matrix.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/modules/core/src/matrix.cpp b/modules/core/src/matrix.cpp index 42b271f1eb..b273c8a7d8 100644 --- a/modules/core/src/matrix.cpp +++ b/modules/core/src/matrix.cpp @@ -4816,7 +4816,8 @@ void SparseMat::copyTo( SparseMat& m ) const void SparseMat::copyTo( Mat& m ) const { CV_Assert( hdr ); - m.create( dims(), hdr->size, type() ); + int ndims = dims(); + m.create( ndims, hdr->size, type() ); m = Scalar(0); SparseMatConstIterator from = begin(); @@ -4825,7 +4826,7 @@ void SparseMat::copyTo( Mat& m ) const for( i = 0; i < N; i++, ++from ) { const Node* n = from.node(); - copyElem( from.ptr, m.ptr(n->idx), esz); + copyElem( from.ptr, (ndims > 1 ? m.ptr(n->idx) : m.ptr(n->idx[0])), esz); } } From d40eefd5a477ea46e238b06db5627e5d21156f35 Mon Sep 17 00:00:00 2001 From: Maxim Kostin Date: Fri, 15 May 2015 16:28:25 +0300 Subject: [PATCH 26/31] Moved old WinRT related wrappers from highgui to videoio fixing long broken logic. Signed-off-by: Maxim Kostin --- modules/videoio/src/agile_wrl.hpp | 568 ++ modules/videoio/src/ppltasks_winrt.hpp | 9466 ++++++++++++++++++++++++ 2 files changed, 10034 insertions(+) create mode 100644 modules/videoio/src/agile_wrl.hpp create mode 100644 modules/videoio/src/ppltasks_winrt.hpp diff --git a/modules/videoio/src/agile_wrl.hpp b/modules/videoio/src/agile_wrl.hpp new file mode 100644 index 0000000000..99fbf41856 --- /dev/null +++ b/modules/videoio/src/agile_wrl.hpp @@ -0,0 +1,568 @@ +// +// Copyright (C) Microsoft Corporation +// All rights reserved. +// Modified for native C++ WRL support by Gregory Morse +// +// Code in Details namespace is for internal usage within the library code +// + +#ifndef _PLATFORM_AGILE_H_ +#define _PLATFORM_AGILE_H_ + +#ifdef _MSC_VER +#pragma once +#endif // _MSC_VER + +#include +#include + +template class Agile; + +template +struct UnwrapAgile +{ + static const bool _IsAgile = false; +}; +template +struct UnwrapAgile> +{ + static const bool _IsAgile = true; +}; +template +struct UnwrapAgile> +{ + static const bool _IsAgile = true; +}; + +#define IS_AGILE(T) UnwrapAgile::_IsAgile + +#define __is_winrt_agile(T) (std::is_same::value || std::is_base_of::value || std::is_base_of::value) //derived from Microsoft::WRL::FtmBase or IAgileObject + +#define __is_win_interface(T) (std::is_base_of::value || std::is_base_of::value) //derived from IUnknown or IInspectable + +#define __is_win_class(T) (std::is_same::value || std::is_base_of::value) //derived from Microsoft::WRL::RuntimeClass or HSTRING + + namespace Details + { + IUnknown* __stdcall GetObjectContext(); + HRESULT __stdcall GetProxyImpl(IUnknown*, REFIID, IUnknown*, IUnknown**); + HRESULT __stdcall ReleaseInContextImpl(IUnknown*, IUnknown*); + + template +#if _MSC_VER >= 1800 + __declspec(no_refcount) inline HRESULT GetProxy(T *ObjectIn, IUnknown *ContextCallBack, T **Proxy) +#else + inline HRESULT GetProxy(T *ObjectIn, IUnknown *ContextCallBack, T **Proxy) +#endif + { +#if _MSC_VER >= 1800 + return GetProxyImpl(*reinterpret_cast(&ObjectIn), __uuidof(T*), ContextCallBack, reinterpret_cast(Proxy)); +#else + return GetProxyImpl(*reinterpret_cast(&const_cast(ObjectIn)), __uuidof(T*), ContextCallBack, reinterpret_cast(Proxy)); +#endif + } + + template + inline HRESULT ReleaseInContext(T *ObjectIn, IUnknown *ContextCallBack) + { + return ReleaseInContextImpl(ObjectIn, ContextCallBack); + } + + template + class AgileHelper + { + __abi_IUnknown* _p; + bool _release; + public: + AgileHelper(__abi_IUnknown* p, bool release = true) : _p(p), _release(release) + { + } + AgileHelper(AgileHelper&& other) : _p(other._p), _release(other._release) + { + _other._p = nullptr; + _other._release = true; + } + AgileHelper operator=(AgileHelper&& other) + { + _p = other._p; + _release = other._release; + _other._p = nullptr; + _other._release = true; + return *this; + } + + ~AgileHelper() + { + if (_release && _p) + { + _p->__abi_Release(); + } + } + + __declspec(no_refcount) __declspec(no_release_return) + T* operator->() + { + return reinterpret_cast(_p); + } + + __declspec(no_refcount) __declspec(no_release_return) + operator T * () + { + return reinterpret_cast(_p); + } + private: + AgileHelper(const AgileHelper&); + AgileHelper operator=(const AgileHelper&); + }; + template + struct __remove_hat + { + typedef T type; + }; + template + struct __remove_hat + { + typedef T type; + }; + template + struct AgileTypeHelper + { + typename typedef __remove_hat::type type; + typename typedef __remove_hat::type* agileMemberType; + }; + } // namespace Details + +#pragma warning(push) +#pragma warning(disable: 4451) // Usage of ref class inside this context can lead to invalid marshaling of object across contexts + + template < + typename T, + bool TIsNotAgile = (__is_win_class(typename Details::AgileTypeHelper::type) && !__is_winrt_agile(typename Details::AgileTypeHelper::type)) || + __is_win_interface(typename Details::AgileTypeHelper::type) + > + class Agile + { + static_assert(__is_win_class(typename Details::AgileTypeHelper::type) || __is_win_interface(typename Details::AgileTypeHelper::type), "Agile can only be used with ref class or interface class types"); + typename typedef Details::AgileTypeHelper::agileMemberType TypeT; + TypeT _object; + ::Microsoft::WRL::ComPtr _contextCallback; + ULONG_PTR _contextToken; + +#if _MSC_VER >= 1800 + enum class AgileState + { + NonAgilePointer = 0, + AgilePointer = 1, + Unknown = 2 + }; + AgileState _agileState; +#endif + + void CaptureContext() + { + _contextCallback = Details::GetObjectContext(); + __abi_ThrowIfFailed(CoGetContextToken(&_contextToken)); + } + + void SetObject(TypeT object) + { + // Capture context before setting the pointer + // If context capture fails then nothing to cleanup + Release(); + if (object != nullptr) + { + ::Microsoft::WRL::ComPtr checkIfAgile; + HRESULT hr = reinterpret_cast(object)->QueryInterface(__uuidof(IAgileObject), &checkIfAgile); + // Don't Capture context if object is agile + if (hr != S_OK) + { +#if _MSC_VER >= 1800 + _agileState = AgileState::NonAgilePointer; +#endif + CaptureContext(); + } +#if _MSC_VER >= 1800 + else + { + _agileState = AgileState::AgilePointer; + } +#endif + } + _object = object; + } + + public: + Agile() throw() : _object(nullptr), _contextToken(0) +#if _MSC_VER >= 1800 + , _agileState(AgileState::Unknown) +#endif + { + } + + Agile(nullptr_t) throw() : _object(nullptr), _contextToken(0) +#if _MSC_VER >= 1800 + , _agileState(AgileState::Unknown) +#endif + { + } + + explicit Agile(TypeT object) throw() : _object(nullptr), _contextToken(0) +#if _MSC_VER >= 1800 + , _agileState(AgileState::Unknown) +#endif + { + // Assumes that the source object is from the current context + SetObject(object); + } + + Agile(const Agile& object) throw() : _object(nullptr), _contextToken(0) +#if _MSC_VER >= 1800 + , _agileState(AgileState::Unknown) +#endif + { + // Get returns pointer valid for current context + SetObject(object.Get()); + } + + Agile(Agile&& object) throw() : _object(nullptr), _contextToken(0) +#if _MSC_VER >= 1800 + , _agileState(AgileState::Unknown) +#endif + { + // Assumes that the source object is from the current context + Swap(object); + } + + ~Agile() throw() + { + Release(); + } + + TypeT Get() const + { + // Agile object, no proxy required +#if _MSC_VER >= 1800 + if (_agileState == AgileState::AgilePointer || _object == nullptr) +#else + if (_contextToken == 0 || _contextCallback == nullptr || _object == nullptr) +#endif + { + return _object; + } + + // Do the check for same context + ULONG_PTR currentContextToken; + __abi_ThrowIfFailed(CoGetContextToken(¤tContextToken)); + if (currentContextToken == _contextToken) + { + return _object; + } + +#if _MSC_VER >= 1800 + // Different context and holding on to a non agile object + // Do the costly work of getting a proxy + TypeT localObject; + __abi_ThrowIfFailed(Details::GetProxy(_object, _contextCallback.Get(), &localObject)); + + if (_agileState == AgileState::Unknown) +#else + // Object is agile if it implements IAgileObject + // GetAddressOf captures the context with out knowing the type of object that it will hold + if (_object != nullptr) +#endif + { +#if _MSC_VER >= 1800 + // Object is agile if it implements IAgileObject + // GetAddressOf captures the context with out knowing the type of object that it will hold + ::Microsoft::WRL::ComPtr checkIfAgile; + HRESULT hr = reinterpret_cast(localObject)->QueryInterface(__uuidof(IAgileObject), &checkIfAgile); +#else + ::Microsoft::WRL::ComPtr checkIfAgile; + HRESULT hr = reinterpret_cast(_object)->QueryInterface(__uuidof(IAgileObject), &checkIfAgile); +#endif + if (hr == S_OK) + { + auto pThis = const_cast(this); +#if _MSC_VER >= 1800 + pThis->_agileState = AgileState::AgilePointer; +#endif + pThis->_contextToken = 0; + pThis->_contextCallback = nullptr; + return _object; + } +#if _MSC_VER >= 1800 + else + { + auto pThis = const_cast(this); + pThis->_agileState = AgileState::NonAgilePointer; + } +#endif + } + +#if _MSC_VER < 1800 + // Different context and holding on to a non agile object + // Do the costly work of getting a proxy + TypeT localObject; + __abi_ThrowIfFailed(Details::GetProxy(_object, _contextCallback.Get(), &localObject)); +#endif + return localObject; + } + + TypeT* GetAddressOf() throw() + { + Release(); + CaptureContext(); + return &_object; + } + + TypeT* GetAddressOfForInOut() throw() + { + CaptureContext(); + return &_object; + } + + TypeT operator->() const throw() + { + return Get(); + } + + Agile& operator=(nullptr_t) throw() + { + Release(); + return *this; + } + + Agile& operator=(TypeT object) throw() + { + Agile(object).Swap(*this); + return *this; + } + + Agile& operator=(Agile object) throw() + { + // parameter is by copy which gets pointer valid for current context + object.Swap(*this); + return *this; + } + +#if _MSC_VER < 1800 + Agile& operator=(IUnknown* lp) throw() + { + // bump ref count + ::Microsoft::WRL::ComPtr spObject(lp); + + // put it into Platform Object + Platform::Object object; + *(IUnknown**)(&object) = spObject.Detach(); + + SetObject(object); + return *this; + } +#endif + + void Swap(Agile& object) + { + std::swap(_object, object._object); + std::swap(_contextCallback, object._contextCallback); + std::swap(_contextToken, object._contextToken); +#if _MSC_VER >= 1800 + std::swap(_agileState, object._agileState); +#endif + } + + // Release the interface and set to NULL + void Release() throw() + { + if (_object) + { + // Cast to IInspectable (no QI) + IUnknown* pObject = *(IUnknown**)(&_object); + // Set * to null without release + *(IUnknown**)(&_object) = nullptr; + + ULONG_PTR currentContextToken; + __abi_ThrowIfFailed(CoGetContextToken(¤tContextToken)); + if (_contextToken == 0 || _contextCallback == nullptr || _contextToken == currentContextToken) + { + pObject->Release(); + } + else + { + Details::ReleaseInContext(pObject, _contextCallback.Get()); + } + _contextCallback = nullptr; + _contextToken = 0; +#if _MSC_VER >= 1800 + _agileState = AgileState::Unknown; +#endif + } + } + + bool operator==(nullptr_t) const throw() + { + return _object == nullptr; + } + + bool operator==(const Agile& other) const throw() + { + return _object == other._object && _contextToken == other._contextToken; + } + + bool operator<(const Agile& other) const throw() + { + if (reinterpret_cast(_object) < reinterpret_cast(other._object)) + { + return true; + } + + return _object == other._object && _contextToken < other._contextToken; + } + }; + + template + class Agile + { + static_assert(__is_win_class(typename Details::AgileTypeHelper::type) || __is_win_interface(typename Details::AgileTypeHelper::type), "Agile can only be used with ref class or interface class types"); + typename typedef Details::AgileTypeHelper::agileMemberType TypeT; + TypeT _object; + + public: + Agile() throw() : _object(nullptr) + { + } + + Agile(nullptr_t) throw() : _object(nullptr) + { + } + + explicit Agile(TypeT object) throw() : _object(object) + { + } + + Agile(const Agile& object) throw() : _object(object._object) + { + } + + Agile(Agile&& object) throw() : _object(nullptr) + { + Swap(object); + } + + ~Agile() throw() + { + Release(); + } + + TypeT Get() const + { + return _object; + } + + TypeT* GetAddressOf() throw() + { + Release(); + return &_object; + } + + TypeT* GetAddressOfForInOut() throw() + { + return &_object; + } + + TypeT operator->() const throw() + { + return Get(); + } + + Agile& operator=(nullptr_t) throw() + { + Release(); + return *this; + } + + Agile& operator=(TypeT object) throw() + { + if (_object != object) + { + _object = object; + } + return *this; + } + + Agile& operator=(Agile object) throw() + { + object.Swap(*this); + return *this; + } + +#if _MSC_VER < 1800 + Agile& operator=(IUnknown* lp) throw() + { + Release(); + // bump ref count + ::Microsoft::WRL::ComPtr spObject(lp); + + // put it into Platform Object + Platform::Object object; + *(IUnknown**)(&object) = spObject.Detach(); + + _object = object; + return *this; + } +#endif + + // Release the interface and set to NULL + void Release() throw() + { + _object = nullptr; + } + + void Swap(Agile& object) + { + std::swap(_object, object._object); + } + + bool operator==(nullptr_t) const throw() + { + return _object == nullptr; + } + + bool operator==(const Agile& other) const throw() + { + return _object == other._object; + } + + bool operator<(const Agile& other) const throw() + { + return reinterpret_cast(_object) < reinterpret_cast(other._object); + } + }; + +#pragma warning(pop) + + template + bool operator==(nullptr_t, const Agile& a) throw() + { + return a == nullptr; + } + + template + bool operator!=(const Agile& a, nullptr_t) throw() + { + return !(a == nullptr); + } + + template + bool operator!=(nullptr_t, const Agile& a) throw() + { + return !(a == nullptr); + } + + template + bool operator!=(const Agile& a, const Agile& b) throw() + { + return !(a == b); + } + + +#endif // _PLATFORM_AGILE_H_ diff --git a/modules/videoio/src/ppltasks_winrt.hpp b/modules/videoio/src/ppltasks_winrt.hpp new file mode 100644 index 0000000000..3eddd24ea7 --- /dev/null +++ b/modules/videoio/src/ppltasks_winrt.hpp @@ -0,0 +1,9466 @@ +/*** +* ==++== +* +* Copyright (c) Microsoft Corporation. All rights reserved. +* +* Modified for native C++ WRL support by Gregory Morse +* +* ==--== +* =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ +* +* ppltasks_winrt.h +* +* Parallel Patterns Library - PPL Tasks +* +* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +****/ + +#pragma once + +#ifndef _PPLTASKS_WINRT_H +#define _PPLTASKS_WINRT_H + +#include +#include +#if _MSC_VER >= 1800 +#include + +// Cannot build using a compiler that is older than dev10 SP1 +#ifdef _MSC_VER +#if _MSC_FULL_VER < 160040219 /*IFSTRIP=IGN*/ +#error ERROR: Visual Studio 2010 SP1 or later is required to build ppltasks +#endif /*IFSTRIP=IGN*/ +#endif +#else +#include +#endif +#include +#include +#include +#include +#if _MSC_VER >= 1800 +#include +#endif + +#ifndef __cplusplus_winrt + +#include +#include +#if _MSC_VER >= 1800 +#include "agile_wrl.hpp" +#endif +#include +#include + +#ifndef _UITHREADCTXT_SUPPORT + +#ifdef WINAPI_FAMILY /*IFSTRIP=IGN*/ + +// It is safe to include winapifamily as WINAPI_FAMILY was defined by the user +#include + +#if WINAPI_FAMILY == WINAPI_FAMILY_APP /*IFSTRIP=IGN*/ + // UI thread context support is not required for desktop and Windows Store apps + #define _UITHREADCTXT_SUPPORT 0 +#elif WINAPI_FAMILY == WINAPI_FAMILY_DESKTOP_APP /*IFSTRIP=IGN*/ + // UI thread context support is not required for desktop and Windows Store apps + #define _UITHREADCTXT_SUPPORT 0 +#else /* WINAPI_FAMILY == WINAPI_FAMILY_DESKTOP_APP */ + #define _UITHREADCTXT_SUPPORT 1 +#endif /* WINAPI_FAMILY == WINAPI_FAMILY_DESKTOP_APP */ + +#else /* WINAPI_FAMILY */ + // Not supported without a WINAPI_FAMILY setting. + #define _UITHREADCTXT_SUPPORT 0 +#endif /* WINAPI_FAMILY */ + +#endif /* _UITHREADCTXT_SUPPORT */ + +#if _UITHREADCTXT_SUPPORT +#include +#endif /* _UITHREADCTXT_SUPPORT */ + +#pragma detect_mismatch("_PPLTASKS_WITH_WINRT", "0") + +#ifdef _DEBUG +#define _DBG_ONLY(X) X +#else +#define _DBG_ONLY(X) +#endif // #ifdef _DEBUG + +// std::copy_exception changed to std::make_exception_ptr from VS 2010 to VS 11. +#ifdef _MSC_VER +#if _MSC_VER < 1700 /*IFSTRIP=IGN*/ +namespace std +{ + template exception_ptr make_exception_ptr(_E _Except) + { + return copy_exception(_Except); + } +} +#endif +#ifndef _PPLTASK_ASYNC_LOGGING +#if _MSC_VER >= 1800 && defined(__cplusplus_winrt) +#define _PPLTASK_ASYNC_LOGGING 1 // Only enable async logging under dev12 winrt +#else +#define _PPLTASK_ASYNC_LOGGING 0 +#endif +#endif +#endif + +#pragma pack(push,_CRT_PACKING) + +#pragma warning(push) +#pragma warning(disable: 28197) +#pragma warning(disable: 4100) // Unreferenced formal parameter - needed for document generation +#if _MSC_VER >= 1800 +#pragma warning(disable: 4127) // constant express in if condition - we use it for meta programming +#else +#pragma warning(disable: 4702) // Unreachable code - it is caused by user lambda throw exceptions +#endif + +// All CRT public header files are required to be protected from the macro new +#pragma push_macro("new") +#undef new + +// stuff ported from Dev11 CRT +// NOTE: this doesn't actually match std::declval. it behaves differently for void! +// so don't blindly change it to std::declval. +namespace stdx +{ + template + _T&& declval(); +} + +/// +/// The Concurrency_winrt namespace provides classes and functions that give you access to the Concurrency Runtime, +/// a concurrent programming framework for C++. For more information, see . +/// +/**/ +namespace Concurrency_winrt +{ + // In debug builds, default to 10 frames, unless this is overridden prior to #includ'ing ppltasks.h. In retail builds, default to only one frame. +#ifndef PPL_TASK_SAVE_FRAME_COUNT +#ifdef _DEBUG +#define PPL_TASK_SAVE_FRAME_COUNT 10 +#else +#define PPL_TASK_SAVE_FRAME_COUNT 1 +#endif +#endif + + /// + /// Helper macro to determine how many stack frames need to be saved. When any number less or equal to 1 is specified, + /// only one frame is captured and no stackwalk will be involved. Otherwise, the number of callstack frames will be captured. + /// + /// + /// This needs to be defined as a macro rather than a function so that if we're only gathering one frame, _ReturnAddress() + /// will evaluate to client code, rather than a helper function inside of _TaskCreationCallstack, itself. + /// +#ifdef _CAPTURE_CALLSTACK +#undef _CAPTURE_CALLSTACK +#endif +#if PPL_TASK_SAVE_FRAME_COUNT > 1 +#if !defined(_DEBUG) +#pragma message ("WARNING: Redefinning PPL_TASK_SAVE_FRAME_COUNT under Release build for non-desktop applications is not supported; only one frame will be captured!") +#define _CAPTURE_CALLSTACK() ::Concurrency_winrt::details::_TaskCreationCallstack::_CaptureSingleFrameCallstack(_ReturnAddress()) +#else +#define _CAPTURE_CALLSTACK() ::Concurrency_winrt::details::_TaskCreationCallstack::_CaptureMultiFramesCallstack(PPL_TASK_SAVE_FRAME_COUNT) +#endif +#else +#define _CAPTURE_CALLSTACK() ::Concurrency_winrt::details::_TaskCreationCallstack::_CaptureSingleFrameCallstack(_ReturnAddress()) +#endif +/// + +/// A type that represents the terminal state of a task. Valid values are completed and canceled. +/// +/// +/**/ +typedef Concurrency::task_group_status task_status; + +template class task; +template <> class task; + +/// +/// Returns an indication of whether the task that is currently executing has received a request to cancel its +/// execution. Cancellation is requested on a task if the task was created with a cancellation token, and +/// the token source associated with that token is canceled. +/// +/// +/// true if the currently executing task has received a request for cancellation, false otherwise. +/// +/// +/// If you call this method in the body of a task and it returns true, you must respond with a call to +/// cancel_current_task to acknowledge the cancellation request, +/// after performing any cleanup you need. This will abort the execution of the task and cause it to enter into +/// the canceled state. If you do not respond and continue execution, or return instead of calling +/// cancel_current_task, the task will enter the completed state when it is done. +/// state. +/// A task is not cancellable if it was created without a cancellation token. +/// +/// +/// +/// +/// +/**/ +#if _MSC_VER >= 1800 +inline bool __cdecl is_task_cancellation_requested() +{ + return ::Concurrency::details::_TaskCollection_t::_Is_cancellation_requested(); +} +#else +inline bool __cdecl is_task_cancellation_requested() +{ + // ConcRT scheduler under the hood is using TaskCollection, which is same as task_group + return ::Concurrency::is_current_task_group_canceling(); +} +#endif + +/// +/// Cancels the currently executing task. This function can be called from within the body of a task to abort the +/// task's execution and cause it to enter the canceled state. While it may be used in response to +/// the is_task_cancellation_requested function, you may +/// also use it by itself, to initiate cancellation of the task that is currently executing. +/// It is not a supported scenario to call this function if you are not within the body of a task. +/// Doing so will result in undefined behavior such as a crash or a hang in your application. +/// +/// +/// +/**/ +//#if _MSC_VER >= 1800 +inline __declspec(noreturn) void __cdecl cancel_current_task() +{ + throw Concurrency::task_canceled(); +} +//#else +//_CRTIMP2 __declspec(noreturn) void __cdecl cancel_current_task(); +//#endif + +namespace details +{ +#if _MSC_VER >= 1800 + /// + /// Callstack container, which is used to capture and preserve callstacks in ppltasks. + /// Members of this class is examined by vc debugger, thus there will be no public access methods. + /// Please note that names of this class should be kept stable for debugger examining. + /// + class _TaskCreationCallstack + { + private: + // If _M_SingleFrame != nullptr, there will be only one frame of callstacks, which is stored in _M_SingleFrame; + // otherwise, _M_Frame will store all the callstack frames. + void* _M_SingleFrame; + std::vector _M_frames; + public: + _TaskCreationCallstack() + { + _M_SingleFrame = nullptr; + } + + // Store one frame of callstack. This function works for both Debug / Release CRT. + static _TaskCreationCallstack _CaptureSingleFrameCallstack(void *_SingleFrame) + { + _TaskCreationCallstack _csc; + _csc._M_SingleFrame = _SingleFrame; + return _csc; + } + + // Capture _CaptureFrames number of callstack frames. This function only work properly for Desktop or Debug CRT. + __declspec(noinline) + static _TaskCreationCallstack _CaptureMultiFramesCallstack(size_t _CaptureFrames) + { + _TaskCreationCallstack _csc; + _csc._M_frames.resize(_CaptureFrames); + // skip 2 frames to make sure callstack starts from user code + _csc._M_frames.resize(::Concurrency::details::platform::CaptureCallstack(&_csc._M_frames[0], 2, _CaptureFrames)); + return _csc; + } + }; +#endif + typedef UINT32 _Unit_type; + + struct _TypeSelectorNoAsync {}; + struct _TypeSelectorAsyncOperationOrTask {}; + struct _TypeSelectorAsyncOperation : public _TypeSelectorAsyncOperationOrTask { }; + struct _TypeSelectorAsyncTask : public _TypeSelectorAsyncOperationOrTask { }; + struct _TypeSelectorAsyncAction {}; + struct _TypeSelectorAsyncActionWithProgress {}; + struct _TypeSelectorAsyncOperationWithProgress {}; + + template + struct _NormalizeVoidToUnitType + { + typedef _Ty _Type; + }; + + template<> + struct _NormalizeVoidToUnitType + { + typedef _Unit_type _Type; + }; + + template + struct _IsUnwrappedAsyncSelector + { + static const bool _Value = true; + }; + + template<> + struct _IsUnwrappedAsyncSelector<_TypeSelectorNoAsync> + { + static const bool _Value = false; + }; + + template + struct _UnwrapTaskType + { + typedef _Ty _Type; + }; + + template + struct _UnwrapTaskType> + { + typedef _Ty _Type; + }; + + template + _TypeSelectorAsyncTask _AsyncOperationKindSelector(task<_T>); + + _TypeSelectorNoAsync _AsyncOperationKindSelector(...); + + template + struct _Unhat + { + typedef _Type _Value; + }; + + template + struct _Unhat<_Type*> + { + typedef _Type _Value; + }; + + //struct _NonUserType { public: int _Dummy; }; + + template + struct _ValueTypeOrRefType + { + typedef _Unit_type _Value; + }; + + template + struct _ValueTypeOrRefType<_Type, true> + { + typedef _Type _Value; + }; + + template + _Ty _UnwrapAsyncActionWithProgressSelector(ABI::Windows::Foundation::IAsyncActionWithProgress_impl<_Ty>*); + + template + _Ty _UnwrapAsyncActionWithProgressSelector(...); + + template + _Progress _UnwrapAsyncOperationWithProgressProgressSelector(ABI::Windows::Foundation::IAsyncOperationWithProgress_impl<_Ty, _Progress>*); + + template + _Progress _UnwrapAsyncOperationWithProgressProgressSelector(...); + + template + _T2 _ProgressTypeSelector(ABI::Windows::Foundation::IAsyncOperationWithProgress<_T1, _T2>*); + + template + _T1 _ProgressTypeSelector(ABI::Windows::Foundation::IAsyncActionWithProgress<_T1>*); + + template + struct _GetProgressType + { + typedef decltype(_ProgressTypeSelector(stdx::declval<_Type>())) _Value; + }; + + template + _TypeSelectorAsyncOperation _AsyncOperationKindSelector(ABI::Windows::Foundation::IAsyncOperation<_T>*); + + _TypeSelectorAsyncAction _AsyncOperationKindSelector(ABI::Windows::Foundation::IAsyncAction*); + + template + _TypeSelectorAsyncOperationWithProgress _AsyncOperationKindSelector(ABI::Windows::Foundation::IAsyncOperationWithProgress<_T1, _T2>*); + + template + _TypeSelectorAsyncActionWithProgress _AsyncOperationKindSelector(ABI::Windows::Foundation::IAsyncActionWithProgress<_T>*); + + template + struct _IsIAsyncInfo + { + static const bool _Value = std::is_base_of::_Value>::value || + std::is_same<_TypeSelectorAsyncAction, decltype(details::_AsyncOperationKindSelector(stdx::declval<_Type>()))>::value || + std::is_same<_TypeSelectorAsyncOperation, decltype(details::_AsyncOperationKindSelector(stdx::declval<_Type>()))>::value || + std::is_same<_TypeSelectorAsyncOperationWithProgress, decltype(details::_AsyncOperationKindSelector(stdx::declval<_Type>()))>::value || + std::is_same<_TypeSelectorAsyncActionWithProgress, decltype(details::_AsyncOperationKindSelector(stdx::declval<_Type>()))>::value; + }; + + template <> + struct _IsIAsyncInfo + { + static const bool _Value = false; + }; + + template + _Ty _UnwrapAsyncOperationSelector(ABI::Windows::Foundation::IAsyncOperation_impl<_Ty>*); + + template + _Ty _UnwrapAsyncOperationSelector(...); + + template + _Ty _UnwrapAsyncOperationWithProgressSelector(ABI::Windows::Foundation::IAsyncOperationWithProgress_impl<_Ty, _Progress>*); + + template + _Ty _UnwrapAsyncOperationWithProgressSelector(...); + + // Unwrap functions for asyncOperations + template + auto _GetUnwrappedType(ABI::Windows::Foundation::IAsyncOperation<_Ty>*) -> typename ABI::Windows::Foundation::Internal::GetAbiType*>()))>::type; + + void _GetUnwrappedType(ABI::Windows::Foundation::IAsyncAction*); + + template + auto _GetUnwrappedType(ABI::Windows::Foundation::IAsyncOperationWithProgress<_Ty, _Progress>*) -> typename ABI::Windows::Foundation::Internal::GetAbiType*>()))>::type; + + template + void _GetUnwrappedType(ABI::Windows::Foundation::IAsyncActionWithProgress<_Progress>*); + + template + _T _ReturnAsyncOperationKindSelector(ABI::Windows::Foundation::IAsyncOperation<_T>*); + + void _ReturnAsyncOperationKindSelector(ABI::Windows::Foundation::IAsyncAction*); + + template + _T1 _ReturnAsyncOperationKindSelector(ABI::Windows::Foundation::IAsyncOperationWithProgress<_T1, _T2>*); + + template + void _ReturnAsyncOperationKindSelector(ABI::Windows::Foundation::IAsyncActionWithProgress<_T>*); + + class _ProgressReporterCtorArgType{}; + + template ::_Value> + struct _TaskTypeTraits + { + typedef typename details::_UnwrapTaskType<_Type>::_Type _TaskRetType; + typedef _TaskRetType _TaskRetType_abi; + typedef decltype(_AsyncOperationKindSelector(stdx::declval<_Type>())) _AsyncKind; + typedef typename details::_NormalizeVoidToUnitType<_TaskRetType>::_Type _NormalizedTaskRetType; + + static const bool _IsAsyncTask = _IsAsync; + static const bool _IsUnwrappedTaskOrAsync = details::_IsUnwrappedAsyncSelector<_AsyncKind>::_Value; + }; + + template + struct _TaskTypeTraits<_Type, true> + { + typedef decltype(_ReturnAsyncOperationKindSelector(stdx::declval<_Type>())) _TaskRetType; + typedef decltype(_GetUnwrappedType(stdx::declval<_Type>())) _TaskRetType_abi; + typedef _TaskRetType _NormalizedTaskRetType; + typedef decltype(_AsyncOperationKindSelector(stdx::declval<_Type>())) _AsyncKind; + + static const bool _IsAsyncTask = true; + static const bool _IsUnwrappedTaskOrAsync = details::_IsUnwrappedAsyncSelector<_AsyncKind>::_Value; + }; + + template auto _IsCallable(_Function _Func, int, int, int) -> decltype(_Func(stdx::declval*>()), std::true_type()) { (void)_Func; return std::true_type(); } + template auto _IsCallable(_Function _Func, int, int, ...) -> decltype(_Func(stdx::declval<_ReturnType*>()), std::true_type()) { (void)_Func; return std::true_type(); } + template auto _IsCallable(_Function _Func, int, ...) -> decltype(_Func(), std::true_type()) { (void)_Func; return std::true_type(); } + template std::false_type _IsCallable(_Function, ...) { return std::false_type(); } + + template <> + struct _TaskTypeTraits + { + typedef void _TaskRetType; + typedef void _TaskRetType_abi; + typedef _TypeSelectorNoAsync _AsyncKind; + typedef _Unit_type _NormalizedTaskRetType; + + static const bool _IsAsyncTask = false; + static const bool _IsUnwrappedTaskOrAsync = false; + }; + + // *************************************************************************** + // Template type traits and helpers for async production APIs: + // + + struct _ZeroArgumentFunctor { }; + struct _OneArgumentFunctor { }; + struct _TwoArgumentFunctor { }; + struct _ThreeArgumentFunctor { }; + + // **************************************** + // CLASS TYPES: + + // mutable functions + // ******************** + // THREE ARGUMENTS: + + // non-void arg: + template + _Arg1 _Arg1ClassHelperThunk(_ReturnType(_Class::*)(_Arg1, _Arg2, _Arg3)); + + // non-void arg: + template + _Arg2 _Arg2ClassHelperThunk(_ReturnType(_Class::*)(_Arg1, _Arg2, _Arg3)); + + // non-void arg: + template + _Arg3 _Arg3ClassHelperThunk(_ReturnType(_Class::*)(_Arg1, _Arg2, _Arg3)); + + template + _ReturnType _ReturnTypeClassHelperThunk(_ReturnType(_Class::*)(_Arg1, _Arg2, _Arg3)); + + template + _ThreeArgumentFunctor _ArgumentCountHelper(_ReturnType(_Class::*)(_Arg1, _Arg2, _Arg3)); + + // ******************** + // TWO ARGUMENTS: + + // non-void arg: + template + _Arg1 _Arg1ClassHelperThunk(_ReturnType(_Class::*)(_Arg1, _Arg2)); + + // non-void arg: + template + _Arg2 _Arg2ClassHelperThunk(_ReturnType(_Class::*)(_Arg1, _Arg2)); + + // non-void arg: + template + void _Arg3ClassHelperThunk(_ReturnType(_Class::*)(_Arg1, _Arg2)); + + template + _ReturnType _ReturnTypeClassHelperThunk(_ReturnType(_Class::*)(_Arg1, _Arg2)); + + template + _TwoArgumentFunctor _ArgumentCountHelper(_ReturnType(_Class::*)(_Arg1, _Arg2)); + + // ******************** + // ONE ARGUMENT: + + // non-void arg: + template + _Arg1 _Arg1ClassHelperThunk(_ReturnType(_Class::*)(_Arg1)); + + // non-void arg: + template + void _Arg2ClassHelperThunk(_ReturnType(_Class::*)(_Arg1)); + + // non-void arg: + template + void _Arg3ClassHelperThunk(_ReturnType(_Class::*)(_Arg1)); + + template + _ReturnType _ReturnTypeClassHelperThunk(_ReturnType(_Class::*)(_Arg1)); + + template + _OneArgumentFunctor _ArgumentCountHelper(_ReturnType(_Class::*)(_Arg1)); + + // ******************** + // ZERO ARGUMENT: + + // void arg: + template + void _Arg1ClassHelperThunk(_ReturnType(_Class::*)()); + + // void arg: + template + void _Arg2ClassHelperThunk(_ReturnType(_Class::*)()); + + // void arg: + template + void _Arg3ClassHelperThunk(_ReturnType(_Class::*)()); + + // void arg: + template + _ReturnType _ReturnTypeClassHelperThunk(_ReturnType(_Class::*)()); + + template + _ZeroArgumentFunctor _ArgumentCountHelper(_ReturnType(_Class::*)()); + + // ******************** + // THREE ARGUMENTS: + + // non-void arg: + template + _Arg1 _Arg1ClassHelperThunk(_ReturnType(_Class::*)(_Arg1, _Arg2, _Arg3) const); + + // non-void arg: + template + _Arg2 _Arg2ClassHelperThunk(_ReturnType(_Class::*)(_Arg1, _Arg2, _Arg3) const); + + // non-void arg: + template + _Arg3 _Arg3ClassHelperThunk(_ReturnType(_Class::*)(_Arg1, _Arg2, _Arg3) const); + + template + _ReturnType _ReturnTypeClassHelperThunk(_ReturnType(_Class::*)(_Arg1, _Arg2, _Arg3) const); + + template + _ThreeArgumentFunctor _ArgumentCountHelper(_ReturnType(_Class::*)(_Arg1, _Arg2, _Arg3) const); + + // ******************** + // TWO ARGUMENTS: + + // non-void arg: + template + _Arg1 _Arg1ClassHelperThunk(_ReturnType(_Class::*)(_Arg1, _Arg2) const); + + // non-void arg: + template + _Arg2 _Arg2ClassHelperThunk(_ReturnType(_Class::*)(_Arg1, _Arg2) const); + + // non-void arg: + template + void _Arg3ClassHelperThunk(_ReturnType(_Class::*)(_Arg1, _Arg2) const); + + template + _ReturnType _ReturnTypeClassHelperThunk(_ReturnType(_Class::*)(_Arg1, _Arg2) const); + + template + _TwoArgumentFunctor _ArgumentCountHelper(_ReturnType(_Class::*)(_Arg1, _Arg2) const); + + // ******************** + // ONE ARGUMENT: + + // non-void arg: + template + _Arg1 _Arg1ClassHelperThunk(_ReturnType(_Class::*)(_Arg1) const); + + // non-void arg: + template + void _Arg2ClassHelperThunk(_ReturnType(_Class::*)(_Arg1) const); + + // non-void arg: + template + void _Arg3ClassHelperThunk(_ReturnType(_Class::*)(_Arg1) const); + + template + _ReturnType _ReturnTypeClassHelperThunk(_ReturnType(_Class::*)(_Arg1) const); + + template + _OneArgumentFunctor _ArgumentCountHelper(_ReturnType(_Class::*)(_Arg1) const); + + // ******************** + // ZERO ARGUMENT: + + // void arg: + template + void _Arg1ClassHelperThunk(_ReturnType(_Class::*)() const); + + // void arg: + template + void _Arg2ClassHelperThunk(_ReturnType(_Class::*)() const); + + // void arg: + template + void _Arg3ClassHelperThunk(_ReturnType(_Class::*)() const); + + // void arg: + template + _ReturnType _ReturnTypeClassHelperThunk(_ReturnType(_Class::*)() const); + + template + _ZeroArgumentFunctor _ArgumentCountHelper(_ReturnType(_Class::*)() const); + + // **************************************** + // POINTER TYPES: + + // ******************** + // THREE ARGUMENTS: + + template + _Arg1 _Arg1PFNHelperThunk(_ReturnType(__cdecl *)(_Arg1, _Arg2, _Arg3)); + + template + _Arg2 _Arg2PFNHelperThunk(_ReturnType(__cdecl *)(_Arg1, _Arg2, _Arg3)); + + template + _Arg3 _Arg3PFNHelperThunk(_ReturnType(__cdecl *)(_Arg1, _Arg2, _Arg3)); + + template + _ReturnType _ReturnTypePFNHelperThunk(_ReturnType(__cdecl *)(_Arg1, _Arg2, _Arg3)); + + template + _ThreeArgumentFunctor _ArgumentCountHelper(_ReturnType(__cdecl *)(_Arg1, _Arg2, _Arg3)); + + template + _Arg1 _Arg1PFNHelperThunk(_ReturnType(__stdcall *)(_Arg1, _Arg2, _Arg3)); + + template + _Arg2 _Arg2PFNHelperThunk(_ReturnType(__stdcall *)(_Arg1, _Arg2, _Arg3)); + + template + _Arg3 _Arg3PFNHelperThunk(_ReturnType(__stdcall *)(_Arg1, _Arg2, _Arg3)); + + template + _ReturnType _ReturnTypePFNHelperThunk(_ReturnType(__stdcall *)(_Arg1, _Arg2, _Arg3)); + + template + _ThreeArgumentFunctor _ArgumentCountHelper(_ReturnType(__stdcall *)(_Arg1, _Arg2, _Arg3)); + + template + _Arg1 _Arg1PFNHelperThunk(_ReturnType(__fastcall *)(_Arg1, _Arg2, _Arg3)); + + template + _Arg2 _Arg2PFNHelperThunk(_ReturnType(__fastcall *)(_Arg1, _Arg2, _Arg3)); + + template + _Arg3 _Arg3PFNHelperThunk(_ReturnType(__fastcall *)(_Arg1, _Arg2, _Arg3)); + + template + _ReturnType _ReturnTypePFNHelperThunk(_ReturnType(__fastcall *)(_Arg1, _Arg2, _Arg3)); + + template + _ThreeArgumentFunctor _ArgumentCountHelper(_ReturnType(__fastcall *)(_Arg1, _Arg2, _Arg3)); + + // ******************** + // TWO ARGUMENTS: + + template + _Arg1 _Arg1PFNHelperThunk(_ReturnType(__cdecl *)(_Arg1, _Arg2)); + + template + _Arg2 _Arg2PFNHelperThunk(_ReturnType(__cdecl *)(_Arg1, _Arg2)); + + template + void _Arg3PFNHelperThunk(_ReturnType(__cdecl *)(_Arg1, _Arg2)); + + template + _ReturnType _ReturnTypePFNHelperThunk(_ReturnType(__cdecl *)(_Arg1, _Arg2)); + + template + _TwoArgumentFunctor _ArgumentCountHelper(_ReturnType(__cdecl *)(_Arg1, _Arg2)); + + template + _Arg1 _Arg1PFNHelperThunk(_ReturnType(__stdcall *)(_Arg1, _Arg2)); + + template + _Arg2 _Arg2PFNHelperThunk(_ReturnType(__stdcall *)(_Arg1, _Arg2)); + + template + void _Arg3PFNHelperThunk(_ReturnType(__stdcall *)(_Arg1, _Arg2)); + + template + _ReturnType _ReturnTypePFNHelperThunk(_ReturnType(__stdcall *)(_Arg1, _Arg2)); + + template + _TwoArgumentFunctor _ArgumentCountHelper(_ReturnType(__stdcall *)(_Arg1, _Arg2)); + + template + _Arg1 _Arg1PFNHelperThunk(_ReturnType(__fastcall *)(_Arg1, _Arg2)); + + template + _Arg2 _Arg2PFNHelperThunk(_ReturnType(__fastcall *)(_Arg1, _Arg2)); + + template + void _Arg3PFNHelperThunk(_ReturnType(__fastcall *)(_Arg1, _Arg2)); + + template + _ReturnType _ReturnTypePFNHelperThunk(_ReturnType(__fastcall *)(_Arg1, _Arg2)); + + template + _TwoArgumentFunctor _ArgumentCountHelper(_ReturnType(__fastcall *)(_Arg1, _Arg2)); + + // ******************** + // ONE ARGUMENT: + + template + _Arg1 _Arg1PFNHelperThunk(_ReturnType(__cdecl *)(_Arg1)); + + template + void _Arg2PFNHelperThunk(_ReturnType(__cdecl *)(_Arg1)); + + template + void _Arg3PFNHelperThunk(_ReturnType(__cdecl *)(_Arg1)); + + template + _ReturnType _ReturnTypePFNHelperThunk(_ReturnType(__cdecl *)(_Arg1)); + + template + _OneArgumentFunctor _ArgumentCountHelper(_ReturnType(__cdecl *)(_Arg1)); + + template + _Arg1 _Arg1PFNHelperThunk(_ReturnType(__stdcall *)(_Arg1)); + + template + void _Arg2PFNHelperThunk(_ReturnType(__stdcall *)(_Arg1)); + + template + void _Arg3PFNHelperThunk(_ReturnType(__stdcall *)(_Arg1)); + + template + _ReturnType _ReturnTypePFNHelperThunk(_ReturnType(__stdcall *)(_Arg1)); + + template + _OneArgumentFunctor _ArgumentCountHelper(_ReturnType(__stdcall *)(_Arg1)); + + template + _Arg1 _Arg1PFNHelperThunk(_ReturnType(__fastcall *)(_Arg1)); + + template + void _Arg2PFNHelperThunk(_ReturnType(__fastcall *)(_Arg1)); + + template + void _Arg3PFNHelperThunk(_ReturnType(__fastcall *)(_Arg1)); + + template + _ReturnType _ReturnTypePFNHelperThunk(_ReturnType(__fastcall *)(_Arg1)); + + template + _OneArgumentFunctor _ArgumentCountHelper(_ReturnType(__fastcall *)(_Arg1)); + + // ******************** + // ZERO ARGUMENT: + + template + void _Arg1PFNHelperThunk(_ReturnType(__cdecl *)()); + + template + void _Arg2PFNHelperThunk(_ReturnType(__cdecl *)()); + + template + void _Arg3PFNHelperThunk(_ReturnType(__cdecl *)()); + + template + _ReturnType _ReturnTypePFNHelperThunk(_ReturnType(__cdecl *)()); + + template + _ZeroArgumentFunctor _ArgumentCountHelper(_ReturnType(__cdecl *)()); + + template + void _Arg1PFNHelperThunk(_ReturnType(__stdcall *)()); + + template + void _Arg2PFNHelperThunk(_ReturnType(__stdcall *)()); + + template + void _Arg3PFNHelperThunk(_ReturnType(__stdcall *)()); + + template + _ReturnType _ReturnTypePFNHelperThunk(_ReturnType(__stdcall *)()); + + template + _ZeroArgumentFunctor _ArgumentCountHelper(_ReturnType(__stdcall *)()); + + template + void _Arg1PFNHelperThunk(_ReturnType(__fastcall *)()); + + template + void _Arg2PFNHelperThunk(_ReturnType(__fastcall *)()); + + template + void _Arg3PFNHelperThunk(_ReturnType(__fastcall *)()); + + template + _ReturnType _ReturnTypePFNHelperThunk(_ReturnType(__fastcall *)()); + + template + _ZeroArgumentFunctor _ArgumentCountHelper(_ReturnType(__fastcall *)()); + + template + struct _FunctorArguments + { + static const size_t _Count = 0; + }; + + template<> + struct _FunctorArguments<_OneArgumentFunctor> + { + static const size_t _Count = 1; + }; + + template<> + struct _FunctorArguments<_TwoArgumentFunctor> + { + static const size_t _Count = 2; + }; + + template<> + struct _FunctorArguments<_ThreeArgumentFunctor> + { + static const size_t _Count = 3; + }; + + template + struct _FunctorTypeTraits + { + typedef decltype(_ArgumentCountHelper(&(_T::operator()))) _ArgumentCountType; + static const size_t _ArgumentCount = _FunctorArguments<_ArgumentCountType>::_Count; + + typedef decltype(_ReturnTypeClassHelperThunk(&(_T::operator()))) _ReturnType; + typedef decltype(_Arg1ClassHelperThunk(&(_T::operator()))) _Argument1Type; + typedef decltype(_Arg2ClassHelperThunk(&(_T::operator()))) _Argument2Type; + typedef decltype(_Arg3ClassHelperThunk(&(_T::operator()))) _Argument3Type; + }; + + template + struct _FunctorTypeTraits<_T *> + { + typedef decltype(_ArgumentCountHelper(stdx::declval<_T*>())) _ArgumentCountType; + static const size_t _ArgumentCount = _FunctorArguments<_ArgumentCountType>::_Count; + + typedef decltype(_ReturnTypePFNHelperThunk(stdx::declval<_T*>())) _ReturnType; + typedef decltype(_Arg1PFNHelperThunk(stdx::declval<_T*>())) _Argument1Type; + typedef decltype(_Arg2PFNHelperThunk(stdx::declval<_T*>())) _Argument2Type; + typedef decltype(_Arg3PFNHelperThunk(stdx::declval<_T*>())) _Argument3Type; + }; + + task _To_task(); + + template auto _IsVoidConversionHelper(_Function _Func, int) -> typename decltype(_Func(_To_task()), std::true_type()); + template std::false_type _IsVoidConversionHelper(_Function _Func, ...); + + template std::true_type _VoidIsTaskHelper(task _Arg, int); + template std::false_type _VoidIsTaskHelper(T _Arg, ...); + + template(), 0)), std::true_type>::value, const size_t _Count = _FunctorTypeTraits<_Function>::_ArgumentCount> + struct _FunctionTypeTraits + { + typedef typename _Unhat::_Argument2Type>::_Value _FuncRetType; + static_assert(std::is_same::_Argument1Type, _ExpectedParameterType>::value || + std::is_same::_Argument1Type, task<_ExpectedParameterType>>::value, "incorrect parameter type for the callable object in 'then'; consider _ExpectedParameterType or task<_ExpectedParameterType> (see below)"); + + typedef decltype(_VoidIsTaskHelper(stdx::declval<_FunctorTypeTraits<_Function>::_Argument1Type>(), 0)) _Takes_task; + }; + + //if there is a continuation parameter, then must use void/no return value + template + struct _FunctionTypeTraits<_Function, _ExpectedParameterType, _IsVoidConversion, 1> + { + typedef void _FuncRetType; + static_assert(std::is_same::_Argument1Type, _ExpectedParameterType>::value || + std::is_same::_Argument1Type, task<_ExpectedParameterType>>::value, "incorrect parameter type for the callable object in 'then'; consider _ExpectedParameterType or task<_ExpectedParameterType> (see below)"); + + typedef decltype(_VoidIsTaskHelper(stdx::declval<_FunctorTypeTraits<_Function>::_Argument1Type>(), 0)) _Takes_task; + }; + + template + struct _FunctionTypeTraits<_Function, void, true, 1> + { + typedef void _FuncRetType; + static_assert(std::is_same::_Argument1Type, decltype(_To_task())>::value, "incorrect parameter type for the callable object in 'then'; consider _ExpectedParameterType or task<_ExpectedParameterType> (see below)"); + + typedef decltype(_VoidIsTaskHelper(stdx::declval<_FunctorTypeTraits<_Function>::_Argument1Type>(), 0)) _Takes_task; + }; + + template + struct _FunctionTypeTraits<_Function, void, false, 1> + { + typedef typename _Unhat::_Argument1Type>::_Value _FuncRetType; + + typedef std::false_type _Takes_task; + }; + + template + struct _FunctionTypeTraits<_Function, _ExpectedParameterType, _IsVoidConversion, 0> + { + typedef void _FuncRetType; + + typedef std::false_type _Takes_task; + }; + + template + struct _ContinuationTypeTraits + { + typedef typename task::_FuncRetType>::_TaskRetType_abi> _TaskOfType; + }; + + // _InitFunctorTypeTraits is used to decide whether a task constructed with a lambda should be unwrapped. Depending on how the variable is + // declared, the constructor may or may not perform unwrapping. For eg. + // + // This declaration SHOULD NOT cause unwrapping + // task> t1([]() -> task { + // task t2([]() {}); + // return t2; + // }); + // + // This declaration SHOULD cause unwrapping + // task> t1([]() -> task { + // task t2([]() {}); + // return t2; + // }); + // If the type of the task is the same as the return type of the function, no unwrapping should take place. Else normal rules apply. + template + struct _InitFunctorTypeTraits + { + typedef typename _TaskTypeTraits<_FuncRetType>::_AsyncKind _AsyncKind; + static const bool _IsAsyncTask = _TaskTypeTraits<_FuncRetType>::_IsAsyncTask; + static const bool _IsUnwrappedTaskOrAsync = _TaskTypeTraits<_FuncRetType>::_IsUnwrappedTaskOrAsync; + }; + + template + struct _InitFunctorTypeTraits + { + typedef _TypeSelectorNoAsync _AsyncKind; + static const bool _IsAsyncTask = false; + static const bool _IsUnwrappedTaskOrAsync = false; + }; + /// + /// Helper object used for LWT invocation. + /// + struct _TaskProcThunk + { + _TaskProcThunk(const std::function & _Callback) : + _M_func(_Callback) + { + } + + static void __cdecl _Bridge(void *_PData) + { + _TaskProcThunk *_PThunk = reinterpret_cast<_TaskProcThunk *>(_PData); +#if _MSC_VER >= 1800 + _Holder _ThunkHolder(_PThunk); +#endif + _PThunk->_M_func(); +#if _MSC_VER < 1800 + delete _PThunk; +#endif + } + private: +#if _MSC_VER >= 1800 + // RAII holder + struct _Holder + { + _Holder(_TaskProcThunk * _PThunk) : _M_pThunk(_PThunk) + { + } + + ~_Holder() + { + delete _M_pThunk; + } + + _TaskProcThunk * _M_pThunk; + + private: + _Holder& operator=(const _Holder&); + }; +#endif + std::function _M_func; + _TaskProcThunk& operator=(const _TaskProcThunk&); + }; + + /// + /// Schedule a functor with automatic inlining. Note that this is "fire and forget" scheduling, which cannot be + /// waited on or canceled after scheduling. + /// This schedule method will perform automatic inlining base on . + /// + /// + /// The user functor need to be scheduled. + /// + /// + /// The inlining scheduling policy for current functor. + /// +#if _MSC_VER >= 1800 + typedef Concurrency::details::_TaskInliningMode_t _TaskInliningMode; +#else + typedef Concurrency::details::_TaskInliningMode _TaskInliningMode; +#endif + static void _ScheduleFuncWithAutoInline(const std::function & _Func, _TaskInliningMode _InliningMode) + { +#if _MSC_VER >= 1800 + Concurrency::details::_TaskCollection_t::_RunTask(&_TaskProcThunk::_Bridge, new _TaskProcThunk(_Func), _InliningMode); +#else + Concurrency::details::_StackGuard _Guard; + if (_Guard._ShouldInline(_InliningMode)) + { + _Func(); + } + else + { + Concurrency::details::_CurrentScheduler::_ScheduleTask(reinterpret_cast(&_TaskProcThunk::_Bridge), new _TaskProcThunk(_Func)); + } +#endif + } + class _ContextCallback + { + typedef std::function _CallbackFunction; + + public: + + static _ContextCallback _CaptureCurrent() + { + _ContextCallback _Context; + _Context._Capture(); + return _Context; + } + + ~_ContextCallback() + { + _Reset(); + } + + _ContextCallback(bool _DeferCapture = false) + { + if (_DeferCapture) + { + _M_context._M_captureMethod = _S_captureDeferred; + } + else + { + _M_context._M_pContextCallback = nullptr; + } + } + + // Resolves a context that was created as _S_captureDeferred based on the environment (ancestor, current context). + void _Resolve(bool _CaptureCurrent) + { + if (_M_context._M_captureMethod == _S_captureDeferred) + { + _M_context._M_pContextCallback = nullptr; + + if (_CaptureCurrent) + { + if (_IsCurrentOriginSTA()) + { + _Capture(); + } +#if _UITHREADCTXT_SUPPORT + else + { + // This method will fail if not called from the UI thread. + HRESULT _Hr = CaptureUiThreadContext(&_M_context._M_pContextCallback); + if (FAILED(_Hr)) + { + _M_context._M_pContextCallback = nullptr; + } + } +#endif // _UITHREADCTXT_SUPPORT + } + } + } + + void _Capture() + { + HRESULT _Hr = CoGetObjectContext(IID_IContextCallback, reinterpret_cast(&_M_context._M_pContextCallback)); + if (FAILED(_Hr)) + { + _M_context._M_pContextCallback = nullptr; + } + } + + _ContextCallback(const _ContextCallback& _Src) + { + _Assign(_Src._M_context._M_pContextCallback); + } + + _ContextCallback(_ContextCallback&& _Src) + { + _M_context._M_pContextCallback = _Src._M_context._M_pContextCallback; + _Src._M_context._M_pContextCallback = nullptr; + } + + _ContextCallback& operator=(const _ContextCallback& _Src) + { + if (this != &_Src) + { + _Reset(); + _Assign(_Src._M_context._M_pContextCallback); + } + return *this; + } + + _ContextCallback& operator=(_ContextCallback&& _Src) + { + if (this != &_Src) + { + _M_context._M_pContextCallback = _Src._M_context._M_pContextCallback; + _Src._M_context._M_pContextCallback = nullptr; + } + return *this; + } + + bool _HasCapturedContext() const + { + _CONCRT_ASSERT(_M_context._M_captureMethod != _S_captureDeferred); + return (_M_context._M_pContextCallback != nullptr); + } + + HRESULT _CallInContext(_CallbackFunction _Func) const + { + if (!_HasCapturedContext()) + { + _Func(); + } + else + { + ComCallData callData; + ZeroMemory(&callData, sizeof(callData)); + callData.pUserDefined = reinterpret_cast(&_Func); + + HRESULT _Hr = _M_context._M_pContextCallback->ContextCallback(&_Bridge, &callData, IID_ICallbackWithNoReentrancyToApplicationSTA, 5, nullptr); + if (FAILED(_Hr)) + { + return _Hr; + } + } + return S_OK; + } + + bool operator==(const _ContextCallback& _Rhs) const + { + return (_M_context._M_pContextCallback == _Rhs._M_context._M_pContextCallback); + } + + bool operator!=(const _ContextCallback& _Rhs) const + { + return !(operator==(_Rhs)); + } + + private: + + void _Reset() + { + if (_M_context._M_captureMethod != _S_captureDeferred && _M_context._M_pContextCallback != nullptr) + { + _M_context._M_pContextCallback->Release(); + } + } + + void _Assign(IContextCallback *_PContextCallback) + { + _M_context._M_pContextCallback = _PContextCallback; + if (_M_context._M_captureMethod != _S_captureDeferred && _M_context._M_pContextCallback != nullptr) + { + _M_context._M_pContextCallback->AddRef(); + } + } + + static HRESULT __stdcall _Bridge(ComCallData *_PParam) + { + _CallbackFunction *pFunc = reinterpret_cast<_CallbackFunction *>(_PParam->pUserDefined); + return (*pFunc)(); + } + + // Returns the origin information for the caller (runtime / Windows Runtime apartment as far as task continuations need know) + static bool _IsCurrentOriginSTA() + { + APTTYPE _AptType; + APTTYPEQUALIFIER _AptTypeQualifier; + + HRESULT hr = CoGetApartmentType(&_AptType, &_AptTypeQualifier); + if (SUCCEEDED(hr)) + { + // We determine the origin of a task continuation by looking at where .then is called, so we can tell whether + // to need to marshal the continuation back to the originating apartment. If an STA thread is in executing in + // a neutral aparment when it schedules a continuation, we will not marshal continuations back to the STA, + // since variables used within a neutral apartment are expected to be apartment neutral. + switch (_AptType) + { + case APTTYPE_MAINSTA: + case APTTYPE_STA: + return true; + default: + break; + } + } + return false; + } + + union + { + IContextCallback *_M_pContextCallback; + size_t _M_captureMethod; + } _M_context; + + static const size_t _S_captureDeferred = 1; + }; + +#if _MSC_VER >= 1800 + template + struct _ResultHolder + { + void Set(const _Type& _type) + { + _Result = _type; + } + + _Type Get() + { + return _Result; + } + + _Type _Result; + }; + + template + struct _ResultHolder<_Type*> + { + void Set(_Type* const & _type) + { + _M_Result = _type; + } + + _Type* Get() + { + return _M_Result.Get(); + } + private: + // ::Platform::Agile handle specialization of all hats + // including ::Platform::String and ::Platform::Array + Agile<_Type*> _M_Result; + }; + + // + // The below are for composability with tasks auto-created from when_any / when_all / && / || constructs. + // + template + struct _ResultHolder> + { + void Set(const std::vector<_Type*>& _type) + { + _Result.reserve(_type.size()); + + for (auto _PTask = _type.begin(); _PTask != _type.end(); ++_PTask) + { + _Result.emplace_back(*_PTask); + } + } + + std::vector<_Type*> Get() + { + // Return vectory with the objects that are marshaled in the proper appartment + std::vector<_Type*> _Return; + _Return.reserve(_Result.size()); + + for (auto _PTask = _Result.begin(); _PTask != _Result.end(); ++_PTask) + { + _Return.push_back(_PTask->Get()); // Agile will marshal the object to appropriate appartment if neccessary + } + + return _Return; + } + + std::vector< Agile<_Type*> > _Result; + }; + + template + struct _ResultHolder > + { + void Set(const std::pair<_Type*, size_t>& _type) + { + _M_Result = _type; + } + + std::pair<_Type*, size_t> Get() + { + return std::make_pair(_M_Result.first, _M_Result.second); + } + private: + std::pair, size_t> _M_Result; + }; +#else + template + struct _ResultContext + { + static _ContextCallback _GetContext(bool /* _RuntimeAggregate */) + { + return _ContextCallback(); + } + + static _Type _GetValue(_Type _ObjInCtx, const _ContextCallback & /* _Ctx */, bool /* _RuntimeAggregate */) + { + return _ObjInCtx; + } + }; + + template::value> + struct _MarshalHelper + { + }; + template + struct _MarshalHelper<_Type, N, true> + { + static _Type* _Perform(_Type(&_ObjInCtx)[N], const _ContextCallback& _Ctx) + { + static_assert(__is_valid_winrt_type(_Type*), "must be a WinRT array compatible type"); + if (_ObjInCtx == nullptr) + { + return nullptr; + } + + HRESULT _Hr; + IStream * _PStream; + _Ctx._CallInContext([&]() -> HRESULT { + // It isn't safe to simply reinterpret_cast a hat type to IUnknown* because some types do not have a real vtable ptr. + // Instead, we could to create a property value to make it "grow" the vtable ptr but instead primitives are not marshalled. + + IUnknown * _PUnk = winrt_array_type::create(_ObjInCtx, N); + _Hr = CoMarshalInterThreadInterfaceInStream(winrt_type<_Type>::getuuid(), _PUnk, &_PStream); + return S_OK; + }); + + // With an APPX manifest, this call should never fail. + _CONCRT_ASSERT(SUCCEEDED(_Hr)); + + _Type* _Proxy; + // + // Cannot use IID_PPV_ARGS with ^ types. + // + _Hr = CoGetInterfaceAndReleaseStream(_PStream, winrt_type<_Type>::getuuid(), reinterpret_cast(&_Proxy)); + if (FAILED(_Hr)) + { + throw std::make_exception_ptr(_Hr); + } + return _Proxy; + } + }; + template + struct _MarshalHelper<_Type, 0, false> + { + static _Type* _Perform(_Type* _ObjInCtx, const _ContextCallback& _Ctx) + { + static_assert(std::is_base_of::value || __is_valid_winrt_type(_Type), "must be a COM or WinRT type"); + if (_ObjInCtx == nullptr) + { + return nullptr; + } + + HRESULT _Hr; + IStream * _PStream; + _Ctx._CallInContext([&]() -> HRESULT { + // It isn't safe to simply reinterpret_cast a hat type to IUnknown* because some types do not have a real vtable ptr. + // Instead, we could to create a property value to make it "grow" the vtable ptr but instead primitives are not marshalled. + + IUnknown * _PUnk = winrt_type<_Type>::create(_ObjInCtx); + _Hr = CoMarshalInterThreadInterfaceInStream(winrt_type<_Type>::getuuid(), _PUnk, &_PStream); + return S_OK; + }); + + // With an APPX manifest, this call should never fail. + _CONCRT_ASSERT(SUCCEEDED(_Hr)); + + _Type* _Proxy; + // + // Cannot use IID_PPV_ARGS with ^ types. + // + _Hr = CoGetInterfaceAndReleaseStream(_PStream, winrt_type<_Type>::getuuid(), reinterpret_cast(&_Proxy)); + if (FAILED(_Hr)) + { + throw std::make_exception_ptr(_Hr); + } + return _Proxy; + } + }; + + // Arrays must be converted to IPropertyValue objects. + + template<> + struct _MarshalHelper + { + static HSTRING _Perform(HSTRING _ObjInCtx, const _ContextCallback& _Ctx) + { + return _ObjInCtx; + } + }; + + template + _Type* _Marshal(_Type* _ObjInCtx, const _ContextCallback& _Ctx) + { + return _MarshalHelper<_Type>::_Perform(_ObjInCtx, _Ctx); + } + + template + struct _InContext + { + static _Type _Get(_Type _ObjInCtx, const _ContextCallback& _Ctx) + { + return _ObjInCtx; + } + }; + + template + struct _InContext<_Type*> + { + static _Type* _Get(_Type* _ObjInCtx, const _ContextCallback& _Ctx) + { + _ContextCallback _CurrentContext = _ContextCallback::_CaptureCurrent(); + if (!_Ctx._HasCapturedContext() || _Ctx == _CurrentContext) + { + return _ObjInCtx; + } + + // + // The object is from another apartment. If it's marshalable, do so. + // + return _Marshal<_Type>(_ObjInCtx, _Ctx); + } + }; + + template + struct _ResultContext<_Type*> + { + static _Type* _GetValue(_Type* _ObjInCtx, const _ContextCallback& _Ctx, bool /* _RuntimeAggregate */) + { + return _InContext<_Type*>::_Get(_ObjInCtx, _Ctx); + } + + static _ContextCallback _GetContext(bool /* _RuntimeAggregate */) + { + return _ContextCallback::_CaptureCurrent(); + } + }; + + // + // The below are for composability with tasks auto-created from when_any / when_all / && / || constructs. + // + template + struct _ResultContext> + { + static std::vector<_Type*> _GetValue(std::vector<_Type*> _ObjInCtx, const _ContextCallback& _Ctx, bool _RuntimeAggregate) + { + if (!_RuntimeAggregate) + { + return _ObjInCtx; + } + + _ContextCallback _CurrentContext = _ContextCallback::_CaptureCurrent(); + if (!_Ctx._HasCapturedContext() || _Ctx == _CurrentContext) + { + return _ObjInCtx; + } + + for (auto _It = _ObjInCtx.begin(); _It != _ObjInCtx.end(); ++_It) + { + *_It = _Marshal<_Type>(*_It, _Ctx); + } + + return _ObjInCtx; + } + + static _ContextCallback _GetContext(bool _RuntimeAggregate) + { + if (!_RuntimeAggregate) + { + return _ContextCallback(); + } + else + { + return _ContextCallback::_CaptureCurrent(); + } + } + }; + + template + struct _ResultContext> + { + static std::pair<_Type*, size_t> _GetValue(std::pair<_Type*, size_t> _ObjInCtx, const _ContextCallback& _Ctx, bool _RuntimeAggregate) + { + if (!_RuntimeAggregate) + { + return _ObjInCtx; + } + + _ContextCallback _CurrentContext = _ContextCallback::_CaptureCurrent(); + if (!_Ctx._HasCapturedContext() || _Ctx == _CurrentContext) + { + return _ObjInCtx; + } + + return std::pair<_Type*, size_t>(_Marshal<_Type>(_ObjInCtx.first, _Ctx), _ObjInCtx.second); + } + + static _ContextCallback _GetContext(bool _RuntimeAggregate) + { + if (!_RuntimeAggregate) + { + return _ContextCallback(); + } + else + { + return _ContextCallback::_CaptureCurrent(); + } + } + }; +#endif + // An exception thrown by the task body is captured in an exception holder and it is shared with all value based continuations rooted at the task. + // The exception is 'observed' if the user invokes get()/wait() on any of the tasks that are sharing this exception holder. If the exception + // is not observed by the time the internal object owned by the shared pointer destructs, the process will fail fast. + struct _ExceptionHolder + { +#if _MSC_VER >= 1800 + private: + void ReportUnhandledError() + { + if (_M_winRTException != nullptr) + { + throw _M_winRTException.Get(); + } + } + public: + explicit _ExceptionHolder(const std::exception_ptr& _E, const _TaskCreationCallstack &_stackTrace) : + _M_exceptionObserved(0), _M_stdException(_E), _M_stackTrace(_stackTrace) + { + } + + explicit _ExceptionHolder(IRestrictedErrorInfo*& _E, const _TaskCreationCallstack &_stackTrace) : + _M_exceptionObserved(0), _M_winRTException(_E), _M_stackTrace(_stackTrace) + { + } +#else + explicit _ExceptionHolder(const std::exception_ptr& _E, void* _SourceAddressHint) : + _M_exceptionObserved(0), _M_stdException(_E), _M_disassembleMe(_SourceAddressHint) + { + } + + explicit _ExceptionHolder(IRestrictedErrorInfo*& _E, void* _SourceAddressHint) : + _M_exceptionObserved(0), _M_disassembleMe(_SourceAddressHint), _M_winRTException(_E) + { + } +#endif + __declspec(noinline) + ~_ExceptionHolder() + { + if (_M_exceptionObserved == 0) + { +#if _MSC_VER >= 1800 + // If you are trapped here, it means an exception thrown in task chain didn't get handled. + // Please add task-based continuation to handle all exceptions coming from tasks. + // this->_M_stackTrace keeps the creation callstack of the task generates this exception. + _REPORT_PPLTASK_UNOBSERVED_EXCEPTION(); +#else + // Disassemble at this->_M_disassembleMe to get to the source location right after either the creation of the task (constructor + // or then method) that encountered this exception, or the set_exception call for a task_completion_event. + Concurrency::details::_ReportUnobservedException(); +#endif + } + } + + void _RethrowUserException() + { + if (_M_exceptionObserved == 0) + { +#if _MSC_VER >= 1800 + Concurrency::details::atomic_exchange(_M_exceptionObserved, 1l); +#else + _InterlockedExchange(&_M_exceptionObserved, 1); +#endif + } + + if (_M_winRTException != nullptr) + { + throw _M_winRTException.Get(); + } + std::rethrow_exception(_M_stdException); + } + + // A variable that remembers if this exception was every rethrown into user code (and hence handled by the user). Exceptions that + // are unobserved when the exception holder is destructed will terminate the process. +#if _MSC_VER >= 1800 + Concurrency::details::atomic_long _M_exceptionObserved; +#else + long volatile _M_exceptionObserved; +#endif + + // Either _M_stdException or _M_winRTException is populated based on the type of exception encountered. + std::exception_ptr _M_stdException; + Microsoft::WRL::ComPtr _M_winRTException; + + // Disassembling this value will point to a source instruction right after a call instruction. If the call is to create_task, + // a task constructor or the then method, the task created by that method is the one that encountered this exception. If the call + // is to task_completion_event::set_exception, the set_exception method was the source of the exception. + // DO NOT REMOVE THIS VARIABLE. It is extremely helpful for debugging. +#if _MSC_VER >= 1800 + _TaskCreationCallstack _M_stackTrace; +#else + void* _M_disassembleMe; +#endif + }; + +#ifndef RUNTIMECLASS_Concurrency_winrt_details__AsyncInfoImpl_DEFINED +#define RUNTIMECLASS_Concurrency_winrt_details__AsyncInfoImpl_DEFINED + extern const __declspec(selectany) WCHAR RuntimeClass_Concurrency_winrt_details__AsyncInfoImpl[] = L"Concurrency_winrt.details._AsyncInfoImpl"; +#endif + + /// + /// Base converter class for converting asynchronous interfaces to IAsyncOperation + /// + template + struct _AsyncInfoImpl abstract : public Microsoft::WRL::RuntimeClass< + Microsoft::WRL::RuntimeClassFlags< Microsoft::WRL::RuntimeClassType::WinRt>, + Microsoft::WRL::Implements>> + { + InspectableClass(RuntimeClass_Concurrency_winrt_details__AsyncInfoImpl, BaseTrust) + public: + // The async action, action with progress or operation with progress that this stub forwards to. +#if _MSC_VER >= 1800 + Agile<_AsyncOperationType> _M_asyncInfo; +#else + Microsoft::WRL::ComPtr<_AsyncOperationType> _M_asyncInfo; + // The context in which this async info is valid - may be different from the context where the completion handler runs, + // and may require marshalling before it is used. + _ContextCallback _M_asyncInfoContext; +#endif + + Microsoft::WRL::ComPtr<_CompletionHandlerType> _M_CompletedHandler; + + _AsyncInfoImpl(_AsyncOperationType* _AsyncInfo) : _M_asyncInfo(_AsyncInfo) +#if _MSC_VER < 1800 + , _M_asyncInfoContext(_ContextCallback::_CaptureCurrent()) +#endif + {} + + public: + virtual HRESULT OnStart() { return S_OK; } + virtual void OnCancel() { + Microsoft::WRL::ComPtr pAsyncInfo; + HRESULT hr; +#if _MSC_VER >= 1800 + if (SUCCEEDED(hr = _M_asyncInfo.Get()->QueryInterface(pAsyncInfo.GetAddressOf()))) +#else + if (SUCCEEDED(hr = _M_asyncInfo.As(&pAsyncInfo))) +#endif + pAsyncInfo->Cancel(); + else + throw std::make_exception_ptr(hr); + } + virtual void OnClose() { + Microsoft::WRL::ComPtr pAsyncInfo; + HRESULT hr; +#if _MSC_VER >= 1800 + if (SUCCEEDED(hr = _M_asyncInfo.Get()->QueryInterface(pAsyncInfo.GetAddressOf()))) +#else + if (SUCCEEDED(hr = _M_asyncInfo.As(&pAsyncInfo))) +#endif + pAsyncInfo->Close(); + else + throw std::make_exception_ptr(hr); + } + + virtual STDMETHODIMP get_ErrorCode(HRESULT* errorCode) + { + Microsoft::WRL::ComPtr pAsyncInfo; + HRESULT hr; +#if _MSC_VER >= 1800 + if (SUCCEEDED(hr = _M_asyncInfo.Get()->QueryInterface(pAsyncInfo.GetAddressOf()))) +#else + if (SUCCEEDED(hr = _M_asyncInfo.As(&pAsyncInfo))) +#endif + return pAsyncInfo->get_ErrorCode(errorCode); + return hr; + } + + virtual STDMETHODIMP get_Id(UINT* id) + { + Microsoft::WRL::ComPtr pAsyncInfo; + HRESULT hr; +#if _MSC_VER >= 1800 + if (SUCCEEDED(hr = _M_asyncInfo.Get()->QueryInterface(pAsyncInfo.GetAddressOf()))) +#else + if (SUCCEEDED(hr = _M_asyncInfo.As(&pAsyncInfo))) +#endif + return pAsyncInfo->get_Id(id); + return hr; + } + + virtual STDMETHODIMP get_Status(ABI::Windows::Foundation::AsyncStatus *status) + { + Microsoft::WRL::ComPtr pAsyncInfo; + HRESULT hr; +#if _MSC_VER >= 1800 + if (SUCCEEDED(hr = _M_asyncInfo.Get()->QueryInterface(pAsyncInfo.GetAddressOf()))) +#else + if (SUCCEEDED(hr = _M_asyncInfo.As(&pAsyncInfo))) +#endif + return pAsyncInfo->get_Status(status); + return hr; + } + + virtual STDMETHODIMP GetResults(_Result_abi*) { throw std::runtime_error("derived class must implement"); } + + virtual STDMETHODIMP get_Completed(_CompletionHandlerType** handler) + { + if (!handler) return E_POINTER; + _M_CompletedHandler.CopyTo(handler); + return S_OK; + } + + virtual STDMETHODIMP put_Completed(_CompletionHandlerType* value) + { + _M_CompletedHandler = value; + Microsoft::WRL::ComPtr<_CompletionHandlerType> handler = Microsoft::WRL::Callback<_CompletionHandlerType>([&](_AsyncOperationType*, ABI::Windows::Foundation::AsyncStatus status) -> HRESULT { +#if _MSC_VER < 1800 + // Update the saved _M_asyncInfo with a proxy valid in the current context if required. Some Windows APIs return an IAsyncInfo + // that is only valid for the thread that called the API to retrieve. Since this completion handler can run on any thread, we + // need to ensure that the async info is valid in the current apartment. _M_asyncInfo will be accessed via calls to 'this' inside + // _AsyncInit. + _M_asyncInfo = _ResultContext<_AsyncOperationType*>::_GetValue(_M_asyncInfo.Get(), _M_asyncInfoContext, false); +#endif + return _M_CompletedHandler->Invoke(_M_asyncInfo.Get(), status); + }); +#if _MSC_VER >= 1800 + return _M_asyncInfo.Get()->put_Completed(handler.Get()); +#else + return _M_asyncInfo->put_Completed(handler.Get()); +#endif + } + }; + + extern const __declspec(selectany) WCHAR RuntimeClass_IAsyncOperationToAsyncOperationConverter[] = L"_IAsyncOperationToAsyncOperationConverter"; + + /// + /// Class _IAsyncOperationToAsyncOperationConverter is used to convert an instance of IAsyncOperationWithProgress into IAsyncOperation + /// + template + struct _IAsyncOperationToAsyncOperationConverter : + _AsyncInfoImpl, + ABI::Windows::Foundation::IAsyncOperationCompletedHandler<_Result>, + typename ABI::Windows::Foundation::Internal::GetAbiType*>()))>::type> + { + typedef typename ABI::Windows::Foundation::Internal::GetAbiType*>()))>::type _Result_abi; + + InspectableClass(RuntimeClass_IAsyncOperationToAsyncOperationConverter, BaseTrust) + public: + _IAsyncOperationToAsyncOperationConverter(ABI::Windows::Foundation::IAsyncOperation<_Result>* _Operation) : + _AsyncInfoImpl, + ABI::Windows::Foundation::IAsyncOperationCompletedHandler<_Result>, + _Result_abi>(_Operation) {} + public: + virtual STDMETHODIMP GetResults(_Result_abi* results) override { + if (!results) return E_POINTER; +#if _MSC_VER >= 1800 + return _M_asyncInfo.Get()->GetResults(results); +#else + return _M_asyncInfo->GetResults(results); +#endif + } + }; + + extern const __declspec(selectany) WCHAR RuntimeClass_IAsyncOperationWithProgressToAsyncOperationConverter[] = L"_IAsyncOperationWithProgressToAsyncOperationConverter"; + + /// + /// Class _IAsyncOperationWithProgressToAsyncOperationConverter is used to convert an instance of IAsyncOperationWithProgress into IAsyncOperation + /// + template + struct _IAsyncOperationWithProgressToAsyncOperationConverter : + _AsyncInfoImpl, + ABI::Windows::Foundation::IAsyncOperationWithProgressCompletedHandler<_Result, _Progress>, + typename ABI::Windows::Foundation::Internal::GetAbiType*>()))>::type> + { + typedef typename ABI::Windows::Foundation::Internal::GetAbiType*>()))>::type _Result_abi; + + InspectableClass(RuntimeClass_IAsyncOperationWithProgressToAsyncOperationConverter, BaseTrust) + public: + _IAsyncOperationWithProgressToAsyncOperationConverter(ABI::Windows::Foundation::IAsyncOperationWithProgress<_Result, _Progress>* _Operation) : + _AsyncInfoImpl, + ABI::Windows::Foundation::IAsyncOperationWithProgressCompletedHandler<_Result, _Progress>, + _Result_abi>(_Operation) {} + public: + virtual STDMETHODIMP GetResults(_Result_abi* results) override { + if (!results) return E_POINTER; +#if _MSC_VER >= 1800 + return _M_asyncInfo.Get()->GetResults(results); +#else + return _M_asyncInfo->GetResults(results); +#endif + } + }; + + extern const __declspec(selectany) WCHAR RuntimeClass_IAsyncActionToAsyncOperationConverter[] = L"_IAsyncActionToAsyncOperationConverter"; + + /// + /// Class _IAsyncActionToAsyncOperationConverter is used to convert an instance of IAsyncAction into IAsyncOperation<_Unit_type> + /// + struct _IAsyncActionToAsyncOperationConverter : + _AsyncInfoImpl + { + InspectableClass(RuntimeClass_IAsyncActionToAsyncOperationConverter, BaseTrust) + public: + _IAsyncActionToAsyncOperationConverter(ABI::Windows::Foundation::IAsyncAction* _Operation) : + _AsyncInfoImpl(_Operation) {} + + public: + virtual STDMETHODIMP GetResults(details::_Unit_type* results) + { + if (!results) return E_POINTER; + // Invoke GetResults on the IAsyncAction to allow exceptions to be thrown to higher layers before returning a dummy value. +#if _MSC_VER >= 1800 + HRESULT hr = _M_asyncInfo.Get()->GetResults(); +#else + HRESULT hr = _M_asyncInfo->GetResults(); +#endif + if (SUCCEEDED(hr)) *results = _Unit_type(); + return hr; + } + }; + + extern const __declspec(selectany) WCHAR RuntimeClass_IAsyncActionWithProgressToAsyncOperationConverter[] = L"_IAsyncActionWithProgressToAsyncOperationConverter"; + + /// + /// Class _IAsyncActionWithProgressToAsyncOperationConverter is used to convert an instance of IAsyncActionWithProgress into IAsyncOperation<_Unit_type> + /// + template + struct _IAsyncActionWithProgressToAsyncOperationConverter : + _AsyncInfoImpl, + ABI::Windows::Foundation::IAsyncActionWithProgressCompletedHandler<_Progress>, + _Unit_type> + { + InspectableClass(RuntimeClass_IAsyncActionWithProgressToAsyncOperationConverter, BaseTrust) + public: + _IAsyncActionWithProgressToAsyncOperationConverter(ABI::Windows::Foundation::IAsyncActionWithProgress<_Progress>* _Action) : + _AsyncInfoImpl, + ABI::Windows::Foundation::IAsyncActionWithProgressCompletedHandler<_Progress>, + _Unit_type>(_Action) {} + public: + virtual STDMETHODIMP GetResults(_Unit_type* results) override + { + if (!results) return E_POINTER; + // Invoke GetResults on the IAsyncActionWithProgress to allow exceptions to be thrown before returning a dummy value. +#if _MSC_VER >= 1800 + HRESULT hr = _M_asyncInfo.Get()->GetResults(); +#else + HRESULT hr = _M_asyncInfo->GetResults(); +#endif + if (SUCCEEDED(hr)) *results = _Unit_type(); + return hr; + } + }; +} + +/// +/// The task_continuation_context class allows you to specify where you would like a continuation to be executed. +/// It is only useful to use this class from a Windows Store app. For non-Windows Store apps, the task continuation's +/// execution context is determined by the runtime, and not configurable. +/// +/// +/**/ +class task_continuation_context : public details::_ContextCallback +{ +public: + + /// + /// Creates the default task continuation context. + /// + /// + /// The default continuation context. + /// + /// + /// The default context is used if you don't specifiy a continuation context when you call the then method. In Windows + /// applications for Windows 7 and below, as well as desktop applications on Windows 8 and higher, the runtime determines where + /// task continuations will execute. However, in a Windows Store app, the default continuation context for a continuation on an + /// apartment aware task is the apartment where then is invoked. + /// An apartment aware task is a task that unwraps a Windows Runtime IAsyncInfo interface, or a task that is descended from such + /// a task. Therefore, if you schedule a continuation on an apartment aware task in a Windows Runtime STA, the continuation will execute in + /// that STA. + /// A continuation on a non-apartment aware task will execute in a context the Runtime chooses. + /// + /**/ + static task_continuation_context use_default() + { + // The callback context is created with the context set to CaptureDeferred and resolved when it is used in .then() + return task_continuation_context(true); // sets it to deferred, is resolved in the constructor of _ContinuationTaskHandle + } + + /// + /// Creates a task continuation context which allows the Runtime to choose the execution context for a continuation. + /// + /// + /// A task continuation context that represents an arbitrary location. + /// + /// + /// When this continuation context is used the continuation will execute in a context the runtime chooses even if the antecedent task + /// is apartment aware. + /// use_arbitrary can be used to turn off the default behavior for a continuation on an apartment + /// aware task created in an STA. + /// This method is only available to Windows Store apps. + /// + /**/ + static task_continuation_context use_arbitrary() + { + task_continuation_context _Arbitrary(true); + _Arbitrary._Resolve(false); + return _Arbitrary; + } + + /// + /// Returns a task continuation context object that represents the current execution context. + /// + /// + /// The current execution context. + /// + /// + /// This method captures the caller's Windows Runtime context so that continuations can be executed in the right apartment. + /// The value returned by use_current can be used to indicate to the Runtime that the continuation should execute in + /// the captured context (STA vs MTA) regardless of whether or not the antecedent task is apartment aware. An apartment aware task is + /// a task that unwraps a Windows Runtime IAsyncInfo interface, or a task that is descended from such a task. + /// This method is only available to Windows Store apps. + /// + /**/ + static task_continuation_context use_current() + { + task_continuation_context _Current(true); + _Current._Resolve(true); + return _Current; + } + +private: + + task_continuation_context(bool _DeferCapture = false) : details::_ContextCallback(_DeferCapture) + { + } +}; + +#if _MSC_VER >= 1800 +class task_options; +namespace details +{ + struct _Internal_task_options + { + bool _M_hasPresetCreationCallstack; + _TaskCreationCallstack _M_presetCreationCallstack; + + void _set_creation_callstack(const _TaskCreationCallstack &_callstack) + { + _M_hasPresetCreationCallstack = true; + _M_presetCreationCallstack = _callstack; + } + _Internal_task_options() + { + _M_hasPresetCreationCallstack = false; + } + }; + + inline _Internal_task_options &_get_internal_task_options(task_options &options); + inline const _Internal_task_options &_get_internal_task_options(const task_options &options); +} +/// +/// Represents the allowed options for creating a task +/// +class task_options +{ +public: + + + /// + /// Default list of task creation options + /// + task_options() + : _M_Scheduler(Concurrency::get_ambient_scheduler()), + _M_CancellationToken(Concurrency::cancellation_token::none()), + _M_ContinuationContext(task_continuation_context::use_default()), + _M_HasCancellationToken(false), + _M_HasScheduler(false) + { + } + + /// + /// Task option that specify a cancellation token + /// + task_options(Concurrency::cancellation_token _Token) + : _M_Scheduler(Concurrency::get_ambient_scheduler()), + _M_CancellationToken(_Token), + _M_ContinuationContext(task_continuation_context::use_default()), + _M_HasCancellationToken(true), + _M_HasScheduler(false) + { + } + + /// + /// Task option that specify a continuation context. This is valid only for continuations (then) + /// + task_options(task_continuation_context _ContinuationContext) + : _M_Scheduler(Concurrency::get_ambient_scheduler()), + _M_CancellationToken(Concurrency::cancellation_token::none()), + _M_ContinuationContext(_ContinuationContext), + _M_HasCancellationToken(false), + _M_HasScheduler(false) + { + } + + /// + /// Task option that specify a cancellation token and a continuation context. This is valid only for continuations (then) + /// + task_options(Concurrency::cancellation_token _Token, task_continuation_context _ContinuationContext) + : _M_Scheduler(Concurrency::get_ambient_scheduler()), + _M_CancellationToken(_Token), + _M_ContinuationContext(_ContinuationContext), + _M_HasCancellationToken(false), + _M_HasScheduler(false) + { + } + + /// + /// Task option that specify a scheduler with shared lifetime + /// + template + task_options(std::shared_ptr<_SchedType> _Scheduler) + : _M_Scheduler(std::move(_Scheduler)), + _M_CancellationToken(cancellation_token::none()), + _M_ContinuationContext(task_continuation_context::use_default()), + _M_HasCancellationToken(false), + _M_HasScheduler(true) + { + } + + /// + /// Task option that specify a scheduler reference + /// + task_options(Concurrency::scheduler_interface& _Scheduler) + : _M_Scheduler(&_Scheduler), + _M_CancellationToken(Concurrency::cancellation_token::none()), + _M_ContinuationContext(task_continuation_context::use_default()), + _M_HasCancellationToken(false), + _M_HasScheduler(true) + { + } + + /// + /// Task option that specify a scheduler + /// + task_options(Concurrency::scheduler_ptr _Scheduler) + : _M_Scheduler(std::move(_Scheduler)), + _M_CancellationToken(Concurrency::cancellation_token::none()), + _M_ContinuationContext(task_continuation_context::use_default()), + _M_HasCancellationToken(false), + _M_HasScheduler(true) + { + } + + /// + /// Task option copy constructor + /// + task_options(const task_options& _TaskOptions) + : _M_Scheduler(_TaskOptions.get_scheduler()), + _M_CancellationToken(_TaskOptions.get_cancellation_token()), + _M_ContinuationContext(_TaskOptions.get_continuation_context()), + _M_HasCancellationToken(_TaskOptions.has_cancellation_token()), + _M_HasScheduler(_TaskOptions.has_scheduler()) + { + } + + /// + /// Sets the given token in the options + /// + void set_cancellation_token(Concurrency::cancellation_token _Token) + { + _M_CancellationToken = _Token; + _M_HasCancellationToken = true; + } + + /// + /// Sets the given continuation context in the options + /// + void set_continuation_context(task_continuation_context _ContinuationContext) + { + _M_ContinuationContext = _ContinuationContext; + } + + /// + /// Indicates whether a cancellation token was specified by the user + /// + bool has_cancellation_token() const + { + return _M_HasCancellationToken; + } + + /// + /// Returns the cancellation token + /// + Concurrency::cancellation_token get_cancellation_token() const + { + return _M_CancellationToken; + } + + /// + /// Returns the continuation context + /// + task_continuation_context get_continuation_context() const + { + return _M_ContinuationContext; + } + + /// + /// Indicates whether a scheduler n was specified by the user + /// + bool has_scheduler() const + { + return _M_HasScheduler; + } + + /// + /// Returns the scheduler + /// + Concurrency::scheduler_ptr get_scheduler() const + { + return _M_Scheduler; + } + +private: + + task_options const& operator=(task_options const& _Right); + friend details::_Internal_task_options &details::_get_internal_task_options(task_options &); + friend const details::_Internal_task_options &details::_get_internal_task_options(const task_options &); + + Concurrency::scheduler_ptr _M_Scheduler; + Concurrency::cancellation_token _M_CancellationToken; + task_continuation_context _M_ContinuationContext; + details::_Internal_task_options _M_InternalTaskOptions; + bool _M_HasCancellationToken; + bool _M_HasScheduler; +}; +#endif + +namespace details +{ +#if _MSC_VER >= 1800 + inline _Internal_task_options & _get_internal_task_options(task_options &options) + { + return options._M_InternalTaskOptions; + } + inline const _Internal_task_options & _get_internal_task_options(const task_options &options) + { + return options._M_InternalTaskOptions; + } +#endif + struct _Task_impl_base; + template struct _Task_impl; + + template + struct _Task_ptr + { + typedef std::shared_ptr<_Task_impl<_ReturnType>> _Type; +#if _MSC_VER >= 1800 + static _Type _Make(Concurrency::details::_CancellationTokenState * _Ct, Concurrency::scheduler_ptr _Scheduler_arg) { return std::make_shared<_Task_impl<_ReturnType>>(_Ct, _Scheduler_arg); } +#else + static _Type _Make(Concurrency::details::_CancellationTokenState * _Ct) { return std::make_shared<_Task_impl<_ReturnType>>(_Ct); } +#endif + }; +#if _MSC_VER >= 1800 + typedef Concurrency::details::_TaskCollection_t::_TaskProcHandle_t _UnrealizedChore_t; + typedef _UnrealizedChore_t _UnrealizedChore; + typedef Concurrency::extensibility::scoped_critical_section_t scoped_lock; + typedef Concurrency::extensibility::critical_section_t critical_section; + typedef Concurrency::details::atomic_size_t atomic_size_t; +#else + typedef Concurrency::details::_UnrealizedChore _UnrealizedChore; + typedef Concurrency::critical_section::scoped_lock scoped_lock; + typedef Concurrency::critical_section critical_section; + typedef volatile size_t atomic_size_t; +#endif + typedef std::shared_ptr<_Task_impl_base> _Task_ptr_base; + // The weak-typed base task handler for continuation tasks. + struct _ContinuationTaskHandleBase : _UnrealizedChore + { + _ContinuationTaskHandleBase * _M_next; + task_continuation_context _M_continuationContext; + bool _M_isTaskBasedContinuation; + + // This field gives inlining scheduling policy for current chore. + _TaskInliningMode _M_inliningMode; + + virtual _Task_ptr_base _GetTaskImplBase() const = 0; + + _ContinuationTaskHandleBase() : + _M_next(nullptr), _M_isTaskBasedContinuation(false), _M_continuationContext(task_continuation_context::use_default()), _M_inliningMode(Concurrency::details::_NoInline) + { + } + virtual ~_ContinuationTaskHandleBase() {} + }; +#if _MSC_VER >= 1800 +#if _PPLTASK_ASYNC_LOGGING + // GUID used for identifying causality logs from PPLTask + const ::Platform::Guid _PPLTaskCausalityPlatformID(0x7A76B220, 0xA758, 0x4E6E, 0xB0, 0xE0, 0xD7, 0xC6, 0xD7, 0x4A, 0x88, 0xFE); + + __declspec(selectany) volatile long _isCausalitySupported = 0; + + inline bool _IsCausalitySupported() + { +#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) + if (_isCausalitySupported == 0) + { + long _causality = 1; + OSVERSIONINFOEX _osvi = {}; + _osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); + + // The Causality is supported on Windows version higher than Windows 8 + _osvi.dwMajorVersion = 6; + _osvi.dwMinorVersion = 3; + + DWORDLONG _conditionMask = 0; + VER_SET_CONDITION(_conditionMask, VER_MAJORVERSION, VER_GREATER_EQUAL); + VER_SET_CONDITION(_conditionMask, VER_MINORVERSION, VER_GREATER_EQUAL); + + if (::VerifyVersionInfo(&_osvi, VER_MAJORVERSION | VER_MINORVERSION, _conditionMask)) + { + _causality = 2; + } + + _isCausalitySupported = _causality; + return _causality == 2; + } + + return _isCausalitySupported == 2 ? true : false; +#else + return true; +#endif + } + + // Stateful logger rests inside task_impl_base. + struct _TaskEventLogger + { + _Task_impl_base *_M_task; + bool _M_scheduled; + bool _M_taskPostEventStarted; + + // Log before scheduling task + void _LogScheduleTask(bool _isContinuation) + { + if (details::_IsCausalitySupported()) + { + ::Windows::Foundation::Diagnostics::AsyncCausalityTracer::TraceOperationCreation(::Windows::Foundation::Diagnostics::CausalityTraceLevel::Required, ::Windows::Foundation::Diagnostics::CausalitySource::Library, + _PPLTaskCausalityPlatformID, reinterpret_cast(_M_task), + _isContinuation ? "Concurrency::PPLTask::ScheduleContinuationTask" : "Concurrency::PPLTask::ScheduleTask", 0); + _M_scheduled = true; + } + } + + // It will log the cancel event but not canceled state. _LogTaskCompleted will log the terminal state, which includes cancel state. + void _LogCancelTask() + { + if (details::_IsCausalitySupported()) + { + ::Windows::Foundation::Diagnostics::AsyncCausalityTracer::TraceOperationRelation(::Windows::Foundation::Diagnostics::CausalityTraceLevel::Important, ::Windows::Foundation::Diagnostics::CausalitySource::Library, + _PPLTaskCausalityPlatformID, reinterpret_cast(_M_task), ::Windows::Foundation::Diagnostics::CausalityRelation::Cancel); + + } + } + + // Log when task reaches terminal state. Note: the task can reach a terminal state (by cancellation or exception) without having run + void _LogTaskCompleted(); + + // Log when task body (which includes user lambda and other scheduling code) begin to run + void _LogTaskExecutionStarted() { } + + // Log when task body finish executing + void _LogTaskExecutionCompleted() + { + if (_M_taskPostEventStarted && details::_IsCausalitySupported()) + { + ::Windows::Foundation::Diagnostics::AsyncCausalityTracer::TraceSynchronousWorkCompletion(::Windows::Foundation::Diagnostics::CausalityTraceLevel::Required, ::Windows::Foundation::Diagnostics::CausalitySource::Library, + ::Windows::Foundation::Diagnostics::CausalitySynchronousWork::CompletionNotification); + } + } + + // Log right before user lambda being invoked + void _LogWorkItemStarted() + { + if (details::_IsCausalitySupported()) + { + ::Windows::Foundation::Diagnostics::AsyncCausalityTracer::TraceSynchronousWorkStart(::Windows::Foundation::Diagnostics::CausalityTraceLevel::Required, ::Windows::Foundation::Diagnostics::CausalitySource::Library, + _PPLTaskCausalityPlatformID, reinterpret_cast(_M_task), ::Windows::Foundation::Diagnostics::CausalitySynchronousWork::Execution); + } + } + + // Log right after user lambda being invoked + void _LogWorkItemCompleted() + { + if (details::_IsCausalitySupported()) + { + ::Windows::Foundation::Diagnostics::AsyncCausalityTracer::TraceSynchronousWorkCompletion(::Windows::Foundation::Diagnostics::CausalityTraceLevel::Required, ::Windows::Foundation::Diagnostics::CausalitySource::Library, + ::Windows::Foundation::Diagnostics::CausalitySynchronousWork::Execution); + + ::Windows::Foundation::Diagnostics::AsyncCausalityTracer::TraceSynchronousWorkStart(::Windows::Foundation::Diagnostics::CausalityTraceLevel::Required, ::Windows::Foundation::Diagnostics::CausalitySource::Library, + _PPLTaskCausalityPlatformID, reinterpret_cast(_M_task), ::Windows::Foundation::Diagnostics::CausalitySynchronousWork::CompletionNotification); + _M_taskPostEventStarted = true; + } + } + + _TaskEventLogger(_Task_impl_base *_task) : _M_task(_task) + { + _M_scheduled = false; + _M_taskPostEventStarted = false; + } + }; + + // Exception safe logger for user lambda + struct _TaskWorkItemRAIILogger + { + _TaskEventLogger &_M_logger; + _TaskWorkItemRAIILogger(_TaskEventLogger &_taskHandleLogger) : _M_logger(_taskHandleLogger) + { + _M_logger._LogWorkItemStarted(); + } + + ~_TaskWorkItemRAIILogger() + { + _M_logger._LogWorkItemCompleted(); + } + _TaskWorkItemRAIILogger &operator =(const _TaskWorkItemRAIILogger &); // cannot be assigned + }; + +#else + inline void _LogCancelTask(_Task_impl_base *) {} + struct _TaskEventLogger + { + void _LogScheduleTask(bool) {} + void _LogCancelTask() {} + void _LogWorkItemStarted() {} + void _LogWorkItemCompleted() {} + void _LogTaskExecutionStarted() {} + void _LogTaskExecutionCompleted() {} + void _LogTaskCompleted() {} + _TaskEventLogger(_Task_impl_base *) {} + }; + struct _TaskWorkItemRAIILogger + { + _TaskWorkItemRAIILogger(_TaskEventLogger &) {} + }; +#endif +#endif + /// + /// The _PPLTaskHandle is the strong-typed task handle base. All user task functions need to be wrapped in this task handler + /// to be executable by PPL. By deriving from a different _BaseTaskHandle, it can be used for both initial tasks and continuation tasks. + /// For initial tasks, _PPLTaskHandle will be derived from _UnrealizedChore, and for continuation tasks, it will be derived from + /// _ContinuationTaskHandleBase. The life time of the _PPLTaskHandle object is be managed by runtime if task handle is scheduled. + /// + /// + /// The result type of the _Task_impl. + /// + /// + /// The derived task handle class. The operator () needs to be implemented. + /// + /// + /// The base class from which _PPLTaskHandle should be derived. This is either _UnrealizedChore or _ContinuationTaskHandleBase. + /// + template + struct _PPLTaskHandle : _BaseTaskHandle + { + _PPLTaskHandle(const typename _Task_ptr<_ReturnType>::_Type & _PTask) : _M_pTask(_PTask) + { +#if _MSC_VER < 1800 + m_pFunction = reinterpret_cast (&_UnrealizedChore::_InvokeBridge<_PPLTaskHandle>); + _SetRuntimeOwnsLifetime(true); +#endif + } + virtual ~_PPLTaskHandle() { +#if _MSC_VER >= 1800 + // Here is the sink of all task completion code paths + _M_pTask->_M_taskEventLogger._LogTaskCompleted(); +#endif + } +#if _MSC_VER >= 1800 + virtual void invoke() const +#else + void operator()() const +#endif + { + // All exceptions should be rethrown to finish cleanup of the task collection. They will be caught and handled + // by the runtime. + _CONCRT_ASSERT(_M_pTask != nullptr); + if (!_M_pTask->_TransitionedToStarted()) { +#if _MSC_VER >= 1800 + static_cast(this)->_SyncCancelAndPropagateException(); +#endif + return; + } +#if _MSC_VER >= 1800 + _M_pTask->_M_taskEventLogger._LogTaskExecutionStarted(); +#endif + try + { + // All derived task handle must implement this contract function. + static_cast(this)->_Perform(); + } + catch (const Concurrency::task_canceled &) + { + _M_pTask->_Cancel(true); +#if _MSC_VER < 1800 + throw; +#endif + } + catch (const Concurrency::details::_Interruption_exception &) + { + _M_pTask->_Cancel(true); +#if _MSC_VER < 1800 + throw; +#endif + } + catch (IRestrictedErrorInfo*& _E) + { + _M_pTask->_CancelWithException(_E); +#if _MSC_VER < 1800 + throw; +#endif + } + catch (...) + { + _M_pTask->_CancelWithException(std::current_exception()); +#if _MSC_VER < 1800 + throw; +#endif + } +#if _MSC_VER >= 1800 + _M_pTask->_M_taskEventLogger._LogTaskExecutionCompleted(); +#endif + } + + // Cast _M_pTask pointer to "type-less" _Task_impl_base pointer, which can be used in _ContinuationTaskHandleBase. + // The return value should be automatically optimized by R-value ref. + _Task_ptr_base _GetTaskImplBase() const + { + return _M_pTask; + } + + typename _Task_ptr<_ReturnType>::_Type _M_pTask; + + private: + _PPLTaskHandle const & operator=(_PPLTaskHandle const&); // no assignment operator + }; + + /// + /// The base implementation of a first-class task. This class contains all the non-type specific + /// implementation details of the task. + /// + /**/ + struct _Task_impl_base + { + enum _TaskInternalState + { + // Tracks the state of the task, rather than the task collection on which the task is scheduled + _Created, + _Started, + _PendingCancel, + _Completed, + _Canceled + }; +#if _MSC_VER >= 1800 + _Task_impl_base(Concurrency::details::_CancellationTokenState * _PTokenState, Concurrency::scheduler_ptr _Scheduler_arg) + : _M_TaskState(_Created), + _M_fFromAsync(false), _M_fUnwrappedTask(false), + _M_pRegistration(nullptr), _M_Continuations(nullptr), _M_TaskCollection(_Scheduler_arg), + _M_taskEventLogger(this) +#else + _Task_impl_base(Concurrency::details::_CancellationTokenState * _PTokenState) : _M_TaskState(_Created), + _M_fFromAsync(false), _M_fRuntimeAggregate(false), _M_fUnwrappedTask(false), + _M_pRegistration(nullptr), _M_Continuations(nullptr), _M_pTaskCollection(nullptr), + _M_pTaskCreationAddressHint(nullptr) +#endif + { + // Set cancelation token + _M_pTokenState = _PTokenState; + _CONCRT_ASSERT(_M_pTokenState != nullptr); + if (_M_pTokenState != Concurrency::details::_CancellationTokenState::_None()) + _M_pTokenState->_Reference(); + + } + + virtual ~_Task_impl_base() + { + _CONCRT_ASSERT(_M_pTokenState != nullptr); + if (_M_pTokenState != Concurrency::details::_CancellationTokenState::_None()) + { + _M_pTokenState->_Release(); + } +#if _MSC_VER < 1800 + if (_M_pTaskCollection != nullptr) + { + _M_pTaskCollection->_Release(); + _M_pTaskCollection = nullptr; + } +#endif + } + + task_status _Wait() + { + bool _DoWait = true; + + if (_IsNonBlockingThread()) + { + // In order to prevent Windows Runtime STA threads from blocking the UI, calling task.wait() task.get() is illegal + // if task has not been completed. + if (!_IsCompleted() && !_IsCanceled()) + { + throw Concurrency::invalid_operation("Illegal to wait on a task in a Windows Runtime STA"); + } + else + { + // Task Continuations are 'scheduled' *inside* the chore that is executing on the ancestors's task group. If a continuation + // needs to be marshalled to a different apartment, instead of scheduling, we make a synchronous cross apartment COM + // call to execute the continuation. If it then happens to do something which waits on the ancestor (say it calls .get(), which + // task based continuations are wont to do), waiting on the task group results in on the chore that is making this + // synchronous callback, which causes a deadlock. To avoid this, we test the state ancestor's event , and we will NOT wait on + // if it has finished execution (which means now we are on the inline synchronous callback). + _DoWait = false; + } + } + if (_DoWait) + { +#if _MSC_VER < 1800 + // Wait for the task to be actually scheduled, otherwise the underlying task collection + // might not be created yet. If we don't wait, we will miss the chance to inline this task. + _M_Scheduled.wait(); + + + // A PPL task created by a task_completion_event does not have an underlying TaskCollection. For + // These tasks, a call to wait should wait for the event to be set. The TaskCollection must either + // be nullptr or allocated (the setting of _M_Scheduled) ensures that. +#endif + // If this task was created from a Windows Runtime async operation, do not attempt to inline it. The + // async operation will take place on a thread in the appropriate apartment Simply wait for the completed + // event to be set. +#if _MSC_VER >= 1800 + if (_M_fFromAsync) +#else + if ((_M_pTaskCollection == nullptr) || _M_fFromAsync) +#endif + { +#if _MSC_VER >= 1800 + _M_TaskCollection._Wait(); +#else + _M_Completed.wait(); +#endif + } + else + { + // Wait on the task collection to complete. The task collection is guaranteed to still be + // valid since the task must be still within scope so that the _Task_impl_base destructor + // has not yet been called. This call to _Wait potentially inlines execution of work. + try + { + // Invoking wait on a task collection resets the state of the task collection. This means that + // if the task collection itself were canceled, or had encountered an exception, only the first + // call to wait will receive this status. However, both cancellation and exceptions flowing through + // tasks set state in the task impl itself. + + // When it returns cancelled, either work chore or the cancel thread should already have set task's state + // properly -- cancelled state or completed state (because there was no interruption point). + // For tasks with unwrapped tasks, we should not change the state of current task, since the unwrapped task are still running. +#if _MSC_VER >= 1800 + _M_TaskCollection._RunAndWait(); +#else + _M_pTaskCollection->_RunAndWait(); +#endif + } + catch (Concurrency::details::_Interruption_exception&) + { + // The _TaskCollection will never be an interruption point since it has a none token. + _CONCRT_ASSERT(false); + } + catch (Concurrency::task_canceled&) + { + // task_canceled is a special exception thrown by cancel_current_task. The spec states that cancel_current_task + // must be called from code that is executed within the task (throwing it from parallel work created by and waited + // upon by the task is acceptable). We can safely assume that the task wrapper _PPLTaskHandle::operator() has seen + // the exception and canceled the task. Swallow the exception here. + _CONCRT_ASSERT(_IsCanceled()); + } + catch (IRestrictedErrorInfo*& _E) + { + // Its possible the task body hasn't seen the exception, if so we need to cancel with exception here. + if(!_HasUserException()) + { + _CancelWithException(_E); + } + // Rethrow will mark the exception as observed. + _M_exceptionHolder->_RethrowUserException(); + } + catch (...) + { + // Its possible the task body hasn't seen the exception, if so we need to cancel with exception here. + if (!_HasUserException()) + { + _CancelWithException(std::current_exception()); + } + // Rethrow will mark the exception as observed. + _M_exceptionHolder->_RethrowUserException(); + } + + // If the lambda body for this task (executed or waited upon in _RunAndWait above) happened to return a task + // which is to be unwrapped and plumbed to the output of this task, we must not only wait on the lambda body, we must + // wait on the **INNER** body. It is in theory possible that we could inline such if we plumb a series of things through; + // however, this takes the tact of simply waiting upon the completion signal. + if (_M_fUnwrappedTask) + { +#if _MSC_VER >= 1800 + _M_TaskCollection._Wait(); +#else + _M_Completed.wait(); +#endif + } + } + } + + if (_HasUserException()) + { + _M_exceptionHolder->_RethrowUserException(); + } + else if (_IsCanceled()) + { + return Concurrency::canceled; + } + _CONCRT_ASSERT(_IsCompleted()); + return Concurrency::completed; + } + /// + /// Requests cancellation on the task and schedules continuations if the task can be transitioned to a terminal state. + /// + /// + /// Set to true if the cancel takes place as a result of the task body encountering an exception, or because an ancestor or task_completion_event the task + /// was registered with were canceled with an exception. A synchronous cancel is one that assures the task could not be running on a different thread at + /// the time the cancellation is in progress. An asynchronous cancel is one where the thread performing the cancel has no control over the thread that could + /// be executing the task, that is the task could execute concurrently while the cancellation is in progress. + /// + /// + /// Whether an exception other than the internal runtime cancellation exceptions caused this cancellation. + /// + /// + /// Whether this exception came from an ancestor task or a task_completion_event as opposed to an exception that was encountered by the task itself. Only valid when + /// _UserException is set to true. + /// + /// + /// The exception holder that represents the exception. Only valid when _UserException is set to true. + /// + virtual bool _CancelAndRunContinuations(bool _SynchronousCancel, bool _UserException, bool _PropagatedFromAncestor, const std::shared_ptr<_ExceptionHolder>& _ExHolder) = 0; + + bool _Cancel(bool _SynchronousCancel) + { + // Send in a dummy value for exception. It is not used when the first parameter is false. + return _CancelAndRunContinuations(_SynchronousCancel, false, false, _M_exceptionHolder); + } + + bool _CancelWithExceptionHolder(const std::shared_ptr<_ExceptionHolder>& _ExHolder, bool _PropagatedFromAncestor) + { + // This task was canceled because an ancestor task encountered an exception. + return _CancelAndRunContinuations(true, true, _PropagatedFromAncestor, _ExHolder); + } + + bool _CancelWithException(IRestrictedErrorInfo*& _Exception) + { + // This task was canceled because the task body encountered an exception. + _CONCRT_ASSERT(!_HasUserException()); +#if _MSC_VER >= 1800 + return _CancelAndRunContinuations(true, true, false, std::make_shared<_ExceptionHolder>(_Exception, _GetTaskCreationCallstack())); +#else + return _CancelAndRunContinuations(true, true, false, std::make_shared<_ExceptionHolder>(_Exception, _GetTaskCreationAddressHint())); +#endif + } + bool _CancelWithException(const std::exception_ptr& _Exception) + { + // This task was canceled because the task body encountered an exception. + _CONCRT_ASSERT(!_HasUserException()); +#if _MSC_VER >= 1800 + return _CancelAndRunContinuations(true, true, false, std::make_shared<_ExceptionHolder>(_Exception, _GetTaskCreationCallstack())); +#else + return _CancelAndRunContinuations(true, true, false, std::make_shared<_ExceptionHolder>(_Exception, _GetTaskCreationAddressHint())); +#endif + } + +#if _MSC_VER >= 1800 + void _RegisterCancellation(std::weak_ptr<_Task_impl_base> _WeakPtr) +#else + void _RegisterCancellation() +#endif + { + _CONCRT_ASSERT(Concurrency::details::_CancellationTokenState::_IsValid(_M_pTokenState)); +#if _MSC_VER >= 1800 + auto _CancellationCallback = [_WeakPtr](){ + // Taking ownership of the task prevents dead lock during destruction + // if the destructor waits for the cancellations to be finished + auto _task = _WeakPtr.lock(); + if (_task != nullptr) + _task->_Cancel(false); + }; + + _M_pRegistration = new Concurrency::details::_CancellationTokenCallback(_CancellationCallback); + _M_pTokenState->_RegisterCallback(_M_pRegistration); +#else + _M_pRegistration = _M_pTokenState->_RegisterCallback(reinterpret_cast(&_CancelViaToken), (_Task_impl_base *)this); +#endif + } + + void _DeregisterCancellation() + { + if (_M_pRegistration != nullptr) + { + _M_pTokenState->_DeregisterCallback(_M_pRegistration); + _M_pRegistration->_Release(); + _M_pRegistration = nullptr; + } + } +#if _MSC_VER < 1800 + static void _CancelViaToken(_Task_impl_base *_PImpl) + { + _PImpl->_Cancel(false); + } +#endif + bool _IsCreated() + { + return (_M_TaskState == _Created); + } + + bool _IsStarted() + { + return (_M_TaskState == _Started); + } + + bool _IsPendingCancel() + { + return (_M_TaskState == _PendingCancel); + } + + bool _IsCompleted() + { + return (_M_TaskState == _Completed); + } + + bool _IsCanceled() + { + return (_M_TaskState == _Canceled); + } + + bool _HasUserException() + { + return static_cast(_M_exceptionHolder); + } +#if _MSC_VER < 1800 + void _SetScheduledEvent() + { + _M_Scheduled.set(); + } +#endif + const std::shared_ptr<_ExceptionHolder>& _GetExceptionHolder() + { + _CONCRT_ASSERT(_HasUserException()); + return _M_exceptionHolder; + } + + bool _IsApartmentAware() + { + return _M_fFromAsync; + } + + void _SetAsync(bool _Async = true) + { + _M_fFromAsync = _Async; + } +#if _MSC_VER >= 1800 + _TaskCreationCallstack _GetTaskCreationCallstack() + { + return _M_pTaskCreationCallstack; + } + + void _SetTaskCreationCallstack(const _TaskCreationCallstack &_Callstack) + { + _M_pTaskCreationCallstack = _Callstack; + } +#else + void* _GetTaskCreationAddressHint() + { + return _M_pTaskCreationAddressHint; + } + + void _SetTaskCreationAddressHint(void* _AddressHint) + { + _M_pTaskCreationAddressHint = _AddressHint; + } +#endif + /// + /// Helper function to schedule the task on the Task Collection. + /// + /// + /// The task chore handle that need to be executed. + /// + /// + /// The inlining scheduling policy for current _PTaskHandle. + /// + void _ScheduleTask(_UnrealizedChore * _PTaskHandle, _TaskInliningMode _InliningMode) + { +#if _MSC_VER < 1800 + // Construct the task collection; We use none token to provent it becoming interruption point. + _M_pTaskCollection = Concurrency::details::_AsyncTaskCollection::_NewCollection(Concurrency::details::_CancellationTokenState::_None()); + // _M_pTaskCollection->_ScheduleWithAutoInline will schedule the chore onto AsyncTaskCollection with automatic inlining, in a way that honors cancellation etc. +#endif + try + { +#if _MSC_VER >= 1800 + _M_TaskCollection._ScheduleTask(_PTaskHandle, _InliningMode); +#else + // Do not need to check its returning state, more details please refer to _Wait method. + _M_pTaskCollection->_ScheduleWithAutoInline(_PTaskHandle, _InliningMode); +#endif + } + catch (const Concurrency::task_canceled &) + { + // task_canceled is a special exception thrown by cancel_current_task. The spec states that cancel_current_task + // must be called from code that is executed within the task (throwing it from parallel work created by and waited + // upon by the task is acceptable). We can safely assume that the task wrapper _PPLTaskHandle::operator() has seen + // the exception and canceled the task. Swallow the exception here. + _CONCRT_ASSERT(_IsCanceled()); + } + catch (const Concurrency::details::_Interruption_exception &) + { + // The _TaskCollection will never be an interruption point since it has a none token. + _CONCRT_ASSERT(false); + } + catch (...) + { + // This exception could only have come from within the chore body. It should've been caught + // and the task should be canceled with exception. Swallow the exception here. + _CONCRT_ASSERT(_HasUserException()); + } +#if _MSC_VER < 1800 + // Set the event in case anyone is waiting to notify that this task has been scheduled. In the case where we + // execute the chore inline, the event should be set after the chore has executed, to prevent a different thread + // performing a wait on the task from waiting on the task collection before the chore is actually added to it, + // and thereby returning from the wait() before the chore has executed. + _SetScheduledEvent(); +#endif + } + + /// + /// Function executes a continuation. This function is recorded by a parent task implementation + /// when a continuation is created in order to execute later. + /// + /// + /// The continuation task chore handle that need to be executed. + /// + /**/ + void _RunContinuation(_ContinuationTaskHandleBase * _PTaskHandle) + { + _Task_ptr_base _ImplBase = _PTaskHandle->_GetTaskImplBase(); + if (_IsCanceled() && !_PTaskHandle->_M_isTaskBasedContinuation) + { + if (_HasUserException()) + { + // If the ancestor encountered an exception, transfer the exception to the continuation + // This traverses down the tree to propagate the exception. + _ImplBase->_CancelWithExceptionHolder(_GetExceptionHolder(), true); + } + else + { + // If the ancestor was canceled, then your own execution should be canceled. + // This traverses down the tree to cancel it. + _ImplBase->_Cancel(true); + } + } + else + { + // This can only run when the ancestor has completed or it's a task based continuation that fires when a task is canceled + // (with or without a user exception). + _CONCRT_ASSERT(_IsCompleted() || _PTaskHandle->_M_isTaskBasedContinuation); + +#if _MSC_VER >= 1800 + _CONCRT_ASSERT(!_ImplBase->_IsCanceled()); + return _ImplBase->_ScheduleContinuationTask(_PTaskHandle); +#else + // If it has been canceled here (before starting), do nothing. The guy firing cancel will do the clean up. + if (!_ImplBase->_IsCanceled()) + { + return _ImplBase->_ScheduleContinuationTask(_PTaskHandle); + } +#endif + } + + // If the handle is not scheduled, we need to manually delete it. + delete _PTaskHandle; + } + + // Schedule a continuation to run + void _ScheduleContinuationTask(_ContinuationTaskHandleBase * _PTaskHandle) + { +#if _MSC_VER >= 1800 + _M_taskEventLogger._LogScheduleTask(true); +#endif + // Ensure that the continuation runs in proper context (this might be on a Concurrency Runtime thread or in a different Windows Runtime apartment) + if (_PTaskHandle->_M_continuationContext._HasCapturedContext()) + { + // For those continuations need to be scheduled inside captured context, we will try to apply automatic inlining to their inline modes, + // if they haven't been specified as _ForceInline yet. This change will encourage those continuations to be executed inline so that reduce + // the cost of marshaling. + // For normal continuations we won't do any change here, and their inline policies are completely decided by ._ThenImpl method. + if (_PTaskHandle->_M_inliningMode != Concurrency::details::_ForceInline) + { + _PTaskHandle->_M_inliningMode = Concurrency::details::_DefaultAutoInline; + } + details::_ScheduleFuncWithAutoInline([_PTaskHandle]() -> HRESULT { + // Note that we cannot directly capture "this" pointer, instead, we should use _TaskImplPtr, a shared_ptr to the _Task_impl_base. + // Because "this" pointer will be invalid as soon as _PTaskHandle get deleted. _PTaskHandle will be deleted after being scheduled. + auto _TaskImplPtr = _PTaskHandle->_GetTaskImplBase(); + if (details::_ContextCallback::_CaptureCurrent() == _PTaskHandle->_M_continuationContext) + { + _TaskImplPtr->_ScheduleTask(_PTaskHandle, Concurrency::details::_ForceInline); + } + else + { + // + // It's entirely possible that the attempt to marshal the call into a differing context will fail. In this case, we need to handle + // the exception and mark the continuation as canceled with the appropriate exception. There is one slight hitch to this: + // + // NOTE: COM's legacy behavior is to swallow SEH exceptions and marshal them back as HRESULTS. This will in effect turn an SEH into + // a C++ exception that gets tagged on the task. One unfortunate result of this is that various pieces of the task infrastructure will + // not be in a valid state after this in /EHsc (due to the lack of destructors running, etc...). + // + try + { + // Dev10 compiler needs this! + auto _PTaskHandle1 = _PTaskHandle; + _PTaskHandle->_M_continuationContext._CallInContext([_PTaskHandle1, _TaskImplPtr]() -> HRESULT { + _TaskImplPtr->_ScheduleTask(_PTaskHandle1, Concurrency::details::_ForceInline); + return S_OK; + }); + } + catch (IRestrictedErrorInfo*& _E) + { + _TaskImplPtr->_CancelWithException(_E); + } + catch (...) + { + _TaskImplPtr->_CancelWithException(std::current_exception()); + } + } + return S_OK; + }, _PTaskHandle->_M_inliningMode); + } + else + { + _ScheduleTask(_PTaskHandle, _PTaskHandle->_M_inliningMode); + } + } + + /// + /// Schedule the actual continuation. This will either schedule the function on the continuation task's implementation + /// if the task has completed or append it to a list of functions to execute when the task actually does complete. + /// + /// + /// The input type of the task. + /// + /// + /// The output type of the task. + /// + /**/ + void _ScheduleContinuation(_ContinuationTaskHandleBase * _PTaskHandle) + { + enum { _Nothing, _Schedule, _Cancel, _CancelWithException } _Do = _Nothing; + + // If the task has canceled, cancel the continuation. If the task has completed, execute the continuation right away. + // Otherwise, add it to the list of pending continuations + { + scoped_lock _LockHolder(_M_ContinuationsCritSec); + if (_IsCompleted() || (_IsCanceled() && _PTaskHandle->_M_isTaskBasedContinuation)) + { + _Do = _Schedule; + } + else if (_IsCanceled()) + { + if (_HasUserException()) + { + _Do = _CancelWithException; + } + else + { + _Do = _Cancel; + } + } + else + { + // chain itself on the continuation chain. + _PTaskHandle->_M_next = _M_Continuations; + _M_Continuations = _PTaskHandle; + } + } + + // Cancellation and execution of continuations should be performed after releasing the lock. Continuations off of + // async tasks may execute inline. + switch (_Do) + { + case _Schedule: + { + _PTaskHandle->_GetTaskImplBase()->_ScheduleContinuationTask(_PTaskHandle); + break; + } + case _Cancel: + { + // If the ancestor was canceled, then your own execution should be canceled. + // This traverses down the tree to cancel it. + _PTaskHandle->_GetTaskImplBase()->_Cancel(true); + + delete _PTaskHandle; + break; + } + case _CancelWithException: + { + // If the ancestor encountered an exception, transfer the exception to the continuation + // This traverses down the tree to propagate the exception. + _PTaskHandle->_GetTaskImplBase()->_CancelWithExceptionHolder(_GetExceptionHolder(), true); + + delete _PTaskHandle; + break; + } + case _Nothing: + default: + // In this case, we have inserted continuation to continuation chain, + // nothing more need to be done, just leave. + break; + } + } + + void _RunTaskContinuations() + { + // The link list can no longer be modified at this point, + // since all following up continuations will be scheduled by themselves. + _ContinuationList _Cur = _M_Continuations, _Next; + _M_Continuations = nullptr; + while (_Cur) + { + // Current node might be deleted after running, + // so we must fetch the next first. + _Next = _Cur->_M_next; + _RunContinuation(_Cur); + _Cur = _Next; + } + } + static bool _IsNonBlockingThread() + { + APTTYPE _AptType; + APTTYPEQUALIFIER _AptTypeQualifier; + + HRESULT hr = CoGetApartmentType(&_AptType, &_AptTypeQualifier); + // + // If it failed, it's not a Windows Runtime/COM initialized thread. This is not a failure. + // + if (SUCCEEDED(hr)) + { + switch (_AptType) + { + case APTTYPE_STA: + case APTTYPE_MAINSTA: + return true; + break; + case APTTYPE_NA: + switch (_AptTypeQualifier) + { + // A thread executing in a neutral apartment is either STA or MTA. To find out if this thread is allowed + // to wait, we check the app qualifier. If it is an STA thread executing in a neutral apartment, waiting + // is illegal, because the thread is responsible for pumping messages and waiting on a task could take the + // thread out of circulation for a while. + case APTTYPEQUALIFIER_NA_ON_STA: + case APTTYPEQUALIFIER_NA_ON_MAINSTA: + return true; + break; + } + break; + } + } +#if _UITHREADCTXT_SUPPORT + // This method is used to throw an exepection in _Wait() if called within STA. We + // want the same behavior if _Wait is called on the UI thread. + if (SUCCEEDED(CaptureUiThreadContext(nullptr))) + { + return true; + } +#endif // _UITHREADCTXT_SUPPORT + + return false; + } + + template + static void _AsyncInit(const typename _Task_ptr<_ReturnType>::_Type & _OuterTask, + _AsyncInfoImpl<_OpType, _CompHandlerType, _ResultType>* _AsyncOp) + { + typedef typename ABI::Windows::Foundation::Internal::GetAbiType()))>::type _Result_abi; + // This method is invoked either when a task is created from an existing async operation or + // when a lambda that creates an async operation executes. + + // If the outer task is pending cancel, cancel the async operation before setting the completed handler. The COM reference on + // the IAsyncInfo object will be released when all *references to the operation go out of scope. + + // This assertion uses the existence of taskcollection to determine if the task was created from an event. + // That is no longer valid as even tasks created from a user lambda could have no underlying taskcollection + // when a custom scheduler is used. +#if _MSC_VER < 1800 + _CONCRT_ASSERT(((_OuterTask->_M_pTaskCollection == nullptr) || _OuterTask->_M_fUnwrappedTask) && !_OuterTask->_IsCanceled()); +#endif + + // Pass the shared_ptr by value into the lambda instead of using 'this'. + + _AsyncOp->put_Completed(Microsoft::WRL::Callback<_CompHandlerType>( + [_OuterTask, _AsyncOp](_OpType* _Operation, ABI::Windows::Foundation::AsyncStatus _Status) mutable -> HRESULT + { + HRESULT hr = S_OK; + if (_Status == ABI::Windows::Foundation::AsyncStatus::Canceled) + { + _OuterTask->_Cancel(true); + } + else if (_Status == ABI::Windows::Foundation::AsyncStatus::Error) + { + HRESULT _hr; + Microsoft::WRL::ComPtr pAsyncInfo; + if (SUCCEEDED(hr = _Operation->QueryInterface(pAsyncInfo.GetAddressOf())) && SUCCEEDED(hr = pAsyncInfo->get_ErrorCode(&_hr))) + _OuterTask->_CancelWithException(std::make_exception_ptr(_hr)); + } + else + { + _CONCRT_ASSERT(_Status == ABI::Windows::Foundation::AsyncStatus::Completed); + _NormalizeVoidToUnitType<_Result_abi>::_Type results; + if (SUCCEEDED(hr = _AsyncOp->GetResults(&results))) + _OuterTask->_FinalizeAndRunContinuations(results); + } + // Take away this shared pointers reference on the task instead of waiting for the delegate to be released. It could + // be released on a different thread after a delay, and not releasing the reference here could cause the tasks to hold + // on to resources longer than they should. As an example, without this reset, writing to a file followed by reading from + // it using the Windows Runtime Async APIs causes a sharing violation. + // Using const_cast is the workaround for failed mutable keywords + const_cast<_Task_ptr<_ReturnType>::_Type &>(_OuterTask).reset(); + return hr; + }).Get()); + _OuterTask->_SetUnwrappedAsyncOp(_AsyncOp); + } + template + static void _AsyncInit(const typename _Task_ptr<_ReturnType>::_Type& _OuterTask, const task<_InternalReturnType> & _UnwrappedTask) + { + _CONCRT_ASSERT(_OuterTask->_M_fUnwrappedTask && !_OuterTask->_IsCanceled()); + // + // We must ensure that continuations off _OuterTask (especially exception handling ones) continue to function in the + // presence of an exception flowing out of the inner task _UnwrappedTask. This requires an exception handling continuation + // off the inner task which does the appropriate funnelling to the outer one. We use _Then instead of then to prevent + // the exception from being marked as observed by our internal continuation. This continuation must be scheduled regardless + // of whether or not the _OuterTask task is canceled. + // + _UnwrappedTask._Then([_OuterTask](task<_InternalReturnType> _AncestorTask) -> HRESULT { + + if (_AncestorTask._GetImpl()->_IsCompleted()) + { + _OuterTask->_FinalizeAndRunContinuations(_AncestorTask._GetImpl()->_GetResult()); + } + else + { + _CONCRT_ASSERT(_AncestorTask._GetImpl()->_IsCanceled()); + if (_AncestorTask._GetImpl()->_HasUserException()) + { + // Set _PropagatedFromAncestor to false, since _AncestorTask is not an ancestor of _UnwrappedTask. + // Instead, it is the enclosing task. + _OuterTask->_CancelWithExceptionHolder(_AncestorTask._GetImpl()->_GetExceptionHolder(), false); + } + else + { + _OuterTask->_Cancel(true); + } + } + return S_OK; +#if _MSC_VER >= 1800 + }, nullptr, Concurrency::details::_DefaultAutoInline); +#else + }, nullptr, false, Concurrency::details::_DefaultAutoInline); +#endif + } + +#if _MSC_VER >= 1800 + Concurrency::scheduler_ptr _GetScheduler() const + { + return _M_TaskCollection._GetScheduler(); + } +#else + Concurrency::event _M_Completed; + Concurrency::event _M_Scheduled; +#endif + + // Tracks the internal state of the task + volatile _TaskInternalState _M_TaskState; + // Set to true either if the ancestor task had the flag set to true, or if the lambda that does the work of this task returns an + // async operation or async action that is unwrapped by the runtime. + bool _M_fFromAsync; +#if _MSC_VER < 1800 + // Set to true if we need to marshal the inner parts of an aggregate type like std::vector or std::pair. We only marshal + // the contained T^s if we create the vector or pair, such as on a when_any or a when_all operation. + bool _M_fRuntimeAggregate; +#endif + // Set to true when a continuation unwraps a task or async operation. + bool _M_fUnwrappedTask; + + // An exception thrown by the task body is captured in an exception holder and it is shared with all value based continuations rooted at the task. + // The exception is 'observed' if the user invokes get()/wait() on any of the tasks that are sharing this exception holder. If the exception + // is not observed by the time the internal object owned by the shared pointer destructs, the process will fail fast. + std::shared_ptr<_ExceptionHolder> _M_exceptionHolder; + + typedef _ContinuationTaskHandleBase * _ContinuationList; + + critical_section _M_ContinuationsCritSec; + _ContinuationList _M_Continuations; + + // The cancellation token state. + Concurrency::details::_CancellationTokenState * _M_pTokenState; + + // The registration on the token. + Concurrency::details::_CancellationTokenRegistration * _M_pRegistration; + + // The async task collection wrapper +#if _MSC_VER >= 1800 + Concurrency::details::_TaskCollection_t _M_TaskCollection; + + // Callstack for function call (constructor or .then) that created this task impl. + _TaskCreationCallstack _M_pTaskCreationCallstack; + + _TaskEventLogger _M_taskEventLogger; +#else + Concurrency::details::_AsyncTaskCollection * _M_pTaskCollection; + + // Points to the source code instruction right after the function call (constructor or .then) that created this task impl. + void* _M_pTaskCreationAddressHint; +#endif + + private: + // Must not be copied by value: + _Task_impl_base(const _Task_impl_base&); + _Task_impl_base const & operator=(_Task_impl_base const&); + }; + +#if _MSC_VER >= 1800 +#if _PPLTASK_ASYNC_LOGGING + inline void _TaskEventLogger::_LogTaskCompleted() + { + if (_M_scheduled) + { + ::Windows::Foundation::AsyncStatus _State; + if (_M_task->_IsCompleted()) + _State = ::Windows::Foundation::AsyncStatus::Completed; + else if (_M_task->_HasUserException()) + _State = ::Windows::Foundation::AsyncStatus::Error; + else + _State = ::Windows::Foundation::AsyncStatus::Canceled; + + if (details::_IsCausalitySupported()) + { + ::Windows::Foundation::Diagnostics::AsyncCausalityTracer::TraceOperationCompletion(::Windows::Foundation::Diagnostics::CausalityTraceLevel::Required, ::Windows::Foundation::Diagnostics::CausalitySource::Library, + _PPLTaskCausalityPlatformID, reinterpret_cast(_M_task), _State); + } + } + } +#endif +#endif + + template + struct _Task_impl : public _Task_impl_base + { + typedef ABI::Windows::Foundation::IAsyncInfo _AsyncOperationType; +#if _MSC_VER >= 1800 + _Task_impl(Concurrency::details::_CancellationTokenState * _Ct, Concurrency::scheduler_ptr _Scheduler_arg) + : _Task_impl_base(_Ct, _Scheduler_arg) +#else + _Task_impl(Concurrency::details::_CancellationTokenState * _Ct) : _Task_impl_base(_Ct) +#endif + { + _M_unwrapped_async_op = nullptr; + } + virtual ~_Task_impl() + { + // We must invoke _DeregisterCancellation in the derived class destructor. Calling it in the base class destructor could cause + // a partially initialized _Task_impl to be in the list of registrations for a cancellation token. + _DeregisterCancellation(); + } + virtual bool _CancelAndRunContinuations(bool _SynchronousCancel, bool _UserException, bool _PropagatedFromAncestor, const std::shared_ptr<_ExceptionHolder> & _ExceptionHolder) + { + enum { _Nothing, _RunContinuations, _Cancel } _Do = _Nothing; + { + scoped_lock _LockHolder(_M_ContinuationsCritSec); + if (_UserException) + { + _CONCRT_ASSERT(_SynchronousCancel && !_IsCompleted()); + // If the state is _Canceled, the exception has to be coming from an ancestor. + _CONCRT_ASSERT(!_IsCanceled() || _PropagatedFromAncestor); +#if _MSC_VER < 1800 + // If the state is _Started or _PendingCancel, the exception cannot be coming from an ancestor. + _CONCRT_ASSERT((!_IsStarted() && !_IsPendingCancel()) || !_PropagatedFromAncestor); +#endif + // We should not be canceled with an exception more than once. + _CONCRT_ASSERT(!_HasUserException()); + + if (_M_TaskState == _Canceled) + { + // If the task has finished cancelling there should not be any continuation records in the array. + return false; + } + else + { + _CONCRT_ASSERT(_M_TaskState != _Completed); + _M_exceptionHolder = _ExceptionHolder; + } + } + else + { + // Completed is a non-cancellable state, and if this is an asynchronous cancel, we're unable to do better than the last async cancel + // which is to say, cancellation is already initiated, so return early. + if (_IsCompleted() || _IsCanceled() || (_IsPendingCancel() && !_SynchronousCancel)) + { + _CONCRT_ASSERT(!_IsCompleted() || !_HasUserException()); + return false; + } + _CONCRT_ASSERT(!_SynchronousCancel || !_HasUserException()); + } + +#if _MSC_VER >= 1800 + if (_SynchronousCancel) +#else + if (_SynchronousCancel || _IsCreated()) +#endif + { + // Be aware that this set must be done BEFORE _M_Scheduled being set, or race will happen between this and wait() + _M_TaskState = _Canceled; +#if _MSC_VER < 1800 + _M_Scheduled.set(); +#endif + + // Cancellation completes the task, so all dependent tasks must be run to cancel them + // They are canceled when they begin running (see _RunContinuation) and see that their + // ancestor has been canceled. + _Do = _RunContinuations; + } + else + { +#if _MSC_VER >= 1800 + _CONCRT_ASSERT(!_UserException); + + if (_IsStarted()) + { + // should not initiate cancellation under a lock + _Do = _Cancel; + } + + // The _M_TaskState variable transitions to _Canceled when cancellation is completed (the task is not executing user code anymore). + // In the case of a synchronous cancel, this can happen immediately, whereas with an asynchronous cancel, the task has to move from + // _Started to _PendingCancel before it can move to _Canceled when it is finished executing. + _M_TaskState = _PendingCancel; + + _M_taskEventLogger._LogCancelTask(); + } + } + + switch (_Do) + { + case _Cancel: + { +#else + _CONCRT_ASSERT(_IsStarted() && !_UserException); +#endif + // The _M_TaskState variable transitions to _Canceled when cancellation is completed (the task is not executing user code anymore). + // In the case of a synchronous cancel, this can happen immediately, whereas with an asynchronous cancel, the task has to move from + // _Started to _PendingCancel before it can move to _Canceled when it is finished executing. + _M_TaskState = _PendingCancel; + if (_M_unwrapped_async_op != nullptr) + { + // We will only try to cancel async operation but not unwrapped tasks, since unwrapped tasks cannot be canceled without its token. + if (_M_unwrapped_async_op) _M_unwrapped_async_op->Cancel(); + } +#if _MSC_VER >= 1800 + _M_TaskCollection._Cancel(); + break; +#else + // Optimistic trying for cancelation + if (_M_pTaskCollection != nullptr) + { + _M_pTaskCollection->_Cancel(); + } +#endif + } +#if _MSC_VER < 1800 + } +#endif + + // Only execute continuations and mark the task as completed if we were able to move the task to the _Canceled state. +#if _MSC_VER >= 1800 + case _RunContinuations: + { + _M_TaskCollection._Complete(); +#else + if (_RunContinuations) + { + _M_Completed.set(); +#endif + + if (_M_Continuations) + { + // Scheduling cancellation with automatic inlining. + details::_ScheduleFuncWithAutoInline([=]() -> HRESULT { _RunTaskContinuations(); return S_OK; }, Concurrency::details::_DefaultAutoInline); + } +#if _MSC_VER >= 1800 + break; + } +#endif + } + return true; + } + void _FinalizeAndRunContinuations(_ReturnType _Result) + { + +#if _MSC_VER >= 1800 + _M_Result.Set(_Result); +#else + _M_Result = _Result; + _M_ResultContext = _ResultContext<_ReturnType>::_GetContext(_M_fRuntimeAggregate); +#endif + { + // + // Hold this lock to ensure continuations being concurrently either get added + // to the _M_Continuations vector or wait for the result + // + scoped_lock _LockHolder(_M_ContinuationsCritSec); + + // A task could still be in the _Created state if it was created with a task_completion_event. + // It could also be in the _Canceled state for the same reason. + _CONCRT_ASSERT(!_HasUserException() && !_IsCompleted()); + if (_IsCanceled()) + { + return; + } + + // Always transition to "completed" state, even in the face of unacknowledged pending cancellation + _M_TaskState = _Completed; + } +#if _MSC_VER >= 1800 + _M_TaskCollection._Complete(); +#else + _M_Completed.set(); +#endif + _RunTaskContinuations(); + } + // + // This method is invoked when the starts executing. The task returns early if this method returns true. + // + bool _TransitionedToStarted() + { + scoped_lock _LockHolder(_M_ContinuationsCritSec); +#if _MSC_VER >= 1800 + // Canceled state could only result from antecedent task's canceled state, but that code path will not reach here. + _ASSERT(!_IsCanceled()); + if (_IsPendingCancel()) +#else + if (_IsCanceled()) +#endif + { + return false; + } + _CONCRT_ASSERT(_IsCreated()); + _M_TaskState = _Started; + return true; + } + void _SetUnwrappedAsyncOp(_AsyncOperationType* _AsyncOp) + { + scoped_lock _LockHolder(_M_ContinuationsCritSec); + // Cancel the async operation if the task itself is canceled, since the thread that canceled the task missed it. + if (_IsPendingCancel()) + { + _CONCRT_ASSERT(!_IsCanceled()); + if (_AsyncOp) _AsyncOp->Cancel(); + } + else + { + _M_unwrapped_async_op = _AsyncOp; + } + } +#if _MSC_VER >= 1800 + // Return true if the task has reached a terminal state + bool _IsDone() + { + return _IsCompleted() || _IsCanceled(); + } +#endif + _ReturnType _GetResult() + { +#if _MSC_VER >= 1800 + return _M_Result.Get(); +#else + return _ResultContext<_ReturnType>::_GetValue(_M_Result, _M_ResultContext, _M_fRuntimeAggregate); +#endif + } +#if _MSC_VER >= 1800 + _ResultHolder<_ReturnType> _M_Result; // this means that the result type must have a public default ctor. +#else + _ReturnType _M_Result; // this means that the result type must have a public default ctor. +#endif + Microsoft::WRL::ComPtr<_AsyncOperationType> _M_unwrapped_async_op; +#if _MSC_VER < 1800 + _ContextCallback _M_ResultContext; +#endif + }; + + template + struct _Task_completion_event_impl + { +#if _MSC_VER >= 1800 + private: + _Task_completion_event_impl(const _Task_completion_event_impl&); + _Task_completion_event_impl& operator=(const _Task_completion_event_impl&); + + public: +#endif + typedef std::vector::_Type> _TaskList; + + _Task_completion_event_impl() : _M_fHasValue(false), _M_fIsCanceled(false) + { + } + + bool _HasUserException() + { + return _M_exceptionHolder != nullptr; + } + + ~_Task_completion_event_impl() + { + for (auto _TaskIt = _M_tasks.begin(); _TaskIt != _M_tasks.end(); ++_TaskIt) + { + _CONCRT_ASSERT(!_M_fHasValue && !_M_fIsCanceled); + // Cancel the tasks since the event was never signaled or canceled. + (*_TaskIt)->_Cancel(true); + } + } + + // We need to protect the loop over the array, so concurrent_vector would not have helped + _TaskList _M_tasks; + critical_section _M_taskListCritSec; +#if _MSC_VER >= 1800 + _ResultHolder<_ResultType> _M_value; +#else + _ResultType _M_value; +#endif + std::shared_ptr<_ExceptionHolder> _M_exceptionHolder; + bool _M_fHasValue; + bool _M_fIsCanceled; + }; + + // Utility method for dealing with void functions + inline std::function _MakeVoidToUnitFunc(const std::function& _Func) + { + return [=](_Unit_type* retVal) -> HRESULT { HRESULT hr = _Func(); *retVal = _Unit_type(); return hr; }; + } + + template + std::function _MakeUnitToTFunc(const std::function& _Func) + { + return [=](_Unit_type, _Type* retVal) -> HRESULT { HRESULT hr = _Func(retVal); return hr; }; + } + + template + std::function _MakeTToUnitFunc(const std::function& _Func) + { + return[=](_Type t, _Unit_type* retVal) -> HRESULT { HRESULT hr = _Func(t); *retVal = _Unit_type(); return hr; }; + } + + inline std::function _MakeUnitToUnitFunc(const std::function& _Func) + { + return [=](_Unit_type, _Unit_type* retVal) -> HRESULT { HRESULT hr = _Func(); *retVal = _Unit_type(); return hr; }; + } +} + + +/// +/// The task_completion_event class allows you to delay the execution of a task until a condition is satisfied, +/// or start a task in response to an external event. +/// +/// +/// The result type of this task_completion_event class. +/// +/// +/// Use a task created from a task completion event when your scenario requires you to create a task that will complete, and +/// thereby have its continuations scheduled for execution, at some point in the future. The task_completion_event must +/// have the same type as the task you create, and calling the set method on the task completion event with a value of that type +/// will cause the associated task to complete, and provide that value as a result to its continuations. +/// If the task completion event is never signaled, any tasks created from it will be canceled when it is destructed. +/// task_completion_event behaves like a smart pointer, and should be passed by value. +/// +/// +/**/ +template +class task_completion_event +{ +public: + /// + /// Constructs a task_completion_event object. + /// + /**/ + task_completion_event() : _M_Impl(std::make_shared>()) + { + } + + /// + /// Sets the task completion event. + /// + /// + /// The result to set this event with. + /// + /// + /// The method returns true if it was successful in setting the event. It returns false if the event is already set. + /// + /// + /// In the presence of multiple or concurrent calls to set, only the first call will succeed and its result (if any) will be stored in the + /// task completion event. The remaining sets are ignored and the method will return false. When you set a task completion event, all the + /// tasks created from that event will immediately complete, and its continuations, if any, will be scheduled. Task completion objects that have + /// a other than void will pass the value to their continuations. + /// + /**/ + bool set(_ResultType _Result) const // 'const' (even though it's not deep) allows to safely pass events by value into lambdas + { + // Subsequent sets are ignored. This makes races to set benign: the first setter wins and all others are ignored. + if (_IsTriggered()) + { + return false; + } + + _TaskList _Tasks; + bool _RunContinuations = false; + { + details::scoped_lock _LockHolder(_M_Impl->_M_taskListCritSec); + + if (!_IsTriggered()) + { +#if _MSC_VER >= 1800 + _M_Impl->_M_value.Set(_Result); +#else + _M_Impl->_M_value = _Result; +#endif + _M_Impl->_M_fHasValue = true; + + _Tasks.swap(_M_Impl->_M_tasks); + _RunContinuations = true; + } + } + + if (_RunContinuations) + { + for (auto _TaskIt = _Tasks.begin(); _TaskIt != _Tasks.end(); ++_TaskIt) + { +#if _MSC_VER >= 1800 + // If current task was cancelled by a cancellation_token, it would be in cancel pending state. + if ((*_TaskIt)->_IsPendingCancel()) + (*_TaskIt)->_Cancel(true); + else + { + // Tasks created with task_completion_events can be marked as async, (we do this in when_any and when_all + // if one of the tasks involved is an async task). Since continuations of async tasks can execute inline, we + // need to run continuations after the lock is released. + (*_TaskIt)->_FinalizeAndRunContinuations(_M_Impl->_M_value.Get()); + } +#else + // Tasks created with task_completion_events can be marked as async, (we do this in when_any and when_all + // if one of the tasks involved is an async task). Since continuations of async tasks can execute inline, we + // need to run continuations after the lock is released. + (*_TaskIt)->_FinalizeAndRunContinuations(_M_Impl->_M_value); +#endif + } + if (_M_Impl->_HasUserException()) + { + _M_Impl->_M_exceptionHolder.reset(); + } + return true; + } + + return false; + } +#if _MSC_VER >= 1800 + + template + __declspec(noinline) // Ask for no inlining so that the _ReturnAddress intrinsic gives us the expected result + bool set_exception(_E _Except) const // 'const' (even though it's not deep) allows to safely pass events by value into lambdas + { + // It is important that _CAPTURE_CALLSTACK() evaluate to the instruction after the call instruction for set_exception. + return _Cancel(std::make_exception_ptr(_Except), _CAPTURE_CALLSTACK()); + } +#endif + + /// + /// Propagates an exception to all tasks associated with this event. + /// + /// + /// The exception_ptr that indicates the exception to set this event with. + /// + /**/ + __declspec(noinline) // Ask for no inlining so that the _ReturnAddress intrinsic gives us the expected result + bool set_exception(std::exception_ptr _ExceptionPtr) const // 'const' (even though it's not deep) allows to safely pass events by value into lambdas + { + // It is important that _ReturnAddress() evaluate to the instruction after the call instruction for set_exception. +#if _MSC_VER >= 1800 + return _Cancel(_ExceptionPtr, _CAPTURE_CALLSTACK()); +#else + return _Cancel(_ExceptionPtr, _ReturnAddress()); +#endif + } + + /// + /// Internal method to cancel the task_completion_event. Any task created using this event will be marked as canceled if it has + /// not already been set. + /// + bool _Cancel() const + { + // Cancel with the stored exception if one exists. + return _CancelInternal(); + } + + /// + /// Internal method to cancel the task_completion_event with the exception provided. Any task created using this event will be canceled + /// with the same exception. + /// + template +#if _MSC_VER >= 1800 + bool _Cancel(_ExHolderType _ExHolder, const details::_TaskCreationCallstack &_SetExceptionAddressHint = details::_TaskCreationCallstack()) const +#else + bool _Cancel(_ExHolderType _ExHolder, void* _SetExceptionAddressHint = nullptr) const +#endif + { + (void)_SetExceptionAddressHint; + bool _Canceled; +#if _MSC_VER >= 1800 + if(_StoreException(_ExHolder, _SetExceptionAddressHint)) +#else + if (_StoreException(_ExHolder)) +#endif + { + _Canceled = _CancelInternal(); + _CONCRT_ASSERT(_Canceled); + } + else + { + _Canceled = false; + } + return _Canceled; + } + + /// + /// Internal method that stores an exception in the task completion event. This is used internally by when_any. + /// Note, this does not cancel the task completion event. A task completion event with a stored exception + /// can bet set() successfully. If it is canceled, it will cancel with the stored exception, if one is present. + /// + template +#if _MSC_VER >= 1800 + bool _StoreException(_ExHolderType _ExHolder, const details::_TaskCreationCallstack &_SetExceptionAddressHint = details::_TaskCreationCallstack()) const +#else + bool _StoreException(_ExHolderType _ExHolder, void* _SetExceptionAddressHint = nullptr) const +#endif + { + details::scoped_lock _LockHolder(_M_Impl->_M_taskListCritSec); + if (!_IsTriggered() && !_M_Impl->_HasUserException()) + { + // Create the exception holder only if we have ensured there we will be successful in setting it onto the + // task completion event. Failing to do so will result in an unobserved task exception. + _M_Impl->_M_exceptionHolder = _ToExceptionHolder(_ExHolder, _SetExceptionAddressHint); + return true; + } + return false; + } + + /// + /// Tests whether current event has been either Set, or Canceled. + /// + bool _IsTriggered() const + { + return _M_Impl->_M_fHasValue || _M_Impl->_M_fIsCanceled; + } + +private: + +#if _MSC_VER >= 1800 + static std::shared_ptr _ToExceptionHolder(const std::shared_ptr& _ExHolder, const details::_TaskCreationCallstack&) +#else + static std::shared_ptr _ToExceptionHolder(const std::shared_ptr& _ExHolder, void*) +#endif + { + return _ExHolder; + } + +#if _MSC_VER >= 1800 + static std::shared_ptr _ToExceptionHolder(std::exception_ptr _ExceptionPtr, const details::_TaskCreationCallstack &_SetExceptionAddressHint) +#else + static std::shared_ptr _ToExceptionHolder(std::exception_ptr _ExceptionPtr, void* _SetExceptionAddressHint) +#endif + { + return std::make_shared(_ExceptionPtr, _SetExceptionAddressHint); + } + + template friend class task; // task can register itself with the event by calling the private _RegisterTask + template friend class task_completion_event; + + typedef typename details::_Task_completion_event_impl<_ResultType>::_TaskList _TaskList; + + /// + /// Cancels the task_completion_event. + /// + bool _CancelInternal() const + { + // Cancellation of task completion events is an internal only utility. Our usage is such that _CancelInternal + // will never be invoked if the task completion event has been set. + _CONCRT_ASSERT(!_M_Impl->_M_fHasValue); + if (_M_Impl->_M_fIsCanceled) + { + return false; + } + + _TaskList _Tasks; + bool _Cancel = false; + { + details::scoped_lock _LockHolder(_M_Impl->_M_taskListCritSec); + _CONCRT_ASSERT(!_M_Impl->_M_fHasValue); + if (!_M_Impl->_M_fIsCanceled) + { + _M_Impl->_M_fIsCanceled = true; + _Tasks.swap(_M_Impl->_M_tasks); + _Cancel = true; + } + } + + bool _UserException = _M_Impl->_HasUserException(); + + if (_Cancel) + { + for (auto _TaskIt = _Tasks.begin(); _TaskIt != _Tasks.end(); ++_TaskIt) + { + // Need to call this after the lock is released. See comments in set(). + if (_UserException) + { + (*_TaskIt)->_CancelWithExceptionHolder(_M_Impl->_M_exceptionHolder, true); + } + else + { + (*_TaskIt)->_Cancel(true); + } + } + } + return _Cancel; + } + + /// + /// Register a task with this event. This function is called when a task is constructed using + /// a task_completion_event. + /// + void _RegisterTask(const typename details::_Task_ptr<_ResultType>::_Type & _TaskParam) + { + details::scoped_lock _LockHolder(_M_Impl->_M_taskListCritSec); +#if _MSC_VER < 1800 + _TaskParam->_SetScheduledEvent(); +#endif + //If an exception was already set on this event, then cancel the task with the stored exception. + if (_M_Impl->_HasUserException()) + { + _TaskParam->_CancelWithExceptionHolder(_M_Impl->_M_exceptionHolder, true); + } + else if (_M_Impl->_M_fHasValue) + { +#if _MSC_VER >= 1800 + _TaskParam->_FinalizeAndRunContinuations(_M_Impl->_M_value.Get()); +#else + _TaskParam->_FinalizeAndRunContinuations(_M_Impl->_M_value); +#endif + } + else + { + _M_Impl->_M_tasks.push_back(_TaskParam); + } + } + + std::shared_ptr> _M_Impl; +}; + +/// +/// The task_completion_event class allows you to delay the execution of a task until a condition is satisfied, +/// or start a task in response to an external event. +/// +/// +/// Use a task created from a task completion event when your scenario requires you to create a task that will complete, and +/// thereby have its continuations scheduled for execution, at some point in the future. The task_completion_event must +/// have the same type as the task you create, and calling the set method on the task completion event with a value of that type +/// will cause the associated task to complete, and provide that value as a result to its continuations. +/// If the task completion event is never signaled, any tasks created from it will be canceled when it is destructed. +/// task_completion_event behaves like a smart pointer, and should be passed by value. +/// +/// +/**/ +template<> +class task_completion_event +{ +public: + /// + /// Sets the task completion event. + /// + /// + /// The method returns true if it was successful in setting the event. It returns false if the event is already set. + /// + /// + /// In the presence of multiple or concurrent calls to set, only the first call will succeed and its result (if any) will be stored in the + /// task completion event. The remaining sets are ignored and the method will return false. When you set a task completion event, all the + /// tasks created from that event will immediately complete, and its continuations, if any, will be scheduled. Task completion objects that have + /// a other than void will pass the value to their continuations. + /// + /**/ + bool set() const // 'const' (even though it's not deep) allows to safely pass events by value into lambdas + { + return _M_unitEvent.set(details::_Unit_type()); + } +#if _MSC_VER >= 1800 + + template + __declspec(noinline) // Ask for no inlining so that the _ReturnAddress intrinsic gives us the expected result + bool set_exception(_E _Except) const // 'const' (even though it's not deep) allows to safely pass events by value into lambdas + { + return _M_unitEvent._Cancel(std::make_exception_ptr(_Except), _CAPTURE_CALLSTACK()); + } +#endif + + /// + /// Propagates an exception to all tasks associated with this event. + /// + /// + /// The exception_ptr that indicates the exception to set this event with. + /// + /**/ + __declspec(noinline) // Ask for no inlining so that the _ReturnAddress intrinsic gives us the expected result + bool set_exception(std::exception_ptr _ExceptionPtr) const // 'const' (even though it's not deep) allows to safely pass events by value into lambdas + { + // It is important that _ReturnAddress() evaluate to the instruction after the call instruction for set_exception. +#if _MSC_VER >= 1800 + return _M_unitEvent._Cancel(_ExceptionPtr, _CAPTURE_CALLSTACK()); +#else + return _M_unitEvent._Cancel(_ExceptionPtr, _ReturnAddress()); +#endif + } + + /// + /// Cancel the task_completion_event. Any task created using this event will be marked as canceled if it has + /// not already been set. + /// + void _Cancel() const // 'const' (even though it's not deep) allows to safely pass events by value into lambdas + { + _M_unitEvent._Cancel(); + } + + /// + /// Cancel the task_completion_event with the exception holder provided. Any task created using this event will be canceled + /// with the same exception. + /// + void _Cancel(const std::shared_ptr& _ExHolder) const + { + _M_unitEvent._Cancel(_ExHolder); + } + + /// + /// Method that stores an exception in the task completion event. This is used internally by when_any. + /// Note, this does not cancel the task completion event. A task completion event with a stored exception + /// can bet set() successfully. If it is canceled, it will cancel with the stored exception, if one is present. + /// + bool _StoreException(const std::shared_ptr& _ExHolder) const + { + return _M_unitEvent._StoreException(_ExHolder); + } + + /// + /// Test whether current event has been either Set, or Canceled. + /// + bool _IsTriggered() const + { + return _M_unitEvent._IsTriggered(); + } + +private: + template friend class task; // task can register itself with the event by calling the private _RegisterTask + + /// + /// Register a task with this event. This function is called when a task is constructed using + /// a task_completion_event. + /// + void _RegisterTask(details::_Task_ptr::_Type _TaskParam) + { + _M_unitEvent._RegisterTask(_TaskParam); + } + + // The void event contains an event a dummy type so common code can be used for events with void and non-void results. + task_completion_event _M_unitEvent; +}; +namespace details +{ + // + // Compile-time validation helpers + // + + // Task constructor validation: issue helpful diagnostics for common user errors. Do not attempt full validation here. + // + // Anything callable is fine + template + auto _IsValidTaskCtor(_Ty _Param, int, int, int, int, int, int, int) -> typename decltype(_Param(), std::true_type()); + + // Anything callable with a task return value is fine + template + auto _IsValidTaskCtor(_Ty _Param, int, int, int, int, int, int, ...) -> typename decltype(_Param(stdx::declval*>()), std::true_type()); + + // Anything callable with a return value is fine + template + auto _IsValidTaskCtor(_Ty _Param, int, int, int, int, int, ...) -> typename decltype(_Param(stdx::declval<_ReturnType*>()), std::true_type()); + + // Anything that has GetResults is fine: this covers AsyncAction* + template + auto _IsValidTaskCtor(_Ty _Param, int, int, int, int, ...) -> typename decltype(_Param->GetResults(), std::true_type()); + + // Anything that has GetResults(TResult_abi*) is fine: this covers AsyncOperation* + template + auto _IsValidTaskCtor(_Ty _Param, int, int, int, ...) -> typename decltype(_Param->GetResults(stdx::declval()))*>()), std::true_type()); + + // Allow parameters with set: this covers task_completion_event + template + auto _IsValidTaskCtor(_Ty _Param, int, int, ...) -> typename decltype(_Param.set(stdx::declval<_ReturnType>()), std::true_type()); + + template + auto _IsValidTaskCtor(_Ty _Param, int, ...) -> typename decltype(_Param.set(), std::true_type()); + + // All else is invalid + template + std::false_type _IsValidTaskCtor(_Ty _Param, ...); + + template + void _ValidateTaskConstructorArgs(_Ty _Param) + { + (void)_Param; + static_assert(std::is_same(_Param, 0, 0, 0, 0, 0, 0, 0)), std::true_type>::value, + "incorrect argument for task constructor; can be a callable object, an asynchronous operation, or a task_completion_event" + ); + static_assert(!(std::is_same<_Ty, _ReturnType>::value && details::_IsIAsyncInfo<_Ty>::_Value), + "incorrect template argument for task; consider using the return type of the async operation"); + } + // Helpers for create_async validation + // + // A parameter lambda taking no arguments is valid + template + static auto _IsValidCreateAsync(_Ty _Param, int, int, int, int, int, int, int, int) -> typename decltype(_Param(), std::true_type()); + + // A parameter lambda taking a result argument is valid + template + static auto _IsValidCreateAsync(_Ty _Param, int, int, int, int, int, int, int, ...) -> typename decltype(_Param(stdx::declval<_ReturnType*>()), std::true_type()); + + // A parameter lambda taking an cancellation_token argument is valid + template + static auto _IsValidCreateAsync(_Ty _Param, int, int, int, int, int, int, ...) -> typename decltype(_Param(Concurrency::cancellation_token::none()), std::true_type()); + + // A parameter lambda taking an cancellation_token argument and a result argument is valid + template + static auto _IsValidCreateAsync(_Ty _Param, int, int, int, int, int, ...) -> typename decltype(_Param(Concurrency::cancellation_token::none(), stdx::declval<_ReturnType*>()), std::true_type()); + + // A parameter lambda taking a progress report argument is valid + template + static auto _IsValidCreateAsync(_Ty _Param, int, int, int, int, ...) -> typename decltype(_Param(details::_ProgressReporterCtorArgType()), std::true_type()); + + // A parameter lambda taking a progress report argument and a result argument is valid + template + static auto _IsValidCreateAsync(_Ty _Param, int, int, int, ...) -> typename decltype(_Param(details::_ProgressReporterCtorArgType(), stdx::declval<_ReturnType*>()), std::true_type()); + + // A parameter lambda taking a progress report and a cancellation_token argument is valid + template + static auto _IsValidCreateAsync(_Ty _Param, int, int, ...) -> typename decltype(_Param(details::_ProgressReporterCtorArgType(), Concurrency::cancellation_token::none()), std::true_type()); + + // A parameter lambda taking a progress report and a cancellation_token argument and a result argument is valid + template + static auto _IsValidCreateAsync(_Ty _Param, int, ...) -> typename decltype(_Param(details::_ProgressReporterCtorArgType(), Concurrency::cancellation_token::none(), stdx::declval<_ReturnType*>()), std::true_type()); + + // All else is invalid + template + static std::false_type _IsValidCreateAsync(_Ty _Param, ...); +} + +/// +/// The Parallel Patterns Library (PPL) task class. A task object represents work that can be executed asynchronously, +/// and concurrently with other tasks and parallel work produced by parallel algorithms in the Concurrency Runtime. It produces +/// a result of type on successful completion. Tasks of type task<void> produce no result. +/// A task can be waited upon and canceled independently of other tasks. It can also be composed with other tasks using +/// continuations(then), and join(when_all) and choice(when_any) patterns. +/// +/// +/// The result type of this task. +/// +/// +/// For more information, see . +/// +/**/ +template +class task +{ +public: + /// + /// The type of the result an object of this class produces. + /// + /**/ + typedef _ReturnType result_type; + + /// + /// Constructs a task object. + /// + /// + /// The default constructor for a task is only present in order to allow tasks to be used within containers. + /// A default constructed task cannot be used until you assign a valid task to it. Methods such as get, wait or then + /// will throw an invalid_argument exception when called on a default constructed task. + /// A task that is created from a task_completion_event will complete (and have its continuations scheduled) when the task + /// completion event is set. + /// The version of the constructor that takes a cancellation token creates a task that can be canceled using the + /// cancellation_token_source the token was obtained from. Tasks created without a cancellation token are not cancelable. + /// Tasks created from a Windows::Foundation::IAsyncInfo interface or a lambda that returns an IAsyncInfo interface + /// reach their terminal state when the enclosed Windows Runtime asynchronous operation or action completes. Similarly, tasks created + /// from a lamda that returns a task<result_type> reach their terminal state when the inner task reaches its terminal state, + /// and not when the lamda returns. + /// task behaves like a smart pointer and is safe to pass around by value. It can be accessed by multiple threads + /// without the need for locks. + /// The constructor overloads that take a Windows::Foundation::IAsyncInfo interface or a lambda returning such an interface, are only available + /// to Windows Store apps. + /// For more information, see . + /// + /**/ + task() : _M_Impl(nullptr) + { + // The default constructor should create a task with a nullptr impl. This is a signal that the + // task is not usable and should throw if any wait(), get() or then() APIs are used. + } + + /// + /// Constructs a task object. + /// + /// + /// The type of the parameter from which the task is to be constructed. + /// + /// + /// The parameter from which the task is to be constructed. This could be a lambda, a function object, a task_completion_event<result_type> + /// object, or a Windows::Foundation::IAsyncInfo if you are using tasks in your Windows Store app. The lambda or function + /// object should be a type equivalent to std::function<X(void)>, where X can be a variable of type result_type, + /// task<result_type>, or a Windows::Foundation::IAsyncInfo in Windows Store apps. + /// + /// + /// The cancellation token to associate with this task. A task created without a cancellation token cannot be canceled. It implicitly receives + /// the token cancellation_token::none(). + /// + /// + /// The default constructor for a task is only present in order to allow tasks to be used within containers. + /// A default constructed task cannot be used until you assign a valid task to it. Methods such as get, wait or then + /// will throw an invalid_argument exception when called on a default constructed task. + /// A task that is created from a task_completion_event will complete (and have its continuations scheduled) when the task + /// completion event is set. + /// The version of the constructor that takes a cancellation token creates a task that can be canceled using the + /// cancellation_token_source the token was obtained from. Tasks created without a cancellation token are not cancelable. + /// Tasks created from a Windows::Foundation::IAsyncInfo interface or a lambda that returns an IAsyncInfo interface + /// reach their terminal state when the enclosed Windows Runtime asynchronous operation or action completes. Similarly, tasks created + /// from a lamda that returns a task<result_type> reach their terminal state when the inner task reaches its terminal state, + /// and not when the lamda returns. + /// task behaves like a smart pointer and is safe to pass around by value. It can be accessed by multiple threads + /// without the need for locks. + /// The constructor overloads that take a Windows::Foundation::IAsyncInfo interface or a lambda returning such an interface, are only available + /// to Windows Store apps. + /// For more information, see . + /// + /**/ + template + __declspec(noinline) // Ask for no inlining so that the _ReturnAddress intrinsic gives us the expected result + explicit task(_Ty _Param) + { +#if _MSC_VER >= 1800 + task_options _TaskOptions; +#endif + details::_ValidateTaskConstructorArgs<_ReturnType, _Ty>(_Param); + +#if _MSC_VER >= 1800 + _CreateImpl(_TaskOptions.get_cancellation_token()._GetImplValue(), _TaskOptions.get_scheduler()); +#else + _CreateImpl(Concurrency::cancellation_token::none()._GetImplValue()); +#endif + // Do not move the next line out of this function. It is important that _ReturnAddress() evaluate to the the call site of the task constructor. +#if _MSC_VER >= 1800 + _SetTaskCreationCallstack(_CAPTURE_CALLSTACK()); +#else + _SetTaskCreationAddressHint(_ReturnAddress()); +#endif + _TaskInitMaybeFunctor(_Param, details::_IsCallable<_ReturnType>(_Param, 0, 0, 0)); + } + + /// + /// Constructs a task object. + /// + /// + /// The type of the parameter from which the task is to be constructed. + /// + /// + /// The parameter from which the task is to be constructed. This could be a lambda, a function object, a task_completion_event<result_type> + /// object, or a Windows::Foundation::IAsyncInfo if you are using tasks in your Windows Store app. The lambda or function + /// object should be a type equivalent to std::function<X(void)>, where X can be a variable of type result_type, + /// task<result_type>, or a Windows::Foundation::IAsyncInfo in Windows Store apps. + /// + /// + /// The cancellation token to associate with this task. A task created without a cancellation token cannot be canceled. It implicitly receives + /// the token cancellation_token::none(). + /// + /// + /// The default constructor for a task is only present in order to allow tasks to be used within containers. + /// A default constructed task cannot be used until you assign a valid task to it. Methods such as get, wait or then + /// will throw an invalid_argument exception when called on a default constructed task. + /// A task that is created from a task_completion_event will complete (and have its continuations scheduled) when the task + /// completion event is set. + /// The version of the constructor that takes a cancellation token creates a task that can be canceled using the + /// cancellation_token_source the token was obtained from. Tasks created without a cancellation token are not cancelable. + /// Tasks created from a Windows::Foundation::IAsyncInfo interface or a lambda that returns an IAsyncInfo interface + /// reach their terminal state when the enclosed Windows Runtime asynchronous operation or action completes. Similarly, tasks created + /// from a lamda that returns a task<result_type> reach their terminal state when the inner task reaches its terminal state, + /// and not when the lamda returns. + /// task behaves like a smart pointer and is safe to pass around by value. It can be accessed by multiple threads + /// without the need for locks. + /// The constructor overloads that take a Windows::Foundation::IAsyncInfo interface or a lambda returning such an interface, are only available + /// to Windows Store apps. + /// For more information, see . + /// + /**/ + template + __declspec(noinline) // Ask for no inlining so that the _ReturnAddress intrinsic gives us the expected result +#if _MSC_VER >= 1800 + explicit task(_Ty _Param, const task_options &_TaskOptions) +#else + explicit task(_Ty _Param, Concurrency::cancellation_token _Token) +#endif + { + details::_ValidateTaskConstructorArgs<_ReturnType, _Ty>(_Param); + +#if _MSC_VER >= 1800 + _CreateImpl(_TaskOptions.get_cancellation_token()._GetImplValue(), _TaskOptions.get_scheduler()); +#else + _CreateImpl(_Token._GetImplValue()); +#endif + // Do not move the next line out of this function. It is important that _ReturnAddress() evaluate to the the call site of the task constructor. +#if _MSC_VER >= 1800 + _SetTaskCreationCallstack(details::_get_internal_task_options(_TaskOptions)._M_hasPresetCreationCallstack ? details::_get_internal_task_options(_TaskOptions)._M_presetCreationCallstack : _CAPTURE_CALLSTACK()); +#else + _SetTaskCreationAddressHint(_ReturnAddress()); +#endif + _TaskInitMaybeFunctor(_Param, details::_IsCallable<_ReturnType>(_Param, 0, 0, 0)); + } + + /// + /// Constructs a task object. + /// + /// + /// The source task object. + /// + /// + /// The default constructor for a task is only present in order to allow tasks to be used within containers. + /// A default constructed task cannot be used until you assign a valid task to it. Methods such as get, wait or then + /// will throw an invalid_argument exception when called on a default constructed task. + /// A task that is created from a task_completion_event will complete (and have its continuations scheduled) when the task + /// completion event is set. + /// The version of the constructor that takes a cancellation token creates a task that can be canceled using the + /// cancellation_token_source the token was obtained from. Tasks created without a cancellation token are not cancelable. + /// Tasks created from a Windows::Foundation::IAsyncInfo interface or a lambda that returns an IAsyncInfo interface + /// reach their terminal state when the enclosed Windows Runtime asynchronous operation or action completes. Similarly, tasks created + /// from a lamda that returns a task<result_type> reach their terminal state when the inner task reaches its terminal state, + /// and not when the lamda returns. + /// task behaves like a smart pointer and is safe to pass around by value. It can be accessed by multiple threads + /// without the need for locks. + /// The constructor overloads that take a Windows::Foundation::IAsyncInfo interface or a lambda returning such an interface, are only available + /// to Windows Store apps. + /// For more information, see . + /// + /**/ + task(const task& _Other) : _M_Impl(_Other._M_Impl) {} + + /// + /// Constructs a task object. + /// + /// + /// The source task object. + /// + /// + /// The default constructor for a task is only present in order to allow tasks to be used within containers. + /// A default constructed task cannot be used until you assign a valid task to it. Methods such as get, wait or then + /// will throw an invalid_argument exception when called on a default constructed task. + /// A task that is created from a task_completion_event will complete (and have its continuations scheduled) when the task + /// completion event is set. + /// The version of the constructor that takes a cancellation token creates a task that can be canceled using the + /// cancellation_token_source the token was obtained from. Tasks created without a cancellation token are not cancelable. + /// Tasks created from a Windows::Foundation::IAsyncInfo interface or a lambda that returns an IAsyncInfo interface + /// reach their terminal state when the enclosed Windows Runtime asynchronous operation or action completes. Similarly, tasks created + /// from a lamda that returns a task<result_type> reach their terminal state when the inner task reaches its terminal state, + /// and not when the lamda returns. + /// task behaves like a smart pointer and is safe to pass around by value. It can be accessed by multiple threads + /// without the need for locks. + /// The constructor overloads that take a Windows::Foundation::IAsyncInfo interface or a lambda returning such an interface, are only available + /// to Windows Store apps. + /// For more information, see . + /// + /**/ + task(task&& _Other) : _M_Impl(std::move(_Other._M_Impl)) {} + + /// + /// Replaces the contents of one task object with another. + /// + /// + /// The source task object. + /// + /// + /// As task behaves like a smart pointer, after a copy assignment, this task objects represents the same + /// actual task as does. + /// + /**/ + task& operator=(const task& _Other) + { + if (this != &_Other) + { + _M_Impl = _Other._M_Impl; + } + return *this; + } + + /// + /// Replaces the contents of one task object with another. + /// + /// + /// The source task object. + /// + /// + /// As task behaves like a smart pointer, after a copy assignment, this task objects represents the same + /// actual task as does. + /// + /**/ + task& operator=(task&& _Other) + { + if (this != &_Other) + { + _M_Impl = std::move(_Other._M_Impl); + } + return *this; + } + + /// + /// Adds a continuation task to this task. + /// + /// + /// The type of the function object that will be invoked by this task. + /// + /// + /// The continuation function to execute when this task completes. This continuation function must take as input + /// a variable of either result_type or task<result_type>, where result_type is the type + /// of the result this task produces. + /// + /// + /// The newly created continuation task. The result type of the returned task is determined by what returns. + /// + /// + /// The overloads of then that take a lambda or functor that returns a Windows::Foundation::IAsyncInfo interface, are only available + /// to Windows Store apps. + /// For more information on how to use task continuations to compose asynchronous work, see . + /// + /**/ + template + __declspec(noinline) // Ask for no inlining so that the _ReturnAddress intrinsic gives us the expected result + auto then(const _Function& _Func) const -> typename details::_ContinuationTypeTraits<_Function, _ReturnType>::_TaskOfType + { +#if _MSC_VER >= 1800 + task_options _TaskOptions; + details::_get_internal_task_options(_TaskOptions)._set_creation_callstack(_CAPTURE_CALLSTACK()); + return _ThenImpl<_ReturnType, _Function>(_Func, _TaskOptions); +#else + auto _ContinuationTask = _ThenImpl<_ReturnType, _Function>(_Func, nullptr, task_continuation_context::use_default()); + // Do not move the next line out of this function. It is important that _ReturnAddress() evaluate to the the call site of then. + _ContinuationTask._SetTaskCreationAddressHint(_ReturnAddress()); + return _ContinuationTask; +#endif + } + + /// + /// Adds a continuation task to this task. + /// + /// + /// The type of the function object that will be invoked by this task. + /// + /// + /// The continuation function to execute when this task completes. This continuation function must take as input + /// a variable of either result_type or task<result_type>, where result_type is the type + /// of the result this task produces. + /// + /// + /// The cancellation token to associate with the continuation task. A continuation task that is created without a cancellation token will inherit + /// the token of its antecedent task. + /// + /// + /// The newly created continuation task. The result type of the returned task is determined by what returns. + /// + /// + /// The overloads of then that take a lambda or functor that returns a Windows::Foundation::IAsyncInfo interface, are only available + /// to Windows Store apps. + /// For more information on how to use task continuations to compose asynchronous work, see . + /// + /**/ + template + __declspec(noinline) // Ask for no inlining so that the _ReturnAddress intrinsic gives us the expected result +#if _MSC_VER >= 1800 + auto then(const _Function& _Func, task_options _TaskOptions) const -> typename details::_ContinuationTypeTraits<_Function, _ReturnType>::_TaskOfType +#else + auto then(const _Function& _Func, Concurrency::cancellation_token _CancellationToken) const -> typename details::_ContinuationTypeTraits<_Function, _ReturnType>::_TaskOfType +#endif + { +#if _MSC_VER >= 1800 + details::_get_internal_task_options(_TaskOptions)._set_creation_callstack(_CAPTURE_CALLSTACK()); + return _ThenImpl<_ReturnType, _Function>(_Func, _TaskOptions); +#else + auto _ContinuationTask = _ThenImpl<_ReturnType, _Function>(_Func, _CancellationToken._GetImplValue(), task_continuation_context::use_default()); + // Do not move the next line out of this function. It is important that _ReturnAddress() evaluate to the the call site of then. + _ContinuationTask._SetTaskCreationAddressHint(_ReturnAddress()); + return _ContinuationTask; +#endif + } +#if _MSC_VER < 1800 + /// + /// Adds a continuation task to this task. + /// + /// + /// The type of the function object that will be invoked by this task. + /// + /// + /// The continuation function to execute when this task completes. This continuation function must take as input + /// a variable of either result_type or task<result_type>, where result_type is the type + /// of the result this task produces. + /// + /// + /// A variable that specifies where the continuation should execute. This variable is only useful when used in a + /// Windows Store app. For more information, see task_continuation_context + /// + /// + /// The newly created continuation task. The result type of the returned task is determined by what returns. + /// + /// + /// The overloads of then that take a lambda or functor that returns a Windows::Foundation::IAsyncInfo interface, are only available + /// to Windows Store apps. + /// For more information on how to use task continuations to compose asynchronous work, see . + /// + /**/ + template + __declspec(noinline) // Ask for no inlining so that the _ReturnAddress intrinsic gives us the expected result + auto then(const _Function& _Func, task_continuation_context _ContinuationContext) const -> typename details::_ContinuationTypeTraits<_Function, _ReturnType>::_TaskOfType + { + auto _ContinuationTask = _ThenImpl<_ReturnType, _Function>(_Func, nullptr, _ContinuationContext); + // Do not move the next line out of this function. It is important that _ReturnAddress() evaluate to the the call site of then. + _ContinuationTask._SetTaskCreationAddressHint(_ReturnAddress()); + return _ContinuationTask; + } +#endif + /// + /// Adds a continuation task to this task. + /// + /// + /// The type of the function object that will be invoked by this task. + /// + /// + /// The continuation function to execute when this task completes. This continuation function must take as input + /// a variable of either result_type or task<result_type>, where result_type is the type + /// of the result this task produces. + /// + /// + /// The cancellation token to associate with the continuation task. A continuation task that is created without a cancellation token will inherit + /// the token of its antecedent task. + /// + /// + /// A variable that specifies where the continuation should execute. This variable is only useful when used in a + /// Windows Store app. For more information, see task_continuation_context + /// + /// + /// The newly created continuation task. The result type of the returned task is determined by what returns. + /// + /// + /// The overloads of then that take a lambda or functor that returns a Windows::Foundation::IAsyncInfo interface, are only available + /// to Windows Store apps. + /// For more information on how to use task continuations to compose asynchronous work, see . + /// + /**/ + template + __declspec(noinline) // Ask for no inlining so that the _ReturnAddress intrinsic gives us the expected result + auto then(const _Function& _Func, Concurrency::cancellation_token _CancellationToken, task_continuation_context _ContinuationContext) const -> typename details::_ContinuationTypeTraits<_Function, _ReturnType>::_TaskOfType + { +#if _MSC_VER >= 1800 + task_options _TaskOptions(_CancellationToken, _ContinuationContext); + details::_get_internal_task_options(_TaskOptions)._set_creation_callstack(_CAPTURE_CALLSTACK()); + return _ThenImpl<_ReturnType, _Function>(_Func, _TaskOptions); +#else + auto _ContinuationTask = _ThenImpl<_ReturnType, _Function>(_Func, _CancellationToken._GetImplValue(), _ContinuationContext); + // Do not move the next line out of this function. It is important that _ReturnAddress() evaluate to the the call site of then. + _ContinuationTask._SetTaskCreationAddressHint(_ReturnAddress()); + return _ContinuationTask; +#endif + } + + /// + /// Waits for this task to reach a terminal state. It is possible for wait to execute the task inline, if all of the tasks + /// dependencies are satisfied, and it has not already been picked up for execution by a background worker. + /// + /// + /// A task_status value which could be either completed or canceled. If the task encountered an exception + /// during execution, or an exception was propagated to it from an antecedent task, wait will throw that exception. + /// + /**/ + task_status wait() const + { + if (_M_Impl == nullptr) + { + throw Concurrency::invalid_operation("wait() cannot be called on a default constructed task."); + } + + return _M_Impl->_Wait(); + } + + /// + /// Returns the result this task produced. If the task is not in a terminal state, a call to get will wait for the task to + /// finish. This method does not return a value when called on a task with a result_type of void. + /// + /// + /// The result of the task. + /// + /// + /// If the task is canceled, a call to get will throw a task_canceled exception. If the task + /// encountered an different exception or an exception was propagated to it from an antecedent task, a call to get will throw that exception. + /// + /**/ + _ReturnType get() const + { + if (_M_Impl == nullptr) + { + throw Concurrency::invalid_operation("get() cannot be called on a default constructed task."); + } + + if (_M_Impl->_Wait() == Concurrency::canceled) + { + throw Concurrency::task_canceled(); + } + + return _M_Impl->_GetResult(); + } +#if _MSC_VER >= 1800 + /// + /// Determines if the task is completed. + /// + /// + /// True if the task has completed, false otherwise. + /// + /// + /// The function returns true if the task is completed or canceled (with or without user exception). + /// + bool is_done() const + { + if (!_M_Impl) + { + throw Concurrency::invalid_operation("is_done() cannot be called on a default constructed task."); + } + + return _M_Impl->_IsDone(); + } + + /// + /// Returns the scheduler for this task + /// + /// + /// A pointer to the scheduler + /// + Concurrency::scheduler_ptr scheduler() const + { + if (!_M_Impl) + { + throw Concurrency::invalid_operation("scheduler() cannot be called on a default constructed task."); + } + + return _M_Impl->_GetScheduler(); + } +#endif + /// + /// Determines whether the task unwraps a Windows Runtime IAsyncInfo interface or is descended from such a task. + /// + /// + /// true if the task unwraps an IAsyncInfo interface or is descended from such a task, false otherwise. + /// + /**/ + bool is_apartment_aware() const + { + if (_M_Impl == nullptr) + { + throw Concurrency::invalid_operation("is_apartment_aware() cannot be called on a default constructed task."); + } + return _M_Impl->_IsApartmentAware(); + } + + /// + /// Determines whether two task objects represent the same internal task. + /// + /// + /// true if the objects refer to the same underlying task, and false otherwise. + /// + /**/ + bool operator==(const task<_ReturnType>& _Rhs) const + { + return (_M_Impl == _Rhs._M_Impl); + } + + /// + /// Determines whether two task objects represent different internal tasks. + /// + /// + /// true if the objects refer to different underlying tasks, and false otherwise. + /// + /**/ + bool operator!=(const task<_ReturnType>& _Rhs) const + { + return !operator==(_Rhs); + } + + /// + /// Create an underlying task implementation. + /// +#if _MSC_VER >= 1800 + void _CreateImpl(Concurrency::details::_CancellationTokenState * _Ct, Concurrency::scheduler_ptr _Scheduler) +#else + void _CreateImpl(Concurrency::details::_CancellationTokenState * _Ct) +#endif + { + _CONCRT_ASSERT(_Ct != nullptr); +#if _MSC_VER >= 1800 + _M_Impl = details::_Task_ptr<_ReturnType>::_Make(_Ct, _Scheduler); +#else + _M_Impl = details::_Task_ptr<_ReturnType>::_Make(_Ct); +#endif + if (_Ct != Concurrency::details::_CancellationTokenState::_None()) + { +#if _MSC_VER >= 1800 + _M_Impl->_RegisterCancellation(_M_Impl); +#else + _M_Impl->_RegisterCancellation(); +#endif + } + } + + /// + /// Return the underlying implementation for this task. + /// + const typename details::_Task_ptr<_ReturnType>::_Type & _GetImpl() const + { + return _M_Impl; + } + + /// + /// Set the implementation of the task to be the supplied implementaion. + /// + void _SetImpl(const typename details::_Task_ptr<_ReturnType>::_Type & _Impl) + { + _CONCRT_ASSERT(_M_Impl == nullptr); + _M_Impl = _Impl; + } + + /// + /// Set the implementation of the task to be the supplied implementaion using a move instead of a copy. + /// + void _SetImpl(typename details::_Task_ptr<_ReturnType>::_Type && _Impl) + { + _CONCRT_ASSERT(_M_Impl == nullptr); + _M_Impl = std::move(_Impl); + } + + /// + /// Sets a property determining whether the task is apartment aware. + /// + void _SetAsync(bool _Async = true) + { + _GetImpl()->_SetAsync(_Async); + } + + /// + /// Sets a field in the task impl to the return address for calls to the task constructors and the then method. + /// +#if _MSC_VER >= 1800 + void _SetTaskCreationCallstack(const details::_TaskCreationCallstack &_callstack) + { + _GetImpl()->_SetTaskCreationCallstack(_callstack); + } +#else + void _SetTaskCreationAddressHint(void* _Address) + { + _GetImpl()->_SetTaskCreationAddressHint(_Address); + } +#endif + /// + /// An internal version of then that takes additional flags and always execute the continuation inline by default. + /// When _ForceInline is set to false, continuations inlining will be limited to default _DefaultAutoInline. + /// This function is Used for runtime internal continuations only. + /// + template +#if _MSC_VER >= 1800 + auto _Then(const _Function& _Func, Concurrency::details::_CancellationTokenState *_PTokenState, + details::_TaskInliningMode _InliningMode = Concurrency::details::_ForceInline) const -> typename details::_ContinuationTypeTraits<_Function, _ReturnType>::_TaskOfType + { + // inherit from antecedent + auto _Scheduler = _GetImpl()->_GetScheduler(); + + return _ThenImpl<_ReturnType, _Function>(_Func, _PTokenState, task_continuation_context::use_default(), _Scheduler, _CAPTURE_CALLSTACK(), _InliningMode); + } +#else + auto _Then(const _Function& _Func, Concurrency::details::_CancellationTokenState *_PTokenState, bool _Aggregating, + details::_TaskInliningMode _InliningMode = Concurrency::details::_ForceInline) const -> typename details::_ContinuationTypeTraits<_Function, _ReturnType>::_TaskOfType + { + return _ThenImpl<_ReturnType, _Function>(_Func, _PTokenState, task_continuation_context::use_default(), _Aggregating, _InliningMode); + } +#endif + +private: + template friend class task; + + // A helper class template that transforms an intial task lambda returns void into a lambda that returns a non-void type (details::_Unit_type is used + // to substitute for void). This is to minimize the special handling required for 'void'. + template + class _Init_func_transformer + { + public: + static auto _Perform(std::function _Func) -> decltype(_Func) + { + return _Func; + } + }; + + template<> + class _Init_func_transformer + { + public: + static auto _Perform(std::function _Func) -> decltype(details::_MakeVoidToUnitFunc(_Func)) + { + return details::_MakeVoidToUnitFunc(_Func); + } + }; + + // The task handle type used to construct an 'initial task' - a task with no dependents. + template + struct _InitialTaskHandle : + details::_PPLTaskHandle<_ReturnType, _InitialTaskHandle<_InternalReturnType, _Function, _TypeSelection>, details::_UnrealizedChore> + { + _Function _M_function; + _InitialTaskHandle(const typename details::_Task_ptr<_ReturnType>::_Type & _TaskImpl, const _Function & _Function) : _M_function(_Function), _PPLTaskHandle(_TaskImpl) + { + } + virtual ~_InitialTaskHandle() {} + +#if _MSC_VER >= 1800 + template + auto _LogWorkItemAndInvokeUserLambda(_Func && _func, _RetArg && _retArg) const -> decltype(_func(std::forward<_RetArg>(_retArg))) + { + details::_TaskWorkItemRAIILogger _LogWorkItem(this->_M_pTask->_M_taskEventLogger); + return _func(std::forward<_RetArg>(_retArg)); + } +#endif + + void _Perform() const + { + _Init(_TypeSelection()); + } +#if _MSC_VER >= 1800 + + void _SyncCancelAndPropagateException() const + { + this->_M_pTask->_Cancel(true); + } +#endif + // + // Overload 0: returns _InternalReturnType + // + // This is the most basic task with no unwrapping + // + void _Init(details::_TypeSelectorNoAsync) const + { + _ReturnType retVal; +#if _MSC_VER >= 1800 + HRESULT hr = _LogWorkItemAndInvokeUserLambda(_Init_func_transformer<_InternalReturnType>::_Perform(_M_function), &retVal); +#else + HRESULT hr = _Init_func_transformer<_InternalReturnType>::_Perform(_M_function)(&retVal); +#endif + if (FAILED(hr)) throw std::make_exception_ptr(hr); + _M_pTask->_FinalizeAndRunContinuations(retVal); + } + + // + // Overload 1: returns IAsyncOperation<_InternalReturnType>* + // or + // returns task<_InternalReturnType> + // + // This is task whose functor returns an async operation or a task which will be unwrapped for continuation + // Depending on the output type, the right _AsyncInit gets invoked + // + void _Init(details::_TypeSelectorAsyncTask) const + { + task<_InternalReturnType> retVal; +#if _MSC_VER >= 1800 + HRESULT hr = _LogWorkItemAndInvokeUserLambda(_M_function, &retVal); +#else + HRESULT hr = _M_function(&retVal); +#endif + if (FAILED(hr)) throw std::make_exception_ptr(hr); + details::_Task_impl_base::_AsyncInit<_ReturnType, _InternalReturnType>(_M_pTask, retVal); + } + void _Init(details::_TypeSelectorAsyncOperation) const + { + _ReturnType retVal; +#if _MSC_VER >= 1800 + HRESULT hr = _LogWorkItemAndInvokeUserLambda(_M_function, &retVal); +#else + HRESULT hr = _M_function(&retVal); +#endif + if (FAILED(hr)) throw std::make_exception_ptr(hr); + details::_Task_impl_base::_AsyncInit<_ReturnType, _InternalReturnType>(_M_pTask, + Microsoft::WRL::Make>(retVal).Get()); + } + + // + // Overload 2: returns IAsyncAction* + // + // This is task whose functor returns an async action which will be unwrapped for continuation + // + void _Init(details::_TypeSelectorAsyncAction) const + { + _ReturnType retVal; +#if _MSC_VER >= 1800 + HRESULT hr = _LogWorkItemAndInvokeUserLambda(_M_function, &retVal); +#else + HRESULT hr = _M_function(&retVal); +#endif + if (FAILED(hr)) throw std::make_exception_ptr(hr); + details::_Task_impl_base::_AsyncInit<_ReturnType, _InternalReturnType>(_M_pTask, Microsoft::WRL::Make(retVal).Get()); + } + + // + // Overload 3: returns IAsyncOperationWithProgress<_InternalReturnType, _ProgressType>* + // + // This is task whose functor returns an async operation with progress which will be unwrapped for continuation + // + void _Init(details::_TypeSelectorAsyncOperationWithProgress) const + { + typedef details::_GetProgressType::_Value _ProgressType; + _ReturnType retVal; +#if _MSC_VER >= 1800 + HRESULT hr = _LogWorkItemAndInvokeUserLambda(_M_function, &retVal); +#else + HRESULT hr = _M_function(&retVal); +#endif + if (FAILED(hr)) throw std::make_exception_ptr(hr); + details::_Task_impl_base::_AsyncInit<_ReturnType, _InternalReturnType>(_M_pTask, + Microsoft::WRL::Make>(retVal).Get()); + } + + // + // Overload 4: returns IAsyncActionWithProgress<_ProgressType>* + // + // This is task whose functor returns an async action with progress which will be unwrapped for continuation + // + void _Init(details::_TypeSelectorAsyncActionWithProgress) const + { + typedef details::_GetProgressType::_Value _ProgressType; + _ReturnType retVal; +#if _MSC_VER >= 1800 + HRESULT hr = _LogWorkItemAndInvokeUserLambda(_M_function, &retVal); +#else + HRESULT hr = _M_function(&retVal); +#endif + if (FAILED(hr)) throw std::make_exception_ptr(hr); + details::_Task_impl_base::_AsyncInit<_ReturnType, _InternalReturnType>(_M_pTask, + Microsoft::WRL::Make>(retVal).Get()); + } + }; + + /// + /// A helper class template that transforms a continuation lambda that either takes or returns void, or both, into a lambda that takes and returns a + /// non-void type (details::_Unit_type is used to substitute for void). This is to minimize the special handling required for 'void'. + /// + template + class _Continuation_func_transformer + { + public: + static auto _Perform(std::function _Func) -> decltype(_Func) + { + return _Func; + } + }; + + template + class _Continuation_func_transformer + { + public: + static auto _Perform(std::function _Func) -> decltype(details::_MakeUnitToTFunc<_OutType>(_Func)) + { + return details::_MakeUnitToTFunc<_OutType>(_Func); + } + }; + + template + class _Continuation_func_transformer<_InType, void> + { + public: + static auto _Perform(std::function _Func) -> decltype(details::_MakeTToUnitFunc<_InType>(_Func)) + { + return details::_MakeTToUnitFunc<_InType>(_Func); + } + }; + + template<> + class _Continuation_func_transformer + { + public: + static auto _Perform(std::function _Func) -> decltype(details::_MakeUnitToUnitFunc(_Func)) + { + return details::_MakeUnitToUnitFunc(_Func); + } + }; + /// + /// The task handle type used to create a 'continuation task'. + /// + template + struct _ContinuationTaskHandle : + details::_PPLTaskHandle::_Type, + _ContinuationTaskHandle<_InternalReturnType, _ContinuationReturnType, _Function, _IsTaskBased, _TypeSelection>, details::_ContinuationTaskHandleBase> + { + typedef typename details::_NormalizeVoidToUnitType<_ContinuationReturnType>::_Type _NormalizedContinuationReturnType; + + typename details::_Task_ptr<_ReturnType>::_Type _M_ancestorTaskImpl; + _Function _M_function; + + _ContinuationTaskHandle(const typename details::_Task_ptr<_ReturnType>::_Type & _AncestorImpl, + const typename details::_Task_ptr<_NormalizedContinuationReturnType>::_Type & _ContinuationImpl, + const _Function & _Func, const task_continuation_context & _Context, details::_TaskInliningMode _InliningMode) : +#if _MSC_VER >= 1800 + details::_PPLTaskHandle::_Type, + _ContinuationTaskHandle<_InternalReturnType, _ContinuationReturnType, _Function, _IsTaskBased, _TypeSelection>, details::_ContinuationTaskHandleBase> + ::_PPLTaskHandle(_ContinuationImpl) + , _M_ancestorTaskImpl(_AncestorImpl) + , _M_function(_Func) +#else + _M_ancestorTaskImpl(_AncestorImpl), _PPLTaskHandle(_ContinuationImpl), _M_function(_Func) +#endif + { + _M_isTaskBasedContinuation = _IsTaskBased::value; + _M_continuationContext = _Context; + _M_continuationContext._Resolve(_AncestorImpl->_IsApartmentAware()); + _M_inliningMode = _InliningMode; + } + + virtual ~_ContinuationTaskHandle() {} + +#if _MSC_VER >= 1800 + template + auto _LogWorkItemAndInvokeUserLambda(_Func && _func, _Arg && _value, _RetArg && _retArg) const -> decltype(_func(std::forward<_Arg>(_value), std::forward<_RetArg>(_retArg))) + { + details::_TaskWorkItemRAIILogger _LogWorkItem(this->_M_pTask->_M_taskEventLogger); + return _func(std::forward<_Arg>(_value), std::forward<_RetArg>(_retArg)); + } +#endif + + void _Perform() const + { + _Continue(_IsTaskBased(), _TypeSelection()); + } + +#if _MSC_VER >= 1800 + void _SyncCancelAndPropagateException() const + { + if (_M_ancestorTaskImpl->_HasUserException()) + { + // If the ancestor encountered an exception, transfer the exception to the continuation + // This traverses down the tree to propagate the exception. + this->_M_pTask->_CancelWithExceptionHolder(_M_ancestorTaskImpl->_GetExceptionHolder(), true); + } + else + { + // If the ancestor was canceled, then your own execution should be canceled. + // This traverses down the tree to cancel it. + this->_M_pTask->_Cancel(true); + } + } +#endif + + // + // Overload 0-0: _InternalReturnType -> _TaskType + // + // This is a straight task continuation which simply invokes its target with the ancestor's completion argument + // + void _Continue(std::false_type, details::_TypeSelectorNoAsync) const + { + _NormalizedContinuationReturnType retVal; +#if _MSC_VER >= 1800 + HRESULT hr = _LogWorkItemAndInvokeUserLambda(_Continuation_func_transformer<_InternalReturnType, _ContinuationReturnType>::_Perform(_M_function), _M_ancestorTaskImpl->_GetResult(), &retVal); +#else + HRESULT hr =_Continuation_func_transformer<_InternalReturnType, _ContinuationReturnType>::_Perform(_M_function)(_M_ancestorTaskImpl->_GetResult(), &retVal); +#endif + if (FAILED(hr)) throw std::make_exception_ptr(hr); + _M_pTask->_FinalizeAndRunContinuations(retVal); + } + + // + // Overload 0-1: _InternalReturnType -> IAsyncOperation<_TaskType>* + // or + // _InternalReturnType -> task<_TaskType> + // + // This is a straight task continuation which returns an async operation or a task which will be unwrapped for continuation + // Depending on the output type, the right _AsyncInit gets invoked + // + void _Continue(std::false_type, details::_TypeSelectorAsyncTask) const + { + typedef typename details::_FunctionTypeTraits<_Function, _InternalReturnType>::_FuncRetType _FuncOutputType; + _FuncOutputType retVal; +#if _MSC_VER >= 1800 + HRESULT hr = _LogWorkItemAndInvokeUserLambda(_Continuation_func_transformer<_InternalReturnType, _FuncOutputType>::_Perform(_M_function), _M_ancestorTaskImpl->_GetResult(), &retVal); +#else + HRESULT hr = _Continuation_func_transformer<_InternalReturnType, _FuncOutputType>::_Perform(_M_function)(_M_ancestorTaskImpl->_GetResult(), &retVal); +#endif + if (FAILED(hr)) throw std::make_exception_ptr(hr); + details::_Task_impl_base::_AsyncInit<_NormalizedContinuationReturnType, _ContinuationReturnType>( + _M_pTask, + retVal + ); + } + void _Continue(std::false_type, details::_TypeSelectorAsyncOperation) const + { + typedef typename details::_FunctionTypeTraits<_Function, _InternalReturnType>::_FuncRetType _FuncOutputType; + _FuncOutputType retVal; +#if _MSC_VER >= 1800 + HRESULT hr = _LogWorkItemAndInvokeUserLambda(_Continuation_func_transformer<_InternalReturnType, _FuncOutputType>::_Perform(_M_function), _M_ancestorTaskImpl->_GetResult(), &retVal); +#else + HRESULT hr = _Continuation_func_transformer<_InternalReturnType, _FuncOutputType>::_Perform(_M_function)(_M_ancestorTaskImpl->_GetResult(), &retVal); +#endif + if (FAILED(hr)) throw std::make_exception_ptr(hr); + details::_Task_impl_base::_AsyncInit<_NormalizedContinuationReturnType, _ContinuationReturnType>( + _M_pTask, + Microsoft::WRL::Make>(retVal).Get()); + } + + // + // Overload 0-2: _InternalReturnType -> IAsyncAction* + // + // This is a straight task continuation which returns an async action which will be unwrapped for continuation + // + void _Continue(std::false_type, details::_TypeSelectorAsyncAction) const + { + typedef details::_FunctionTypeTraits<_Function, _InternalReturnType>::_FuncRetType _FuncOutputType; + _FuncOutputType retVal; +#if _MSC_VER >= 1800 + HRESULT hr = _LogWorkItemAndInvokeUserLambda(_Continuation_func_transformer<_InternalReturnType, _FuncOutputType>::_Perform(_M_function), _M_ancestorTaskImpl->_GetResult(), &retVal); +#else + HRESULT hr = _Continuation_func_transformer<_InternalReturnType, _FuncOutputType>::_Perform(_M_function)(_M_ancestorTaskImpl->_GetResult(), &retVal); +#endif + if (FAILED(hr)) throw std::make_exception_ptr(hr); + details::_Task_impl_base::_AsyncInit<_NormalizedContinuationReturnType, _ContinuationReturnType>( + _M_pTask, + Microsoft::WRL::Make( + retVal).Get()); + } + + // + // Overload 0-3: _InternalReturnType -> IAsyncOperationWithProgress<_TaskType, _ProgressType>* + // + // This is a straight task continuation which returns an async operation with progress which will be unwrapped for continuation + // + void _Continue(std::false_type, details::_TypeSelectorAsyncOperationWithProgress) const + { + typedef details::_FunctionTypeTraits<_Function, _InternalReturnType>::_FuncRetType _FuncOutputType; + + _FuncOutputType _OpWithProgress; +#if _MSC_VER >= 1800 + HRESULT hr = _LogWorkItemAndInvokeUserLambda(_Continuation_func_transformer<_InternalReturnType, _FuncOutputType>::_Perform(_M_function), _M_ancestorTaskImpl->_GetResult(), &_OpWithProgress); +#else + HRESULT hr = _Continuation_func_transformer<_InternalReturnType, _FuncOutputType>::_Perform(_M_function)(_M_ancestorTaskImpl->_GetResult(), &_OpWithProgress); +#endif + typedef details::_GetProgressType::_Value _ProgressType; + + if (FAILED(hr)) throw std::make_exception_ptr(hr); + details::_Task_impl_base::_AsyncInit<_NormalizedContinuationReturnType, _ContinuationReturnType>( + _M_pTask, + Microsoft::WRL::Make>(_OpWithProgress).Get()); + } + + // + // Overload 0-4: _InternalReturnType -> IAsyncActionWithProgress<_ProgressType>* + // + // This is a straight task continuation which returns an async action with progress which will be unwrapped for continuation + // + void _Continue(std::false_type, details::_TypeSelectorAsyncActionWithProgress) const + { + typedef details::_FunctionTypeTraits<_Function, _InternalReturnType>::_FuncRetType _FuncOutputType; + + _FuncOutputType _OpWithProgress; +#if _MSC_VER >= 1800 + HRESULT hr = _LogWorkItemAndInvokeUserLambda(_Continuation_func_transformer<_InternalReturnType, _FuncOutputType>::_Perform(_M_function), _M_ancestorTaskImpl->_GetResult(), &_OpWithProgress); +#else + HRESULT hr = _Continuation_func_transformer<_InternalReturnType, _FuncOutputType>::_Perform(_M_function)(_M_ancestorTaskImpl->_GetResult(), &_OpWithProgress); +#endif + typedef details::_GetProgressType::_Value _ProgressType; + + if (FAILED(hr)) throw std::make_exception_ptr(hr); + details::_Task_impl_base::_AsyncInit<_NormalizedContinuationReturnType, _ContinuationReturnType>( + _M_pTask, + Microsoft::WRL::Make>(_OpWithProgress).Get()); + } + + + // + // Overload 1-0: task<_InternalReturnType> -> _TaskType + // + // This is an exception handling type of continuation which takes the task rather than the task's result. + // + void _Continue(std::true_type, details::_TypeSelectorNoAsync) const + { + typedef task<_InternalReturnType> _FuncInputType; + task<_InternalReturnType> _ResultTask; + _ResultTask._SetImpl(std::move(_M_ancestorTaskImpl)); + _NormalizedContinuationReturnType retVal; +#if _MSC_VER >= 1800 + HRESULT hr = _LogWorkItemAndInvokeUserLambda(_Continuation_func_transformer<_FuncInputType, _ContinuationReturnType>::_Perform(_M_function), std::move(_ResultTask), &retVal); +#else + HRESULT hr = _Continuation_func_transformer<_FuncInputType, _ContinuationReturnType>::_Perform(_M_function)(std::move(_ResultTask), &retVal); +#endif + if (FAILED(hr)) throw std::make_exception_ptr(hr); + _M_pTask->_FinalizeAndRunContinuations(retVal); + } + + // + // Overload 1-1: task<_InternalReturnType> -> IAsyncOperation<_TaskType>^ + // or + // task<_TaskType> + // + // This is an exception handling type of continuation which takes the task rather than + // the task's result. It also returns an async operation or a task which will be unwrapped + // for continuation + // + void _Continue(std::true_type, details::_TypeSelectorAsyncTask) const + { + // The continuation takes a parameter of type task<_Input>, which is the same as the ancestor task. + task<_InternalReturnType> _ResultTask; + _ResultTask._SetImpl(std::move(_M_ancestorTaskImpl)); + _ContinuationReturnType retVal; +#if _MSC_VER >= 1800 + HRESULT hr = _LogWorkItemAndInvokeUserLambda(_M_function, std::move(_ResultTask), &retVal); +#else + HRESULT hr = _M_function(std::move(_ResultTask), &retVal); +#endif + if (FAILED(hr)) throw std::make_exception_ptr(hr); + details::_Task_impl_base::_AsyncInit<_NormalizedContinuationReturnType, _ContinuationReturnType>(_M_pTask, retVal); + } + void _Continue(std::true_type, details::_TypeSelectorAsyncOperation) const + { + // The continuation takes a parameter of type task<_Input>, which is the same as the ancestor task. + task<_InternalReturnType> _ResultTask; + _ResultTask._SetImpl(std::move(_M_ancestorTaskImpl)); + _ContinuationReturnType retVal; +#if _MSC_VER >= 1800 + HRESULT hr = _LogWorkItemAndInvokeUserLambda(_M_function, std::move(_ResultTask), &retVal); +#else + HRESULT hr = _M_function(std::move(_ResultTask), &retVal); +#endif + if (FAILED(hr)) throw std::make_exception_ptr(hr); + details::_Task_impl_base::_AsyncInit<_NormalizedContinuationReturnType, _ContinuationReturnType>(_M_pTask, + Microsoft::WRL::Make>(retVal)); + } + + // + // Overload 1-2: task<_InternalReturnType> -> IAsyncAction* + // + // This is an exception handling type of continuation which takes the task rather than + // the task's result. It also returns an async action which will be unwrapped for continuation + // + void _Continue(std::true_type, details::_TypeSelectorAsyncAction) const + { + // The continuation takes a parameter of type task<_Input>, which is the same as the ancestor task. + task<_InternalReturnType> _ResultTask; + _ResultTask._SetImpl(std::move(_M_ancestorTaskImpl)); + _ContinuationReturnType retVal; +#if _MSC_VER >= 1800 + HRESULT hr = _LogWorkItemAndInvokeUserLambda(_M_function, std::move(_ResultTask), &retVal); +#else + HRESULT hr = _M_function(std::move(_ResultTask), &retVal); +#endif + if (FAILED(hr)) throw std::make_exception_ptr(hr); + details::_Task_impl_base::_AsyncInit<_NormalizedContinuationReturnType, _ContinuationReturnType>(_M_pTask, + Microsoft::WRL::Make(retVal)); + } + + // + // Overload 1-3: task<_InternalReturnType> -> IAsyncOperationWithProgress<_TaskType, _ProgressType>* + // + // This is an exception handling type of continuation which takes the task rather than + // the task's result. It also returns an async operation with progress which will be unwrapped + // for continuation + // + void _Continue(std::true_type, details::_TypeSelectorAsyncOperationWithProgress) const + { + // The continuation takes a parameter of type task<_Input>, which is the same as the ancestor task. + task<_InternalReturnType> _ResultTask; + _ResultTask._SetImpl(std::move(_M_ancestorTaskImpl)); + + typedef details::_GetProgressType::_Value _ProgressType; + _ContinuationReturnType retVal; +#if _MSC_VER >= 1800 + HRESULT hr = _LogWorkItemAndInvokeUserLambda(_M_function, std::move(_ResultTask), &retVal); +#else + HRESULT hr = _M_function(std::move(_ResultTask), &retVal); +#endif + if (FAILED(hr)) throw std::make_exception_ptr(hr); + details::_Task_impl_base::_AsyncInit<_NormalizedContinuationReturnType, _ContinuationReturnType>(_M_pTask, + Microsoft::WRL::Make>(retVal)); + } + + // + // Overload 1-4: task<_InternalReturnType> -> IAsyncActionWithProgress<_ProgressType>* + // + // This is an exception handling type of continuation which takes the task rather than + // the task's result. It also returns an async operation with progress which will be unwrapped + // for continuation + // + void _Continue(std::true_type, details::_TypeSelectorAsyncActionWithProgress) const + { + // The continuation takes a parameter of type task<_Input>, which is the same as the ancestor task. + task<_InternalReturnType> _ResultTask; + _ResultTask._SetImpl(std::move(_M_ancestorTaskImpl)); + + typedef details::_GetProgressType::_Value _ProgressType; + _ContinuationReturnType retVal; +#if _MSC_VER >= 1800 + HRESULT hr = _LogWorkItemAndInvokeUserLambda(_M_function, std::move(_ResultTask), &retVal); +#else + HRESULT hr = _M_function(std::move(_ResultTask), &retVal); +#endif + if (FAILED(hr)) throw std::make_exception_ptr(hr); + details::_Task_impl_base::_AsyncInit<_NormalizedContinuationReturnType, _ContinuationReturnType>(_M_pTask, + Microsoft::WRL::Make>(retVal)); + } + }; + /// + /// Initializes a task using a lambda, function pointer or function object. + /// + template + void _TaskInitWithFunctor(const _Function& _Func) + { + typedef details::_InitFunctorTypeTraits<_InternalReturnType, details::_FunctionTypeTraits<_Function, void>::_FuncRetType> _Async_type_traits; + + _M_Impl->_M_fFromAsync = _Async_type_traits::_IsAsyncTask; + _M_Impl->_M_fUnwrappedTask = _Async_type_traits::_IsUnwrappedTaskOrAsync; +#if _MSC_VER >= 1800 + _M_Impl->_M_taskEventLogger._LogScheduleTask(false); +#endif + _M_Impl->_ScheduleTask(new _InitialTaskHandle<_InternalReturnType, _Function, typename _Async_type_traits::_AsyncKind>(_GetImpl(), _Func), Concurrency::details::_NoInline); + } + + /// + /// Initializes a task using a task completion event. + /// + void _TaskInitNoFunctor(task_completion_event<_ReturnType>& _Event) + { + _Event._RegisterTask(_M_Impl); + } + + /// + /// Initializes a task using an asynchronous operation IAsyncOperation* + /// + template + void _TaskInitAsyncOp(details::_AsyncInfoImpl<_OpType, _CompHandlerType, _ResultType>* _AsyncOp) + { + _M_Impl->_M_fFromAsync = true; +#if _MSC_VER < 1800 + _M_Impl->_SetScheduledEvent(); +#endif + // Mark this task as started here since we can set the state in the constructor without acquiring a lock. Once _AsyncInit + // returns a completion could execute concurrently and the task must be fully initialized before that happens. + _M_Impl->_M_TaskState = details::_Task_impl_base::_Started; + // Pass the shared pointer into _AsyncInit for storage in the Async Callback. + details::_Task_impl_base::_AsyncInit<_ReturnType, _Result>(_M_Impl, _AsyncOp); + } + + /// + /// Initializes a task using an asynchronous operation IAsyncOperation* + /// + template + void _TaskInitNoFunctor(ABI::Windows::Foundation::IAsyncOperation<_Result>* _AsyncOp) + { + _TaskInitAsyncOp<_Result>(Microsoft::WRL::Make>(_AsyncOp).Get()); + } + + /// + /// Initializes a task using an asynchronous operation with progress IAsyncOperationWithProgress* + /// + template + void _TaskInitNoFunctor(ABI::Windows::Foundation::IAsyncOperationWithProgress<_Result, _Progress>* _AsyncOp) + { + _TaskInitAsyncOp<_Result>(Microsoft::WRL::Make>(_AsyncOp).Get()); + } + /// + /// Initializes a task using a callable object. + /// + template + void _TaskInitMaybeFunctor(_Function & _Func, std::true_type) + { + _TaskInitWithFunctor<_ReturnType, _Function>(_Func); + } + + /// + /// Initializes a task using a non-callable object. + /// + template + void _TaskInitMaybeFunctor(_Ty & _Param, std::false_type) + { + _TaskInitNoFunctor(_Param); + } +#if _MSC_VER >= 1800 + template + auto _ThenImpl(const _Function& _Func, const task_options& _TaskOptions) const -> typename details::_ContinuationTypeTraits<_Function, _InternalReturnType>::_TaskOfType + { + if (!_M_Impl) + { + throw Concurrency::invalid_operation("then() cannot be called on a default constructed task."); + } + + Concurrency::details::_CancellationTokenState *_PTokenState = _TaskOptions.has_cancellation_token() ? _TaskOptions.get_cancellation_token()._GetImplValue() : nullptr; + auto _Scheduler = _TaskOptions.has_scheduler() ? _TaskOptions.get_scheduler() : _GetImpl()->_GetScheduler(); + auto _CreationStack = details::_get_internal_task_options(_TaskOptions)._M_hasPresetCreationCallstack ? details::_get_internal_task_options(_TaskOptions)._M_presetCreationCallstack : details::_TaskCreationCallstack(); + return _ThenImpl<_InternalReturnType, _Function>(_Func, _PTokenState, _TaskOptions.get_continuation_context(), _Scheduler, _CreationStack); + } +#endif + /// + /// The one and only implementation of then for void and non-void tasks. + /// + template +#if _MSC_VER >= 1800 + auto _ThenImpl(const _Function& _Func, Concurrency::details::_CancellationTokenState *_PTokenState, const task_continuation_context& _ContinuationContext, Concurrency::scheduler_ptr _Scheduler, details::_TaskCreationCallstack _CreationStack, + details::_TaskInliningMode _InliningMode = Concurrency::details::_NoInline) const -> typename details::_ContinuationTypeTraits<_Function, _InternalReturnType>::_TaskOfType +#else + auto _ThenImpl(const _Function& _Func, Concurrency::details::_CancellationTokenState *_PTokenState, const task_continuation_context& _ContinuationContext, + bool _Aggregating = false, details::_TaskInliningMode _InliningMode = Concurrency::details::_NoInline) const -> typename details::_ContinuationTypeTraits<_Function, _InternalReturnType>::_TaskOfType +#endif + { + if (_M_Impl == nullptr) + { + throw Concurrency::invalid_operation("then() cannot be called on a default constructed task."); + } + + typedef details::_FunctionTypeTraits<_Function, _InternalReturnType> _Function_type_traits; + typedef details::_TaskTypeTraits _Async_type_traits; + typedef typename _Async_type_traits::_TaskRetType _TaskType; + + // + // A **nullptr** token state indicates that it was not provided by the user. In this case, we inherit the antecedent's token UNLESS this is a + // an exception handling continuation. In that case, we break the chain with a _None. That continuation is never canceled unless the user + // explicitly passes the same token. + // + if (_PTokenState == nullptr) + { +#if _MSC_VER >= 1800 + if (_Function_type_traits::_Takes_task::value) +#else + if (_Function_type_traits::_Takes_task()) +#endif + { + _PTokenState = Concurrency::details::_CancellationTokenState::_None(); + } + else + { + _PTokenState = _GetImpl()->_M_pTokenState; + } + } + + task<_TaskType> _ContinuationTask; +#if _MSC_VER >= 1800 + _ContinuationTask._CreateImpl(_PTokenState, _Scheduler); +#else + _ContinuationTask._CreateImpl(_PTokenState); +#endif + _ContinuationTask._GetImpl()->_M_fFromAsync = (_GetImpl()->_M_fFromAsync || _Async_type_traits::_IsAsyncTask); +#if _MSC_VER < 1800 + _ContinuationTask._GetImpl()->_M_fRuntimeAggregate = _Aggregating; +#endif + _ContinuationTask._GetImpl()->_M_fUnwrappedTask = _Async_type_traits::_IsUnwrappedTaskOrAsync; +#if _MSC_VER >= 1800 + _ContinuationTask._SetTaskCreationCallstack(_CreationStack); +#endif + _GetImpl()->_ScheduleContinuation(new _ContinuationTaskHandle<_InternalReturnType, _TaskType, _Function, typename _Function_type_traits::_Takes_task, typename _Async_type_traits::_AsyncKind>( + _GetImpl(), _ContinuationTask._GetImpl(), _Func, _ContinuationContext, _InliningMode)); + + return _ContinuationTask; + } + + // The underlying implementation for this task + typename details::_Task_ptr<_ReturnType>::_Type _M_Impl; +}; + +/// +/// The Parallel Patterns Library (PPL) task class. A task object represents work that can be executed asynchronously, +/// and concurrently with other tasks and parallel work produced by parallel algorithms in the Concurrency Runtime. It produces +/// a result of type on successful completion. Tasks of type task<void> produce no result. +/// A task can be waited upon and canceled independently of other tasks. It can also be composed with other tasks using +/// continuations(then), and join(when_all) and choice(when_any) patterns. +/// +/// +/// For more information, see . +/// +/**/ +template<> +class task +{ +public: + /// + /// The type of the result an object of this class produces. + /// + /**/ + typedef void result_type; + + /// + /// Constructs a task object. + /// + /// + /// The default constructor for a task is only present in order to allow tasks to be used within containers. + /// A default constructed task cannot be used until you assign a valid task to it. Methods such as get, wait or then + /// will throw an invalid_argument exception when called on a default constructed task. + /// A task that is created from a task_completion_event will complete (and have its continuations scheduled) when the task + /// completion event is set. + /// The version of the constructor that takes a cancellation token creates a task that can be canceled using the + /// cancellation_token_source the token was obtained from. Tasks created without a cancellation token are not cancelable. + /// Tasks created from a Windows::Foundation::IAsyncInfo interface or a lambda that returns an IAsyncInfo interface + /// reach their terminal state when the enclosed Windows Runtime asynchronous operation or action completes. Similarly, tasks created + /// from a lamda that returns a task<result_type> reach their terminal state when the inner task reaches its terminal state, + /// and not when the lamda returns. + /// task behaves like a smart pointer and is safe to pass around by value. It can be accessed by multiple threads + /// without the need for locks. + /// The constructor overloads that take a Windows::Foundation::IAsyncInfo interface or a lambda returning such an interface, are only available + /// to Windows Store apps. + /// For more information, see . + /// + /**/ + task() : _M_unitTask() + { + // The default constructor should create a task with a nullptr impl. This is a signal that the + // task is not usable and should throw if any wait(), get() or then() APIs are used. + } +#if _MSC_VER < 1800 + /// + /// Constructs a task object. + /// + /// + /// The type of the parameter from which the task is to be constructed. + /// + /// + /// The parameter from which the task is to be constructed. This could be a lambda, a function object, a task_completion_event<result_type> + /// object, or a Windows::Foundation::IAsyncInfo if you are using tasks in your Windows Store app. The lambda or function + /// object should be a type equivalent to std::function<X(void)>, where X can be a variable of type result_type, + /// task<result_type>, or a Windows::Foundation::IAsyncInfo in Windows Store apps. + /// + /// + /// The default constructor for a task is only present in order to allow tasks to be used within containers. + /// A default constructed task cannot be used until you assign a valid task to it. Methods such as get, wait or then + /// will throw an invalid_argument exception when called on a default constructed task. + /// A task that is created from a task_completion_event will complete (and have its continuations scheduled) when the task + /// completion event is set. + /// The version of the constructor that takes a cancellation token creates a task that can be canceled using the + /// cancellation_token_source the token was obtained from. Tasks created without a cancellation token are not cancelable. + /// Tasks created from a Windows::Foundation::IAsyncInfo interface or a lambda that returns an IAsyncInfo interface + /// reach their terminal state when the enclosed Windows Runtime asynchronous operation or action completes. Similarly, tasks created + /// from a lamda that returns a task<result_type> reach their terminal state when the inner task reaches its terminal state, + /// and not when the lamda returns. + /// task behaves like a smart pointer and is safe to pass around by value. It can be accessed by multiple threads + /// without the need for locks. + /// The constructor overloads that take a Windows::Foundation::IAsyncInfo interface or a lambda returning such an interface, are only available + /// to Windows Store apps. + /// For more information, see . + /// + /**/ + template + __declspec(noinline) // Ask for no inlining so that the _ReturnAddress intrinsic gives us the expected result + explicit task(_Ty _Param) + { + details::_ValidateTaskConstructorArgs(_Param); + + _M_unitTask._CreateImpl(Concurrency::cancellation_token::none()._GetImplValue()); + // Do not move the next line out of this function. It is important that _ReturnAddress() evaluate to the the call site of the task constructor. + _M_unitTask._SetTaskCreationAddressHint(_ReturnAddress()); + + _TaskInitMaybeFunctor(_Param, details::_IsCallable(_Param, 0, 0, 0)); + } +#endif + /// + /// Constructs a task object. + /// + /// + /// The type of the parameter from which the task is to be constructed. + /// + /// + /// The parameter from which the task is to be constructed. This could be a lambda, a function object, a task_completion_event<result_type> + /// object, or a Windows::Foundation::IAsyncInfo if you are using tasks in your Windows Store app. The lambda or function + /// object should be a type equivalent to std::function<X(void)>, where X can be a variable of type result_type, + /// task<result_type>, or a Windows::Foundation::IAsyncInfo in Windows Store apps. + /// + /// + /// The cancellation token to associate with this task. A task created without a cancellation token cannot be canceled. It implicitly receives + /// the token cancellation_token::none(). + /// + /// + /// The default constructor for a task is only present in order to allow tasks to be used within containers. + /// A default constructed task cannot be used until you assign a valid task to it. Methods such as get, wait or then + /// will throw an invalid_argument exception when called on a default constructed task. + /// A task that is created from a task_completion_event will complete (and have its continuations scheduled) when the task + /// completion event is set. + /// The version of the constructor that takes a cancellation token creates a task that can be canceled using the + /// cancellation_token_source the token was obtained from. Tasks created without a cancellation token are not cancelable. + /// Tasks created from a Windows::Foundation::IAsyncInfo interface or a lambda that returns an IAsyncInfo interface + /// reach their terminal state when the enclosed Windows Runtime asynchronous operation or action completes. Similarly, tasks created + /// from a lamda that returns a task<result_type> reach their terminal state when the inner task reaches its terminal state, + /// and not when the lamda returns. + /// task behaves like a smart pointer and is safe to pass around by value. It can be accessed by multiple threads + /// without the need for locks. + /// The constructor overloads that take a Windows::Foundation::IAsyncInfo interface or a lambda returning such an interface, are only available + /// to Windows Store apps. + /// For more information, see . + /// + /**/ + template + __declspec(noinline) // Ask for no inlining so that the _ReturnAddress intrinsic gives us the expected result +#if _MSC_VER >= 1800 + explicit task(_Ty _Param, const task_options& _TaskOptions = task_options()) +#else + explicit task(_Ty _Param, Concurrency::cancellation_token _CancellationToken) +#endif + { + details::_ValidateTaskConstructorArgs(_Param); +#if _MSC_VER >= 1800 + _M_unitTask._CreateImpl(_TaskOptions.get_cancellation_token()._GetImplValue(), _TaskOptions.get_scheduler()); +#else + _M_unitTask._CreateImpl(_CancellationToken._GetImplValue()); +#endif + // Do not move the next line out of this function. It is important that _ReturnAddress() evaluate to the the call site of the task constructor. +#if _MSC_VER >= 1800 + _M_unitTask._SetTaskCreationCallstack(details::_get_internal_task_options(_TaskOptions)._M_hasPresetCreationCallstack ? details::_get_internal_task_options(_TaskOptions)._M_presetCreationCallstack : _CAPTURE_CALLSTACK()); +#else + _M_unitTask._SetTaskCreationAddressHint(_ReturnAddress()); +#endif + _TaskInitMaybeFunctor(_Param, details::_IsCallable(_Param, 0, 0, 0)); + } + + /// + /// Constructs a task object. + /// + /// + /// The source task object. + /// + /// + /// The default constructor for a task is only present in order to allow tasks to be used within containers. + /// A default constructed task cannot be used until you assign a valid task to it. Methods such as get, wait or then + /// will throw an invalid_argument exception when called on a default constructed task. + /// A task that is created from a task_completion_event will complete (and have its continuations scheduled) when the task + /// completion event is set. + /// The version of the constructor that takes a cancellation token creates a task that can be canceled using the + /// cancellation_token_source the token was obtained from. Tasks created without a cancellation token are not cancelable. + /// Tasks created from a Windows::Foundation::IAsyncInfo interface or a lambda that returns an IAsyncInfo interface + /// reach their terminal state when the enclosed Windows Runtime asynchronous operation or action completes. Similarly, tasks created + /// from a lamda that returns a task<result_type> reach their terminal state when the inner task reaches its terminal state, + /// and not when the lamda returns. + /// task behaves like a smart pointer and is safe to pass around by value. It can be accessed by multiple threads + /// without the need for locks. + /// The constructor overloads that take a Windows::Foundation::IAsyncInfo interface or a lambda returning such an interface, are only available + /// to Windows Store apps. + /// For more information, see . + /// + /**/ + task(const task& _Other) : _M_unitTask(_Other._M_unitTask){} + + /// + /// Constructs a task object. + /// + /// + /// The source task object. + /// + /// + /// The default constructor for a task is only present in order to allow tasks to be used within containers. + /// A default constructed task cannot be used until you assign a valid task to it. Methods such as get, wait or then + /// will throw an invalid_argument exception when called on a default constructed task. + /// A task that is created from a task_completion_event will complete (and have its continuations scheduled) when the task + /// completion event is set. + /// The version of the constructor that takes a cancellation token creates a task that can be canceled using the + /// cancellation_token_source the token was obtained from. Tasks created without a cancellation token are not cancelable. + /// Tasks created from a Windows::Foundation::IAsyncInfo interface or a lambda that returns an IAsyncInfo interface + /// reach their terminal state when the enclosed Windows Runtime asynchronous operation or action completes. Similarly, tasks created + /// from a lamda that returns a task<result_type> reach their terminal state when the inner task reaches its terminal state, + /// and not when the lamda returns. + /// task behaves like a smart pointer and is safe to pass around by value. It can be accessed by multiple threads + /// without the need for locks. + /// The constructor overloads that take a Windows::Foundation::IAsyncInfo interface or a lambda returning such an interface, are only available + /// to Windows Store apps. + /// For more information, see . + /// + /**/ + task(task&& _Other) : _M_unitTask(std::move(_Other._M_unitTask)) {} + + /// + /// Replaces the contents of one task object with another. + /// + /// + /// The source task object. + /// + /// + /// As task behaves like a smart pointer, after a copy assignment, this task objects represents the same + /// actual task as does. + /// + /**/ + task& operator=(const task& _Other) + { + if (this != &_Other) + { + _M_unitTask = _Other._M_unitTask; + } + return *this; + } + + /// + /// Replaces the contents of one task object with another. + /// + /// + /// The source task object. + /// + /// + /// As task behaves like a smart pointer, after a copy assignment, this task objects represents the same + /// actual task as does. + /// + /**/ + task& operator=(task&& _Other) + { + if (this != &_Other) + { + _M_unitTask = std::move(_Other._M_unitTask); + } + return *this; + } +#if _MSC_VER < 1800 + /// + /// Adds a continuation task to this task. + /// + /// + /// The type of the function object that will be invoked by this task. + /// + /// + /// The continuation function to execute when this task completes. This continuation function must take as input + /// a variable of either result_type or task<result_type>, where result_type is the type + /// of the result this task produces. + /// + /// + /// The newly created continuation task. The result type of the returned task is determined by what returns. + /// + /// + /// The overloads of then that take a lambda or functor that returns a Windows::Foundation::IAsyncInfo interface, are only available + /// to Windows Store apps. + /// For more information on how to use task continuations to compose asynchronous work, see . + /// + /**/ + template + __declspec(noinline) // Ask for no inlining so that the _ReturnAddress intrinsic gives us the expected result + auto then(const _Function& _Func) const -> typename details::_ContinuationTypeTraits<_Function, void>::_TaskOfType + { + auto _ContinuationTask = _M_unitTask._ThenImpl(_Func, nullptr, task_continuation_context::use_default()); + // Do not move the next line out of this function. It is important that _ReturnAddress() evaluate to the the call site of then. + _ContinuationTask._SetTaskCreationAddressHint(_ReturnAddress()); + return _ContinuationTask; + } +#endif + /// + /// Adds a continuation task to this task. + /// + /// + /// The type of the function object that will be invoked by this task. + /// + /// + /// The continuation function to execute when this task completes. This continuation function must take as input + /// a variable of either result_type or task<result_type>, where result_type is the type + /// of the result this task produces. + /// + /// + /// The cancellation token to associate with the continuation task. A continuation task that is created without a cancellation token will inherit + /// the token of its antecedent task. + /// + /// + /// The newly created continuation task. The result type of the returned task is determined by what returns. + /// + /// + /// The overloads of then that take a lambda or functor that returns a Windows::Foundation::IAsyncInfo interface, are only available + /// to Windows Store apps. + /// For more information on how to use task continuations to compose asynchronous work, see . + /// + /**/ + template + __declspec(noinline) // Ask for no inlining so that the _ReturnAddress intrinsic gives us the expected result +#if _MSC_VER >= 1800 + auto then(const _Function& _Func, task_options _TaskOptions = task_options()) const -> typename details::_ContinuationTypeTraits<_Function, void>::_TaskOfType + { + details::_get_internal_task_options(_TaskOptions)._set_creation_callstack(_CAPTURE_CALLSTACK()); + return _M_unitTask._ThenImpl(_Func, _TaskOptions); + } +#else + auto then(const _Function& _Func, Concurrency::cancellation_token _CancellationToken) const -> typename details::_ContinuationTypeTraits<_Function, void>::_TaskOfType + { + auto _ContinuationTask = _M_unitTask._ThenImpl(_Func, _CancellationToken._GetImplValue(), task_continuation_context::use_default()); + // Do not move the next line out of this function. It is important that _ReturnAddress() evaluate to the the call site of then. + _ContinuationTask._SetTaskCreationAddressHint(_ReturnAddress()); + return _ContinuationTask; + } + /// + /// Adds a continuation task to this task. + /// + /// + /// The type of the function object that will be invoked by this task. + /// + /// + /// The continuation function to execute when this task completes. This continuation function must take as input + /// a variable of either result_type or task<result_type>, where result_type is the type + /// of the result this task produces. + /// + /// + /// A variable that specifies where the continuation should execute. This variable is only useful when used in a + /// Windows Store app. For more information, see task_continuation_context + /// + /// + /// The newly created continuation task. The result type of the returned task is determined by what returns. + /// + /// + /// The overloads of then that take a lambda or functor that returns a Windows::Foundation::IAsyncInfo interface, are only available + /// to Windows Store apps. + /// For more information on how to use task continuations to compose asynchronous work, see . + /// + /**/ + template + __declspec(noinline) // Ask for no inlining so that the _ReturnAddress intrinsic gives us the expected result + auto then(const _Function& _Func, task_continuation_context _ContinuationContext) const -> typename details::_ContinuationTypeTraits<_Function, void>::_TaskOfType + { + auto _ContinuationTask = _M_unitTask._ThenImpl(_Func, nullptr, _ContinuationContext); + // Do not move the next line out of this function. It is important that _ReturnAddress() evaluate to the the call site of then. + _ContinuationTask._SetTaskCreationAddressHint(_ReturnAddress()); + return _ContinuationTask; + + } +#endif + /// + /// Adds a continuation task to this task. + /// + /// + /// The type of the function object that will be invoked by this task. + /// + /// + /// The continuation function to execute when this task completes. This continuation function must take as input + /// a variable of either result_type or task<result_type>, where result_type is the type + /// of the result this task produces. + /// + /// + /// The cancellation token to associate with the continuation task. A continuation task that is created without a cancellation token will inherit + /// the token of its antecedent task. + /// + /// + /// A variable that specifies where the continuation should execute. This variable is only useful when used in a + /// Windows Store app. For more information, see task_continuation_context + /// + /// + /// The newly created continuation task. The result type of the returned task is determined by what returns. + /// + /// + /// The overloads of then that take a lambda or functor that returns a Windows::Foundation::IAsyncInfo interface, are only available + /// to Windows Store apps. + /// For more information on how to use task continuations to compose asynchronous work, see . + /// + /**/ + template + __declspec(noinline) // Ask for no inlining so that the _ReturnAddress intrinsic gives us the expected result +#if _MSC_VER >= 1800 + auto then(const _Function& _Func, Concurrency::cancellation_token _CancellationToken, task_continuation_context _ContinuationContext) const -> typename details::_ContinuationTypeTraits<_Function, void>::_TaskOfType + { + task_options _TaskOptions(_CancellationToken, _ContinuationContext); + details::_get_internal_task_options(_TaskOptions)._set_creation_callstack(_CAPTURE_CALLSTACK()); + return _M_unitTask._ThenImpl(_Func, _TaskOptions); + } +#else + auto then(const _Function& _Func, Concurrency::cancellation_token _CancellationToken, task_continuation_context _ContinuationContext) const -> typename details::_ContinuationTypeTraits<_Function, void>::_TaskOfType + { + auto _ContinuationTask = _M_unitTask._ThenImpl(_Func, _CancellationToken._GetImplValue(), _ContinuationContext); + // Do not move the next line out of this function. It is important that _ReturnAddress() evaluate to the the call site of then. + _ContinuationTask._SetTaskCreationAddressHint(_ReturnAddress()); + return _ContinuationTask; + } +#endif + + /// + /// Waits for this task to reach a terminal state. It is possible for wait to execute the task inline, if all of the tasks + /// dependencies are satisfied, and it has not already been picked up for execution by a background worker. + /// + /// + /// A task_status value which could be either completed or canceled. If the task encountered an exception + /// during execution, or an exception was propagated to it from an antecedent task, wait will throw that exception. + /// + /**/ + task_status wait() const + { + return _M_unitTask.wait(); + } + + /// + /// Returns the result this task produced. If the task is not in a terminal state, a call to get will wait for the task to + /// finish. This method does not return a value when called on a task with a result_type of void. + /// + /// + /// If the task is canceled, a call to get will throw a task_canceled exception. If the task + /// encountered an different exception or an exception was propagated to it from an antecedent task, a call to get will throw that exception. + /// + /**/ + void get() const + { + _M_unitTask.get(); + } +#if _MSC_VER >= 1800 + + /// + /// Determines if the task is completed. + /// + /// + /// True if the task has completed, false otherwise. + /// + /// + /// The function returns true if the task is completed or canceled (with or without user exception). + /// + bool is_done() const + { + return _M_unitTask.is_done(); + } + + /// + /// Returns the scheduler for this task + /// + /// + /// A pointer to the scheduler + /// + Concurrency::scheduler_ptr scheduler() const + { + return _M_unitTask.scheduler(); + } +#endif + /// + /// Determines whether the task unwraps a Windows Runtime IAsyncInfo interface or is descended from such a task. + /// + /// + /// true if the task unwraps an IAsyncInfo interface or is descended from such a task, false otherwise. + /// + /**/ + bool is_apartment_aware() const + { + return _M_unitTask.is_apartment_aware(); + } + + /// + /// Determines whether two task objects represent the same internal task. + /// + /// + /// true if the objects refer to the same underlying task, and false otherwise. + /// + /**/ + bool operator==(const task& _Rhs) const + { + return (_M_unitTask == _Rhs._M_unitTask); + } + + /// + /// Determines whether two task objects represent different internal tasks. + /// + /// + /// true if the objects refer to different underlying tasks, and false otherwise. + /// + /**/ + bool operator!=(const task& _Rhs) const + { + return !operator==(_Rhs); + } + + /// + /// Create an underlying task implementation. + /// +#if _MSC_VER >= 1800 + void _CreateImpl(Concurrency::details::_CancellationTokenState * _Ct, Concurrency::scheduler_ptr _Scheduler) + { + _M_unitTask._CreateImpl(_Ct, _Scheduler); + } +#else + void _CreateImpl(Concurrency::details::_CancellationTokenState * _Ct) + { + _M_unitTask._CreateImpl(_Ct); + } +#endif + + /// + /// Return the underlying implementation for this task. + /// + const details::_Task_ptr::_Type & _GetImpl() const + { + return _M_unitTask._M_Impl; + } + + /// + /// Set the implementation of the task to be the supplied implementaion. + /// + void _SetImpl(const details::_Task_ptr::_Type & _Impl) + { + _M_unitTask._SetImpl(_Impl); + } + + /// + /// Set the implementation of the task to be the supplied implementaion using a move instead of a copy. + /// + void _SetImpl(details::_Task_ptr::_Type && _Impl) + { + _M_unitTask._SetImpl(std::move(_Impl)); + } + + /// + /// Sets a property determining whether the task is apartment aware. + /// + void _SetAsync(bool _Async = true) + { + _M_unitTask._SetAsync(_Async); + } + + /// + /// Sets a field in the task impl to the return address for calls to the task constructors and the then method. + /// +#if _MSC_VER >= 1800 + void _SetTaskCreationCallstack(const details::_TaskCreationCallstack &_callstack) + { + _M_unitTask._SetTaskCreationCallstack(_callstack); + } +#else + void _SetTaskCreationAddressHint(void* _Address) + { + _M_unitTask._SetTaskCreationAddressHint(_Address); + } +#endif + + /// + /// An internal version of then that takes additional flags and executes the continuation inline. Used for runtime internal continuations only. + /// + template +#if _MSC_VER >= 1800 + auto _Then(const _Function& _Func, Concurrency::details::_CancellationTokenState *_PTokenState, + details::_TaskInliningMode _InliningMode = Concurrency::details::_ForceInline) const -> typename details::_ContinuationTypeTraits<_Function, void>::_TaskOfType + { + // inherit from antecedent + auto _Scheduler = _GetImpl()->_GetScheduler(); + + return _M_unitTask._ThenImpl(_Func, _PTokenState, task_continuation_context::use_default(), _Scheduler, _CAPTURE_CALLSTACK(), _InliningMode); + } +#else + auto _Then(const _Function& _Func, Concurrency::details::_CancellationTokenState *_PTokenState, + bool _Aggregating, details::_TaskInliningMode _InliningMode = Concurrency::details::_ForceInline) const -> typename details::_ContinuationTypeTraits<_Function, void>::_TaskOfType + { + return _M_unitTask._ThenImpl(_Func, _PTokenState, task_continuation_context::use_default(), _Aggregating, _InliningMode); + } +#endif + +private: + template friend class task; + template friend class task_completion_event; + + /// + /// Initializes a task using a task completion event. + /// + void _TaskInitNoFunctor(task_completion_event& _Event) + { + _M_unitTask._TaskInitNoFunctor(_Event._M_unitEvent); + } + /// + /// Initializes a task using an asynchronous action IAsyncAction* + /// + void _TaskInitNoFunctor(ABI::Windows::Foundation::IAsyncAction* _AsyncAction) + { + _M_unitTask._TaskInitAsyncOp(Microsoft::WRL::Make(_AsyncAction).Get()); + } + + /// + /// Initializes a task using an asynchronous action with progress IAsyncActionWithProgress<_P>* + /// + template + void _TaskInitNoFunctor(ABI::Windows::Foundation::IAsyncActionWithProgress<_P>* _AsyncActionWithProgress) + { + _M_unitTask._TaskInitAsyncOp(Microsoft::WRL::Make>(_AsyncActionWithProgress).Get()); + } + /// + /// Initializes a task using a callable object. + /// + template + void _TaskInitMaybeFunctor(_Function & _Func, std::true_type) + { + _M_unitTask._TaskInitWithFunctor(_Func); + } + + /// + /// Initializes a task using a non-callable object. + /// + template + void _TaskInitMaybeFunctor(_T & _Param, std::false_type) + { + _TaskInitNoFunctor(_Param); + } + + // The void task contains a task of a dummy type so common code can be used for tasks with void and non-void results. + task _M_unitTask; +}; + +namespace details +{ + + /// + /// The following type traits are used for the create_task function. + /// + + // Unwrap task + template + _Ty _GetUnwrappedType(task<_Ty>); + + // Unwrap all supported types + template + auto _GetUnwrappedReturnType(_Ty _Arg, int) -> decltype(_GetUnwrappedType(_Arg)); + // fallback + template + _Ty _GetUnwrappedReturnType(_Ty, ...); + + /// + /// _GetTaskType functions will retrieve task type T in task[T](Arg), + /// for given constructor argument Arg and its property "callable". + /// It will automatically unwrap argument to get the final return type if necessary. + /// + + // Non-Callable + template + _Ty _GetTaskType(task_completion_event<_Ty>, std::false_type); + + // Non-Callable + template + auto _GetTaskType(_Ty _NonFunc, std::false_type) -> decltype(_GetUnwrappedType(_NonFunc)); + + // Callable + template + auto _GetTaskType(_Ty _Func, std::true_type) -> decltype(_GetUnwrappedReturnType(stdx::declval<_FunctionTypeTraits<_Ty, void>::_FuncRetType>(), 0)); + + // Special callable returns void + void _GetTaskType(std::function, std::true_type); + struct _BadArgType{}; + + template + auto _FilterValidTaskType(_Ty _Param, int) -> decltype(_GetTaskType(_Param, _IsCallable<_ReturnType>(_Param, 0, 0, 0))); + + template + _BadArgType _FilterValidTaskType(_Ty _Param, ...); + + template + struct _TaskTypeFromParam + { + typedef decltype(_FilterValidTaskType<_ReturnType>(stdx::declval<_Ty>(), 0)) _Type; + }; +} + + +/// +/// Creates a PPL task object. create_task can be used anywhere you would have used a task constructor. +/// It is provided mainly for convenience, because it allows use of the auto keyword while creating tasks. +/// +/// +/// The type of the parameter from which the task is to be constructed. +/// +/// +/// The parameter from which the task is to be constructed. This could be a lambda or function object, a task_completion_event +/// object, a different task object, or a Windows::Foundation::IAsyncInfo interface if you are using tasks in your Windows Store app. +/// +/// +/// A new task of type T, that is inferred from . +/// +/// +/// The first overload behaves like a task constructor that takes a single parameter. +/// The second overload associates the cancellation token provided with the newly created task. If you use this overload you are not +/// allowed to pass in a different task object as the first parameter. +/// The type of the returned task is inferred from the first parameter to the function. If is a task_completion_event<T>, +/// a task<T>, or a functor that returns either type T or task<T>, the type of the created task is task<T>. +/// In a Windows Store app, if is of type Windows::Foundation::IAsyncOperation<T>^ or +/// Windows::Foundation::IAsyncOperationWithProgress<T,P>^, or a functor that returns either of those types, the created task will be of type task<T>. +/// If is of type Windows::Foundation::IAsyncAction^ or Windows::Foundation::IAsyncActionWithProgress<P>^, or a functor +/// that returns either of those types, the created task will have type task<void>. +/// +/// +/// +/**/ +template +__declspec(noinline) +#if _MSC_VER >= 1800 +auto create_task(_Ty _Param, task_options _TaskOptions = task_options()) -> task::_Type> +#else +auto create_task(_Ty _Param) -> task::_Type> +#endif +{ + static_assert(!std::is_same::_Type, details::_BadArgType>::value, + "incorrect argument for create_task; can be a callable object, an asynchronous operation, or a task_completion_event" + ); +#if _MSC_VER >= 1800 + details::_get_internal_task_options(_TaskOptions)._set_creation_callstack(_CAPTURE_CALLSTACK()); + task::_Type> _CreatedTask(_Param, _TaskOptions); +#else + task::_Type> _CreatedTask(_Param); + // Ideally we would like to forceinline create_task, but __forceinline does nothing on debug builds. Therefore, we ask for no inlining + // and overwrite the creation address hint set by the task constructor. DO NOT REMOVE this next line from create_task. It is + // essential that _ReturnAddress() evaluate to the instruction right after the call to create_task in client code. + _CreatedTask._SetTaskCreationAddressHint(_ReturnAddress()); +#endif + return _CreatedTask; +} + +/// +/// Creates a PPL task object. create_task can be used anywhere you would have used a task constructor. +/// It is provided mainly for convenience, because it allows use of the auto keyword while creating tasks. +/// +/// +/// The type of the parameter from which the task is to be constructed. +/// +/// +/// The parameter from which the task is to be constructed. This could be a lambda or function object, a task_completion_event +/// object, a different task object, or a Windows::Foundation::IAsyncInfo interface if you are using tasks in your Windows Store app. +/// +/// +/// The cancellation token to associate with the task. When the source for this token is canceled, cancellation will be requested on the task. +/// +/// +/// A new task of type T, that is inferred from . +/// +/// +/// The first overload behaves like a task constructor that takes a single parameter. +/// The second overload associates the cancellation token provided with the newly created task. If you use this overload you are not +/// allowed to pass in a different task object as the first parameter. +/// The type of the returned task is inferred from the first parameter to the function. If is a task_completion_event<T>, +/// a task<T>, or a functor that returns either type T or task<T>, the type of the created task is task<T>. +/// In a Windows Store app, if is of type Windows::Foundation::IAsyncOperation<T>^ or +/// Windows::Foundation::IAsyncOperationWithProgress<T,P>^, or a functor that returns either of those types, the created task will be of type task<T>. +/// If is of type Windows::Foundation::IAsyncAction^ or Windows::Foundation::IAsyncActionWithProgress<P>^, or a functor +/// that returns either of those types, the created task will have type task<void>. +/// +/// +/// +/**/ +#if _MSC_VER >= 1800 +template +__declspec(noinline) +task<_ReturnType> create_task(const task<_ReturnType>& _Task) +{ + task<_ReturnType> _CreatedTask(_Task); + return _CreatedTask; +} +#else +template +__declspec(noinline) +auto create_task(_Ty _Param, Concurrency::cancellation_token _Token) -> task::_Type> +{ + static_assert(!std::is_same::_Type, details::_BadArgType>::value, + "incorrect argument for create_task; can be a callable object, an asynchronous operation, or a task_completion_event" + ); + task::_Type> _CreatedTask(_Param, _Token); + // Ideally we would like to forceinline create_task, but __forceinline does nothing on debug builds. Therefore, we ask for no inlining + // and overwrite the creation address hint set by the task constructor. DO NOT REMOVE this next line from create_task. It is + // essential that _ReturnAddress() evaluate to the instruction right after the call to create_task in client code. + _CreatedTask._SetTaskCreationAddressHint(_ReturnAddress()); + return _CreatedTask; +} +#endif + +namespace details +{ + template + task*>()))>::type> _To_task_helper(ABI::Windows::Foundation::IAsyncOperation<_T>* op) + { + return task<_T>(op); + } + + template + task*>()))>::type> _To_task_helper(ABI::Windows::Foundation::IAsyncOperationWithProgress<_T, _Progress>* op) + { + return task<_T>(op); + } + + inline task _To_task_helper(ABI::Windows::Foundation::IAsyncAction* op) + { + return task(op); + } + + template + task _To_task_helper(ABI::Windows::Foundation::IAsyncActionWithProgress<_Progress>* op) + { + return task(op); + } + + template + class _ProgressDispatcherBase + { + public: + + virtual ~_ProgressDispatcherBase() + { + } + + virtual void _Report(const _ProgressType& _Val) = 0; + }; + + template + class _ProgressDispatcher : public _ProgressDispatcherBase<_ProgressType> + { + public: + + virtual ~_ProgressDispatcher() + { + } + + _ProgressDispatcher(_ClassPtrType _Ptr) : _M_ptr(_Ptr) + { + } + + virtual void _Report(const _ProgressType& _Val) + { + _M_ptr->_FireProgress(_Val); + } + + private: + + _ClassPtrType _M_ptr; + }; +} // namespace details + + +/// +/// The progress reporter class allows reporting progress notifications of a specific type. Each progress_reporter object is bound +/// to a particular asynchronous action or operation. +/// +/// +/// The payload type of each progress notification reported through the progress reporter. +/// +/// +/// This type is only available to Windows Store apps. +/// +/// +/**/ +template +class progress_reporter +{ + typedef std::shared_ptr> _PtrType; + +public: + + /// + /// Sends a progress report to the asynchronous action or operation to which this progress reporter is bound. + /// + /// + /// The payload to report through a progress notification. + /// + /**/ + void report(const _ProgressType& _Val) const + { + _M_dispatcher->_Report(_Val); + } + + template + static progress_reporter _CreateReporter(_ClassPtrType _Ptr) + { + progress_reporter _Reporter; + details::_ProgressDispatcherBase<_ProgressType> *_PDispatcher = new details::_ProgressDispatcher<_ProgressType, _ClassPtrType>(_Ptr); + _Reporter._M_dispatcher = _PtrType(_PDispatcher); + return _Reporter; + } + progress_reporter() {} + +private: + progress_reporter(details::_ProgressReporterCtorArgType); + + _PtrType _M_dispatcher; +}; + +namespace details +{ + // + // maps internal definitions for AsyncStatus and defines states that are not client visible + // + enum _AsyncStatusInternal + { + _AsyncCreated = -1, // externally invisible + // client visible states (must match AsyncStatus exactly) + _AsyncStarted = ABI::Windows::Foundation::AsyncStatus::Started, // 0 + _AsyncCompleted = ABI::Windows::Foundation::AsyncStatus::Completed, // 1 + _AsyncCanceled = ABI::Windows::Foundation::AsyncStatus::Canceled, // 2 + _AsyncError = ABI::Windows::Foundation::AsyncStatus::Error, // 3 + // non-client visible internal states + _AsyncCancelPending, + _AsyncClosed, + _AsyncUndefined + }; + + // + // designates whether the "GetResults" method returns a single result (after complete fires) or multiple results + // (which are progressively consumable between Start state and before Close is called) + // + enum _AsyncResultType + { + SingleResult = 0x0001, + MultipleResults = 0x0002 + }; + + template + struct _ProgressTypeTraits + { + static const bool _TakesProgress = false; + typedef void _ProgressType; + }; + + template + struct _ProgressTypeTraits> + { + static const bool _TakesProgress = true; + typedef typename _T _ProgressType; + }; + + template::value, bool bTakesProgress = _ProgressTypeTraits<_T>::_TakesProgress> + struct _TokenTypeTraits + { + static const bool _TakesToken = false; + typedef typename _T _ReturnType; + }; + + template + struct _TokenTypeTraits<_T, false, true> + { + static const bool _TakesToken = false; + typedef void _ReturnType; + }; + + template + struct _TokenTypeTraits<_T, true, false> + { + static const bool _TakesToken = true; + typedef void _ReturnType; + }; + + template::_ArgumentCount> + struct _CAFunctorOptions + { + static const bool _TakesProgress = false; + static const bool _TakesToken = false; + typedef void _ProgressType; + typedef void _ReturnType; + }; + + template + struct _CAFunctorOptions<_T, 1> + { + private: + + typedef typename _FunctorTypeTraits<_T>::_Argument1Type _Argument1Type; + + public: + + static const bool _TakesProgress = _ProgressTypeTraits<_Argument1Type>::_TakesProgress; + static const bool _TakesToken = _TokenTypeTraits<_Argument1Type>::_TakesToken; + typedef typename _ProgressTypeTraits<_Argument1Type>::_ProgressType _ProgressType; + typedef typename _TokenTypeTraits<_Argument1Type>::_ReturnType _ReturnType; + }; + + template + struct _CAFunctorOptions<_T, 2> + { + private: + + typedef typename _FunctorTypeTraits<_T>::_Argument1Type _Argument1Type; + typedef typename _FunctorTypeTraits<_T>::_Argument2Type _Argument2Type; + + public: + + static const bool _TakesProgress = _ProgressTypeTraits<_Argument1Type>::_TakesProgress; + static const bool _TakesToken = !_TakesProgress ? true : _TokenTypeTraits<_Argument2Type>::_TakesToken; + typedef typename _ProgressTypeTraits<_Argument1Type>::_ProgressType _ProgressType; + typedef typename _TokenTypeTraits<_Argument2Type>::_ReturnType _ReturnType; + }; + + template + struct _CAFunctorOptions<_T, 3> + { + private: + + typedef typename _FunctorTypeTraits<_T>::_Argument1Type _Argument1Type; + + public: + + static const bool _TakesProgress = true; + static const bool _TakesToken = true; + typedef typename _ProgressTypeTraits<_Argument1Type>::_ProgressType _ProgressType; + typedef typename _FunctorTypeTraits<_T>::_Argument3Type _ReturnType; + }; + + class _Zip + { + }; + + // *************************************************************************** + // Async Operation Task Generators + // + + // + // Functor returns an IAsyncInfo - result needs to be wrapped in a task: + // + template + struct _SelectorTaskGenerator + { +#if _MSC_VER >= 1800 + template + static task<_ReturnType> _GenerateTask_0(const _Function& _Func, Concurrency::cancellation_token_source _Cts, _ReturnType* _pRet, const _TaskCreationCallstack & _callstack) + { + task_options _taskOptinos(_Cts.get_token()); + details::_get_internal_task_options(_taskOptinos)._set_creation_callstack(_callstack); + return task<_ReturnType>(_Func(_pRet), _taskOptinos); + } + + template + static task<_ReturnType> _GenerateTask_1C(const _Function& _Func, Concurrency::cancellation_token_source _Cts, _ReturnType* _pRet, const _TaskCreationCallstack & _callstack) + { + task_options _taskOptinos(_Cts.get_token()); + details::_get_internal_task_options(_taskOptinos)._set_creation_callstack(_callstack); + return task<_ReturnType>(_Func(_Cts.get_token(), _pRet), _taskOptinos); + } + + template + static task<_ReturnType> _GenerateTask_1P(const _Function& _Func, const _ProgressObject& _Progress, Concurrency::cancellation_token_source _Cts, _ReturnType* _pRet, const _TaskCreationCallstack & _callstack) + { + task_options _taskOptinos(_Cts.get_token()); + details::_get_internal_task_options(_taskOptinos)._set_creation_callstack(_callstack); + return task<_ReturnType>(_Func(_Progress, _pRet), _taskOptinos); + } + + template + static task<_ReturnType> _GenerateTask_2PC(const _Function& _Func, const _ProgressObject& _Progress, Concurrency::cancellation_token_source _Cts, _ReturnType* _pRet, const _TaskCreationCallstack & _callstack) + { + task_options _taskOptinos(_Cts.get_token()); + details::_get_internal_task_options(_taskOptinos)._set_creation_callstack(_callstack); + return task<_ReturnType>(_Func(_Progress, _Cts.get_token(), _pRet), _taskOptinos); + } +#else + template + static task<_ReturnType> _GenerateTask_0(const _Function& _Func, Concurrency::cancellation_token_source _Cts, _ReturnType* _pRet) + { + return task<_ReturnType>(_Func(_pRet), _Cts.get_token()); + } + + template + static task<_ReturnType> _GenerateTask_1C(const _Function& _Func, Concurrency::cancellation_token_source _Cts, _ReturnType* _pRet) + { + return task<_ReturnType>(_Func(_Cts.get_token(), _pRet), _Cts.get_token()); + } + + template + static task<_ReturnType> _GenerateTask_1P(const _Function& _Func, const _ProgressObject& _Progress, Concurrency::cancellation_token_source _Cts, _ReturnType* _pRet) + { + return task<_ReturnType>(_Func(_Progress, _pRet), _Cts.get_token()); + } + + template + static task<_ReturnType> _GenerateTask_2PC(const _Function& _Func, const _ProgressObject& _Progress, Concurrency::cancellation_token_source _Cts, _ReturnType* _pRet) + { + return task<_ReturnType>(_Func(_Progress, _Cts.get_token(), _pRet), _Cts.get_token()); + } +#endif + }; + + template + struct _SelectorTaskGenerator<_AsyncSelector, void> + { +#if _MSC_VER >= 1800 + template + static task _GenerateTask_0(const _Function& _Func, Concurrency::cancellation_token_source _Cts, const _TaskCreationCallstack & _callstack) + { + task_options _taskOptinos(_Cts.get_token()); + details::_get_internal_task_options(_taskOptinos)._set_creation_callstack(_callstack); + return task(_Func(), _taskOptinos); + } + + template + static task _GenerateTask_1C(const _Function& _Func, Concurrency::cancellation_token_source _Cts, const _TaskCreationCallstack & _callstack) + { + task_options _taskOptinos(_Cts.get_token()); + details::_get_internal_task_options(_taskOptinos)._set_creation_callstack(_callstack); + return task(_Func(_Cts.get_token()), _taskOptinos); + } + + template + static task _GenerateTask_1P(const _Function& _Func, const _ProgressObject& _Progress, Concurrency::cancellation_token_source _Cts, const _TaskCreationCallstack & _callstack) + { + task_options _taskOptinos(_Cts.get_token()); + details::_get_internal_task_options(_taskOptinos)._set_creation_callstack(_callstack); + return task(_Func(_Progress), _taskOptinos); + } + + template + static task _GenerateTask_2PC(const _Function& _Func, const _ProgressObject& _Progress, Concurrency::cancellation_token_source _Cts, const _TaskCreationCallstack & _callstack) + { + task_options _taskOptinos(_Cts.get_token()); + details::_get_internal_task_options(_taskOptinos)._set_creation_callstack(_callstack); + return task(_Func(_Progress, _Cts.get_token()), _taskOptinos); + } +#else + template + static task _GenerateTask_0(const _Function& _Func, Concurrency::cancellation_token_source _Cts) + { + return task(_Func(), _Cts.get_token()); + } + + template + static task _GenerateTask_1C(const _Function& _Func, Concurrency::cancellation_token_source _Cts) + { + return task(_Func(_Cts.get_token()), _Cts.get_token()); + } + + template + static task _GenerateTask_1P(const _Function& _Func, const _ProgressObject& _Progress, Concurrency::cancellation_token_source _Cts) + { + return task(_Func(_Progress), _Cts.get_token()); + } + + template + static task _GenerateTask_2PC(const _Function& _Func, const _ProgressObject& _Progress, Concurrency::cancellation_token_source _Cts) + { + return task(_Func(_Progress, _Cts.get_token()), _Cts.get_token()); + } +#endif + }; + +#if _MSC_VER < 1800 + // For create_async lambdas that return a (non-task) result, we oversubscriber the current task for the duration of the + // lambda. + struct _Task_generator_oversubscriber + { + _Task_generator_oversubscriber() + { + Concurrency::details::_Context::_Oversubscribe(true); + } + + ~_Task_generator_oversubscriber() + { + Concurrency::details::_Context::_Oversubscribe(false); + } + }; +#endif + + // + // Functor returns a result - it needs to be wrapped in a task: + // + template + struct _SelectorTaskGenerator + { +#if _MSC_VER >= 1800 + +#pragma warning(push) +#pragma warning(disable: 4702) + template + static task<_ReturnType> _GenerateTask_0(const _Function& _Func, Concurrency::cancellation_token_source _Cts, _ReturnType* _pRet, const _TaskCreationCallstack & _callstack) + { + task_options _taskOptinos(_Cts.get_token()); + details::_get_internal_task_options(_taskOptinos)._set_creation_callstack(_callstack); + return task<_ReturnType>([=](_ReturnType* retVal) -> HRESULT { + Concurrency::details::_Task_generator_oversubscriber_t _Oversubscriber; + (_Oversubscriber); + HRESULT hr = _Func(_pRet); + retVal = _pRet; + return hr; + }, _taskOptinos); + } +#pragma warning(pop) + + template + static task<_ReturnType> _GenerateTask_1C(const _Function& _Func, Concurrency::cancellation_token_source _Cts, _ReturnType* _pRet, const _TaskCreationCallstack & _callstack) + { + task_options _taskOptinos(_Cts.get_token()); + details::_get_internal_task_options(_taskOptinos)._set_creation_callstack(_callstack); + return task<_ReturnType>([=](_ReturnType* retVal) -> HRESULT { + Concurrency::details::_Task_generator_oversubscriber_t _Oversubscriber; + (_Oversubscriber); + HRESULT hr = _Func(_Cts.get_token(), _pRet); + retVal = _pRet; + return hr; + }, _taskOptinos); + } + + template + static task<_ReturnType> _GenerateTask_1P(const _Function& _Func, const _ProgressObject& _Progress, Concurrency::cancellation_token_source _Cts, _ReturnType* _pRet, const _TaskCreationCallstack & _callstack) + { + task_options _taskOptinos(_Cts.get_token()); + details::_get_internal_task_options(_taskOptinos)._set_creation_callstack(_callstack); + return task<_ReturnType>([=](_ReturnType* retVal) -> HRESULT { + Concurrency::details::_Task_generator_oversubscriber_t _Oversubscriber; + (_Oversubscriber); + HRESULT hr = _Func(_Progress, _pRet); + retVal = _pRet; + return hr; + }, _taskOptinos); + } + + template + static task<_ReturnType> _GenerateTask_2PC(const _Function& _Func, const _ProgressObject& _Progress, Concurrency::cancellation_token_source _Cts, _ReturnType* _pRet, const _TaskCreationCallstack & _callstack) + { + task_options _taskOptinos(_Cts.get_token()); + details::_get_internal_task_options(_taskOptinos)._set_creation_callstack(_callstack); + return task<_ReturnType>([=](_ReturnType* retVal) -> HRESULT { + Concurrency::details::_Task_generator_oversubscriber_t _Oversubscriber; + (_Oversubscriber); + HRESULT hr = _Func(_Progress, _Cts.get_token(), _pRet); + retVal = _pRet; + return hr; + }, _taskOptinos); + } +#else + template + static task<_ReturnType> _GenerateTask_0(const _Function& _Func, Concurrency::cancellation_token_source _Cts, _ReturnType* _pRet) + { + return task<_ReturnType>([=](_ReturnType* retVal) -> HRESULT { + _Task_generator_oversubscriber _Oversubscriber; + HRESULT hr = _Func(_pRet); + retVal = _pRet; + return hr; + }, _Cts.get_token()); + } + + template + static task<_ReturnType> _GenerateTask_1C(const _Function& _Func, Concurrency::cancellation_token_source _Cts, _ReturnType* _pRet) + { + return task<_ReturnType>([=](_ReturnType* retVal) -> HRESULT { + _Task_generator_oversubscriber _Oversubscriber; + HRESULT hr = _Func(_Cts.get_token(), _pRet); + retVal = _pRet; + return hr; + }, _Cts.get_token()); + } + + template + static task<_ReturnType> _GenerateTask_1P(const _Function& _Func, const _ProgressObject& _Progress, Concurrency::cancellation_token_source _Cts, _ReturnType* _pRet) + { + return task<_ReturnType>([=](_ReturnType* retVal) -> HRESULT { + _Task_generator_oversubscriber _Oversubscriber; + HRESULT hr = _Func(_Progress, _pRet); + retVal = _pRet; + return hr; + }, _Cts.get_token()); + } + + template + static task<_ReturnType> _GenerateTask_2PC(const _Function& _Func, const _ProgressObject& _Progress, Concurrency::cancellation_token_source _Cts, _ReturnType* _pRet) + { + return task<_ReturnType>([=](_ReturnType* retVal) -> HRESULT { + _Task_generator_oversubscriber _Oversubscriber; + HRESULT hr = _Func(_Progress, _Cts.get_token(), _pRet); + retVal = _pRet; + return hr; + }, _Cts.get_token()); + } +#endif + }; + + template<> + struct _SelectorTaskGenerator + { +#if _MSC_VER >= 1800 + template + static task _GenerateTask_0(const _Function& _Func, Concurrency::cancellation_token_source _Cts, const _TaskCreationCallstack & _callstack) + { + task_options _taskOptinos(_Cts.get_token()); + details::_get_internal_task_options(_taskOptinos)._set_creation_callstack(_callstack); + return task([=]() -> HRESULT { + Concurrency::details::_Task_generator_oversubscriber_t _Oversubscriber; + (_Oversubscriber); + return _Func(); + }, _taskOptinos); + } + + template + static task _GenerateTask_1C(const _Function& _Func, Concurrency::cancellation_token_source _Cts, const _TaskCreationCallstack & _callstack) + { + task_options _taskOptinos(_Cts.get_token()); + details::_get_internal_task_options(_taskOptinos)._set_creation_callstack(_callstack); + return task([=]() -> HRESULT { + Concurrency::details::_Task_generator_oversubscriber_t _Oversubscriber; + (_Oversubscriber); + return _Func(_Cts.get_token()); + }, _taskOptinos); + } + + template + static task _GenerateTask_1P(const _Function& _Func, const _ProgressObject& _Progress, Concurrency::cancellation_token_source _Cts, const _TaskCreationCallstack & _callstack) + { + task_options _taskOptinos(_Cts.get_token()); + details::_get_internal_task_options(_taskOptinos)._set_creation_callstack(_callstack); + return task([=]() -> HRESULT { + Concurrency::details::_Task_generator_oversubscriber_t _Oversubscriber; + (_Oversubscriber); + return _Func(_Progress); + }, _taskOptinos); + } + + template + static task _GenerateTask_2PC(const _Function& _Func, const _ProgressObject& _Progress, Concurrency::cancellation_token_source _Cts, const _TaskCreationCallstack & _callstack) + { + task_options _taskOptinos(_Cts.get_token()); + details::_get_internal_task_options(_taskOptinos)._set_creation_callstack(_callstack); + return task([=]() -> HRESULT { + Concurrency::details::_Task_generator_oversubscriber_t _Oversubscriber; + (_Oversubscriber); + return _Func(_Progress, _Cts.get_token()); + }, _taskOptinos); + } +#else + template + static task _GenerateTask_0(const _Function& _Func, Concurrency::cancellation_token_source _Cts) + { + return task([=]() -> HRESULT { + _Task_generator_oversubscriber _Oversubscriber; + return _Func(); + }, _Cts.get_token()); + } + + template + static task _GenerateTask_1C(const _Function& _Func, Concurrency::cancellation_token_source _Cts) + { + return task([=]() -> HRESULT { + _Task_generator_oversubscriber _Oversubscriber; + return _Func(_Cts.get_token()); + }, _Cts.get_token()); + } + + template + static task _GenerateTask_1P(const _Function& _Func, const _ProgressObject& _Progress, Concurrency::cancellation_token_source _Cts) + { + return task([=]() -> HRESULT { + _Task_generator_oversubscriber _Oversubscriber; + return _Func(_Progress); + }, _Cts.get_token()); + } + + template + static task _GenerateTask_2PC(const _Function& _Func, const _ProgressObject& _Progress, Concurrency::cancellation_token_source _Cts) + { + return task([=]() -> HRESULT { + _Task_generator_oversubscriber _Oversubscriber; + return _Func(_Progress, _Cts.get_token()); + }, _Cts.get_token()); + } +#endif + }; + + // + // Functor returns a task - the task can directly be returned: + // + template + struct _SelectorTaskGenerator + { + template +#if _MSC_VER >= 1800 + static task<_ReturnType> _GenerateTask_0(const _Function& _Func, Concurrency::cancellation_token_source _Cts, _ReturnType* _pRet, const _TaskCreationCallstack & _callstack) +#else + static task<_ReturnType> _GenerateTask_0(const _Function& _Func, Concurrency::cancellation_token_source _Cts, _ReturnType* _pRet) +#endif + { + task<_ReturnType> _task; + _Func(&_task); + return _task; + } + + template +#if _MSC_VER >= 1800 + static task<_ReturnType> _GenerateTask_1C(const _Function& _Func, Concurrency::cancellation_token_source _Cts, _ReturnType* _pRet, const _TaskCreationCallstack & _callstack) +#else + static task<_ReturnType> _GenerateTask_1C(const _Function& _Func, Concurrency::cancellation_token_source _Cts, _ReturnType* _pRet) +#endif + { + task<_ReturnType> _task; + _Func(_Cts.get_token(), &_task); + return _task; + } + + template +#if _MSC_VER >= 1800 + static task<_ReturnType> _GenerateTask_1P(const _Function& _Func, const _ProgressObject& _Progress, Concurrency::cancellation_token_source _Cts, _ReturnType* _pRet, const _TaskCreationCallstack & _callstack) +#else + static task<_ReturnType> _GenerateTask_1P(const _Function& _Func, const _ProgressObject& _Progress, Concurrency::cancellation_token_source _Cts, _ReturnType* _pRet) +#endif + { + task<_ReturnType> _task; + _Func(_Progress, &_task); + return _task; + } + + template +#if _MSC_VER >= 1800 + static task<_ReturnType> _GenerateTask_2PC(const _Function& _Func, const _ProgressObject& _Progress, Concurrency::cancellation_token_source _Cts, _ReturnType* _pRet, const _TaskCreationCallstack & _callstack) +#else + static task<_ReturnType> _GenerateTask_2PC(const _Function& _Func, const _ProgressObject& _Progress, Concurrency::cancellation_token_source _Cts, _ReturnType* _pRet) +#endif + { + task<_ReturnType> _task; + _Func(_Progress, _Cts.get_token(), &_task); + return _task; + } + }; + + template<> + struct _SelectorTaskGenerator + { + template +#if _MSC_VER >= 1800 + static task _GenerateTask_0(const _Function& _Func, Concurrency::cancellation_token_source _Cts, const _TaskCreationCallstack & _callstack) +#else + static task _GenerateTask_0(const _Function& _Func, Concurrency::cancellation_token_source _Cts) +#endif + { + task _task; + _Func(&_task); + return _task; + } + + template +#if _MSC_VER >= 1800 + static task _GenerateTask_1C(const _Function& _Func, Concurrency::cancellation_token_source _Cts, const _TaskCreationCallstack & _callstack) +#else + static task _GenerateTask_1C(const _Function& _Func, Concurrency::cancellation_token_source _Cts) +#endif + { + task _task; + _Func(_Cts.get_token(), &_task); + return _task; + } + + template +#if _MSC_VER >= 1800 + static task _GenerateTask_1P(const _Function& _Func, const _ProgressObject& _Progress, Concurrency::cancellation_token_source _Cts, const _TaskCreationCallstack & _callstack) +#else + static task _GenerateTask_1P(const _Function& _Func, const _ProgressObject& _Progress, Concurrency::cancellation_token_source _Cts) +#endif + { + task _task; + _Func(_Progress, &_task); + return _task; + } + + template +#if _MSC_VER >= 1800 + static task _GenerateTask_2PC(const _Function& _Func, const _ProgressObject& _Progress, Concurrency::cancellation_token_source _Cts, const _TaskCreationCallstack & _callstack) +#else + static task _GenerateTask_2PC(const _Function& _Func, const _ProgressObject& _Progress, Concurrency::cancellation_token_source _Cts) +#endif + { + task _task; + _Func(_Progress, _Cts.get_token(), &_task); + return _task; + } + }; + + template + struct _TaskGenerator + { + }; + + template + struct _TaskGenerator<_Generator, false, false> + { +#if _MSC_VER >= 1800 + template + static auto _GenerateTaskNoRet(const _Function& _Func, _ClassPtr _Ptr, Concurrency::cancellation_token_source _Cts, const _TaskCreationCallstack & _callstack) + -> decltype(_Generator::_GenerateTask_0(_Func, _Cts, _callstack)) + { + (void)_Ptr; + return _Generator::_GenerateTask_0(_Func, _Cts, _callstack); + } + + template + static auto _GenerateTask(const _Function& _Func, _ClassPtr _Ptr, Concurrency::cancellation_token_source _Cts, _ReturnType* _pRet, const _TaskCreationCallstack & _callstack) + -> decltype(_Generator::_GenerateTask_0(_Func, _Cts, _pRet, _callstack)) + { + return _Generator::_GenerateTask_0(_Func, _Cts, _pRet, _callstack); + } +#else + template + static auto _GenerateTaskNoRet(const _Function& _Func, _ClassPtr _Ptr, Concurrency::cancellation_token_source _Cts) + -> decltype(_Generator::_GenerateTask_0(_Func, _Cts)) + { + (void)_Ptr; + return _Generator::_GenerateTask_0(_Func, _Cts); + } + + template + static auto _GenerateTask(const _Function& _Func, _ClassPtr _Ptr, Concurrency::cancellation_token_source _Cts, _ReturnType* _pRet) + -> decltype(_Generator::_GenerateTask_0(_Func, _Cts, _pRet)) + { + return _Generator::_GenerateTask_0(_Func, _Cts, _pRet); + } +#endif + }; + + template + struct _TaskGenerator<_Generator, true, false> + { +#if _MSC_VER >= 1800 + template + static auto _GenerateTaskNoRet(const _Function& _Func, _ClassPtr _Ptr, Concurrency::cancellation_token_source _Cts, const _TaskCreationCallstack & _callstack) + -> decltype(_Generator::_GenerateTask_0(_Func, _Cts, _callstack)) + { + return _Generator::_GenerateTask_1C(_Func, _Cts, _callstack); + } + + template + static auto _GenerateTask(const _Function& _Func, _ClassPtr _Ptr, Concurrency::cancellation_token_source _Cts, _ReturnType* _pRet, const _TaskCreationCallstack & _callstack) + -> decltype(_Generator::_GenerateTask_0(_Func, _Cts, _pRet, _callstack)) + { + return _Generator::_GenerateTask_1C(_Func, _Cts, _pRet, _callstack); + } +#else + template + static auto _GenerateTaskNoRet(const _Function& _Func, _ClassPtr _Ptr, Concurrency::cancellation_token_source _Cts) + -> decltype(_Generator::_GenerateTask_0(_Func, _Cts)) + { + return _Generator::_GenerateTask_1C(_Func, _Cts); + } + + template + static auto _GenerateTask(const _Function& _Func, _ClassPtr _Ptr, Concurrency::cancellation_token_source _Cts, _ReturnType* _pRet) + -> decltype(_Generator::_GenerateTask_0(_Func, _Cts, _pRet)) + { + return _Generator::_GenerateTask_1C(_Func, _Cts, _pRet); + } +#endif + }; + + template + struct _TaskGenerator<_Generator, false, true> + { +#if _MSC_VER >= 1800 + template + static auto _GenerateTaskNoRet(const _Function& _Func, _ClassPtr _Ptr, Concurrency::cancellation_token_source _Cts, const _TaskCreationCallstack & _callstack) + -> decltype(_Generator::_GenerateTask_0(_Func, _Cts, _callstack)) + { + return _Generator::_GenerateTask_1P(_Func, progress_reporter<_ProgressType>::_CreateReporter(_Ptr), _Cts, _callstack); + } + + template + static auto _GenerateTask(const _Function& _Func, _ClassPtr _Ptr, Concurrency::cancellation_token_source _Cts, _ReturnType* _pRet, const _TaskCreationCallstack & _callstack) + -> decltype(_Generator::_GenerateTask_0(_Func, _Cts, _pRet, _callstack)) + { + return _Generator::_GenerateTask_1P(_Func, progress_reporter<_ProgressType>::_CreateReporter(_Ptr), _Cts, _pRet, _callstack); + } +#else + template + static auto _GenerateTaskNoRet(const _Function& _Func, _ClassPtr _Ptr, Concurrency::cancellation_token_source _Cts) + -> decltype(_Generator::_GenerateTask_0(_Func, _Cts)) + { + return _Generator::_GenerateTask_1P(_Func, progress_reporter<_ProgressType>::_CreateReporter(_Ptr), _Cts); + } + + template + static auto _GenerateTask(const _Function& _Func, _ClassPtr _Ptr, Concurrency::cancellation_token_source _Cts, _ReturnType* _pRet) + -> decltype(_Generator::_GenerateTask_0(_Func, _Cts, _pRet)) + { + return _Generator::_GenerateTask_1P(_Func, progress_reporter<_ProgressType>::_CreateReporter(_Ptr), _Cts, _pRet); + } +#endif + }; + + template + struct _TaskGenerator<_Generator, true, true> + { +#if _MSC_VER >= 1800 + template + static auto _GenerateTaskNoRet(const _Function& _Func, _ClassPtr _Ptr, Concurrency::cancellation_token_source _Cts, const _TaskCreationCallstack & _callstack) + -> decltype(_Generator::_GenerateTask_0(_Func, _Cts, _callstack)) + { + return _Generator::_GenerateTask_2PC(_Func, progress_reporter<_ProgressType>::_CreateReporter(_Ptr), _Cts, _callstack); + } + + template + static auto _GenerateTask(const _Function& _Func, _ClassPtr _Ptr, Concurrency::cancellation_token_source _Cts, _ReturnType* _pRet, const _TaskCreationCallstack & _callstack) + -> decltype(_Generator::_GenerateTask_0(_Func, _Cts, _pRet, _callstack)) + { + return _Generator::_GenerateTask_2PC(_Func, progress_reporter<_ProgressType>::_CreateReporter(_Ptr), _Cts, _pRet, _callstack); + } +#else + template + static auto _GenerateTaskNoRet(const _Function& _Func, _ClassPtr _Ptr, Concurrency::cancellation_token_source _Cts) + -> decltype(_Generator::_GenerateTask_0(_Func, _Cts)) + { + return _Generator::_GenerateTask_2PC(_Func, progress_reporter<_ProgressType>::_CreateReporter(_Ptr), _Cts); + } + + template + static auto _GenerateTask(const _Function& _Func, _ClassPtr _Ptr, Concurrency::cancellation_token_source _Cts, _ReturnType* _pRet) + -> decltype(_Generator::_GenerateTask_0(_Func, _Cts, _pRet)) + { + return _Generator::_GenerateTask_2PC(_Func, progress_reporter<_ProgressType>::_CreateReporter(_Ptr), _Cts, _pRet); + } +#endif + }; + + // *************************************************************************** + // Async Operation Attributes Classes + // + // These classes are passed through the hierarchy of async base classes in order to hold multiple attributes of a given async construct in + // a single container. An attribute class must define: + // + // Mandatory: + // ------------------------- + // + // _AsyncBaseType : The Windows Runtime interface which is being implemented. + // _CompletionDelegateType : The Windows Runtime completion delegate type for the interface. + // _ProgressDelegateType : If _TakesProgress is true, the Windows Runtime progress delegate type for the interface. If it is false, an empty Windows Runtime type. + // _ReturnType : The return type of the async construct (void for actions / non-void for operations) + // + // _TakesProgress : An indication as to whether or not + // + // _Generate_Task : A function adapting the user's function into what's necessary to produce the appropriate task + // + // Optional: + // ------------------------- + // + + template + struct _AsyncAttributes + { + }; + + template + struct _AsyncAttributes<_Function, _ProgressType, _ReturnType, _TaskTraits, _TakesToken, true> + { + typedef typename ABI::Windows::Foundation::IAsyncOperationWithProgress<_ReturnType, _ProgressType> _AsyncBaseType; + typedef typename ABI::Windows::Foundation::IAsyncOperationProgressHandler<_ReturnType, _ProgressType> _ProgressDelegateType; + typedef typename ABI::Windows::Foundation::IAsyncOperationWithProgressCompletedHandler<_ReturnType, _ProgressType> _CompletionDelegateType; + typedef typename _ReturnType _ReturnType; + typedef typename ABI::Windows::Foundation::Internal::GetAbiType()))>::type _ReturnType_abi; + typedef typename _ProgressType _ProgressType; + typedef typename ABI::Windows::Foundation::Internal::GetAbiType()))>::type _ProgressType_abi; + typedef typename _TaskTraits::_AsyncKind _AsyncKind; + typedef typename _SelectorTaskGenerator<_AsyncKind, _ReturnType> _SelectorTaskGenerator; + typedef typename _TaskGenerator<_SelectorTaskGenerator, _TakesToken, true> _TaskGenerator; + + static const bool _TakesProgress = true; + static const bool _TakesToken = _TakesToken; + + template +#if _MSC_VER >= 1800 + static task _Generate_Task(const _Function& _Func, _ClassPtr _Ptr, Concurrency::cancellation_token_source _Cts, _ReturnType* _pRet, const _TaskCreationCallstack & _callstack) + { + return _TaskGenerator::_GenerateTask<_Function, _ClassPtr, _ProgressType_abi, _ReturnType>(_Func, _Ptr, _Cts, _pRet, _callstack); + } +#else + static task _Generate_Task(const _Function& _Func, _ClassPtr _Ptr, Concurrency::cancellation_token_source _Cts, _ReturnType* _pRet) + { + return _TaskGenerator::_GenerateTask<_Function, _ClassPtr, _ProgressType_abi, _ReturnType>(_Func, _Ptr, _Cts, _pRet); + } +#endif + }; + + template + struct _AsyncAttributes<_Function, _ProgressType, _ReturnType, _TaskTraits, _TakesToken, false> + { + typedef typename ABI::Windows::Foundation::IAsyncOperation<_ReturnType> _AsyncBaseType; + typedef _Zip _ProgressDelegateType; + typedef typename ABI::Windows::Foundation::IAsyncOperationCompletedHandler<_ReturnType> _CompletionDelegateType; + typedef typename _ReturnType _ReturnType; + typedef typename ABI::Windows::Foundation::Internal::GetAbiType()))>::type _ReturnType_abi; + typedef typename _TaskTraits::_AsyncKind _AsyncKind; + typedef typename _SelectorTaskGenerator<_AsyncKind, _ReturnType> _SelectorTaskGenerator; + typedef typename _TaskGenerator<_SelectorTaskGenerator, _TakesToken, false> _TaskGenerator; + + static const bool _TakesProgress = false; + static const bool _TakesToken = _TakesToken; + + template +#if _MSC_VER >= 1800 + static task _Generate_Task(const _Function& _Func, _ClassPtr _Ptr, Concurrency::cancellation_token_source _Cts, _ReturnType* _pRet, const _TaskCreationCallstack & _callstack) + { + return _TaskGenerator::_GenerateTask<_Function, _ClassPtr, _ProgressType, _ReturnType>(_Func, _Ptr, _Cts, _pRet, _callstack); + } +#else + static task _Generate_Task(const _Function& _Func, _ClassPtr _Ptr, Concurrency::cancellation_token_source _Cts, _ReturnType* _pRet) + { + return _TaskGenerator::_GenerateTask<_Function, _ClassPtr, _ProgressType, _ReturnType>(_Func, _Ptr, _Cts, _pRet); + } +#endif + }; + + template + struct _AsyncAttributes<_Function, _ProgressType, void, _TaskTraits, _TakesToken, true> + { + typedef typename ABI::Windows::Foundation::IAsyncActionWithProgress<_ProgressType> _AsyncBaseType; + typedef typename ABI::Windows::Foundation::IAsyncActionProgressHandler<_ProgressType> _ProgressDelegateType; + typedef typename ABI::Windows::Foundation::IAsyncActionWithProgressCompletedHandler<_ProgressType> _CompletionDelegateType; + typedef void _ReturnType; + typedef void _ReturnType_abi; + typedef typename _ProgressType _ProgressType; + typedef typename ABI::Windows::Foundation::Internal::GetAbiType()))>::type _ProgressType_abi; + typedef typename _TaskTraits::_AsyncKind _AsyncKind; + typedef typename _SelectorTaskGenerator<_AsyncKind, _ReturnType> _SelectorTaskGenerator; + typedef typename _TaskGenerator<_SelectorTaskGenerator, _TakesToken, true> _TaskGenerator; + + static const bool _TakesProgress = true; + static const bool _TakesToken = _TakesToken; + +#if _MSC_VER >= 1800 + template + static task _Generate_Task(const _Function& _Func, _ClassPtr _Ptr, Concurrency::cancellation_token_source _Cts, const _TaskCreationCallstack & _callstack) + { + return _TaskGenerator::_GenerateTaskNoRet<_Function, _ClassPtr, _ProgressType_abi>(_Func, _Ptr, _Cts, _callstack); + } + template + static task> _Generate_Task(const _Function& _Func, _ClassPtr _Ptr, Concurrency::cancellation_token_source _Cts, _ReturnType* _pRet, const _TaskCreationCallstack & _callstack) + { + return _TaskGenerator::_GenerateTask<_Function, _ClassPtr, _ProgressType_abi>(_Func, _Ptr, _Cts, _pRet, _callstack); + } +#else + template + static task _Generate_Task(const _Function& _Func, _ClassPtr _Ptr, Concurrency::cancellation_token_source _Cts) + { + return _TaskGenerator::_GenerateTaskNoRet<_Function, _ClassPtr, _ProgressType_abi>(_Func, _Ptr, _Cts); + } + template + static task> _Generate_Task(const _Function& _Func, _ClassPtr _Ptr, Concurrency::cancellation_token_source _Cts, _ReturnType* _pRet) + { + return _TaskGenerator::_GenerateTask<_Function, _ClassPtr, _ProgressType_abi>(_Func, _Ptr, _Cts, _pRet); + } +#endif + }; + + template + struct _AsyncAttributes<_Function, _ProgressType, void, _TaskTraits, _TakesToken, false> + { + typedef typename ABI::Windows::Foundation::IAsyncAction _AsyncBaseType; + typedef _Zip _ProgressDelegateType; + typedef typename ABI::Windows::Foundation::IAsyncActionCompletedHandler _CompletionDelegateType; + typedef void _ReturnType; + typedef void _ReturnType_abi; + typedef typename _TaskTraits::_AsyncKind _AsyncKind; + typedef typename _SelectorTaskGenerator<_AsyncKind, _ReturnType> _SelectorTaskGenerator; + typedef typename _TaskGenerator<_SelectorTaskGenerator, _TakesToken, false> _TaskGenerator; + + static const bool _TakesProgress = false; + static const bool _TakesToken = _TakesToken; + +#if _MSC_VER >= 1800 + template + static task _Generate_Task(const _Function& _Func, _ClassPtr _Ptr, Concurrency::cancellation_token_source _Cts, const _TaskCreationCallstack & _callstack) + { + return _TaskGenerator::_GenerateTaskNoRet<_Function, _ClassPtr, _ProgressType>(_Func, _Ptr, _Cts, _callstack); + } + template + static task> _Generate_Task(const _Function& _Func, _ClassPtr _Ptr, Concurrency::cancellation_token_source _Cts, _ReturnType* _pRet, const _TaskCreationCallstack & _callstack) + { + return _TaskGenerator::_GenerateTask<_Function, _ClassPtr, _ProgressType>(_Func, _Ptr, _Cts, _pRet, _callstack); + } +#else + template + static task _Generate_Task(const _Function& _Func, _ClassPtr _Ptr, Concurrency::cancellation_token_source _Cts) + { + return _TaskGenerator::_GenerateTaskNoRet<_Function, _ClassPtr, _ProgressType>(_Func, _Ptr, _Cts); + } + template + static task> _Generate_Task(const _Function& _Func, _ClassPtr _Ptr, Concurrency::cancellation_token_source _Cts, _ReturnType* _pRet) + { + return _TaskGenerator::_GenerateTask<_Function, _ClassPtr, _ProgressType>(_Func, _Ptr, _Cts, _pRet); + } +#endif + }; + + template + struct _AsyncLambdaTypeTraits + { + typedef typename _Unhat::_ReturnType>::_Value _ReturnType; + typedef typename _FunctorTypeTraits<_Function>::_Argument1Type _Argument1Type; + typedef typename _CAFunctorOptions<_Function>::_ProgressType _ProgressType; + + static const bool _TakesProgress = _CAFunctorOptions<_Function>::_TakesProgress; + static const bool _TakesToken = _CAFunctorOptions<_Function>::_TakesToken; + + typedef typename _TaskTypeTraits<_ReturnType> _TaskTraits; + typedef typename _AsyncAttributes<_Function, _ProgressType, typename _TaskTraits::_TaskRetType, _TaskTraits, _TakesToken, _TakesProgress> _AsyncAttributes; + }; + // *************************************************************************** + // AsyncInfo (and completion) Layer: + // +#ifndef RUNTIMECLASS_Concurrency_winrt_details__AsyncInfoBase_DEFINED +#define RUNTIMECLASS_Concurrency_winrt_details__AsyncInfoBase_DEFINED + extern const __declspec(selectany) WCHAR RuntimeClass_Concurrency_winrt_details__AsyncInfoBase[] = L"Concurrency_winrt.details._AsyncInfoBase"; +#endif + + // + // Internal base class implementation for async operations (based on internal Windows representation for ABI level async operations) + // + template < typename _Attributes, _AsyncResultType resultType = SingleResult > + class _AsyncInfoBase abstract : public Microsoft::WRL::RuntimeClass< + Microsoft::WRL::RuntimeClassFlags< Microsoft::WRL::RuntimeClassType::WinRt>, Microsoft::WRL::Implements> + { + InspectableClass(RuntimeClass_Concurrency_winrt_details__AsyncInfoBase, BaseTrust) + public: + _AsyncInfoBase() : + _M_currentStatus(_AsyncStatusInternal::_AsyncCreated), + _M_errorCode(S_OK), + _M_completeDelegate(nullptr), + _M_CompleteDelegateAssigned(0), + _M_CallbackMade(0) + { +#if _MSC_VER < 1800 + _M_id = Concurrency::details::_GetNextAsyncId(); +#else + _M_id = Concurrency::details::platform::GetNextAsyncId(); +#endif + } + public: + virtual STDMETHODIMP GetResults(typename _Attributes::_ReturnType_abi* results) + { + (void)results; + return E_UNEXPECTED; + } + + virtual STDMETHODIMP get_Id(unsigned int* id) + { + HRESULT hr = _CheckValidStateForAsyncInfoCall(); + if (FAILED(hr)) return hr; + if (!id) return E_POINTER; + *id = _M_id; + return S_OK; + } + + virtual STDMETHODIMP put_Id(unsigned int id) + { + HRESULT hr = _CheckValidStateForAsyncInfoCall(); + if (FAILED(hr)) return hr; + + if (id == 0) + { + return E_INVALIDARG; + } + else if (_M_currentStatus != _AsyncStatusInternal::_AsyncCreated) + { + return E_ILLEGAL_METHOD_CALL; + } + + _M_id = id; + return S_OK; + } + virtual STDMETHODIMP get_Status(ABI::Windows::Foundation::AsyncStatus* status) + { + HRESULT hr = _CheckValidStateForAsyncInfoCall(); + if (FAILED(hr)) return hr; + if (!status) return E_POINTER; + + _AsyncStatusInternal _Current = _M_currentStatus; + // + // Map our internal cancel pending to cancelled. This way "pending cancelled" looks to the outside as "cancelled" but + // can still transition to "completed" if the operation completes without acknowledging the cancellation request + // + switch (_Current) + { + case _AsyncCancelPending: + _Current = _AsyncCanceled; + break; + case _AsyncCreated: + _Current = _AsyncStarted; + break; + default: + break; + } + + *status = static_cast(_Current); + return S_OK; + } + + virtual STDMETHODIMP get_ErrorCode(HRESULT* errorCode) + { + HRESULT hr = _CheckValidStateForAsyncInfoCall(); + if (FAILED(hr)) return hr; + if (!hr) return hr; + *errorCode = _M_errorCode; + return S_OK; + } + + virtual STDMETHODIMP get_Progress(typename _Attributes::_ProgressDelegateType** _ProgressHandler) + { + return _GetOnProgress(_ProgressHandler); + } + + virtual STDMETHODIMP put_Progress(typename _Attributes::_ProgressDelegateType* _ProgressHandler) + { + return _PutOnProgress(_ProgressHandler); + } + + virtual STDMETHODIMP Cancel() + { + if (_TransitionToState(_AsyncCancelPending)) + { + _OnCancel(); + } + return S_OK; + } + + virtual STDMETHODIMP Close() + { + if (_TransitionToState(_AsyncClosed)) + { + _OnClose(); + } + else + { + if (_M_currentStatus != _AsyncClosed) // Closed => Closed transition is just ignored + { + return E_ILLEGAL_STATE_CHANGE; + } + } + return S_OK; + } + + virtual STDMETHODIMP get_Completed(typename _Attributes::_CompletionDelegateType** _CompleteHandler) + { + _CheckValidStateForDelegateCall(); + if (!_CompleteHandler) return E_POINTER; + *_CompleteHandler = _M_completeDelegate.Get(); + return S_OK; + } + + virtual STDMETHODIMP put_Completed(typename _Attributes::_CompletionDelegateType* _CompleteHandler) + { + _CheckValidStateForDelegateCall(); + // this delegate property is "write once" + if (InterlockedIncrement(&_M_CompleteDelegateAssigned) == 1) + { + _M_completeDelegateContext = _ContextCallback::_CaptureCurrent(); + _M_completeDelegate = _CompleteHandler; + // Guarantee that the write of _M_completeDelegate is ordered with respect to the read of state below + // as perceived from _FireCompletion on another thread. + MemoryBarrier(); + if (_IsTerminalState()) + { + _FireCompletion(); + } + } + else + { + return E_ILLEGAL_DELEGATE_ASSIGNMENT; + } + return S_OK; + } + + protected: + // _Start - this is not externally visible since async operations "hot start" before returning to the caller + STDMETHODIMP _Start() + { + if (_TransitionToState(_AsyncStarted)) + { + _OnStart(); + } + else + { + return E_ILLEGAL_STATE_CHANGE; + } + return S_OK; + } + + HRESULT _FireCompletion() + { + HRESULT hr = S_OK; + _TryTransitionToCompleted(); + + // we guarantee that completion can only ever be fired once + if (_M_completeDelegate != nullptr && InterlockedIncrement(&_M_CallbackMade) == 1) + { + hr = _M_completeDelegateContext._CallInContext([=]() -> HRESULT { + ABI::Windows::Foundation::AsyncStatus status; + HRESULT hr; + if (SUCCEEDED(hr = this->get_Status(&status))) + _M_completeDelegate->Invoke((_Attributes::_AsyncBaseType*)this, status); + _M_completeDelegate = nullptr; + return hr; + }); + } + return hr; + } + + virtual STDMETHODIMP _GetOnProgress(typename _Attributes::_ProgressDelegateType** _ProgressHandler) + { + (void)_ProgressHandler; + return E_UNEXPECTED; + } + + virtual STDMETHODIMP _PutOnProgress(typename _Attributes::_ProgressDelegateType* _ProgressHandler) + { + (void)_ProgressHandler; + return E_UNEXPECTED; + } + + + bool _TryTransitionToCompleted() + { + return _TransitionToState(_AsyncStatusInternal::_AsyncCompleted); + } + + bool _TryTransitionToCancelled() + { + return _TransitionToState(_AsyncStatusInternal::_AsyncCanceled); + } + + bool _TryTransitionToError(const HRESULT error) + { + _InterlockedCompareExchange(reinterpret_cast(&_M_errorCode), error, S_OK); + return _TransitionToState(_AsyncStatusInternal::_AsyncError); + } + + // This method checks to see if the delegate properties can be + // modified in the current state and generates the appropriate + // error hr in the case of violation. + inline HRESULT _CheckValidStateForDelegateCall() + { + if (_M_currentStatus == _AsyncClosed) + { + return E_ILLEGAL_METHOD_CALL; + } + return S_OK; + } + + // This method checks to see if results can be collected in the + // current state and generates the appropriate error hr in + // the case of a violation. + inline HRESULT _CheckValidStateForResultsCall() + { + _AsyncStatusInternal _Current = _M_currentStatus; + + if (_Current == _AsyncError) + { + return _M_errorCode; + } +#pragma warning(push) +#pragma warning(disable: 4127) // Conditional expression is constant + // single result illegal before transition to Completed or Cancelled state + if (resultType == SingleResult) +#pragma warning(pop) + { + if (_Current != _AsyncCompleted) + { + return E_ILLEGAL_METHOD_CALL; + } + } + // multiple results can be called after Start has been called and before/after Completed + else if (_Current != _AsyncStarted && + _Current != _AsyncCancelPending && + _Current != _AsyncCanceled && + _Current != _AsyncCompleted) + { + return E_ILLEGAL_METHOD_CALL; + } + return S_OK; + } + + // This method can be called by derived classes periodically to determine + // whether the asynchronous operation should continue processing or should + // be halted. + inline bool _ContinueAsyncOperation() + { + return _M_currentStatus == _AsyncStarted; + } + + // These two methods are used to allow the async worker implementation do work on + // state transitions. No real "work" should be done in these methods. In other words + // they should not block for a long time on UI timescales. + virtual void _OnStart() = 0; + virtual void _OnClose() = 0; + virtual void _OnCancel() = 0; + + private: + + // This method is used to check if calls to the AsyncInfo properties + // (id, status, errorcode) are legal in the current state. It also + // generates the appropriate error hr to return in the case of an + // illegal call. + inline HRESULT _CheckValidStateForAsyncInfoCall() + { + _AsyncStatusInternal _Current = _M_currentStatus; + if (_Current == _AsyncClosed) + { + return E_ILLEGAL_METHOD_CALL; + } + else if (_Current == _AsyncCreated) + { + return E_ASYNC_OPERATION_NOT_STARTED; + } + return S_OK; + } + + inline bool _TransitionToState(const _AsyncStatusInternal _NewState) + { + _AsyncStatusInternal _Current = _M_currentStatus; + + // This enforces the valid state transitions of the asynchronous worker object + // state machine. + switch (_NewState) + { + case _AsyncStatusInternal::_AsyncStarted: + if (_Current != _AsyncCreated) + { + return false; + } + break; + case _AsyncStatusInternal::_AsyncCompleted: + if (_Current != _AsyncStarted && _Current != _AsyncCancelPending) + { + return false; + } + break; + case _AsyncStatusInternal::_AsyncCancelPending: + if (_Current != _AsyncStarted) + { + return false; + } + break; + case _AsyncStatusInternal::_AsyncCanceled: + if (_Current != _AsyncStarted && _Current != _AsyncCancelPending) + { + return false; + } + break; + case _AsyncStatusInternal::_AsyncError: + if (_Current != _AsyncStarted && _Current != _AsyncCancelPending) + { + return false; + } + break; + case _AsyncStatusInternal::_AsyncClosed: + if (!_IsTerminalState(_Current)) + { + return false; + } + break; + default: + return false; + break; + } + + // attempt the transition to the new state + // Note: if currentStatus_ == _Current, then there was no intervening write + // by the async work object and the swap succeeded. + _AsyncStatusInternal _RetState = static_cast<_AsyncStatusInternal>( + _InterlockedCompareExchange(reinterpret_cast(&_M_currentStatus), + _NewState, + static_cast(_Current))); + + // ICE returns the former state, if the returned state and the + // state we captured at the beginning of this method are the same, + // the swap succeeded. + return (_RetState == _Current); + } + + inline bool _IsTerminalState() + { + return _IsTerminalState(_M_currentStatus); + } + + inline bool _IsTerminalState(_AsyncStatusInternal status) + { + return (status == _AsyncError || + status == _AsyncCanceled || + status == _AsyncCompleted || + status == _AsyncClosed); + } + + private: + + _ContextCallback _M_completeDelegateContext; + Microsoft::WRL::ComPtr _M_completeDelegate; //ComPtr cannot be volatile as it does not have volatile accessors + _AsyncStatusInternal volatile _M_currentStatus; + HRESULT volatile _M_errorCode; + unsigned int _M_id; + long volatile _M_CompleteDelegateAssigned; + long volatile _M_CallbackMade; + }; + + // *************************************************************************** + // Progress Layer (optional): + // + + template< typename _Attributes, bool _HasProgress, _AsyncResultType _ResultType = SingleResult > + class _AsyncProgressBase abstract : public _AsyncInfoBase<_Attributes, _ResultType> + { + }; + + template< typename _Attributes, _AsyncResultType _ResultType> + class _AsyncProgressBase<_Attributes, true, _ResultType> abstract : public _AsyncInfoBase<_Attributes, _ResultType> + { + public: + + _AsyncProgressBase() : _AsyncInfoBase<_Attributes, _ResultType>(), + _M_progressDelegate(nullptr) + { + } + + virtual STDMETHODIMP _GetOnProgress(typename _Attributes::_ProgressDelegateType** _ProgressHandler) override + { + HRESULT hr = _CheckValidStateForDelegateCall(); + if (FAILED(hr)) return hr; + *_ProgressHandler = _M_progressDelegate; + return S_OK; + } + + virtual STDMETHODIMP _PutOnProgress(typename _Attributes::_ProgressDelegateType* _ProgressHandler) override + { + HRESULT hr = _CheckValidStateForDelegateCall(); + if (FAILED(hr)) return hr; + _M_progressDelegate = _ProgressHandler; + _M_progressDelegateContext = _ContextCallback::_CaptureCurrent(); + return S_OK; + } + + public: + + void _FireProgress(const typename _Attributes::_ProgressType_abi& _ProgressValue) + { + if (_M_progressDelegate != nullptr) + { + _M_progressDelegateContext._CallInContext([=]() -> HRESULT { + _M_progressDelegate->Invoke((_Attributes::_AsyncBaseType*)this, _ProgressValue); + return S_OK; + }); + } + } + + private: + + _ContextCallback _M_progressDelegateContext; + typename _Attributes::_ProgressDelegateType* _M_progressDelegate; + }; + + template + class _AsyncBaseProgressLayer abstract : public _AsyncProgressBase<_Attributes, _Attributes::_TakesProgress, _ResultType> + { + }; + + // *************************************************************************** + // Task Adaptation Layer: + // + + // + // _AsyncTaskThunkBase provides a bridge between IAsync and task. + // + template + class _AsyncTaskThunkBase abstract : public _AsyncBaseProgressLayer<_Attributes> + { + public: + + //AsyncAction* + virtual STDMETHODIMP GetResults() + { + HRESULT hr = _CheckValidStateForResultsCall(); + if (FAILED(hr)) return hr; + _M_task.get(); + return S_OK; + } + public: + typedef task<_ReturnType> _TaskType; + + _AsyncTaskThunkBase(const _TaskType& _Task) + : _M_task(_Task) + { + } + + _AsyncTaskThunkBase() + { + } +#if _MSC_VER < 1800 + void _SetTaskCreationAddressHint(void* _SourceAddressHint) + { + if (!(std::is_same<_Attributes::_AsyncKind, _TypeSelectorAsyncTask>::value)) + { + // Overwrite the creation address with the return address of create_async unless the + // lambda returned a task. If the create async lambda returns a task, that task is reused and + // we want to preserve its creation address hint. + _M_task._SetTaskCreationAddressHint(_SourceAddressHint); + } + } +#endif + protected: + virtual void _OnStart() override + { + _M_task.then([=](_TaskType _Antecedent) -> HRESULT { + try + { + _Antecedent.get(); + } + catch (Concurrency::task_canceled&) + { + _TryTransitionToCancelled(); + } + catch (IRestrictedErrorInfo*& _Ex) + { + HRESULT hr; + HRESULT _hr; + hr = _Ex->GetErrorDetails(NULL, &_hr, NULL, NULL); + if (SUCCEEDED(hr)) hr = _hr; + _TryTransitionToError(hr); + } + catch (...) + { + _TryTransitionToError(E_FAIL); + } + return _FireCompletion(); + }); + } + + protected: + _TaskType _M_task; + Concurrency::cancellation_token_source _M_cts; + }; + + template + class _AsyncTaskReturn abstract : public _AsyncTaskThunkBase<_Attributes, _Return> + { + public: + //AsyncOperation* + virtual STDMETHODIMP GetResults(_ReturnType* results) + { + HRESULT hr = _CheckValidStateForResultsCall(); + if (FAILED(hr)) return hr; + _M_task.get(); + *results = _M_results; + return S_OK; + } + template +#if _MSC_VER >= 1800 + void DoCreateTask(_Function _func, const _TaskCreationCallstack & _callstack) + { + _M_task = _Attributes::_Generate_Task(_func, this, _M_cts, &_M_results, _callstack); + } +#else + void DoCreateTask(_Function _func) + { + _M_task = _Attributes::_Generate_Task(_func, this, _M_cts, &_M_results); + } +#endif + protected: + _ReturnType _M_results; + }; + + template + class _AsyncTaskReturn<_Attributes, _ReturnType, void> abstract : public _AsyncTaskThunkBase<_Attributes, void> + { + public: + template +#if _MSC_VER >= 1800 + void DoCreateTask(_Function _func, const _TaskCreationCallstack & _callstack) + { + _M_task = _Attributes::_Generate_Task(_func, this, _M_cts, _callstack); + } +#else + void DoCreateTask(_Function _func) + { + _M_task = _Attributes::_Generate_Task(_func, this, _M_cts); + } +#endif + }; + + template + class _AsyncTaskReturn<_Attributes, void, task> abstract : public _AsyncTaskThunkBase<_Attributes, task> + { + public: + template +#if _MSC_VER >= 1800 + void DoCreateTask(_Function _func, const _TaskCreationCallstack & _callstack) + { + _M_task = _Attributes::_Generate_Task(_func, this, _M_cts, &_M_results, _callstack); + } +#else + void DoCreateTask(_Function _func) + { + _M_task = _Attributes::_Generate_Task(_func, this, _M_cts, &_M_results); + } +#endif + protected: + task _M_results; + }; + + template + class _AsyncTaskThunk : public _AsyncTaskReturn<_Attributes, typename _Attributes::_ReturnType_abi, typename _Attributes::_ReturnType> + { + public: + + _AsyncTaskThunk(const _TaskType& _Task) : + _AsyncTaskThunkBase(_Task) + { + } + + _AsyncTaskThunk() + { + } + + protected: + + virtual void _OnClose() override + { + } + + virtual void _OnCancel() override + { + _M_cts.cancel(); + } + }; + + // *************************************************************************** + // Async Creation Layer: + // + template + class _AsyncTaskGeneratorThunk : public _AsyncTaskThunk::_AsyncAttributes> + { + public: + + typedef typename _AsyncLambdaTypeTraits<_Function>::_AsyncAttributes _Attributes; + typedef typename _AsyncTaskThunk<_Attributes> _Base; + typedef typename _Attributes::_AsyncBaseType _AsyncBaseType; + +#if _MSC_VER >= 1800 + _AsyncTaskGeneratorThunk(const _Function& _Func, const _TaskCreationCallstack &_callstack) : _M_func(_Func), _M_creationCallstack(_callstack) +#else + _AsyncTaskGeneratorThunk(const _Function& _Func) : _M_func(_Func) +#endif + { + // Virtual call here is safe as the class is declared 'sealed' + _Start(); + } + + protected: + + // + // The only thing we must do different from the base class is we must spin the hot task on transition from Created->Started. Otherwise, + // let the base thunk handle everything. + // + + virtual void _OnStart() override + { + // + // Call the appropriate task generator to actually produce a task of the expected type. This might adapt the user lambda for progress reports, + // wrap the return result in a task, or allow for direct return of a task depending on the form of the lambda. + // +#if _MSC_VER >= 1800 + DoCreateTask<_Function>(_M_func, _M_creationCallstack); +#else + DoCreateTask<_Function>(_M_func); +#endif + _Base::_OnStart(); + } + + virtual void _OnCancel() override + { + _Base::_OnCancel(); + } + + private: +#if _MSC_VER >= 1800 + _TaskCreationCallstack _M_creationCallstack; +#endif + _Function _M_func; + }; +} // namespace details + +/// +/// Creates a Windows Runtime asynchronous construct based on a user supplied lambda or function object. The return type of create_async is +/// one of either IAsyncAction^, IAsyncActionWithProgress<TProgress>^, IAsyncOperation<TResult>^, or +/// IAsyncOperationWithProgress<TResult, TProgress>^ based on the signature of the lambda passed to the method. +/// +/// +/// The lambda or function object from which to create a Windows Runtime asynchronous construct. +/// +/// +/// An asynchronous construct represented by an IAsyncAction^, IAsyncActionWithProgress<TProgress>^, IAsyncOperation<TResult>^, or an +/// IAsyncOperationWithProgress<TResult, TProgress>^. The interface returned depends on the signature of the lambda passed into the function. +/// +/// +/// The return type of the lambda determines whether the construct is an action or an operation. +/// Lambdas that return void cause the creation of actions. Lambdas that return a result of type TResult cause the creation of +/// operations of TResult. +/// The lambda may also return a task<TResult> which encapsulates the aysnchronous work within itself or is the continuation of +/// a chain of tasks that represent the asynchronous work. In this case, the lambda itself is executed inline, since the tasks are the ones that +/// execute asynchronously, and the return type of the lambda is unwrapped to produce the asynchronous construct returned by create_async. +/// This implies that a lambda that returns a task<void> will cause the creation of actions, and a lambda that returns a task<TResult> will +/// cause the creation of operations of TResult. +/// The lambda may take either zero, one or two arguments. The valid arguments are progress_reporter<TProgress> and +/// cancellation_token, in that order if both are used. A lambda without arguments causes the creation of an asynchronous construct without +/// the capability for progress reporting. A lambda that takes a progress_reporter<TProgress> will cause create_async to return an asynchronous +/// construct which reports progress of type TProgress each time the report method of the progress_reporter object is called. A lambda that +/// takes a cancellation_token may use that token to check for cancellation, or pass it to tasks that it creates so that cancellation of the +/// asynchronous construct causes cancellation of those tasks. +/// If the body of the lambda or function object returns a result (and not a task<TResult>), the lamdba will be executed +/// asynchronously within the process MTA in the context of a task the Runtime implicitly creates for it. The IAsyncInfo::Cancel method will +/// cause cancellation of the implicit task. +/// If the body of the lambda returns a task, the lamba executes inline, and by declaring the lambda to take an argument of type +/// cancellation_token you can trigger cancellation of any tasks you create within the lambda by passing that token in when you create them. +/// You may also use the register_callback method on the token to cause the Runtime to invoke a callback when you call IAsyncInfo::Cancel on +/// the async operation or action produced.. +/// This function is only available to Windows Store apps. +/// +/// +/// +/// +/**/ +template +__declspec(noinline) // Ask for no inlining so that the _ReturnAddress intrinsic gives us the expected result +details::_AsyncTaskGeneratorThunk<_Function>* create_async(const _Function& _Func) +{ + static_assert(std::is_same(_Func, 0, 0, 0, 0, 0, 0, 0, 0)), std::true_type>::value, + "argument to create_async must be a callable object taking zero, one, two or three arguments"); +#if _MSC_VER >= 1800 + Microsoft::WRL::ComPtr> _AsyncInfo = Microsoft::WRL::Make>(_Func, _CAPTURE_CALLSTACK()); +#else + Microsoft::WRL::ComPtr> _AsyncInfo = Microsoft::WRL::Make>(_Func); + _AsyncInfo->_SetTaskCreationAddressHint(_ReturnAddress()); +#endif + return _AsyncInfo.Detach(); +} + +namespace details +{ +#if _MSC_VER < 1800 + // Internal API which retrieves the next async id. + _CRTIMP2 unsigned int __cdecl _GetNextAsyncId(); +#endif + // Helper struct for when_all operators to know when tasks have completed + template + struct _RunAllParam + { + _RunAllParam() : _M_completeCount(0), _M_numTasks(0) + { + } + + void _Resize(size_t _Len, bool _SkipVector = false) + { + _M_numTasks = _Len; + if (!_SkipVector) +#if _MSC_VER >= 1800 + { + _M_vector._Result.resize(_Len); + } +#else + _M_vector.resize(_Len); + _M_contexts.resize(_Len); +#endif + } + + task_completion_event<_Unit_type> _M_completed; + atomic_size_t _M_completeCount; +#if _MSC_VER >= 1800 + _ResultHolder > _M_vector; + _ResultHolder<_Type> _M_mergeVal; +#else + std::vector<_Type> _M_vector; + std::vector<_ContextCallback> _M_contexts; + _Type _M_mergeVal; +#endif + size_t _M_numTasks; + }; + +#if _MSC_VER >= 1800 + template + struct _RunAllParam > + { + _RunAllParam() : _M_completeCount(0), _M_numTasks(0) + { + } + + void _Resize(size_t _Len, bool _SkipVector = false) + { + _M_numTasks = _Len; + + if (!_SkipVector) + { + _M_vector.resize(_Len); + } + } + + task_completion_event<_Unit_type> _M_completed; + std::vector<_ResultHolder > > _M_vector; + atomic_size_t _M_completeCount; + size_t _M_numTasks; + }; +#endif + + // Helper struct specialization for void + template<> +#if _MSC_VER >= 1800 + struct _RunAllParam<_Unit_type> +#else + struct _RunAllParam +#endif + { + _RunAllParam() : _M_completeCount(0), _M_numTasks(0) + { + } + + void _Resize(size_t _Len) + { + _M_numTasks = _Len; + } + + task_completion_event<_Unit_type> _M_completed; + atomic_size_t _M_completeCount; + size_t _M_numTasks; + }; + + inline void _JoinAllTokens_Add(const Concurrency::cancellation_token_source& _MergedSrc, Concurrency::details::_CancellationTokenState *_PJoinedTokenState) + { + if (_PJoinedTokenState != nullptr && _PJoinedTokenState != Concurrency::details::_CancellationTokenState::_None()) + { + Concurrency::cancellation_token _T = Concurrency::cancellation_token::_FromImpl(_PJoinedTokenState); + _T.register_callback([=](){ + _MergedSrc.cancel(); + }); + } + } + + template + void _WhenAllContinuationWrapper(_RunAllParam<_ElementType>* _PParam, _Function _Func, task<_TaskType>& _Task) + { + if (_Task._GetImpl()->_IsCompleted()) + { + _Func(); +#if _MSC_VER >= 1800 + if (Concurrency::details::atomic_increment(_PParam->_M_completeCount) == _PParam->_M_numTasks) +#else + if (_InterlockedIncrementSizeT(&_PParam->_M_completeCount) == _PParam->_M_numTasks) +#endif + { + // Inline execute its direct continuation, the _ReturnTask + _PParam->_M_completed.set(_Unit_type()); + // It's safe to delete it since all usage of _PParam in _ReturnTask has been finished. + delete _PParam; + } + } + else + { + _CONCRT_ASSERT(_Task._GetImpl()->_IsCanceled()); + if (_Task._GetImpl()->_HasUserException()) + { + // _Cancel will return false if the TCE is already canceled with or without exception + _PParam->_M_completed._Cancel(_Task._GetImpl()->_GetExceptionHolder()); + } + else + { + _PParam->_M_completed._Cancel(); + } +#if _MSC_VER >= 1800 + if (Concurrency::details::atomic_increment(_PParam->_M_completeCount) == _PParam->_M_numTasks) +#else + if (_InterlockedIncrementSizeT(&_PParam->_M_completeCount) == _PParam->_M_numTasks) +#endif + { + delete _PParam; + } + } + } + + template + struct _WhenAllImpl + { +#if _MSC_VER >= 1800 + static task> _Perform(const task_options& _TaskOptions, _Iterator _Begin, _Iterator _End) +#else + static task> _Perform(Concurrency::details::_CancellationTokenState *_PTokenState, _Iterator _Begin, _Iterator _End) +#endif + { +#if _MSC_VER >= 1800 + Concurrency::details::_CancellationTokenState *_PTokenState = _TaskOptions.has_cancellation_token() ? _TaskOptions.get_cancellation_token()._GetImplValue() : nullptr; +#endif + auto _PParam = new _RunAllParam<_ElementType>(); + Concurrency::cancellation_token_source _MergedSource; + + // Step1: Create task completion event. +#if _MSC_VER >= 1800 + task_options _Options(_TaskOptions); + _Options.set_cancellation_token(_MergedSource.get_token()); + task<_Unit_type> _All_tasks_completed(_PParam->_M_completed, _Options); +#else + task<_Unit_type> _All_tasks_completed(_PParam->_M_completed, _MergedSource.get_token()); +#endif + // The return task must be created before step 3 to enforce inline execution. + auto _ReturnTask = _All_tasks_completed._Then([=](_Unit_type, std::vector<_ElementType>* retVal) -> HRESULT { +#if _MSC_VER >= 1800 + * retVal = _PParam->_M_vector.Get(); +#else + auto _Result = _PParam->_M_vector; // copy by value + + size_t _Index = 0; + for (auto _It = _Result.begin(); _It != _Result.end(); ++_It) + { + *_It = _ResultContext<_ElementType>::_GetValue(*_It, _PParam->_M_contexts[_Index++], false); + } + *retVal = _Result; +#endif + return S_OK; +#if _MSC_VER >= 1800 + }, nullptr); +#else + }, nullptr, true); +#endif + // Step2: Combine and check tokens, and count elements in range. + if (_PTokenState) + { + details::_JoinAllTokens_Add(_MergedSource, _PTokenState); + _PParam->_Resize(static_cast(std::distance(_Begin, _End))); + } + else + { + size_t _TaskNum = 0; + for (auto _PTask = _Begin; _PTask != _End; ++_PTask) + { + _TaskNum++; + details::_JoinAllTokens_Add(_MergedSource, _PTask->_GetImpl()->_M_pTokenState); + } + _PParam->_Resize(_TaskNum); + } + + // Step3: Check states of previous tasks. + if (_Begin == _End) + { + _PParam->_M_completed.set(_Unit_type()); + delete _PParam; + } + else + { + size_t _Index = 0; + for (auto _PTask = _Begin; _PTask != _End; ++_PTask) + { + if (_PTask->is_apartment_aware()) + { + _ReturnTask._SetAsync(); + } + + _PTask->_Then([_PParam, _Index](task<_ElementType> _ResultTask) -> HRESULT { + +#if _MSC_VER >= 1800 + // Dev10 compiler bug + typedef _ElementType _ElementTypeDev10; + auto _PParamCopy = _PParam; + auto _IndexCopy = _Index; + auto _Func = [_PParamCopy, _IndexCopy, &_ResultTask](){ + _PParamCopy->_M_vector._Result[_IndexCopy] = _ResultTask._GetImpl()->_GetResult(); + }; +#else + auto _Func = [_PParam, _Index, &_ResultTask](){ + _PParam->_M_vector[_Index] = _ResultTask._GetImpl()->_GetResult(); + _PParam->_M_contexts[_Index] = _ResultContext<_ElementType>::_GetContext(false); + }; +#endif + _WhenAllContinuationWrapper(_PParam, _Func, _ResultTask); + return S_OK; +#if _MSC_VER >= 1800 + }, Concurrency::details::_CancellationTokenState::_None()); +#else + }, Concurrency::details::_CancellationTokenState::_None(), false); +#endif + + _Index++; + } + } + + return _ReturnTask; + } + }; + + template + struct _WhenAllImpl, _Iterator> + { +#if _MSC_VER >= 1800 + static task> _Perform(const task_options& _TaskOptions, _Iterator _Begin, _Iterator _End) +#else + static task> _Perform(Concurrency::details::_CancellationTokenState *_PTokenState, _Iterator _Begin, _Iterator _End) +#endif + { +#if _MSC_VER >= 1800 + Concurrency::details::_CancellationTokenState *_PTokenState = _TaskOptions.has_cancellation_token() ? _TaskOptions.get_cancellation_token()._GetImplValue() : nullptr; +#endif + auto _PParam = new _RunAllParam>(); + Concurrency::cancellation_token_source _MergedSource; + + // Step1: Create task completion event. +#if _MSC_VER >= 1800 + task_options _Options(_TaskOptions); + _Options.set_cancellation_token(_MergedSource.get_token()); + task<_Unit_type> _All_tasks_completed(_PParam->_M_completed, _Options); +#else + task<_Unit_type> _All_tasks_completed(_PParam->_M_completed, _MergedSource.get_token()); +#endif + // The return task must be created before step 3 to enforce inline execution. + auto _ReturnTask = _All_tasks_completed._Then([=](_Unit_type, std::vector<_ElementType>* retVal) -> HRESULT { + _CONCRT_ASSERT(_PParam->_M_completeCount == _PParam->_M_numTasks); + std::vector<_ElementType> _Result; + for (size_t _I = 0; _I < _PParam->_M_numTasks; _I++) + { +#if _MSC_VER >= 1800 + const std::vector<_ElementType>& _Vec = _PParam->_M_vector[_I].Get(); +#else + std::vector<_ElementType>& _Vec = _PParam->_M_vector[_I]; + + for (auto _It = _Vec.begin(); _It != _Vec.end(); ++_It) + { + *_It = _ResultContext<_ElementType>::_GetValue(*_It, _PParam->_M_contexts[_I], false); + } +#endif + _Result.insert(_Result.end(), _Vec.begin(), _Vec.end()); + } + *retVal = _Result; + return S_OK; +#if _MSC_VER >= 1800 + }, nullptr); +#else + }, nullptr, true); +#endif + + // Step2: Combine and check tokens, and count elements in range. + if (_PTokenState) + { + details::_JoinAllTokens_Add(_MergedSource, _PTokenState); + _PParam->_Resize(static_cast(std::distance(_Begin, _End))); + } + else + { + size_t _TaskNum = 0; + for (auto _PTask = _Begin; _PTask != _End; ++_PTask) + { + _TaskNum++; + details::_JoinAllTokens_Add(_MergedSource, _PTask->_GetImpl()->_M_pTokenState); + } + _PParam->_Resize(_TaskNum); + } + + // Step3: Check states of previous tasks. + if (_Begin == _End) + { + _PParam->_M_completed.set(_Unit_type()); + delete _PParam; + } + else + { + size_t _Index = 0; + for (auto _PTask = _Begin; _PTask != _End; ++_PTask) + { + if (_PTask->is_apartment_aware()) + { + _ReturnTask._SetAsync(); + } + + _PTask->_Then([_PParam, _Index](task> _ResultTask) -> HRESULT { +#if _MSC_VER >= 1800 + // Dev10 compiler bug + typedef _ElementType _ElementTypeDev10; + auto _PParamCopy = _PParam; + auto _IndexCopy = _Index; + auto _Func = [_PParamCopy, _IndexCopy, &_ResultTask]() { + _PParamCopy->_M_vector[_IndexCopy].Set(_ResultTask._GetImpl()->_GetResult()); + }; +#else + auto _Func = [_PParam, _Index, &_ResultTask]() { + _PParam->_M_vector[_Index] = _ResultTask._GetImpl()->_GetResult(); + _PParam->_M_contexts[_Index] = _ResultContext<_ElementType>::_GetContext(false); + }; +#endif + _WhenAllContinuationWrapper(_PParam, _Func, _ResultTask); + return S_OK; +#if _MSC_VER >= 1800 + }, Concurrency::details::_CancellationTokenState::_None()); +#else + }, Concurrency::details::_CancellationTokenState::_None(), false); +#endif + + _Index++; + } + } + + return _ReturnTask; + } + }; + + template + struct _WhenAllImpl + { +#if _MSC_VER >= 1800 + static task _Perform(const task_options& _TaskOptions, _Iterator _Begin, _Iterator _End) +#else + static task _Perform(Concurrency::details::_CancellationTokenState *_PTokenState, _Iterator _Begin, _Iterator _End) +#endif + { +#if _MSC_VER >= 1800 + Concurrency::details::_CancellationTokenState *_PTokenState = _TaskOptions.has_cancellation_token() ? _TaskOptions.get_cancellation_token()._GetImplValue() : nullptr; +#endif + auto _PParam = new _RunAllParam<_Unit_type>(); + Concurrency::cancellation_token_source _MergedSource; + + // Step1: Create task completion event. +#if _MSC_VER >= 1800 + task_options _Options(_TaskOptions); + _Options.set_cancellation_token(_MergedSource.get_token()); + task<_Unit_type> _All_tasks_completed(_PParam->_M_completed, _Options); +#else + task<_Unit_type> _All_tasks_completed(_PParam->_M_completed, _MergedSource.get_token()); +#endif + // The return task must be created before step 3 to enforce inline execution. + auto _ReturnTask = _All_tasks_completed._Then([=](_Unit_type) -> HRESULT { return S_OK; +#if _MSC_VER >= 1800 + }, nullptr); +#else + }, nullptr, false); +#endif + + // Step2: Combine and check tokens, and count elements in range. + if (_PTokenState) + { + details::_JoinAllTokens_Add(_MergedSource, _PTokenState); + _PParam->_Resize(static_cast(std::distance(_Begin, _End))); + } + else + { + size_t _TaskNum = 0; + for (auto _PTask = _Begin; _PTask != _End; ++_PTask) + { + _TaskNum++; + details::_JoinAllTokens_Add(_MergedSource, _PTask->_GetImpl()->_M_pTokenState); + } + _PParam->_Resize(_TaskNum); + } + + // Step3: Check states of previous tasks. + if (_Begin == _End) + { + _PParam->_M_completed.set(_Unit_type()); + delete _PParam; + } + else + { + for (auto _PTask = _Begin; _PTask != _End; ++_PTask) + { + if (_PTask->is_apartment_aware()) + { + _ReturnTask._SetAsync(); + } + + _PTask->_Then([_PParam](task _ResultTask) -> HRESULT { + + auto _Func = []() -> HRESULT { return S_OK; }; + _WhenAllContinuationWrapper(_PParam, _Func, _ResultTask); + return S_OK; +#if _MSC_VER >= 1800 + }, Concurrency::details::_CancellationTokenState::_None()); +#else + }, Concurrency::details::_CancellationTokenState::_None(), false); +#endif + } + } + + return _ReturnTask; + } + }; + + template + task> _WhenAllVectorAndValue(const task>& _VectorTask, const task<_ReturnType>& _ValueTask, + bool _OutputVectorFirst) + { + auto _PParam = new _RunAllParam<_ReturnType>(); + Concurrency::cancellation_token_source _MergedSource; + + // Step1: Create task completion event. + task<_Unit_type> _All_tasks_completed(_PParam->_M_completed, _MergedSource.get_token()); + // The return task must be created before step 3 to enforce inline execution. + auto _ReturnTask = _All_tasks_completed._Then([=](_Unit_type, std::vector<_ReturnType>* retVal) -> HRESULT { + _CONCRT_ASSERT(_PParam->_M_completeCount == 2); +#if _MSC_VER >= 1800 + auto _Result = _PParam->_M_vector.Get(); // copy by value + auto _mergeVal = _PParam->_M_mergeVal.Get(); +#else + auto _Result = _PParam->_M_vector; // copy by value + for (auto _It = _Result.begin(); _It != _Result.end(); ++_It) + { + *_It = _ResultContext<_ReturnType>::_GetValue(*_It, _PParam->_M_contexts[0], false); + } +#endif + + if (_OutputVectorFirst == true) + { +#if _MSC_VER >= 1800 + _Result.push_back(_mergeVal); +#else + _Result.push_back(_ResultContext<_ReturnType>::_GetValue(_PParam->_M_mergeVal, _PParam->_M_contexts[1], false)); +#endif + } + else + { +#if _MSC_VER >= 1800 + _Result.insert(_Result.begin(), _mergeVal); +#else + _Result.insert(_Result.begin(), _ResultContext<_ReturnType>::_GetValue(_PParam->_M_mergeVal, _PParam->_M_contexts[1], false)); +#endif + } + *retVal = _Result; + return S_OK; + }, nullptr, true); + + // Step2: Combine and check tokens. + _JoinAllTokens_Add(_MergedSource, _VectorTask._GetImpl()->_M_pTokenState); + _JoinAllTokens_Add(_MergedSource, _ValueTask._GetImpl()->_M_pTokenState); + + // Step3: Check states of previous tasks. + _PParam->_Resize(2, true); + + if (_VectorTask.is_apartment_aware() || _ValueTask.is_apartment_aware()) + { + _ReturnTask._SetAsync(); + } + _VectorTask._Then([_PParam](task> _ResultTask) -> HRESULT { +#if _MSC_VER >= 1800 + // Dev10 compiler bug + typedef _ReturnType _ReturnTypeDev10; + auto _PParamCopy = _PParam; + auto _Func = [_PParamCopy, &_ResultTask]() { + auto _ResultLocal = _ResultTask._GetImpl()->_GetResult(); + _PParamCopy->_M_vector.Set(_ResultLocal); + }; +#else + auto _Func = [_PParam, &_ResultTask]() { + _PParam->_M_vector = _ResultTask._GetImpl()->_GetResult(); + _PParam->_M_contexts[0] = _ResultContext<_ReturnType>::_GetContext(false); + }; +#endif + + _WhenAllContinuationWrapper(_PParam, _Func, _ResultTask); + return S_OK; +#if _MSC_VER >= 1800 + }, _CancellationTokenState::_None()); +#else + }, _CancellationTokenState::_None(), false); +#endif + _ValueTask._Then([_PParam](task<_ReturnType> _ResultTask) -> HRESULT { +#if _MSC_VER >= 1800 + // Dev10 compiler bug + typedef _ReturnType _ReturnTypeDev10; + auto _PParamCopy = _PParam; + auto _Func = [_PParamCopy, &_ResultTask]() { + auto _ResultLocal = _ResultTask._GetImpl()->_GetResult(); + _PParamCopy->_M_mergeVal.Set(_ResultLocal); + }; +#else + auto _Func = [_PParam, &_ResultTask]() { + _PParam->_M_mergeVal = _ResultTask._GetImpl()->_GetResult(); + _PParam->_M_contexts[1] = _ResultContext<_ReturnType>::_GetContext(false); + }; +#endif + _WhenAllContinuationWrapper(_PParam, _Func, _ResultTask); + return S_OK; +#if _MSC_VER >= 1800 + }, _CancellationTokenState::_None()); +#else + }, _CancellationTokenState::_None(), false); +#endif + + return _ReturnTask; + } +} // namespace details + +#if _MSC_VER < 1800 +/// +/// Creates a task that will complete successfully when all of the tasks supplied as arguments complete successfully. +/// +/// +/// The type of the input iterator. +/// +/// +/// The position of the first element in the range of elements to be combined into the resulting task. +/// +/// +/// The position of the first element beyond the range of elements to be combined into the resulting task. +/// +/// +/// A task that completes sucessfully when all of the input tasks have completed successfully. If the input tasks are of type T, +/// the output of this function will be a task<std::vector<T>>. If the input tasks are of type void the output +/// task will also be a task<void>. +/// +/// +/// If one of the tasks is canceled or throws an exception, the returned task will complete early, in the canceled state, and the exception, +/// if one is encoutered, will be thrown if you call get() or wait() on that task. +/// +/// +/**/ +template +auto when_all(_Iterator _Begin, _Iterator _End) +-> decltype (details::_WhenAllImpl::value_type::result_type, _Iterator>::_Perform(nullptr, _Begin, _End)) +{ + typedef typename std::iterator_traits<_Iterator>::value_type::result_type _ElementType; + return details::_WhenAllImpl<_ElementType, _Iterator>::_Perform(nullptr, _Begin, _End); +} +#endif + +/// +/// Creates a task that will complete successfully when all of the tasks supplied as arguments complete successfully. +/// +/// +/// The type of the input iterator. +/// +/// +/// The position of the first element in the range of elements to be combined into the resulting task. +/// +/// +/// The position of the first element beyond the range of elements to be combined into the resulting task. +/// +/// +/// The cancellation token which controls cancellation of the returned task. If you do not provide a cancellation token, the resulting +/// task will be created with a token that is a combination of all the cancelable tokens (tokens created by methods other than +/// cancellation_token::none()of the tasks supplied. +/// +/// +/// A task that completes sucessfully when all of the input tasks have completed successfully. If the input tasks are of type T, +/// the output of this function will be a task<std::vector<T>>. If the input tasks are of type void the output +/// task will also be a task<void>. +/// +/// +/// If one of the tasks is canceled or throws an exception, the returned task will complete early, in the canceled state, and the exception, +/// if one is encoutered, will be thrown if you call get() or wait() on that task. +/// +/// +/**/ +template +#if _MSC_VER >= 1800 +auto when_all(_Iterator _Begin, _Iterator _End, const task_options& _TaskOptions = task_options()) +-> decltype (details::_WhenAllImpl::value_type::result_type, _Iterator>::_Perform(_TaskOptions, _Begin, _End)) +{ + typedef typename std::iterator_traits<_Iterator>::value_type::result_type _ElementType; + return details::_WhenAllImpl<_ElementType, _Iterator>::_Perform(_TaskOptions, _Begin, _End); +} +#else +auto when_all(_Iterator _Begin, _Iterator _End, Concurrency::cancellation_token _CancellationToken) +-> decltype (details::_WhenAllImpl::value_type::result_type, _Iterator>::_Perform(_CancellationToken._GetImplValue(), _Begin, _End)) +{ + typedef typename std::iterator_traits<_Iterator>::value_type::result_type _ElementType; + return details::_WhenAllImpl<_ElementType, _Iterator>::_Perform(_CancellationToken._GetImplValue(), _Begin, _End); +} +#endif + +/// +/// Creates a task that will complete succesfully when both of the tasks supplied as arguments complete successfully. +/// +/// +/// The type of the returned task. +/// +/// +/// The first task to combine into the resulting task. +/// +/// +/// The second task to combine into the resulting task. +/// +/// +/// A task that completes successfully when both of the input tasks have completed successfully. If the input tasks are of type T, +/// the output of this function will be a task<std::vector<T>>. If the input tasks are of type void the output +/// task will also be a task<void>. +/// To allow for a construct of the sort taskA && taskB && taskC, which are combined in pairs, the && operator +/// produces a task<std::vector<T>> if either one or both of the tasks are of type task<std::vector<T>>. +/// +/// +/// If one of the tasks is canceled or throws an exception, the returned task will complete early, in the canceled state, and the exception, +/// if one is encoutered, will be thrown if you call get() or wait() on that task. +/// +/// +/**/ +template +task> operator&&(const task<_ReturnType> & _Lhs, const task<_ReturnType> & _Rhs) +{ + task<_ReturnType> _PTasks[2] = { _Lhs, _Rhs }; + return when_all(_PTasks, _PTasks + 2); +} + +/// +/// Creates a task that will complete succesfully when both of the tasks supplied as arguments complete successfully. +/// +/// +/// The type of the returned task. +/// +/// +/// The first task to combine into the resulting task. +/// +/// +/// The second task to combine into the resulting task. +/// +/// +/// A task that completes successfully when both of the input tasks have completed successfully. If the input tasks are of type T, +/// the output of this function will be a task<std::vector<T>>. If the input tasks are of type void the output +/// task will also be a task<void>. +/// To allow for a construct of the sort taskA && taskB && taskC, which are combined in pairs, the && operator +/// produces a task<std::vector<T>> if either one or both of the tasks are of type task<std::vector<T>>. +/// +/// +/// If one of the tasks is canceled or throws an exception, the returned task will complete early, in the canceled state, and the exception, +/// if one is encoutered, will be thrown if you call get() or wait() on that task. +/// +/// +/**/ +template +task> operator&&(const task> & _Lhs, const task<_ReturnType> & _Rhs) +{ + return details::_WhenAllVectorAndValue(_Lhs, _Rhs, true); +} + +/// +/// Creates a task that will complete succesfully when both of the tasks supplied as arguments complete successfully. +/// +/// +/// The type of the returned task. +/// +/// +/// The first task to combine into the resulting task. +/// +/// +/// The second task to combine into the resulting task. +/// +/// +/// A task that completes successfully when both of the input tasks have completed successfully. If the input tasks are of type T, +/// the output of this function will be a task<std::vector<T>>. If the input tasks are of type void the output +/// task will also be a task<void>. +/// To allow for a construct of the sort taskA && taskB && taskC, which are combined in pairs, the && operator +/// produces a task<std::vector<T>> if either one or both of the tasks are of type task<std::vector<T>>. +/// +/// +/// If one of the tasks is canceled or throws an exception, the returned task will complete early, in the canceled state, and the exception, +/// if one is encoutered, will be thrown if you call get() or wait() on that task. +/// +/// +/**/ +template +task> operator&&(const task<_ReturnType> & _Lhs, const task> & _Rhs) +{ + return details::_WhenAllVectorAndValue(_Rhs, _Lhs, false); +} + +/// +/// Creates a task that will complete succesfully when both of the tasks supplied as arguments complete successfully. +/// +/// +/// The type of the returned task. +/// +/// +/// The first task to combine into the resulting task. +/// +/// +/// The second task to combine into the resulting task. +/// +/// +/// A task that completes successfully when both of the input tasks have completed successfully. If the input tasks are of type T, +/// the output of this function will be a task<std::vector<T>>. If the input tasks are of type void the output +/// task will also be a task<void>. +/// To allow for a construct of the sort taskA && taskB && taskC, which are combined in pairs, the && operator +/// produces a task<std::vector<T>> if either one or both of the tasks are of type task<std::vector<T>>. +/// +/// +/// If one of the tasks is canceled or throws an exception, the returned task will complete early, in the canceled state, and the exception, +/// if one is encoutered, will be thrown if you call get() or wait() on that task. +/// +/// +/**/ +template +task> operator&&(const task> & _Lhs, const task> & _Rhs) +{ + task> _PTasks[2] = { _Lhs, _Rhs }; + return when_all(_PTasks, _PTasks + 2); +} + +/// +/// Creates a task that will complete succesfully when both of the tasks supplied as arguments complete successfully. +/// +/// +/// The type of the returned task. +/// +/// +/// The first task to combine into the resulting task. +/// +/// +/// The second task to combine into the resulting task. +/// +/// +/// A task that completes successfully when both of the input tasks have completed successfully. If the input tasks are of type T, +/// the output of this function will be a task<std::vector<T>>. If the input tasks are of type void the output +/// task will also be a task<void>. +/// To allow for a construct of the sort taskA && taskB && taskC, which are combined in pairs, the && operator +/// produces a task<std::vector<T>> if either one or both of the tasks are of type task<std::vector<T>>. +/// +/// +/// If one of the tasks is canceled or throws an exception, the returned task will complete early, in the canceled state, and the exception, +/// if one is encoutered, will be thrown if you call get() or wait() on that task. +/// +/// +/**/ +inline task operator&&(const task & _Lhs, const task & _Rhs) +{ + task _PTasks[2] = { _Lhs, _Rhs }; + return when_all(_PTasks, _PTasks + 2); +} + +namespace details +{ + // Helper struct for when_any operators to know when tasks have completed + template + struct _RunAnyParam + { + _RunAnyParam() : _M_completeCount(0), _M_numTasks(0), _M_exceptionRelatedToken(nullptr), _M_fHasExplicitToken(false) + { + } + ~_RunAnyParam() + { + if (Concurrency::details::_CancellationTokenState::_IsValid(_M_exceptionRelatedToken)) + _M_exceptionRelatedToken->_Release(); + } + task_completion_event<_CompletionType> _M_Completed; + Concurrency::cancellation_token_source _M_cancellationSource; + Concurrency::details::_CancellationTokenState* _M_exceptionRelatedToken; + atomic_size_t _M_completeCount; + size_t _M_numTasks; + bool _M_fHasExplicitToken; + }; + + template + void _WhenAnyContinuationWrapper(_RunAnyParam<_CompletionType> * _PParam, const _Function & _Func, task<_TaskType>& _Task) + { + bool _IsTokenCancled = !_PParam->_M_fHasExplicitToken && _Task._GetImpl()->_M_pTokenState != Concurrency::details::_CancellationTokenState::_None() && _Task._GetImpl()->_M_pTokenState->_IsCanceled(); + if (_Task._GetImpl()->_IsCompleted() && !_IsTokenCancled) + { + _Func(); +#if _MSC_VER >= 1800 + if (Concurrency::details::atomic_increment(_PParam->_M_completeCount) == _PParam->_M_numTasks) +#else + if (_InterlockedIncrementSizeT(&_PParam->_M_completeCount) == _PParam->_M_numTasks) +#endif + { + delete _PParam; + } + } + else + { + _CONCRT_ASSERT(_Task._GetImpl()->_IsCanceled() || _IsTokenCancled); + if (_Task._GetImpl()->_HasUserException() && !_IsTokenCancled) + { + if (_PParam->_M_Completed._StoreException(_Task._GetImpl()->_GetExceptionHolder())) + { + // This can only enter once. + _PParam->_M_exceptionRelatedToken = _Task._GetImpl()->_M_pTokenState; + _CONCRT_ASSERT(_PParam->_M_exceptionRelatedToken); + // Deref token will be done in the _PParam destructor. + if (_PParam->_M_exceptionRelatedToken != Concurrency::details::_CancellationTokenState::_None()) + { + _PParam->_M_exceptionRelatedToken->_Reference(); + } + } + } + +#if _MSC_VER >= 1800 + if (Concurrency::details::atomic_increment(_PParam->_M_completeCount) == _PParam->_M_numTasks) +#else + if (_InterlockedIncrementSizeT(&_PParam->_M_completeCount) == _PParam->_M_numTasks) +#endif + { + // If no one has be completed so far, we need to make some final cancellation decision. + if (!_PParam->_M_Completed._IsTriggered()) + { + // If we already explicit token, we can skip the token join part. + if (!_PParam->_M_fHasExplicitToken) + { + if (_PParam->_M_exceptionRelatedToken) + { + details::_JoinAllTokens_Add(_PParam->_M_cancellationSource, _PParam->_M_exceptionRelatedToken); + } + else + { + // If haven't captured any exception token yet, there was no exception for all those tasks, + // so just pick a random token (current one) for normal cancellation. + details::_JoinAllTokens_Add(_PParam->_M_cancellationSource, _Task._GetImpl()->_M_pTokenState); + } + } + // Do exception cancellation or normal cancellation based on whether it has stored exception. + _PParam->_M_Completed._Cancel(); + } + delete _PParam; + } + } + } + + template + struct _WhenAnyImpl + { +#if _MSC_VER >= 1800 + static task> _Perform(const task_options& _TaskOptions, _Iterator _Begin, _Iterator _End) +#else + static task> _Perform(Concurrency::details::_CancellationTokenState *_PTokenState, _Iterator _Begin, _Iterator _End) +#endif + { + if (_Begin == _End) + { + throw Concurrency::invalid_operation("when_any(begin, end) cannot be called on an empty container."); + } +#if _MSC_VER >= 1800 + Concurrency::details::_CancellationTokenState *_PTokenState = _TaskOptions.has_cancellation_token() ? _TaskOptions.get_cancellation_token()._GetImplValue() : nullptr; +#endif + auto _PParam = new _RunAnyParam, Concurrency::details::_CancellationTokenState *>>(); + + if (_PTokenState) + { + details::_JoinAllTokens_Add(_PParam->_M_cancellationSource, _PTokenState); + _PParam->_M_fHasExplicitToken = true; + } +#if _MSC_VER >= 1800 + task_options _Options(_TaskOptions); + _Options.set_cancellation_token(_PParam->_M_cancellationSource.get_token()); + task, Concurrency::details::_CancellationTokenState *>> _Any_tasks_completed(_PParam->_M_Completed, _Options); +#else + task, Concurrency::details::_CancellationTokenState *>> _Any_tasks_completed(_PParam->_M_Completed, _PParam->_M_cancellationSource.get_token()); + _Any_tasks_completed._GetImpl()->_M_fRuntimeAggregate = true; +#endif + // Keep a copy ref to the token source + auto _CancellationSource = _PParam->_M_cancellationSource; + + _PParam->_M_numTasks = static_cast(std::distance(_Begin, _End)); + size_t index = 0; + for (auto _PTask = _Begin; _PTask != _End; ++_PTask) + { + if (_PTask->is_apartment_aware()) + { + _Any_tasks_completed._SetAsync(); + } + + _PTask->_Then([_PParam, index](task<_ElementType> _ResultTask) -> HRESULT { +#if _MSC_VER >= 1800 + auto _PParamCopy = _PParam; // Dev10 + auto _IndexCopy = index; // Dev10 + auto _Func = [&_ResultTask, _PParamCopy, _IndexCopy]() { + _PParamCopy->_M_Completed.set(std::make_pair(std::make_pair(_ResultTask._GetImpl()->_GetResult(), _IndexCopy), _ResultTask._GetImpl()->_M_pTokenState)); + }; +#else + auto _Func = [&_ResultTask, _PParam, index]() { + _PParam->_M_Completed.set(std::make_pair(std::make_pair(_ResultTask._GetImpl()->_GetResult(), index), _ResultTask._GetImpl()->_M_pTokenState)); + }; +#endif + _WhenAnyContinuationWrapper(_PParam, _Func, _ResultTask); + return S_OK; +#if _MSC_VER >= 1800 + }, Concurrency::details::_CancellationTokenState::_None()); +#else + }, Concurrency::details::_CancellationTokenState::_None(), false); +#endif + index++; + } + + // All _Any_tasks_completed._SetAsync() must be finished before this return continuation task being created. + return _Any_tasks_completed._Then([=](std::pair, Concurrency::details::_CancellationTokenState *> _Result, std::pair<_ElementType, size_t>* retVal) -> HRESULT { + _CONCRT_ASSERT(_Result.second); + if (!_PTokenState) + { + details::_JoinAllTokens_Add(_CancellationSource, _Result.second); + } + *retVal = _Result.first; + return S_OK; +#if _MSC_VER >= 1800 + }, nullptr); +#else + }, nullptr, true); +#endif + } + }; + + template + struct _WhenAnyImpl + { +#if _MSC_VER >= 1800 + static task _Perform(const task_options& _TaskOptions, _Iterator _Begin, _Iterator _End) +#else + static task _Perform(Concurrency::details::_CancellationTokenState *_PTokenState, _Iterator _Begin, _Iterator _End) +#endif + { + if (_Begin == _End) + { + throw Concurrency::invalid_operation("when_any(begin, end) cannot be called on an empty container."); + } +#if _MSC_VER >= 1800 + Concurrency::details::_CancellationTokenState *_PTokenState = _TaskOptions.has_cancellation_token() ? _TaskOptions.get_cancellation_token()._GetImplValue() : nullptr; +#endif + auto _PParam = new _RunAnyParam>(); + + if (_PTokenState) + { + details::_JoinAllTokens_Add(_PParam->_M_cancellationSource, _PTokenState); + _PParam->_M_fHasExplicitToken = true; + } + +#if _MSC_VER >= 1800 + task_options _Options(_TaskOptions); + _Options.set_cancellation_token(_PParam->_M_cancellationSource.get_token()); + task> _Any_tasks_completed(_PParam->_M_Completed, _Options); +#else + task> _Any_tasks_completed(_PParam->_M_Completed, _PParam->_M_cancellationSource.get_token()); +#endif + // Keep a copy ref to the token source + auto _CancellationSource = _PParam->_M_cancellationSource; + + _PParam->_M_numTasks = static_cast(std::distance(_Begin, _End)); + size_t index = 0; + for (auto _PTask = _Begin; _PTask != _End; ++_PTask) + { + if (_PTask->is_apartment_aware()) + { + _Any_tasks_completed._SetAsync(); + } + + _PTask->_Then([_PParam, index](task _ResultTask) -> HRESULT { +#if _MSC_VER >= 1800 + auto _PParamCopy = _PParam; // Dev10 + auto _IndexCopy = index; // Dev10 + auto _Func = [&_ResultTask, _PParamCopy, _IndexCopy]() { + _PParamCopy->_M_Completed.set(std::make_pair(_IndexCopy, _ResultTask._GetImpl()->_M_pTokenState)); + }; +#else + auto _Func = [&_ResultTask, _PParam, index]() { + _PParam->_M_Completed.set(std::make_pair(index, _ResultTask._GetImpl()->_M_pTokenState)); + }; +#endif + _WhenAnyContinuationWrapper(_PParam, _Func, _ResultTask); + return S_OK; +#if _MSC_VER >= 1800 + }, Concurrency::details::_CancellationTokenState::_None()); +#else + }, Concurrency::details::_CancellationTokenState::_None(), false); +#endif + + index++; + } + + // All _Any_tasks_completed._SetAsync() must be finished before this return continuation task being created. + return _Any_tasks_completed._Then([=](std::pair _Result, size_t* retVal) -> HRESULT { + _CONCRT_ASSERT(_Result.second); + if (!_PTokenState) + { + details::_JoinAllTokens_Add(_CancellationSource, _Result.second); + } + *retVal = _Result.first; + return S_OK; +#if _MSC_VER >= 1800 + }, nullptr); +#else + }, nullptr, false); +#endif + } + }; +} // namespace details + +/// +/// Creates a task that will complete successfully when any of the tasks supplied as arguments completes successfully. +/// +/// +/// The type of the input iterator. +/// +/// +/// The position of the first element in the range of elements to be combined into the resulting task. +/// +/// +/// The position of the first element beyond the range of elements to be combined into the resulting task. +/// +/// +/// A task that completes successfully when any one of the input tasks has completed successfully. If the input tasks are of type T, +/// the output of this function will be a task<std::pair<T, size_t>>>, where the first element of the pair is the result +/// of the completing task, and the second element is the index of the task that finished. If the input tasks are of type void +/// the output is a task<size_t>, where the result is the index of the completing task. +/// +/// +/**/ +template +#if _MSC_VER >= 1800 +auto when_any(_Iterator _Begin, _Iterator _End, const task_options& _TaskOptions = task_options()) +-> decltype (details::_WhenAnyImpl::value_type::result_type, _Iterator>::_Perform(_TaskOptions, _Begin, _End)) +{ + typedef typename std::iterator_traits<_Iterator>::value_type::result_type _ElementType; + return details::_WhenAnyImpl<_ElementType, _Iterator>::_Perform(_TaskOptions, _Begin, _End); +} +#else +auto when_any(_Iterator _Begin, _Iterator _End) +-> decltype (details::_WhenAnyImpl::value_type::result_type, _Iterator>::_Perform(nullptr, _Begin, _End)) +{ + typedef typename std::iterator_traits<_Iterator>::value_type::result_type _ElementType; + return details::_WhenAnyImpl<_ElementType, _Iterator>::_Perform(nullptr, _Begin, _End); +} +#endif + +/// +/// Creates a task that will complete successfully when any of the tasks supplied as arguments completes successfully. +/// +/// +/// The type of the input iterator. +/// +/// +/// The position of the first element in the range of elements to be combined into the resulting task. +/// +/// +/// The position of the first element beyond the range of elements to be combined into the resulting task. +/// +/// +/// The cancellation token which controls cancellation of the returned task. If you do not provide a cancellation token, the resulting +/// task will receive the cancellation token of the task that causes it to complete. +/// +/// +/// A task that completes successfully when any one of the input tasks has completed successfully. If the input tasks are of type T, +/// the output of this function will be a task<std::pair<T, size_t>>>, where the first element of the pair is the result +/// of the completing task, and the second element is the index of the task that finished. If the input tasks are of type void +/// the output is a task<size_t>, where the result is the index of the completing task. +/// +/// +/**/ +template +auto when_any(_Iterator _Begin, _Iterator _End, Concurrency::cancellation_token _CancellationToken) +-> decltype (details::_WhenAnyImpl::value_type::result_type, _Iterator>::_Perform(_CancellationToken._GetImplValue(), _Begin, _End)) +{ + typedef typename std::iterator_traits<_Iterator>::value_type::result_type _ElementType; + return details::_WhenAnyImpl<_ElementType, _Iterator>::_Perform(_CancellationToken._GetImplValue(), _Begin, _End); +} + +/// +/// Creates a task that will complete successfully when either of the tasks supplied as arguments completes successfully. +/// +/// +/// The type of the returned task. +/// +/// +/// The first task to combine into the resulting task. +/// +/// +/// The second task to combine into the resulting task. +/// +/// +/// A task that completes sucessfully when either of the input tasks has completed successfully. If the input tasks are of type T, +/// the output of this function will be a task<std::vector<T>. If the input tasks are of type void the output task +/// will also be a task<void>. +/// To allow for a construct of the sort taskA || taskB && taskC, which are combined in pairs, with && taking precedence +/// over ||, the operator|| produces a task<std::vector<T>> if one of the tasks is of type task<std::vector<T>> +/// and the other one is of type task<T>. +/// +/// +/// If both of the tasks are canceled or throw exceptions, the returned task will complete in the canceled state, and one of the exceptions, +/// if any are encountered, will be thrown when you call get() or wait() on that task. +/// +/// +/**/ +template +task<_ReturnType> operator||(const task<_ReturnType> & _Lhs, const task<_ReturnType> & _Rhs) +{ +#if _MSC_VER >= 1800 + auto _PParam = new details::_RunAnyParam>(); + + task> _Any_tasks_completed(_PParam->_M_Completed, _PParam->_M_cancellationSource.get_token()); + // Chain the return continuation task here to ensure it will get inline execution when _M_Completed.set is called, + // So that _PParam can be used before it getting deleted. + auto _ReturnTask = _Any_tasks_completed._Then([=](std::pair<_ReturnType, size_t> _Ret, _ReturnType* retVal) -> HRESULT { + _CONCRT_ASSERT(_Ret.second); + details::_JoinAllTokens_Add(_PParam->_M_cancellationSource, reinterpret_cast(_Ret.second)); + *retVal = _Ret.first; + return S_OK; + }, nullptr); +#else + auto _PParam = new details::_RunAnyParam>(); + + task> _Any_tasks_completed(_PParam->_M_Completed, _PParam->_M_cancellationSource.get_token()); + // Chain the return continuation task here to ensure it will get inline execution when _M_Completed.set is called, + // So that _PParam can be used before it getting deleted. + auto _ReturnTask = _Any_tasks_completed._Then([=](std::pair<_ReturnType, Concurrency::details::_CancellationTokenState *> _Ret, _ReturnType* retVal) -> HRESULT { + _CONCRT_ASSERT(_Ret.second); + details::_JoinAllTokens_Add(_PParam->_M_cancellationSource, _Ret.second); + *retVal = _Ret.first; + return S_OK; + }, nullptr, false); +#endif + if (_Lhs.is_apartment_aware() || _Rhs.is_apartment_aware()) + { + _ReturnTask._SetAsync(); + } + + _PParam->_M_numTasks = 2; + auto _Continuation = [_PParam](task<_ReturnType> _ResultTask) -> HRESULT { +#if _MSC_VER >= 1800 + // Dev10 compiler bug + auto _PParamCopy = _PParam; + auto _Func = [&_ResultTask, _PParamCopy]() { + _PParamCopy->_M_Completed.set(std::make_pair(_ResultTask._GetImpl()->_GetResult(), reinterpret_cast(_ResultTask._GetImpl()->_M_pTokenState))); + }; +#else + auto _Func = [&_ResultTask, _PParam]() { + _PParam->_M_Completed.set(std::make_pair(_ResultTask._GetImpl()->_GetResult(), _ResultTask._GetImpl()->_M_pTokenState)); + }; +#endif + _WhenAnyContinuationWrapper(_PParam, _Func, _ResultTask); + return S_OK; + }; + +#if _MSC_VER >= 1800 + _Lhs._Then(_Continuation, Concurrency::details::_CancellationTokenState::_None()); + _Rhs._Then(_Continuation, Concurrency::details::_CancellationTokenState::_None()); +#else + _Lhs._Then(_Continuation, Concurrency::details::_CancellationTokenState::_None(), false); + _Rhs._Then(_Continuation, Concurrency::details::_CancellationTokenState::_None(), false); +#endif + return _ReturnTask; +} + +/// +/// Creates a task that will complete successfully when any of the tasks supplied as arguments completes successfully. +/// +/// +/// The type of the returned task. +/// +/// +/// The first task to combine into the resulting task. +/// +/// +/// The second task to combine into the resulting task. +/// +/// +/// A task that completes sucessfully when either of the input tasks has completed successfully. If the input tasks are of type T, +/// the output of this function will be a task<std::vector<T>. If the input tasks are of type void the output task +/// will also be a task<void>. +/// To allow for a construct of the sort taskA || taskB && taskC, which are combined in pairs, with && taking precedence +/// over ||, the operator|| produces a task<std::vector<T>> if one of the tasks is of type task<std::vector<T>> +/// and the other one is of type task<T>. +/// +/// +/// If both of the tasks are canceled or throw exceptions, the returned task will complete in the canceled state, and one of the exceptions, +/// if any are encountered, will be thrown when you call get() or wait() on that task. +/// +/// +/**/ +template +task> operator||(const task> & _Lhs, const task<_ReturnType> & _Rhs) +{ + auto _PParam = new details::_RunAnyParam, Concurrency::details::_CancellationTokenState *>>(); + + task, Concurrency::details::_CancellationTokenState *>> _Any_tasks_completed(_PParam->_M_Completed, _PParam->_M_cancellationSource.get_token()); +#if _MSC_VER < 1800 + _Any_tasks_completed._GetImpl()->_M_fRuntimeAggregate = true; +#endif + // Chain the return continuation task here to ensure it will get inline execution when _M_Completed.set is called, + // So that _PParam can be used before it getting deleted. + auto _ReturnTask = _Any_tasks_completed._Then([=](std::pair, Concurrency::details::_CancellationTokenState *> _Ret, std::vector<_ReturnType>* retVal) -> HRESULT { + _CONCRT_ASSERT(_Ret.second); + details::_JoinAllTokens_Add(_PParam->_M_cancellationSource, _Ret.second); + *retVal = _Ret.first; + return S_OK; + }, nullptr, true); + + if (_Lhs.is_apartment_aware() || _Rhs.is_apartment_aware()) + { + _ReturnTask._SetAsync(); + } + + _PParam->_M_numTasks = 2; + _Lhs._Then([_PParam](task> _ResultTask) -> HRESULT { +#if _MSC_VER >= 1800 + // Dev10 compiler bug + auto _PParamCopy = _PParam; + auto _Func = [&_ResultTask, _PParamCopy]() { + auto _Result = _ResultTask._GetImpl()->_GetResult(); + _PParamCopy->_M_Completed.set(std::make_pair(_Result, _ResultTask._GetImpl()->_M_pTokenState)); + }; +#else + auto _Func = [&_ResultTask, _PParam]() { + std::vector<_ReturnType> _Result = _ResultTask._GetImpl()->_GetResult(); + _PParam->_M_Completed.set(std::make_pair(_Result, _ResultTask._GetImpl()->_M_pTokenState)); + }; +#endif + _WhenAnyContinuationWrapper(_PParam, _Func, _ResultTask); + return S_OK; +#if _MSC_VER >= 1800 + }, Concurrency::details::_CancellationTokenState::_None()); +#else + }, Concurrency::details::_CancellationTokenState::_None(), false); +#endif + _Rhs._Then([_PParam](task<_ReturnType> _ResultTask) -> HRESULT { +#if _MSC_VER >= 1800 + // Dev10 compiler bug + typedef _ReturnType _ReturnTypeDev10; + auto _PParamCopy = _PParam; + auto _Func = [&_ResultTask, _PParamCopy]() { + auto _Result = _ResultTask._GetImpl()->_GetResult(); + + std::vector<_ReturnTypeDev10> _Vec; + _Vec.push_back(_Result); + _PParamCopy->_M_Completed.set(std::make_pair(_Vec, _ResultTask._GetImpl()->_M_pTokenState)); + }; +#else + auto _Func = [&_ResultTask, _PParam]() { + _ReturnType _Result = _ResultTask._GetImpl()->_GetResult(); + + std::vector<_ReturnType> _Vec; + _Vec.push_back(_Result); + _PParam->_M_Completed.set(std::make_pair(_Vec, _ResultTask._GetImpl()->_M_pTokenState)); + }; +#endif + _WhenAnyContinuationWrapper(_PParam, _Func, _ResultTask); + return S_OK; +#if _MSC_VER >= 1800 + }, Concurrency::details::_CancellationTokenState::_None()); +#else + }, Concurrency::details::_CancellationTokenState::_None(), false); +#endif + return _ReturnTask; +} + +/// +/// Creates a task that will complete successfully when any of the tasks supplied as arguments completes successfully. +/// +/// +/// The type of the returned task. +/// +/// +/// The first task to combine into the resulting task. +/// +/// +/// The second task to combine into the resulting task. +/// +/// +/// A task that completes sucessfully when either of the input tasks has completed successfully. If the input tasks are of type T, +/// the output of this function will be a task<std::vector<T>. If the input tasks are of type void the output task +/// will also be a task<void>. +/// To allow for a construct of the sort taskA || taskB && taskC, which are combined in pairs, with && taking precedence +/// over ||, the operator|| produces a task<std::vector<T>> if one of the tasks is of type task<std::vector<T>> +/// and the other one is of type task<T>. +/// +/// +/// If both of the tasks are canceled or throw exceptions, the returned task will complete in the canceled state, and one of the exceptions, +/// if any are encountered, will be thrown when you call get() or wait() on that task. +/// +/// +/**/ +template +task> operator||(const task<_ReturnType> & _Lhs, const task> & _Rhs) +{ + return _Rhs || _Lhs; +} + +/// +/// Creates a task that will complete successfully when any of the tasks supplied as arguments completes successfully. +/// +/// +/// The type of the returned task. +/// +/// +/// The first task to combine into the resulting task. +/// +/// +/// The second task to combine into the resulting task. +/// +/// +/// A task that completes sucessfully when either of the input tasks has completed successfully. If the input tasks are of type T, +/// the output of this function will be a task<std::vector<T>. If the input tasks are of type void the output task +/// will also be a task<void>. +/// To allow for a construct of the sort taskA || taskB && taskC, which are combined in pairs, with && taking precedence +/// over ||, the operator|| produces a task<std::vector<T>> if one of the tasks is of type task<std::vector<T>> +/// and the other one is of type task<T>. +/// +/// +/// If both of the tasks are canceled or throw exceptions, the returned task will complete in the canceled state, and one of the exceptions, +/// if any are encountered, will be thrown when you call get() or wait() on that task. +/// +/// +/**/ +inline task operator||(const task & _Lhs, const task & _Rhs) +{ + auto _PParam = new details::_RunAnyParam>(); + + task> _Any_task_completed(_PParam->_M_Completed, _PParam->_M_cancellationSource.get_token()); + // Chain the return continuation task here to ensure it will get inline execution when _M_Completed.set is called, + // So that _PParam can be used before it getting deleted. + auto _ReturnTask = _Any_task_completed._Then([=](std::pair _Ret) -> HRESULT { + _CONCRT_ASSERT(_Ret.second); + details::_JoinAllTokens_Add(_PParam->_M_cancellationSource, _Ret.second); + return S_OK; +#if _MSC_VER >= 1800 + }, nullptr); +#else + }, nullptr, false); +#endif + + if (_Lhs.is_apartment_aware() || _Rhs.is_apartment_aware()) + { + _ReturnTask._SetAsync(); + } + + _PParam->_M_numTasks = 2; + auto _Continuation = [_PParam](task _ResultTask) mutable -> HRESULT { + // Dev10 compiler needs this. + auto _PParam1 = _PParam; + auto _Func = [&_ResultTask, _PParam1]() { + _PParam1->_M_Completed.set(std::make_pair(details::_Unit_type(), _ResultTask._GetImpl()->_M_pTokenState)); + }; + _WhenAnyContinuationWrapper(_PParam, _Func, _ResultTask); + return S_OK; + }; + +#if _MSC_VER >= 1800 + _Lhs._Then(_Continuation, Concurrency::details::_CancellationTokenState::_None()); + _Rhs._Then(_Continuation, Concurrency::details::_CancellationTokenState::_None()); +#else + _Lhs._Then(_Continuation, Concurrency::details::_CancellationTokenState::_None(), false); + _Rhs._Then(_Continuation, Concurrency::details::_CancellationTokenState::_None(), false); +#endif + + return _ReturnTask; +} + +#if _MSC_VER >= 1800 +template +task<_Ty> task_from_result(_Ty _Param, const task_options& _TaskOptions = task_options()) +{ + task_completion_event<_Ty> _Tce; + _Tce.set(_Param); + return create_task<_Ty>(_Tce, _TaskOptions); +} + +// Work around VS 2010 compiler bug +#if _MSC_VER == 1600 +inline task task_from_result(bool _Param) +{ + task_completion_event _Tce; + _Tce.set(_Param); + return create_task(_Tce, task_options()); +} +#endif +inline task task_from_result(const task_options& _TaskOptions = task_options()) +{ + task_completion_event _Tce; + _Tce.set(); + return create_task(_Tce, _TaskOptions); +} + +template +task<_TaskType> task_from_exception(_ExType _Exception, const task_options& _TaskOptions = task_options()) +{ + task_completion_event<_TaskType> _Tce; + _Tce.set_exception(_Exception); + return create_task<_TaskType>(_Tce, _TaskOptions); +} + +namespace details +{ + /// + /// A convenient extension to Concurrency: loop until a condition is no longer met + /// + /// + /// A function representing the body of the loop. It will be invoked at least once and + /// then repetitively as long as it returns true. + /// + inline + task do_while(std::function(void)> func) + { + task first = func(); + return first.then([=](bool guard, task* retVal) -> HRESULT { + if (guard) + *retVal = do_while(func); + else + *retVal = first; + return S_OK; + }); + } + +} // namespace details +#endif + +} // namespace Concurrency_winrt + +namespace concurrency_winrt = Concurrency_winrt; + +#pragma pop_macro("new") +#pragma warning(pop) +#pragma pack(pop) +#endif + +#endif From d08cb6b357f779e2099d00ea9d3b6530271ff45a Mon Sep 17 00:00:00 2001 From: Maxim Kostin Date: Fri, 15 May 2015 16:28:47 +0300 Subject: [PATCH 27/31] Added WinRT support for videoio. Signed-off-by: Maxim Kostin --- modules/videoio/include/opencv2/videoio.hpp | 6 +- .../include/opencv2/videoio/cap_winrt.hpp | 130 ++++++ modules/videoio/src/cap.cpp | 42 +- .../src/cap_winrt/CaptureFrameGrabber.cpp | 173 ++++++++ .../src/cap_winrt/CaptureFrameGrabber.hpp | 85 ++++ modules/videoio/src/cap_winrt/MFIncludes.hpp | 172 ++++++++ modules/videoio/src/cap_winrt/MediaSink.hpp | 396 ++++++++++++++++++ .../videoio/src/cap_winrt/MediaStreamSink.cpp | 386 +++++++++++++++++ .../videoio/src/cap_winrt/MediaStreamSink.hpp | 114 +++++ modules/videoio/src/cap_winrt_bridge.cpp | 89 ++++ modules/videoio/src/cap_winrt_bridge.hpp | 96 +++++ modules/videoio/src/cap_winrt_capture.cpp | 279 ++++++++++++ modules/videoio/src/cap_winrt_capture.hpp | 82 ++++ modules/videoio/src/cap_winrt_video.cpp | 322 ++++++++++++++ modules/videoio/src/cap_winrt_video.hpp | 73 ++++ 15 files changed, 2442 insertions(+), 3 deletions(-) create mode 100644 modules/videoio/include/opencv2/videoio/cap_winrt.hpp create mode 100644 modules/videoio/src/cap_winrt/CaptureFrameGrabber.cpp create mode 100644 modules/videoio/src/cap_winrt/CaptureFrameGrabber.hpp create mode 100644 modules/videoio/src/cap_winrt/MFIncludes.hpp create mode 100644 modules/videoio/src/cap_winrt/MediaSink.hpp create mode 100644 modules/videoio/src/cap_winrt/MediaStreamSink.cpp create mode 100644 modules/videoio/src/cap_winrt/MediaStreamSink.hpp create mode 100644 modules/videoio/src/cap_winrt_bridge.cpp create mode 100644 modules/videoio/src/cap_winrt_bridge.hpp create mode 100644 modules/videoio/src/cap_winrt_capture.cpp create mode 100644 modules/videoio/src/cap_winrt_capture.hpp create mode 100644 modules/videoio/src/cap_winrt_video.cpp create mode 100644 modules/videoio/src/cap_winrt_video.hpp diff --git a/modules/videoio/include/opencv2/videoio.hpp b/modules/videoio/include/opencv2/videoio.hpp index b0245b1df0..a9a42dfb5b 100644 --- a/modules/videoio/include/opencv2/videoio.hpp +++ b/modules/videoio/include/opencv2/videoio.hpp @@ -50,6 +50,7 @@ @{ @defgroup videoio_c C API @defgroup videoio_ios iOS glue + @defgroup videoio_winrt WinRT glue @} */ @@ -85,8 +86,9 @@ enum { CAP_ANY = 0, // autodetect CAP_AVFOUNDATION = 1200, // AVFoundation framework for iOS (OS X Lion will have the same API) CAP_GIGANETIX = 1300, // Smartek Giganetix GigEVisionSDK CAP_MSMF = 1400, // Microsoft Media Foundation (via videoInput) - CAP_INTELPERC = 1500, // Intel Perceptual Computing SDK - CAP_OPENNI2 = 1600, // OpenNI2 (for Kinect) + CAP_WINRT = 1410, // Microsoft Windows Runtime using Media Foundation + CAP_INTELPERC = 1500, // Intel Perceptual Computing SDK + CAP_OPENNI2 = 1600, // OpenNI2 (for Kinect) CAP_OPENNI2_ASUS = 1610 // OpenNI2 (for Asus Xtion and Occipital Structure sensors) }; diff --git a/modules/videoio/include/opencv2/videoio/cap_winrt.hpp b/modules/videoio/include/opencv2/videoio/cap_winrt.hpp new file mode 100644 index 0000000000..39f98d3a83 --- /dev/null +++ b/modules/videoio/include/opencv2/videoio/cap_winrt.hpp @@ -0,0 +1,130 @@ +// Video support for Windows Runtime + +// Copyright (c) Microsoft Open Technologies, Inc. +// All rights reserved. +// +// (3 - clause BSD License) +// +// Redistribution and use in source and binary forms, with or without modification, are permitted provided that +// the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the +// following disclaimer. +// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the +// following disclaimer in the documentation and/or other materials provided with the distribution. +// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or +// promote products derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED +// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +// PARTICULAR PURPOSE ARE DISCLAIMED.IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY +// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES(INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT(INCLUDING +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. + +#include +#include +#include +#include + +using namespace Windows::UI::Xaml::Controls; + +namespace cv +{ + +//! @addtogroup videoio_winrt +//! @{ + +enum { + OPEN_CAMERA = 300, + CLOSE_CAMERA, + UPDATE_IMAGE_ELEMENT, + SHOW_TRACKBAR +}; + +/********************************** WinRT API ************************************************/ + +template +CV_EXPORTS void winrt_startMessageLoop(std::function&& callback, Args... args); + +template +CV_EXPORTS void winrt_startMessageLoop(void callback(Args...), Args... args); + +/** @brief +@note + Sets the reporter method for the HighguiAssist singleton. Starts the main OpenCV as + an async thread in WinRT. See VideoCapture for the example of callback implementation. + Here is how the class can be used: +@code + void cvMain() + { + Mat frame; + VideoCapture cam; + cam.open(0); + + while (1) + { + cam >> frame; + + // don't reprocess the same frame again + if (!cam.grab()) continue; + + // your processing logic goes here + + // obligatory step to get XAML image component updated + winrt_imshow(); + } + } + + MainPage::MainPage() + { + InitializeComponent(); + + cv::winrt_setFrameContainer(cvImage); + cv::winrt_startMessageLoop(cvMain); + } +@endcode +*/ +template +CV_EXPORTS void winrt_startMessageLoop(void callback(void)); + +/** @brief +@note + Must be called from WinRT specific callback to handle image grabber state. + Here is how the class can be used: +@code + MainPage::MainPage() + { + // ... + Window::Current->VisibilityChanged += ref new Windows::UI::Xaml::WindowVisibilityChangedEventHandler(this, &Application::MainPage::OnVisibilityChanged); + // ... + } + + void Application::MainPage::OnVisibilityChanged(Platform::Object ^sender, + Windows::UI::Core::VisibilityChangedEventArgs ^e) + { + cv::winrt_onVisibilityChanged(e->Visible); + } +@endcode +*/ +CV_EXPORTS void winrt_onVisibilityChanged(bool visible); + +/** @brief +@note + Must be called to assign WinRT control holding image you're working with. + Code sample is available for winrt_startMessageLoop(). +*/ +CV_EXPORTS void winrt_setFrameContainer(::Windows::UI::Xaml::Controls::Image^ image); + +/** @brief +@note + Must be called to update attached image source. + Code sample is available for winrt_startMessageLoop(). +*/ +CV_EXPORTS void winrt_imshow(); + +//! @} videoio_winrt + +} // cv \ No newline at end of file diff --git a/modules/videoio/src/cap.cpp b/modules/videoio/src/cap.cpp index 1fedb0b66d..67eb28395d 100644 --- a/modules/videoio/src/cap.cpp +++ b/modules/videoio/src/cap.cpp @@ -43,6 +43,13 @@ #include "cap_intelperc.hpp" #include "cap_dshow.hpp" +// All WinRT versions older than 8.0 should provide classes used for video support +#if defined(WINRT) && !defined(WINRT_8_0) +# include "cap_winrt_capture.hpp" +# include "cap_winrt_bridge.hpp" +# define WINRT_VIDEO +#endif + #if defined _M_X64 && defined _MSC_VER && !defined CV_ICC #pragma optimize("",off) #pragma warning(disable: 4748) @@ -508,6 +515,9 @@ static Ptr IVideoCapture_create(int index) #endif #ifdef HAVE_INTELPERC CV_CAP_INTELPERC, +#endif +#ifdef WINRT_VIDEO + CAP_WINRT, #endif -1, -1 }; @@ -526,6 +536,7 @@ static Ptr IVideoCapture_create(int index) { #if defined(HAVE_DSHOW) || \ defined(HAVE_INTELPERC) || \ + defined(WINRT_VIDEO) || \ (0) Ptr capture; @@ -540,6 +551,13 @@ static Ptr IVideoCapture_create(int index) case CV_CAP_INTELPERC: capture = makePtr(); break; // CV_CAP_INTEL_PERC +#endif +#ifdef WINRT_VIDEO + case CAP_WINRT: + capture = Ptr(new cv::VideoCapture_WinRT(index)); + if (capture) + return capture; + break; // CAP_WINRT #endif } if (capture && capture->isOpened()) @@ -664,7 +682,29 @@ bool VideoCapture::read(OutputArray image) VideoCapture& VideoCapture::operator >> (Mat& image) { +#ifdef WINRT_VIDEO + if (grab()) + { + if (retrieve(image)) + { + std::lock_guard lock(VideoioBridge::getInstance().inputBufferMutex); + VideoioBridge& bridge = VideoioBridge::getInstance(); + + // double buffering + bridge.swapInputBuffers(); + auto p = bridge.frontInputPtr; + + bridge.bIsFrameNew = false; + + // needed here because setting Mat 'image' is not allowed by OutputArray in read() + Mat m(bridge.height, bridge.width, CV_8UC3, p); + image = m; + } + } +#else read(image); +#endif + return *this; } @@ -760,4 +800,4 @@ int VideoWriter::fourcc(char c1, char c2, char c3, char c4) return (c1 & 255) + ((c2 & 255) << 8) + ((c3 & 255) << 16) + ((c4 & 255) << 24); } -} +} \ No newline at end of file diff --git a/modules/videoio/src/cap_winrt/CaptureFrameGrabber.cpp b/modules/videoio/src/cap_winrt/CaptureFrameGrabber.cpp new file mode 100644 index 0000000000..236e22766e --- /dev/null +++ b/modules/videoio/src/cap_winrt/CaptureFrameGrabber.cpp @@ -0,0 +1,173 @@ +// Copyright (c) Microsoft. All rights reserved. +// +// The MIT License (MIT) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files(the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions : +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#include "MediaStreamSink.hpp" +#include "MediaSink.hpp" +#include "CaptureFrameGrabber.hpp" + +using namespace Media; +using namespace Platform; +using namespace Windows::Foundation; +using namespace Windows::Media; +using namespace Windows::Media::Capture; +using namespace Windows::Media::MediaProperties; +using namespace concurrency; +using namespace Microsoft::WRL::Details; +using namespace Microsoft::WRL; + +task Media::CaptureFrameGrabber::CreateAsync(_In_ MediaCapture^ capture, _In_ VideoEncodingProperties^ props, CaptureStreamType streamType) +{ + auto reader = ref new Media::CaptureFrameGrabber(capture, props, streamType); + + auto profile = ref new MediaEncodingProfile(); + profile->Video = props; + + task task; + if (reader->_streamType == CaptureStreamType::Preview) + { + task = create_task(capture->StartPreviewToCustomSinkAsync(profile, reader->_mediaExtension)); + } + else + { + task = create_task(capture->StartRecordToCustomSinkAsync(profile, reader->_mediaExtension)); + } + + return task.then([reader]() + { + reader->_state = State::Started; + return reader; + }); +} + +Media::CaptureFrameGrabber::CaptureFrameGrabber(_In_ MediaCapture^ capture, _In_ VideoEncodingProperties^ props, CaptureStreamType streamType) +: _state(State::Created) +, _streamType(streamType) +, _capture(capture) +{ + auto videoSampleHandler = ref new MediaSampleHandler(this, &Media::CaptureFrameGrabber::ProcessSample); + + _mediaSink = Make(nullptr, props, nullptr, videoSampleHandler); + _mediaExtension = reinterpret_cast(static_cast(_mediaSink.Get())); +} + +Media::CaptureFrameGrabber::~CaptureFrameGrabber() +{ + if (_state == State::Started) + { + if (_streamType == CaptureStreamType::Preview) + { + (void)_capture->StopPreviewAsync(); + } + else + { + (void)_capture->StopRecordAsync(); + } + } + + if (_mediaSink != nullptr) + { + (void)_mediaSink->Shutdown(); + _mediaSink = nullptr; + } + _mediaExtension = nullptr; + _capture = nullptr; +} + +void Media::CaptureFrameGrabber::ShowCameraSettings() +{ +#if WINAPI_FAMILY!=WINAPI_FAMILY_PHONE_APP + if (_state == State::Started) + { + CameraOptionsUI::Show(_capture.Get()); + } +#endif +} + +task Media::CaptureFrameGrabber::FinishAsync() +{ + auto lock = _lock.LockExclusive(); + + if (_state != State::Started) + { + throw ref new COMException(E_UNEXPECTED, L"State"); + } + _state = State::Closing; + + if (_mediaSink != nullptr) + { + (void)_mediaSink->Shutdown(); + _mediaSink = nullptr; + } + _mediaExtension = nullptr; + + task task; + if (_streamType == CaptureStreamType::Preview) + { + task = create_task(_capture->StopPreviewAsync()); + } + else + { + task = create_task(_capture->StopRecordAsync()); + } + + return task.then([this]() + { + auto lock = _lock.LockExclusive(); + _state = State::Closed; + _capture = nullptr; + }); +} + +task> Media::CaptureFrameGrabber::GetFrameAsync() +{ + auto lock = _lock.LockExclusive(); + + if (_state != State::Started) + { + throw ref new COMException(E_UNEXPECTED, L"State"); + } + + _mediaSink->RequestVideoSample(); + + task_completion_event> taskEvent; + _videoSampleRequestQueue.push(taskEvent); + + return create_task(taskEvent); +} + +void Media::CaptureFrameGrabber::ProcessSample(_In_ MediaSample^ sample) +{ + task_completion_event> t; + + { + auto lock = _lock.LockExclusive(); + + t = _videoSampleRequestQueue.front(); + _videoSampleRequestQueue.pop(); + } + + ComPtr buffer; + CHK(sample->Sample->ConvertToContiguousBuffer(&buffer)); + + // Dispatch without the lock taken to avoid deadlocks + t.set(As(buffer)); +} \ No newline at end of file diff --git a/modules/videoio/src/cap_winrt/CaptureFrameGrabber.hpp b/modules/videoio/src/cap_winrt/CaptureFrameGrabber.hpp new file mode 100644 index 0000000000..d3bcec20db --- /dev/null +++ b/modules/videoio/src/cap_winrt/CaptureFrameGrabber.hpp @@ -0,0 +1,85 @@ +// Copyright (c) Microsoft. All rights reserved. +// +// The MIT License (MIT) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files(the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions : +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#pragma once + +#include "MFIncludes.hpp" + + +namespace Media { + +class MediaSink; + +enum class CaptureStreamType +{ + Preview = 0, + Record +}; + +ref class CaptureFrameGrabber sealed +{ +public: + + // IClosable + virtual ~CaptureFrameGrabber(); + + virtual void ShowCameraSettings(); + +internal: + + static concurrency::task CreateAsync(_In_ WMC::MediaCapture^ capture, _In_ WMMp::VideoEncodingProperties^ props) + { + return CreateAsync(capture, props, CaptureStreamType::Preview); + } + + static concurrency::task CreateAsync(_In_ WMC::MediaCapture^ capture, _In_ WMMp::VideoEncodingProperties^ props, CaptureStreamType streamType); + + concurrency::task> GetFrameAsync(); + concurrency::task FinishAsync(); + +private: + + CaptureFrameGrabber(_In_ WMC::MediaCapture^ capture, _In_ WMMp::VideoEncodingProperties^ props, CaptureStreamType streamType); + + void ProcessSample(_In_ MediaSample^ sample); + + Platform::Agile _capture; + ::Windows::Media::IMediaExtension^ _mediaExtension; + + MW::ComPtr _mediaSink; + + CaptureStreamType _streamType; + + enum class State + { + Created, + Started, + Closing, + Closed + } _state; + + std::queue>> _videoSampleRequestQueue; + AutoMF _mf; + MWW::SRWLock _lock; +}; + +} \ No newline at end of file diff --git a/modules/videoio/src/cap_winrt/MFIncludes.hpp b/modules/videoio/src/cap_winrt/MFIncludes.hpp new file mode 100644 index 0000000000..de831eeb16 --- /dev/null +++ b/modules/videoio/src/cap_winrt/MFIncludes.hpp @@ -0,0 +1,172 @@ +// Header for standard system include files. + +// Copyright (c) Microsoft. All rights reserved. +// +// The MIT License (MIT) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files(the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions : +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#pragma once + +#include +#include + +#include +#include +#include + +#include +#include + +#include + +#include +#include +#include + +#include +#include + +namespace AWM = ::ABI::Windows::Media; +namespace AWMMp = ::ABI::Windows::Media::MediaProperties; +namespace AWFC = ::ABI::Windows::Foundation::Collections; +namespace MW = ::Microsoft::WRL; +namespace MWD = ::Microsoft::WRL::Details; +namespace MWW = ::Microsoft::WRL::Wrappers; +namespace WMC = ::Windows::Media::Capture; +namespace WF = ::Windows::Foundation; +namespace WMMp = ::Windows::Media::MediaProperties; +namespace WSS = ::Windows::Storage::Streams; + +// Exception-based error handling +#define CHK(statement) {HRESULT _hr = (statement); if (FAILED(_hr)) { throw ref new Platform::COMException(_hr); };} +#define CHKNULL(p) {if ((p) == nullptr) { throw ref new Platform::NullReferenceException(L#p); };} + +// Exception-free error handling +#define CHK_RETURN(statement) {hr = (statement); if (FAILED(hr)) { return hr; };} + +// Cast a C++/CX msartpointer to an ABI smartpointer +template +MW::ComPtr As(U^ in) +{ + MW::ComPtr out; + CHK(reinterpret_cast(in)->QueryInterface(IID_PPV_ARGS(&out))); + return out; +} + +// Cast an ABI smartpointer +template +Microsoft::WRL::ComPtr As(const Microsoft::WRL::ComPtr& in) +{ + Microsoft::WRL::ComPtr out; + CHK(in.As(&out)); + return out; +} + +// Cast an ABI smartpointer +template +Microsoft::WRL::ComPtr As(U* in) +{ + Microsoft::WRL::ComPtr out; + CHK(in->QueryInterface(IID_PPV_ARGS(&out))); + return out; +} + +// Get access to bytes in IBuffer +inline unsigned char* GetData(_In_ WSS::IBuffer^ buffer) +{ + unsigned char* bytes = nullptr; + CHK(As(buffer)->Buffer(&bytes)); + return bytes; +} + +// Class to start and shutdown Media Foundation +class AutoMF +{ +public: + AutoMF() + : _bInitialized(false) + { + CHK(MFStartup(MF_VERSION)); + } + + ~AutoMF() + { + if (_bInitialized) + { + (void)MFShutdown(); + } + } + +private: + bool _bInitialized; +}; + +// Class to track error origin +template +HRESULT OriginateError(__in HRESULT hr, __in wchar_t const (&str)[N]) +{ + if (FAILED(hr)) + { + ::RoOriginateErrorW(hr, N - 1, str); + } + return hr; +} + +// Class to track error origin +inline HRESULT OriginateError(__in HRESULT hr) +{ + if (FAILED(hr)) + { + ::RoOriginateErrorW(hr, 0, nullptr); + } + return hr; +} + +// Converts exceptions into HRESULTs +template +HRESULT ExceptionBoundary(Lambda&& lambda) +{ + try + { + lambda(); + return S_OK; + } + catch (Platform::Exception^ e) + { + return e->HResult; + } + catch (const std::bad_alloc&) + { + return E_OUTOFMEMORY; + } + catch (const std::exception&) + { + return E_FAIL; + } +} + +// Wraps an IMFSample in a C++/CX class to be able to define a callback delegate +ref class MediaSample sealed +{ +internal: + MW::ComPtr Sample; +}; + +delegate void MediaSampleHandler(MediaSample^ sample); \ No newline at end of file diff --git a/modules/videoio/src/cap_winrt/MediaSink.hpp b/modules/videoio/src/cap_winrt/MediaSink.hpp new file mode 100644 index 0000000000..40fe0e40b3 --- /dev/null +++ b/modules/videoio/src/cap_winrt/MediaSink.hpp @@ -0,0 +1,396 @@ +// Copyright (c) Microsoft. All rights reserved. +// +// The MIT License (MIT) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files(the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions : +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#pragma once + +#include "MediaStreamSink.hpp" +#include "MFIncludes.hpp" + +namespace Media { + +const unsigned int c_audioStreamSinkId = 0; +const unsigned int c_videoStreamSinkId = 1; + +class MediaSink WrlSealed + : public MW::RuntimeClass< + MW::RuntimeClassFlags< + MW::RuntimeClassType::WinRtClassicComMix> + , AWM::IMediaExtension + , IMFMediaSink + , IMFClockStateSink + , MW::FtmBase + > +{ + InspectableClass(L"MediaSink", BaseTrust) + +public: + + MediaSink( + _In_opt_ WMMp::AudioEncodingProperties^ audioProps, + _In_opt_ WMMp::VideoEncodingProperties^ videoProps, + _In_opt_ MediaSampleHandler^ audioSampleHandler, + _In_opt_ MediaSampleHandler^ videoSampleHandler + ) + : _shutdown(false) + { + MW::ComPtr audioMT; + if (audioProps != nullptr) + { + CHK(MFCreateMediaTypeFromProperties(As(audioProps).Get(), &audioMT)); + _audioStreamSink = MW::Make( + this, + c_audioStreamSinkId, + audioMT, + audioSampleHandler + ); + } + + MW::ComPtr videoMT; + if (videoProps != nullptr) + { + CHK(MFCreateMediaTypeFromProperties(As(videoProps).Get(), &videoMT)); + _videoStreamSink = MW::Make( + this, + c_videoStreamSinkId, + videoMT, + videoSampleHandler + ); + } + } + + void RequestAudioSample() + { + auto lock = _lock.LockExclusive(); + + _VerifyNotShutdown(); + + _audioStreamSink->RequestSample(); + } + + void RequestVideoSample() + { + auto lock = _lock.LockExclusive(); + + _VerifyNotShutdown(); + + _videoStreamSink->RequestSample(); + } + + void SetCurrentAudioMediaType(_In_ IMFMediaType* mt) + { + auto lock = _lock.LockExclusive(); + + _VerifyNotShutdown(); + + _audioStreamSink->InternalSetCurrentMediaType(mt); + } + + void SetCurrentVideoMediaType(_In_ IMFMediaType* mt) + { + auto lock = _lock.LockExclusive(); + + _VerifyNotShutdown(); + + _videoStreamSink->InternalSetCurrentMediaType(mt); + } + + // + // IMediaExtension + // + + IFACEMETHODIMP SetProperties(_In_ AWFC::IPropertySet * /*configuration*/) + { + return ExceptionBoundary([this]() + { + auto lock = _lock.LockExclusive(); + + _VerifyNotShutdown(); + }); + } + + // + // IMFMediaSink + // + + IFACEMETHODIMP GetCharacteristics(_Out_ DWORD *characteristics) + { + return ExceptionBoundary([this, characteristics]() + { + _VerifyNotShutdown(); + + CHKNULL(characteristics); + *characteristics = MEDIASINK_RATELESS | MEDIASINK_FIXED_STREAMS; + }); + } + + IFACEMETHODIMP AddStreamSink( + DWORD /*streamSinkIdentifier*/, + _In_ IMFMediaType * /*mediaType*/, + _COM_Outptr_ IMFStreamSink **streamSink + ) + { + return ExceptionBoundary([this, streamSink]() + { + _VerifyNotShutdown(); + + CHKNULL(streamSink); + *streamSink = nullptr; + + CHK(MF_E_STREAMSINKS_FIXED); + }); + } + + IFACEMETHODIMP RemoveStreamSink(DWORD /*streamSinkIdentifier*/) + { + return ExceptionBoundary([this]() + { + _VerifyNotShutdown(); + + CHK(MF_E_STREAMSINKS_FIXED); + }); + } + + IFACEMETHODIMP GetStreamSinkCount(_Out_ DWORD *streamSinkCount) + { + return ExceptionBoundary([this, streamSinkCount]() + { + CHKNULL(streamSinkCount); + + _VerifyNotShutdown(); + + *streamSinkCount = (_audioStreamSink != nullptr) + (_videoStreamSink != nullptr); + }); + } + + IFACEMETHODIMP GetStreamSinkByIndex(DWORD index, _COM_Outptr_ IMFStreamSink **streamSink) + { + return ExceptionBoundary([this, index, streamSink]() + { + auto lock = _lock.LockExclusive(); + + CHKNULL(streamSink); + *streamSink = nullptr; + + _VerifyNotShutdown(); + + switch (index) + { + case 0: + if (_audioStreamSink != nullptr) + { + CHK(_audioStreamSink.CopyTo(streamSink)); + } + else + { + CHK(_videoStreamSink.CopyTo(streamSink)); + } + break; + + case 1: + if ((_audioStreamSink != nullptr) && (_videoStreamSink != nullptr)) + { + CHK(_videoStreamSink.CopyTo(streamSink)); + } + else + { + CHK(E_INVALIDARG); + } + break; + + default: + CHK(E_INVALIDARG); + } + }); + } + + IFACEMETHODIMP GetStreamSinkById(DWORD identifier, _COM_Outptr_ IMFStreamSink **streamSink) + { + return ExceptionBoundary([this, identifier, streamSink]() + { + auto lock = _lock.LockExclusive(); + + CHKNULL(streamSink); + *streamSink = nullptr; + + _VerifyNotShutdown(); + + if ((identifier == 0) && (_audioStreamSink != nullptr)) + { + CHK(_audioStreamSink.CopyTo(streamSink)); + } + else if ((identifier == 1) && (_videoStreamSink != nullptr)) + { + CHK(_videoStreamSink.CopyTo(streamSink)); + } + else + { + CHK(E_INVALIDARG); + } + }); + } + + IFACEMETHODIMP SetPresentationClock(_In_ IMFPresentationClock *clock) + { + return ExceptionBoundary([this, clock]() + { + auto lock = _lock.LockExclusive(); + + _VerifyNotShutdown(); + + if (_clock != nullptr) + { + CHK(_clock->RemoveClockStateSink(this)); + _clock = nullptr; + } + + if (clock != nullptr) + { + CHK(clock->AddClockStateSink(this)); + _clock = clock; + } + }); + } + + IFACEMETHODIMP GetPresentationClock(_COM_Outptr_ IMFPresentationClock **clock) + { + return ExceptionBoundary([this, clock]() + { + auto lock = _lock.LockExclusive(); + + CHKNULL(clock); + *clock = nullptr; + + _VerifyNotShutdown(); + + if (_clock != nullptr) + { + CHK(_clock.CopyTo(clock)) + } + }); + } + + IFACEMETHODIMP Shutdown() + { + return ExceptionBoundary([this]() + { + auto lock = _lock.LockExclusive(); + + if (_shutdown) + { + return; + } + _shutdown = true; + + if (_audioStreamSink != nullptr) + { + _audioStreamSink->Shutdown(); + _audioStreamSink = nullptr; + } + + if (_videoStreamSink != nullptr) + { + _videoStreamSink->Shutdown(); + _videoStreamSink = nullptr; + } + + if (_clock != nullptr) + { + (void)_clock->RemoveClockStateSink(this); + _clock = nullptr; + } + }); + } + + // + // IMFClockStateSink methods + // + + IFACEMETHODIMP OnClockStart(MFTIME /*hnsSystemTime*/, LONGLONG /*llClockStartOffset*/) + { + return ExceptionBoundary([this]() + { + auto lock = _lock.LockExclusive(); + + _VerifyNotShutdown(); + }); + } + + IFACEMETHODIMP OnClockStop(MFTIME /*hnsSystemTime*/) + { + return ExceptionBoundary([this]() + { + auto lock = _lock.LockExclusive(); + + _VerifyNotShutdown(); + }); + } + + IFACEMETHODIMP OnClockPause(MFTIME /*hnsSystemTime*/) + { + return ExceptionBoundary([this]() + { + auto lock = _lock.LockExclusive(); + + _VerifyNotShutdown(); + }); + } + + IFACEMETHODIMP OnClockRestart(MFTIME /*hnsSystemTime*/) + { + return ExceptionBoundary([this]() + { + auto lock = _lock.LockExclusive(); + + _VerifyNotShutdown(); + }); + } + + IFACEMETHODIMP OnClockSetRate(MFTIME /*hnsSystemTime*/, float /*flRate*/) + { + return ExceptionBoundary([this]() + { + auto lock = _lock.LockExclusive(); + + _VerifyNotShutdown(); + }); + } + +private: + + bool _shutdown; + + void _VerifyNotShutdown() + { + if (_shutdown) + { + CHK(MF_E_SHUTDOWN); + } + } + + MW::ComPtr _audioStreamSink; + MW::ComPtr _videoStreamSink; + MW::ComPtr _clock; + + MWW::SRWLock _lock; +}; + +} \ No newline at end of file diff --git a/modules/videoio/src/cap_winrt/MediaStreamSink.cpp b/modules/videoio/src/cap_winrt/MediaStreamSink.cpp new file mode 100644 index 0000000000..1df3b4cfbb --- /dev/null +++ b/modules/videoio/src/cap_winrt/MediaStreamSink.cpp @@ -0,0 +1,386 @@ +// Copyright (c) Microsoft. All rights reserved. +// +// The MIT License (MIT) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files(the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions : +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#include "MediaStreamSink.hpp" +#include "MFIncludes.hpp" + +using namespace Media; +using namespace Microsoft::WRL; +using namespace Platform; +using namespace Windows::Foundation; + +MediaStreamSink::MediaStreamSink( + __in const MW::ComPtr& sink, + __in DWORD id, + __in const MW::ComPtr& mt, + __in MediaSampleHandler^ sampleHandler + ) + : _shutdown(false) + , _id(-1) + , _width(0) + , _height(0) +{ + CHK(MFCreateEventQueue(&_eventQueue)); + CHK(MFCreateMediaType(&_curMT)); + + _UpdateMediaType(mt); + + _sink = sink; + _id = id; + _sampleHandler = sampleHandler; +} + +HRESULT MediaStreamSink::GetMediaSink(__deref_out IMFMediaSink **sink) +{ + return ExceptionBoundary([this, sink]() + { + auto lock = _lock.LockExclusive(); + + CHKNULL(sink); + *sink = nullptr; + + _VerifyNotShutdown(); + + CHK(_sink.CopyTo(sink)); + }); +} + +HRESULT MediaStreamSink::GetIdentifier(__out DWORD *identifier) +{ + return ExceptionBoundary([this, identifier]() + { + auto lock = _lock.LockExclusive(); + + CHKNULL(identifier); + + _VerifyNotShutdown(); + + *identifier = _id; + }); +} + +HRESULT MediaStreamSink::GetMediaTypeHandler(__deref_out IMFMediaTypeHandler **handler) +{ + return ExceptionBoundary([this, handler]() + { + auto lock = _lock.LockExclusive(); + + CHKNULL(handler); + *handler = nullptr; + + _VerifyNotShutdown(); + + *handler = this; + this->AddRef(); + + }); +} + +void MediaStreamSink::RequestSample() +{ + auto lock = _lock.LockExclusive(); + + _VerifyNotShutdown(); + + CHK(_eventQueue->QueueEventParamVar(MEStreamSinkRequestSample, GUID_NULL, S_OK, nullptr)); +} + +HRESULT MediaStreamSink::ProcessSample(__in_opt IMFSample *sample) +{ + return ExceptionBoundary([this, sample]() + { + MediaSampleHandler^ sampleHandler; + auto mediaSample = ref new MediaSample(); + + { + auto lock = _lock.LockExclusive(); + + _VerifyNotShutdown(); + + if (sample == nullptr) + { + return; + } + + mediaSample->Sample = sample; + sampleHandler = _sampleHandler; + } + + // Call back without the lock taken to avoid deadlocks + sampleHandler(mediaSample); + }); +} + +HRESULT MediaStreamSink::PlaceMarker(__in MFSTREAMSINK_MARKER_TYPE /*markerType*/, __in const PROPVARIANT * /*markerValue*/, __in const PROPVARIANT * contextValue) +{ + return ExceptionBoundary([this, contextValue]() + { + auto lock = _lock.LockExclusive(); + CHKNULL(contextValue); + + _VerifyNotShutdown(); + + CHK(_eventQueue->QueueEventParamVar(MEStreamSinkMarker, GUID_NULL, S_OK, contextValue)); + }); +} + +HRESULT MediaStreamSink::Flush() +{ + return ExceptionBoundary([this]() + { + auto lock = _lock.LockExclusive(); + + _VerifyNotShutdown(); + }); +} + +HRESULT MediaStreamSink::GetEvent(__in DWORD flags, __deref_out IMFMediaEvent **event) +{ + return ExceptionBoundary([this, flags, event]() + { + CHKNULL(event); + *event = nullptr; + + ComPtr eventQueue; + + { + auto lock = _lock.LockExclusive(); + + _VerifyNotShutdown(); + + eventQueue = _eventQueue; + } + + // May block for a while + CHK(eventQueue->GetEvent(flags, event)); + }); +} + +HRESULT MediaStreamSink::BeginGetEvent(__in IMFAsyncCallback *callback, __in_opt IUnknown *state) +{ + return ExceptionBoundary([this, callback, state]() + { + auto lock = _lock.LockExclusive(); + + _VerifyNotShutdown(); + + CHK(_eventQueue->BeginGetEvent(callback, state)); + }); +} + + +HRESULT MediaStreamSink::EndGetEvent(__in IMFAsyncResult *result, __deref_out IMFMediaEvent **event) +{ + return ExceptionBoundary([this, result, event]() + { + auto lock = _lock.LockExclusive(); + + CHKNULL(event); + *event = nullptr; + + _VerifyNotShutdown(); + + CHK(_eventQueue->EndGetEvent(result, event)); + }); +} + +HRESULT MediaStreamSink::QueueEvent( + __in MediaEventType met, + __in REFGUID extendedType, + __in HRESULT status, + __in_opt const PROPVARIANT *value + ) +{ + return ExceptionBoundary([this, met, extendedType, status, value]() + { + auto lock = _lock.LockExclusive(); + + _VerifyNotShutdown(); + + CHK(_eventQueue->QueueEventParamVar(met, extendedType, status, value)); + }); +} + +HRESULT MediaStreamSink::IsMediaTypeSupported(__in IMFMediaType *mediaType, __deref_out_opt IMFMediaType **closestMediaType) +{ + bool supported = false; + + HRESULT hr = ExceptionBoundary([this, mediaType, closestMediaType, &supported]() + { + auto lock = _lock.LockExclusive(); + HRESULT hr = S_OK; + + if (closestMediaType != nullptr) + { + *closestMediaType = nullptr; + } + + CHKNULL(mediaType); + + _VerifyNotShutdown(); + + supported = _IsMediaTypeSupported(mediaType); + }); + + // Avoid throwing an exception to return MF_E_INVALIDMEDIATYPE as this is not a exceptional case + return FAILED(hr) ? hr : supported ? S_OK : MF_E_INVALIDMEDIATYPE; +} + +HRESULT MediaStreamSink::GetMediaTypeCount(__out DWORD *typeCount) +{ + return ExceptionBoundary([this, typeCount]() + { + auto lock = _lock.LockExclusive(); + + CHKNULL(typeCount); + + _VerifyNotShutdown(); + + // No media type provided by default (app needs to specify it) + *typeCount = 0; + }); +} + +HRESULT MediaStreamSink::GetMediaTypeByIndex(__in DWORD /*index*/, __deref_out IMFMediaType **mediaType) +{ + HRESULT hr = ExceptionBoundary([this, mediaType]() + { + auto lock = _lock.LockExclusive(); + + CHKNULL(mediaType); + *mediaType = nullptr; + + _VerifyNotShutdown(); + }); + + // Avoid throwing an exception to return MF_E_NO_MORE_TYPES as this is not a exceptional case + return FAILED(hr) ? hr : MF_E_NO_MORE_TYPES; +} + +HRESULT MediaStreamSink::SetCurrentMediaType(__in IMFMediaType *mediaType) +{ + return ExceptionBoundary([this, mediaType]() + { + auto lock = _lock.LockExclusive(); + HRESULT hr = S_OK; + + CHKNULL(mediaType); + + _VerifyNotShutdown(); + + if (!_IsMediaTypeSupported(mediaType)) + { + CHK(MF_E_INVALIDMEDIATYPE); + } + + _UpdateMediaType(mediaType); + }); +} + +HRESULT MediaStreamSink::GetCurrentMediaType(__deref_out_opt IMFMediaType **mediaType) +{ + return ExceptionBoundary([this, mediaType]() + { + auto lock = _lock.LockExclusive(); + + CHKNULL(mediaType); + *mediaType = nullptr; + + _VerifyNotShutdown(); + + ComPtr mt; + CHK(MFCreateMediaType(&mt)); + CHK(_curMT->CopyAllItems(mt.Get())); + *mediaType = mt.Detach(); + }); +} + +HRESULT MediaStreamSink::GetMajorType(__out GUID *majorType) +{ + return ExceptionBoundary([this, majorType]() + { + auto lock = _lock.LockExclusive(); + + CHKNULL(majorType); + + _VerifyNotShutdown(); + + *majorType = _majorType; + }); +} + +void MediaStreamSink::InternalSetCurrentMediaType(__in const ComPtr& mediaType) +{ + auto lock = _lock.LockExclusive(); + + CHKNULL(mediaType); + + _VerifyNotShutdown(); + + _UpdateMediaType(mediaType); +} + +void MediaStreamSink::Shutdown() +{ + auto lock = _lock.LockExclusive(); + + if (_shutdown) + { + return; + } + _shutdown = true; + + (void)_eventQueue->Shutdown(); + _eventQueue = nullptr; + + _curMT = nullptr; + _sink = nullptr; + _sampleHandler = nullptr; +} + +bool MediaStreamSink::_IsMediaTypeSupported(__in const ComPtr& mt) const +{ + GUID majorType; + GUID subType; + if (SUCCEEDED(mt->GetGUID(MF_MT_MAJOR_TYPE, &majorType)) && + SUCCEEDED(mt->GetGUID(MF_MT_SUBTYPE, &subType)) && + (majorType == _majorType) && + (subType == _subType)) + { + return true; + } + + return false; +} + +void MediaStreamSink::_UpdateMediaType(__in const ComPtr& mt) +{ + CHK(mt->GetGUID(MF_MT_MAJOR_TYPE, &_majorType)); + CHK(mt->GetGUID(MF_MT_SUBTYPE, &_subType)); + + if (_majorType == MFMediaType_Video) + { + CHK(MFGetAttributeSize(mt.Get(), MF_MT_FRAME_SIZE, &_width, &_height)); + } + + CHK(mt->CopyAllItems(_curMT.Get())); +} \ No newline at end of file diff --git a/modules/videoio/src/cap_winrt/MediaStreamSink.hpp b/modules/videoio/src/cap_winrt/MediaStreamSink.hpp new file mode 100644 index 0000000000..3434adff02 --- /dev/null +++ b/modules/videoio/src/cap_winrt/MediaStreamSink.hpp @@ -0,0 +1,114 @@ +// Copyright (c) Microsoft. All rights reserved. +// +// The MIT License (MIT) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files(the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions : +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#pragma once + +#include "MFIncludes.hpp" + +namespace Media { + +class MediaStreamSink WrlSealed : + public Microsoft::WRL::RuntimeClass< + Microsoft::WRL::RuntimeClassFlags, + IMFStreamSink, + IMFMediaEventGenerator, + IMFMediaTypeHandler + > +{ +public: + + MediaStreamSink( + __in const MW::ComPtr& sink, + __in DWORD id, + __in const MW::ComPtr& mt, + __in MediaSampleHandler^ sampleHandler + ); + + // + // IMFStreamSink + // + + IFACEMETHODIMP GetMediaSink(__deref_out IMFMediaSink **sink); + IFACEMETHODIMP GetIdentifier(__out DWORD *identifier); + IFACEMETHODIMP GetMediaTypeHandler(__deref_out IMFMediaTypeHandler **handler); + IFACEMETHODIMP ProcessSample(__in_opt IMFSample *sample); + IFACEMETHODIMP PlaceMarker(__in MFSTREAMSINK_MARKER_TYPE markerType, __in const PROPVARIANT * markerValue, __in const PROPVARIANT * contextValue); + IFACEMETHODIMP Flush(); + + // + // IMFMediaEventGenerator + // + + IFACEMETHODIMP GetEvent(__in DWORD flags, __deref_out IMFMediaEvent **event); + IFACEMETHODIMP BeginGetEvent(__in IMFAsyncCallback *callback, __in_opt IUnknown *state); + IFACEMETHODIMP EndGetEvent(__in IMFAsyncResult *result, __deref_out IMFMediaEvent **event); + IFACEMETHODIMP QueueEvent(__in MediaEventType met, __in REFGUID extendedType, __in HRESULT status, __in_opt const PROPVARIANT *value); + + // + // IMFMediaTypeHandler + // + + IFACEMETHODIMP IsMediaTypeSupported(__in IMFMediaType *mediaType, __deref_out_opt IMFMediaType **closestMediaType); + IFACEMETHODIMP GetMediaTypeCount(__out DWORD *typeCount); + IFACEMETHODIMP GetMediaTypeByIndex(__in DWORD index, __deref_out IMFMediaType **mediaType); + IFACEMETHODIMP SetCurrentMediaType(__in IMFMediaType *mediaType); + IFACEMETHODIMP GetCurrentMediaType(__deref_out_opt IMFMediaType **mediaType); + IFACEMETHODIMP GetMajorType(__out GUID *majorType); + + // + // Misc + // + + void InternalSetCurrentMediaType(__in const MW::ComPtr& mediaType); + void RequestSample(); + void Shutdown(); + +private: + + bool _IsMediaTypeSupported(__in const MW::ComPtr& mt) const; + void _UpdateMediaType(__in const MW::ComPtr& mt); + + void _VerifyNotShutdown() + { + if (_shutdown) + { + CHK(MF_E_SHUTDOWN); + } + } + + MW::ComPtr _sink; + MW::ComPtr _eventQueue; + MW::ComPtr _curMT; + + MediaSampleHandler^ _sampleHandler; + + GUID _majorType; + GUID _subType; + unsigned int _width; + unsigned int _height; + DWORD _id; + bool _shutdown; + + MWW::SRWLock _lock; +}; + +} \ No newline at end of file diff --git a/modules/videoio/src/cap_winrt_bridge.cpp b/modules/videoio/src/cap_winrt_bridge.cpp new file mode 100644 index 0000000000..11bd0b7155 --- /dev/null +++ b/modules/videoio/src/cap_winrt_bridge.cpp @@ -0,0 +1,89 @@ +// videoio to XAML bridge for OpenCV + +// Copyright (c) Microsoft Open Technologies, Inc. +// All rights reserved. +// +// (3 - clause BSD License) +// +// Redistribution and use in source and binary forms, with or without modification, are permitted provided that +// the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the +// following disclaimer. +// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the +// following disclaimer in the documentation and/or other materials provided with the distribution. +// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or +// promote products derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED +// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +// PARTICULAR PURPOSE ARE DISCLAIMED.IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY +// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES(INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT(INCLUDING +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. + +#include "opencv2\videoio\cap_winrt.hpp" +#include "cap_winrt_capture.hpp" +#include "cap_winrt_bridge.hpp" +#include "cap_winrt_video.hpp" + +using namespace Windows::Foundation; +using namespace Windows::Media::Capture; +using namespace Windows::Media::MediaProperties; +using namespace Windows::Devices::Enumeration; + +using namespace Windows::UI::Xaml::Media::Imaging; +using namespace Microsoft::WRL; + +using namespace Platform; +using namespace ::Concurrency; + +using namespace ::std; + +/***************************** VideoioBridge class ******************************/ + +// non-blocking +void VideoioBridge::requestForUIthreadAsync(int action, int widthp, int heightp) +{ + reporter.report(action); +} + +VideoioBridge& VideoioBridge::getInstance() +{ + static VideoioBridge instance; + return instance; +} + +void VideoioBridge::swapInputBuffers() +{ + // TODO: already locked, check validity + // lock_guard lock(inputBufferMutex); + swap(backInputPtr, frontInputPtr); + //if (currentFrame != frameCounter) + //{ + // currentFrame = frameCounter; + // swap(backInputPtr, frontInputPtr); + //} +} + +void VideoioBridge::swapOutputBuffers() +{ + lock_guard lock(outputBufferMutex); + swap(frontOutputBuffer, backOutputBuffer); +} + +void VideoioBridge::allocateOutputBuffers() +{ + frontOutputBuffer = ref new WriteableBitmap(width, height); + backOutputBuffer = ref new WriteableBitmap(width, height); +} + +void VideoioBridge::imshow() +{ + VideoioBridge::getInstance().swapOutputBuffers(); + VideoioBridge::getInstance().requestForUIthreadAsync(cv::UPDATE_IMAGE_ELEMENT); +} + +// end \ No newline at end of file diff --git a/modules/videoio/src/cap_winrt_bridge.hpp b/modules/videoio/src/cap_winrt_bridge.hpp new file mode 100644 index 0000000000..02f57b034e --- /dev/null +++ b/modules/videoio/src/cap_winrt_bridge.hpp @@ -0,0 +1,96 @@ +// videoio to XAML bridge for OpenCV + +// Copyright (c) Microsoft Open Technologies, Inc. +// All rights reserved. +// +// (3 - clause BSD License) +// +// Redistribution and use in source and binary forms, with or without modification, are permitted provided that +// the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the +// following disclaimer. +// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the +// following disclaimer in the documentation and/or other materials provided with the distribution. +// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or +// promote products derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED +// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +// PARTICULAR PURPOSE ARE DISCLAIMED.IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY +// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES(INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT(INCLUDING +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. + +#pragma once + +// this header is included in the XAML App, so it cannot include any +// OpenCV headers, or a static assert will be raised + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + + +// Class VideoioBridge (singleton) is needed because the interface for +// VideoCapture_WinRT in cap_winrt_capture.hpp is fixed by OpenCV. +class VideoioBridge +{ +public: + + static VideoioBridge& getInstance(); + + // call after initialization + void setReporter(Concurrency::progress_reporter pr) { reporter = pr; } + + // to be called from cvMain via cap_winrt on bg thread - non-blocking (async) + void requestForUIthreadAsync( int action, int width=0, int height=0 ); + + // TODO: modify in window.cpp: void cv::imshow( const String& winname, InputArray _img ) + void imshow(/*cv::InputArray matToShow*/); // shows Mat in the cvImage element + void swapInputBuffers(); + void allocateOutputBuffers(); + void swapOutputBuffers(); + + + int deviceIndex, width, height; + std::atomic bIsFrameNew; + std::mutex inputBufferMutex; // input is double buffered + unsigned char * frontInputPtr; // OpenCV reads this + unsigned char * backInputPtr; // Video grabber writes this + std::atomic frameCounter; + unsigned long currentFrame; + + std::mutex outputBufferMutex; // output is double buffered + Windows::UI::Xaml::Media::Imaging::WriteableBitmap^ frontOutputBuffer; // OpenCV write this + Windows::UI::Xaml::Media::Imaging::WriteableBitmap^ backOutputBuffer; // XAML reads this + Windows::UI::Xaml::Controls::Image ^cvImage; + +private: + + VideoioBridge() { + deviceIndex = 0; + width = 640; + height = 480; + deviceReady = false; + bIsFrameNew = false; + currentFrame = 0; + frameCounter = 0; + }; + + // singleton + VideoioBridge(VideoioBridge const &); + void operator=(const VideoioBridge &); + + std::atomic deviceReady; + Concurrency::progress_reporter reporter; +}; \ No newline at end of file diff --git a/modules/videoio/src/cap_winrt_capture.cpp b/modules/videoio/src/cap_winrt_capture.cpp new file mode 100644 index 0000000000..882172279c --- /dev/null +++ b/modules/videoio/src/cap_winrt_capture.cpp @@ -0,0 +1,279 @@ +// Capture support for WinRT + +// Copyright (c) Microsoft Open Technologies, Inc. +// All rights reserved. +// +// (3 - clause BSD License) +// +// Redistribution and use in source and binary forms, with or without modification, are permitted provided that +// the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the +// following disclaimer. +// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the +// following disclaimer in the documentation and/or other materials provided with the distribution. +// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or +// promote products derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED +// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +// PARTICULAR PURPOSE ARE DISCLAIMED.IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY +// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES(INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT(INCLUDING +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. + + +#include "precomp.hpp" +#include "cap_winrt_capture.hpp" +#include "cap_winrt_bridge.hpp" +#include "cap_winrt_video.hpp" +#include + +using namespace Windows::Foundation; +using namespace Windows::Media::Capture; +using namespace Windows::Media::MediaProperties; +using namespace Windows::Devices::Enumeration; + +using namespace Platform; + +using namespace Windows::UI::Xaml::Media::Imaging; +using namespace Microsoft::WRL; + +using namespace ::std; + + +// nb. VideoCapture_WinRT is not a singleton, so the Mats are made file statics +// we do not support more than one capture device simultaneously with the +// design at this time + +// nb. inputBufferMutex was not able to guarantee that OpenCV Mats were +// ready to accept data in the UI thread (memory access exceptions were thrown +// even though buffer address was good). +// Therefore allocation of Mats is also done on the UI thread before the video +// device is initialized. + +static cv::Mat frontInputMat; +static cv::Mat backInputMat; + +namespace cv { + + /***************************** exported control functions ******************************/ + + template + void winrt_startMessageLoop(std::function&& callback, Args... args) + { + auto asyncTask = ::concurrency::create_async([=](::concurrency::progress_reporter reporter) + { + VideoioBridge::getInstance().setReporter(reporter); + + // frame reading loop + callback(args...); + }); + + asyncTask->Progress = ref new AsyncActionProgressHandler([=](IAsyncActionWithProgress^ act, int progress) + { + int action = progress; + + // these actions will be processed on the UI thread asynchronously + switch (action) + { + case OPEN_CAMERA: + winrt_openCamera(); + break; + case CLOSE_CAMERA: + winrt_closeGrabber(); + break; + case UPDATE_IMAGE_ELEMENT: + winrt_updateFrameContainer(); + break; + } + }); + } + + template + void winrt_startMessageLoop(void callback(Args...), Args... args) + { + winrt_startMessageLoop(std::function(callback), args...); + } + + void winrt_onVisibilityChanged(bool visible) { + if (visible) + { + VideoioBridge& bridge = VideoioBridge::getInstance(); + + // only start the grabber if the camera was opened in OpenCV + if (bridge.backInputPtr != nullptr) + { + if (Video::getInstance().isStarted()) return; + + int device = bridge.deviceIndex; + int width = bridge.width; + int height = bridge.height; + + winrt_initGrabber(device, width, height); + } + } else + { + //grabberStarted = false; + winrt_closeGrabber(); + } + } + + void winrt_imshow() { + VideoioBridge::getInstance().imshow(); + } + + void winrt_setFrameContainer(::Windows::UI::Xaml::Controls::Image^ image) { + VideoioBridge::getInstance().cvImage = image; + } + + + /********************************* Internal helpers ************************************/ + + void winrt_updateFrameContainer() + { + // copy output Mat to WBM + winrt_copyOutput(); + + // set XAML image element with image WBM + VideoioBridge::getInstance().cvImage->Source = VideoioBridge::getInstance().backOutputBuffer; + } + + // performed on UI thread + bool winrt_openCamera() + { + VideoioBridge& bridge = VideoioBridge::getInstance(); + + int device = bridge.deviceIndex; + int width = bridge.width; + int height = bridge.height; + + // buffers must alloc'd on UI thread + winrt_allocateBuffers(width, height); + + // nb. video capture device init must be done on UI thread; + if (!Video::getInstance().isStarted()) + { + winrt_initGrabber(device, width, height); + return true; + } + + return false; + } + + // performed on UI thread + void winrt_allocateBuffers(int width, int height) + { + VideoioBridge& bridge = VideoioBridge::getInstance(); + + // allocate input Mats (bgra8 = CV_8UC4, RGB24 = CV_8UC3) + frontInputMat.create(height, width, CV_8UC3); + backInputMat.create(height, width, CV_8UC3); + + bridge.frontInputPtr = frontInputMat.ptr(0); + bridge.backInputPtr = backInputMat.ptr(0); + + bridge.allocateOutputBuffers(); + } + + // non-blocking + bool winrt_initGrabber(int device, int w, int h) { + // nb. Video class is not exported outside of this DLL + // due to complexities in the CaptureFrameGrabber ref class + // as written in the header not mixing well with pure C++ classes + return Video::getInstance().initGrabber(device, w, h); + } + + void winrt_closeGrabber() { + Video::getInstance().closeGrabber(); + } + + // nb on UI thread + void winrt_copyOutput() { + Video::getInstance().CopyOutput(); + } + + + /********************************* VideoCapture_WinRT class ****************************/ + + VideoCapture_WinRT::VideoCapture_WinRT(int device) : started(false) + { + VideoioBridge::getInstance().deviceIndex = device; + } + + bool VideoCapture_WinRT::isOpened() const + { + return true; // started; + } + + // grab a frame: + // this will NOT block per spec + // should be called on the image processing thread, not the UI thread + bool VideoCapture_WinRT::grabFrame() + { + // if device is not started we must return true so retrieveFrame() is called to start device + // nb. we cannot start the device here because we do not know the size of the input Mat + if (!started) return true; + + if (VideoioBridge::getInstance().bIsFrameNew) + { + return true; + } + + // nb. if blocking is to be added: + // unique_lock lock(VideoioBridge::getInstance().frameReadyMutex); + // VideoioBridge::getInstance().frameReadyEvent.wait(lock); + return false; + } + + // should be called on the image processing thread after grabFrame + // see VideoCapture::read + bool VideoCapture_WinRT::retrieveFrame(int channel, cv::OutputArray outArray) + { + if (!started) { + + int width, height; + width = outArray.size().width; + height = outArray.size().height; + if (width == 0) width = 640; + if (height == 0) height = 480; + + VideoioBridge::getInstance().width = width; + VideoioBridge::getInstance().height = height; + + // nb. Mats will be alloc'd on UI thread + + // request device init on UI thread - this does not block, and is async + VideoioBridge::getInstance().requestForUIthreadAsync(OPEN_CAMERA, + outArray.size().width, outArray.size().height); + + started = true; + return false; + } + + if (!started) return false; + + return VideoioBridge::getInstance().bIsFrameNew; + } + + + bool VideoCapture_WinRT::setProperty(int property_id, double value) + { + switch (property_id) + { + case CAP_PROP_FRAME_WIDTH: + size.width = (int)value; + break; + case CAP_PROP_FRAME_HEIGHT: + size.height = (int)value; + break; + default: + return false; + } + return true; + } +} + +// end \ No newline at end of file diff --git a/modules/videoio/src/cap_winrt_capture.hpp b/modules/videoio/src/cap_winrt_capture.hpp new file mode 100644 index 0000000000..918a4d6fc6 --- /dev/null +++ b/modules/videoio/src/cap_winrt_capture.hpp @@ -0,0 +1,82 @@ +// Capture support for WinRT + +// Copyright (c) Microsoft Open Technologies, Inc. +// All rights reserved. +// +// (3 - clause BSD License) +// +// Redistribution and use in source and binary forms, with or without modification, are permitted provided that +// the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the +// following disclaimer. +// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the +// following disclaimer in the documentation and/or other materials provided with the distribution. +// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or +// promote products derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED +// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +// PARTICULAR PURPOSE ARE DISCLAIMED.IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY +// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES(INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT(INCLUDING +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. + +#pragma once + +#include "precomp.hpp" + +#include +#include +#include +#include + +#include + + +// nb. implemented the newer IVideoCapture C++ interface so that we can work +// directly with Mat, not the older C cv interface +// (which may have added overhead for IPL file conversion) + +namespace cv { + + /******************* Internal helpers **************************************/ + + void winrt_updateFrameContainer(); + bool winrt_openCamera(); + bool winrt_initGrabber(int device, int w, int h); + void winrt_closeGrabber(); + void winrt_copyOutput(); + void winrt_allocateBuffers(int width, int height); + + /******************* VideoCapture_WinRT class ******************************/ + + class VideoCapture_WinRT : public IVideoCapture + { + public: + VideoCapture_WinRT() : started(false) {} + VideoCapture_WinRT(int device); + virtual ~VideoCapture_WinRT() {} + + // from base class IVideoCapture + virtual double getProperty(int) { return 0; } + virtual bool setProperty(int, double); + virtual bool grabFrame(); + virtual bool retrieveFrame(int channel, cv::OutputArray outArray); + + // Return the type of the capture object + virtual int getCaptureDomain() { return CAP_WINRT; } + + virtual bool isOpened() const; + + protected: + + bool started; + CvSize size; + int bytesPerPixel; + unsigned long frameCurrent; + std::atomic isFrameNew; + }; +} \ No newline at end of file diff --git a/modules/videoio/src/cap_winrt_video.cpp b/modules/videoio/src/cap_winrt_video.cpp new file mode 100644 index 0000000000..a41e1f9e3a --- /dev/null +++ b/modules/videoio/src/cap_winrt_video.cpp @@ -0,0 +1,322 @@ +// Video support with XAML + +// Copyright (c) Microsoft Open Technologies, Inc. +// All rights reserved. +// +// (3 - clause BSD License) +// +// Redistribution and use in source and binary forms, with or without modification, are permitted provided that +// the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the +// following disclaimer. +// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the +// following disclaimer in the documentation and/or other materials provided with the distribution. +// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or +// promote products derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED +// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +// PARTICULAR PURPOSE ARE DISCLAIMED.IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY +// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES(INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT(INCLUDING +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. + +#include "cap_winrt_video.hpp" + +#include +#include +#include +#include + +#include +#include +#include + + +using namespace ::concurrency; +using namespace ::Windows::Foundation; +using namespace ::std; + +using namespace Microsoft::WRL; +using namespace Windows::Media::Devices; +using namespace Windows::Media::MediaProperties; +using namespace Windows::Media::Capture; +using namespace Windows::UI::Xaml::Media::Imaging; +using namespace Windows::Devices::Enumeration; + +#include "cap_winrt/CaptureFrameGrabber.hpp" + +// pull in Media Foundation libs +#pragma comment(lib, "mfplat") +#pragma comment(lib, "mf") +#pragma comment(lib, "mfuuid") + +#if (WINAPI_FAMILY!=WINAPI_FAMILY_PHONE_APP) && !defined(_M_ARM) +#pragma comment(lib, "Shlwapi") +#endif + +#include "cap_winrt_bridge.hpp" + +Video::Video() {} + +Video &Video::getInstance() { + static Video v; + return v; +} + +bool Video::isStarted() { + return bGrabberInited.load(); +} + +void Video::closeGrabber() { + // assigning nullptr causes deref of grabber and thus closes the device + m_frameGrabber = nullptr; + bGrabberInited = false; + bGrabberInitInProgress = false; +} + + +bool Video::initGrabber(int device, int w, int h) { + // already started? + if (bGrabberInited || bGrabberInitInProgress) return false; + + width = w; + height = h; + + bGrabberInited = false; + bGrabberInitInProgress = true; + + m_deviceID = device; + + create_task(DeviceInformation::FindAllAsync(DeviceClass::VideoCapture)) + .then([this](task findTask) + { + m_devices = findTask.get(); + + // got selected device? + if ((unsigned)m_deviceID >= m_devices.Get()->Size) + { + OutputDebugStringA("Video::initGrabber - no video device found\n"); + return false; + } + + auto devInfo = m_devices.Get()->GetAt(m_deviceID); + + auto settings = ref new MediaCaptureInitializationSettings(); + settings->StreamingCaptureMode = StreamingCaptureMode::Video; // Video-only capture + settings->VideoDeviceId = devInfo->Id; + + auto location = devInfo->EnclosureLocation; + bFlipImageX = true; + if (location != nullptr && location->Panel == Windows::Devices::Enumeration::Panel::Back) + { + bFlipImageX = false; + } + + m_capture = ref new MediaCapture(); + create_task(m_capture->InitializeAsync(settings)).then([this](){ + + auto props = safe_cast(m_capture->VideoDeviceController->GetMediaStreamProperties(MediaStreamType::VideoPreview)); + + // for 24 bpp + props->Subtype = MediaEncodingSubtypes::Rgb24; bytesPerPixel = 3; + + // format used by XAML & WBM (for testing) + // props->Subtype = MediaEncodingSubtypes::Bgra8; bytesPerPixel = 4; + + props->Width = width; + props->Height = height; + + return ::Media::CaptureFrameGrabber::CreateAsync(m_capture.Get(), props); + + }).then([this](::Media::CaptureFrameGrabber^ frameGrabber) + { + m_frameGrabber = frameGrabber; + bGrabberInited = true; + bGrabberInitInProgress = false; + //ready = true; + _GrabFrameAsync(frameGrabber); + }); + + return true; + }); + + // nb. cannot block here - this will lock the UI thread: + + return true; +} + + +void Video::_GrabFrameAsync(::Media::CaptureFrameGrabber^ frameGrabber) { + // use rgb24 layout + create_task(frameGrabber->GetFrameAsync()).then([this, frameGrabber](const ComPtr& buffer) + { + // do the RGB swizzle while copying the pixels from the IMF2DBuffer2 + BYTE *pbScanline; + LONG plPitch; + unsigned int colBytes = width * bytesPerPixel; + CHK(buffer->Lock2D(&pbScanline, &plPitch)); + + // flip + if (bFlipImageX) + { + std::lock_guard lock(VideoioBridge::getInstance().inputBufferMutex); + + // ptr to input Mat data array + auto buf = VideoioBridge::getInstance().backInputPtr; + + for (unsigned int row = 0; row < height; row++) + { + unsigned int i = 0; + unsigned int j = colBytes - 1; + + while (i < colBytes) + { + // reverse the scan line + // as a side effect this also swizzles R and B channels + buf[j--] = pbScanline[i++]; + buf[j--] = pbScanline[i++]; + buf[j--] = pbScanline[i++]; + } + pbScanline += plPitch; + buf += colBytes; + } + VideoioBridge::getInstance().bIsFrameNew = true; + } else + { + std::lock_guard lock(VideoioBridge::getInstance().inputBufferMutex); + + // ptr to input Mat data array + auto buf = VideoioBridge::getInstance().backInputPtr; + + for (unsigned int row = 0; row < height; row++) + { + // used for Bgr8: + //for (unsigned int i = 0; i < colBytes; i++ ) + // buf[i] = pbScanline[i]; + + // used for RGB24: + for (unsigned int i = 0; i < colBytes; i += bytesPerPixel) + { + // swizzle the R and B values (BGR to RGB) + buf[i] = pbScanline[i + 2]; + buf[i + 1] = pbScanline[i + 1]; + buf[i + 2] = pbScanline[i]; + + // no swizzle + //buf[i] = pbScanline[i]; + //buf[i + 1] = pbScanline[i + 1]; + //buf[i + 2] = pbScanline[i + 2]; + } + + pbScanline += plPitch; + buf += colBytes; + } + VideoioBridge::getInstance().bIsFrameNew = true; + } + CHK(buffer->Unlock2D()); + + VideoioBridge::getInstance().frameCounter++; + + if (bGrabberInited) + { + _GrabFrameAsync(frameGrabber); + } + }, task_continuation_context::use_current()); +} + + +// copy from input Mat to output WBM +// must be on UI thread +void Video::CopyOutput() { + { + std::lock_guard lock(VideoioBridge::getInstance().outputBufferMutex); + + auto inAr = VideoioBridge::getInstance().frontInputPtr; + auto outAr = GetData(VideoioBridge::getInstance().frontOutputBuffer->PixelBuffer); + + const unsigned int bytesPerPixel = 3; + auto pbScanline = inAr; + auto plPitch = width * bytesPerPixel; + + auto buf = outAr; + unsigned int colBytes = width * 4; + + // copy RGB24 to bgra8 + for (unsigned int row = 0; row < height; row++) + { + // used for Bgr8: + // nb. no alpha + // for (unsigned int i = 0; i < colBytes; i++ ) buf[i] = pbScanline[i]; + + // used for RGB24: + // nb. alpha is set to full opaque + for (unsigned int i = 0, j = 0; i < plPitch; i += bytesPerPixel, j += 4) + { + // swizzle the R and B values (RGB24 to Bgr8) + buf[j] = pbScanline[i + 2]; + buf[j + 1] = pbScanline[i + 1]; + buf[j + 2] = pbScanline[i]; + buf[j + 3] = 0xff; + + // if no swizzle is desired: + //buf[i] = pbScanline[i]; + //buf[i + 1] = pbScanline[i + 1]; + //buf[i + 2] = pbScanline[i + 2]; + //buf[i + 3] = 0xff; + } + + pbScanline += plPitch; + buf += colBytes; + } + VideoioBridge::getInstance().frontOutputBuffer->PixelBuffer->Length = width * height * 4; + } +} + + +bool Video::listDevicesTask() { + std::atomic ready(false); + + auto settings = ref new MediaCaptureInitializationSettings(); + + //vector devices; + + create_task(DeviceInformation::FindAllAsync(DeviceClass::VideoCapture)) + .then([this, &ready](task findTask) + { + m_devices = findTask.get(); + + for (size_t i = 0; i < m_devices->Size; i++) + { + // ofVideoDevice deviceInfo; + auto d = m_devices->GetAt(i); + //deviceInfo.bAvailable = true; + //deviceInfo.deviceName = PlatformStringToString(d->Name); + //deviceInfo.hardwareName = deviceInfo.deviceName; + // devices.push_back(deviceInfo); + } + + ready = true; + }); + + // wait for async task to complete + int count = 0; + while (!ready) + { + count++; + } + + return true; +} + + +bool Video::listDevices() { + // synchronous version of listing video devices on WinRT + std::future result = std::async(std::launch::async, &Video::listDevicesTask, this); + return result.get(); +} + +// end \ No newline at end of file diff --git a/modules/videoio/src/cap_winrt_video.hpp b/modules/videoio/src/cap_winrt_video.hpp new file mode 100644 index 0000000000..9ece69e1fe --- /dev/null +++ b/modules/videoio/src/cap_winrt_video.hpp @@ -0,0 +1,73 @@ +// Video support with XAML + +// Copyright (c) Microsoft Open Technologies, Inc. +// All rights reserved. +// +// (3 - clause BSD License) +// +// Redistribution and use in source and binary forms, with or without modification, are permitted provided that +// the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the +// following disclaimer. +// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the +// following disclaimer in the documentation and/or other materials provided with the distribution. +// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or +// promote products derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED +// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +// PARTICULAR PURPOSE ARE DISCLAIMED.IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY +// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES(INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT(INCLUDING +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. + +#pragma once + +#include "cap_winrt/CaptureFrameGrabber.hpp" + +#include +#include + +class Video { +public: + + bool initGrabber(int device, int w, int h); + void closeGrabber(); + bool isStarted(); + + // singleton + static Video &getInstance(); + + void CopyOutput(); + +private: + // singleton + Video(); + + void _GrabFrameAsync(::Media::CaptureFrameGrabber^ frameGrabber); + + bool listDevices(); + + Platform::Agile m_capture; + Platform::Agile m_devices; + + ::Media::CaptureFrameGrabber^ m_frameGrabber; + + bool listDevicesTask(); + + bool bChooseDevice; + bool bVerbose; + bool bFlipImageX; + //std::atomic bGrabberInited; + int m_deviceID; + int attemptFramerate; + std::atomic bIsFrameNew; + std::atomic bGrabberInited; + std::atomic bGrabberInitInProgress; + unsigned int width, height; + int bytesPerPixel; + +}; \ No newline at end of file From 55f78f8a83c482278c0d656920901474d24535ff Mon Sep 17 00:00:00 2001 From: Maxim Kostin Date: Fri, 15 May 2015 16:29:06 +0300 Subject: [PATCH 28/31] Added configuration changes enabling videoio WinRT support. Signed-off-by: Maxim Kostin --- CMakeLists.txt | 18 ++++++++++++++++ modules/videoio/CMakeLists.txt | 36 +++++++++++++++++++++++++++----- modules/videostab/CMakeLists.txt | 4 ++++ 3 files changed, 53 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a02b71a8bb..f9dab3b7d7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -45,6 +45,24 @@ endif(CMAKE_SYSTEM_NAME MATCHES WindowsPhone OR CMAKE_SYSTEM_NAME MATCHES Window if(WINRT) add_definitions(-DWINRT -DNO_GETENV) + + # Making definitions available to other configurations and + # to filter dependency restrictions at compile time. + if(CMAKE_SYSTEM_NAME MATCHES WindowsPhone) + set(WINRT_PHONE TRUE) + add_definitions(-DWINRT_PHONE) + elseif(CMAKE_SYSTEM_NAME MATCHES WindowsStore) + set(WINRT_STORE TRUE) + add_definitions(-DWINRT_STORE) + endif() + + if(CMAKE_SYSTEM_VERSION MATCHES 8.1) + set(WINRT_8_1 TRUE) + add_definitions(-DWINRT_8_1) + elseif(CMAKE_SYSTEM_VERSION MATCHES 8.0) + set(WINRT_8_0 TRUE) + add_definitions(-DWINRT_8_0) + endif() endif() if(POLICY CMP0022) diff --git a/modules/videoio/CMakeLists.txt b/modules/videoio/CMakeLists.txt index 9332f28606..810f31f638 100644 --- a/modules/videoio/CMakeLists.txt +++ b/modules/videoio/CMakeLists.txt @@ -1,7 +1,3 @@ -if(WINRT) - ocv_module_disable(videoio) -endif() - set(the_description "Media I/O") ocv_add_module(videoio opencv_imgproc opencv_imgcodecs OPTIONAL opencv_androidcamera WRAP java python) @@ -11,7 +7,7 @@ ocv_add_module(videoio opencv_imgproc opencv_imgcodecs OPTIONAL opencv_androidca # Jose Luis Blanco, 2008 # ---------------------------------------------------------------------------- -if(HAVE_WINRT_CX AND NOT WINRT) +if(WINRT_8_1) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /ZW") endif() @@ -36,6 +32,36 @@ file(GLOB videoio_ext_hdrs "${CMAKE_CURRENT_LIST_DIR}/include/opencv2/${name}/*.hpp" "${CMAKE_CURRENT_LIST_DIR}/include/opencv2/${name}/*.h") +# Removing WinRT API headers by default +status(" ${name}: Removing WinRT API headers by default") +list(REMOVE_ITEM videoio_ext_hdrs "${CMAKE_CURRENT_LIST_DIR}/include/opencv2/${name}/cap_winrt.hpp") + +# Dependencies used by the implementation referenced +# below are not available on WinRT 8.0. +# Enabling it for WiRT 8.1+ only. +if(DEFINED WINRT AND NOT DEFINED WINRT_8_0) + + # WinRT detected. Adding WinRT API header + status(" ${name}: WinRT detected. Adding WinRT API header") + list(APPEND videoio_ext_hdrs "${CMAKE_CURRENT_LIST_DIR}/include/opencv2/${name}/cap_winrt.hpp") + + # Adding WinRT internal sources and headers + list(APPEND videoio_srcs + ${CMAKE_CURRENT_LIST_DIR}/src/cap_winrt_capture.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/cap_winrt_bridge.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/cap_winrt_video.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/cap_winrt/CaptureFrameGrabber.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/cap_winrt/MediaStreamSink.cpp) + list(APPEND videoio_hdrs + ${CMAKE_CURRENT_LIST_DIR}/src/cap_winrt_capture.hpp + ${CMAKE_CURRENT_LIST_DIR}/src/cap_winrt_bridge.hpp + ${CMAKE_CURRENT_LIST_DIR}/src/cap_winrt_video.hpp + ${CMAKE_CURRENT_LIST_DIR}/src/cap_winrt/MFIncludes.hpp + ${CMAKE_CURRENT_LIST_DIR}/src/cap_winrt/CaptureFrameGrabber.hpp + ${CMAKE_CURRENT_LIST_DIR}/src/cap_winrt/MediaSink.hpp + ${CMAKE_CURRENT_LIST_DIR}/src/cap_winrt/MediaStreamSink.hpp) +endif() + if(WIN32 AND NOT ARM) list(APPEND videoio_srcs ${CMAKE_CURRENT_LIST_DIR}/src/cap_cmu.cpp) endif() diff --git a/modules/videostab/CMakeLists.txt b/modules/videostab/CMakeLists.txt index 8f7ae830a8..49e75f9ad1 100644 --- a/modules/videostab/CMakeLists.txt +++ b/modules/videostab/CMakeLists.txt @@ -4,5 +4,9 @@ if(HAVE_CUDA) ocv_warnings_disable(CMAKE_CXX_FLAGS -Wundef -Wmissing-declarations -Wshadow -Wunused-parameter) endif() +if(WINRT_8_1) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /ZW") +endif() + ocv_define_module(videostab opencv_imgproc opencv_features2d opencv_video opencv_photo opencv_calib3d OPTIONAL opencv_cudawarping opencv_cudaoptflow opencv_videoio WRAP python) From 3d20157d4f0a8e9ee3efe8d5ef6c7db9e16bf68e Mon Sep 17 00:00:00 2001 From: Maxim Kostin Date: Fri, 15 May 2015 16:29:35 +0300 Subject: [PATCH 29/31] Added sample Windows Universal application (UAP) using videoio logic for video preview and processing. Signed-off-by: Maxim Kostin --- .../VideoCaptureXAML/VideoCaptureXAML.sln | 84 + .../video_capture_xaml/opencv.props | 58 + .../video_capture_xaml.Shared/App.xaml | 4 + .../video_capture_xaml.Shared/App.xaml.cpp | 173 + .../video_capture_xaml.Shared/App.xaml.h | 57 + .../video_capture_xaml.Shared/main.cpp | 87 + .../video_capture_xaml.Shared/pch.cpp | 6 + .../video_capture_xaml.Shared/pch.h | 11 + .../video_capture_xaml.Shared.vcxitems | 35 + ...video_capture_xaml.Shared.vcxitems.filters | 13 + .../Assets/Logo.scale-100.png | Bin 0 -> 801 bytes .../Assets/SmallLogo.scale-100.png | Bin 0 -> 329 bytes .../Assets/SplashScreen.scale-100.png | Bin 0 -> 2146 bytes .../Assets/StoreLogo.scale-100.png | Bin 0 -> 429 bytes .../Assets/haarcascade_frontalface_alt.xml | 24350 ++++++++++++++++ .../video_capture_xaml.Windows/MainPage.xaml | 25 + .../MainPage.xaml.cpp | 61 + .../MainPage.xaml.h | 24 + .../Package.appxmanifest | 27 + .../video_capture_xaml.Windows/readme.txt | 30 + .../video_capture_xaml.Windows.vcxproj | 200 + ...video_capture_xaml.Windows.vcxproj.filters | 46 + ...ideo_capture_xaml.Windows_TemporaryKey.pfx | Bin 0 -> 2536 bytes .../Assets/Logo.scale-240.png | Bin 0 -> 2516 bytes .../Assets/SmallLogo.scale-240.png | Bin 0 -> 753 bytes .../Assets/SplashScreen.scale-240.png | Bin 0 -> 14715 bytes .../Assets/Square71x71Logo.scale-240.png | Bin 0 -> 1122 bytes .../Assets/StoreLogo.scale-240.png | Bin 0 -> 2200 bytes .../Assets/WideLogo.scale-240.png | Bin 0 -> 4530 bytes .../MainPage.xaml | 26 + .../MainPage.xaml.cpp | 79 + .../MainPage.xaml.h | 28 + .../Package.appxmanifest | 46 + .../video_capture_xaml.WindowsPhone.vcxproj | 147 + ..._capture_xaml.WindowsPhone.vcxproj.filters | 42 + ...capture_xaml.WindowsPhone_TemporaryKey.pfx | Bin 0 -> 2536 bytes 36 files changed, 25659 insertions(+) create mode 100644 samples/winrt_universal/VideoCaptureXAML/VideoCaptureXAML.sln create mode 100644 samples/winrt_universal/VideoCaptureXAML/video_capture_xaml/opencv.props create mode 100644 samples/winrt_universal/VideoCaptureXAML/video_capture_xaml/video_capture_xaml.Shared/App.xaml create mode 100644 samples/winrt_universal/VideoCaptureXAML/video_capture_xaml/video_capture_xaml.Shared/App.xaml.cpp create mode 100644 samples/winrt_universal/VideoCaptureXAML/video_capture_xaml/video_capture_xaml.Shared/App.xaml.h create mode 100644 samples/winrt_universal/VideoCaptureXAML/video_capture_xaml/video_capture_xaml.Shared/main.cpp create mode 100644 samples/winrt_universal/VideoCaptureXAML/video_capture_xaml/video_capture_xaml.Shared/pch.cpp create mode 100644 samples/winrt_universal/VideoCaptureXAML/video_capture_xaml/video_capture_xaml.Shared/pch.h create mode 100644 samples/winrt_universal/VideoCaptureXAML/video_capture_xaml/video_capture_xaml.Shared/video_capture_xaml.Shared.vcxitems create mode 100644 samples/winrt_universal/VideoCaptureXAML/video_capture_xaml/video_capture_xaml.Shared/video_capture_xaml.Shared.vcxitems.filters create mode 100644 samples/winrt_universal/VideoCaptureXAML/video_capture_xaml/video_capture_xaml.Windows/Assets/Logo.scale-100.png create mode 100644 samples/winrt_universal/VideoCaptureXAML/video_capture_xaml/video_capture_xaml.Windows/Assets/SmallLogo.scale-100.png create mode 100644 samples/winrt_universal/VideoCaptureXAML/video_capture_xaml/video_capture_xaml.Windows/Assets/SplashScreen.scale-100.png create mode 100644 samples/winrt_universal/VideoCaptureXAML/video_capture_xaml/video_capture_xaml.Windows/Assets/StoreLogo.scale-100.png create mode 100644 samples/winrt_universal/VideoCaptureXAML/video_capture_xaml/video_capture_xaml.Windows/Assets/haarcascade_frontalface_alt.xml create mode 100644 samples/winrt_universal/VideoCaptureXAML/video_capture_xaml/video_capture_xaml.Windows/MainPage.xaml create mode 100644 samples/winrt_universal/VideoCaptureXAML/video_capture_xaml/video_capture_xaml.Windows/MainPage.xaml.cpp create mode 100644 samples/winrt_universal/VideoCaptureXAML/video_capture_xaml/video_capture_xaml.Windows/MainPage.xaml.h create mode 100644 samples/winrt_universal/VideoCaptureXAML/video_capture_xaml/video_capture_xaml.Windows/Package.appxmanifest create mode 100644 samples/winrt_universal/VideoCaptureXAML/video_capture_xaml/video_capture_xaml.Windows/readme.txt create mode 100644 samples/winrt_universal/VideoCaptureXAML/video_capture_xaml/video_capture_xaml.Windows/video_capture_xaml.Windows.vcxproj create mode 100644 samples/winrt_universal/VideoCaptureXAML/video_capture_xaml/video_capture_xaml.Windows/video_capture_xaml.Windows.vcxproj.filters create mode 100644 samples/winrt_universal/VideoCaptureXAML/video_capture_xaml/video_capture_xaml.Windows/video_capture_xaml.Windows_TemporaryKey.pfx create mode 100644 samples/winrt_universal/VideoCaptureXAML/video_capture_xaml/video_capture_xaml.WindowsPhone/Assets/Logo.scale-240.png create mode 100644 samples/winrt_universal/VideoCaptureXAML/video_capture_xaml/video_capture_xaml.WindowsPhone/Assets/SmallLogo.scale-240.png create mode 100644 samples/winrt_universal/VideoCaptureXAML/video_capture_xaml/video_capture_xaml.WindowsPhone/Assets/SplashScreen.scale-240.png create mode 100644 samples/winrt_universal/VideoCaptureXAML/video_capture_xaml/video_capture_xaml.WindowsPhone/Assets/Square71x71Logo.scale-240.png create mode 100644 samples/winrt_universal/VideoCaptureXAML/video_capture_xaml/video_capture_xaml.WindowsPhone/Assets/StoreLogo.scale-240.png create mode 100644 samples/winrt_universal/VideoCaptureXAML/video_capture_xaml/video_capture_xaml.WindowsPhone/Assets/WideLogo.scale-240.png create mode 100644 samples/winrt_universal/VideoCaptureXAML/video_capture_xaml/video_capture_xaml.WindowsPhone/MainPage.xaml create mode 100644 samples/winrt_universal/VideoCaptureXAML/video_capture_xaml/video_capture_xaml.WindowsPhone/MainPage.xaml.cpp create mode 100644 samples/winrt_universal/VideoCaptureXAML/video_capture_xaml/video_capture_xaml.WindowsPhone/MainPage.xaml.h create mode 100644 samples/winrt_universal/VideoCaptureXAML/video_capture_xaml/video_capture_xaml.WindowsPhone/Package.appxmanifest create mode 100644 samples/winrt_universal/VideoCaptureXAML/video_capture_xaml/video_capture_xaml.WindowsPhone/video_capture_xaml.WindowsPhone.vcxproj create mode 100644 samples/winrt_universal/VideoCaptureXAML/video_capture_xaml/video_capture_xaml.WindowsPhone/video_capture_xaml.WindowsPhone.vcxproj.filters create mode 100644 samples/winrt_universal/VideoCaptureXAML/video_capture_xaml/video_capture_xaml.WindowsPhone/video_capture_xaml.WindowsPhone_TemporaryKey.pfx diff --git a/samples/winrt_universal/VideoCaptureXAML/VideoCaptureXAML.sln b/samples/winrt_universal/VideoCaptureXAML/VideoCaptureXAML.sln new file mode 100644 index 0000000000..a489e3b5c3 --- /dev/null +++ b/samples/winrt_universal/VideoCaptureXAML/VideoCaptureXAML.sln @@ -0,0 +1,84 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2013 +VisualStudioVersion = 12.0.31101.0 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "video_capture_xaml", "video_capture_xaml", "{D7F9BEB3-65C8-443A-82C6-9D6A5B2B00FC}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "video_capture_xaml.Shared", "video_capture_xaml\video_capture_xaml.Shared\video_capture_xaml.Shared.vcxitems", "{6A274B7F-3982-499E-B55A-1F12EF2E3EC0}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "video_capture_xaml.Windows", "video_capture_xaml\video_capture_xaml.Windows\video_capture_xaml.Windows.vcxproj", "{32FDAB94-F87E-4F0A-89A4-9EC10A3B1D3D}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "video_capture_xaml.WindowsPhone", "video_capture_xaml\video_capture_xaml.WindowsPhone\video_capture_xaml.WindowsPhone.vcxproj", "{D7A82E7F-1535-4EEC-ABA9-2C8447669D33}" +EndProject +Global + GlobalSection(SharedMSBuildProjectFiles) = preSolution + video_capture_xaml\video_capture_xaml.Shared\video_capture_xaml.Shared.vcxitems*{d7a82e7f-1535-4eec-aba9-2c8447669d33}*SharedItemsImports = 4 + video_capture_xaml\video_capture_xaml.Shared\video_capture_xaml.Shared.vcxitems*{6a274b7f-3982-499e-b55a-1f12ef2e3ec0}*SharedItemsImports = 9 + video_capture_xaml\video_capture_xaml.Shared\video_capture_xaml.Shared.vcxitems*{32fdab94-f87e-4f0a-89a4-9ec10a3b1d3d}*SharedItemsImports = 4 + EndGlobalSection + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|ARM = Debug|ARM + Debug|Mixed Platforms = Debug|Mixed Platforms + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 + Release|ARM = Release|ARM + Release|Mixed Platforms = Release|Mixed Platforms + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {32FDAB94-F87E-4F0A-89A4-9EC10A3B1D3D}.Debug|ARM.ActiveCfg = Debug|ARM + {32FDAB94-F87E-4F0A-89A4-9EC10A3B1D3D}.Debug|ARM.Build.0 = Debug|ARM + {32FDAB94-F87E-4F0A-89A4-9EC10A3B1D3D}.Debug|ARM.Deploy.0 = Debug|ARM + {32FDAB94-F87E-4F0A-89A4-9EC10A3B1D3D}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 + {32FDAB94-F87E-4F0A-89A4-9EC10A3B1D3D}.Debug|Mixed Platforms.Build.0 = Debug|Win32 + {32FDAB94-F87E-4F0A-89A4-9EC10A3B1D3D}.Debug|Mixed Platforms.Deploy.0 = Debug|Win32 + {32FDAB94-F87E-4F0A-89A4-9EC10A3B1D3D}.Debug|Win32.ActiveCfg = Debug|Win32 + {32FDAB94-F87E-4F0A-89A4-9EC10A3B1D3D}.Debug|Win32.Build.0 = Debug|Win32 + {32FDAB94-F87E-4F0A-89A4-9EC10A3B1D3D}.Debug|Win32.Deploy.0 = Debug|Win32 + {32FDAB94-F87E-4F0A-89A4-9EC10A3B1D3D}.Debug|x64.ActiveCfg = Debug|x64 + {32FDAB94-F87E-4F0A-89A4-9EC10A3B1D3D}.Debug|x64.Build.0 = Debug|x64 + {32FDAB94-F87E-4F0A-89A4-9EC10A3B1D3D}.Debug|x64.Deploy.0 = Debug|x64 + {32FDAB94-F87E-4F0A-89A4-9EC10A3B1D3D}.Release|ARM.ActiveCfg = Release|ARM + {32FDAB94-F87E-4F0A-89A4-9EC10A3B1D3D}.Release|ARM.Build.0 = Release|ARM + {32FDAB94-F87E-4F0A-89A4-9EC10A3B1D3D}.Release|ARM.Deploy.0 = Release|ARM + {32FDAB94-F87E-4F0A-89A4-9EC10A3B1D3D}.Release|Mixed Platforms.ActiveCfg = Release|Win32 + {32FDAB94-F87E-4F0A-89A4-9EC10A3B1D3D}.Release|Mixed Platforms.Build.0 = Release|Win32 + {32FDAB94-F87E-4F0A-89A4-9EC10A3B1D3D}.Release|Mixed Platforms.Deploy.0 = Release|Win32 + {32FDAB94-F87E-4F0A-89A4-9EC10A3B1D3D}.Release|Win32.ActiveCfg = Release|Win32 + {32FDAB94-F87E-4F0A-89A4-9EC10A3B1D3D}.Release|Win32.Build.0 = Release|Win32 + {32FDAB94-F87E-4F0A-89A4-9EC10A3B1D3D}.Release|Win32.Deploy.0 = Release|Win32 + {32FDAB94-F87E-4F0A-89A4-9EC10A3B1D3D}.Release|x64.ActiveCfg = Release|x64 + {32FDAB94-F87E-4F0A-89A4-9EC10A3B1D3D}.Release|x64.Build.0 = Release|x64 + {32FDAB94-F87E-4F0A-89A4-9EC10A3B1D3D}.Release|x64.Deploy.0 = Release|x64 + {D7A82E7F-1535-4EEC-ABA9-2C8447669D33}.Debug|ARM.ActiveCfg = Debug|ARM + {D7A82E7F-1535-4EEC-ABA9-2C8447669D33}.Debug|ARM.Build.0 = Debug|ARM + {D7A82E7F-1535-4EEC-ABA9-2C8447669D33}.Debug|ARM.Deploy.0 = Debug|ARM + {D7A82E7F-1535-4EEC-ABA9-2C8447669D33}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 + {D7A82E7F-1535-4EEC-ABA9-2C8447669D33}.Debug|Mixed Platforms.Build.0 = Debug|Win32 + {D7A82E7F-1535-4EEC-ABA9-2C8447669D33}.Debug|Mixed Platforms.Deploy.0 = Debug|Win32 + {D7A82E7F-1535-4EEC-ABA9-2C8447669D33}.Debug|Win32.ActiveCfg = Debug|Win32 + {D7A82E7F-1535-4EEC-ABA9-2C8447669D33}.Debug|Win32.Build.0 = Debug|Win32 + {D7A82E7F-1535-4EEC-ABA9-2C8447669D33}.Debug|Win32.Deploy.0 = Debug|Win32 + {D7A82E7F-1535-4EEC-ABA9-2C8447669D33}.Debug|x64.ActiveCfg = Debug|Win32 + {D7A82E7F-1535-4EEC-ABA9-2C8447669D33}.Release|ARM.ActiveCfg = Release|ARM + {D7A82E7F-1535-4EEC-ABA9-2C8447669D33}.Release|ARM.Build.0 = Release|ARM + {D7A82E7F-1535-4EEC-ABA9-2C8447669D33}.Release|ARM.Deploy.0 = Release|ARM + {D7A82E7F-1535-4EEC-ABA9-2C8447669D33}.Release|Mixed Platforms.ActiveCfg = Release|Win32 + {D7A82E7F-1535-4EEC-ABA9-2C8447669D33}.Release|Mixed Platforms.Build.0 = Release|Win32 + {D7A82E7F-1535-4EEC-ABA9-2C8447669D33}.Release|Mixed Platforms.Deploy.0 = Release|Win32 + {D7A82E7F-1535-4EEC-ABA9-2C8447669D33}.Release|Win32.ActiveCfg = Release|Win32 + {D7A82E7F-1535-4EEC-ABA9-2C8447669D33}.Release|Win32.Build.0 = Release|Win32 + {D7A82E7F-1535-4EEC-ABA9-2C8447669D33}.Release|Win32.Deploy.0 = Release|Win32 + {D7A82E7F-1535-4EEC-ABA9-2C8447669D33}.Release|x64.ActiveCfg = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {6A274B7F-3982-499E-B55A-1F12EF2E3EC0} = {D7F9BEB3-65C8-443A-82C6-9D6A5B2B00FC} + {32FDAB94-F87E-4F0A-89A4-9EC10A3B1D3D} = {D7F9BEB3-65C8-443A-82C6-9D6A5B2B00FC} + {D7A82E7F-1535-4EEC-ABA9-2C8447669D33} = {D7F9BEB3-65C8-443A-82C6-9D6A5B2B00FC} + EndGlobalSection +EndGlobal diff --git a/samples/winrt_universal/VideoCaptureXAML/video_capture_xaml/opencv.props b/samples/winrt_universal/VideoCaptureXAML/video_capture_xaml/opencv.props new file mode 100644 index 0000000000..cd56dfe539 --- /dev/null +++ b/samples/winrt_universal/VideoCaptureXAML/video_capture_xaml/opencv.props @@ -0,0 +1,58 @@ + + + + + WP + WS + $(OPENCV_WINRT_INSTALL_DIR)$(Runtime)\8.1\$(PlatformTarget)\$(PlatformTarget)\vc12\bin\ + $(OPENCV_WINRT_INSTALL_DIR)$(Runtime)\8.1\$(PlatformTarget)\$(PlatformTarget)\vc12\lib\ + $(OPENCV_WINRT_INSTALL_DIR)$(Runtime)\8.1\$(PlatformTarget)\include\ + + d + + + + + + + + + true + + + true + + + true + + + true + + + true + + + + + true + + + + + true + + + true + + + + + $(OpenCV_Include);%(AdditionalIncludeDirectories); + + + + opencv_core300$(DebugSuffix).lib;opencv_imgproc300$(DebugSuffix).lib;opencv_flann300$(DebugSuffix).lib;opencv_videoio300$(DebugSuffix).lib;opencv_features2d300$(DebugSuffix).lib;opencv_objdetect300$(DebugSuffix).lib;opencv_ml300$(DebugSuffix).lib;%(AdditionalDependencies) + $(OpenCV_Lib);%(AdditionalLibraryDirectories); + + + \ No newline at end of file diff --git a/samples/winrt_universal/VideoCaptureXAML/video_capture_xaml/video_capture_xaml.Shared/App.xaml b/samples/winrt_universal/VideoCaptureXAML/video_capture_xaml/video_capture_xaml.Shared/App.xaml new file mode 100644 index 0000000000..ab25d184ec --- /dev/null +++ b/samples/winrt_universal/VideoCaptureXAML/video_capture_xaml/video_capture_xaml.Shared/App.xaml @@ -0,0 +1,4 @@ + \ No newline at end of file diff --git a/samples/winrt_universal/VideoCaptureXAML/video_capture_xaml/video_capture_xaml.Shared/App.xaml.cpp b/samples/winrt_universal/VideoCaptureXAML/video_capture_xaml/video_capture_xaml.Shared/App.xaml.cpp new file mode 100644 index 0000000000..1e08d09d0a --- /dev/null +++ b/samples/winrt_universal/VideoCaptureXAML/video_capture_xaml/video_capture_xaml.Shared/App.xaml.cpp @@ -0,0 +1,173 @@ +// +// App.xaml.cpp +// Implementation of the App class. +// + +// Copyright (c) Microsoft Open Technologies, Inc. +// All rights reserved. +// +// (3 - clause BSD License) +// +// Redistribution and use in source and binary forms, with or without modification, are permitted provided that +// the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the +// following disclaimer. +// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the +// following disclaimer in the documentation and/or other materials provided with the distribution. +// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or +// promote products derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED +// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +// PARTICULAR PURPOSE ARE DISCLAIMED.IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY +// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES(INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT(INCLUDING +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. + +#include "pch.h" +#include "MainPage.xaml.h" +#include "App.xaml.h" + +using namespace video_capture_xaml; + +using namespace Platform; +using namespace Windows::ApplicationModel; +using namespace Windows::ApplicationModel::Activation; +using namespace Windows::Foundation; +using namespace Windows::Foundation::Collections; +using namespace Windows::UI::Xaml::Media::Animation; +using namespace Windows::UI::Xaml; +using namespace Windows::UI::Xaml::Controls; +using namespace Windows::UI::Xaml::Controls::Primitives; +using namespace Windows::UI::Xaml::Data; +using namespace Windows::UI::Xaml::Input; +using namespace Windows::UI::Xaml::Interop; +using namespace Windows::UI::Xaml::Media; +using namespace Windows::UI::Xaml::Navigation; + +// The Blank Application template is documented at http://go.microsoft.com/fwlink/?LinkId=234227 + +/// +/// Initializes the singleton application object. This is the first line of authored code +/// executed, and as such is the logical equivalent of main() or WinMain(). +/// +App::App() +{ + InitializeComponent(); + Suspending += ref new SuspendingEventHandler(this, &App::OnSuspending); + Resuming += ref new Windows::Foundation::EventHandler(this, &video_capture_xaml::App::OnResuming); +} + +/// +/// Invoked when the application is launched normally by the end user. Other entry points +/// will be used when the application is launched to open a specific file, to display +/// search results, and so forth. +/// +/// Details about the launch request and process. +void App::OnLaunched(LaunchActivatedEventArgs^ e) +{ +#if _DEBUG + if (IsDebuggerPresent()) + { + DebugSettings->EnableFrameRateCounter = true; + } +#endif + + auto rootFrame = dynamic_cast(Window::Current->Content); + + // Do not repeat app initialization when the Window already has content, + // just ensure that the window is active. + if (rootFrame == nullptr) + { + // Create a Frame to act as the navigation context and associate it with + // a SuspensionManager key + rootFrame = ref new Frame(); + + // TODO: Change this value to a cache size that is appropriate for your application. + rootFrame->CacheSize = 1; + + if (e->PreviousExecutionState == ApplicationExecutionState::Terminated) + { + // TODO: Restore the saved session state only when appropriate, scheduling the + // final launch steps after the restore is complete. + } + + // Place the frame in the current Window + Window::Current->Content = rootFrame; + } + + if (rootFrame->Content == nullptr) + { +#if WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP + // Removes the turnstile navigation for startup. + if (rootFrame->ContentTransitions != nullptr) + { + _transitions = ref new TransitionCollection(); + for (auto transition : rootFrame->ContentTransitions) + { + _transitions->Append(transition); + } + } + + rootFrame->ContentTransitions = nullptr; + _firstNavigatedToken = rootFrame->Navigated += ref new NavigatedEventHandler(this, &App::RootFrame_FirstNavigated); +#endif + + // When the navigation stack isn't restored navigate to the first page, + // configuring the new page by passing required information as a navigation + // parameter. + if (!rootFrame->Navigate(MainPage::typeid, e->Arguments)) + { + throw ref new FailureException("Failed to create initial page"); + } + } + + // Ensure the current window is active + Window::Current->Activate(); +} + +#if WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP +/// +/// Restores the content transitions after the app has launched. +/// +void App::RootFrame_FirstNavigated(Object^ sender, NavigationEventArgs^ e) +{ + auto rootFrame = safe_cast(sender); + + TransitionCollection^ newTransitions; + if (_transitions == nullptr) + { + newTransitions = ref new TransitionCollection(); + newTransitions->Append(ref new NavigationThemeTransition()); + } + else + { + newTransitions = _transitions; + } + + rootFrame->ContentTransitions = newTransitions; + + rootFrame->Navigated -= _firstNavigatedToken; +} +#endif + +/// +/// Invoked when application execution is being suspended. Application state is saved +/// without knowing whether the application will be terminated or resumed with the contents +/// of memory still intact. +/// +void App::OnSuspending(Object^ sender, SuspendingEventArgs^ e) +{ + (void) sender; // Unused parameter + (void) e; // Unused parameter + + // TODO: Save application state and stop any background activity +} + +void video_capture_xaml::App::OnResuming(Platform::Object ^sender, Platform::Object ^args) +{ + // throw ref new Platform::NotImplementedException(); +} \ No newline at end of file diff --git a/samples/winrt_universal/VideoCaptureXAML/video_capture_xaml/video_capture_xaml.Shared/App.xaml.h b/samples/winrt_universal/VideoCaptureXAML/video_capture_xaml/video_capture_xaml.Shared/App.xaml.h new file mode 100644 index 0000000000..c68e7fab2a --- /dev/null +++ b/samples/winrt_universal/VideoCaptureXAML/video_capture_xaml/video_capture_xaml.Shared/App.xaml.h @@ -0,0 +1,57 @@ +// +// App.xaml.h +// Declaration of the App class. +// + +// Copyright (c) Microsoft Open Technologies, Inc. +// All rights reserved. +// +// (3 - clause BSD License) +// +// Redistribution and use in source and binary forms, with or without modification, are permitted provided that +// the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the +// following disclaimer. +// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the +// following disclaimer in the documentation and/or other materials provided with the distribution. +// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or +// promote products derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED +// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +// PARTICULAR PURPOSE ARE DISCLAIMED.IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY +// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES(INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT(INCLUDING +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. + +#pragma once + +#include "App.g.h" + +namespace video_capture_xaml +{ + /// + /// Provides application-specific behavior to supplement the default Application class. + /// + ref class App sealed + { + public: + App(); + + virtual void OnLaunched(Windows::ApplicationModel::Activation::LaunchActivatedEventArgs^ e) override; + + private: +#if WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP + Windows::UI::Xaml::Media::Animation::TransitionCollection^ _transitions; + Windows::Foundation::EventRegistrationToken _firstNavigatedToken; + + void RootFrame_FirstNavigated(Platform::Object^ sender, Windows::UI::Xaml::Navigation::NavigationEventArgs^ e); +#endif + + void OnSuspending(Platform::Object^ sender, Windows::ApplicationModel::SuspendingEventArgs^ e); + void OnResuming(Platform::Object ^sender, Platform::Object ^args); + }; +} diff --git a/samples/winrt_universal/VideoCaptureXAML/video_capture_xaml/video_capture_xaml.Shared/main.cpp b/samples/winrt_universal/VideoCaptureXAML/video_capture_xaml/video_capture_xaml.Shared/main.cpp new file mode 100644 index 0000000000..625542d326 --- /dev/null +++ b/samples/winrt_universal/VideoCaptureXAML/video_capture_xaml/video_capture_xaml.Shared/main.cpp @@ -0,0 +1,87 @@ +// main.cpp + +// Copyright (c) Microsoft Open Technologies, Inc. +// All rights reserved. +// +// (3 - clause BSD License) +// +// Redistribution and use in source and binary forms, with or without modification, are permitted provided that +// the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the +// following disclaimer. +// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the +// following disclaimer in the documentation and/or other materials provided with the distribution. +// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or +// promote products derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED +// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +// PARTICULAR PURPOSE ARE DISCLAIMED.IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY +// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES(INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT(INCLUDING +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. + +#include "pch.h" + +#include +#include +#include +#include +#include + +using namespace cv; + +namespace video_capture_xaml { + + void cvMain() + { + VideoCapture cam; + + // open the default camera + cam.open(0); + + Mat edges; + Mat frame; + + // process frames + while (1) + { + // get a new frame from camera - this is non-blocking per spec + cam >> frame; + + // don't reprocess the same frame again + // nb if commented then flashing may occur + if (!cam.grab()) continue; + + // image processing calculations here + // nb Mat frame is in RGB24 format (8UC3) + + // select processing type 1 or 2 + #if 0 + // image manipulation example #1 + // write color bar at row 100 for 200 rows + auto ar = frame.ptr(100); + int bytesPerPixel = 3; + int adjust = (int)(((float)30 / 100.0f) * 255.0); + for (int i = 0; i < 640 * 100 * bytesPerPixel;) + { + ar[i++] = adjust; // R + i++; // G + ar[i++] = 255 - adjust; // B + } + #else + // image processing example #2 + // apply 'canny' filter + cvtColor(frame, edges, COLOR_RGB2GRAY); + GaussianBlur(edges, edges, Size(7, 7), 1.5, 1.5); + Canny(edges, edges, 0, 30, 3); + cvtColor(edges, frame, COLOR_GRAY2RGB); + #endif + // important step to get XAML image component updated + winrt_imshow(); + } + } +} \ No newline at end of file diff --git a/samples/winrt_universal/VideoCaptureXAML/video_capture_xaml/video_capture_xaml.Shared/pch.cpp b/samples/winrt_universal/VideoCaptureXAML/video_capture_xaml/video_capture_xaml.Shared/pch.cpp new file mode 100644 index 0000000000..01484ff5aa --- /dev/null +++ b/samples/winrt_universal/VideoCaptureXAML/video_capture_xaml/video_capture_xaml.Shared/pch.cpp @@ -0,0 +1,6 @@ +// +// pch.cpp +// Include the standard header and generate the precompiled header. +// + +#include "pch.h" diff --git a/samples/winrt_universal/VideoCaptureXAML/video_capture_xaml/video_capture_xaml.Shared/pch.h b/samples/winrt_universal/VideoCaptureXAML/video_capture_xaml/video_capture_xaml.Shared/pch.h new file mode 100644 index 0000000000..2c4354dd11 --- /dev/null +++ b/samples/winrt_universal/VideoCaptureXAML/video_capture_xaml/video_capture_xaml.Shared/pch.h @@ -0,0 +1,11 @@ +// +// pch.h +// Header for standard system include files. +// + +#pragma once + +#include +#include + +#include "App.xaml.h" diff --git a/samples/winrt_universal/VideoCaptureXAML/video_capture_xaml/video_capture_xaml.Shared/video_capture_xaml.Shared.vcxitems b/samples/winrt_universal/VideoCaptureXAML/video_capture_xaml/video_capture_xaml.Shared/video_capture_xaml.Shared.vcxitems new file mode 100644 index 0000000000..ab88eced12 --- /dev/null +++ b/samples/winrt_universal/VideoCaptureXAML/video_capture_xaml/video_capture_xaml.Shared/video_capture_xaml.Shared.vcxitems @@ -0,0 +1,35 @@ + + + + $(MSBuildAllProjects);$(MSBuildThisFileFullPath) + true + 98633655-f156-43bb-b452-37cd6a71e3f0 + {6a274b7f-3982-499e-b55a-1f12ef2e3ec0} + highgui_xaml + video_capture_xaml.Shared + + + + %(AdditionalIncludeDirectories);$(MSBuildThisFileDirectory) + + + + + Designer + + + $(MSBuildThisFileDirectory)App.xaml + + + + $(MSBuildThisFileDirectory)App.xaml + + + Create + + + + + + + \ No newline at end of file diff --git a/samples/winrt_universal/VideoCaptureXAML/video_capture_xaml/video_capture_xaml.Shared/video_capture_xaml.Shared.vcxitems.filters b/samples/winrt_universal/VideoCaptureXAML/video_capture_xaml/video_capture_xaml.Shared/video_capture_xaml.Shared.vcxitems.filters new file mode 100644 index 0000000000..2201d842e8 --- /dev/null +++ b/samples/winrt_universal/VideoCaptureXAML/video_capture_xaml/video_capture_xaml.Shared/video_capture_xaml.Shared.vcxitems.filters @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/samples/winrt_universal/VideoCaptureXAML/video_capture_xaml/video_capture_xaml.Windows/Assets/Logo.scale-100.png b/samples/winrt_universal/VideoCaptureXAML/video_capture_xaml/video_capture_xaml.Windows/Assets/Logo.scale-100.png new file mode 100644 index 0000000000000000000000000000000000000000..e26771cb33a49bbef824aa333737181b0a5b09a3 GIT binary patch literal 801 zcmeAS@N?(olHy`uVBq!ia0vp^(?FPm4M^HB7Cr(}k|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*9U+m=1foIEGZ*dUJQLud<^=L*gE#63Ho!PGzwUb%GPK6&5iF zt!p@aGNX}6(PVh|N)M-?0RNcTbjaWgEU8noxUax-n>&3Ay)#!y&O11y2sKEF zt72@XC1)RvT6Xw=y_`Ce)`nGULLL^lI$kwi^E+dQT7YeXY4GvlRR%kj1x$VZi%Bdd zz}2Giy=-_$h+v#(S+};)DuE4EM?_^qB_eDeo@&q%StD1F>L|*0ZC2sb-}llSMTM?O z6{b3iid~yk@VE7q7Wb+P8?H5IYp?pSVcLE~18m#ygK20HL@6W5woI~Fjlw$fX1U{xQA5a+t0 zH$WNIb=fNpWHo}M9#;K6eszDZKty_|-?j4iocj5#zotrWc;@;w`H@=mjsvS2wXX0_ zY}l$4@^sE?UcC)ji*L=Z&}P!xaL&2((OQlj2dv~pV-ifAS;ZsH1{`D!GY%yys5WH)f>ZLo5m%6XjuXdbKMR7MEHSyb{m!_{Afji&MT$_sz7 z>1{~MlIFe28FRN(GC_~;#Jp4ADipP+9hh|P#-&`vO-Upt3jE0@YLh(^55uYWl9g)Z RA3>Rb!PC{xWt~$(69A&hN*MqE literal 0 HcmV?d00001 diff --git a/samples/winrt_universal/VideoCaptureXAML/video_capture_xaml/video_capture_xaml.Windows/Assets/SmallLogo.scale-100.png b/samples/winrt_universal/VideoCaptureXAML/video_capture_xaml/video_capture_xaml.Windows/Assets/SmallLogo.scale-100.png new file mode 100644 index 0000000000000000000000000000000000000000..1eb0d9d528c42f132872e8af4dc563081b0b9aff GIT binary patch literal 329 zcmV-P0k-~$P)q$gGRCwC#*X;?zAP@%N+|i#I!$mrh zlQ>KU$Rdu>|JH&931_?y6Djl{gb>4nCV5pzDJ?S!mq|4ZejKj%i@j$H{#ML~2Y{DF z$=}bKPaz+UGt{v(4CTQQXym}&iW8{s!ew~XIE7NLjQpy#I2S$rous$~?f%DHT#B*+ zq=#!zc5=0FEqWFpB%UE(L807on!pidHPLgYO}XEgorrg;PB=8ipgQ5u5`&g_MQaRd zaU7Ao8XQMuuN21-s0PPTs1%38x_Yl3Fs-|Y4!C-;M-8g@n*v@1|s#GQ665=9@Rxy?u0YW0&WN+~=RXpPbVXXL4m7Aq=E6I0%{06TwRn=U9d8>exk> zD-Z%M3DNQ`bTLSEF=%NFyoHcAkD*CiXqljo*0E?o$GiDC4q}}|%*0WghLlK#npw?hecrM}Mw?`E(z5C8< z8&*b^!{>5?4aT89vdrgBgSc-x6JZD3F^l#*G(@OO*^1D%Eu7?HAy<3kTLqW9N{^#6vso zVQwY48q7)m{~xQ64RV7{E7Y=&T~?^05Ky`5oNQ8bLgFCPq9co^R09BVRS1OAmH;hU zC#q(N!gNqm!zU#%sv{r5mm-Uv8b-~a1F-;p^>)pnXfKge4s9?;;MFIr*fixPG}NBA z6_G5BEmeO6XXh(emkciB{7tA;iwC2^s^VzyU_h0@ae84ACMY`cIDEju=<`q|2QAEv zW_)W|i|9aknqdmS=#w73eW_csQ$8IhT^vY1^1;X3&J0{%*tcQq!gJpr3w?TJc~@5= zKV5sM{$3k>b#S$@CTkhIF*{v*u(F&$&Yq1naHxt8Mz2N%7aQ3(^VNRZahk1||7?Bl z*idzO_u)FhRj4cPzDO>YA>>lxAGaciEiX8Xzp1SVPv91};$OG3cC&8!v3{Jq^kH@8 UTIccK;hzT5*3#}uZuEx!0OwrBv;Y7A literal 0 HcmV?d00001 diff --git a/samples/winrt_universal/VideoCaptureXAML/video_capture_xaml/video_capture_xaml.Windows/Assets/StoreLogo.scale-100.png b/samples/winrt_universal/VideoCaptureXAML/video_capture_xaml/video_capture_xaml.Windows/Assets/StoreLogo.scale-100.png new file mode 100644 index 0000000000000000000000000000000000000000..dcb672712c6823a0c91548ded70a8acb85536b4d GIT binary patch literal 429 zcmV;e0aE^nP)NtYJa1l)bQ5qwGXpZbs7%2oRMd4y35$s&66(fxhNg8W02!vSn zdlrL2h^Fx+3=$z;kK{0D#MyeJ8WRWZcLSf(PcQ_mLOhrmC}O-tX^0c>5`YvCUZVsc zG-6#78ubjJ5nA;OX&^K(q=i6ZNE3m?kTwE^AqxZoLskfB3|S&1F=UO9!cY$g2@Lgu z;9{sJ1P9|X2L`r1#Gs8R{E^$PRrMaC86q| + + +BOOST + HAAR + 20 + 20 + + 213 + + 0 + 22 + + <_> + 3 + 8.2268941402435303e-01 + + <_> + + 0 -1 0 4.0141958743333817e-03 + + 3.3794190734624863e-02 8.3781069517135620e-01 + <_> + + 0 -1 1 1.5151339583098888e-02 + + 1.5141320228576660e-01 7.4888122081756592e-01 + <_> + + 0 -1 2 4.2109931819140911e-03 + + 9.0049281716346741e-02 6.3748198747634888e-01 + <_> + 16 + 6.9566087722778320e+00 + + <_> + + 0 -1 3 1.6227109590545297e-03 + + 6.9308586418628693e-02 7.1109461784362793e-01 + <_> + + 0 -1 4 2.2906649392098188e-03 + + 1.7958030104637146e-01 6.6686922311782837e-01 + <_> + + 0 -1 5 5.0025708042085171e-03 + + 1.6936729848384857e-01 6.5540069341659546e-01 + <_> + + 0 -1 6 7.9659894108772278e-03 + + 5.8663320541381836e-01 9.1414518654346466e-02 + <_> + + 0 -1 7 -3.5227010957896709e-03 + + 1.4131669700145721e-01 6.0318958759307861e-01 + <_> + + 0 -1 8 3.6667689681053162e-02 + + 3.6756721138954163e-01 7.9203182458877563e-01 + <_> + + 0 -1 9 9.3361474573612213e-03 + + 6.1613857746124268e-01 2.0885099470615387e-01 + <_> + + 0 -1 10 8.6961314082145691e-03 + + 2.8362309932708740e-01 6.3602739572525024e-01 + <_> + + 0 -1 11 1.1488880263641477e-03 + + 2.2235809266567230e-01 5.8007007837295532e-01 + <_> + + 0 -1 12 -2.1484689787030220e-03 + + 2.4064640700817108e-01 5.7870548963546753e-01 + <_> + + 0 -1 13 2.1219060290604830e-03 + + 5.5596548318862915e-01 1.3622370362281799e-01 + <_> + + 0 -1 14 -9.3949146568775177e-02 + + 8.5027372837066650e-01 4.7177401185035706e-01 + <_> + + 0 -1 15 1.3777789426967502e-03 + + 5.9936738014221191e-01 2.8345298767089844e-01 + <_> + + 0 -1 16 7.3063157498836517e-02 + + 4.3418860435485840e-01 7.0600342750549316e-01 + <_> + + 0 -1 17 3.6767389974556863e-04 + + 3.0278879404067993e-01 6.0515749454498291e-01 + <_> + + 0 -1 18 -6.0479710809886456e-03 + + 1.7984339594841003e-01 5.6752568483352661e-01 + <_> + 21 + 9.4985427856445312e+00 + + <_> + + 0 -1 19 -1.6510689631104469e-02 + + 6.6442251205444336e-01 1.4248579740524292e-01 + <_> + + 0 -1 20 2.7052499353885651e-03 + + 6.3253521919250488e-01 1.2884770333766937e-01 + <_> + + 0 -1 21 2.8069869149476290e-03 + + 1.2402880191802979e-01 6.1931931972503662e-01 + <_> + + 0 -1 22 -1.5402400167658925e-03 + + 1.4321430027484894e-01 5.6700158119201660e-01 + <_> + + 0 -1 23 -5.6386279175058007e-04 + + 1.6574330627918243e-01 5.9052079916000366e-01 + <_> + + 0 -1 24 1.9253729842603207e-03 + + 2.6955071091651917e-01 5.7388240098953247e-01 + <_> + + 0 -1 25 -5.0214841030538082e-03 + + 1.8935389816761017e-01 5.7827740907669067e-01 + <_> + + 0 -1 26 2.6365420781075954e-03 + + 2.3093290627002716e-01 5.6954258680343628e-01 + <_> + + 0 -1 27 -1.5127769438549876e-03 + + 2.7596020698547363e-01 5.9566420316696167e-01 + <_> + + 0 -1 28 -1.0157439857721329e-02 + + 1.7325380444526672e-01 5.5220472812652588e-01 + <_> + + 0 -1 29 -1.1953660286962986e-02 + + 1.3394099473953247e-01 5.5590140819549561e-01 + <_> + + 0 -1 30 4.8859491944313049e-03 + + 3.6287039518356323e-01 6.1888492107391357e-01 + <_> + + 0 -1 31 -8.0132916569709778e-02 + + 9.1211050748825073e-02 5.4759448766708374e-01 + <_> + + 0 -1 32 1.0643280111253262e-03 + + 3.7151429057121277e-01 5.7113999128341675e-01 + <_> + + 0 -1 33 -1.3419450260698795e-03 + + 5.9533137083053589e-01 3.3180978894233704e-01 + <_> + + 0 -1 34 -5.4601140320301056e-02 + + 1.8440659344196320e-01 5.6028461456298828e-01 + <_> + + 0 -1 35 2.9071690514683723e-03 + + 3.5942441225051880e-01 6.1317151784896851e-01 + <_> + + 0 -1 36 7.4718717951327562e-04 + + 5.9943532943725586e-01 3.4595629572868347e-01 + <_> + + 0 -1 37 4.3013808317482471e-03 + + 4.1726520657539368e-01 6.9908452033996582e-01 + <_> + + 0 -1 38 4.5017572119832039e-03 + + 4.5097151398658752e-01 7.8014570474624634e-01 + <_> + + 0 -1 39 2.4138500913977623e-02 + + 5.4382127523422241e-01 1.3198269903659821e-01 + <_> + 39 + 1.8412969589233398e+01 + + <_> + + 0 -1 40 1.9212230108678341e-03 + + 1.4152669906616211e-01 6.1998707056045532e-01 + <_> + + 0 -1 41 -1.2748669541906565e-04 + + 6.1910742521286011e-01 1.8849289417266846e-01 + <_> + + 0 -1 42 5.1409931620582938e-04 + + 1.4873969554901123e-01 5.8579277992248535e-01 + <_> + + 0 -1 43 4.1878609918057919e-03 + + 2.7469098567962646e-01 6.3592398166656494e-01 + <_> + + 0 -1 44 5.1015717908740044e-03 + + 5.8708512783050537e-01 2.1756289899349213e-01 + <_> + + 0 -1 45 -2.1448440384119749e-03 + + 5.8809447288513184e-01 2.9795908927917480e-01 + <_> + + 0 -1 46 -2.8977119363844395e-03 + + 2.3733270168304443e-01 5.8766472339630127e-01 + <_> + + 0 -1 47 -2.1610679104924202e-02 + + 1.2206549942493439e-01 5.1942020654678345e-01 + <_> + + 0 -1 48 -4.6299318782985210e-03 + + 2.6312309503555298e-01 5.8174091577529907e-01 + <_> + + 0 -1 49 5.9393711853772402e-04 + + 3.6386200785636902e-01 5.6985449790954590e-01 + <_> + + 0 -1 50 5.3878661245107651e-02 + + 4.3035310506820679e-01 7.5593662261962891e-01 + <_> + + 0 -1 51 1.8887349870055914e-03 + + 2.1226030588150024e-01 5.6134271621704102e-01 + <_> + + 0 -1 52 -2.3635339457541704e-03 + + 5.6318491697311401e-01 2.6427671313285828e-01 + <_> + + 0 -1 53 2.4017799645662308e-02 + + 5.7971078157424927e-01 2.7517059445381165e-01 + <_> + + 0 -1 54 2.0543030404951423e-04 + + 2.7052420377731323e-01 5.7525688409805298e-01 + <_> + + 0 -1 55 8.4790197433903813e-04 + + 5.4356247186660767e-01 2.3348769545555115e-01 + <_> + + 0 -1 56 1.4091329649090767e-03 + + 5.3194248676300049e-01 2.0631550252437592e-01 + <_> + + 0 -1 57 1.4642629539594054e-03 + + 5.4189807176589966e-01 3.0688610672950745e-01 + <_> + + 0 -1 58 1.6352549428120255e-03 + + 3.6953729391098022e-01 6.1128681898117065e-01 + <_> + + 0 -1 59 8.3172752056270838e-04 + + 3.5650369524955750e-01 6.0252362489700317e-01 + <_> + + 0 -1 60 -2.0998890977352858e-03 + + 1.9139820337295532e-01 5.3628271818161011e-01 + <_> + + 0 -1 61 -7.4213981861248612e-04 + + 3.8355550169944763e-01 5.5293101072311401e-01 + <_> + + 0 -1 62 3.2655049581080675e-03 + + 4.3128961324691772e-01 7.1018958091735840e-01 + <_> + + 0 -1 63 8.9134991867467761e-04 + + 3.9848309755325317e-01 6.3919639587402344e-01 + <_> + + 0 -1 64 -1.5284179709851742e-02 + + 2.3667329549789429e-01 5.4337137937545776e-01 + <_> + + 0 -1 65 4.8381411470472813e-03 + + 5.8175009489059448e-01 3.2391890883445740e-01 + <_> + + 0 -1 66 -9.1093179071322083e-04 + + 5.5405938625335693e-01 2.9118689894676208e-01 + <_> + + 0 -1 67 -6.1275060288608074e-03 + + 1.7752550542354584e-01 5.1966291666030884e-01 + <_> + + 0 -1 68 -4.4576259097084403e-04 + + 3.0241701006889343e-01 5.5335938930511475e-01 + <_> + + 0 -1 69 2.2646540775895119e-02 + + 4.4149309396743774e-01 6.9753772020339966e-01 + <_> + + 0 -1 70 -1.8804960418492556e-03 + + 2.7913948893547058e-01 5.4979521036148071e-01 + <_> + + 0 -1 71 7.0889107882976532e-03 + + 5.2631992101669312e-01 2.3855470120906830e-01 + <_> + + 0 -1 72 1.7318050377070904e-03 + + 4.3193790316581726e-01 6.9836008548736572e-01 + <_> + + 0 -1 73 -6.8482700735330582e-03 + + 3.0820429325103760e-01 5.3909200429916382e-01 + <_> + + 0 -1 74 -1.5062530110299122e-05 + + 5.5219221115112305e-01 3.1203660368919373e-01 + <_> + + 0 -1 75 2.9475569725036621e-02 + + 5.4013228416442871e-01 1.7706030607223511e-01 + <_> + + 0 -1 76 8.1387329846620560e-03 + + 5.1786178350448608e-01 1.2110190093517303e-01 + <_> + + 0 -1 77 2.0942950621247292e-02 + + 5.2902942895889282e-01 3.3112218976020813e-01 + <_> + + 0 -1 78 -9.5665529370307922e-03 + + 7.4719941616058350e-01 4.4519689679145813e-01 + <_> + 33 + 1.5324139595031738e+01 + + <_> + + 0 -1 79 -2.8206960996612906e-04 + + 2.0640860497951508e-01 6.0767322778701782e-01 + <_> + + 0 -1 80 1.6790600493550301e-03 + + 5.8519971370697021e-01 1.2553839385509491e-01 + <_> + + 0 -1 81 6.9827912375330925e-04 + + 9.4018429517745972e-02 5.7289612293243408e-01 + <_> + + 0 -1 82 7.8959012171253562e-04 + + 1.7819879949092865e-01 5.6943088769912720e-01 + <_> + + 0 -1 83 -2.8560499195009470e-03 + + 1.6383990645408630e-01 5.7886648178100586e-01 + <_> + + 0 -1 84 -3.8122469559311867e-03 + + 2.0854400098323822e-01 5.5085647106170654e-01 + <_> + + 0 -1 85 1.5896620461717248e-03 + + 5.7027608156204224e-01 1.8572150170803070e-01 + <_> + + 0 -1 86 1.0078339837491512e-02 + + 5.1169431209564209e-01 2.1897700428962708e-01 + <_> + + 0 -1 87 -6.3526302576065063e-02 + + 7.1313798427581787e-01 4.0438130497932434e-01 + <_> + + 0 -1 88 -9.1031491756439209e-03 + + 2.5671818852424622e-01 5.4639732837677002e-01 + <_> + + 0 -1 89 -2.4035000242292881e-03 + + 1.7006659507751465e-01 5.5909740924835205e-01 + <_> + + 0 -1 90 1.5226360410451889e-03 + + 5.4105567932128906e-01 2.6190540194511414e-01 + <_> + + 0 -1 91 1.7997439950704575e-02 + + 3.7324368953704834e-01 6.5352207422256470e-01 + <_> + + 0 -1 92 -6.4538191072642803e-03 + + 2.6264819502830505e-01 5.5374461412429810e-01 + <_> + + 0 -1 93 -1.1880760081112385e-02 + + 2.0037539303302765e-01 5.5447459220886230e-01 + <_> + + 0 -1 94 1.2713660253211856e-03 + + 5.5919027328491211e-01 3.0319759249687195e-01 + <_> + + 0 -1 95 1.1376109905540943e-03 + + 2.7304071187973022e-01 5.6465089321136475e-01 + <_> + + 0 -1 96 -4.2651998810470104e-03 + + 1.4059090614318848e-01 5.4618209600448608e-01 + <_> + + 0 -1 97 -2.9602861031889915e-03 + + 1.7950350046157837e-01 5.4592901468276978e-01 + <_> + + 0 -1 98 -8.8448226451873779e-03 + + 5.7367831468582153e-01 2.8092199563980103e-01 + <_> + + 0 -1 99 -6.6430689767003059e-03 + + 2.3706759512424469e-01 5.5038261413574219e-01 + <_> + + 0 -1 100 3.9997808635234833e-03 + + 5.6081998348236084e-01 3.3042821288108826e-01 + <_> + + 0 -1 101 -4.1221720166504383e-03 + + 1.6401059925556183e-01 5.3789931535720825e-01 + <_> + + 0 -1 102 1.5624909661710262e-02 + + 5.2276492118835449e-01 2.2886039316654205e-01 + <_> + + 0 -1 103 -1.0356419719755650e-02 + + 7.0161938667297363e-01 4.2529278993606567e-01 + <_> + + 0 -1 104 -8.7960809469223022e-03 + + 2.7673470973968506e-01 5.3558301925659180e-01 + <_> + + 0 -1 105 1.6226939857006073e-01 + + 4.3422400951385498e-01 7.4425792694091797e-01 + <_> + + 0 -1 106 4.5542530715465546e-03 + + 5.7264858484268188e-01 2.5821250677108765e-01 + <_> + + 0 -1 107 -2.1309209987521172e-03 + + 2.1068480610847473e-01 5.3610187768936157e-01 + <_> + + 0 -1 108 -1.3208420015871525e-02 + + 7.5937908887863159e-01 4.5524680614471436e-01 + <_> + + 0 -1 109 -6.5996676683425903e-02 + + 1.2524759769439697e-01 5.3440397977828979e-01 + <_> + + 0 -1 110 7.9142656177282333e-03 + + 3.3153840899467468e-01 5.6010431051254272e-01 + <_> + + 0 -1 111 2.0894279703497887e-02 + + 5.5060499906539917e-01 2.7688381075859070e-01 + <_> + 44 + 2.1010639190673828e+01 + + <_> + + 0 -1 112 1.1961159761995077e-03 + + 1.7626909911632538e-01 6.1562412977218628e-01 + <_> + + 0 -1 113 -1.8679830245673656e-03 + + 6.1181068420410156e-01 1.8323999643325806e-01 + <_> + + 0 -1 114 -1.9579799845814705e-04 + + 9.9044263362884521e-02 5.7238161563873291e-01 + <_> + + 0 -1 115 -8.0255657667294145e-04 + + 5.5798798799514771e-01 2.3772829771041870e-01 + <_> + + 0 -1 116 -2.4510810617357492e-03 + + 2.2314579784870148e-01 5.8589351177215576e-01 + <_> + + 0 -1 117 5.0361850298941135e-04 + + 2.6539939641952515e-01 5.7941037416458130e-01 + <_> + + 0 -1 118 4.0293349884450436e-03 + + 5.8038270473480225e-01 2.4848650395870209e-01 + <_> + + 0 -1 119 -1.4451709575951099e-02 + + 1.8303519487380981e-01 5.4842048883438110e-01 + <_> + + 0 -1 120 2.0380979403853416e-03 + + 3.3635589480400085e-01 6.0510927438735962e-01 + <_> + + 0 -1 121 -1.6155190533027053e-03 + + 2.2866420447826385e-01 5.4412460327148438e-01 + <_> + + 0 -1 122 3.3458340913057327e-03 + + 5.6259131431579590e-01 2.3923380672931671e-01 + <_> + + 0 -1 123 1.6379579901695251e-03 + + 3.9069938659667969e-01 5.9646219015121460e-01 + <_> + + 0 -1 124 3.0251210555434227e-02 + + 5.2484822273254395e-01 1.5757469832897186e-01 + <_> + + 0 -1 125 3.7251990288496017e-02 + + 4.1943109035491943e-01 6.7484188079833984e-01 + <_> + + 0 -1 126 -2.5109790265560150e-02 + + 1.8825499713420868e-01 5.4734510183334351e-01 + <_> + + 0 -1 127 -5.3099058568477631e-03 + + 1.3399730622768402e-01 5.2271109819412231e-01 + <_> + + 0 -1 128 1.2086479691788554e-03 + + 3.7620881199836731e-01 6.1096358299255371e-01 + <_> + + 0 -1 129 -2.1907679736614227e-02 + + 2.6631429791450500e-01 5.4040068387985229e-01 + <_> + + 0 -1 130 5.4116579703986645e-03 + + 5.3635787963867188e-01 2.2322730720043182e-01 + <_> + + 0 -1 131 6.9946326315402985e-02 + + 5.3582328557968140e-01 2.4536980688571930e-01 + <_> + + 0 -1 132 3.4520021290518343e-04 + + 2.4096719920635223e-01 5.3769302368164062e-01 + <_> + + 0 -1 133 1.2627709656953812e-03 + + 5.4258567094802856e-01 3.1556931138038635e-01 + <_> + + 0 -1 134 2.2719509899616241e-02 + + 4.1584059596061707e-01 6.5978652238845825e-01 + <_> + + 0 -1 135 -1.8111000536009669e-03 + + 2.8112530708312988e-01 5.5052447319030762e-01 + <_> + + 0 -1 136 3.3469670452177525e-03 + + 5.2600282430648804e-01 1.8914650380611420e-01 + <_> + + 0 -1 137 4.0791751234792173e-04 + + 5.6735092401504517e-01 3.3442100882530212e-01 + <_> + + 0 -1 138 1.2734799645841122e-02 + + 5.3435921669006348e-01 2.3956120014190674e-01 + <_> + + 0 -1 139 -7.3119727894663811e-03 + + 6.0108900070190430e-01 4.0222078561782837e-01 + <_> + + 0 -1 140 -5.6948751211166382e-02 + + 8.1991511583328247e-01 4.5431908965110779e-01 + <_> + + 0 -1 141 -5.0116591155529022e-03 + + 2.2002810239791870e-01 5.3577107191085815e-01 + <_> + + 0 -1 142 6.0334368608891964e-03 + + 4.4130811095237732e-01 7.1817511320114136e-01 + <_> + + 0 -1 143 3.9437441155314445e-03 + + 5.4788607358932495e-01 2.7917331457138062e-01 + <_> + + 0 -1 144 -3.6591119132936001e-03 + + 6.3578677177429199e-01 3.9897239208221436e-01 + <_> + + 0 -1 145 -3.8456181064248085e-03 + + 3.4936860203742981e-01 5.3006649017333984e-01 + <_> + + 0 -1 146 -7.1926261298358440e-03 + + 1.1196149885654449e-01 5.2296727895736694e-01 + <_> + + 0 -1 147 -5.2798941731452942e-02 + + 2.3871029913425446e-01 5.4534512758255005e-01 + <_> + + 0 -1 148 -7.9537667334079742e-03 + + 7.5869178771972656e-01 4.4393768906593323e-01 + <_> + + 0 -1 149 -2.7344180271029472e-03 + + 2.5654768943786621e-01 5.4893219470977783e-01 + <_> + + 0 -1 150 -1.8507939530536532e-03 + + 6.7343479394912720e-01 4.2524749040603638e-01 + <_> + + 0 -1 151 1.5918919816613197e-02 + + 5.4883527755737305e-01 2.2926619648933411e-01 + <_> + + 0 -1 152 -1.2687679845839739e-03 + + 6.1043310165405273e-01 4.0223899483680725e-01 + <_> + + 0 -1 153 6.2883910723030567e-03 + + 5.3108531236648560e-01 1.5361930429935455e-01 + <_> + + 0 -1 154 -6.2259892001748085e-03 + + 1.7291119694709778e-01 5.2416062355041504e-01 + <_> + + 0 -1 155 -1.2132599949836731e-02 + + 6.5977597236633301e-01 4.3251821398735046e-01 + <_> + 50 + 2.3918790817260742e+01 + + <_> + + 0 -1 156 -3.9184908382594585e-03 + + 6.1034351587295532e-01 1.4693309366703033e-01 + <_> + + 0 -1 157 1.5971299726516008e-03 + + 2.6323631405830383e-01 5.8964669704437256e-01 + <_> + + 0 -1 158 1.7780110239982605e-02 + + 5.8728742599487305e-01 1.7603619396686554e-01 + <_> + + 0 -1 159 6.5334769897162914e-04 + + 1.5678019821643829e-01 5.5960661172866821e-01 + <_> + + 0 -1 160 -2.8353091329336166e-04 + + 1.9131539762020111e-01 5.7320362329483032e-01 + <_> + + 0 -1 161 1.6104689566418529e-03 + + 2.9149138927459717e-01 5.6230807304382324e-01 + <_> + + 0 -1 162 -9.7750619053840637e-02 + + 1.9434769451618195e-01 5.6482332944869995e-01 + <_> + + 0 -1 163 5.5182358482852578e-04 + + 3.1346169114112854e-01 5.5046397447586060e-01 + <_> + + 0 -1 164 -1.2858220376074314e-02 + + 2.5364819169044495e-01 5.7601428031921387e-01 + <_> + + 0 -1 165 4.1530239395797253e-03 + + 5.7677221298217773e-01 3.6597740650177002e-01 + <_> + + 0 -1 166 1.7092459602281451e-03 + + 2.8431910276412964e-01 5.9189391136169434e-01 + <_> + + 0 -1 167 7.5217359699308872e-03 + + 4.0524271130561829e-01 6.1831092834472656e-01 + <_> + + 0 -1 168 2.2479810286313295e-03 + + 5.7837551832199097e-01 3.1354010105133057e-01 + <_> + + 0 -1 169 5.2006211131811142e-02 + + 5.5413120985031128e-01 1.9166369736194611e-01 + <_> + + 0 -1 170 1.2085529975593090e-02 + + 4.0326559543609619e-01 6.6445910930633545e-01 + <_> + + 0 -1 171 1.4687820112158079e-05 + + 3.5359779000282288e-01 5.7093828916549683e-01 + <_> + + 0 -1 172 7.1395188570022583e-06 + + 3.0374449491500854e-01 5.6102699041366577e-01 + <_> + + 0 -1 173 -4.6001640148460865e-03 + + 7.1810871362686157e-01 4.5803260803222656e-01 + <_> + + 0 -1 174 2.0058949012309313e-03 + + 5.6219518184661865e-01 2.9536840319633484e-01 + <_> + + 0 -1 175 4.5050270855426788e-03 + + 4.6153879165649414e-01 7.6190179586410522e-01 + <_> + + 0 -1 176 1.1746830306947231e-02 + + 5.3438371419906616e-01 1.7725290358066559e-01 + <_> + + 0 -1 177 -5.8316338807344437e-02 + + 1.6862459480762482e-01 5.3407722711563110e-01 + <_> + + 0 -1 178 2.3629379575140774e-04 + + 3.7920561432838440e-01 6.0268038511276245e-01 + <_> + + 0 -1 179 -7.8156180679798126e-03 + + 1.5128670632839203e-01 5.3243237733840942e-01 + <_> + + 0 -1 180 -1.0876160115003586e-02 + + 2.0818220078945160e-01 5.3199452161788940e-01 + <_> + + 0 -1 181 -2.7745519764721394e-03 + + 4.0982469916343689e-01 5.2103281021118164e-01 + <_> + + 0 -1 182 -7.8276381827890873e-04 + + 5.6932741403579712e-01 3.4788420796394348e-01 + <_> + + 0 -1 183 1.3870409689843655e-02 + + 5.3267508745193481e-01 2.2576980292797089e-01 + <_> + + 0 -1 184 -2.3674910888075829e-02 + + 1.5513050556182861e-01 5.2007079124450684e-01 + <_> + + 0 -1 185 -1.4879409718560055e-05 + + 5.5005669593811035e-01 3.8201761245727539e-01 + <_> + + 0 -1 186 3.6190641112625599e-03 + + 4.2386838793754578e-01 6.6397482156753540e-01 + <_> + + 0 -1 187 -1.9817110151052475e-02 + + 2.1500380337238312e-01 5.3823578357696533e-01 + <_> + + 0 -1 188 -3.8154039066284895e-03 + + 6.6757112741470337e-01 4.2152971029281616e-01 + <_> + + 0 -1 189 -4.9775829538702965e-03 + + 2.2672890126705170e-01 5.3863281011581421e-01 + <_> + + 0 -1 190 2.2441020701080561e-03 + + 4.3086910247802734e-01 6.8557357788085938e-01 + <_> + + 0 -1 191 1.2282459996640682e-02 + + 5.8366149663925171e-01 3.4674790501594543e-01 + <_> + + 0 -1 192 -2.8548699337989092e-03 + + 7.0169448852539062e-01 4.3114539980888367e-01 + <_> + + 0 -1 193 -3.7875669077038765e-03 + + 2.8953450918197632e-01 5.2249461412429810e-01 + <_> + + 0 -1 194 -1.2201230274513364e-03 + + 2.9755708575248718e-01 5.4816448688507080e-01 + <_> + + 0 -1 195 1.0160599835216999e-02 + + 4.8888179659843445e-01 8.1826978921890259e-01 + <_> + + 0 -1 196 -1.6174569725990295e-02 + + 1.4814929664134979e-01 5.2399927377700806e-01 + <_> + + 0 -1 197 1.9292460754513741e-02 + + 4.7863098978996277e-01 7.3781907558441162e-01 + <_> + + 0 -1 198 -3.2479539513587952e-03 + + 7.3742228746414185e-01 4.4706439971923828e-01 + <_> + + 0 -1 199 -9.3803480267524719e-03 + + 3.4891548752784729e-01 5.5379962921142578e-01 + <_> + + 0 -1 200 -1.2606129981577396e-02 + + 2.3796869814395905e-01 5.3154432773590088e-01 + <_> + + 0 -1 201 -2.5621930137276649e-02 + + 1.9646880030632019e-01 5.1387697458267212e-01 + <_> + + 0 -1 202 -7.5741496402770281e-05 + + 5.5905228853225708e-01 3.3658531308174133e-01 + <_> + + 0 -1 203 -8.9210882782936096e-02 + + 6.3404656946659088e-02 5.1626348495483398e-01 + <_> + + 0 -1 204 -2.7670480776578188e-03 + + 7.3234677314758301e-01 4.4907060265541077e-01 + <_> + + 0 -1 205 2.7152578695677221e-04 + + 4.1148349642753601e-01 5.9855180978775024e-01 + <_> + 51 + 2.4527879714965820e+01 + + <_> + + 0 -1 206 1.4786219689995050e-03 + + 2.6635450124740601e-01 6.6433167457580566e-01 + <_> + + 0 -1 207 -1.8741659587249160e-03 + + 6.1438488960266113e-01 2.5185129046440125e-01 + <_> + + 0 -1 208 -1.7151009524241090e-03 + + 5.7663410902023315e-01 2.3974630236625671e-01 + <_> + + 0 -1 209 -1.8939269939437509e-03 + + 5.6820458173751831e-01 2.5291448831558228e-01 + <_> + + 0 -1 210 -5.3006052039563656e-03 + + 1.6406759619712830e-01 5.5560797452926636e-01 + <_> + + 0 -1 211 -4.6662531793117523e-02 + + 6.1231541633605957e-01 4.7628301382064819e-01 + <_> + + 0 -1 212 -7.9431332414969802e-04 + + 5.7078588008880615e-01 2.8394040465354919e-01 + <_> + + 0 -1 213 1.4891670085489750e-02 + + 4.0896728634834290e-01 6.0063672065734863e-01 + <_> + + 0 -1 214 -1.2046529445797205e-03 + + 5.7124507427215576e-01 2.7052891254425049e-01 + <_> + + 0 -1 215 6.0619381256401539e-03 + + 5.2625042200088501e-01 3.2622259855270386e-01 + <_> + + 0 -1 216 -2.5286648888140917e-03 + + 6.8538308143615723e-01 4.1992568969726562e-01 + <_> + + 0 -1 217 -5.9010218828916550e-03 + + 3.2662820816040039e-01 5.4348129034042358e-01 + <_> + + 0 -1 218 5.6702760048210621e-03 + + 5.4684108495712280e-01 2.3190039396286011e-01 + <_> + + 0 -1 219 -3.0304100364446640e-03 + + 5.5706679821014404e-01 2.7082380652427673e-01 + <_> + + 0 -1 220 2.9803649522364140e-03 + + 3.7005689740180969e-01 5.8906257152557373e-01 + <_> + + 0 -1 221 -7.5840510427951813e-02 + + 2.1400700509548187e-01 5.4199481010437012e-01 + <_> + + 0 -1 222 1.9262539222836494e-02 + + 5.5267721414566040e-01 2.7265900373458862e-01 + <_> + + 0 -1 223 1.8888259364757687e-04 + + 3.9580118656158447e-01 6.0172098875045776e-01 + <_> + + 0 -1 224 2.9369549825787544e-02 + + 5.2413737773895264e-01 1.4357580244541168e-01 + <_> + + 0 -1 225 1.0417619487270713e-03 + + 3.3854091167449951e-01 5.9299832582473755e-01 + <_> + + 0 -1 226 2.6125640142709017e-03 + + 5.4853779077529907e-01 3.0215978622436523e-01 + <_> + + 0 -1 227 9.6977467183023691e-04 + + 3.3752760291099548e-01 5.5320328474044800e-01 + <_> + + 0 -1 228 5.9512659208849072e-04 + + 5.6317430734634399e-01 3.3593991398811340e-01 + <_> + + 0 -1 229 -1.0156559944152832e-01 + + 6.3735038042068481e-02 5.2304250001907349e-01 + <_> + + 0 -1 230 3.6156699061393738e-02 + + 5.1369631290435791e-01 1.0295289754867554e-01 + <_> + + 0 -1 231 3.4624140243977308e-03 + + 3.8793200254440308e-01 5.5582892894744873e-01 + <_> + + 0 -1 232 1.9554980099201202e-02 + + 5.2500867843627930e-01 1.8758599460124969e-01 + <_> + + 0 -1 233 -2.3121440317481756e-03 + + 6.6720288991928101e-01 4.6796411275863647e-01 + <_> + + 0 -1 234 -1.8605289515107870e-03 + + 7.1633791923522949e-01 4.3346709012985229e-01 + <_> + + 0 -1 235 -9.4026362057775259e-04 + + 3.0213609337806702e-01 5.6502032279968262e-01 + <_> + + 0 -1 236 -5.2418331615626812e-03 + + 1.8200090527534485e-01 5.2502560615539551e-01 + <_> + + 0 -1 237 1.1729019752237946e-04 + + 3.3891880512237549e-01 5.4459732770919800e-01 + <_> + + 0 -1 238 1.1878840159624815e-03 + + 4.0853491425514221e-01 6.2535631656646729e-01 + <_> + + 0 -1 239 -1.0881359688937664e-02 + + 3.3783990144729614e-01 5.7000827789306641e-01 + <_> + + 0 -1 240 1.7354859737679362e-03 + + 4.2046359181404114e-01 6.5230387449264526e-01 + <_> + + 0 -1 241 -6.5119052305817604e-03 + + 2.5952160358428955e-01 5.4281437397003174e-01 + <_> + + 0 -1 242 -1.2136430013924837e-03 + + 6.1651438474655151e-01 3.9778938889503479e-01 + <_> + + 0 -1 243 -1.0354240424931049e-02 + + 1.6280280053615570e-01 5.2195048332214355e-01 + <_> + + 0 -1 244 5.5858830455690622e-04 + + 3.1996509432792664e-01 5.5035740137100220e-01 + <_> + + 0 -1 245 1.5299649909138680e-02 + + 4.1039940714836121e-01 6.1223882436752319e-01 + <_> + + 0 -1 246 -2.1588210016489029e-02 + + 1.0349129885435104e-01 5.1973849534988403e-01 + <_> + + 0 -1 247 -1.2834629416465759e-01 + + 8.4938651323318481e-01 4.8931029438972473e-01 + <_> + + 0 -1 248 -2.2927189711481333e-03 + + 3.1301578879356384e-01 5.4715752601623535e-01 + <_> + + 0 -1 249 7.9915106296539307e-02 + + 4.8563209176063538e-01 6.0739892721176147e-01 + <_> + + 0 -1 250 -7.9441092908382416e-02 + + 8.3946740627288818e-01 4.6245330572128296e-01 + <_> + + 0 -1 251 -5.2800010889768600e-03 + + 1.8816959857940674e-01 5.3066980838775635e-01 + <_> + + 0 -1 252 1.0463109938427806e-03 + + 5.2712291479110718e-01 2.5830659270286560e-01 + <_> + + 0 -1 253 2.6317298761568964e-04 + + 4.2353048920631409e-01 5.7354408502578735e-01 + <_> + + 0 -1 254 -3.6173160187900066e-03 + + 6.9343960285186768e-01 4.4954448938369751e-01 + <_> + + 0 -1 255 1.1421879753470421e-02 + + 5.9009212255477905e-01 4.1381931304931641e-01 + <_> + + 0 -1 256 -1.9963278900831938e-03 + + 6.4663827419281006e-01 4.3272399902343750e-01 + <_> + 56 + 2.7153350830078125e+01 + + <_> + + 0 -1 257 -9.9691245704889297e-03 + + 6.1423242092132568e-01 2.4822120368480682e-01 + <_> + + 0 -1 258 7.3073059320449829e-04 + + 5.7049518823623657e-01 2.3219659924507141e-01 + <_> + + 0 -1 259 6.4045301405712962e-04 + + 2.1122519671916962e-01 5.8149331808090210e-01 + <_> + + 0 -1 260 4.5424019917845726e-03 + + 2.9504820704460144e-01 5.8663117885589600e-01 + <_> + + 0 -1 261 9.2477443104144186e-05 + + 2.9909908771514893e-01 5.7913267612457275e-01 + <_> + + 0 -1 262 -8.6603146046400070e-03 + + 2.8130298852920532e-01 5.6355422735214233e-01 + <_> + + 0 -1 263 8.0515816807746887e-03 + + 3.5353690385818481e-01 6.0547572374343872e-01 + <_> + + 0 -1 264 4.3835240649059415e-04 + + 5.5965322256088257e-01 2.7315109968185425e-01 + <_> + + 0 -1 265 -9.8168973636347800e-05 + + 5.9780317544937134e-01 3.6385610699653625e-01 + <_> + + 0 -1 266 -1.1298790341243148e-03 + + 2.7552521228790283e-01 5.4327291250228882e-01 + <_> + + 0 -1 267 6.4356150105595589e-03 + + 4.3056419491767883e-01 7.0698332786560059e-01 + <_> + + 0 -1 268 -5.6829329580068588e-02 + + 2.4952429533004761e-01 5.2949970960617065e-01 + <_> + + 0 -1 269 4.0668169967830181e-03 + + 5.4785531759262085e-01 2.4977239966392517e-01 + <_> + + 0 -1 270 4.8164798499783501e-05 + + 3.9386010169982910e-01 5.7063561677932739e-01 + <_> + + 0 -1 271 6.1795017682015896e-03 + + 4.4076061248779297e-01 7.3947668075561523e-01 + <_> + + 0 -1 272 6.4985752105712891e-03 + + 5.4452431201934814e-01 2.4791529774665833e-01 + <_> + + 0 -1 273 -1.0211090557277203e-03 + + 2.5447669625282288e-01 5.3389710187911987e-01 + <_> + + 0 -1 274 -5.4247528314590454e-03 + + 2.7188581228256226e-01 5.3240692615509033e-01 + <_> + + 0 -1 275 -1.0559899965301156e-03 + + 3.1782880425453186e-01 5.5345088243484497e-01 + <_> + + 0 -1 276 6.6465808777138591e-04 + + 4.2842191457748413e-01 6.5581941604614258e-01 + <_> + + 0 -1 277 -2.7524109464138746e-04 + + 5.9028607606887817e-01 3.8102629780769348e-01 + <_> + + 0 -1 278 4.2293202131986618e-03 + + 3.8164898753166199e-01 5.7093858718872070e-01 + <_> + + 0 -1 279 -3.2868210691958666e-03 + + 1.7477439343929291e-01 5.2595442533493042e-01 + <_> + + 0 -1 280 1.5611879643984139e-04 + + 3.6017221212387085e-01 5.7256120443344116e-01 + <_> + + 0 -1 281 -7.3621381488919724e-06 + + 5.4018580913543701e-01 3.0444970726966858e-01 + <_> + + 0 -1 282 -1.4767250046133995e-02 + + 3.2207700610160828e-01 5.5734348297119141e-01 + <_> + + 0 -1 283 2.4489590898156166e-02 + + 4.3015280365943909e-01 6.5188127756118774e-01 + <_> + + 0 -1 284 -3.7652091123163700e-04 + + 3.5645830631256104e-01 5.5982369184494019e-01 + <_> + + 0 -1 285 7.3657688517414499e-06 + + 3.4907829761505127e-01 5.5618977546691895e-01 + <_> + + 0 -1 286 -1.5099939890205860e-02 + + 1.7762720584869385e-01 5.3352999687194824e-01 + <_> + + 0 -1 287 -3.8316650316119194e-03 + + 6.1496877670288086e-01 4.2213940620422363e-01 + <_> + + 0 -1 288 1.6925400123000145e-02 + + 5.4130148887634277e-01 2.1665850281715393e-01 + <_> + + 0 -1 289 -3.0477850232273340e-03 + + 6.4494907855987549e-01 4.3546178936958313e-01 + <_> + + 0 -1 290 3.2140589319169521e-03 + + 5.4001551866531372e-01 3.5232171416282654e-01 + <_> + + 0 -1 291 -4.0023201145231724e-03 + + 2.7745240926742554e-01 5.3384172916412354e-01 + <_> + + 0 -1 292 7.4182129465043545e-03 + + 5.6767392158508301e-01 3.7028178572654724e-01 + <_> + + 0 -1 293 -8.8764587417244911e-03 + + 7.7492219209671021e-01 4.5836889743804932e-01 + <_> + + 0 -1 294 2.7311739977449179e-03 + + 5.3387218713760376e-01 3.9966610074043274e-01 + <_> + + 0 -1 295 -2.5082379579544067e-03 + + 5.6119632720947266e-01 3.7774989008903503e-01 + <_> + + 0 -1 296 -8.0541074275970459e-03 + + 2.9152289032936096e-01 5.1791828870773315e-01 + <_> + + 0 -1 297 -9.7938813269138336e-04 + + 5.5364328622817993e-01 3.7001928687095642e-01 + <_> + + 0 -1 298 -5.8745909482240677e-03 + + 3.7543910741806030e-01 5.6793761253356934e-01 + <_> + + 0 -1 299 -4.4936719350516796e-03 + + 7.0196992158889771e-01 4.4809499382972717e-01 + <_> + + 0 -1 300 -5.4389229044318199e-03 + + 2.3103649914264679e-01 5.3133869171142578e-01 + <_> + + 0 -1 301 -7.5094640487805009e-04 + + 5.8648687601089478e-01 4.1293430328369141e-01 + <_> + + 0 -1 302 1.4528800420521293e-05 + + 3.7324070930480957e-01 5.6196212768554688e-01 + <_> + + 0 -1 303 4.0758069604635239e-02 + + 5.3120911121368408e-01 2.7205219864845276e-01 + <_> + + 0 -1 304 6.6505931317806244e-03 + + 4.7100159525871277e-01 6.6934937238693237e-01 + <_> + + 0 -1 305 4.5759351924061775e-03 + + 5.1678192615509033e-01 1.6372759640216827e-01 + <_> + + 0 -1 306 6.5269311890006065e-03 + + 5.3976088762283325e-01 2.9385319352149963e-01 + <_> + + 0 -1 307 -1.3660379685461521e-02 + + 7.0864880084991455e-01 4.5322000980377197e-01 + <_> + + 0 -1 308 2.7358869090676308e-02 + + 5.2064812183380127e-01 3.5892319679260254e-01 + <_> + + 0 -1 309 6.2197551596909761e-04 + + 3.5070759057998657e-01 5.4411232471466064e-01 + <_> + + 0 -1 310 -3.3077080734074116e-03 + + 5.8595228195190430e-01 4.0248918533325195e-01 + <_> + + 0 -1 311 -1.0631109587848186e-02 + + 6.7432671785354614e-01 4.4226029515266418e-01 + <_> + + 0 -1 312 1.9441649317741394e-02 + + 5.2827161550521851e-01 1.7979049682617188e-01 + <_> + 71 + 3.4554111480712891e+01 + + <_> + + 0 -1 313 -5.5052167735993862e-03 + + 5.9147310256958008e-01 2.6265591382980347e-01 + <_> + + 0 -1 314 1.9562279339879751e-03 + + 2.3125819861888885e-01 5.7416272163391113e-01 + <_> + + 0 -1 315 -8.8924784213304520e-03 + + 1.6565300524234772e-01 5.6266540288925171e-01 + <_> + + 0 -1 316 8.3638377487659454e-02 + + 5.4234498739242554e-01 1.9572949409484863e-01 + <_> + + 0 -1 317 1.2282270472496748e-03 + + 3.4179040789604187e-01 5.9925037622451782e-01 + <_> + + 0 -1 318 5.7629169896245003e-03 + + 3.7195819616317749e-01 6.0799038410186768e-01 + <_> + + 0 -1 319 -1.6417410224676132e-03 + + 2.5774860382080078e-01 5.5769157409667969e-01 + <_> + + 0 -1 320 3.4113149158656597e-03 + + 2.9507490992546082e-01 5.5141717195510864e-01 + <_> + + 0 -1 321 -1.1069320142269135e-02 + + 7.5693589448928833e-01 4.4770789146423340e-01 + <_> + + 0 -1 322 3.4865971654653549e-02 + + 5.5837088823318481e-01 2.6696211099624634e-01 + <_> + + 0 -1 323 6.5701099811121821e-04 + + 5.6273132562637329e-01 2.9888901114463806e-01 + <_> + + 0 -1 324 -2.4339130148291588e-02 + + 2.7711850404739380e-01 5.1088631153106689e-01 + <_> + + 0 -1 325 5.9435202274471521e-04 + + 5.5806517601013184e-01 3.1203418970108032e-01 + <_> + + 0 -1 326 2.2971509024500847e-03 + + 3.3302500844001770e-01 5.6790757179260254e-01 + <_> + + 0 -1 327 -3.7801829166710377e-03 + + 2.9905349016189575e-01 5.3448081016540527e-01 + <_> + + 0 -1 328 -1.3420669734477997e-01 + + 1.4638589322566986e-01 5.3925681114196777e-01 + <_> + + 0 -1 329 7.5224548345431685e-04 + + 3.7469539046287537e-01 5.6927347183227539e-01 + <_> + + 0 -1 330 -4.0545541793107986e-02 + + 2.7547478675842285e-01 5.4842978715896606e-01 + <_> + + 0 -1 331 1.2572970008477569e-03 + + 3.7445840239524841e-01 5.7560759782791138e-01 + <_> + + 0 -1 332 -7.4249948374927044e-03 + + 7.5138592720031738e-01 4.7282311320304871e-01 + <_> + + 0 -1 333 5.0908129196614027e-04 + + 5.4048967361450195e-01 2.9323211312294006e-01 + <_> + + 0 -1 334 -1.2808450264856219e-03 + + 6.1697798967361450e-01 4.2733490467071533e-01 + <_> + + 0 -1 335 -1.8348860321566463e-03 + + 2.0484960079193115e-01 5.2064722776412964e-01 + <_> + + 0 -1 336 2.7484869584441185e-02 + + 5.2529847621917725e-01 1.6755220293998718e-01 + <_> + + 0 -1 337 2.2372419480234385e-03 + + 5.2677828073501587e-01 2.7776581048965454e-01 + <_> + + 0 -1 338 -8.8635291904211044e-03 + + 6.9545578956604004e-01 4.8120489716529846e-01 + <_> + + 0 -1 339 4.1753971017897129e-03 + + 4.2918878793716431e-01 6.3491958379745483e-01 + <_> + + 0 -1 340 -1.7098189564421773e-03 + + 2.9305368661880493e-01 5.3612488508224487e-01 + <_> + + 0 -1 341 6.5328548662364483e-03 + + 4.4953250885009766e-01 7.4096941947937012e-01 + <_> + + 0 -1 342 -9.5372907817363739e-03 + + 3.1491199135780334e-01 5.4165017604827881e-01 + <_> + + 0 -1 343 2.5310989469289780e-02 + + 5.1218920946121216e-01 1.3117079436779022e-01 + <_> + + 0 -1 344 3.6460969597101212e-02 + + 5.1759117841720581e-01 2.5913399457931519e-01 + <_> + + 0 -1 345 2.0854329690337181e-02 + + 5.1371401548385620e-01 1.5823160111904144e-01 + <_> + + 0 -1 346 -8.7207747856155038e-04 + + 5.5743098258972168e-01 4.3989789485931396e-01 + <_> + + 0 -1 347 -1.5227000403683633e-05 + + 5.5489408969879150e-01 3.7080699205398560e-01 + <_> + + 0 -1 348 -8.4316509310156107e-04 + + 3.3874198794364929e-01 5.5542111396789551e-01 + <_> + + 0 -1 349 3.6037859972566366e-03 + + 5.3580617904663086e-01 3.4111711382865906e-01 + <_> + + 0 -1 350 -6.8057891912758350e-03 + + 6.1252027750015259e-01 4.3458628654479980e-01 + <_> + + 0 -1 351 -4.7021660953760147e-02 + + 2.3581659793853760e-01 5.1937389373779297e-01 + <_> + + 0 -1 352 -3.6954108625650406e-02 + + 7.3231112957000732e-01 4.7609439492225647e-01 + <_> + + 0 -1 353 1.0439479956403375e-03 + + 5.4194551706314087e-01 3.4113308787345886e-01 + <_> + + 0 -1 354 -2.1050689974799752e-04 + + 2.8216940164566040e-01 5.5549472570419312e-01 + <_> + + 0 -1 355 -8.0831587314605713e-02 + + 9.1299301385879517e-01 4.6974349021911621e-01 + <_> + + 0 -1 356 -3.6579059087671340e-04 + + 6.0226702690124512e-01 3.9782929420471191e-01 + <_> + + 0 -1 357 -1.2545920617412776e-04 + + 5.6132131814956665e-01 3.8455399870872498e-01 + <_> + + 0 -1 358 -6.8786486983299255e-02 + + 2.2616119682788849e-01 5.3004968166351318e-01 + <_> + + 0 -1 359 1.2415789999067783e-02 + + 4.0756919980049133e-01 5.8288121223449707e-01 + <_> + + 0 -1 360 -4.7174817882478237e-03 + + 2.8272539377212524e-01 5.2677577733993530e-01 + <_> + + 0 -1 361 3.8136858493089676e-02 + + 5.0747412443161011e-01 1.0236159712076187e-01 + <_> + + 0 -1 362 -2.8168049175292253e-03 + + 6.1690068244934082e-01 4.3596929311752319e-01 + <_> + + 0 -1 363 8.1303603947162628e-03 + + 4.5244330167770386e-01 7.6060950756072998e-01 + <_> + + 0 -1 364 6.0056019574403763e-03 + + 5.2404087781906128e-01 1.8597120046615601e-01 + <_> + + 0 -1 365 1.9139319658279419e-02 + + 5.2093791961669922e-01 2.3320719599723816e-01 + <_> + + 0 -1 366 1.6445759683847427e-02 + + 5.4507029056549072e-01 3.2642349600791931e-01 + <_> + + 0 -1 367 -3.7356890738010406e-02 + + 6.9990468025207520e-01 4.5332419872283936e-01 + <_> + + 0 -1 368 -1.9727900624275208e-02 + + 2.6536649465560913e-01 5.4128098487854004e-01 + <_> + + 0 -1 369 6.6972579807043076e-03 + + 4.4805660843849182e-01 7.1386522054672241e-01 + <_> + + 0 -1 370 7.4457528535276651e-04 + + 4.2313501238822937e-01 5.4713201522827148e-01 + <_> + + 0 -1 371 1.1790640419349074e-03 + + 5.3417021036148071e-01 3.1304550170898438e-01 + <_> + + 0 -1 372 3.4980610013008118e-02 + + 5.1186597347259521e-01 3.4305301308631897e-01 + <_> + + 0 -1 373 5.6859792675822973e-04 + + 3.5321870446205139e-01 5.4686397314071655e-01 + <_> + + 0 -1 374 -1.1340649798512459e-02 + + 2.8423538804054260e-01 5.3487008810043335e-01 + <_> + + 0 -1 375 -6.6228108480572701e-03 + + 6.8836402893066406e-01 4.4926649332046509e-01 + <_> + + 0 -1 376 -8.0160330981016159e-03 + + 1.7098939418792725e-01 5.2243089675903320e-01 + <_> + + 0 -1 377 1.4206819469109178e-03 + + 5.2908462285995483e-01 2.9933831095695496e-01 + <_> + + 0 -1 378 -2.7801711112260818e-03 + + 6.4988541603088379e-01 4.4604998826980591e-01 + <_> + + 0 -1 379 -1.4747589593753219e-03 + + 3.2604381442070007e-01 5.3881132602691650e-01 + <_> + + 0 -1 380 -2.3830339312553406e-02 + + 7.5289410352706909e-01 4.8012199997901917e-01 + <_> + + 0 -1 381 6.9369790144264698e-03 + + 5.3351658582687378e-01 3.2614278793334961e-01 + <_> + + 0 -1 382 8.2806255668401718e-03 + + 4.5803940296173096e-01 5.7378298044204712e-01 + <_> + + 0 -1 383 -1.0439500212669373e-02 + + 2.5923201441764832e-01 5.2338278293609619e-01 + <_> + 80 + 3.9107288360595703e+01 + + <_> + + 0 -1 384 7.2006587870419025e-03 + + 3.2588860392570496e-01 6.8498080968856812e-01 + <_> + + 0 -1 385 -2.8593589086085558e-03 + + 5.8388811349868774e-01 2.5378298759460449e-01 + <_> + + 0 -1 386 6.8580528022721410e-04 + + 5.7080817222595215e-01 2.8124240040779114e-01 + <_> + + 0 -1 387 7.9580191522836685e-03 + + 2.5010511279106140e-01 5.5442607402801514e-01 + <_> + + 0 -1 388 -1.2124150525778532e-03 + + 2.3853680491447449e-01 5.4333502054214478e-01 + <_> + + 0 -1 389 7.9426132142543793e-03 + + 3.9550709724426270e-01 6.2207579612731934e-01 + <_> + + 0 -1 390 2.4630590341985226e-03 + + 5.6397080421447754e-01 2.9923579096794128e-01 + <_> + + 0 -1 391 -6.0396599583327770e-03 + + 2.1865129470825195e-01 5.4116767644882202e-01 + <_> + + 0 -1 392 -1.2988339876756072e-03 + + 2.3507060110569000e-01 5.3645849227905273e-01 + <_> + + 0 -1 393 2.2299369447864592e-04 + + 3.8041129708290100e-01 5.7296061515808105e-01 + <_> + + 0 -1 394 1.4654280385002494e-03 + + 2.5101679563522339e-01 5.2582687139511108e-01 + <_> + + 0 -1 395 -8.1210042117163539e-04 + + 5.9928238391876221e-01 3.8511589169502258e-01 + <_> + + 0 -1 396 -1.3836020370945334e-03 + + 5.6813961267471313e-01 3.6365869641304016e-01 + <_> + + 0 -1 397 -2.7936449274420738e-02 + + 1.4913170039653778e-01 5.3775602579116821e-01 + <_> + + 0 -1 398 -4.6919551095925272e-04 + + 3.6924299597740173e-01 5.5724847316741943e-01 + <_> + + 0 -1 399 -4.9829659983515739e-03 + + 6.7585092782974243e-01 4.5325040817260742e-01 + <_> + + 0 -1 400 1.8815309740602970e-03 + + 5.3680229187011719e-01 2.9325398802757263e-01 + <_> + + 0 -1 401 -1.9067550078034401e-02 + + 1.6493770480155945e-01 5.3300672769546509e-01 + <_> + + 0 -1 402 -4.6906559728085995e-03 + + 1.9639259576797485e-01 5.1193618774414062e-01 + <_> + + 0 -1 403 5.9777139686048031e-03 + + 4.6711719036102295e-01 7.0083981752395630e-01 + <_> + + 0 -1 404 -3.3303130418062210e-02 + + 1.1554169654846191e-01 5.1041620969772339e-01 + <_> + + 0 -1 405 9.0744107961654663e-02 + + 5.1496601104736328e-01 1.3061730563640594e-01 + <_> + + 0 -1 406 9.3555898638442159e-04 + + 3.6054810881614685e-01 5.4398590326309204e-01 + <_> + + 0 -1 407 1.4901650138199329e-02 + + 4.8862120509147644e-01 7.6875698566436768e-01 + <_> + + 0 -1 408 6.1594118596985936e-04 + + 5.3568130731582642e-01 3.2409390807151794e-01 + <_> + + 0 -1 409 -5.0670988857746124e-02 + + 1.8486219644546509e-01 5.2304041385650635e-01 + <_> + + 0 -1 410 6.8665749859064817e-04 + + 3.8405799865722656e-01 5.5179458856582642e-01 + <_> + + 0 -1 411 8.3712432533502579e-03 + + 4.2885640263557434e-01 6.1317539215087891e-01 + <_> + + 0 -1 412 -1.2953069526702166e-03 + + 2.9136741161346436e-01 5.2807378768920898e-01 + <_> + + 0 -1 413 -4.1941680014133453e-02 + + 7.5547999143600464e-01 4.8560309410095215e-01 + <_> + + 0 -1 414 -2.3529380559921265e-02 + + 2.8382799029350281e-01 5.2560812234878540e-01 + <_> + + 0 -1 415 4.0857449173927307e-02 + + 4.8709350824356079e-01 6.2772971391677856e-01 + <_> + + 0 -1 416 -2.5406869128346443e-02 + + 7.0997077226638794e-01 4.5750290155410767e-01 + <_> + + 0 -1 417 -4.1415440500713885e-04 + + 4.0308868885040283e-01 5.4694122076034546e-01 + <_> + + 0 -1 418 2.1824119612574577e-02 + + 4.5020240545272827e-01 6.7687010765075684e-01 + <_> + + 0 -1 419 1.4114039950072765e-02 + + 5.4428607225418091e-01 3.7917000055313110e-01 + <_> + + 0 -1 420 6.7214590671937913e-05 + + 4.2004638910293579e-01 5.8734762668609619e-01 + <_> + + 0 -1 421 -7.9417638480663300e-03 + + 3.7925618886947632e-01 5.5852657556533813e-01 + <_> + + 0 -1 422 -7.2144409641623497e-03 + + 7.2531038522720337e-01 4.6035489439964294e-01 + <_> + + 0 -1 423 2.5817339774221182e-03 + + 4.6933019161224365e-01 5.9002387523651123e-01 + <_> + + 0 -1 424 1.3409319519996643e-01 + + 5.1492130756378174e-01 1.8088449537754059e-01 + <_> + + 0 -1 425 2.2962710354477167e-03 + + 5.3997439146041870e-01 3.7178671360015869e-01 + <_> + + 0 -1 426 -2.1575849968940020e-03 + + 2.4084959924221039e-01 5.1488637924194336e-01 + <_> + + 0 -1 427 -4.9196188338100910e-03 + + 6.5735882520675659e-01 4.7387400269508362e-01 + <_> + + 0 -1 428 1.6267469618469477e-03 + + 4.1928219795227051e-01 6.3031142950057983e-01 + <_> + + 0 -1 429 3.3413388882763684e-04 + + 5.5402982234954834e-01 3.7021011114120483e-01 + <_> + + 0 -1 430 -2.6698080822825432e-02 + + 1.7109179496765137e-01 5.1014107465744019e-01 + <_> + + 0 -1 431 -3.0561879277229309e-02 + + 1.9042180478572845e-01 5.1687937974929810e-01 + <_> + + 0 -1 432 2.8511548880487680e-03 + + 4.4475069642066956e-01 6.3138538599014282e-01 + <_> + + 0 -1 433 -3.6211479455232620e-02 + + 2.4907270073890686e-01 5.3773492574691772e-01 + <_> + + 0 -1 434 -2.4115189444273710e-03 + + 5.3812432289123535e-01 3.6642369627952576e-01 + <_> + + 0 -1 435 -7.7253201743587852e-04 + + 5.5302321910858154e-01 3.5415500402450562e-01 + <_> + + 0 -1 436 2.9481729143299162e-04 + + 4.1326990723609924e-01 5.6672430038452148e-01 + <_> + + 0 -1 437 -6.2334560789167881e-03 + + 9.8787233233451843e-02 5.1986688375473022e-01 + <_> + + 0 -1 438 -2.6274729520082474e-02 + + 9.1127492487430573e-02 5.0281071662902832e-01 + <_> + + 0 -1 439 5.3212260827422142e-03 + + 4.7266489267349243e-01 6.2227207422256470e-01 + <_> + + 0 -1 440 -4.1129058226943016e-03 + + 2.1574570238590240e-01 5.1378047466278076e-01 + <_> + + 0 -1 441 3.2457809429615736e-03 + + 5.4107707738876343e-01 3.7217769026756287e-01 + <_> + + 0 -1 442 -1.6359709203243256e-02 + + 7.7878749370574951e-01 4.6852919459342957e-01 + <_> + + 0 -1 443 3.2166109303943813e-04 + + 5.4789870977401733e-01 4.2403739690780640e-01 + <_> + + 0 -1 444 6.4452440710738301e-04 + + 5.3305608034133911e-01 3.5013249516487122e-01 + <_> + + 0 -1 445 -7.8909732401371002e-03 + + 6.9235211610794067e-01 4.7265690565109253e-01 + <_> + + 0 -1 446 4.8336211591959000e-02 + + 5.0559002161026001e-01 7.5749203562736511e-02 + <_> + + 0 -1 447 -7.5178127735853195e-04 + + 3.7837418913841248e-01 5.5385738611221313e-01 + <_> + + 0 -1 448 -2.4953910615295172e-03 + + 3.0816510319709778e-01 5.3596121072769165e-01 + <_> + + 0 -1 449 -2.2385010961443186e-03 + + 6.6339588165283203e-01 4.6493428945541382e-01 + <_> + + 0 -1 450 -1.7988430336117744e-03 + + 6.5968447923660278e-01 4.3471878767013550e-01 + <_> + + 0 -1 451 8.7860915809869766e-03 + + 5.2318328619003296e-01 2.3155799508094788e-01 + <_> + + 0 -1 452 3.6715380847454071e-03 + + 5.2042502164840698e-01 2.9773768782615662e-01 + <_> + + 0 -1 453 -3.5336449742317200e-02 + + 7.2388780117034912e-01 4.8615050315856934e-01 + <_> + + 0 -1 454 -6.9189240457490087e-04 + + 3.1050220131874084e-01 5.2298247814178467e-01 + <_> + + 0 -1 455 -3.3946109469980001e-03 + + 3.1389680504798889e-01 5.2101737260818481e-01 + <_> + + 0 -1 456 9.8569283727556467e-04 + + 4.5365801453590393e-01 6.5850979089736938e-01 + <_> + + 0 -1 457 -5.0163101404905319e-02 + + 1.8044540286064148e-01 5.1989167928695679e-01 + <_> + + 0 -1 458 -2.2367259953171015e-03 + + 7.2557020187377930e-01 4.6513590216636658e-01 + <_> + + 0 -1 459 7.4326287722215056e-04 + + 4.4129210710525513e-01 5.8985459804534912e-01 + <_> + + 0 -1 460 -9.3485182151198387e-04 + + 3.5000529885292053e-01 5.3660178184509277e-01 + <_> + + 0 -1 461 1.7497939988970757e-02 + + 4.9121949076652527e-01 8.3152848482131958e-01 + <_> + + 0 -1 462 -1.5200000489130616e-03 + + 3.5702759027481079e-01 5.3705602884292603e-01 + <_> + + 0 -1 463 7.8003940870985389e-04 + + 4.3537721037864685e-01 5.9673351049423218e-01 + <_> + 103 + 5.0610481262207031e+01 + + <_> + + 0 -1 464 -9.9945552647113800e-03 + + 6.1625832319259644e-01 3.0545330047607422e-01 + <_> + + 0 -1 465 -1.1085229925811291e-03 + + 5.8182948827743530e-01 3.1555780768394470e-01 + <_> + + 0 -1 466 1.0364380432292819e-03 + + 2.5520521402359009e-01 5.6929117441177368e-01 + <_> + + 0 -1 467 6.8211311008781195e-04 + + 3.6850899457931519e-01 5.9349310398101807e-01 + <_> + + 0 -1 468 -6.8057340104132891e-04 + + 2.3323920369148254e-01 5.4747921228408813e-01 + <_> + + 0 -1 469 2.6068789884448051e-04 + + 3.2574570178985596e-01 5.6675457954406738e-01 + <_> + + 0 -1 470 5.1607372006401420e-04 + + 3.7447169423103333e-01 5.8454728126525879e-01 + <_> + + 0 -1 471 8.5007521556690335e-04 + + 3.4203711152076721e-01 5.5228072404861450e-01 + <_> + + 0 -1 472 -1.8607829697430134e-03 + + 2.8044199943542480e-01 5.3754240274429321e-01 + <_> + + 0 -1 473 -1.5033970121294260e-03 + + 2.5790509581565857e-01 5.4989522695541382e-01 + <_> + + 0 -1 474 2.3478909861296415e-03 + + 4.1751560568809509e-01 6.3137108087539673e-01 + <_> + + 0 -1 475 -2.8880240279249847e-04 + + 5.8651697635650635e-01 4.0526661276817322e-01 + <_> + + 0 -1 476 8.9405477046966553e-03 + + 5.2111411094665527e-01 2.3186540603637695e-01 + <_> + + 0 -1 477 -1.9327739253640175e-02 + + 2.7534329891204834e-01 5.2415257692337036e-01 + <_> + + 0 -1 478 -2.0202060113660991e-04 + + 5.7229787111282349e-01 3.6771959066390991e-01 + <_> + + 0 -1 479 2.1179069299250841e-03 + + 4.4661080837249756e-01 5.5424308776855469e-01 + <_> + + 0 -1 480 -1.7743760254234076e-03 + + 2.8132531046867371e-01 5.3009599447250366e-01 + <_> + + 0 -1 481 4.2234458960592747e-03 + + 4.3997099995613098e-01 5.7954281568527222e-01 + <_> + + 0 -1 482 -1.4375220052897930e-02 + + 2.9811179637908936e-01 5.2920591831207275e-01 + <_> + + 0 -1 483 -1.5349180437624454e-02 + + 7.7052152156829834e-01 4.7481718659400940e-01 + <_> + + 0 -1 484 1.5152279956964776e-05 + + 3.7188440561294556e-01 5.5768972635269165e-01 + <_> + + 0 -1 485 -9.1293919831514359e-03 + + 3.6151960492134094e-01 5.2867668867111206e-01 + <_> + + 0 -1 486 2.2512159775942564e-03 + + 5.3647047281265259e-01 3.4862980246543884e-01 + <_> + + 0 -1 487 -4.9696918576955795e-03 + + 6.9276517629623413e-01 4.6768361330032349e-01 + <_> + + 0 -1 488 -1.2829010374844074e-02 + + 7.7121537923812866e-01 4.6607351303100586e-01 + <_> + + 0 -1 489 -9.3660065904259682e-03 + + 3.3749839663505554e-01 5.3512877225875854e-01 + <_> + + 0 -1 490 3.2452319283038378e-03 + + 5.3251898288726807e-01 3.2896101474761963e-01 + <_> + + 0 -1 491 -1.1723560281097889e-02 + + 6.8376529216766357e-01 4.7543001174926758e-01 + <_> + + 0 -1 492 2.9257940695970319e-05 + + 3.5720878839492798e-01 5.3605020046234131e-01 + <_> + + 0 -1 493 -2.2244219508138485e-05 + + 5.5414271354675293e-01 3.5520640015602112e-01 + <_> + + 0 -1 494 5.0881509669125080e-03 + + 5.0708442926406860e-01 1.2564620375633240e-01 + <_> + + 0 -1 495 2.7429679408669472e-02 + + 5.2695602178573608e-01 1.6258180141448975e-01 + <_> + + 0 -1 496 -6.4142867922782898e-03 + + 7.1455889940261841e-01 4.5841971039772034e-01 + <_> + + 0 -1 497 3.3479959238320589e-03 + + 5.3986120223999023e-01 3.4946969151496887e-01 + <_> + + 0 -1 498 -8.2635492086410522e-02 + + 2.4391929805278778e-01 5.1602262258529663e-01 + <_> + + 0 -1 499 1.0261740535497665e-03 + + 3.8868919014930725e-01 5.7679080963134766e-01 + <_> + + 0 -1 500 -1.6307090409100056e-03 + + 3.3894580602645874e-01 5.3477007150650024e-01 + <_> + + 0 -1 501 2.4546680506318808e-03 + + 4.6014139056205750e-01 6.3872468471527100e-01 + <_> + + 0 -1 502 -9.9476519972085953e-04 + + 5.7698792219161987e-01 4.1203960776329041e-01 + <_> + + 0 -1 503 1.5409190207719803e-02 + + 4.8787090182304382e-01 7.0898222923278809e-01 + <_> + + 0 -1 504 1.1784400558099151e-03 + + 5.2635532617568970e-01 2.8952449560165405e-01 + <_> + + 0 -1 505 -2.7701919898390770e-02 + + 1.4988289773464203e-01 5.2196067571640015e-01 + <_> + + 0 -1 506 -2.9505399987101555e-02 + + 2.4893319234251976e-02 4.9998161196708679e-01 + <_> + + 0 -1 507 4.5159430010244250e-04 + + 5.4646229743957520e-01 4.0296629071235657e-01 + <_> + + 0 -1 508 7.1772639639675617e-03 + + 4.2710569500923157e-01 5.8662968873977661e-01 + <_> + + 0 -1 509 -7.4182048439979553e-02 + + 6.8741792440414429e-01 4.9190279841423035e-01 + <_> + + 0 -1 510 -1.7254160717129707e-02 + + 3.3706760406494141e-01 5.3487390279769897e-01 + <_> + + 0 -1 511 1.4851559884846210e-02 + + 4.6267929673194885e-01 6.1299049854278564e-01 + <_> + + 0 -1 512 1.0002000257372856e-02 + + 5.3461229801177979e-01 3.4234538674354553e-01 + <_> + + 0 -1 513 2.0138120744377375e-03 + + 4.6438300609588623e-01 5.8243042230606079e-01 + <_> + + 0 -1 514 1.5135470312088728e-03 + + 5.1963961124420166e-01 2.8561499714851379e-01 + <_> + + 0 -1 515 3.1381431035697460e-03 + + 4.8381629586219788e-01 5.9585297107696533e-01 + <_> + + 0 -1 516 -5.1450440660119057e-03 + + 8.9203029870986938e-01 4.7414121031761169e-01 + <_> + + 0 -1 517 -4.4736708514392376e-03 + + 2.0339429378509521e-01 5.3372788429260254e-01 + <_> + + 0 -1 518 1.9628470763564110e-03 + + 4.5716339349746704e-01 6.7258632183074951e-01 + <_> + + 0 -1 519 5.4260450415313244e-03 + + 5.2711081504821777e-01 2.8456708788871765e-01 + <_> + + 0 -1 520 4.9611460417509079e-04 + + 4.1383129358291626e-01 5.7185977697372437e-01 + <_> + + 0 -1 521 9.3728788197040558e-03 + + 5.2251511812210083e-01 2.8048470616340637e-01 + <_> + + 0 -1 522 6.0500897234305739e-04 + + 5.2367687225341797e-01 3.3145239949226379e-01 + <_> + + 0 -1 523 5.6792551185935736e-04 + + 4.5310598611831665e-01 6.2769711017608643e-01 + <_> + + 0 -1 524 2.4644339457154274e-02 + + 5.1308518648147583e-01 2.0171439647674561e-01 + <_> + + 0 -1 525 -1.0290450416505337e-02 + + 7.7865952253341675e-01 4.8766410350799561e-01 + <_> + + 0 -1 526 2.0629419013857841e-03 + + 4.2885988950729370e-01 5.8812642097473145e-01 + <_> + + 0 -1 527 -5.0519481301307678e-03 + + 3.5239779949188232e-01 5.2860087156295776e-01 + <_> + + 0 -1 528 -5.7692620903253555e-03 + + 6.8410861492156982e-01 4.5880940556526184e-01 + <_> + + 0 -1 529 -4.5789941214025021e-04 + + 3.5655200481414795e-01 5.4859781265258789e-01 + <_> + + 0 -1 530 -7.5918837683275342e-04 + + 3.3687931299209595e-01 5.2541971206665039e-01 + <_> + + 0 -1 531 -1.7737259622663260e-03 + + 3.4221610426902771e-01 5.4540151357650757e-01 + <_> + + 0 -1 532 -8.5610467940568924e-03 + + 6.5336120128631592e-01 4.4858568906784058e-01 + <_> + + 0 -1 533 1.7277270089834929e-03 + + 5.3075802326202393e-01 3.9253529906272888e-01 + <_> + + 0 -1 534 -2.8199609369039536e-02 + + 6.8574589490890503e-01 4.5885840058326721e-01 + <_> + + 0 -1 535 -1.7781109781935811e-03 + + 4.0378510951995850e-01 5.3698569536209106e-01 + <_> + + 0 -1 536 3.3177141449414194e-04 + + 5.3997987508773804e-01 3.7057501077651978e-01 + <_> + + 0 -1 537 2.6385399978607893e-03 + + 4.6654370427131653e-01 6.4527308940887451e-01 + <_> + + 0 -1 538 -2.1183069329708815e-03 + + 5.9147810935974121e-01 4.0646770596504211e-01 + <_> + + 0 -1 539 -1.4773289673030376e-02 + + 3.6420381069183350e-01 5.2947628498077393e-01 + <_> + + 0 -1 540 -1.6815440729260445e-02 + + 2.6642319560050964e-01 5.1449728012084961e-01 + <_> + + 0 -1 541 -6.3370140269398689e-03 + + 6.7795312404632568e-01 4.8520979285240173e-01 + <_> + + 0 -1 542 -4.4560048991115764e-05 + + 5.6139647960662842e-01 4.1530540585517883e-01 + <_> + + 0 -1 543 -1.0240620467811823e-03 + + 5.9644782543182373e-01 4.5663040876388550e-01 + <_> + + 0 -1 544 -2.3161689750850201e-03 + + 2.9761150479316711e-01 5.1881599426269531e-01 + <_> + + 0 -1 545 5.3217571973800659e-01 + + 5.1878392696380615e-01 2.2026319801807404e-01 + <_> + + 0 -1 546 -1.6643050312995911e-01 + + 1.8660229444503784e-01 5.0603431463241577e-01 + <_> + + 0 -1 547 1.1253529787063599e-01 + + 5.2121251821517944e-01 1.1850229650735855e-01 + <_> + + 0 -1 548 9.3046864494681358e-03 + + 4.5899370312690735e-01 6.8261492252349854e-01 + <_> + + 0 -1 549 -4.6255099587142467e-03 + + 3.0799409747123718e-01 5.2250087261199951e-01 + <_> + + 0 -1 550 -1.1116469651460648e-01 + + 2.1010440587997437e-01 5.0808018445968628e-01 + <_> + + 0 -1 551 -1.0888439603149891e-02 + + 5.7653552293777466e-01 4.7904640436172485e-01 + <_> + + 0 -1 552 5.8564301580190659e-03 + + 5.0651001930236816e-01 1.5635989606380463e-01 + <_> + + 0 -1 553 5.4854389280080795e-02 + + 4.9669149518013000e-01 7.2305107116699219e-01 + <_> + + 0 -1 554 -1.1197339743375778e-02 + + 2.1949790418148041e-01 5.0987982749938965e-01 + <_> + + 0 -1 555 4.4069071300327778e-03 + + 4.7784018516540527e-01 6.7709028720855713e-01 + <_> + + 0 -1 556 -6.3665293157100677e-02 + + 1.9363629817962646e-01 5.0810241699218750e-01 + <_> + + 0 -1 557 -9.8081491887569427e-03 + + 5.9990632534027100e-01 4.8103410005569458e-01 + <_> + + 0 -1 558 -2.1717099007219076e-03 + + 3.3383339643478394e-01 5.2354729175567627e-01 + <_> + + 0 -1 559 -1.3315520249307156e-02 + + 6.6170698404312134e-01 4.9192130565643311e-01 + <_> + + 0 -1 560 2.5442079640924931e-03 + + 4.4887441396713257e-01 6.0821849107742310e-01 + <_> + + 0 -1 561 1.2037839740514755e-02 + + 5.4093921184539795e-01 3.2924321293830872e-01 + <_> + + 0 -1 562 -2.0701050758361816e-02 + + 6.8191200494766235e-01 4.5949959754943848e-01 + <_> + + 0 -1 563 2.7608279138803482e-02 + + 4.6307921409606934e-01 5.7672828435897827e-01 + <_> + + 0 -1 564 1.2370620388537645e-03 + + 5.1653790473937988e-01 2.6350161433219910e-01 + <_> + + 0 -1 565 -3.7669338285923004e-02 + + 2.5363931059837341e-01 5.2789801359176636e-01 + <_> + + 0 -1 566 -1.8057259730994701e-03 + + 3.9851561188697815e-01 5.5175000429153442e-01 + <_> + 111 + 5.4620071411132812e+01 + + <_> + + 0 -1 567 4.4299028813838959e-03 + + 2.8910180926322937e-01 6.3352262973785400e-01 + <_> + + 0 -1 568 -2.3813319858163595e-03 + + 6.2117892503738403e-01 3.4774878621101379e-01 + <_> + + 0 -1 569 2.2915711160749197e-03 + + 2.2544120252132416e-01 5.5821180343627930e-01 + <_> + + 0 -1 570 9.9457940086722374e-04 + + 3.7117108702659607e-01 5.9300708770751953e-01 + <_> + + 0 -1 571 7.7164667891338468e-04 + + 5.6517201662063599e-01 3.3479958772659302e-01 + <_> + + 0 -1 572 -1.1386410333216190e-03 + + 3.0691260099411011e-01 5.5086308717727661e-01 + <_> + + 0 -1 573 -1.6403039626311511e-04 + + 5.7628279924392700e-01 3.6990478634834290e-01 + <_> + + 0 -1 574 2.9793529392918572e-05 + + 2.6442441344261169e-01 5.4379111528396606e-01 + <_> + + 0 -1 575 8.5774902254343033e-03 + + 5.0511389970779419e-01 1.7957249283790588e-01 + <_> + + 0 -1 576 -2.6032689493149519e-04 + + 5.8269691467285156e-01 4.4468268752098083e-01 + <_> + + 0 -1 577 -6.1404630541801453e-03 + + 3.1138521432876587e-01 5.3469717502593994e-01 + <_> + + 0 -1 578 -2.3086950182914734e-02 + + 3.2779461145401001e-01 5.3311979770660400e-01 + <_> + + 0 -1 579 -1.4243650250136852e-02 + + 7.3817098140716553e-01 4.5880630612373352e-01 + <_> + + 0 -1 580 1.9487129524350166e-02 + + 5.2566307783126831e-01 2.2744719684123993e-01 + <_> + + 0 -1 581 -9.6681108698248863e-04 + + 5.5112308263778687e-01 3.8150069117546082e-01 + <_> + + 0 -1 582 3.1474709976464510e-03 + + 5.4256367683410645e-01 2.5437268614768982e-01 + <_> + + 0 -1 583 -1.8026070029009134e-04 + + 5.3801918029785156e-01 3.4063041210174561e-01 + <_> + + 0 -1 584 -6.0266260989010334e-03 + + 3.0358019471168518e-01 5.4205721616744995e-01 + <_> + + 0 -1 585 4.4462960795499384e-04 + + 3.9909970760345459e-01 5.6601101160049438e-01 + <_> + + 0 -1 586 2.2609760053455830e-03 + + 5.5628067255020142e-01 3.9406880736351013e-01 + <_> + + 0 -1 587 5.1133058965206146e-02 + + 4.6096539497375488e-01 7.1185618638992310e-01 + <_> + + 0 -1 588 -1.7786309123039246e-02 + + 2.3161660134792328e-01 5.3221440315246582e-01 + <_> + + 0 -1 589 -4.9679628573358059e-03 + + 2.3307719826698303e-01 5.1220291852951050e-01 + <_> + + 0 -1 590 2.0667689386755228e-03 + + 4.6574440598487854e-01 6.4554882049560547e-01 + <_> + + 0 -1 591 7.4413768015801907e-03 + + 5.1543921232223511e-01 2.3616339266300201e-01 + <_> + + 0 -1 592 -3.6277279723435640e-03 + + 6.2197732925415039e-01 4.4766610860824585e-01 + <_> + + 0 -1 593 -5.3530759178102016e-03 + + 1.8373550474643707e-01 5.1022082567214966e-01 + <_> + + 0 -1 594 1.4530919492244720e-01 + + 5.1459872722625732e-01 1.5359309315681458e-01 + <_> + + 0 -1 595 2.4394490756094456e-03 + + 5.3436601161956787e-01 3.6246618628501892e-01 + <_> + + 0 -1 596 -3.1283390708267689e-03 + + 6.2150079011917114e-01 4.8455920815467834e-01 + <_> + + 0 -1 597 1.7940260004252195e-03 + + 4.2992618680000305e-01 5.8241981267929077e-01 + <_> + + 0 -1 598 3.6253821104764938e-02 + + 5.2603340148925781e-01 1.4394679665565491e-01 + <_> + + 0 -1 599 -5.1746722310781479e-03 + + 3.5065388679504395e-01 5.2870452404022217e-01 + <_> + + 0 -1 600 6.5383297624066472e-04 + + 4.8096409440040588e-01 6.1220401525497437e-01 + <_> + + 0 -1 601 -2.6480229571461678e-02 + + 1.1393620073795319e-01 5.0455862283706665e-01 + <_> + + 0 -1 602 -3.0440660193562508e-03 + + 6.3520950078964233e-01 4.7947341203689575e-01 + <_> + + 0 -1 603 3.6993520334362984e-03 + + 5.1311182975769043e-01 2.4985109269618988e-01 + <_> + + 0 -1 604 -3.6762931267730892e-04 + + 5.4213947057723999e-01 3.7095320224761963e-01 + <_> + + 0 -1 605 -4.1382260620594025e-02 + + 1.8949599564075470e-01 5.0816917419433594e-01 + <_> + + 0 -1 606 -1.0532729793339968e-03 + + 6.4543670415878296e-01 4.7836089134216309e-01 + <_> + + 0 -1 607 -2.1648600231856108e-03 + + 6.2150311470031738e-01 4.4998261332511902e-01 + <_> + + 0 -1 608 -5.6747748749330640e-04 + + 3.7126109004020691e-01 5.4193347692489624e-01 + <_> + + 0 -1 609 1.7375840246677399e-01 + + 5.0236439704895020e-01 1.2157420068979263e-01 + <_> + + 0 -1 610 -2.9049699660390615e-03 + + 3.2402679324150085e-01 5.3818839788436890e-01 + <_> + + 0 -1 611 1.2299539521336555e-03 + + 4.1655078530311584e-01 5.7034862041473389e-01 + <_> + + 0 -1 612 -5.4329237900674343e-04 + + 3.8540428876876831e-01 5.5475491285324097e-01 + <_> + + 0 -1 613 -8.3297258242964745e-03 + + 2.2044940292835236e-01 5.0970828533172607e-01 + <_> + + 0 -1 614 -1.0417630255687982e-04 + + 5.6070661544799805e-01 4.3030360341072083e-01 + <_> + + 0 -1 615 3.1204700469970703e-02 + + 4.6216571331024170e-01 6.9820040464401245e-01 + <_> + + 0 -1 616 7.8943502157926559e-03 + + 5.2695941925048828e-01 2.2690680623054504e-01 + <_> + + 0 -1 617 -4.3645310215651989e-03 + + 6.3592231273651123e-01 4.5379561185836792e-01 + <_> + + 0 -1 618 7.6793059706687927e-03 + + 5.2747678756713867e-01 2.7404838800430298e-01 + <_> + + 0 -1 619 -2.5431139394640923e-02 + + 2.0385199785232544e-01 5.0717329978942871e-01 + <_> + + 0 -1 620 8.2000601105391979e-04 + + 4.5874550938606262e-01 6.1198681592941284e-01 + <_> + + 0 -1 621 2.9284600168466568e-03 + + 5.0712740421295166e-01 2.0282049477100372e-01 + <_> + + 0 -1 622 4.5256470912136137e-05 + + 4.8121041059494019e-01 5.4308217763900757e-01 + <_> + + 0 -1 623 1.3158309739083052e-03 + + 4.6258139610290527e-01 6.7793232202529907e-01 + <_> + + 0 -1 624 1.5870389761403203e-03 + + 5.3862917423248291e-01 3.4314650297164917e-01 + <_> + + 0 -1 625 -2.1539660170674324e-02 + + 2.5942500680685043e-02 5.0032228231430054e-01 + <_> + + 0 -1 626 1.4334480278193951e-02 + + 5.2028447389602661e-01 1.5906329452991486e-01 + <_> + + 0 -1 627 -8.3881383761763573e-03 + + 7.2824811935424805e-01 4.6480441093444824e-01 + <_> + + 0 -1 628 9.1906841844320297e-03 + + 5.5623567104339600e-01 3.9231911301612854e-01 + <_> + + 0 -1 629 -5.8453059755265713e-03 + + 6.8033927679061890e-01 4.6291279792785645e-01 + <_> + + 0 -1 630 -5.4707799106836319e-02 + + 2.5616711378097534e-01 5.2061259746551514e-01 + <_> + + 0 -1 631 9.1142775490880013e-03 + + 5.1896202564239502e-01 3.0538770556449890e-01 + <_> + + 0 -1 632 -1.5575000084936619e-02 + + 1.2950749695301056e-01 5.1690948009490967e-01 + <_> + + 0 -1 633 -1.2050600344082341e-04 + + 5.7350981235504150e-01 4.2308250069618225e-01 + <_> + + 0 -1 634 1.2273970060050488e-03 + + 5.2898782491683960e-01 4.0797919034957886e-01 + <_> + + 0 -1 635 -1.2186600361019373e-03 + + 6.5756398439407349e-01 4.5744091272354126e-01 + <_> + + 0 -1 636 -3.3256649039685726e-03 + + 3.6280471086502075e-01 5.1950198411941528e-01 + <_> + + 0 -1 637 -1.3288309797644615e-02 + + 1.2842659652233124e-01 5.0434887409210205e-01 + <_> + + 0 -1 638 -3.3839771058410406e-03 + + 6.2922400236129761e-01 4.7575059533119202e-01 + <_> + + 0 -1 639 -2.1954220533370972e-01 + + 1.4877319335937500e-01 5.0650137662887573e-01 + <_> + + 0 -1 640 4.9111708067357540e-03 + + 4.2561021447181702e-01 5.6658387184143066e-01 + <_> + + 0 -1 641 -1.8744950648397207e-04 + + 4.0041440725326538e-01 5.5868571996688843e-01 + <_> + + 0 -1 642 -5.2178641781210899e-03 + + 6.0091161727905273e-01 4.8127061128616333e-01 + <_> + + 0 -1 643 -1.1111519997939467e-03 + + 3.5149338841438293e-01 5.2870899438858032e-01 + <_> + + 0 -1 644 4.4036400504410267e-03 + + 4.6422758698463440e-01 5.9240859746932983e-01 + <_> + + 0 -1 645 1.2299499660730362e-01 + + 5.0255292654037476e-01 6.9152481853961945e-02 + <_> + + 0 -1 646 -1.2313510291278362e-02 + + 5.8845919370651245e-01 4.9340128898620605e-01 + <_> + + 0 -1 647 4.1471039876341820e-03 + + 4.3722391128540039e-01 5.8934777975082397e-01 + <_> + + 0 -1 648 -3.5502649843692780e-03 + + 4.3275511264801025e-01 5.3962701559066772e-01 + <_> + + 0 -1 649 -1.9224269315600395e-02 + + 1.9131340086460114e-01 5.0683307647705078e-01 + <_> + + 0 -1 650 1.4395059552043676e-03 + + 5.3081780672073364e-01 4.2435330152511597e-01 + <_> + + 0 -1 651 -6.7751999013125896e-03 + + 6.3653957843780518e-01 4.5400860905647278e-01 + <_> + + 0 -1 652 7.0119630545377731e-03 + + 5.1898342370986938e-01 3.0261999368667603e-01 + <_> + + 0 -1 653 5.4014651104807854e-03 + + 5.1050621271133423e-01 2.5576829910278320e-01 + <_> + + 0 -1 654 9.0274988906458020e-04 + + 4.6969148516654968e-01 5.8618277311325073e-01 + <_> + + 0 -1 655 1.1474450118839741e-02 + + 5.0536459684371948e-01 1.5271779894828796e-01 + <_> + + 0 -1 656 -6.7023430019617081e-03 + + 6.5089809894561768e-01 4.8906040191650391e-01 + <_> + + 0 -1 657 -2.0462959073483944e-03 + + 6.2418168783187866e-01 4.5146000385284424e-01 + <_> + + 0 -1 658 -9.9951568990945816e-03 + + 3.4327811002731323e-01 5.4009538888931274e-01 + <_> + + 0 -1 659 -3.5700708627700806e-02 + + 1.8780590593814850e-01 5.0740778446197510e-01 + <_> + + 0 -1 660 4.5584561303257942e-04 + + 3.8052770495414734e-01 5.4025697708129883e-01 + <_> + + 0 -1 661 -5.4260600358247757e-02 + + 6.8437147140502930e-01 4.5950970053672791e-01 + <_> + + 0 -1 662 6.0600461438298225e-03 + + 5.5029052495956421e-01 4.5005279779434204e-01 + <_> + + 0 -1 663 -6.4791832119226456e-03 + + 3.3688580989837646e-01 5.3107571601867676e-01 + <_> + + 0 -1 664 -1.4939469983801246e-03 + + 6.4876401424407959e-01 4.7561758756637573e-01 + <_> + + 0 -1 665 1.4610530342906713e-05 + + 4.0345790982246399e-01 5.4510641098022461e-01 + <_> + + 0 -1 666 -7.2321938350796700e-03 + + 6.3868737220764160e-01 4.8247399926185608e-01 + <_> + + 0 -1 667 -4.0645818226039410e-03 + + 2.9864218831062317e-01 5.1573359966278076e-01 + <_> + + 0 -1 668 3.0463080853223801e-02 + + 5.0221997499465942e-01 7.1599560976028442e-01 + <_> + + 0 -1 669 -8.0544911324977875e-03 + + 6.4924520254135132e-01 4.6192750334739685e-01 + <_> + + 0 -1 670 3.9505138993263245e-02 + + 5.1505708694458008e-01 2.4506139755249023e-01 + <_> + + 0 -1 671 8.4530208259820938e-03 + + 4.5736691355705261e-01 6.3940370082855225e-01 + <_> + + 0 -1 672 -1.1688120430335402e-03 + + 3.8655120134353638e-01 5.4836612939834595e-01 + <_> + + 0 -1 673 2.8070670086890459e-03 + + 5.1285791397094727e-01 2.7014800906181335e-01 + <_> + + 0 -1 674 4.7365209320560098e-04 + + 4.0515819191932678e-01 5.3874611854553223e-01 + <_> + + 0 -1 675 1.1741080321371555e-02 + + 5.2959501743316650e-01 3.7194138765335083e-01 + <_> + + 0 -1 676 3.1833238899707794e-03 + + 4.7894069552421570e-01 6.8951261043548584e-01 + <_> + + 0 -1 677 7.0241501089185476e-04 + + 5.3844892978668213e-01 3.9180809259414673e-01 + <_> + 102 + 5.0169731140136719e+01 + + <_> + + 0 -1 678 1.7059929668903351e-02 + + 3.9485278725624084e-01 7.1425348520278931e-01 + <_> + + 0 -1 679 2.1840840578079224e-02 + + 3.3703160285949707e-01 6.0900169610977173e-01 + <_> + + 0 -1 680 2.4520049919374287e-04 + + 3.5005760192871094e-01 5.9879022836685181e-01 + <_> + + 0 -1 681 8.3272606134414673e-03 + + 3.2675281167030334e-01 5.6972408294677734e-01 + <_> + + 0 -1 682 5.7148298947140574e-04 + + 3.0445998907089233e-01 5.5316567420959473e-01 + <_> + + 0 -1 683 6.7373987985774875e-04 + + 3.6500120162963867e-01 5.6726312637329102e-01 + <_> + + 0 -1 684 3.4681590477703139e-05 + + 3.3135411143302917e-01 5.3887271881103516e-01 + <_> + + 0 -1 685 -5.8563398197293282e-03 + + 2.6979428529739380e-01 5.4987788200378418e-01 + <_> + + 0 -1 686 8.5102273151278496e-03 + + 5.2693581581115723e-01 2.7628791332244873e-01 + <_> + + 0 -1 687 -6.9817207753658295e-02 + + 2.9096031188964844e-01 5.2592468261718750e-01 + <_> + + 0 -1 688 -8.6113670840859413e-04 + + 5.8925771713256836e-01 4.0736979246139526e-01 + <_> + + 0 -1 689 9.7149249631911516e-04 + + 3.5235640406608582e-01 5.4158622026443481e-01 + <_> + + 0 -1 690 -1.4727490452060010e-05 + + 5.4230177402496338e-01 3.5031560063362122e-01 + <_> + + 0 -1 691 4.8420291393995285e-02 + + 5.1939457654953003e-01 3.4111958742141724e-01 + <_> + + 0 -1 692 1.3257140526548028e-03 + + 3.1577691435813904e-01 5.3353762626647949e-01 + <_> + + 0 -1 693 1.4922149603080470e-05 + + 4.4512999057769775e-01 5.5365538597106934e-01 + <_> + + 0 -1 694 -2.7173398993909359e-03 + + 3.0317419767379761e-01 5.2480888366699219e-01 + <_> + + 0 -1 695 2.9219500720500946e-03 + + 4.7814530134201050e-01 6.6060417890548706e-01 + <_> + + 0 -1 696 -1.9804988987743855e-03 + + 3.1863081455230713e-01 5.2876251935958862e-01 + <_> + + 0 -1 697 -4.0012109093368053e-03 + + 6.4135968685150146e-01 4.7499281167984009e-01 + <_> + + 0 -1 698 -4.3491991236805916e-03 + + 1.5074980258941650e-01 5.0989967584609985e-01 + <_> + + 0 -1 699 1.3490889687091112e-03 + + 4.3161588907241821e-01 5.8811670541763306e-01 + <_> + + 0 -1 700 1.8597070127725601e-02 + + 4.7355538606643677e-01 9.0897941589355469e-01 + <_> + + 0 -1 701 -1.8562379991635680e-03 + + 3.5531890392303467e-01 5.5778372287750244e-01 + <_> + + 0 -1 702 2.2940430790185928e-03 + + 4.5000949501991272e-01 6.5808779001235962e-01 + <_> + + 0 -1 703 2.9982850537635386e-04 + + 5.6292420625686646e-01 3.9758789539337158e-01 + <_> + + 0 -1 704 3.5455459728837013e-03 + + 5.3815472126007080e-01 3.6054858565330505e-01 + <_> + + 0 -1 705 9.6104722470045090e-03 + + 5.2559971809387207e-01 1.7967459559440613e-01 + <_> + + 0 -1 706 -6.2783220782876015e-03 + + 2.2728569805622101e-01 5.1140302419662476e-01 + <_> + + 0 -1 707 3.4598479978740215e-03 + + 4.6263080835342407e-01 6.6082191467285156e-01 + <_> + + 0 -1 708 -1.3112019514665008e-03 + + 6.3175398111343384e-01 4.4368579983711243e-01 + <_> + + 0 -1 709 2.6876179035753012e-03 + + 5.4211097955703735e-01 4.0540221333503723e-01 + <_> + + 0 -1 710 3.9118169806897640e-03 + + 5.3584778308868408e-01 3.2734549045562744e-01 + <_> + + 0 -1 711 -1.4206450432538986e-02 + + 7.7935767173767090e-01 4.9757811427116394e-01 + <_> + + 0 -1 712 7.1705528534948826e-04 + + 5.2973198890686035e-01 3.5609039664268494e-01 + <_> + + 0 -1 713 1.6635019565001130e-03 + + 4.6780940890312195e-01 5.8164817094802856e-01 + <_> + + 0 -1 714 3.3686188980937004e-03 + + 5.2767342329025269e-01 3.4464201331138611e-01 + <_> + + 0 -1 715 1.2799530290067196e-02 + + 4.8346799612045288e-01 7.4721592664718628e-01 + <_> + + 0 -1 716 3.3901201095432043e-03 + + 4.5118591189384460e-01 6.4017212390899658e-01 + <_> + + 0 -1 717 4.7070779837667942e-03 + + 5.3356587886810303e-01 3.5552209615707397e-01 + <_> + + 0 -1 718 1.4819339849054813e-03 + + 4.2507070302963257e-01 5.7727241516113281e-01 + <_> + + 0 -1 719 -6.9995759986341000e-03 + + 3.0033200979232788e-01 5.2929002046585083e-01 + <_> + + 0 -1 720 1.5939010307192802e-02 + + 5.0673192739486694e-01 1.6755819320678711e-01 + <_> + + 0 -1 721 7.6377349905669689e-03 + + 4.7950699925422668e-01 7.0856010913848877e-01 + <_> + + 0 -1 722 6.7334040068089962e-03 + + 5.1331132650375366e-01 2.1624700725078583e-01 + <_> + + 0 -1 723 -1.2858809903264046e-02 + + 1.9388419389724731e-01 5.2513718605041504e-01 + <_> + + 0 -1 724 -6.2270800117403269e-04 + + 5.6865382194519043e-01 4.1978681087493896e-01 + <_> + + 0 -1 725 -5.2651681471616030e-04 + + 4.2241689562797546e-01 5.4296958446502686e-01 + <_> + + 0 -1 726 1.1075099930167198e-02 + + 5.1137751340866089e-01 2.5145179033279419e-01 + <_> + + 0 -1 727 -3.6728251725435257e-02 + + 7.1946620941162109e-01 4.8496189713478088e-01 + <_> + + 0 -1 728 -2.8207109426148236e-04 + + 3.8402619957923889e-01 5.3944462537765503e-01 + <_> + + 0 -1 729 -2.7489690110087395e-03 + + 5.9370887279510498e-01 4.5691820979118347e-01 + <_> + + 0 -1 730 1.0047519579529762e-02 + + 5.1385760307312012e-01 2.8022980690002441e-01 + <_> + + 0 -1 731 -8.1497840583324432e-03 + + 6.0900372266769409e-01 4.6361210942268372e-01 + <_> + + 0 -1 732 -6.8833888508379459e-03 + + 3.4586110711097717e-01 5.2546602487564087e-01 + <_> + + 0 -1 733 -1.4039360394235700e-05 + + 5.6931042671203613e-01 4.0820831060409546e-01 + <_> + + 0 -1 734 1.5498419525101781e-03 + + 4.3505370616912842e-01 5.8065170049667358e-01 + <_> + + 0 -1 735 -6.7841499112546444e-03 + + 1.4688730239868164e-01 5.1827752590179443e-01 + <_> + + 0 -1 736 2.1705629478674382e-04 + + 5.2935242652893066e-01 3.4561741352081299e-01 + <_> + + 0 -1 737 3.1198898795992136e-04 + + 4.6524509787559509e-01 5.9424138069152832e-01 + <_> + + 0 -1 738 5.4507530294358730e-03 + + 4.6535089612007141e-01 7.0248460769653320e-01 + <_> + + 0 -1 739 -2.5818689027801156e-04 + + 5.4972952604293823e-01 3.7689670920372009e-01 + <_> + + 0 -1 740 -1.7442539334297180e-02 + + 3.9190879464149475e-01 5.4574978351593018e-01 + <_> + + 0 -1 741 -4.5343529433012009e-02 + + 1.6313570737838745e-01 5.1549088954925537e-01 + <_> + + 0 -1 742 1.9190689781680703e-03 + + 5.1458978652954102e-01 2.7918958663940430e-01 + <_> + + 0 -1 743 -6.0177869163453579e-03 + + 6.5176361799240112e-01 4.7563329339027405e-01 + <_> + + 0 -1 744 -4.0720738470554352e-03 + + 5.5146527290344238e-01 4.0926858782768250e-01 + <_> + + 0 -1 745 3.9855059003457427e-04 + + 3.1652408838272095e-01 5.2855509519577026e-01 + <_> + + 0 -1 746 -6.5418570302426815e-03 + + 6.8533778190612793e-01 4.6528089046478271e-01 + <_> + + 0 -1 747 3.4845089539885521e-03 + + 5.4845881462097168e-01 4.5027598738670349e-01 + <_> + + 0 -1 748 -1.3696780428290367e-02 + + 6.3957798480987549e-01 4.5725551247596741e-01 + <_> + + 0 -1 749 -1.7347140237689018e-02 + + 2.7510729432106018e-01 5.1816147565841675e-01 + <_> + + 0 -1 750 -4.0885428898036480e-03 + + 3.3256360888481140e-01 5.1949840784072876e-01 + <_> + + 0 -1 751 -9.4687901437282562e-03 + + 5.9422808885574341e-01 4.8518198728561401e-01 + <_> + + 0 -1 752 1.7084840219467878e-03 + + 4.1671109199523926e-01 5.5198061466217041e-01 + <_> + + 0 -1 753 9.4809094443917274e-03 + + 5.4338949918746948e-01 4.2085149884223938e-01 + <_> + + 0 -1 754 -4.7389650717377663e-03 + + 6.4071899652481079e-01 4.5606550574302673e-01 + <_> + + 0 -1 755 6.5761050209403038e-03 + + 5.2145552635192871e-01 2.2582270205020905e-01 + <_> + + 0 -1 756 -2.1690549328923225e-03 + + 3.1515279412269592e-01 5.1567047834396362e-01 + <_> + + 0 -1 757 1.4660170301795006e-02 + + 4.8708370327949524e-01 6.6899412870407104e-01 + <_> + + 0 -1 758 1.7231999663636088e-04 + + 3.5697489976882935e-01 5.2510780096054077e-01 + <_> + + 0 -1 759 -2.1803760901093483e-02 + + 8.8259208202362061e-01 4.9663299322128296e-01 + <_> + + 0 -1 760 -9.4736106693744659e-02 + + 1.4461620151996613e-01 5.0611138343811035e-01 + <_> + + 0 -1 761 5.5825551971793175e-03 + + 5.3964787721633911e-01 4.2380660772323608e-01 + <_> + + 0 -1 762 1.9517090404406190e-03 + + 4.1704109311103821e-01 5.4977869987487793e-01 + <_> + + 0 -1 763 1.2149900197982788e-02 + + 4.6983671188354492e-01 5.6642740964889526e-01 + <_> + + 0 -1 764 -7.5169620104134083e-03 + + 6.2677729129791260e-01 4.4631358981132507e-01 + <_> + + 0 -1 765 -7.1667909622192383e-02 + + 3.0970111489295959e-01 5.2210032939910889e-01 + <_> + + 0 -1 766 -8.8292419910430908e-02 + + 8.1123888492584229e-02 5.0063651800155640e-01 + <_> + + 0 -1 767 3.1063079833984375e-02 + + 5.1555037498474121e-01 1.2822559475898743e-01 + <_> + + 0 -1 768 4.6621840447187424e-02 + + 4.6997779607772827e-01 7.3639607429504395e-01 + <_> + + 0 -1 769 -1.2189489789307117e-02 + + 3.9205300807952881e-01 5.5189967155456543e-01 + <_> + + 0 -1 770 1.3016110286116600e-02 + + 5.2606582641601562e-01 3.6851361393928528e-01 + <_> + + 0 -1 771 -3.4952899441123009e-03 + + 6.3392949104309082e-01 4.7162809967994690e-01 + <_> + + 0 -1 772 -4.4015039748046547e-05 + + 5.3330272436141968e-01 3.7761849164962769e-01 + <_> + + 0 -1 773 -1.0966490209102631e-01 + + 1.7653420567512512e-01 5.1983469724655151e-01 + <_> + + 0 -1 774 -9.0279558207839727e-04 + + 5.3241598606109619e-01 3.8389080762863159e-01 + <_> + + 0 -1 775 7.1126641705632210e-04 + + 4.6479299664497375e-01 5.7552242279052734e-01 + <_> + + 0 -1 776 -3.1250279862433672e-03 + + 3.2367089390754700e-01 5.1667708158493042e-01 + <_> + + 0 -1 777 2.4144679773598909e-03 + + 4.7874391078948975e-01 6.4597177505493164e-01 + <_> + + 0 -1 778 4.4391240226104856e-04 + + 4.4093081355094910e-01 6.0102558135986328e-01 + <_> + + 0 -1 779 -2.2611189342569560e-04 + + 4.0381139516830444e-01 5.4932558536529541e-01 + <_> + 135 + 6.6669120788574219e+01 + + <_> + + 0 -1 780 -4.6901289373636246e-02 + + 6.6001719236373901e-01 3.7438011169433594e-01 + <_> + + 0 -1 781 -1.4568349579349160e-03 + + 5.7839912176132202e-01 3.4377971291542053e-01 + <_> + + 0 -1 782 5.5598369799554348e-03 + + 3.6222669482231140e-01 5.9082162380218506e-01 + <_> + + 0 -1 783 7.3170487303286791e-04 + + 5.5004191398620605e-01 2.8735581040382385e-01 + <_> + + 0 -1 784 1.3318009441718459e-03 + + 2.6731699705123901e-01 5.4310190677642822e-01 + <_> + + 0 -1 785 2.4347059661522508e-04 + + 3.8550278544425964e-01 5.7413887977600098e-01 + <_> + + 0 -1 786 -3.0512469820678234e-03 + + 5.5032098293304443e-01 3.4628450870513916e-01 + <_> + + 0 -1 787 -6.8657199153676629e-04 + + 3.2912218570709229e-01 5.4295092821121216e-01 + <_> + + 0 -1 788 1.4668200165033340e-03 + + 3.5883820056915283e-01 5.3518110513687134e-01 + <_> + + 0 -1 789 3.2021870720200241e-04 + + 4.2968419194221497e-01 5.7002341747283936e-01 + <_> + + 0 -1 790 7.4122188379988074e-04 + + 5.2821648120880127e-01 3.3668708801269531e-01 + <_> + + 0 -1 791 3.8330298848450184e-03 + + 4.5595678687095642e-01 6.2573361396789551e-01 + <_> + + 0 -1 792 -1.5456439927220345e-02 + + 2.3501169681549072e-01 5.1294529438018799e-01 + <_> + + 0 -1 793 2.6796779129654169e-03 + + 5.3294152021408081e-01 4.1550621390342712e-01 + <_> + + 0 -1 794 2.8296569362282753e-03 + + 4.2730879783630371e-01 5.8045381307601929e-01 + <_> + + 0 -1 795 -3.9444249123334885e-03 + + 2.9126119613647461e-01 5.2026861906051636e-01 + <_> + + 0 -1 796 2.7179559692740440e-03 + + 5.3076881170272827e-01 3.5856771469116211e-01 + <_> + + 0 -1 797 5.9077627956867218e-03 + + 4.7037750482559204e-01 5.9415858983993530e-01 + <_> + + 0 -1 798 -4.2240349575877190e-03 + + 2.1415670216083527e-01 5.0887960195541382e-01 + <_> + + 0 -1 799 4.0725888684391975e-03 + + 4.7664138674736023e-01 6.8410611152648926e-01 + <_> + + 0 -1 800 1.0149530135095119e-02 + + 5.3607988357543945e-01 3.7484970688819885e-01 + <_> + + 0 -1 801 -1.8864999583456665e-04 + + 5.7201302051544189e-01 3.8538050651550293e-01 + <_> + + 0 -1 802 -4.8864358104765415e-03 + + 3.6931228637695312e-01 5.3409588336944580e-01 + <_> + + 0 -1 803 2.6158479973673820e-02 + + 4.9623748660087585e-01 6.0599899291992188e-01 + <_> + + 0 -1 804 4.8560759751126170e-04 + + 4.4389459490776062e-01 6.0124689340591431e-01 + <_> + + 0 -1 805 1.1268709786236286e-02 + + 5.2442502975463867e-01 1.8403880298137665e-01 + <_> + + 0 -1 806 -2.8114619199186563e-03 + + 6.0602837800979614e-01 4.4098970293998718e-01 + <_> + + 0 -1 807 -5.6112729944288731e-03 + + 3.8911709189414978e-01 5.5892372131347656e-01 + <_> + + 0 -1 808 8.5680093616247177e-03 + + 5.0693458318710327e-01 2.0626190304756165e-01 + <_> + + 0 -1 809 -3.8172779022715986e-04 + + 5.8822017908096313e-01 4.1926109790802002e-01 + <_> + + 0 -1 810 -1.7680290329735726e-04 + + 5.5336058139801025e-01 4.0033689141273499e-01 + <_> + + 0 -1 811 6.5112537704408169e-03 + + 3.3101469278335571e-01 5.4441910982131958e-01 + <_> + + 0 -1 812 -6.5948683186434209e-05 + + 5.4338318109512329e-01 3.9449059963226318e-01 + <_> + + 0 -1 813 6.9939051754772663e-03 + + 5.6003582477569580e-01 4.1927140951156616e-01 + <_> + + 0 -1 814 -4.6744439750909805e-03 + + 6.6854667663574219e-01 4.6049609780311584e-01 + <_> + + 0 -1 815 1.1589850299060345e-02 + + 5.3571212291717529e-01 2.9268300533294678e-01 + <_> + + 0 -1 816 1.3007840141654015e-02 + + 4.6798178553581238e-01 7.3074632883071899e-01 + <_> + + 0 -1 817 -1.1008579749614000e-03 + + 3.9375010132789612e-01 5.4150652885437012e-01 + <_> + + 0 -1 818 6.0472649056464434e-04 + + 4.2423760890960693e-01 5.6040412187576294e-01 + <_> + + 0 -1 819 -1.4494840055704117e-02 + + 3.6312100291252136e-01 5.2931827306747437e-01 + <_> + + 0 -1 820 -5.3056948818266392e-03 + + 6.8604522943496704e-01 4.6218210458755493e-01 + <_> + + 0 -1 821 -8.1829127157106996e-04 + + 3.9440968632698059e-01 5.4204392433166504e-01 + <_> + + 0 -1 822 -1.9077520817518234e-02 + + 1.9626219570636749e-01 5.0378918647766113e-01 + <_> + + 0 -1 823 3.5549470339901745e-04 + + 4.0862590074539185e-01 5.6139731407165527e-01 + <_> + + 0 -1 824 1.9679730758070946e-03 + + 4.4891211390495300e-01 5.9261232614517212e-01 + <_> + + 0 -1 825 6.9189141504466534e-03 + + 5.3359258174896240e-01 3.7283858656883240e-01 + <_> + + 0 -1 826 2.9872779268771410e-03 + + 5.1113212108612061e-01 2.9756438732147217e-01 + <_> + + 0 -1 827 -6.2264618463814259e-03 + + 5.5414897203445435e-01 4.8245379328727722e-01 + <_> + + 0 -1 828 1.3353300280869007e-02 + + 4.5864239335060120e-01 6.4147979021072388e-01 + <_> + + 0 -1 829 3.3505238592624664e-02 + + 5.3924250602722168e-01 3.4299948811531067e-01 + <_> + + 0 -1 830 -2.5294460356235504e-03 + + 1.7037139832973480e-01 5.0133150815963745e-01 + <_> + + 0 -1 831 -1.2801629491150379e-03 + + 5.3054618835449219e-01 4.6974050998687744e-01 + <_> + + 0 -1 832 7.0687388069927692e-03 + + 4.6155458688735962e-01 6.4365047216415405e-01 + <_> + + 0 -1 833 9.6880499040707946e-04 + + 4.8335990309715271e-01 6.0438942909240723e-01 + <_> + + 0 -1 834 3.9647659286856651e-03 + + 5.1876372098922729e-01 3.2318168878555298e-01 + <_> + + 0 -1 835 -2.2057730704545975e-02 + + 4.0792569518089294e-01 5.2009809017181396e-01 + <_> + + 0 -1 836 -6.6906312713399529e-04 + + 5.3316092491149902e-01 3.8156008720397949e-01 + <_> + + 0 -1 837 -6.7009328631684184e-04 + + 5.6554222106933594e-01 4.6889019012451172e-01 + <_> + + 0 -1 838 7.4284552829340100e-04 + + 4.5343810319900513e-01 6.2874001264572144e-01 + <_> + + 0 -1 839 2.2227810695767403e-03 + + 5.3506332635879517e-01 3.3036559820175171e-01 + <_> + + 0 -1 840 -5.4130521602928638e-03 + + 1.1136870086193085e-01 5.0054347515106201e-01 + <_> + + 0 -1 841 -1.4520040167553816e-05 + + 5.6287378072738647e-01 4.3251338601112366e-01 + <_> + + 0 -1 842 2.3369169502984732e-04 + + 4.1658350825309753e-01 5.4477912187576294e-01 + <_> + + 0 -1 843 4.2894547805190086e-03 + + 4.8603910207748413e-01 6.7786490917205811e-01 + <_> + + 0 -1 844 5.9103150852024555e-03 + + 5.2623051404953003e-01 3.6121138930320740e-01 + <_> + + 0 -1 845 1.2900539673864841e-02 + + 5.3193771839141846e-01 3.2502880692481995e-01 + <_> + + 0 -1 846 4.6982979401946068e-03 + + 4.6182450652122498e-01 6.6659259796142578e-01 + <_> + + 0 -1 847 1.0439859703183174e-02 + + 5.5056709051132202e-01 3.8836041092872620e-01 + <_> + + 0 -1 848 3.0443191062659025e-03 + + 4.6978530287742615e-01 7.3018449544906616e-01 + <_> + + 0 -1 849 -6.1593751888722181e-04 + + 3.8308390974998474e-01 5.4649841785430908e-01 + <_> + + 0 -1 850 -3.4247159492224455e-03 + + 2.5663000345230103e-01 5.0895309448242188e-01 + <_> + + 0 -1 851 -9.3538565561175346e-03 + + 6.4699661731719971e-01 4.9407958984375000e-01 + <_> + + 0 -1 852 5.2338998764753342e-02 + + 4.7459828853607178e-01 7.8787708282470703e-01 + <_> + + 0 -1 853 3.5765620414167643e-03 + + 5.3066647052764893e-01 2.7484980225563049e-01 + <_> + + 0 -1 854 7.1555317845195532e-04 + + 5.4131257534027100e-01 4.0419089794158936e-01 + <_> + + 0 -1 855 -1.0516679845750332e-02 + + 6.1585122346878052e-01 4.8152831196784973e-01 + <_> + + 0 -1 856 7.7347927726805210e-03 + + 4.6958059072494507e-01 7.0289808511734009e-01 + <_> + + 0 -1 857 -4.3226778507232666e-03 + + 2.8495660424232483e-01 5.3046840429306030e-01 + <_> + + 0 -1 858 -2.5534399319440126e-03 + + 7.0569849014282227e-01 4.6888920664787292e-01 + <_> + + 0 -1 859 1.0268510231981054e-04 + + 3.9029321074485779e-01 5.5734640359878540e-01 + <_> + + 0 -1 860 7.1395188570022583e-06 + + 3.6842319369316101e-01 5.2639877796173096e-01 + <_> + + 0 -1 861 -1.6711989883333445e-03 + + 3.8491758704185486e-01 5.3872710466384888e-01 + <_> + + 0 -1 862 4.9260449595749378e-03 + + 4.7297719120979309e-01 7.4472510814666748e-01 + <_> + + 0 -1 863 4.3908702209591866e-03 + + 4.8091810941696167e-01 5.5919218063354492e-01 + <_> + + 0 -1 864 -1.7793629318475723e-02 + + 6.9036781787872314e-01 4.6769270300865173e-01 + <_> + + 0 -1 865 2.0469669252634048e-03 + + 5.3706902265548706e-01 3.3081620931625366e-01 + <_> + + 0 -1 866 2.9891489073634148e-02 + + 5.1398652791976929e-01 3.3090591430664062e-01 + <_> + + 0 -1 867 1.5494900289922953e-03 + + 4.6602371335029602e-01 6.0783427953720093e-01 + <_> + + 0 -1 868 1.4956969534978271e-03 + + 4.4048359990119934e-01 5.8639198541641235e-01 + <_> + + 0 -1 869 9.5885928021743894e-04 + + 5.4359710216522217e-01 4.2085230350494385e-01 + <_> + + 0 -1 870 4.9643701640889049e-04 + + 5.3705781698226929e-01 4.0006220340728760e-01 + <_> + + 0 -1 871 -2.7280810754746199e-03 + + 5.6594127416610718e-01 4.2596429586410522e-01 + <_> + + 0 -1 872 2.3026480339467525e-03 + + 5.1616579294204712e-01 3.3508691191673279e-01 + <_> + + 0 -1 873 2.5151631236076355e-01 + + 4.8696619272232056e-01 7.1473097801208496e-01 + <_> + + 0 -1 874 -4.6328022144734859e-03 + + 2.7274489402770996e-01 5.0837898254394531e-01 + <_> + + 0 -1 875 -4.0434490889310837e-02 + + 6.8514388799667358e-01 5.0217670202255249e-01 + <_> + + 0 -1 876 1.4972220014897175e-05 + + 4.2844650149345398e-01 5.5225551128387451e-01 + <_> + + 0 -1 877 -2.4050309730228037e-04 + + 4.2261189222335815e-01 5.3900748491287231e-01 + <_> + + 0 -1 878 2.3657839745283127e-02 + + 4.7446319460868835e-01 7.5043660402297974e-01 + <_> + + 0 -1 879 -8.1449104472994804e-03 + + 4.2450588941574097e-01 5.5383628606796265e-01 + <_> + + 0 -1 880 -3.6992130335420370e-03 + + 5.9523570537567139e-01 4.5297130942344666e-01 + <_> + + 0 -1 881 -6.7718601785600185e-03 + + 4.1377940773963928e-01 5.4733997583389282e-01 + <_> + + 0 -1 882 4.2669530957937241e-03 + + 4.4841149449348450e-01 5.7979941368103027e-01 + <_> + + 0 -1 883 1.7791989957913756e-03 + + 5.6248587369918823e-01 4.4324448704719543e-01 + <_> + + 0 -1 884 1.6774770338088274e-03 + + 4.6377518773078918e-01 6.3642418384552002e-01 + <_> + + 0 -1 885 1.1732629500329494e-03 + + 4.5445030927658081e-01 5.9144157171249390e-01 + <_> + + 0 -1 886 8.6998171173036098e-04 + + 5.3347527980804443e-01 3.8859179615974426e-01 + <_> + + 0 -1 887 7.6378340600058436e-04 + + 5.3985852003097534e-01 3.7449419498443604e-01 + <_> + + 0 -1 888 1.5684569370932877e-04 + + 4.3178731203079224e-01 5.6146162748336792e-01 + <_> + + 0 -1 889 -2.1511370316147804e-02 + + 1.7859250307083130e-01 5.1855427026748657e-01 + <_> + + 0 -1 890 1.3081369979772717e-04 + + 4.3424990773200989e-01 5.6828498840332031e-01 + <_> + + 0 -1 891 2.1992040798068047e-02 + + 5.1617169380187988e-01 2.3793940246105194e-01 + <_> + + 0 -1 892 -8.0136500764638186e-04 + + 5.9867632389068604e-01 4.4664269685745239e-01 + <_> + + 0 -1 893 -8.2736099138855934e-03 + + 4.1082179546356201e-01 5.2510571479797363e-01 + <_> + + 0 -1 894 3.6831789184361696e-03 + + 5.1738142967224121e-01 3.3975180983543396e-01 + <_> + + 0 -1 895 -7.9525681212544441e-03 + + 6.8889832496643066e-01 4.8459240794181824e-01 + <_> + + 0 -1 896 1.5382299898192286e-03 + + 5.1785671710968018e-01 3.4541139006614685e-01 + <_> + + 0 -1 897 -1.4043530449271202e-02 + + 1.6784210503101349e-01 5.1886677742004395e-01 + <_> + + 0 -1 898 1.4315890148282051e-03 + + 4.3682569265365601e-01 5.6557738780975342e-01 + <_> + + 0 -1 899 -3.4014228731393814e-02 + + 7.8022962808609009e-01 4.9592170119285583e-01 + <_> + + 0 -1 900 -1.2027299962937832e-02 + + 1.5851010382175446e-01 5.0322318077087402e-01 + <_> + + 0 -1 901 1.3316619396209717e-01 + + 5.1633048057556152e-01 2.7551281452178955e-01 + <_> + + 0 -1 902 -1.5221949433907866e-03 + + 3.7283179163932800e-01 5.2145522832870483e-01 + <_> + + 0 -1 903 -9.3929271679371595e-04 + + 5.8383792638778687e-01 4.5111650228500366e-01 + <_> + + 0 -1 904 2.7719739824533463e-02 + + 4.7282868623733521e-01 7.3315447568893433e-01 + <_> + + 0 -1 905 3.1030150130391121e-03 + + 5.3022021055221558e-01 4.1015630960464478e-01 + <_> + + 0 -1 906 7.7861219644546509e-02 + + 4.9983340501785278e-01 1.2729619443416595e-01 + <_> + + 0 -1 907 -1.5854939818382263e-02 + + 5.0833359360694885e-02 5.1656562089920044e-01 + <_> + + 0 -1 908 -4.9725300632417202e-03 + + 6.7981338500976562e-01 4.6842318773269653e-01 + <_> + + 0 -1 909 -9.7676506265997887e-04 + + 6.0107719898223877e-01 4.7889319062232971e-01 + <_> + + 0 -1 910 -2.4647710379213095e-03 + + 3.3933979272842407e-01 5.2205038070678711e-01 + <_> + + 0 -1 911 -6.7937700077891350e-03 + + 4.3651369214057922e-01 5.2396631240844727e-01 + <_> + + 0 -1 912 3.2608021050691605e-02 + + 5.0527238845825195e-01 2.4252149462699890e-01 + <_> + + 0 -1 913 -5.8514421107247472e-04 + + 5.7339739799499512e-01 4.7585740685462952e-01 + <_> + + 0 -1 914 -2.9632600024342537e-02 + + 3.8922891020774841e-01 5.2635979652404785e-01 + <_> + 137 + 6.7698921203613281e+01 + + <_> + + 0 -1 915 4.6550851315259933e-02 + + 3.2769501209259033e-01 6.2405228614807129e-01 + <_> + + 0 -1 916 7.9537127166986465e-03 + + 4.2564851045608521e-01 6.9429391622543335e-01 + <_> + + 0 -1 917 6.8221561377868056e-04 + + 3.7114870548248291e-01 5.9007328748703003e-01 + <_> + + 0 -1 918 -1.9348249770700932e-04 + + 2.0411339402198792e-01 5.3005450963973999e-01 + <_> + + 0 -1 919 -2.6710508973337710e-04 + + 5.4161262512207031e-01 3.1031790375709534e-01 + <_> + + 0 -1 920 2.7818060480058193e-03 + + 5.2778327465057373e-01 3.4670698642730713e-01 + <_> + + 0 -1 921 -4.6779078547842801e-04 + + 5.3082311153411865e-01 3.2944920659065247e-01 + <_> + + 0 -1 922 -3.0335160772665404e-05 + + 5.7738727331161499e-01 3.8520970940589905e-01 + <_> + + 0 -1 923 7.8038009814918041e-04 + + 4.3174389004707336e-01 6.1500579118728638e-01 + <_> + + 0 -1 924 -4.2553851380944252e-03 + + 2.9339039325714111e-01 5.3242927789688110e-01 + <_> + + 0 -1 925 -2.4735610350035131e-04 + + 5.4688447713851929e-01 3.8430300354957581e-01 + <_> + + 0 -1 926 -1.4724259381182492e-04 + + 4.2815428972244263e-01 5.7555872201919556e-01 + <_> + + 0 -1 927 1.1864770203828812e-03 + + 3.7473011016845703e-01 5.4714661836624146e-01 + <_> + + 0 -1 928 2.3936580400913954e-03 + + 4.5377838611602783e-01 6.1115288734436035e-01 + <_> + + 0 -1 929 -1.5390539774671197e-03 + + 2.9713419079780579e-01 5.1895380020141602e-01 + <_> + + 0 -1 930 -7.1968790143728256e-03 + + 6.6990667581558228e-01 4.7264769673347473e-01 + <_> + + 0 -1 931 -4.1499789222143590e-04 + + 3.3849540352821350e-01 5.2603179216384888e-01 + <_> + + 0 -1 932 4.4359830208122730e-03 + + 5.3991222381591797e-01 3.9201408624649048e-01 + <_> + + 0 -1 933 2.6606200262904167e-03 + + 4.4825780391693115e-01 6.1196178197860718e-01 + <_> + + 0 -1 934 -1.5287200221791863e-03 + + 3.7112379074096680e-01 5.3402662277221680e-01 + <_> + + 0 -1 935 -4.7397250309586525e-03 + + 6.0310882329940796e-01 4.4551450014114380e-01 + <_> + + 0 -1 936 -1.4829129911959171e-02 + + 2.8387540578842163e-01 5.3418618440628052e-01 + <_> + + 0 -1 937 9.2275557108223438e-04 + + 5.2095472812652588e-01 3.3616539835929871e-01 + <_> + + 0 -1 938 8.3529807627201080e-02 + + 5.1199698448181152e-01 8.1164449453353882e-02 + <_> + + 0 -1 939 -7.5633148662745953e-04 + + 3.3171200752258301e-01 5.1898312568664551e-01 + <_> + + 0 -1 940 9.8403859883546829e-03 + + 5.2475982904434204e-01 2.3349590599536896e-01 + <_> + + 0 -1 941 -1.5953830443322659e-03 + + 5.7500940561294556e-01 4.2956221103668213e-01 + <_> + + 0 -1 942 3.4766020689858124e-05 + + 4.3424451351165771e-01 5.5640292167663574e-01 + <_> + + 0 -1 943 2.9862910509109497e-02 + + 4.5791471004486084e-01 6.5791881084442139e-01 + <_> + + 0 -1 944 1.1325590312480927e-02 + + 5.2743119001388550e-01 3.6738881468772888e-01 + <_> + + 0 -1 945 -8.7828645482659340e-03 + + 7.1003687381744385e-01 4.6421670913696289e-01 + <_> + + 0 -1 946 4.3639959767460823e-03 + + 5.2792161703109741e-01 2.7058771252632141e-01 + <_> + + 0 -1 947 4.1804728098213673e-03 + + 5.0725251436233521e-01 2.4490830302238464e-01 + <_> + + 0 -1 948 -4.5668511302210391e-04 + + 4.2831051349639893e-01 5.5486911535263062e-01 + <_> + + 0 -1 949 -3.7140368949621916e-03 + + 5.5193877220153809e-01 4.1036531329154968e-01 + <_> + + 0 -1 950 -2.5304289534687996e-02 + + 6.8670022487640381e-01 4.8698890209197998e-01 + <_> + + 0 -1 951 -3.4454080741852522e-04 + + 3.7288740277290344e-01 5.2876931428909302e-01 + <_> + + 0 -1 952 -8.3935231668874621e-04 + + 6.0601520538330078e-01 4.6160620450973511e-01 + <_> + + 0 -1 953 1.7280049622058868e-02 + + 5.0496357679367065e-01 1.8198239803314209e-01 + <_> + + 0 -1 954 -6.3595077954232693e-03 + + 1.6312399506568909e-01 5.2327787876129150e-01 + <_> + + 0 -1 955 1.0298109846189618e-03 + + 4.4632780551910400e-01 6.1765491962432861e-01 + <_> + + 0 -1 956 1.0117109632119536e-03 + + 5.4733848571777344e-01 4.3006989359855652e-01 + <_> + + 0 -1 957 -1.0308800265192986e-02 + + 1.1669850349426270e-01 5.0008672475814819e-01 + <_> + + 0 -1 958 5.4682018235325813e-03 + + 4.7692871093750000e-01 6.7192137241363525e-01 + <_> + + 0 -1 959 -9.1696460731327534e-04 + + 3.4710898995399475e-01 5.1781648397445679e-01 + <_> + + 0 -1 960 2.3922820109874010e-03 + + 4.7852361202239990e-01 6.2163108587265015e-01 + <_> + + 0 -1 961 -7.5573818758130074e-03 + + 5.8147960901260376e-01 4.4100850820541382e-01 + <_> + + 0 -1 962 -7.7024032361805439e-04 + + 3.8780000805854797e-01 5.4657220840454102e-01 + <_> + + 0 -1 963 -8.7125990539789200e-03 + + 1.6600510478019714e-01 4.9958360195159912e-01 + <_> + + 0 -1 964 -1.0306320153176785e-02 + + 4.0933910012245178e-01 5.2742338180541992e-01 + <_> + + 0 -1 965 -2.0940979011356831e-03 + + 6.2061947584152222e-01 4.5722800493240356e-01 + <_> + + 0 -1 966 6.8099051713943481e-03 + + 5.5677592754364014e-01 4.1556000709533691e-01 + <_> + + 0 -1 967 -1.0746059706434608e-03 + + 5.6389278173446655e-01 4.3530249595642090e-01 + <_> + + 0 -1 968 2.1550289820879698e-03 + + 4.8262658715248108e-01 6.7497581243515015e-01 + <_> + + 0 -1 969 3.1742319464683533e-02 + + 5.0483798980712891e-01 1.8832489848136902e-01 + <_> + + 0 -1 970 -7.8382723033428192e-02 + + 2.3695489764213562e-01 5.2601581811904907e-01 + <_> + + 0 -1 971 5.7415119372308254e-03 + + 5.0488287210464478e-01 2.7764698863029480e-01 + <_> + + 0 -1 972 -2.9014600440859795e-03 + + 6.2386047840118408e-01 4.6933171153068542e-01 + <_> + + 0 -1 973 -2.6427931152284145e-03 + + 3.3141419291496277e-01 5.1697772741317749e-01 + <_> + + 0 -1 974 -1.0949660092592239e-01 + + 2.3800450563430786e-01 5.1834410429000854e-01 + <_> + + 0 -1 975 7.4075913289561868e-05 + + 4.0696358680725098e-01 5.3621500730514526e-01 + <_> + + 0 -1 976 -5.0593802006915212e-04 + + 5.5067062377929688e-01 4.3745940923690796e-01 + <_> + + 0 -1 977 -8.2131777890026569e-04 + + 5.5257099866867065e-01 4.2093759775161743e-01 + <_> + + 0 -1 978 -6.0276539443293586e-05 + + 5.4554748535156250e-01 4.7482660412788391e-01 + <_> + + 0 -1 979 6.8065142259001732e-03 + + 5.1579958200454712e-01 3.4245771169662476e-01 + <_> + + 0 -1 980 1.7202789895236492e-03 + + 5.0132077932357788e-01 6.3312637805938721e-01 + <_> + + 0 -1 981 -1.3016929733566940e-04 + + 5.5397182703018188e-01 4.2268699407577515e-01 + <_> + + 0 -1 982 -4.8016388900578022e-03 + + 4.4250950217247009e-01 5.4307800531387329e-01 + <_> + + 0 -1 983 -2.5399310979992151e-03 + + 7.1457821130752563e-01 4.6976050734519958e-01 + <_> + + 0 -1 984 -1.4278929447755218e-03 + + 4.0704450011253357e-01 5.3996050357818604e-01 + <_> + + 0 -1 985 -2.5142550468444824e-02 + + 7.8846907615661621e-01 4.7473520040512085e-01 + <_> + + 0 -1 986 -3.8899609353393316e-03 + + 4.2961919307708740e-01 5.5771100521087646e-01 + <_> + + 0 -1 987 4.3947459198534489e-03 + + 4.6931621432304382e-01 7.0239442586898804e-01 + <_> + + 0 -1 988 2.4678420275449753e-02 + + 5.2423220872879028e-01 3.8125100731849670e-01 + <_> + + 0 -1 989 3.8047678768634796e-02 + + 5.0117397308349609e-01 1.6878280043601990e-01 + <_> + + 0 -1 990 7.9424865543842316e-03 + + 4.8285821080207825e-01 6.3695681095123291e-01 + <_> + + 0 -1 991 -1.5110049862414598e-03 + + 5.9064859151840210e-01 4.4876679778099060e-01 + <_> + + 0 -1 992 6.4201741479337215e-03 + + 5.2410978078842163e-01 2.9905700683593750e-01 + <_> + + 0 -1 993 -2.9802159406244755e-03 + + 3.0414658784866333e-01 5.0784897804260254e-01 + <_> + + 0 -1 994 -7.4580078944563866e-04 + + 4.1281390190124512e-01 5.2568262815475464e-01 + <_> + + 0 -1 995 -1.0470950044691563e-02 + + 5.8083951473236084e-01 4.4942960143089294e-01 + <_> + + 0 -1 996 9.3369204550981522e-03 + + 5.2465528249740601e-01 2.6589488983154297e-01 + <_> + + 0 -1 997 2.7936900034546852e-02 + + 4.6749550104141235e-01 7.0872569084167480e-01 + <_> + + 0 -1 998 7.4277678504586220e-03 + + 5.4094868898391724e-01 3.7585180997848511e-01 + <_> + + 0 -1 999 -2.3584509268403053e-02 + + 3.7586399912834167e-01 5.2385509014129639e-01 + <_> + + 0 -1 1000 1.1452640173956752e-03 + + 4.3295788764953613e-01 5.8042472600936890e-01 + <_> + + 0 -1 1001 -4.3468660442158580e-04 + + 5.2806180715560913e-01 3.8730698823928833e-01 + <_> + + 0 -1 1002 1.0648540221154690e-02 + + 4.9021130800247192e-01 5.6812518835067749e-01 + <_> + + 0 -1 1003 -3.9418050437234342e-04 + + 5.5708801746368408e-01 4.3182510137557983e-01 + <_> + + 0 -1 1004 -1.3270479394122958e-04 + + 5.6584399938583374e-01 4.3435549736022949e-01 + <_> + + 0 -1 1005 -2.0125510636717081e-03 + + 6.0567390918731689e-01 4.5375239849090576e-01 + <_> + + 0 -1 1006 2.4854319635778666e-03 + + 5.3904771804809570e-01 4.1380101442337036e-01 + <_> + + 0 -1 1007 1.8237880431115627e-03 + + 4.3548288941383362e-01 5.7171887159347534e-01 + <_> + + 0 -1 1008 -1.6656659543514252e-02 + + 3.0109131336212158e-01 5.2161228656768799e-01 + <_> + + 0 -1 1009 8.0349558265879750e-04 + + 5.3001511096954346e-01 3.8183969259262085e-01 + <_> + + 0 -1 1010 3.4170378930866718e-03 + + 5.3280287981033325e-01 4.2414000630378723e-01 + <_> + + 0 -1 1011 -3.6222729249857366e-04 + + 5.4917281866073608e-01 4.1869771480560303e-01 + <_> + + 0 -1 1012 -1.1630020290613174e-01 + + 1.4407220482826233e-01 5.2264511585235596e-01 + <_> + + 0 -1 1013 -1.4695010147988796e-02 + + 7.7477252483367920e-01 4.7157171368598938e-01 + <_> + + 0 -1 1014 2.1972130052745342e-03 + + 5.3554338216781616e-01 3.3156448602676392e-01 + <_> + + 0 -1 1015 -4.6965209185145795e-04 + + 5.7672351598739624e-01 4.4581368565559387e-01 + <_> + + 0 -1 1016 6.5144998952746391e-03 + + 5.2156740427017212e-01 3.6478888988494873e-01 + <_> + + 0 -1 1017 2.1300060674548149e-02 + + 4.9942049384117126e-01 1.5679509937763214e-01 + <_> + + 0 -1 1018 3.1881409231573343e-03 + + 4.7422000765800476e-01 6.2872701883316040e-01 + <_> + + 0 -1 1019 9.0019777417182922e-04 + + 5.3479540348052979e-01 3.9437520503997803e-01 + <_> + + 0 -1 1020 -5.1772277802228928e-03 + + 6.7271918058395386e-01 5.0131380558013916e-01 + <_> + + 0 -1 1021 -4.3764649890363216e-03 + + 3.1066751480102539e-01 5.1287931203842163e-01 + <_> + + 0 -1 1022 2.6299960445612669e-03 + + 4.8863101005554199e-01 5.7552158832550049e-01 + <_> + + 0 -1 1023 -2.0458688959479332e-03 + + 6.0257941484451294e-01 4.5580768585205078e-01 + <_> + + 0 -1 1024 6.9482706487178802e-02 + + 5.2407479286193848e-01 2.1852590143680573e-01 + <_> + + 0 -1 1025 2.4048939347267151e-02 + + 5.0118672847747803e-01 2.0906220376491547e-01 + <_> + + 0 -1 1026 3.1095340382307768e-03 + + 4.8667120933532715e-01 7.1085482835769653e-01 + <_> + + 0 -1 1027 -1.2503260513767600e-03 + + 3.4078910946846008e-01 5.1561951637268066e-01 + <_> + + 0 -1 1028 -1.0281190043315291e-03 + + 5.5755722522735596e-01 4.4394320249557495e-01 + <_> + + 0 -1 1029 -8.8893622159957886e-03 + + 6.4020007848739624e-01 4.6204420924186707e-01 + <_> + + 0 -1 1030 -6.1094801640138030e-04 + + 3.7664419412612915e-01 5.4488998651504517e-01 + <_> + + 0 -1 1031 -5.7686357758939266e-03 + + 3.3186489343643188e-01 5.1336771249771118e-01 + <_> + + 0 -1 1032 1.8506490159779787e-03 + + 4.9035701155662537e-01 6.4069348573684692e-01 + <_> + + 0 -1 1033 -9.9799469113349915e-02 + + 1.5360510349273682e-01 5.0155621767044067e-01 + <_> + + 0 -1 1034 -3.5128349065780640e-01 + + 5.8823131024837494e-02 5.1743787527084351e-01 + <_> + + 0 -1 1035 -4.5244570821523666e-02 + + 6.9614887237548828e-01 4.6778729557991028e-01 + <_> + + 0 -1 1036 7.1481578052043915e-02 + + 5.1679861545562744e-01 1.0380929708480835e-01 + <_> + + 0 -1 1037 2.1895780228078365e-03 + + 4.2730781435966492e-01 5.5320608615875244e-01 + <_> + + 0 -1 1038 -5.9242651332169771e-04 + + 4.6389439702033997e-01 5.2763891220092773e-01 + <_> + + 0 -1 1039 1.6788389766588807e-03 + + 5.3016489744186401e-01 3.9320349693298340e-01 + <_> + + 0 -1 1040 -2.2163488902151585e-03 + + 5.6306940317153931e-01 4.7570338845252991e-01 + <_> + + 0 -1 1041 1.1568699846975505e-04 + + 4.3075358867645264e-01 5.5357027053833008e-01 + <_> + + 0 -1 1042 -7.2017288766801357e-03 + + 1.4448820054531097e-01 5.1930642127990723e-01 + <_> + + 0 -1 1043 8.9081272017210722e-04 + + 4.3844321370124817e-01 5.5936211347579956e-01 + <_> + + 0 -1 1044 1.9605009583756328e-04 + + 5.3404158353805542e-01 4.7059568762779236e-01 + <_> + + 0 -1 1045 5.2022142335772514e-04 + + 5.2138561010360718e-01 3.8100790977478027e-01 + <_> + + 0 -1 1046 9.4588572392240167e-04 + + 4.7694149613380432e-01 6.1307388544082642e-01 + <_> + + 0 -1 1047 9.1698471806012094e-05 + + 4.2450091242790222e-01 5.4293632507324219e-01 + <_> + + 0 -1 1048 2.1833200007677078e-03 + + 5.4577308893203735e-01 4.1910758614540100e-01 + <_> + + 0 -1 1049 -8.6039671441540122e-04 + + 5.7645887136459351e-01 4.4716599583625793e-01 + <_> + + 0 -1 1050 -1.3236239552497864e-02 + + 6.3728231191635132e-01 4.6950098872184753e-01 + <_> + + 0 -1 1051 4.3376701069064438e-04 + + 5.3178739547729492e-01 3.9458298683166504e-01 + <_> + 140 + 6.9229873657226562e+01 + + <_> + + 0 -1 1052 -2.4847149848937988e-02 + + 6.5555167198181152e-01 3.8733118772506714e-01 + <_> + + 0 -1 1053 6.1348611488938332e-03 + + 3.7480720877647400e-01 5.9739977121353149e-01 + <_> + + 0 -1 1054 6.4498498104512691e-03 + + 5.4254919290542603e-01 2.5488111376762390e-01 + <_> + + 0 -1 1055 6.3491211039945483e-04 + + 2.4624420702457428e-01 5.3872537612915039e-01 + <_> + + 0 -1 1056 1.4023890253156424e-03 + + 5.5943220853805542e-01 3.5286578536033630e-01 + <_> + + 0 -1 1057 3.0044000595808029e-04 + + 3.9585039019584656e-01 5.7659381628036499e-01 + <_> + + 0 -1 1058 1.0042409849120304e-04 + + 3.6989969015121460e-01 5.5349981784820557e-01 + <_> + + 0 -1 1059 -5.0841490738093853e-03 + + 3.7110909819602966e-01 5.5478000640869141e-01 + <_> + + 0 -1 1060 -1.9537260755896568e-02 + + 7.4927550554275513e-01 4.5792970061302185e-01 + <_> + + 0 -1 1061 -7.4532740654831287e-06 + + 5.6497871875762939e-01 3.9040699601173401e-01 + <_> + + 0 -1 1062 -3.6079459823668003e-03 + + 3.3810880780220032e-01 5.2678012847900391e-01 + <_> + + 0 -1 1063 2.0697501022368670e-03 + + 5.5192911624908447e-01 3.7143889069557190e-01 + <_> + + 0 -1 1064 -4.6463840408250690e-04 + + 5.6082147359848022e-01 4.1135668754577637e-01 + <_> + + 0 -1 1065 7.5490452582016587e-04 + + 3.5592061281204224e-01 5.3293561935424805e-01 + <_> + + 0 -1 1066 -9.8322238773107529e-04 + + 5.4147958755493164e-01 3.7632051110267639e-01 + <_> + + 0 -1 1067 -1.9940640777349472e-02 + + 6.3479030132293701e-01 4.7052991390228271e-01 + <_> + + 0 -1 1068 3.7680300883948803e-03 + + 3.9134898781776428e-01 5.5637162923812866e-01 + <_> + + 0 -1 1069 -9.4528505578637123e-03 + + 2.5548928976058960e-01 5.2151167392730713e-01 + <_> + + 0 -1 1070 2.9560849070549011e-03 + + 5.1746791601181030e-01 3.0639201402664185e-01 + <_> + + 0 -1 1071 9.1078737750649452e-03 + + 5.3884482383728027e-01 2.8859630227088928e-01 + <_> + + 0 -1 1072 1.8219229532405734e-03 + + 4.3360430002212524e-01 5.8521968126296997e-01 + <_> + + 0 -1 1073 1.4688739553093910e-02 + + 5.2873617410659790e-01 2.8700059652328491e-01 + <_> + + 0 -1 1074 -1.4387990348041058e-02 + + 7.0194488763809204e-01 4.6473708748817444e-01 + <_> + + 0 -1 1075 -1.8986649811267853e-02 + + 2.9865521192550659e-01 5.2470117807388306e-01 + <_> + + 0 -1 1076 1.1527639580890536e-03 + + 4.3234738707542419e-01 5.9316617250442505e-01 + <_> + + 0 -1 1077 1.0933670215308666e-02 + + 5.2868640422821045e-01 3.1303191184997559e-01 + <_> + + 0 -1 1078 -1.4932730235159397e-02 + + 2.6584190130233765e-01 5.0840771198272705e-01 + <_> + + 0 -1 1079 -2.9970539617352188e-04 + + 5.4635268449783325e-01 3.7407240271568298e-01 + <_> + + 0 -1 1080 4.1677621193230152e-03 + + 4.7034969925880432e-01 7.4357217550277710e-01 + <_> + + 0 -1 1081 -6.3905320130288601e-03 + + 2.0692589879035950e-01 5.2805382013320923e-01 + <_> + + 0 -1 1082 4.5029609464108944e-03 + + 5.1826488971710205e-01 3.4835430979728699e-01 + <_> + + 0 -1 1083 -9.2040365561842918e-03 + + 6.8037772178649902e-01 4.9323600530624390e-01 + <_> + + 0 -1 1084 8.1327259540557861e-02 + + 5.0583988428115845e-01 2.2530519962310791e-01 + <_> + + 0 -1 1085 -1.5079280734062195e-01 + + 2.9634249210357666e-01 5.2646797895431519e-01 + <_> + + 0 -1 1086 3.3179009333252907e-03 + + 4.6554958820343018e-01 7.0729321241378784e-01 + <_> + + 0 -1 1087 7.7402801252901554e-04 + + 4.7803479433059692e-01 5.6682378053665161e-01 + <_> + + 0 -1 1088 6.8199541419744492e-04 + + 4.2869961261749268e-01 5.7221567630767822e-01 + <_> + + 0 -1 1089 5.3671570494771004e-03 + + 5.2993071079254150e-01 3.1146219372749329e-01 + <_> + + 0 -1 1090 9.7018666565418243e-05 + + 3.6746388673782349e-01 5.2694618701934814e-01 + <_> + + 0 -1 1091 -1.2534089386463165e-01 + + 2.3514920473098755e-01 5.2457910776138306e-01 + <_> + + 0 -1 1092 -5.2516269497573376e-03 + + 7.1159368753433228e-01 4.6937671303749084e-01 + <_> + + 0 -1 1093 -7.8342109918594360e-03 + + 4.4626510143280029e-01 5.4090857505798340e-01 + <_> + + 0 -1 1094 -1.1310069821774960e-03 + + 5.9456187486648560e-01 4.4176620244979858e-01 + <_> + + 0 -1 1095 1.7601120052859187e-03 + + 5.3532499074935913e-01 3.9734530448913574e-01 + <_> + + 0 -1 1096 -8.1581249833106995e-04 + + 3.7602680921554565e-01 5.2647268772125244e-01 + <_> + + 0 -1 1097 -3.8687589112669230e-03 + + 6.3099128007888794e-01 4.7498199343681335e-01 + <_> + + 0 -1 1098 1.5207129763439298e-03 + + 5.2301818132400513e-01 3.3612239360809326e-01 + <_> + + 0 -1 1099 5.4586738348007202e-01 + + 5.1671397686004639e-01 1.1726350337266922e-01 + <_> + + 0 -1 1100 1.5650190412998199e-02 + + 4.9794390797615051e-01 1.3932949304580688e-01 + <_> + + 0 -1 1101 -1.1731860227882862e-02 + + 7.1296507120132446e-01 4.9211961030960083e-01 + <_> + + 0 -1 1102 -6.1765122227370739e-03 + + 2.2881029546260834e-01 5.0497019290924072e-01 + <_> + + 0 -1 1103 2.2457661107182503e-03 + + 4.6324339509010315e-01 6.0487258434295654e-01 + <_> + + 0 -1 1104 -5.1915869116783142e-03 + + 6.4674210548400879e-01 4.6021929383277893e-01 + <_> + + 0 -1 1105 -2.3827880620956421e-02 + + 1.4820009469985962e-01 5.2260792255401611e-01 + <_> + + 0 -1 1106 1.0284580057486892e-03 + + 5.1354891061782837e-01 3.3759570121765137e-01 + <_> + + 0 -1 1107 -1.0078850202262402e-02 + + 2.7405610680580139e-01 5.3035670518875122e-01 + <_> + + 0 -1 1108 2.6168930344283581e-03 + + 5.3326708078384399e-01 3.9724540710449219e-01 + <_> + + 0 -1 1109 5.4385367548093200e-04 + + 5.3656041622161865e-01 4.0634119510650635e-01 + <_> + + 0 -1 1110 5.3510512225329876e-03 + + 4.6537590026855469e-01 6.8890458345413208e-01 + <_> + + 0 -1 1111 -1.5274790348485112e-03 + + 5.4495012760162354e-01 3.6247238516807556e-01 + <_> + + 0 -1 1112 -8.0624416470527649e-02 + + 1.6560870409011841e-01 5.0002872943878174e-01 + <_> + + 0 -1 1113 2.2192029282450676e-02 + + 5.1327311992645264e-01 2.0028080046176910e-01 + <_> + + 0 -1 1114 7.3100631125271320e-03 + + 4.6179479360580444e-01 6.3665360212326050e-01 + <_> + + 0 -1 1115 -6.4063072204589844e-03 + + 5.9162509441375732e-01 4.8678609728813171e-01 + <_> + + 0 -1 1116 -7.6415040530264378e-04 + + 3.8884091377258301e-01 5.3157979249954224e-01 + <_> + + 0 -1 1117 7.6734489994123578e-04 + + 4.1590648889541626e-01 5.6052798032760620e-01 + <_> + + 0 -1 1118 6.1474501853808761e-04 + + 3.0890220403671265e-01 5.1201480627059937e-01 + <_> + + 0 -1 1119 -5.0105270929634571e-03 + + 3.9721998572349548e-01 5.2073061466217041e-01 + <_> + + 0 -1 1120 -8.6909132078289986e-03 + + 6.2574082612991333e-01 4.6085759997367859e-01 + <_> + + 0 -1 1121 -1.6391459852457047e-02 + + 2.0852099359035492e-01 5.2422660589218140e-01 + <_> + + 0 -1 1122 4.0973909199237823e-04 + + 5.2224272489547729e-01 3.7803208827972412e-01 + <_> + + 0 -1 1123 -2.5242289993911982e-03 + + 5.8039271831512451e-01 4.6118900179862976e-01 + <_> + + 0 -1 1124 5.0945312250405550e-04 + + 4.4012719392776489e-01 5.8460158109664917e-01 + <_> + + 0 -1 1125 1.9656419754028320e-03 + + 5.3223252296447754e-01 4.1845908761024475e-01 + <_> + + 0 -1 1126 5.6298897834494710e-04 + + 3.7418448925018311e-01 5.2345657348632812e-01 + <_> + + 0 -1 1127 -6.7946797935292125e-04 + + 4.6310418844223022e-01 5.3564780950546265e-01 + <_> + + 0 -1 1128 7.2856349870562553e-03 + + 5.0446701049804688e-01 2.3775640130043030e-01 + <_> + + 0 -1 1129 -1.7459489405155182e-02 + + 7.2891211509704590e-01 5.0504350662231445e-01 + <_> + + 0 -1 1130 -2.5421749800443649e-02 + + 6.6671347618103027e-01 4.6781000494956970e-01 + <_> + + 0 -1 1131 -1.5647639520466328e-03 + + 4.3917590379714966e-01 5.3236269950866699e-01 + <_> + + 0 -1 1132 1.1444360017776489e-02 + + 4.3464401364326477e-01 5.6800121068954468e-01 + <_> + + 0 -1 1133 -6.7352550104260445e-04 + + 4.4771409034729004e-01 5.2968120574951172e-01 + <_> + + 0 -1 1134 9.3194209039211273e-03 + + 4.7402000427246094e-01 7.4626070261001587e-01 + <_> + + 0 -1 1135 1.3328490604180843e-04 + + 5.3650617599487305e-01 4.7521349787712097e-01 + <_> + + 0 -1 1136 -7.8815799206495285e-03 + + 1.7522190511226654e-01 5.0152552127838135e-01 + <_> + + 0 -1 1137 -5.7985680177807808e-03 + + 7.2712367773056030e-01 4.8962008953094482e-01 + <_> + + 0 -1 1138 -3.8922499516047537e-04 + + 4.0039089322090149e-01 5.3449410200119019e-01 + <_> + + 0 -1 1139 -1.9288610201328993e-03 + + 5.6056129932403564e-01 4.8039558529853821e-01 + <_> + + 0 -1 1140 8.4214154630899429e-03 + + 4.7532469034194946e-01 7.6236087083816528e-01 + <_> + + 0 -1 1141 8.1655876711010933e-03 + + 5.3932619094848633e-01 4.1916438937187195e-01 + <_> + + 0 -1 1142 4.8280550981871784e-04 + + 4.2408001422882080e-01 5.3998219966888428e-01 + <_> + + 0 -1 1143 -2.7186630759388208e-03 + + 4.2445999383926392e-01 5.4249238967895508e-01 + <_> + + 0 -1 1144 -1.2507230043411255e-02 + + 5.8958417177200317e-01 4.5504111051559448e-01 + <_> + + 0 -1 1145 -2.4286519736051559e-02 + + 2.6471349596977234e-01 5.1891797780990601e-01 + <_> + + 0 -1 1146 -2.9676330741494894e-03 + + 7.3476827144622803e-01 4.7497498989105225e-01 + <_> + + 0 -1 1147 -1.2528999708592892e-02 + + 2.7560499310493469e-01 5.1775997877120972e-01 + <_> + + 0 -1 1148 -1.0104000102728605e-03 + + 3.5105609893798828e-01 5.1447242498397827e-01 + <_> + + 0 -1 1149 -2.1348530426621437e-03 + + 5.6379258632659912e-01 4.6673199534416199e-01 + <_> + + 0 -1 1150 1.9564259797334671e-02 + + 4.6145731210708618e-01 6.1376398801803589e-01 + <_> + + 0 -1 1151 -9.7146347165107727e-02 + + 2.9983788728713989e-01 5.1935559511184692e-01 + <_> + + 0 -1 1152 4.5014568604528904e-03 + + 5.0778847932815552e-01 3.0457559227943420e-01 + <_> + + 0 -1 1153 6.3706971704959869e-03 + + 4.8610189557075500e-01 6.8875008821487427e-01 + <_> + + 0 -1 1154 -9.0721528977155685e-03 + + 1.6733959317207336e-01 5.0175631046295166e-01 + <_> + + 0 -1 1155 -5.3537208586931229e-03 + + 2.6927569508552551e-01 5.2426332235336304e-01 + <_> + + 0 -1 1156 -1.0932840406894684e-02 + + 7.1838641166687012e-01 4.7360289096832275e-01 + <_> + + 0 -1 1157 8.2356072962284088e-03 + + 5.2239668369293213e-01 2.3898629844188690e-01 + <_> + + 0 -1 1158 -1.0038160253316164e-03 + + 5.7193559408187866e-01 4.4339430332183838e-01 + <_> + + 0 -1 1159 4.0859128348529339e-03 + + 5.4728418588638306e-01 4.1488361358642578e-01 + <_> + + 0 -1 1160 1.5485419332981110e-01 + + 4.9738121032714844e-01 6.1061598360538483e-02 + <_> + + 0 -1 1161 2.0897459762636572e-04 + + 4.7091740369796753e-01 5.4238891601562500e-01 + <_> + + 0 -1 1162 3.3316991175524890e-04 + + 4.0896269679069519e-01 5.3009921312332153e-01 + <_> + + 0 -1 1163 -1.0813400149345398e-02 + + 6.1043697595596313e-01 4.9573341012001038e-01 + <_> + + 0 -1 1164 4.5656010508537292e-02 + + 5.0696891546249390e-01 2.8666600584983826e-01 + <_> + + 0 -1 1165 1.2569549726322293e-03 + + 4.8469170928001404e-01 6.3181710243225098e-01 + <_> + + 0 -1 1166 -1.2015070021152496e-01 + + 6.0526140034198761e-02 4.9809598922729492e-01 + <_> + + 0 -1 1167 -1.0533799650147557e-04 + + 5.3631097078323364e-01 4.7080421447753906e-01 + <_> + + 0 -1 1168 -2.0703190565109253e-01 + + 5.9660330414772034e-02 4.9790981411933899e-01 + <_> + + 0 -1 1169 1.2909180077258497e-04 + + 4.7129771113395691e-01 5.3779977560043335e-01 + <_> + + 0 -1 1170 3.8818528992123902e-04 + + 4.3635380268096924e-01 5.5341911315917969e-01 + <_> + + 0 -1 1171 -2.9243610333651304e-03 + + 5.8111858367919922e-01 4.8252159357070923e-01 + <_> + + 0 -1 1172 8.3882332546636462e-04 + + 5.3117001056671143e-01 4.0381389856338501e-01 + <_> + + 0 -1 1173 -1.9061550265178084e-03 + + 3.7707018852233887e-01 5.2600151300430298e-01 + <_> + + 0 -1 1174 8.9514348655939102e-03 + + 4.7661679983139038e-01 7.6821839809417725e-01 + <_> + + 0 -1 1175 1.3083459809422493e-02 + + 5.2644628286361694e-01 3.0622220039367676e-01 + <_> + + 0 -1 1176 -2.1159330010414124e-01 + + 6.7371982336044312e-01 4.6958100795745850e-01 + <_> + + 0 -1 1177 3.1493250280618668e-03 + + 5.6448352336883545e-01 4.3869531154632568e-01 + <_> + + 0 -1 1178 3.9754100725986063e-04 + + 4.5260611176490784e-01 5.8956301212310791e-01 + <_> + + 0 -1 1179 -1.3814480043947697e-03 + + 6.0705822706222534e-01 4.9424138665199280e-01 + <_> + + 0 -1 1180 -5.8122188784182072e-04 + + 5.9982132911682129e-01 4.5082521438598633e-01 + <_> + + 0 -1 1181 -2.3905329871922731e-03 + + 4.2055889964103699e-01 5.2238482236862183e-01 + <_> + + 0 -1 1182 2.7268929407000542e-02 + + 5.2064472436904907e-01 3.5633018612861633e-01 + <_> + + 0 -1 1183 -3.7658358924090862e-03 + + 3.1447041034698486e-01 5.2188140153884888e-01 + <_> + + 0 -1 1184 -1.4903489500284195e-03 + + 3.3801960945129395e-01 5.1244372129440308e-01 + <_> + + 0 -1 1185 -1.7428230494260788e-02 + + 5.8299607038497925e-01 4.9197259545326233e-01 + <_> + + 0 -1 1186 -1.5278030186891556e-02 + + 6.1631447076797485e-01 4.6178871393203735e-01 + <_> + + 0 -1 1187 3.1995609402656555e-02 + + 5.1663571596145630e-01 1.7127640545368195e-01 + <_> + + 0 -1 1188 -3.8256710395216942e-03 + + 3.4080120921134949e-01 5.1313877105712891e-01 + <_> + + 0 -1 1189 -8.5186436772346497e-03 + + 6.1055189371109009e-01 4.9979418516159058e-01 + <_> + + 0 -1 1190 9.0641621500253677e-04 + + 4.3272709846496582e-01 5.5823111534118652e-01 + <_> + + 0 -1 1191 1.0344849899411201e-02 + + 4.8556530475616455e-01 5.4524201154708862e-01 + <_> + 160 + 7.9249076843261719e+01 + + <_> + + 0 -1 1192 7.8981826081871986e-03 + + 3.3325248956680298e-01 5.9464621543884277e-01 + <_> + + 0 -1 1193 1.6170160379260778e-03 + + 3.4906411170959473e-01 5.5778688192367554e-01 + <_> + + 0 -1 1194 -5.5449741194024682e-04 + + 5.5425661802291870e-01 3.2915300130844116e-01 + <_> + + 0 -1 1195 1.5428980113938451e-03 + + 3.6125791072845459e-01 5.5459791421890259e-01 + <_> + + 0 -1 1196 -1.0329450014978647e-03 + + 3.5301390290260315e-01 5.5761402845382690e-01 + <_> + + 0 -1 1197 7.7698158565908670e-04 + + 3.9167788624763489e-01 5.6453210115432739e-01 + <_> + + 0 -1 1198 1.4320300519466400e-01 + + 4.6674820780754089e-01 7.0236331224441528e-01 + <_> + + 0 -1 1199 -7.3866490274667740e-03 + + 3.0736848711967468e-01 5.2892577648162842e-01 + <_> + + 0 -1 1200 -6.2936742324382067e-04 + + 5.6221181154251099e-01 4.0370491147041321e-01 + <_> + + 0 -1 1201 7.8893528552725911e-04 + + 5.2676612138748169e-01 3.5578748583793640e-01 + <_> + + 0 -1 1202 -1.2228050269186497e-02 + + 6.6683208942413330e-01 4.6255499124526978e-01 + <_> + + 0 -1 1203 3.5420239437371492e-03 + + 5.5214381217956543e-01 3.8696730136871338e-01 + <_> + + 0 -1 1204 -1.0585320414975286e-03 + + 3.6286780238151550e-01 5.3209269046783447e-01 + <_> + + 0 -1 1205 1.4935660146875307e-05 + + 4.6324449777603149e-01 5.3633230924606323e-01 + <_> + + 0 -1 1206 5.2537708543241024e-03 + + 5.1322317123413086e-01 3.2657089829444885e-01 + <_> + + 0 -1 1207 -8.2338023930788040e-03 + + 6.6936898231506348e-01 4.7741401195526123e-01 + <_> + + 0 -1 1208 2.1866810129722580e-05 + + 4.0538620948791504e-01 5.4579311609268188e-01 + <_> + + 0 -1 1209 -3.8150229956954718e-03 + + 6.4549958705902100e-01 4.7931781411170959e-01 + <_> + + 0 -1 1210 1.1105879675596952e-03 + + 5.2704071998596191e-01 3.5296788811683655e-01 + <_> + + 0 -1 1211 -5.7707689702510834e-03 + + 3.8035470247268677e-01 5.3529578447341919e-01 + <_> + + 0 -1 1212 -3.0158339068293571e-03 + + 5.3394031524658203e-01 3.8871330022811890e-01 + <_> + + 0 -1 1213 -8.5453689098358154e-04 + + 3.5646161437034607e-01 5.2736037969589233e-01 + <_> + + 0 -1 1214 1.1050510220229626e-02 + + 4.6719071269035339e-01 6.8497377634048462e-01 + <_> + + 0 -1 1215 4.2605839669704437e-02 + + 5.1514732837677002e-01 7.0220090448856354e-02 + <_> + + 0 -1 1216 -3.0781750101596117e-03 + + 3.0416610836982727e-01 5.1526021957397461e-01 + <_> + + 0 -1 1217 -5.4815728217363358e-03 + + 6.4302957057952881e-01 4.8972299695014954e-01 + <_> + + 0 -1 1218 3.1881860923022032e-03 + + 5.3074932098388672e-01 3.8262099027633667e-01 + <_> + + 0 -1 1219 3.5947180003859103e-04 + + 4.6500471234321594e-01 5.4219049215316772e-01 + <_> + + 0 -1 1220 -4.0705031715333462e-03 + + 2.8496798872947693e-01 5.0791162252426147e-01 + <_> + + 0 -1 1221 -1.4594170264899731e-02 + + 2.9716458916664124e-01 5.1284617185592651e-01 + <_> + + 0 -1 1222 -1.1947689927183092e-04 + + 5.6310981512069702e-01 4.3430820107460022e-01 + <_> + + 0 -1 1223 -6.9344649091362953e-04 + + 4.4035780429840088e-01 5.3599590063095093e-01 + <_> + + 0 -1 1224 1.4834799912932795e-05 + + 3.4210088849067688e-01 5.1646977663040161e-01 + <_> + + 0 -1 1225 9.0296985581517220e-03 + + 4.6393430233001709e-01 6.1140751838684082e-01 + <_> + + 0 -1 1226 -8.0640818923711777e-03 + + 2.8201588988304138e-01 5.0754940509796143e-01 + <_> + + 0 -1 1227 2.6062119752168655e-02 + + 5.2089059352874756e-01 2.6887780427932739e-01 + <_> + + 0 -1 1228 1.7314659431576729e-02 + + 4.6637138724327087e-01 6.7385399341583252e-01 + <_> + + 0 -1 1229 2.2666640579700470e-02 + + 5.2093499898910522e-01 2.2127239406108856e-01 + <_> + + 0 -1 1230 -2.1965929772704840e-03 + + 6.0631012916564941e-01 4.5381900668144226e-01 + <_> + + 0 -1 1231 -9.5282476395368576e-03 + + 4.6352049708366394e-01 5.2474308013916016e-01 + <_> + + 0 -1 1232 8.0943619832396507e-03 + + 5.2894401550292969e-01 3.9138820767402649e-01 + <_> + + 0 -1 1233 -7.2877332568168640e-02 + + 7.7520018815994263e-01 4.9902349710464478e-01 + <_> + + 0 -1 1234 -6.9009521976113319e-03 + + 2.4280390143394470e-01 5.0480902194976807e-01 + <_> + + 0 -1 1235 -1.1308239772915840e-02 + + 5.7343649864196777e-01 4.8423761129379272e-01 + <_> + + 0 -1 1236 5.9613201767206192e-02 + + 5.0298362970352173e-01 2.5249770283699036e-01 + <_> + + 0 -1 1237 -2.8624620754271746e-03 + + 6.0730451345443726e-01 4.8984599113464355e-01 + <_> + + 0 -1 1238 4.4781449250876904e-03 + + 5.0152891874313354e-01 2.2203169763088226e-01 + <_> + + 0 -1 1239 -1.7513240454718471e-03 + + 6.6144287586212158e-01 4.9338689446449280e-01 + <_> + + 0 -1 1240 4.0163420140743256e-02 + + 5.1808780431747437e-01 3.7410449981689453e-01 + <_> + + 0 -1 1241 3.4768949262797832e-04 + + 4.7204169631004333e-01 5.8180320262908936e-01 + <_> + + 0 -1 1242 2.6551650371402502e-03 + + 3.8050109148025513e-01 5.2213358879089355e-01 + <_> + + 0 -1 1243 -8.7706279009580612e-03 + + 2.9441660642623901e-01 5.2312952280044556e-01 + <_> + + 0 -1 1244 -5.5122091434895992e-03 + + 7.3461771011352539e-01 4.7228169441223145e-01 + <_> + + 0 -1 1245 6.8672042107209563e-04 + + 5.4528760910034180e-01 4.2424130439758301e-01 + <_> + + 0 -1 1246 5.6019669864326715e-04 + + 4.3988621234893799e-01 5.6012850999832153e-01 + <_> + + 0 -1 1247 2.4143769405782223e-03 + + 4.7416868805885315e-01 6.1366218328475952e-01 + <_> + + 0 -1 1248 -1.5680900542065501e-03 + + 6.0445529222488403e-01 4.5164099335670471e-01 + <_> + + 0 -1 1249 -3.6827491130679846e-03 + + 2.4524590373039246e-01 5.2949821949005127e-01 + <_> + + 0 -1 1250 -2.9409190756268799e-04 + + 3.7328380346298218e-01 5.2514511346817017e-01 + <_> + + 0 -1 1251 4.2847759323194623e-04 + + 5.4988098144531250e-01 4.0655350685119629e-01 + <_> + + 0 -1 1252 -4.8817070201039314e-03 + + 2.1399089694023132e-01 4.9999570846557617e-01 + <_> + + 0 -1 1253 2.7272020815871656e-04 + + 4.6502870321273804e-01 5.8134287595748901e-01 + <_> + + 0 -1 1254 2.0947199664078653e-04 + + 4.3874868750572205e-01 5.5727928876876831e-01 + <_> + + 0 -1 1255 4.8501189798116684e-02 + + 5.2449727058410645e-01 3.2128891348838806e-01 + <_> + + 0 -1 1256 -4.5166411437094212e-03 + + 6.0568130016326904e-01 4.5458820462226868e-01 + <_> + + 0 -1 1257 -1.2291680090129375e-02 + + 2.0409290492534637e-01 5.1522141695022583e-01 + <_> + + 0 -1 1258 4.8549679922871292e-04 + + 5.2376049757003784e-01 3.7395030260086060e-01 + <_> + + 0 -1 1259 3.0556049197912216e-02 + + 4.9605339765548706e-01 5.9382462501525879e-01 + <_> + + 0 -1 1260 -1.5105320198927075e-04 + + 5.3513038158416748e-01 4.1452041268348694e-01 + <_> + + 0 -1 1261 2.4937440175563097e-03 + + 4.6933668851852417e-01 5.5149412155151367e-01 + <_> + + 0 -1 1262 -1.2382130138576031e-02 + + 6.7913967370986938e-01 4.6816679835319519e-01 + <_> + + 0 -1 1263 -5.1333461888134480e-03 + + 3.6087390780448914e-01 5.2291601896286011e-01 + <_> + + 0 -1 1264 5.1919277757406235e-04 + + 5.3000730276107788e-01 3.6336138844490051e-01 + <_> + + 0 -1 1265 1.5060420334339142e-01 + + 5.1573169231414795e-01 2.2117820382118225e-01 + <_> + + 0 -1 1266 7.7144149690866470e-03 + + 4.4104969501495361e-01 5.7766091823577881e-01 + <_> + + 0 -1 1267 9.4443522393703461e-03 + + 5.4018551111221313e-01 3.7566500902175903e-01 + <_> + + 0 -1 1268 2.5006249779835343e-04 + + 4.3682709336280823e-01 5.6073749065399170e-01 + <_> + + 0 -1 1269 -3.3077150583267212e-03 + + 4.2447990179061890e-01 5.5182307958602905e-01 + <_> + + 0 -1 1270 7.4048910755664110e-04 + + 4.4969621300697327e-01 5.9005767107009888e-01 + <_> + + 0 -1 1271 4.4092051684856415e-02 + + 5.2934932708740234e-01 3.1563550233840942e-01 + <_> + + 0 -1 1272 3.3639909233897924e-03 + + 4.4832968711853027e-01 5.8486622571945190e-01 + <_> + + 0 -1 1273 -3.9760079234838486e-03 + + 4.5595070719718933e-01 5.4836392402648926e-01 + <_> + + 0 -1 1274 2.7716930489987135e-03 + + 5.3417861461639404e-01 3.7924841046333313e-01 + <_> + + 0 -1 1275 -2.4123019829858094e-04 + + 5.6671887636184692e-01 4.5769730210304260e-01 + <_> + + 0 -1 1276 4.9425667384639382e-04 + + 4.4212448596954346e-01 5.6287872791290283e-01 + <_> + + 0 -1 1277 -3.8876468897797167e-04 + + 4.2883709073066711e-01 5.3910630941390991e-01 + <_> + + 0 -1 1278 -5.0048898905515671e-02 + + 6.8995130062103271e-01 4.7037428617477417e-01 + <_> + + 0 -1 1279 -3.6635480821132660e-02 + + 2.2177790105342865e-01 5.1918262243270874e-01 + <_> + + 0 -1 1280 2.4273579474538565e-03 + + 5.1362240314483643e-01 3.4973978996276855e-01 + <_> + + 0 -1 1281 1.9558030180633068e-03 + + 4.8261928558349609e-01 6.4083808660507202e-01 + <_> + + 0 -1 1282 -1.7494610510766506e-03 + + 3.9228358864784241e-01 5.2726852893829346e-01 + <_> + + 0 -1 1283 1.3955079950392246e-02 + + 5.0782018899917603e-01 8.4165048599243164e-01 + <_> + + 0 -1 1284 -2.1896739781368524e-04 + + 5.5204898118972778e-01 4.3142348527908325e-01 + <_> + + 0 -1 1285 -1.5131309628486633e-03 + + 3.9346051216125488e-01 5.3825712203979492e-01 + <_> + + 0 -1 1286 -4.3622800149023533e-03 + + 7.3706287145614624e-01 4.7364759445190430e-01 + <_> + + 0 -1 1287 6.5160587430000305e-02 + + 5.1592797040939331e-01 3.2815951108932495e-01 + <_> + + 0 -1 1288 -2.3567399475723505e-03 + + 3.6728268861770630e-01 5.1728862524032593e-01 + <_> + + 0 -1 1289 1.5146659687161446e-02 + + 5.0314939022064209e-01 6.6876041889190674e-01 + <_> + + 0 -1 1290 -2.2850960493087769e-02 + + 6.7675197124481201e-01 4.7095969319343567e-01 + <_> + + 0 -1 1291 4.8867650330066681e-03 + + 5.2579981088638306e-01 4.0598788857460022e-01 + <_> + + 0 -1 1292 1.7619599821045995e-03 + + 4.6962729096412659e-01 6.6882789134979248e-01 + <_> + + 0 -1 1293 -1.2942519970238209e-03 + + 4.3207129836082458e-01 5.3442817926406860e-01 + <_> + + 0 -1 1294 1.0929949581623077e-02 + + 4.9977061152458191e-01 1.6374860703945160e-01 + <_> + + 0 -1 1295 2.9958489903947338e-05 + + 4.2824178934097290e-01 5.6332242488861084e-01 + <_> + + 0 -1 1296 -6.5884361974895000e-03 + + 6.7721211910247803e-01 4.7005268931388855e-01 + <_> + + 0 -1 1297 3.2527779694646597e-03 + + 5.3133970499038696e-01 4.5361489057540894e-01 + <_> + + 0 -1 1298 -4.0435739792883396e-03 + + 5.6600618362426758e-01 4.4133889675140381e-01 + <_> + + 0 -1 1299 -1.2523540062829852e-03 + + 3.7319138646125793e-01 5.3564518690109253e-01 + <_> + + 0 -1 1300 1.9246719602961093e-04 + + 5.1899862289428711e-01 3.7388110160827637e-01 + <_> + + 0 -1 1301 -3.8589671254158020e-02 + + 2.9563739895820618e-01 5.1888108253479004e-01 + <_> + + 0 -1 1302 1.5489870565943420e-04 + + 4.3471351265907288e-01 5.5095332860946655e-01 + <_> + + 0 -1 1303 -3.3763848245143890e-02 + + 3.2303300499916077e-01 5.1954758167266846e-01 + <_> + + 0 -1 1304 -8.2657067105174065e-03 + + 5.9754890203475952e-01 4.5521140098571777e-01 + <_> + + 0 -1 1305 1.4481440302915871e-05 + + 4.7456780076026917e-01 5.4974269866943359e-01 + <_> + + 0 -1 1306 1.4951299817766994e-05 + + 4.3244731426239014e-01 5.4806441068649292e-01 + <_> + + 0 -1 1307 -1.8741799518465996e-02 + + 1.5800529718399048e-01 5.1785331964492798e-01 + <_> + + 0 -1 1308 1.7572239739820361e-03 + + 4.5176368951797485e-01 5.7737642526626587e-01 + <_> + + 0 -1 1309 -3.1391119118779898e-03 + + 4.1496479511260986e-01 5.4608422517776489e-01 + <_> + + 0 -1 1310 6.6656779381446540e-05 + + 4.0390908718109131e-01 5.2930849790573120e-01 + <_> + + 0 -1 1311 6.7743421532213688e-03 + + 4.7676518559455872e-01 6.1219561100006104e-01 + <_> + + 0 -1 1312 -7.3868161998689175e-03 + + 3.5862588882446289e-01 5.1872807741165161e-01 + <_> + + 0 -1 1313 1.4040930196642876e-02 + + 4.7121399641036987e-01 5.5761557817459106e-01 + <_> + + 0 -1 1314 -5.5258329957723618e-03 + + 2.6610270142555237e-01 5.0392812490463257e-01 + <_> + + 0 -1 1315 3.8684239983558655e-01 + + 5.1443397998809814e-01 2.5258991122245789e-01 + <_> + + 0 -1 1316 1.1459240340627730e-04 + + 4.2849949002265930e-01 5.4233711957931519e-01 + <_> + + 0 -1 1317 -1.8467569723725319e-02 + + 3.8858351111412048e-01 5.2130621671676636e-01 + <_> + + 0 -1 1318 -4.5907011372037232e-04 + + 5.4125630855560303e-01 4.2359098792076111e-01 + <_> + + 0 -1 1319 1.2527540093287826e-03 + + 4.8993051052093506e-01 6.6240912675857544e-01 + <_> + + 0 -1 1320 1.4910609461367130e-03 + + 5.2867782115936279e-01 4.0400519967079163e-01 + <_> + + 0 -1 1321 -7.5435562757775187e-04 + + 6.0329902172088623e-01 4.7951200604438782e-01 + <_> + + 0 -1 1322 -6.9478838704526424e-03 + + 4.0844011306762695e-01 5.3735041618347168e-01 + <_> + + 0 -1 1323 2.8092920547351241e-04 + + 4.8460629582405090e-01 5.7593822479248047e-01 + <_> + + 0 -1 1324 9.6073717577382922e-04 + + 5.1647412776947021e-01 3.5549798607826233e-01 + <_> + + 0 -1 1325 -2.6883929967880249e-04 + + 5.6775820255279541e-01 4.7317659854888916e-01 + <_> + + 0 -1 1326 2.1599370520561934e-03 + + 4.7314870357513428e-01 7.0705670118331909e-01 + <_> + + 0 -1 1327 5.6235301308333874e-03 + + 5.2402430772781372e-01 2.7817919850349426e-01 + <_> + + 0 -1 1328 -5.0243991427123547e-03 + + 2.8370139002799988e-01 5.0623041391372681e-01 + <_> + + 0 -1 1329 -9.7611639648675919e-03 + + 7.4007177352905273e-01 4.9345690011978149e-01 + <_> + + 0 -1 1330 4.1515100747346878e-03 + + 5.1191312074661255e-01 3.4070080518722534e-01 + <_> + + 0 -1 1331 6.2465080991387367e-03 + + 4.9237880110740662e-01 6.5790587663650513e-01 + <_> + + 0 -1 1332 -7.0597478188574314e-03 + + 2.4347110092639923e-01 5.0328421592712402e-01 + <_> + + 0 -1 1333 -2.0587709732353687e-03 + + 5.9003108739852905e-01 4.6950870752334595e-01 + <_> + + 0 -1 1334 -2.4146060459315777e-03 + + 3.6473178863525391e-01 5.1892018318176270e-01 + <_> + + 0 -1 1335 -1.4817609917372465e-03 + + 6.0349482297897339e-01 4.9401280283927917e-01 + <_> + + 0 -1 1336 -6.3016400672495365e-03 + + 5.8189898729324341e-01 4.5604279637336731e-01 + <_> + + 0 -1 1337 3.4763428848236799e-03 + + 5.2174758911132812e-01 3.4839931130409241e-01 + <_> + + 0 -1 1338 -2.2250870242714882e-02 + + 2.3607000708580017e-01 5.0320827960968018e-01 + <_> + + 0 -1 1339 -3.0612550675868988e-02 + + 6.4991867542266846e-01 4.9149191379547119e-01 + <_> + + 0 -1 1340 1.3057479634881020e-02 + + 4.4133231043815613e-01 5.6837642192840576e-01 + <_> + + 0 -1 1341 -6.0095742810517550e-04 + + 4.3597310781478882e-01 5.3334832191467285e-01 + <_> + + 0 -1 1342 -4.1514250915497541e-04 + + 5.5040627717971802e-01 4.3260601162910461e-01 + <_> + + 0 -1 1343 -1.3776290230453014e-02 + + 4.0641129016876221e-01 5.2015489339828491e-01 + <_> + + 0 -1 1344 -3.2296508550643921e-02 + + 4.7351971268653870e-02 4.9771949648857117e-01 + <_> + + 0 -1 1345 5.3556978702545166e-02 + + 4.8817330598831177e-01 6.6669392585754395e-01 + <_> + + 0 -1 1346 8.1889545544981956e-03 + + 5.4000371694564819e-01 4.2408201098442078e-01 + <_> + + 0 -1 1347 2.1055320394225419e-04 + + 4.8020479083061218e-01 5.5638527870178223e-01 + <_> + + 0 -1 1348 -2.4382730480283499e-03 + + 7.3877930641174316e-01 4.7736850380897522e-01 + <_> + + 0 -1 1349 3.2835570164024830e-03 + + 5.2885460853576660e-01 3.1712919473648071e-01 + <_> + + 0 -1 1350 2.3729570675641298e-03 + + 4.7508129477500916e-01 7.0601707696914673e-01 + <_> + + 0 -1 1351 -1.4541699783876538e-03 + + 3.8117301464080811e-01 5.3307390213012695e-01 + <_> + 177 + 8.7696029663085938e+01 + + <_> + + 0 -1 1352 5.5755238980054855e-02 + + 4.0191569924354553e-01 6.8060368299484253e-01 + <_> + + 0 -1 1353 2.4730248842388391e-03 + + 3.3511489629745483e-01 5.9657198190689087e-01 + <_> + + 0 -1 1354 -3.5031698644161224e-04 + + 5.5577081441879272e-01 3.4822869300842285e-01 + <_> + + 0 -1 1355 5.4167630150914192e-04 + + 4.2608588933944702e-01 5.6933808326721191e-01 + <_> + + 0 -1 1356 7.7193678589537740e-04 + + 3.4942400455474854e-01 5.4336887598037720e-01 + <_> + + 0 -1 1357 -1.5999219613149762e-03 + + 4.0284991264343262e-01 5.4843592643737793e-01 + <_> + + 0 -1 1358 -1.1832080053864047e-04 + + 3.8069018721580505e-01 5.4254651069641113e-01 + <_> + + 0 -1 1359 3.2909031142480671e-04 + + 2.6201000809669495e-01 5.4295217990875244e-01 + <_> + + 0 -1 1360 2.9518108931370080e-04 + + 3.7997689843177795e-01 5.3992640972137451e-01 + <_> + + 0 -1 1361 9.0466710389591753e-05 + + 4.4336450099945068e-01 5.4402261972427368e-01 + <_> + + 0 -1 1362 1.5007190086180344e-05 + + 3.7196549773216248e-01 5.4091197252273560e-01 + <_> + + 0 -1 1363 1.3935610651969910e-01 + + 5.5253958702087402e-01 4.4790428876876831e-01 + <_> + + 0 -1 1364 1.6461990308016539e-03 + + 4.2645010352134705e-01 5.7721698284149170e-01 + <_> + + 0 -1 1365 4.9984431825578213e-04 + + 4.3595260381698608e-01 5.6858712434768677e-01 + <_> + + 0 -1 1366 -1.0971280280500650e-03 + + 3.3901369571685791e-01 5.2054089307785034e-01 + <_> + + 0 -1 1367 6.6919892560690641e-04 + + 4.5574560761451721e-01 5.9806597232818604e-01 + <_> + + 0 -1 1368 8.6471042595803738e-04 + + 5.1348412036895752e-01 2.9440331459045410e-01 + <_> + + 0 -1 1369 -2.7182599296793342e-04 + + 3.9065781235694885e-01 5.3771811723709106e-01 + <_> + + 0 -1 1370 3.0249499104684219e-05 + + 3.6796098947525024e-01 5.2256888151168823e-01 + <_> + + 0 -1 1371 -8.5225896909832954e-03 + + 7.2931021451950073e-01 4.8923650383949280e-01 + <_> + + 0 -1 1372 1.6705560265108943e-03 + + 4.3453249335289001e-01 5.6961381435394287e-01 + <_> + + 0 -1 1373 -7.1433838456869125e-03 + + 2.5912800431251526e-01 5.2256238460540771e-01 + <_> + + 0 -1 1374 -1.6319369897246361e-02 + + 6.9222790002822876e-01 4.6515759825706482e-01 + <_> + + 0 -1 1375 4.8034260980784893e-03 + + 5.3522628545761108e-01 3.2863029837608337e-01 + <_> + + 0 -1 1376 -7.5421929359436035e-03 + + 2.0405440032482147e-01 5.0345462560653687e-01 + <_> + + 0 -1 1377 -1.4363110065460205e-02 + + 6.8048888444900513e-01 4.8890590667724609e-01 + <_> + + 0 -1 1378 8.9063588529825211e-04 + + 5.3106957674026489e-01 3.8954809308052063e-01 + <_> + + 0 -1 1379 -4.4060191139578819e-03 + + 5.7415628433227539e-01 4.3724268674850464e-01 + <_> + + 0 -1 1380 -1.8862540309783071e-04 + + 2.8317859768867493e-01 5.0982052087783813e-01 + <_> + + 0 -1 1381 -3.7979281041771173e-03 + + 3.3725079894065857e-01 5.2465802431106567e-01 + <_> + + 0 -1 1382 1.4627049677073956e-04 + + 5.3066742420196533e-01 3.9117100834846497e-01 + <_> + + 0 -1 1383 -4.9164638767251745e-05 + + 5.4624962806701660e-01 3.9427208900451660e-01 + <_> + + 0 -1 1384 -3.3582501113414764e-02 + + 2.1578240394592285e-01 5.0482118129730225e-01 + <_> + + 0 -1 1385 -3.5339309833943844e-03 + + 6.4653122425079346e-01 4.8726969957351685e-01 + <_> + + 0 -1 1386 5.0144111737608910e-03 + + 4.6176680922508240e-01 6.2480747699737549e-01 + <_> + + 0 -1 1387 1.8817370757460594e-02 + + 5.2206891775131226e-01 2.0000520348548889e-01 + <_> + + 0 -1 1388 -1.3434339780360460e-03 + + 4.0145379304885864e-01 5.3016197681427002e-01 + <_> + + 0 -1 1389 1.7557960236445069e-03 + + 4.7940391302108765e-01 5.6531697511672974e-01 + <_> + + 0 -1 1390 -9.5637463033199310e-02 + + 2.0341950654983521e-01 5.0067067146301270e-01 + <_> + + 0 -1 1391 -2.2241229191422462e-02 + + 7.6724731922149658e-01 5.0463402271270752e-01 + <_> + + 0 -1 1392 -1.5575819648802280e-02 + + 7.4903422594070435e-01 4.7558510303497314e-01 + <_> + + 0 -1 1393 5.3599118255078793e-03 + + 5.3653037548065186e-01 4.0046709775924683e-01 + <_> + + 0 -1 1394 -2.1763499826192856e-02 + + 7.4015498161315918e-02 4.9641749262809753e-01 + <_> + + 0 -1 1395 -1.6561590135097504e-01 + + 2.8591030836105347e-01 5.2180862426757812e-01 + <_> + + 0 -1 1396 1.6461320046801120e-04 + + 4.1916158795356750e-01 5.3807932138442993e-01 + <_> + + 0 -1 1397 -8.9077502489089966e-03 + + 6.2731927633285522e-01 4.8774048686027527e-01 + <_> + + 0 -1 1398 8.6346449097618461e-04 + + 5.1599407196044922e-01 3.6710259318351746e-01 + <_> + + 0 -1 1399 -1.3751760125160217e-03 + + 5.8843767642974854e-01 4.5790839195251465e-01 + <_> + + 0 -1 1400 -1.4081239933148026e-03 + + 3.5605099797248840e-01 5.1399451494216919e-01 + <_> + + 0 -1 1401 -3.9342888630926609e-03 + + 5.9942889213562012e-01 4.6642720699310303e-01 + <_> + + 0 -1 1402 -3.1966928392648697e-02 + + 3.3454620838165283e-01 5.1441830396652222e-01 + <_> + + 0 -1 1403 -1.5089280168467667e-05 + + 5.5826562643051147e-01 4.4140571355819702e-01 + <_> + + 0 -1 1404 5.1994470413774252e-04 + + 4.6236801147460938e-01 6.1689937114715576e-01 + <_> + + 0 -1 1405 -3.4220460802316666e-03 + + 6.5570747852325439e-01 4.9748051166534424e-01 + <_> + + 0 -1 1406 1.7723299970384687e-04 + + 5.2695018053054810e-01 3.9019080996513367e-01 + <_> + + 0 -1 1407 1.5716759953647852e-03 + + 4.6333730220794678e-01 5.7904577255249023e-01 + <_> + + 0 -1 1408 -8.9041329920291901e-03 + + 2.6896080374717712e-01 5.0535911321640015e-01 + <_> + + 0 -1 1409 4.0677518700249493e-04 + + 5.4566031694412231e-01 4.3298989534378052e-01 + <_> + + 0 -1 1410 6.7604780197143555e-03 + + 4.6489939093589783e-01 6.6897618770599365e-01 + <_> + + 0 -1 1411 2.9100088868290186e-03 + + 5.3097039461135864e-01 3.3778399229049683e-01 + <_> + + 0 -1 1412 1.3885459629818797e-03 + + 4.0747389197349548e-01 5.3491330146789551e-01 + <_> + + 0 -1 1413 -7.6764263212680817e-02 + + 1.9921760261058807e-01 5.2282422780990601e-01 + <_> + + 0 -1 1414 -2.2688310127705336e-04 + + 5.4385018348693848e-01 4.2530721426010132e-01 + <_> + + 0 -1 1415 -6.3094152137637138e-03 + + 4.2591789364814758e-01 5.3789097070693970e-01 + <_> + + 0 -1 1416 -1.1007279902696609e-01 + + 6.9041568040847778e-01 4.7217491269111633e-01 + <_> + + 0 -1 1417 2.8619659133255482e-04 + + 4.5249149203300476e-01 5.5483061075210571e-01 + <_> + + 0 -1 1418 2.9425329557852820e-05 + + 5.3703737258911133e-01 4.2364639043807983e-01 + <_> + + 0 -1 1419 -2.4886570870876312e-02 + + 6.4235579967498779e-01 4.9693039059638977e-01 + <_> + + 0 -1 1420 3.3148851245641708e-02 + + 4.9884751439094543e-01 1.6138119995594025e-01 + <_> + + 0 -1 1421 7.8491691965609789e-04 + + 5.4160261154174805e-01 4.2230090498924255e-01 + <_> + + 0 -1 1422 4.7087189741432667e-03 + + 4.5763289928436279e-01 6.0275578498840332e-01 + <_> + + 0 -1 1423 2.4144479539245367e-03 + + 5.3089731931686401e-01 4.4224989414215088e-01 + <_> + + 0 -1 1424 1.9523180089890957e-03 + + 4.7056341171264648e-01 6.6633248329162598e-01 + <_> + + 0 -1 1425 1.3031980488449335e-03 + + 4.4061261415481567e-01 5.5269622802734375e-01 + <_> + + 0 -1 1426 4.4735497795045376e-03 + + 5.1290237903594971e-01 3.3014988899230957e-01 + <_> + + 0 -1 1427 -2.6652868837118149e-03 + + 3.1354710459709167e-01 5.1750361919403076e-01 + <_> + + 0 -1 1428 1.3666770246345550e-04 + + 4.1193708777427673e-01 5.3068768978118896e-01 + <_> + + 0 -1 1429 -1.7126450315117836e-02 + + 6.1778062582015991e-01 4.8365789651870728e-01 + <_> + + 0 -1 1430 -2.6601430727168918e-04 + + 3.6543309688568115e-01 5.1697367429733276e-01 + <_> + + 0 -1 1431 -2.2932380437850952e-02 + + 3.4909150004386902e-01 5.1639920473098755e-01 + <_> + + 0 -1 1432 2.3316550068557262e-03 + + 5.1662999391555786e-01 3.7093898653984070e-01 + <_> + + 0 -1 1433 1.6925660893321037e-02 + + 5.0147360563278198e-01 8.0539882183074951e-01 + <_> + + 0 -1 1434 -8.9858826249837875e-03 + + 6.4707887172698975e-01 4.6570208668708801e-01 + <_> + + 0 -1 1435 -1.1874699965119362e-02 + + 3.2463788986206055e-01 5.2587550878524780e-01 + <_> + + 0 -1 1436 1.9350569345988333e-04 + + 5.1919418573379517e-01 3.8396438956260681e-01 + <_> + + 0 -1 1437 5.8713490143418312e-03 + + 4.9181339144706726e-01 6.1870431900024414e-01 + <_> + + 0 -1 1438 -2.4838790297508240e-01 + + 1.8368029594421387e-01 4.9881500005722046e-01 + <_> + + 0 -1 1439 1.2256000190973282e-02 + + 5.2270537614822388e-01 3.6320298910140991e-01 + <_> + + 0 -1 1440 8.3990179700776935e-04 + + 4.4902500510215759e-01 5.7741481065750122e-01 + <_> + + 0 -1 1441 2.5407369248569012e-03 + + 4.8047870397567749e-01 5.8582991361618042e-01 + <_> + + 0 -1 1442 -1.4822429977357388e-02 + + 2.5210499763488770e-01 5.0235372781753540e-01 + <_> + + 0 -1 1443 -5.7973959483206272e-03 + + 5.9966957569122314e-01 4.8537150025367737e-01 + <_> + + 0 -1 1444 7.2662148158997297e-04 + + 5.1537168025970459e-01 3.6717799305915833e-01 + <_> + + 0 -1 1445 -1.7232580110430717e-02 + + 6.6217190027236938e-01 4.9946561455726624e-01 + <_> + + 0 -1 1446 7.8624086454510689e-03 + + 4.6333950757980347e-01 6.2561017274856567e-01 + <_> + + 0 -1 1447 -4.7343620099127293e-03 + + 3.6155730485916138e-01 5.2818852663040161e-01 + <_> + + 0 -1 1448 8.3048478700220585e-04 + + 4.4428890943527222e-01 5.5509579181671143e-01 + <_> + + 0 -1 1449 7.6602199114859104e-03 + + 5.1629352569580078e-01 2.6133549213409424e-01 + <_> + + 0 -1 1450 -4.1048377752304077e-03 + + 2.7896320819854736e-01 5.0190317630767822e-01 + <_> + + 0 -1 1451 4.8512578941881657e-03 + + 4.9689841270446777e-01 5.6616681814193726e-01 + <_> + + 0 -1 1452 9.9896453320980072e-04 + + 4.4456079602241516e-01 5.5518132448196411e-01 + <_> + + 0 -1 1453 -2.7023631334304810e-01 + + 2.9388209804892540e-02 5.1513141393661499e-01 + <_> + + 0 -1 1454 -1.3090680353343487e-02 + + 5.6993997097015381e-01 4.4474598765373230e-01 + <_> + + 0 -1 1455 -9.4342790544033051e-03 + + 4.3054661154747009e-01 5.4878950119018555e-01 + <_> + + 0 -1 1456 -1.5482039889320731e-03 + + 3.6803171038627625e-01 5.1280808448791504e-01 + <_> + + 0 -1 1457 5.3746132180094719e-03 + + 4.8389169573783875e-01 6.1015558242797852e-01 + <_> + + 0 -1 1458 1.5786769799888134e-03 + + 5.3252232074737549e-01 4.1185480356216431e-01 + <_> + + 0 -1 1459 3.6856050137430429e-03 + + 4.8109480738639832e-01 6.2523031234741211e-01 + <_> + + 0 -1 1460 9.3887019902467728e-03 + + 5.2002298831939697e-01 3.6294108629226685e-01 + <_> + + 0 -1 1461 1.2792630121111870e-02 + + 4.9617099761962891e-01 6.7380160093307495e-01 + <_> + + 0 -1 1462 -3.3661040943115950e-03 + + 4.0602791309356689e-01 5.2835988998413086e-01 + <_> + + 0 -1 1463 3.9771420415490866e-04 + + 4.6741139888763428e-01 5.9007751941680908e-01 + <_> + + 0 -1 1464 1.4868030557408929e-03 + + 4.5191168785095215e-01 6.0820537805557251e-01 + <_> + + 0 -1 1465 -8.8686749339103699e-02 + + 2.8078991174697876e-01 5.1809918880462646e-01 + <_> + + 0 -1 1466 -7.4296112870797515e-05 + + 5.2955842018127441e-01 4.0876251459121704e-01 + <_> + + 0 -1 1467 -1.4932939848222304e-05 + + 5.4614001512527466e-01 4.5385429263114929e-01 + <_> + + 0 -1 1468 5.9162238612771034e-03 + + 5.3291612863540649e-01 4.1921341419219971e-01 + <_> + + 0 -1 1469 1.1141640134155750e-03 + + 4.5120179653167725e-01 5.7062172889709473e-01 + <_> + + 0 -1 1470 8.9249362645205110e-05 + + 4.5778059959411621e-01 5.8976382017135620e-01 + <_> + + 0 -1 1471 2.5319510605186224e-03 + + 5.2996039390563965e-01 3.3576390147209167e-01 + <_> + + 0 -1 1472 1.2426200322806835e-02 + + 4.9590590596199036e-01 1.3466019928455353e-01 + <_> + + 0 -1 1473 2.8335750102996826e-02 + + 5.1170790195465088e-01 6.1043637106195092e-04 + <_> + + 0 -1 1474 6.6165882162749767e-03 + + 4.7363498806953430e-01 7.0116281509399414e-01 + <_> + + 0 -1 1475 8.0468766391277313e-03 + + 5.2164179086685181e-01 3.2828199863433838e-01 + <_> + + 0 -1 1476 -1.1193980462849140e-03 + + 5.8098608255386353e-01 4.5637390017509460e-01 + <_> + + 0 -1 1477 1.3277590274810791e-02 + + 5.3983622789382935e-01 4.1039010882377625e-01 + <_> + + 0 -1 1478 4.8794739996083081e-04 + + 4.2492860555648804e-01 5.4105907678604126e-01 + <_> + + 0 -1 1479 1.1243170127272606e-02 + + 5.2699637413024902e-01 3.4382158517837524e-01 + <_> + + 0 -1 1480 -8.9896668214350939e-04 + + 5.6330758333206177e-01 4.4566130638122559e-01 + <_> + + 0 -1 1481 6.6677159629762173e-03 + + 5.3128892183303833e-01 4.3626791238784790e-01 + <_> + + 0 -1 1482 2.8947299346327782e-02 + + 4.7017949819564819e-01 6.5757977962493896e-01 + <_> + + 0 -1 1483 -2.3400049656629562e-02 + + 0. 5.1373988389968872e-01 + <_> + + 0 -1 1484 -8.9117050170898438e-02 + + 2.3745279759168625e-02 4.9424308538436890e-01 + <_> + + 0 -1 1485 -1.4054600149393082e-02 + + 3.1273230910301208e-01 5.1175111532211304e-01 + <_> + + 0 -1 1486 8.1239398568868637e-03 + + 5.0090491771697998e-01 2.5200259685516357e-01 + <_> + + 0 -1 1487 -4.9964650534093380e-03 + + 6.3871437311172485e-01 4.9278119206428528e-01 + <_> + + 0 -1 1488 3.1253970228135586e-03 + + 5.1368498802185059e-01 3.6804521083831787e-01 + <_> + + 0 -1 1489 6.7669642157852650e-03 + + 5.5098438262939453e-01 4.3636319041252136e-01 + <_> + + 0 -1 1490 -2.3711440153419971e-03 + + 6.1623352766036987e-01 4.5869469642639160e-01 + <_> + + 0 -1 1491 -5.3522791713476181e-03 + + 6.1854577064514160e-01 4.9204909801483154e-01 + <_> + + 0 -1 1492 -1.5968859195709229e-02 + + 1.3826179504394531e-01 4.9832528829574585e-01 + <_> + + 0 -1 1493 4.7676060348749161e-03 + + 4.6880578994750977e-01 5.4900461435317993e-01 + <_> + + 0 -1 1494 -2.4714691098779440e-03 + + 2.3685149848461151e-01 5.0039529800415039e-01 + <_> + + 0 -1 1495 -7.1033788844943047e-04 + + 5.8563941717147827e-01 4.7215330600738525e-01 + <_> + + 0 -1 1496 -1.4117559790611267e-01 + + 8.6900062859058380e-02 4.9615910649299622e-01 + <_> + + 0 -1 1497 1.0651809722185135e-01 + + 5.1388370990753174e-01 1.7410050332546234e-01 + <_> + + 0 -1 1498 -5.2744749933481216e-02 + + 7.3536360263824463e-01 4.7728818655014038e-01 + <_> + + 0 -1 1499 -4.7431760467588902e-03 + + 3.8844060897827148e-01 5.2927017211914062e-01 + <_> + + 0 -1 1500 9.9676765967160463e-04 + + 5.2234929800033569e-01 4.0034240484237671e-01 + <_> + + 0 -1 1501 8.0284131690859795e-03 + + 4.9591061472892761e-01 7.2129642963409424e-01 + <_> + + 0 -1 1502 8.6025858763605356e-04 + + 4.4448840618133545e-01 5.5384761095046997e-01 + <_> + + 0 -1 1503 9.3191501218825579e-04 + + 5.3983712196350098e-01 4.1632440686225891e-01 + <_> + + 0 -1 1504 -2.5082060601562262e-03 + + 5.8542650938034058e-01 4.5625001192092896e-01 + <_> + + 0 -1 1505 -2.1378761157393456e-03 + + 4.6080690622329712e-01 5.2802592515945435e-01 + <_> + + 0 -1 1506 -2.1546049974858761e-03 + + 3.7911269068717957e-01 5.2559971809387207e-01 + <_> + + 0 -1 1507 -7.6214009895920753e-03 + + 5.9986090660095215e-01 4.9520739912986755e-01 + <_> + + 0 -1 1508 2.2055360022932291e-03 + + 4.4842061400413513e-01 5.5885308980941772e-01 + <_> + + 0 -1 1509 1.2586950324475765e-03 + + 5.4507470130920410e-01 4.4238409399986267e-01 + <_> + + 0 -1 1510 -5.0926720723509789e-03 + + 4.1182750463485718e-01 5.2630358934402466e-01 + <_> + + 0 -1 1511 -2.5095739401876926e-03 + + 5.7879078388214111e-01 4.9984949827194214e-01 + <_> + + 0 -1 1512 -7.7327556908130646e-02 + + 8.3978658914566040e-01 4.8111200332641602e-01 + <_> + + 0 -1 1513 -4.1485819965600967e-02 + + 2.4086110293865204e-01 5.1769930124282837e-01 + <_> + + 0 -1 1514 1.0355669655837119e-04 + + 4.3553608655929565e-01 5.4170542955398560e-01 + <_> + + 0 -1 1515 1.3255809899419546e-03 + + 5.4539710283279419e-01 4.8940950632095337e-01 + <_> + + 0 -1 1516 -8.0598732456564903e-03 + + 5.7710242271423340e-01 4.5779189467430115e-01 + <_> + + 0 -1 1517 1.9058620557188988e-02 + + 5.1698678731918335e-01 3.4004750847816467e-01 + <_> + + 0 -1 1518 -3.5057891160249710e-02 + + 2.2032439708709717e-01 5.0005030632019043e-01 + <_> + + 0 -1 1519 5.7296059094369411e-03 + + 5.0434082746505737e-01 6.5975707769393921e-01 + <_> + + 0 -1 1520 -1.1648329906165600e-02 + + 2.1862849593162537e-01 4.9966529011726379e-01 + <_> + + 0 -1 1521 1.4544479781761765e-03 + + 5.0076818466186523e-01 5.5037277936935425e-01 + <_> + + 0 -1 1522 -2.5030909455381334e-04 + + 4.1298410296440125e-01 5.2416700124740601e-01 + <_> + + 0 -1 1523 -8.2907272735610604e-04 + + 5.4128682613372803e-01 4.9744960665702820e-01 + <_> + + 0 -1 1524 1.0862209601327777e-03 + + 4.6055299043655396e-01 5.8792287111282349e-01 + <_> + + 0 -1 1525 2.0000500080641359e-04 + + 5.2788549661636353e-01 4.7052091360092163e-01 + <_> + + 0 -1 1526 2.9212920926511288e-03 + + 5.1296097040176392e-01 3.7555369734764099e-01 + <_> + + 0 -1 1527 2.5387400761246681e-02 + + 4.8226919770240784e-01 5.7907682657241821e-01 + <_> + + 0 -1 1528 -3.1968469265848398e-03 + + 5.2483952045440674e-01 3.9628401398658752e-01 + <_> + 182 + 9.0253349304199219e+01 + + <_> + + 0 -1 1529 5.8031738735735416e-03 + + 3.4989839792251587e-01 5.9619832038879395e-01 + <_> + + 0 -1 1530 -9.0003069490194321e-03 + + 6.8166369199752808e-01 4.4785520434379578e-01 + <_> + + 0 -1 1531 -1.1549659539014101e-03 + + 5.5857062339782715e-01 3.5782510042190552e-01 + <_> + + 0 -1 1532 -1.1069850297644734e-03 + + 5.3650361299514771e-01 3.0504280328750610e-01 + <_> + + 0 -1 1533 1.0308309720130637e-04 + + 3.6390951275825500e-01 5.3446358442306519e-01 + <_> + + 0 -1 1534 -5.0984839908778667e-03 + + 2.8591570258140564e-01 5.5042648315429688e-01 + <_> + + 0 -1 1535 8.2572200335562229e-04 + + 5.2365237474441528e-01 3.4760418534278870e-01 + <_> + + 0 -1 1536 9.9783325567841530e-03 + + 4.7503221035003662e-01 6.2196469306945801e-01 + <_> + + 0 -1 1537 -3.7402529269456863e-02 + + 3.3433759212493896e-01 5.2780628204345703e-01 + <_> + + 0 -1 1538 4.8548257909715176e-03 + + 5.1921808719635010e-01 3.7004441022872925e-01 + <_> + + 0 -1 1539 -1.8664470408111811e-03 + + 2.9298439621925354e-01 5.0919449329376221e-01 + <_> + + 0 -1 1540 1.6888890415430069e-02 + + 3.6868458986282349e-01 5.4312258958816528e-01 + <_> + + 0 -1 1541 -5.8372621424496174e-03 + + 3.6321839690208435e-01 5.2213358879089355e-01 + <_> + + 0 -1 1542 -1.4713739510625601e-03 + + 5.8706837892532349e-01 4.7006508708000183e-01 + <_> + + 0 -1 1543 -1.1522950371727347e-03 + + 3.1958949565887451e-01 5.1409542560577393e-01 + <_> + + 0 -1 1544 -4.2560300789773464e-03 + + 6.3018590211868286e-01 4.8149210214614868e-01 + <_> + + 0 -1 1545 -6.7378291860222816e-03 + + 1.9770480692386627e-01 5.0258082151412964e-01 + <_> + + 0 -1 1546 1.1382670141756535e-02 + + 4.9541321396827698e-01 6.8670457601547241e-01 + <_> + + 0 -1 1547 5.1794708706438541e-03 + + 5.1644277572631836e-01 3.3506479859352112e-01 + <_> + + 0 -1 1548 -1.1743789911270142e-01 + + 2.3152460157871246e-01 5.2344137430191040e-01 + <_> + + 0 -1 1549 2.8703449293971062e-02 + + 4.6642971038818359e-01 6.7225211858749390e-01 + <_> + + 0 -1 1550 4.8231030814349651e-03 + + 5.2208751440048218e-01 2.7235329151153564e-01 + <_> + + 0 -1 1551 2.6798530016094446e-03 + + 5.0792771577835083e-01 2.9069489240646362e-01 + <_> + + 0 -1 1552 8.0504082143306732e-03 + + 4.8859509825706482e-01 6.3950210809707642e-01 + <_> + + 0 -1 1553 4.8054959625005722e-03 + + 5.1972568035125732e-01 3.6566638946533203e-01 + <_> + + 0 -1 1554 -2.2420159075409174e-03 + + 6.1534678936004639e-01 4.7637018561363220e-01 + <_> + + 0 -1 1555 -1.3757710345089436e-02 + + 2.6373448967933655e-01 5.0309032201766968e-01 + <_> + + 0 -1 1556 -1.0338299721479416e-01 + + 2.2875219583511353e-01 5.1824611425399780e-01 + <_> + + 0 -1 1557 -9.4432085752487183e-03 + + 6.9533038139343262e-01 4.6949490904808044e-01 + <_> + + 0 -1 1558 8.0271181650459766e-04 + + 5.4506552219390869e-01 4.2687839269638062e-01 + <_> + + 0 -1 1559 -4.1945669800043106e-03 + + 6.0913878679275513e-01 4.5716428756713867e-01 + <_> + + 0 -1 1560 1.0942210443317890e-02 + + 5.2410632371902466e-01 3.2845470309257507e-01 + <_> + + 0 -1 1561 -5.7841069065034389e-04 + + 5.3879290819168091e-01 4.1793689131736755e-01 + <_> + + 0 -1 1562 -2.0888620056211948e-03 + + 4.2926910519599915e-01 5.3017157316207886e-01 + <_> + + 0 -1 1563 3.2383969519287348e-03 + + 3.7923479080200195e-01 5.2207440137863159e-01 + <_> + + 0 -1 1564 4.9075027927756310e-03 + + 5.2372831106185913e-01 4.1267579793930054e-01 + <_> + + 0 -1 1565 -3.2277941703796387e-02 + + 1.9476559758186340e-01 4.9945020675659180e-01 + <_> + + 0 -1 1566 -8.9711230248212814e-03 + + 6.0112851858139038e-01 4.9290320277214050e-01 + <_> + + 0 -1 1567 1.5321089886128902e-02 + + 5.0097537040710449e-01 2.0398220419883728e-01 + <_> + + 0 -1 1568 2.0855569746345282e-03 + + 4.8621898889541626e-01 5.7216948270797729e-01 + <_> + + 0 -1 1569 5.0615021027624607e-03 + + 5.0002187490463257e-01 1.8018059432506561e-01 + <_> + + 0 -1 1570 -3.7174751050770283e-03 + + 5.5301171541213989e-01 4.8975929617881775e-01 + <_> + + 0 -1 1571 -1.2170500122010708e-02 + + 4.1786059737205505e-01 5.3837239742279053e-01 + <_> + + 0 -1 1572 4.6248398721218109e-03 + + 4.9971699714660645e-01 5.7613271474838257e-01 + <_> + + 0 -1 1573 -2.1040429419372231e-04 + + 5.3318071365356445e-01 4.0976810455322266e-01 + <_> + + 0 -1 1574 -1.4641780406236649e-02 + + 5.7559251785278320e-01 5.0517761707305908e-01 + <_> + + 0 -1 1575 3.3199489116668701e-03 + + 4.5769768953323364e-01 6.0318058729171753e-01 + <_> + + 0 -1 1576 3.7236879579722881e-03 + + 4.3803969025611877e-01 5.4158830642700195e-01 + <_> + + 0 -1 1577 8.2951161311939359e-04 + + 5.1630318164825439e-01 3.7022191286087036e-01 + <_> + + 0 -1 1578 -1.1408490128815174e-02 + + 6.0729467868804932e-01 4.8625651001930237e-01 + <_> + + 0 -1 1579 -4.5320121571421623e-03 + + 3.2924759387969971e-01 5.0889629125595093e-01 + <_> + + 0 -1 1580 5.1276017911732197e-03 + + 4.8297679424285889e-01 6.1227089166641235e-01 + <_> + + 0 -1 1581 9.8583158105611801e-03 + + 4.6606799960136414e-01 6.5561771392822266e-01 + <_> + + 0 -1 1582 3.6985918879508972e-02 + + 5.2048492431640625e-01 1.6904720664024353e-01 + <_> + + 0 -1 1583 4.6491161920130253e-03 + + 5.1673221588134766e-01 3.7252250313758850e-01 + <_> + + 0 -1 1584 -4.2664702050387859e-03 + + 6.4064931869506836e-01 4.9873429536819458e-01 + <_> + + 0 -1 1585 -4.7956590424291790e-04 + + 5.8972930908203125e-01 4.4648739695549011e-01 + <_> + + 0 -1 1586 3.6827160511165857e-03 + + 5.4415607452392578e-01 3.4726628661155701e-01 + <_> + + 0 -1 1587 -1.0059880092740059e-02 + + 2.1431629359722137e-01 5.0048297643661499e-01 + <_> + + 0 -1 1588 -3.0361840617842972e-04 + + 5.3864240646362305e-01 4.5903238654136658e-01 + <_> + + 0 -1 1589 -1.4545479789376259e-03 + + 5.7511842250823975e-01 4.4970950484275818e-01 + <_> + + 0 -1 1590 1.6515209572389722e-03 + + 5.4219377040863037e-01 4.2385208606719971e-01 + <_> + + 0 -1 1591 -7.8468639403581619e-03 + + 4.0779209136962891e-01 5.2581572532653809e-01 + <_> + + 0 -1 1592 -5.1259850151836872e-03 + + 4.2292758822441101e-01 5.4794532060623169e-01 + <_> + + 0 -1 1593 -3.6890961229801178e-02 + + 6.5963757038116455e-01 4.6746781468391418e-01 + <_> + + 0 -1 1594 2.4035639944486320e-04 + + 4.2511358857154846e-01 5.5732029676437378e-01 + <_> + + 0 -1 1595 -1.5150169929256663e-05 + + 5.2592468261718750e-01 4.0741148591041565e-01 + <_> + + 0 -1 1596 2.2108471021056175e-03 + + 4.6717229485511780e-01 5.8863520622253418e-01 + <_> + + 0 -1 1597 -1.1568620102480054e-03 + + 5.7110661268234253e-01 4.4871619343757629e-01 + <_> + + 0 -1 1598 4.9996292218565941e-03 + + 5.2641981840133667e-01 2.8983271121978760e-01 + <_> + + 0 -1 1599 -1.4656189596280456e-03 + + 3.8917380571365356e-01 5.1978719234466553e-01 + <_> + + 0 -1 1600 -1.1975039960816503e-03 + + 5.7958728075027466e-01 4.9279558658599854e-01 + <_> + + 0 -1 1601 -4.4954330660402775e-03 + + 2.3776030540466309e-01 5.0125551223754883e-01 + <_> + + 0 -1 1602 1.4997160178609192e-04 + + 4.8766261339187622e-01 5.6176078319549561e-01 + <_> + + 0 -1 1603 2.6391509454697371e-03 + + 5.1680880784988403e-01 3.7655091285705566e-01 + <_> + + 0 -1 1604 -2.9368131072260439e-04 + + 5.4466491937637329e-01 4.8746308684349060e-01 + <_> + + 0 -1 1605 1.4211760135367513e-03 + + 4.6878978610038757e-01 6.6913318634033203e-01 + <_> + + 0 -1 1606 7.9427637159824371e-02 + + 5.1934438943862915e-01 2.7329459786415100e-01 + <_> + + 0 -1 1607 7.9937502741813660e-02 + + 4.9717310070991516e-01 1.7820839583873749e-01 + <_> + + 0 -1 1608 1.1089259758591652e-02 + + 5.1659947633743286e-01 3.2094758749008179e-01 + <_> + + 0 -1 1609 1.6560709627810866e-04 + + 4.0584719181060791e-01 5.3072762489318848e-01 + <_> + + 0 -1 1610 -5.3354292176663876e-03 + + 3.4450569748878479e-01 5.1581299304962158e-01 + <_> + + 0 -1 1611 1.1287260567769408e-03 + + 4.5948630571365356e-01 6.0755330324172974e-01 + <_> + + 0 -1 1612 -2.1969219669699669e-02 + + 1.6804009675979614e-01 5.2285957336425781e-01 + <_> + + 0 -1 1613 -2.1775320055894554e-04 + + 3.8615968823432922e-01 5.2156728506088257e-01 + <_> + + 0 -1 1614 2.0200149447191507e-04 + + 5.5179792642593384e-01 4.3630391359329224e-01 + <_> + + 0 -1 1615 -2.1733149886131287e-02 + + 7.9994601011276245e-01 4.7898510098457336e-01 + <_> + + 0 -1 1616 -8.4399932529777288e-04 + + 4.0859758853912354e-01 5.3747731447219849e-01 + <_> + + 0 -1 1617 -4.3895249837078154e-04 + + 5.4704052209854126e-01 4.3661430478096008e-01 + <_> + + 0 -1 1618 1.5092400135472417e-03 + + 4.9889969825744629e-01 5.8421492576599121e-01 + <_> + + 0 -1 1619 -3.5547839943319559e-03 + + 6.7536902427673340e-01 4.7210058569908142e-01 + <_> + + 0 -1 1620 4.8191400128416717e-04 + + 5.4158538579940796e-01 4.3571090698242188e-01 + <_> + + 0 -1 1621 -6.0264398343861103e-03 + + 2.2585099935531616e-01 4.9918809533119202e-01 + <_> + + 0 -1 1622 -1.1668140068650246e-02 + + 6.2565547227859497e-01 4.9274989962577820e-01 + <_> + + 0 -1 1623 -2.8718370012938976e-03 + + 3.9477849006652832e-01 5.2458018064498901e-01 + <_> + + 0 -1 1624 1.7051169648766518e-02 + + 4.7525110840797424e-01 5.7942241430282593e-01 + <_> + + 0 -1 1625 -1.3352080248296261e-02 + + 6.0411047935485840e-01 4.5445358753204346e-01 + <_> + + 0 -1 1626 -3.9301801007241011e-04 + + 4.2582759261131287e-01 5.5449050664901733e-01 + <_> + + 0 -1 1627 3.0483349692076445e-03 + + 5.2334201335906982e-01 3.7802729010581970e-01 + <_> + + 0 -1 1628 -4.3579288758337498e-03 + + 6.3718891143798828e-01 4.8386740684509277e-01 + <_> + + 0 -1 1629 5.6661018170416355e-03 + + 5.3747057914733887e-01 4.1636660695075989e-01 + <_> + + 0 -1 1630 6.0677339206449687e-05 + + 4.6387958526611328e-01 5.3116250038146973e-01 + <_> + + 0 -1 1631 3.6738160997629166e-02 + + 4.6886560320854187e-01 6.4665240049362183e-01 + <_> + + 0 -1 1632 8.6528137326240540e-03 + + 5.2043187618255615e-01 2.1886579692363739e-01 + <_> + + 0 -1 1633 -1.5371359884738922e-01 + + 1.6303719580173492e-01 4.9588400125503540e-01 + <_> + + 0 -1 1634 -4.1560421232134104e-04 + + 5.7744592428207397e-01 4.6964588761329651e-01 + <_> + + 0 -1 1635 -1.2640169588848948e-03 + + 3.9771759510040283e-01 5.2171981334686279e-01 + <_> + + 0 -1 1636 -3.5473341122269630e-03 + + 6.0465282201766968e-01 4.8083150386810303e-01 + <_> + + 0 -1 1637 3.0019069527043030e-05 + + 3.9967238903045654e-01 5.2282011508941650e-01 + <_> + + 0 -1 1638 1.3113019522279501e-03 + + 4.7121581435203552e-01 5.7659977674484253e-01 + <_> + + 0 -1 1639 -1.3374709524214268e-03 + + 4.1095849871635437e-01 5.2531701326370239e-01 + <_> + + 0 -1 1640 2.0876709371805191e-02 + + 5.2029937505722046e-01 1.7579819262027740e-01 + <_> + + 0 -1 1641 -7.5497948564589024e-03 + + 6.5666097402572632e-01 4.6949750185012817e-01 + <_> + + 0 -1 1642 2.4188550189137459e-02 + + 5.1286739110946655e-01 3.3702209591865540e-01 + <_> + + 0 -1 1643 -2.9358828905969858e-03 + + 6.5807867050170898e-01 4.6945410966873169e-01 + <_> + + 0 -1 1644 5.7557929307222366e-02 + + 5.1464450359344482e-01 2.7752599120140076e-01 + <_> + + 0 -1 1645 -1.1343370424583554e-03 + + 3.8366019725799561e-01 5.1926672458648682e-01 + <_> + + 0 -1 1646 1.6816999763250351e-02 + + 5.0855928659439087e-01 6.1772608757019043e-01 + <_> + + 0 -1 1647 5.0535178743302822e-03 + + 5.1387631893157959e-01 3.6847919225692749e-01 + <_> + + 0 -1 1648 -4.5874710194766521e-03 + + 5.9896552562713623e-01 4.8352020978927612e-01 + <_> + + 0 -1 1649 1.6882460331544280e-03 + + 4.5094868540763855e-01 5.7230567932128906e-01 + <_> + + 0 -1 1650 -1.6554000321775675e-03 + + 3.4967708587646484e-01 5.2433192729949951e-01 + <_> + + 0 -1 1651 -1.9373800605535507e-02 + + 1.1205369979143143e-01 4.9687129259109497e-01 + <_> + + 0 -1 1652 1.0374450124800205e-02 + + 5.1481968164443970e-01 4.3952131271362305e-01 + <_> + + 0 -1 1653 1.4973050565458834e-04 + + 4.0849998593330383e-01 5.2698868513107300e-01 + <_> + + 0 -1 1654 -4.2981930077075958e-02 + + 6.3941049575805664e-01 5.0185042619705200e-01 + <_> + + 0 -1 1655 8.3065936341881752e-03 + + 4.7075539827346802e-01 6.6983532905578613e-01 + <_> + + 0 -1 1656 -4.1285790503025055e-03 + + 4.5413690805435181e-01 5.3236472606658936e-01 + <_> + + 0 -1 1657 1.7399420030415058e-03 + + 4.3339619040489197e-01 5.4398661851882935e-01 + <_> + + 0 -1 1658 1.1739750334527344e-04 + + 4.5796871185302734e-01 5.5434262752532959e-01 + <_> + + 0 -1 1659 1.8585780344437808e-04 + + 4.3246439099311829e-01 5.4267549514770508e-01 + <_> + + 0 -1 1660 5.5587692186236382e-03 + + 5.2572208642959595e-01 3.5506111383438110e-01 + <_> + + 0 -1 1661 -7.9851560294628143e-03 + + 6.0430181026458740e-01 4.6306359767913818e-01 + <_> + + 0 -1 1662 6.0594122624024749e-04 + + 4.5982548594474792e-01 5.5331951379776001e-01 + <_> + + 0 -1 1663 -2.2983040253166109e-04 + + 4.1307520866394043e-01 5.3224611282348633e-01 + <_> + + 0 -1 1664 4.3740210821852088e-04 + + 4.0430399775505066e-01 5.4092890024185181e-01 + <_> + + 0 -1 1665 2.9482020181603730e-04 + + 4.4949638843536377e-01 5.6288522481918335e-01 + <_> + + 0 -1 1666 1.0312659665942192e-02 + + 5.1775109767913818e-01 2.7043169736862183e-01 + <_> + + 0 -1 1667 -7.7241109684109688e-03 + + 1.9880190491676331e-01 4.9805539846420288e-01 + <_> + + 0 -1 1668 -4.6797208487987518e-03 + + 6.6447502374649048e-01 5.0182962417602539e-01 + <_> + + 0 -1 1669 -5.0755459815263748e-03 + + 3.8983049988746643e-01 5.1852691173553467e-01 + <_> + + 0 -1 1670 2.2479740437120199e-03 + + 4.8018088936805725e-01 5.6603360176086426e-01 + <_> + + 0 -1 1671 8.3327008178457618e-04 + + 5.2109199762344360e-01 3.9571881294250488e-01 + <_> + + 0 -1 1672 -4.1279330849647522e-02 + + 6.1545419692993164e-01 5.0070542097091675e-01 + <_> + + 0 -1 1673 -5.0930189900100231e-04 + + 3.9759421348571777e-01 5.2284038066864014e-01 + <_> + + 0 -1 1674 1.2568780221045017e-03 + + 4.9791380763053894e-01 5.9391832351684570e-01 + <_> + + 0 -1 1675 8.0048497766256332e-03 + + 4.9844971299171448e-01 1.6333660483360291e-01 + <_> + + 0 -1 1676 -1.1879300000146031e-03 + + 5.9049648046493530e-01 4.9426248669624329e-01 + <_> + + 0 -1 1677 6.1948952497914433e-04 + + 4.1995579004287720e-01 5.3287261724472046e-01 + <_> + + 0 -1 1678 6.6829859279096127e-03 + + 5.4186028242111206e-01 4.9058890342712402e-01 + <_> + + 0 -1 1679 -3.7062340416014194e-03 + + 3.7259390950202942e-01 5.1380002498626709e-01 + <_> + + 0 -1 1680 -3.9739411324262619e-02 + + 6.4789611101150513e-01 5.0503468513488770e-01 + <_> + + 0 -1 1681 1.4085009461268783e-03 + + 4.6823391318321228e-01 6.3778841495513916e-01 + <_> + + 0 -1 1682 3.9322688826359808e-04 + + 5.4585301876068115e-01 4.1504821181297302e-01 + <_> + + 0 -1 1683 -1.8979819724336267e-03 + + 3.6901599168777466e-01 5.1497042179107666e-01 + <_> + + 0 -1 1684 -1.3970440253615379e-02 + + 6.0505628585815430e-01 4.8113578557968140e-01 + <_> + + 0 -1 1685 -1.0100819915533066e-01 + + 2.0170800387859344e-01 4.9923619627952576e-01 + <_> + + 0 -1 1686 -1.7346920445561409e-02 + + 5.7131487131118774e-01 4.8994860053062439e-01 + <_> + + 0 -1 1687 1.5619759506080300e-04 + + 4.2153888940811157e-01 5.3926420211791992e-01 + <_> + + 0 -1 1688 1.3438929617404938e-01 + + 5.1361519098281860e-01 3.7676128745079041e-01 + <_> + + 0 -1 1689 -2.4582240730524063e-02 + + 7.0273578166961670e-01 4.7479069232940674e-01 + <_> + + 0 -1 1690 -3.8553720805794001e-03 + + 4.3174090981483459e-01 5.4277169704437256e-01 + <_> + + 0 -1 1691 -2.3165249731391668e-03 + + 5.9426987171173096e-01 4.6186479926109314e-01 + <_> + + 0 -1 1692 -4.8518120311200619e-03 + + 6.1915689706802368e-01 4.8848950862884521e-01 + <_> + + 0 -1 1693 2.4699938949197531e-03 + + 5.2566647529602051e-01 4.0171998739242554e-01 + <_> + + 0 -1 1694 4.5496959239244461e-02 + + 5.2378678321838379e-01 2.6857739686965942e-01 + <_> + + 0 -1 1695 -2.0319599658250809e-02 + + 2.1304459869861603e-01 4.9797388911247253e-01 + <_> + + 0 -1 1696 2.6994998916052282e-04 + + 4.8140418529510498e-01 5.5431222915649414e-01 + <_> + + 0 -1 1697 -1.8232699949294329e-03 + + 6.4825797080993652e-01 4.7099891304969788e-01 + <_> + + 0 -1 1698 -6.3015790656208992e-03 + + 4.5819279551506042e-01 5.3062361478805542e-01 + <_> + + 0 -1 1699 -2.4139499873854220e-04 + + 5.2320867776870728e-01 4.0517631173133850e-01 + <_> + + 0 -1 1700 -1.0330369696021080e-03 + + 5.5562019348144531e-01 4.7891938686370850e-01 + <_> + + 0 -1 1701 1.8041160365100950e-04 + + 5.2294427156448364e-01 4.0118101239204407e-01 + <_> + + 0 -1 1702 -6.1407860368490219e-02 + + 6.2986820936203003e-01 5.0107032060623169e-01 + <_> + + 0 -1 1703 -6.9543913006782532e-02 + + 7.2282809019088745e-01 4.7731840610504150e-01 + <_> + + 0 -1 1704 -7.0542663335800171e-02 + + 2.2695130109786987e-01 5.1825290918350220e-01 + <_> + + 0 -1 1705 2.4423799477517605e-03 + + 5.2370971441268921e-01 4.0981510281562805e-01 + <_> + + 0 -1 1706 1.5494349645450711e-03 + + 4.7737509012222290e-01 5.4680430889129639e-01 + <_> + + 0 -1 1707 -2.3914219811558723e-02 + + 7.1469759941101074e-01 4.7838249802589417e-01 + <_> + + 0 -1 1708 -1.2453690171241760e-02 + + 2.6352968811988831e-01 5.2411228418350220e-01 + <_> + + 0 -1 1709 -2.0760179904755205e-04 + + 3.6237570643424988e-01 5.1136088371276855e-01 + <_> + + 0 -1 1710 2.9781080229440704e-05 + + 4.7059321403503418e-01 5.4328018426895142e-01 + <_> + 211 + 1.0474919891357422e+02 + + <_> + + 0 -1 1711 1.1772749945521355e-02 + + 3.8605189323425293e-01 6.4211672544479370e-01 + <_> + + 0 -1 1712 2.7037570253014565e-02 + + 4.3856549263000488e-01 6.7540389299392700e-01 + <_> + + 0 -1 1713 -3.6419500247575343e-05 + + 5.4871010780334473e-01 3.4233158826828003e-01 + <_> + + 0 -1 1714 1.9995409529656172e-03 + + 3.2305321097373962e-01 5.4003179073333740e-01 + <_> + + 0 -1 1715 4.5278300531208515e-03 + + 5.0916397571563721e-01 2.9350438714027405e-01 + <_> + + 0 -1 1716 4.7890920541249216e-04 + + 4.1781538724899292e-01 5.3440642356872559e-01 + <_> + + 0 -1 1717 1.1720920447260141e-03 + + 2.8991821408271790e-01 5.1320707798004150e-01 + <_> + + 0 -1 1718 9.5305702416226268e-04 + + 4.2801249027252197e-01 5.5608451366424561e-01 + <_> + + 0 -1 1719 1.5099150004971307e-05 + + 4.0448719263076782e-01 5.4047602415084839e-01 + <_> + + 0 -1 1720 -6.0817901976406574e-04 + + 4.2717689275741577e-01 5.5034661293029785e-01 + <_> + + 0 -1 1721 3.3224520739167929e-03 + + 3.9627239108085632e-01 5.3697347640991211e-01 + <_> + + 0 -1 1722 -1.1037490330636501e-03 + + 4.7271779179573059e-01 5.2377498149871826e-01 + <_> + + 0 -1 1723 -1.4350269921123981e-03 + + 5.6030082702636719e-01 4.2235091328620911e-01 + <_> + + 0 -1 1724 2.0767399109899998e-03 + + 5.2259171009063721e-01 4.7327259182929993e-01 + <_> + + 0 -1 1725 -1.6412809782195836e-04 + + 3.9990758895874023e-01 5.4327398538589478e-01 + <_> + + 0 -1 1726 8.8302437216043472e-03 + + 4.6783858537673950e-01 6.0273271799087524e-01 + <_> + + 0 -1 1727 -1.0552070103585720e-02 + + 3.4939670562744141e-01 5.2139747142791748e-01 + <_> + + 0 -1 1728 -2.2731600329279900e-03 + + 6.1858189105987549e-01 4.7490629553794861e-01 + <_> + + 0 -1 1729 -8.4786332445219159e-04 + + 5.2853411436080933e-01 3.8434821367263794e-01 + <_> + + 0 -1 1730 1.2081359745934606e-03 + + 5.3606408834457397e-01 3.4473359584808350e-01 + <_> + + 0 -1 1731 2.6512730401009321e-03 + + 4.5582920312881470e-01 6.1939620971679688e-01 + <_> + + 0 -1 1732 -1.1012479662895203e-03 + + 3.6802300810813904e-01 5.3276282548904419e-01 + <_> + + 0 -1 1733 4.9561518244445324e-04 + + 3.9605951309204102e-01 5.2749407291412354e-01 + <_> + + 0 -1 1734 -4.3901771306991577e-02 + + 7.0204448699951172e-01 4.9928390979766846e-01 + <_> + + 0 -1 1735 3.4690350294113159e-02 + + 5.0491642951965332e-01 2.7666029334068298e-01 + <_> + + 0 -1 1736 -2.7442190330475569e-03 + + 2.6726329326629639e-01 5.2749711275100708e-01 + <_> + + 0 -1 1737 3.3316588960587978e-03 + + 4.5794829726219177e-01 6.0011017322540283e-01 + <_> + + 0 -1 1738 -2.0044570788741112e-02 + + 3.1715941429138184e-01 5.2357178926467896e-01 + <_> + + 0 -1 1739 1.3492030557245016e-03 + + 5.2653628587722778e-01 4.0343248844146729e-01 + <_> + + 0 -1 1740 2.9702018946409225e-03 + + 5.3324568271636963e-01 4.5719841122627258e-01 + <_> + + 0 -1 1741 6.3039981760084629e-03 + + 4.5933109521865845e-01 6.0346359014511108e-01 + <_> + + 0 -1 1742 -1.2936590239405632e-02 + + 4.4379639625549316e-01 5.3729712963104248e-01 + <_> + + 0 -1 1743 4.0148729458451271e-03 + + 4.6803238987922668e-01 6.4378339052200317e-01 + <_> + + 0 -1 1744 -2.6401679497212172e-03 + + 3.7096318602561951e-01 5.3143328428268433e-01 + <_> + + 0 -1 1745 1.3918439857661724e-02 + + 4.7235551476478577e-01 7.1308088302612305e-01 + <_> + + 0 -1 1746 -4.5087869511917233e-04 + + 4.4923940300941467e-01 5.3704041242599487e-01 + <_> + + 0 -1 1747 2.5384349282830954e-04 + + 4.4068640470504761e-01 5.5144029855728149e-01 + <_> + + 0 -1 1748 2.2710000630468130e-03 + + 4.6824169158935547e-01 5.9679841995239258e-01 + <_> + + 0 -1 1749 2.4120779708027840e-03 + + 5.0793921947479248e-01 3.0185988545417786e-01 + <_> + + 0 -1 1750 -3.6025670851813629e-05 + + 5.6010371446609497e-01 4.4710969924926758e-01 + <_> + + 0 -1 1751 -7.4905529618263245e-03 + + 2.2075350582599640e-01 4.9899441003799438e-01 + <_> + + 0 -1 1752 -1.7513120546936989e-02 + + 6.5312159061431885e-01 5.0176489353179932e-01 + <_> + + 0 -1 1753 1.4281630516052246e-01 + + 4.9679630994796753e-01 1.4820620417594910e-01 + <_> + + 0 -1 1754 5.5345268920063972e-03 + + 4.8989468812942505e-01 5.9542238712310791e-01 + <_> + + 0 -1 1755 -9.6323591424152255e-04 + + 3.9271169900894165e-01 5.1960742473602295e-01 + <_> + + 0 -1 1756 -2.0370010752230883e-03 + + 5.6133252382278442e-01 4.8848581314086914e-01 + <_> + + 0 -1 1757 1.6614829655736685e-03 + + 4.4728800654411316e-01 5.5788809061050415e-01 + <_> + + 0 -1 1758 -3.1188090797513723e-03 + + 3.8405328989028931e-01 5.3974777460098267e-01 + <_> + + 0 -1 1759 -6.4000617712736130e-03 + + 5.8439838886260986e-01 4.5332181453704834e-01 + <_> + + 0 -1 1760 3.1319601112045348e-04 + + 5.4392218589782715e-01 4.2347279191017151e-01 + <_> + + 0 -1 1761 -1.8222099170088768e-02 + + 1.2884649634361267e-01 4.9584048986434937e-01 + <_> + + 0 -1 1762 8.7969247251749039e-03 + + 4.9512979388237000e-01 7.1534800529479980e-01 + <_> + + 0 -1 1763 -4.2395070195198059e-03 + + 3.9465999603271484e-01 5.1949369907379150e-01 + <_> + + 0 -1 1764 9.7086271271109581e-03 + + 4.8975038528442383e-01 6.0649001598358154e-01 + <_> + + 0 -1 1765 -3.9934171363711357e-03 + + 3.2454401254653931e-01 5.0608289241790771e-01 + <_> + + 0 -1 1766 -1.6785059124231339e-02 + + 1.5819530189037323e-01 5.2037787437438965e-01 + <_> + + 0 -1 1767 1.8272090703248978e-02 + + 4.6809351444244385e-01 6.6269791126251221e-01 + <_> + + 0 -1 1768 5.6872838176786900e-03 + + 5.2116978168487549e-01 3.5121849179267883e-01 + <_> + + 0 -1 1769 -1.0739039862528443e-03 + + 5.7683861255645752e-01 4.5298451185226440e-01 + <_> + + 0 -1 1770 -3.7093870341777802e-03 + + 4.5077630877494812e-01 5.3135812282562256e-01 + <_> + + 0 -1 1771 -2.1110709349159151e-04 + + 5.4608201980590820e-01 4.3333768844604492e-01 + <_> + + 0 -1 1772 1.0670139454305172e-03 + + 5.3718560934066772e-01 4.0783908963203430e-01 + <_> + + 0 -1 1773 3.5943021066486835e-03 + + 4.4712871313095093e-01 5.6438362598419189e-01 + <_> + + 0 -1 1774 -5.1776031032204628e-03 + + 4.4993931055068970e-01 5.2803301811218262e-01 + <_> + + 0 -1 1775 -2.5414369883947074e-04 + + 5.5161732435226440e-01 4.4077080488204956e-01 + <_> + + 0 -1 1776 6.3522560521960258e-03 + + 5.1941901445388794e-01 2.4652279913425446e-01 + <_> + + 0 -1 1777 -4.4205080484971404e-04 + + 3.8307058811187744e-01 5.1396822929382324e-01 + <_> + + 0 -1 1778 7.4488727841526270e-04 + + 4.8910909891128540e-01 5.9747868776321411e-01 + <_> + + 0 -1 1779 -3.5116379149258137e-03 + + 7.4136817455291748e-01 4.7687649726867676e-01 + <_> + + 0 -1 1780 -1.2540910392999649e-02 + + 3.6488190293312073e-01 5.2528268098831177e-01 + <_> + + 0 -1 1781 9.4931852072477341e-03 + + 5.1004928350448608e-01 3.6295869946479797e-01 + <_> + + 0 -1 1782 1.2961150147020817e-02 + + 5.2324420213699341e-01 4.3335610628128052e-01 + <_> + + 0 -1 1783 4.7209449112415314e-03 + + 4.6481490135192871e-01 6.3310527801513672e-01 + <_> + + 0 -1 1784 -2.3119079414755106e-03 + + 5.9303098917007446e-01 4.5310580730438232e-01 + <_> + + 0 -1 1785 -2.8262299019843340e-03 + + 3.8704779744148254e-01 5.2571010589599609e-01 + <_> + + 0 -1 1786 -1.4311339473351836e-03 + + 5.5225032567977905e-01 4.5618548989295959e-01 + <_> + + 0 -1 1787 1.9378310535103083e-03 + + 4.5462208986282349e-01 5.7369667291641235e-01 + <_> + + 0 -1 1788 2.6343559147790074e-04 + + 5.3457391262054443e-01 4.5718750357627869e-01 + <_> + + 0 -1 1789 7.8257522545754910e-04 + + 3.9678159356117249e-01 5.2201879024505615e-01 + <_> + + 0 -1 1790 -1.9550440832972527e-02 + + 2.8296428918838501e-01 5.2435082197189331e-01 + <_> + + 0 -1 1791 4.3914958951063454e-04 + + 4.5900669693946838e-01 5.8990901708602905e-01 + <_> + + 0 -1 1792 2.1452000364661217e-02 + + 5.2314108610153198e-01 2.8553789854049683e-01 + <_> + + 0 -1 1793 5.8973580598831177e-04 + + 4.3972569704055786e-01 5.5064219236373901e-01 + <_> + + 0 -1 1794 -2.6157610118389130e-02 + + 3.1350791454315186e-01 5.1891750097274780e-01 + <_> + + 0 -1 1795 -1.3959860429167747e-02 + + 3.2132729887962341e-01 5.0407177209854126e-01 + <_> + + 0 -1 1796 -6.3699018210172653e-03 + + 6.3875448703765869e-01 4.8495069146156311e-01 + <_> + + 0 -1 1797 -8.5613820701837540e-03 + + 2.7591320872306824e-01 5.0320190191268921e-01 + <_> + + 0 -1 1798 9.6622901037335396e-04 + + 4.6856409311294556e-01 5.8348792791366577e-01 + <_> + + 0 -1 1799 7.6550268568098545e-04 + + 5.1752072572708130e-01 3.8964220881462097e-01 + <_> + + 0 -1 1800 -8.1833340227603912e-03 + + 2.0691369473934174e-01 5.2081221342086792e-01 + <_> + + 0 -1 1801 -9.3976939097046852e-03 + + 6.1340910196304321e-01 4.6412229537963867e-01 + <_> + + 0 -1 1802 4.8028980381786823e-03 + + 5.4541081190109253e-01 4.3952199816703796e-01 + <_> + + 0 -1 1803 -3.5680569708347321e-03 + + 6.3444852828979492e-01 4.6810939908027649e-01 + <_> + + 0 -1 1804 4.0733120404183865e-03 + + 5.2926832437515259e-01 4.0156200528144836e-01 + <_> + + 0 -1 1805 1.2568129459396005e-03 + + 4.3929880857467651e-01 5.4528248310089111e-01 + <_> + + 0 -1 1806 -2.9065010603517294e-03 + + 5.8988320827484131e-01 4.8633798956871033e-01 + <_> + + 0 -1 1807 -2.4409340694546700e-03 + + 4.0693649649620056e-01 5.2474218606948853e-01 + <_> + + 0 -1 1808 2.4830700829625130e-02 + + 5.1827257871627808e-01 3.6825248599052429e-01 + <_> + + 0 -1 1809 -4.8854008316993713e-02 + + 1.3075779378414154e-01 4.9612811207771301e-01 + <_> + + 0 -1 1810 -1.6110379947349429e-03 + + 6.4210057258605957e-01 4.8726621270179749e-01 + <_> + + 0 -1 1811 -9.7009479999542236e-02 + + 4.7769349068403244e-02 4.9509888887405396e-01 + <_> + + 0 -1 1812 1.1209240183234215e-03 + + 4.6162670850753784e-01 5.3547459840774536e-01 + <_> + + 0 -1 1813 -1.3064090162515640e-03 + + 6.2618541717529297e-01 4.6388059854507446e-01 + <_> + + 0 -1 1814 4.5771620352752507e-04 + + 5.3844177722930908e-01 4.6466401219367981e-01 + <_> + + 0 -1 1815 -6.3149951165542006e-04 + + 3.8040471076965332e-01 5.1302570104598999e-01 + <_> + + 0 -1 1816 1.4505970466416329e-04 + + 4.5543101429939270e-01 5.6644618511199951e-01 + <_> + + 0 -1 1817 -1.6474550589919090e-02 + + 6.5969580411911011e-01 4.7158598899841309e-01 + <_> + + 0 -1 1818 1.3369579799473286e-02 + + 5.1954662799835205e-01 3.0359649658203125e-01 + <_> + + 0 -1 1819 1.0271780047332868e-04 + + 5.2291762828826904e-01 4.1070660948753357e-01 + <_> + + 0 -1 1820 -5.5311559699475765e-03 + + 6.3528877496719360e-01 4.9609071016311646e-01 + <_> + + 0 -1 1821 -2.6187049224972725e-03 + + 3.8245460391044617e-01 5.1409840583801270e-01 + <_> + + 0 -1 1822 5.0834268331527710e-03 + + 4.9504399299621582e-01 6.2208187580108643e-01 + <_> + + 0 -1 1823 7.9818159341812134e-02 + + 4.9523359537124634e-01 1.3224759697914124e-01 + <_> + + 0 -1 1824 -9.9226586520671844e-02 + + 7.5427287817001343e-01 5.0084167718887329e-01 + <_> + + 0 -1 1825 -6.5174017800018191e-04 + + 3.6993029713630676e-01 5.1301211118698120e-01 + <_> + + 0 -1 1826 -1.8996849656105042e-02 + + 6.6891789436340332e-01 4.9212029576301575e-01 + <_> + + 0 -1 1827 1.7346899956464767e-02 + + 4.9833008646965027e-01 1.8591980636119843e-01 + <_> + + 0 -1 1828 5.5082101607695222e-04 + + 4.5744240283966064e-01 5.5221217870712280e-01 + <_> + + 0 -1 1829 2.0056050270795822e-03 + + 5.1317447423934937e-01 3.8564699888229370e-01 + <_> + + 0 -1 1830 -7.7688191086053848e-03 + + 4.3617001175880432e-01 5.4343092441558838e-01 + <_> + + 0 -1 1831 5.0878278911113739e-02 + + 4.6827208995819092e-01 6.8406397104263306e-01 + <_> + + 0 -1 1832 -2.2901780903339386e-03 + + 4.3292450904846191e-01 5.3060990571975708e-01 + <_> + + 0 -1 1833 -1.5715380141045898e-04 + + 5.3700572252273560e-01 4.3781641125679016e-01 + <_> + + 0 -1 1834 1.0519240051507950e-01 + + 5.1372742652893066e-01 6.7361466586589813e-02 + <_> + + 0 -1 1835 2.7198919560760260e-03 + + 4.1120609641075134e-01 5.2556651830673218e-01 + <_> + + 0 -1 1836 4.8337779939174652e-02 + + 5.4046237468719482e-01 4.4389671087265015e-01 + <_> + + 0 -1 1837 9.5703761326149106e-04 + + 4.3559691309928894e-01 5.3995108604431152e-01 + <_> + + 0 -1 1838 -2.5371259078383446e-02 + + 5.9951752424240112e-01 5.0310248136520386e-01 + <_> + + 0 -1 1839 5.2457951009273529e-02 + + 4.9502879381179810e-01 1.3983510434627533e-01 + <_> + + 0 -1 1840 -1.2365629896521568e-02 + + 6.3972991704940796e-01 4.9641060829162598e-01 + <_> + + 0 -1 1841 -1.4589719474315643e-01 + + 1.0016699880361557e-01 4.9463221430778503e-01 + <_> + + 0 -1 1842 -1.5908600762486458e-02 + + 3.3123299479484558e-01 5.2083408832550049e-01 + <_> + + 0 -1 1843 3.9486068999394774e-04 + + 4.4063639640808105e-01 5.4261028766632080e-01 + <_> + + 0 -1 1844 -5.2454001270234585e-03 + + 2.7995899319648743e-01 5.1899671554565430e-01 + <_> + + 0 -1 1845 -5.0421799533069134e-03 + + 6.9875800609588623e-01 4.7521421313285828e-01 + <_> + + 0 -1 1846 2.9812189750373363e-03 + + 4.9832889437675476e-01 6.3074797391891479e-01 + <_> + + 0 -1 1847 -7.2884308174252510e-03 + + 2.9823330044746399e-01 5.0268697738647461e-01 + <_> + + 0 -1 1848 1.5094350092113018e-03 + + 5.3084421157836914e-01 3.8329708576202393e-01 + <_> + + 0 -1 1849 -9.3340799212455750e-03 + + 2.0379640161991119e-01 4.9698171019554138e-01 + <_> + + 0 -1 1850 2.8667140752077103e-02 + + 5.0256967544555664e-01 6.9280272722244263e-01 + <_> + + 0 -1 1851 1.7019680142402649e-01 + + 4.9600529670715332e-01 1.4764429628849030e-01 + <_> + + 0 -1 1852 -3.2614478841423988e-03 + + 5.6030637025833130e-01 4.8260560631752014e-01 + <_> + + 0 -1 1853 5.5769277969375253e-04 + + 5.2055621147155762e-01 4.1296330094337463e-01 + <_> + + 0 -1 1854 3.6258339881896973e-01 + + 5.2216529846191406e-01 3.7686121463775635e-01 + <_> + + 0 -1 1855 -1.1615130119025707e-02 + + 6.0226827859878540e-01 4.6374899148941040e-01 + <_> + + 0 -1 1856 -4.0795197710394859e-03 + + 4.0704470872879028e-01 5.3374791145324707e-01 + <_> + + 0 -1 1857 5.7204300537705421e-04 + + 4.6018350124359131e-01 5.9003931283950806e-01 + <_> + + 0 -1 1858 6.7543348995968699e-04 + + 5.3982520103454590e-01 4.3454289436340332e-01 + <_> + + 0 -1 1859 6.3295697327703238e-04 + + 5.2015632390975952e-01 4.0513589978218079e-01 + <_> + + 0 -1 1860 1.2435320531949401e-03 + + 4.6423879265785217e-01 5.5474412441253662e-01 + <_> + + 0 -1 1861 -4.7363857738673687e-03 + + 6.1985671520233154e-01 4.6725520491600037e-01 + <_> + + 0 -1 1862 -6.4658462069928646e-03 + + 6.8373328447341919e-01 5.0190007686614990e-01 + <_> + + 0 -1 1863 3.5017321351915598e-04 + + 4.3448030948638916e-01 5.3636229038238525e-01 + <_> + + 0 -1 1864 1.5754920605104417e-04 + + 4.7600790858268738e-01 5.7320207357406616e-01 + <_> + + 0 -1 1865 9.9774366244673729e-03 + + 5.0909858942031860e-01 3.6350399255752563e-01 + <_> + + 0 -1 1866 -4.1464529931545258e-04 + + 5.5700647830963135e-01 4.5938020944595337e-01 + <_> + + 0 -1 1867 -3.5888899583369493e-04 + + 5.3568458557128906e-01 4.3391349911689758e-01 + <_> + + 0 -1 1868 4.0463250479660928e-04 + + 4.4398030638694763e-01 5.4367768764495850e-01 + <_> + + 0 -1 1869 -8.2184787606820464e-04 + + 4.0422949194908142e-01 5.1762992143630981e-01 + <_> + + 0 -1 1870 5.9467419050633907e-03 + + 4.9276518821716309e-01 5.6337797641754150e-01 + <_> + + 0 -1 1871 -2.1753389388322830e-02 + + 8.0062937736511230e-01 4.8008409142494202e-01 + <_> + + 0 -1 1872 -1.4540379866957664e-02 + + 3.9460548758506775e-01 5.1822227239608765e-01 + <_> + + 0 -1 1873 -4.0510769933462143e-02 + + 2.1324990317225456e-02 4.9357929825782776e-01 + <_> + + 0 -1 1874 -5.8458268176764250e-04 + + 4.0127959847450256e-01 5.3140252828598022e-01 + <_> + + 0 -1 1875 5.5151800625026226e-03 + + 4.6424189209938049e-01 5.8962607383728027e-01 + <_> + + 0 -1 1876 -6.0626221820712090e-03 + + 6.5021592378616333e-01 5.0164777040481567e-01 + <_> + + 0 -1 1877 9.4535842537879944e-02 + + 5.2647089958190918e-01 4.1268271207809448e-01 + <_> + + 0 -1 1878 4.7315051779150963e-03 + + 4.8791998624801636e-01 5.8924478292465210e-01 + <_> + + 0 -1 1879 -5.2571471314877272e-04 + + 3.9172801375389099e-01 5.1894128322601318e-01 + <_> + + 0 -1 1880 -2.5464049540460110e-03 + + 5.8375990390777588e-01 4.9857059121131897e-01 + <_> + + 0 -1 1881 -2.6075689122080803e-02 + + 1.2619839608669281e-01 4.9558219313621521e-01 + <_> + + 0 -1 1882 -5.4779709316790104e-03 + + 5.7225137948989868e-01 5.0102657079696655e-01 + <_> + + 0 -1 1883 5.1337741315364838e-03 + + 5.2732622623443604e-01 4.2263761162757874e-01 + <_> + + 0 -1 1884 4.7944980906322598e-04 + + 4.4500669836997986e-01 5.8195871114730835e-01 + <_> + + 0 -1 1885 -2.1114079281687737e-03 + + 5.7576531171798706e-01 4.5117148756980896e-01 + <_> + + 0 -1 1886 -1.3179990462958813e-02 + + 1.8843810260295868e-01 5.1607340574264526e-01 + <_> + + 0 -1 1887 -4.7968099825084209e-03 + + 6.5897899866104126e-01 4.7361189126968384e-01 + <_> + + 0 -1 1888 6.7483168095350266e-03 + + 5.2594298124313354e-01 3.3563950657844543e-01 + <_> + + 0 -1 1889 1.4623369788751006e-03 + + 5.3552711009979248e-01 4.2640921473503113e-01 + <_> + + 0 -1 1890 4.7645159065723419e-03 + + 5.0344067811965942e-01 5.7868278026580811e-01 + <_> + + 0 -1 1891 6.8066660314798355e-03 + + 4.7566050291061401e-01 6.6778290271759033e-01 + <_> + + 0 -1 1892 3.6608621012419462e-03 + + 5.3696119785308838e-01 4.3115469813346863e-01 + <_> + + 0 -1 1893 2.1449640393257141e-02 + + 4.9686419963836670e-01 1.8888160586357117e-01 + <_> + + 0 -1 1894 4.1678901761770248e-03 + + 4.9307331442832947e-01 5.8153688907623291e-01 + <_> + + 0 -1 1895 8.6467564105987549e-03 + + 5.2052050828933716e-01 4.1325950622558594e-01 + <_> + + 0 -1 1896 -3.6114078829996288e-04 + + 5.4835551977157593e-01 4.8009279370307922e-01 + <_> + + 0 -1 1897 1.0808729566633701e-03 + + 4.6899020671844482e-01 6.0414212942123413e-01 + <_> + + 0 -1 1898 5.7719959877431393e-03 + + 5.1711422204971313e-01 3.0532771348953247e-01 + <_> + + 0 -1 1899 1.5720770461484790e-03 + + 5.2199780941009521e-01 4.1788038611412048e-01 + <_> + + 0 -1 1900 -1.9307859474793077e-03 + + 5.8603698015213013e-01 4.8129200935363770e-01 + <_> + + 0 -1 1901 -7.8926272690296173e-03 + + 1.7492769658565521e-01 4.9717339873313904e-01 + <_> + + 0 -1 1902 -2.2224679123610258e-03 + + 4.3425890803337097e-01 5.2128481864929199e-01 + <_> + + 0 -1 1903 1.9011989934369922e-03 + + 4.7651869058609009e-01 6.8920552730560303e-01 + <_> + + 0 -1 1904 2.7576119173318148e-03 + + 5.2621912956237793e-01 4.3374860286712646e-01 + <_> + + 0 -1 1905 5.1787449046969414e-03 + + 4.8040691018104553e-01 7.8437292575836182e-01 + <_> + + 0 -1 1906 -9.0273341629654169e-04 + + 4.1208469867706299e-01 5.3534239530563354e-01 + <_> + + 0 -1 1907 5.1797959022223949e-03 + + 4.7403728961944580e-01 6.4259600639343262e-01 + <_> + + 0 -1 1908 -1.0114000178873539e-02 + + 2.4687920510768890e-01 5.1750177145004272e-01 + <_> + + 0 -1 1909 -1.8617060035467148e-02 + + 5.7562941312789917e-01 4.6289789676666260e-01 + <_> + + 0 -1 1910 5.9225959703326225e-03 + + 5.1696258783340454e-01 3.2142710685729980e-01 + <_> + + 0 -1 1911 -6.2945079989731312e-03 + + 3.8720148801803589e-01 5.1416367292404175e-01 + <_> + + 0 -1 1912 6.5353019163012505e-03 + + 4.8530489206314087e-01 6.3104897737503052e-01 + <_> + + 0 -1 1913 1.0878399480134249e-03 + + 5.1173150539398193e-01 3.7232589721679688e-01 + <_> + + 0 -1 1914 -2.2542240098118782e-02 + + 5.6927400827407837e-01 4.8871129751205444e-01 + <_> + + 0 -1 1915 -3.0065660830587149e-03 + + 2.5560128688812256e-01 5.0039929151535034e-01 + <_> + + 0 -1 1916 7.4741272255778313e-03 + + 4.8108729720115662e-01 5.6759268045425415e-01 + <_> + + 0 -1 1917 2.6162320747971535e-02 + + 4.9711948633193970e-01 1.7772370576858521e-01 + <_> + + 0 -1 1918 9.4352738233283162e-04 + + 4.9400109052658081e-01 5.4912507534027100e-01 + <_> + + 0 -1 1919 3.3363241702318192e-02 + + 5.0076121091842651e-01 2.7907240390777588e-01 + <_> + + 0 -1 1920 -1.5118650160729885e-02 + + 7.0595788955688477e-01 4.9730318784713745e-01 + <_> + + 0 -1 1921 9.8648946732282639e-04 + + 5.1286202669143677e-01 3.7767618894577026e-01 + <_> + 213 + 1.0576110076904297e+02 + + <_> + + 0 -1 1922 -9.5150798559188843e-02 + + 6.4707571268081665e-01 4.0172868967056274e-01 + <_> + + 0 -1 1923 6.2702340073883533e-03 + + 3.9998221397399902e-01 5.7464492321014404e-01 + <_> + + 0 -1 1924 3.0018089455552399e-04 + + 3.5587701201438904e-01 5.5388098955154419e-01 + <_> + + 0 -1 1925 1.1757409665733576e-03 + + 4.2565348744392395e-01 5.3826177120208740e-01 + <_> + + 0 -1 1926 4.4235268433112651e-05 + + 3.6829081177711487e-01 5.5899268388748169e-01 + <_> + + 0 -1 1927 -2.9936920327600092e-05 + + 5.4524701833724976e-01 4.0203678607940674e-01 + <_> + + 0 -1 1928 3.0073199886828661e-03 + + 5.2390581369400024e-01 3.3178439736366272e-01 + <_> + + 0 -1 1929 -1.0513889603316784e-02 + + 4.3206891417503357e-01 5.3079837560653687e-01 + <_> + + 0 -1 1930 8.3476826548576355e-03 + + 4.5046371221542358e-01 6.4532989263534546e-01 + <_> + + 0 -1 1931 -3.1492270063608885e-03 + + 4.3134251236915588e-01 5.3705251216888428e-01 + <_> + + 0 -1 1932 -1.4435649973165710e-05 + + 5.3266030550003052e-01 3.8179719448089600e-01 + <_> + + 0 -1 1933 -4.2855090578086674e-04 + + 4.3051639199256897e-01 5.3820097446441650e-01 + <_> + + 0 -1 1934 1.5062429883982986e-04 + + 4.2359709739685059e-01 5.5449652671813965e-01 + <_> + + 0 -1 1935 7.1559831500053406e-02 + + 5.3030598163604736e-01 2.6788029074668884e-01 + <_> + + 0 -1 1936 8.4095180500298738e-04 + + 3.5571089386940002e-01 5.2054339647293091e-01 + <_> + + 0 -1 1937 6.2986500561237335e-02 + + 5.2253627777099609e-01 2.8613761067390442e-01 + <_> + + 0 -1 1938 -3.3798629883676767e-03 + + 3.6241859197616577e-01 5.2016979455947876e-01 + <_> + + 0 -1 1939 -1.1810739670181647e-04 + + 5.4744768142700195e-01 3.9598938822746277e-01 + <_> + + 0 -1 1940 -5.4505601292476058e-04 + + 3.7404221296310425e-01 5.2157157659530640e-01 + <_> + + 0 -1 1941 -1.8454910023137927e-03 + + 5.8930522203445435e-01 4.5844489336013794e-01 + <_> + + 0 -1 1942 -4.3832371011376381e-04 + + 4.0845820307731628e-01 5.3853511810302734e-01 + <_> + + 0 -1 1943 -2.4000830017030239e-03 + + 3.7774550914764404e-01 5.2935802936553955e-01 + <_> + + 0 -1 1944 -9.8795741796493530e-02 + + 2.9636120796203613e-01 5.0700891017913818e-01 + <_> + + 0 -1 1945 3.1798239797353745e-03 + + 4.8776328563690186e-01 6.7264437675476074e-01 + <_> + + 0 -1 1946 3.2406419632025063e-04 + + 4.3669110536575317e-01 5.5611097812652588e-01 + <_> + + 0 -1 1947 -3.2547250390052795e-02 + + 3.1281578540802002e-01 5.3086161613464355e-01 + <_> + + 0 -1 1948 -7.7561130747199059e-03 + + 6.5602248907089233e-01 4.6398720145225525e-01 + <_> + + 0 -1 1949 1.6027249395847321e-02 + + 5.1726800203323364e-01 3.1418979167938232e-01 + <_> + + 0 -1 1950 7.1002350523485802e-06 + + 4.0844461321830750e-01 5.3362947702407837e-01 + <_> + + 0 -1 1951 7.3422808200120926e-03 + + 4.9669221043586731e-01 6.6034650802612305e-01 + <_> + + 0 -1 1952 -1.6970280557870865e-03 + + 5.9082370996475220e-01 4.5001828670501709e-01 + <_> + + 0 -1 1953 2.4118260480463505e-03 + + 5.3151607513427734e-01 3.5997208952903748e-01 + <_> + + 0 -1 1954 -5.5300937965512276e-03 + + 2.3340409994125366e-01 4.9968141317367554e-01 + <_> + + 0 -1 1955 -2.6478730142116547e-03 + + 5.8809357881546021e-01 4.6847340464591980e-01 + <_> + + 0 -1 1956 1.1295629665255547e-02 + + 4.9837771058082581e-01 1.8845909833908081e-01 + <_> + + 0 -1 1957 -6.6952878842130303e-04 + + 5.8721381425857544e-01 4.7990199923515320e-01 + <_> + + 0 -1 1958 1.4410680159926414e-03 + + 5.1311892271041870e-01 3.5010111331939697e-01 + <_> + + 0 -1 1959 2.4637870956212282e-03 + + 5.3393721580505371e-01 4.1176390647888184e-01 + <_> + + 0 -1 1960 3.3114518737420440e-04 + + 4.3133831024169922e-01 5.3982460498809814e-01 + <_> + + 0 -1 1961 -3.3557269722223282e-02 + + 2.6753368973731995e-01 5.1791548728942871e-01 + <_> + + 0 -1 1962 1.8539419397711754e-02 + + 4.9738699197769165e-01 2.3171770572662354e-01 + <_> + + 0 -1 1963 -2.9698139405809343e-04 + + 5.5297082662582397e-01 4.6436640620231628e-01 + <_> + + 0 -1 1964 -4.5577259152196348e-04 + + 5.6295841932296753e-01 4.4691911339759827e-01 + <_> + + 0 -1 1965 -1.0158980265259743e-02 + + 6.7062127590179443e-01 4.9259188771247864e-01 + <_> + + 0 -1 1966 -2.2413829356082715e-05 + + 5.2394217252731323e-01 3.9129018783569336e-01 + <_> + + 0 -1 1967 7.2034963523037732e-05 + + 4.7994381189346313e-01 5.5017888545989990e-01 + <_> + + 0 -1 1968 -6.9267209619283676e-03 + + 6.9300097227096558e-01 4.6980848908424377e-01 + <_> + + 0 -1 1969 -7.6997838914394379e-03 + + 4.0996238589286804e-01 5.4808831214904785e-01 + <_> + + 0 -1 1970 -7.3130549862980843e-03 + + 3.2834759354591370e-01 5.0578862428665161e-01 + <_> + + 0 -1 1971 1.9650589674711227e-03 + + 4.9780470132827759e-01 6.3982498645782471e-01 + <_> + + 0 -1 1972 7.1647600270807743e-03 + + 4.6611601114273071e-01 6.2221372127532959e-01 + <_> + + 0 -1 1973 -2.4078639224171638e-02 + + 2.3346449434757233e-01 5.2221620082855225e-01 + <_> + + 0 -1 1974 -2.1027969196438789e-02 + + 1.1836539953947067e-01 4.9382260441780090e-01 + <_> + + 0 -1 1975 3.6017020465806127e-04 + + 5.3250199556350708e-01 4.1167110204696655e-01 + <_> + + 0 -1 1976 -1.7219729721546173e-02 + + 6.2787622213363647e-01 4.6642690896987915e-01 + <_> + + 0 -1 1977 -7.8672142699360847e-03 + + 3.4034150838851929e-01 5.2497369050979614e-01 + <_> + + 0 -1 1978 -4.4777389848604798e-04 + + 3.6104118824005127e-01 5.0862592458724976e-01 + <_> + + 0 -1 1979 5.5486010387539864e-03 + + 4.8842659592628479e-01 6.2034982442855835e-01 + <_> + + 0 -1 1980 -6.9461148232221603e-03 + + 2.6259300112724304e-01 5.0110971927642822e-01 + <_> + + 0 -1 1981 1.3569870498031378e-04 + + 4.3407949805259705e-01 5.6283122301101685e-01 + <_> + + 0 -1 1982 -4.5880250632762909e-02 + + 6.5079987049102783e-01 4.6962749958038330e-01 + <_> + + 0 -1 1983 -2.1582560613751411e-02 + + 3.8265028595924377e-01 5.2876168489456177e-01 + <_> + + 0 -1 1984 -2.0209539681673050e-02 + + 3.2333680987358093e-01 5.0744771957397461e-01 + <_> + + 0 -1 1985 5.8496710844337940e-03 + + 5.1776039600372314e-01 4.4896709918975830e-01 + <_> + + 0 -1 1986 -5.7476379879517481e-05 + + 4.0208509564399719e-01 5.2463638782501221e-01 + <_> + + 0 -1 1987 -1.1513100471347570e-03 + + 6.3150721788406372e-01 4.9051541090011597e-01 + <_> + + 0 -1 1988 1.9862831104546785e-03 + + 4.7024598717689514e-01 6.4971512556076050e-01 + <_> + + 0 -1 1989 -5.2719512023031712e-03 + + 3.6503839492797852e-01 5.2276527881622314e-01 + <_> + + 0 -1 1990 1.2662699446082115e-03 + + 5.1661008596420288e-01 3.8776180148124695e-01 + <_> + + 0 -1 1991 -6.2919440679252148e-03 + + 7.3758941888809204e-01 5.0238478183746338e-01 + <_> + + 0 -1 1992 6.7360111279413104e-04 + + 4.4232261180877686e-01 5.4955857992172241e-01 + <_> + + 0 -1 1993 -1.0523450328037143e-03 + + 5.9763962030410767e-01 4.8595830798149109e-01 + <_> + + 0 -1 1994 -4.4216238893568516e-04 + + 5.9559392929077148e-01 4.3989309668540955e-01 + <_> + + 0 -1 1995 1.1747940443456173e-03 + + 5.3498882055282593e-01 4.6050581336021423e-01 + <_> + + 0 -1 1996 5.2457437850534916e-03 + + 5.0491911172866821e-01 2.9415771365165710e-01 + <_> + + 0 -1 1997 -2.4539720267057419e-02 + + 2.5501778721809387e-01 5.2185869216918945e-01 + <_> + + 0 -1 1998 7.3793041519820690e-04 + + 4.4248610734939575e-01 5.4908162355422974e-01 + <_> + + 0 -1 1999 1.4233799884095788e-03 + + 5.3195142745971680e-01 4.0813559293746948e-01 + <_> + + 0 -1 2000 -2.4149110540747643e-03 + + 4.0876591205596924e-01 5.2389502525329590e-01 + <_> + + 0 -1 2001 -1.2165299849584699e-03 + + 5.6745791435241699e-01 4.9080529808998108e-01 + <_> + + 0 -1 2002 -1.2438809499144554e-03 + + 4.1294258832931519e-01 5.2561181783676147e-01 + <_> + + 0 -1 2003 6.1942739412188530e-03 + + 5.0601941347122192e-01 7.3136532306671143e-01 + <_> + + 0 -1 2004 -1.6607169527560472e-03 + + 5.9796321392059326e-01 4.5963698625564575e-01 + <_> + + 0 -1 2005 -2.7316259220242500e-02 + + 4.1743651032447815e-01 5.3088420629501343e-01 + <_> + + 0 -1 2006 -1.5845570014789701e-03 + + 5.6158047914505005e-01 4.5194861292839050e-01 + <_> + + 0 -1 2007 -1.5514739789068699e-03 + + 4.0761870145797729e-01 5.3607851266860962e-01 + <_> + + 0 -1 2008 3.8446558755822480e-04 + + 4.3472939729690552e-01 5.4304420948028564e-01 + <_> + + 0 -1 2009 -1.4672259800136089e-02 + + 1.6593049466609955e-01 5.1460939645767212e-01 + <_> + + 0 -1 2010 8.1608882173895836e-03 + + 4.9618190526962280e-01 1.8847459554672241e-01 + <_> + + 0 -1 2011 1.1121659772470593e-03 + + 4.8682639002799988e-01 6.0938161611557007e-01 + <_> + + 0 -1 2012 -7.2603770531713963e-03 + + 6.2843251228332520e-01 4.6903759241104126e-01 + <_> + + 0 -1 2013 -2.4046430189628154e-04 + + 5.5750000476837158e-01 4.0460440516471863e-01 + <_> + + 0 -1 2014 -2.3348190006799996e-04 + + 4.1157621145248413e-01 5.2528482675552368e-01 + <_> + + 0 -1 2015 5.5736480280756950e-03 + + 4.7300729155540466e-01 5.6901007890701294e-01 + <_> + + 0 -1 2016 3.0623769387602806e-02 + + 4.9718868732452393e-01 1.7400950193405151e-01 + <_> + + 0 -1 2017 9.2074798885732889e-04 + + 5.3721177577972412e-01 4.3548721075057983e-01 + <_> + + 0 -1 2018 -4.3550739064812660e-05 + + 5.3668838739395142e-01 4.3473169207572937e-01 + <_> + + 0 -1 2019 -6.6452710889279842e-03 + + 3.4355181455612183e-01 5.1605331897735596e-01 + <_> + + 0 -1 2020 4.3221998959779739e-02 + + 4.7667920589447021e-01 7.2936528921127319e-01 + <_> + + 0 -1 2021 2.2331769578158855e-03 + + 5.0293159484863281e-01 5.6331712007522583e-01 + <_> + + 0 -1 2022 3.1829739455133677e-03 + + 4.0160921216011047e-01 5.1921367645263672e-01 + <_> + + 0 -1 2023 -1.8027749320026487e-04 + + 4.0883159637451172e-01 5.4179197549819946e-01 + <_> + + 0 -1 2024 -5.2934689447283745e-03 + + 4.0756770968437195e-01 5.2435618638992310e-01 + <_> + + 0 -1 2025 1.2750959722325206e-03 + + 4.9132829904556274e-01 6.3870108127593994e-01 + <_> + + 0 -1 2026 4.3385322205722332e-03 + + 5.0316721200942993e-01 2.9473468661308289e-01 + <_> + + 0 -1 2027 8.5250744596123695e-03 + + 4.9497890472412109e-01 6.3088691234588623e-01 + <_> + + 0 -1 2028 -9.4266352243721485e-04 + + 5.3283667564392090e-01 4.2856499552726746e-01 + <_> + + 0 -1 2029 1.3609660090878606e-03 + + 4.9915251135826111e-01 5.9415012598037720e-01 + <_> + + 0 -1 2030 4.4782509212382138e-04 + + 4.5735040307044983e-01 5.8544808626174927e-01 + <_> + + 0 -1 2031 1.3360050506889820e-03 + + 4.6043589711189270e-01 5.8490520715713501e-01 + <_> + + 0 -1 2032 -6.0967548051849008e-04 + + 3.9693889021873474e-01 5.2294230461120605e-01 + <_> + + 0 -1 2033 -2.3656780831515789e-03 + + 5.8083200454711914e-01 4.8983570933341980e-01 + <_> + + 0 -1 2034 1.0734340175986290e-03 + + 4.3512108922004700e-01 5.4700392484664917e-01 + <_> + + 0 -1 2035 2.1923359017819166e-03 + + 5.3550601005554199e-01 3.8429039716720581e-01 + <_> + + 0 -1 2036 5.4968618787825108e-03 + + 5.0181388854980469e-01 2.8271919488906860e-01 + <_> + + 0 -1 2037 -7.5368821620941162e-02 + + 1.2250760197639465e-01 5.1488268375396729e-01 + <_> + + 0 -1 2038 2.5134470313787460e-02 + + 4.7317668795585632e-01 7.0254462957382202e-01 + <_> + + 0 -1 2039 -2.9358599931583740e-05 + + 5.4305320978164673e-01 4.6560868620872498e-01 + <_> + + 0 -1 2040 -5.8355910005047917e-04 + + 4.0310400724411011e-01 5.1901197433471680e-01 + <_> + + 0 -1 2041 -2.6639450807124376e-03 + + 4.3081268668174744e-01 5.1617711782455444e-01 + <_> + + 0 -1 2042 -1.3804089976474643e-03 + + 6.2198299169540405e-01 4.6955159306526184e-01 + <_> + + 0 -1 2043 1.2313219485804439e-03 + + 5.3793638944625854e-01 4.4258311390876770e-01 + <_> + + 0 -1 2044 -1.4644179827882908e-05 + + 5.2816402912139893e-01 4.2225030064582825e-01 + <_> + + 0 -1 2045 -1.2818809598684311e-02 + + 2.5820928812026978e-01 5.1799327135086060e-01 + <_> + + 0 -1 2046 2.2852189838886261e-02 + + 4.7786930203437805e-01 7.6092642545700073e-01 + <_> + + 0 -1 2047 8.2305970136076212e-04 + + 5.3409922122955322e-01 4.6717241406440735e-01 + <_> + + 0 -1 2048 1.2770120054483414e-02 + + 4.9657610058784485e-01 1.4723660051822662e-01 + <_> + + 0 -1 2049 -5.0051510334014893e-02 + + 6.4149940013885498e-01 5.0165921449661255e-01 + <_> + + 0 -1 2050 1.5775270760059357e-02 + + 4.5223200321197510e-01 5.6853622198104858e-01 + <_> + + 0 -1 2051 -1.8501620739698410e-02 + + 2.7647489309310913e-01 5.1379591226577759e-01 + <_> + + 0 -1 2052 2.4626250378787518e-03 + + 5.1419419050216675e-01 3.7954080104827881e-01 + <_> + + 0 -1 2053 6.2916167080402374e-02 + + 5.0606489181518555e-01 6.5804338455200195e-01 + <_> + + 0 -1 2054 -2.1648500478477217e-05 + + 5.1953881978988647e-01 4.0198868513107300e-01 + <_> + + 0 -1 2055 2.1180990152060986e-03 + + 4.9623650312423706e-01 5.9544587135314941e-01 + <_> + + 0 -1 2056 -1.6634890809655190e-02 + + 3.7579330801963806e-01 5.1754468679428101e-01 + <_> + + 0 -1 2057 -2.8899470344185829e-03 + + 6.6240137815475464e-01 5.0571787357330322e-01 + <_> + + 0 -1 2058 7.6783262193202972e-02 + + 4.7957968711853027e-01 8.0477148294448853e-01 + <_> + + 0 -1 2059 3.9170677773654461e-03 + + 4.9378821253776550e-01 5.7199418544769287e-01 + <_> + + 0 -1 2060 -7.2670601308345795e-02 + + 5.3894560784101486e-02 4.9439039826393127e-01 + <_> + + 0 -1 2061 5.4039502143859863e-01 + + 5.1297742128372192e-01 1.1433389782905579e-01 + <_> + + 0 -1 2062 2.9510019812732935e-03 + + 4.5283439755439758e-01 5.6985741853713989e-01 + <_> + + 0 -1 2063 3.4508369863033295e-03 + + 5.3577268123626709e-01 4.2187309265136719e-01 + <_> + + 0 -1 2064 -4.2077939724549651e-04 + + 5.9161728620529175e-01 4.6379259228706360e-01 + <_> + + 0 -1 2065 3.3051050268113613e-03 + + 5.2733850479125977e-01 4.3820428848266602e-01 + <_> + + 0 -1 2066 4.7735060798004270e-04 + + 4.0465280413627625e-01 5.1818847656250000e-01 + <_> + + 0 -1 2067 -2.5928510352969170e-02 + + 7.4522358179092407e-01 5.0893861055374146e-01 + <_> + + 0 -1 2068 -2.9729790985584259e-03 + + 3.2954359054565430e-01 5.0587952136993408e-01 + <_> + + 0 -1 2069 5.8508329093456268e-03 + + 4.8571440577507019e-01 5.7930248975753784e-01 + <_> + + 0 -1 2070 -4.5967519283294678e-02 + + 4.3127310276031494e-01 5.3806531429290771e-01 + <_> + + 0 -1 2071 1.5585960447788239e-01 + + 5.1961702108383179e-01 1.6847139596939087e-01 + <_> + + 0 -1 2072 1.5164829790592194e-02 + + 4.7357571125030518e-01 6.7350268363952637e-01 + <_> + + 0 -1 2073 -1.0604249546304345e-03 + + 5.8229267597198486e-01 4.7757029533386230e-01 + <_> + + 0 -1 2074 6.6476291976869106e-03 + + 4.9991989135742188e-01 2.3195350170135498e-01 + <_> + + 0 -1 2075 -1.2231130152940750e-02 + + 4.7508931159973145e-01 5.2629822492599487e-01 + <_> + + 0 -1 2076 5.6528882123529911e-03 + + 5.0697678327560425e-01 3.5618188977241516e-01 + <_> + + 0 -1 2077 1.2977829901501536e-03 + + 4.8756939172744751e-01 5.6190627813339233e-01 + <_> + + 0 -1 2078 1.0781589895486832e-02 + + 4.7507700324058533e-01 6.7823082208633423e-01 + <_> + + 0 -1 2079 2.8654779307544231e-03 + + 5.3054618835449219e-01 4.2907360196113586e-01 + <_> + + 0 -1 2080 2.8663428965955973e-03 + + 4.5184791088104248e-01 5.5393511056900024e-01 + <_> + + 0 -1 2081 -5.1983320154249668e-03 + + 4.1491198539733887e-01 5.4341888427734375e-01 + <_> + + 0 -1 2082 5.3739990107715130e-03 + + 4.7178968787193298e-01 6.5076571702957153e-01 + <_> + + 0 -1 2083 -1.4641529880464077e-02 + + 2.1721640229225159e-01 5.1617771387100220e-01 + <_> + + 0 -1 2084 -1.5042580344015732e-05 + + 5.3373837471008301e-01 4.2988368868827820e-01 + <_> + + 0 -1 2085 -1.1875660129589960e-04 + + 4.6045941114425659e-01 5.5824470520019531e-01 + <_> + + 0 -1 2086 1.6995530575513840e-02 + + 4.9458950757980347e-01 7.3880076408386230e-02 + <_> + + 0 -1 2087 -3.5095941275358200e-02 + + 7.0055091381072998e-01 4.9775910377502441e-01 + <_> + + 0 -1 2088 2.4217350874096155e-03 + + 4.4662651419639587e-01 5.4776942729949951e-01 + <_> + + 0 -1 2089 -9.6340337768197060e-04 + + 4.7140988707542419e-01 5.3133380413055420e-01 + <_> + + 0 -1 2090 1.6391130338888615e-04 + + 4.3315461277961731e-01 5.3422421216964722e-01 + <_> + + 0 -1 2091 -2.1141460165381432e-02 + + 2.6447001099586487e-01 5.2044987678527832e-01 + <_> + + 0 -1 2092 8.7775202700868249e-04 + + 5.2083498239517212e-01 4.1527429223060608e-01 + <_> + + 0 -1 2093 -2.7943920344114304e-02 + + 6.3441252708435059e-01 5.0188118219375610e-01 + <_> + + 0 -1 2094 6.7297378554940224e-03 + + 5.0504380464553833e-01 3.5008639097213745e-01 + <_> + + 0 -1 2095 2.3281039670109749e-02 + + 4.9663180112838745e-01 6.9686770439147949e-01 + <_> + + 0 -1 2096 -1.1644979938864708e-02 + + 3.3002600073814392e-01 5.0496298074722290e-01 + <_> + + 0 -1 2097 1.5764309093356133e-02 + + 4.9915981292724609e-01 7.3211538791656494e-01 + <_> + + 0 -1 2098 -1.3611479662358761e-03 + + 3.9117351174354553e-01 5.1606708765029907e-01 + <_> + + 0 -1 2099 -8.1522337859496474e-04 + + 5.6289112567901611e-01 4.9497190117835999e-01 + <_> + + 0 -1 2100 -6.0066272271797061e-04 + + 5.8535951375961304e-01 4.5505958795547485e-01 + <_> + + 0 -1 2101 4.9715518252924085e-04 + + 4.2714700102806091e-01 5.4435992240905762e-01 + <_> + + 0 -1 2102 2.3475370835512877e-03 + + 5.1431107521057129e-01 3.8876569271087646e-01 + <_> + + 0 -1 2103 -8.9261569082736969e-03 + + 6.0445022583007812e-01 4.9717208743095398e-01 + <_> + + 0 -1 2104 -1.3919910416007042e-02 + + 2.5831609964370728e-01 5.0003677606582642e-01 + <_> + + 0 -1 2105 1.0209949687123299e-03 + + 4.8573741316795349e-01 5.5603581666946411e-01 + <_> + + 0 -1 2106 -2.7441629208624363e-03 + + 5.9368848800659180e-01 4.6457770466804504e-01 + <_> + + 0 -1 2107 -1.6200130805373192e-02 + + 3.1630149483680725e-01 5.1934951543807983e-01 + <_> + + 0 -1 2108 4.3331980705261230e-03 + + 5.0612241029739380e-01 3.4588789939880371e-01 + <_> + + 0 -1 2109 5.8497930876910686e-04 + + 4.7790178656578064e-01 5.8701777458190918e-01 + <_> + + 0 -1 2110 -2.2466450463980436e-03 + + 4.2978510260581970e-01 5.3747731447219849e-01 + <_> + + 0 -1 2111 2.3146099410951138e-03 + + 5.4386717081069946e-01 4.6409699320793152e-01 + <_> + + 0 -1 2112 8.7679121643304825e-03 + + 4.7268930077552795e-01 6.7717897891998291e-01 + <_> + + 0 -1 2113 -2.2448020172305405e-04 + + 4.2291730642318726e-01 5.4280489683151245e-01 + <_> + + 0 -1 2114 -7.4336021207273006e-03 + + 6.0988807678222656e-01 4.6836739778518677e-01 + <_> + + 0 -1 2115 -2.3189240600913763e-03 + + 5.6894367933273315e-01 4.4242420792579651e-01 + <_> + + 0 -1 2116 -2.1042178850620985e-03 + + 3.7622210383415222e-01 5.1870870590209961e-01 + <_> + + 0 -1 2117 4.6034841216169298e-04 + + 4.6994051337242126e-01 5.7712072134017944e-01 + <_> + + 0 -1 2118 1.0547629790380597e-03 + + 4.4652169942855835e-01 5.6017017364501953e-01 + <_> + + 0 -1 2119 8.7148818420246243e-04 + + 5.4498052597045898e-01 3.9147090911865234e-01 + <_> + + 0 -1 2120 3.3364820410497487e-04 + + 4.5640090107917786e-01 5.6457388401031494e-01 + <_> + + 0 -1 2121 -1.4853250468149781e-03 + + 5.7473778724670410e-01 4.6927788853645325e-01 + <_> + + 0 -1 2122 3.0251620337367058e-03 + + 5.1661968231201172e-01 3.7628141045570374e-01 + <_> + + 0 -1 2123 5.0280741415917873e-03 + + 5.0021117925643921e-01 6.1515271663665771e-01 + <_> + + 0 -1 2124 -5.8164511574432254e-04 + + 5.3945982456207275e-01 4.3907511234283447e-01 + <_> + + 0 -1 2125 4.5141529291868210e-02 + + 5.1883268356323242e-01 2.0630359649658203e-01 + <_> + + 0 -1 2126 -1.0795620037242770e-03 + + 3.9046850800514221e-01 5.1379072666168213e-01 + <_> + + 0 -1 2127 1.5995999274309725e-04 + + 4.8953229188919067e-01 5.4275041818618774e-01 + <_> + + 0 -1 2128 -1.9359270110726357e-02 + + 6.9752287864685059e-01 4.7735071182250977e-01 + <_> + + 0 -1 2129 2.0725509524345398e-01 + + 5.2336359024047852e-01 3.0349919199943542e-01 + <_> + + 0 -1 2130 -4.1953290929086506e-04 + + 5.4193967580795288e-01 4.4601860642433167e-01 + <_> + + 0 -1 2131 2.2582069505006075e-03 + + 4.8157641291618347e-01 6.0274088382720947e-01 + <_> + + 0 -1 2132 -6.7811207845807076e-03 + + 3.9802789688110352e-01 5.1833057403564453e-01 + <_> + + 0 -1 2133 1.1154309846460819e-02 + + 5.4312318563461304e-01 4.1887599229812622e-01 + <_> + + 0 -1 2134 4.3162431567907333e-02 + + 4.7382280230522156e-01 6.5229612588882446e-01 + + <_> + + <_> + 3 7 14 4 -1. + <_> + 3 9 14 2 2. + <_> + + <_> + 1 2 18 4 -1. + <_> + 7 2 6 4 3. + <_> + + <_> + 1 7 15 9 -1. + <_> + 1 10 15 3 3. + <_> + + <_> + 5 6 2 6 -1. + <_> + 5 9 2 3 2. + <_> + + <_> + 7 5 6 3 -1. + <_> + 9 5 2 3 3. + <_> + + <_> + 4 0 12 9 -1. + <_> + 4 3 12 3 3. + <_> + + <_> + 6 9 10 8 -1. + <_> + 6 13 10 4 2. + <_> + + <_> + 3 6 14 8 -1. + <_> + 3 10 14 4 2. + <_> + + <_> + 14 1 6 10 -1. + <_> + 14 1 3 10 2. + <_> + + <_> + 7 8 5 12 -1. + <_> + 7 12 5 4 3. + <_> + + <_> + 1 1 18 3 -1. + <_> + 7 1 6 3 3. + <_> + + <_> + 1 8 17 2 -1. + <_> + 1 9 17 1 2. + <_> + + <_> + 16 6 4 2 -1. + <_> + 16 7 4 1 2. + <_> + + <_> + 5 17 2 2 -1. + <_> + 5 18 2 1 2. + <_> + + <_> + 14 2 6 12 -1. + <_> + 14 2 3 12 2. + <_> + + <_> + 4 0 4 12 -1. + <_> + 4 0 2 6 2. + <_> + 6 6 2 6 2. + <_> + + <_> + 2 11 18 8 -1. + <_> + 8 11 6 8 3. + <_> + + <_> + 5 7 10 2 -1. + <_> + 5 8 10 1 2. + <_> + + <_> + 15 11 5 3 -1. + <_> + 15 12 5 1 3. + <_> + + <_> + 5 3 10 9 -1. + <_> + 5 6 10 3 3. + <_> + + <_> + 9 4 2 14 -1. + <_> + 9 11 2 7 2. + <_> + + <_> + 3 5 4 12 -1. + <_> + 3 9 4 4 3. + <_> + + <_> + 4 5 12 5 -1. + <_> + 8 5 4 5 3. + <_> + + <_> + 5 6 10 8 -1. + <_> + 5 10 10 4 2. + <_> + + <_> + 8 0 6 9 -1. + <_> + 8 3 6 3 3. + <_> + + <_> + 9 12 1 8 -1. + <_> + 9 16 1 4 2. + <_> + + <_> + 0 7 20 6 -1. + <_> + 0 9 20 2 3. + <_> + + <_> + 7 0 6 17 -1. + <_> + 9 0 2 17 3. + <_> + + <_> + 9 0 6 4 -1. + <_> + 11 0 2 4 3. + <_> + + <_> + 5 1 6 4 -1. + <_> + 7 1 2 4 3. + <_> + + <_> + 12 1 6 16 -1. + <_> + 14 1 2 16 3. + <_> + + <_> + 0 5 18 8 -1. + <_> + 0 5 9 4 2. + <_> + 9 9 9 4 2. + <_> + + <_> + 8 15 10 4 -1. + <_> + 13 15 5 2 2. + <_> + 8 17 5 2 2. + <_> + + <_> + 3 1 4 8 -1. + <_> + 3 1 2 4 2. + <_> + 5 5 2 4 2. + <_> + + <_> + 3 6 14 10 -1. + <_> + 10 6 7 5 2. + <_> + 3 11 7 5 2. + <_> + + <_> + 2 1 6 16 -1. + <_> + 4 1 2 16 3. + <_> + + <_> + 0 18 20 2 -1. + <_> + 0 19 20 1 2. + <_> + + <_> + 8 13 4 3 -1. + <_> + 8 14 4 1 3. + <_> + + <_> + 9 14 2 3 -1. + <_> + 9 15 2 1 3. + <_> + + <_> + 0 12 9 6 -1. + <_> + 0 14 9 2 3. + <_> + + <_> + 5 7 3 4 -1. + <_> + 5 9 3 2 2. + <_> + + <_> + 9 3 2 16 -1. + <_> + 9 11 2 8 2. + <_> + + <_> + 3 6 13 8 -1. + <_> + 3 10 13 4 2. + <_> + + <_> + 12 3 8 2 -1. + <_> + 12 3 4 2 2. + <_> + + <_> + 8 8 4 12 -1. + <_> + 8 12 4 4 3. + <_> + + <_> + 11 3 8 6 -1. + <_> + 15 3 4 3 2. + <_> + 11 6 4 3 2. + <_> + + <_> + 7 1 6 19 -1. + <_> + 9 1 2 19 3. + <_> + + <_> + 9 0 6 4 -1. + <_> + 11 0 2 4 3. + <_> + + <_> + 3 1 9 3 -1. + <_> + 6 1 3 3 3. + <_> + + <_> + 8 15 10 4 -1. + <_> + 13 15 5 2 2. + <_> + 8 17 5 2 2. + <_> + + <_> + 0 3 6 10 -1. + <_> + 3 3 3 10 2. + <_> + + <_> + 3 4 15 15 -1. + <_> + 3 9 15 5 3. + <_> + + <_> + 6 5 8 6 -1. + <_> + 6 7 8 2 3. + <_> + + <_> + 4 4 12 10 -1. + <_> + 10 4 6 5 2. + <_> + 4 9 6 5 2. + <_> + + <_> + 6 4 4 4 -1. + <_> + 8 4 2 4 2. + <_> + + <_> + 15 11 1 2 -1. + <_> + 15 12 1 1 2. + <_> + + <_> + 3 11 2 2 -1. + <_> + 3 12 2 1 2. + <_> + + <_> + 16 11 1 3 -1. + <_> + 16 12 1 1 3. + <_> + + <_> + 3 15 6 4 -1. + <_> + 3 15 3 2 2. + <_> + 6 17 3 2 2. + <_> + + <_> + 6 7 8 2 -1. + <_> + 6 8 8 1 2. + <_> + + <_> + 3 11 1 3 -1. + <_> + 3 12 1 1 3. + <_> + + <_> + 6 0 12 2 -1. + <_> + 6 1 12 1 2. + <_> + + <_> + 9 14 2 3 -1. + <_> + 9 15 2 1 3. + <_> + + <_> + 7 15 6 2 -1. + <_> + 7 16 6 1 2. + <_> + + <_> + 0 5 4 6 -1. + <_> + 0 7 4 2 3. + <_> + + <_> + 4 12 12 2 -1. + <_> + 8 12 4 2 3. + <_> + + <_> + 6 3 1 9 -1. + <_> + 6 6 1 3 3. + <_> + + <_> + 10 17 3 2 -1. + <_> + 11 17 1 2 3. + <_> + + <_> + 9 9 2 2 -1. + <_> + 9 10 2 1 2. + <_> + + <_> + 7 6 6 4 -1. + <_> + 9 6 2 4 3. + <_> + + <_> + 7 17 3 2 -1. + <_> + 8 17 1 2 3. + <_> + + <_> + 10 17 3 3 -1. + <_> + 11 17 1 3 3. + <_> + + <_> + 8 12 3 2 -1. + <_> + 8 13 3 1 2. + <_> + + <_> + 9 3 6 2 -1. + <_> + 11 3 2 2 3. + <_> + + <_> + 3 11 14 4 -1. + <_> + 3 13 14 2 2. + <_> + + <_> + 1 10 18 4 -1. + <_> + 10 10 9 2 2. + <_> + 1 12 9 2 2. + <_> + + <_> + 0 10 3 3 -1. + <_> + 0 11 3 1 3. + <_> + + <_> + 9 1 6 6 -1. + <_> + 11 1 2 6 3. + <_> + + <_> + 8 7 3 6 -1. + <_> + 9 7 1 6 3. + <_> + + <_> + 1 0 18 9 -1. + <_> + 1 3 18 3 3. + <_> + + <_> + 12 10 2 6 -1. + <_> + 12 13 2 3 2. + <_> + + <_> + 0 5 19 8 -1. + <_> + 0 9 19 4 2. + <_> + + <_> + 7 0 6 9 -1. + <_> + 9 0 2 9 3. + <_> + + <_> + 5 3 6 1 -1. + <_> + 7 3 2 1 3. + <_> + + <_> + 11 3 6 1 -1. + <_> + 13 3 2 1 3. + <_> + + <_> + 5 10 4 6 -1. + <_> + 5 13 4 3 2. + <_> + + <_> + 11 3 6 1 -1. + <_> + 13 3 2 1 3. + <_> + + <_> + 4 4 12 6 -1. + <_> + 4 6 12 2 3. + <_> + + <_> + 15 12 2 6 -1. + <_> + 15 14 2 2 3. + <_> + + <_> + 9 3 2 2 -1. + <_> + 10 3 1 2 2. + <_> + + <_> + 9 3 3 1 -1. + <_> + 10 3 1 1 3. + <_> + + <_> + 1 1 4 14 -1. + <_> + 3 1 2 14 2. + <_> + + <_> + 9 0 4 4 -1. + <_> + 11 0 2 2 2. + <_> + 9 2 2 2 2. + <_> + + <_> + 7 5 1 14 -1. + <_> + 7 12 1 7 2. + <_> + + <_> + 19 0 1 4 -1. + <_> + 19 2 1 2 2. + <_> + + <_> + 5 5 6 4 -1. + <_> + 8 5 3 4 2. + <_> + + <_> + 9 18 3 2 -1. + <_> + 10 18 1 2 3. + <_> + + <_> + 8 18 3 2 -1. + <_> + 9 18 1 2 3. + <_> + + <_> + 4 5 12 6 -1. + <_> + 4 7 12 2 3. + <_> + + <_> + 3 12 2 6 -1. + <_> + 3 14 2 2 3. + <_> + + <_> + 10 8 2 12 -1. + <_> + 10 12 2 4 3. + <_> + + <_> + 7 18 3 2 -1. + <_> + 8 18 1 2 3. + <_> + + <_> + 9 0 6 2 -1. + <_> + 11 0 2 2 3. + <_> + + <_> + 5 11 9 3 -1. + <_> + 5 12 9 1 3. + <_> + + <_> + 9 0 6 2 -1. + <_> + 11 0 2 2 3. + <_> + + <_> + 1 1 18 5 -1. + <_> + 7 1 6 5 3. + <_> + + <_> + 8 0 4 4 -1. + <_> + 10 0 2 2 2. + <_> + 8 2 2 2 2. + <_> + + <_> + 3 12 1 3 -1. + <_> + 3 13 1 1 3. + <_> + + <_> + 8 14 5 3 -1. + <_> + 8 15 5 1 3. + <_> + + <_> + 5 4 10 12 -1. + <_> + 5 4 5 6 2. + <_> + 10 10 5 6 2. + <_> + + <_> + 9 6 9 12 -1. + <_> + 9 10 9 4 3. + <_> + + <_> + 2 2 12 14 -1. + <_> + 2 2 6 7 2. + <_> + 8 9 6 7 2. + <_> + + <_> + 4 7 12 2 -1. + <_> + 8 7 4 2 3. + <_> + + <_> + 7 4 6 4 -1. + <_> + 7 6 6 2 2. + <_> + + <_> + 4 5 11 8 -1. + <_> + 4 9 11 4 2. + <_> + + <_> + 3 10 16 4 -1. + <_> + 3 12 16 2 2. + <_> + + <_> + 0 0 16 2 -1. + <_> + 0 1 16 1 2. + <_> + + <_> + 7 5 6 2 -1. + <_> + 9 5 2 2 3. + <_> + + <_> + 3 2 6 10 -1. + <_> + 3 2 3 5 2. + <_> + 6 7 3 5 2. + <_> + + <_> + 10 5 8 15 -1. + <_> + 10 10 8 5 3. + <_> + + <_> + 3 14 8 6 -1. + <_> + 3 14 4 3 2. + <_> + 7 17 4 3 2. + <_> + + <_> + 14 2 2 2 -1. + <_> + 14 3 2 1 2. + <_> + + <_> + 1 10 7 6 -1. + <_> + 1 13 7 3 2. + <_> + + <_> + 15 4 4 3 -1. + <_> + 15 4 2 3 2. + <_> + + <_> + 2 9 14 6 -1. + <_> + 2 9 7 3 2. + <_> + 9 12 7 3 2. + <_> + + <_> + 5 7 10 4 -1. + <_> + 5 9 10 2 2. + <_> + + <_> + 6 9 8 8 -1. + <_> + 6 9 4 4 2. + <_> + 10 13 4 4 2. + <_> + + <_> + 14 1 3 2 -1. + <_> + 14 2 3 1 2. + <_> + + <_> + 1 4 4 2 -1. + <_> + 3 4 2 2 2. + <_> + + <_> + 11 10 2 8 -1. + <_> + 11 14 2 4 2. + <_> + + <_> + 0 0 5 3 -1. + <_> + 0 1 5 1 3. + <_> + + <_> + 2 5 18 8 -1. + <_> + 11 5 9 4 2. + <_> + 2 9 9 4 2. + <_> + + <_> + 6 6 1 6 -1. + <_> + 6 9 1 3 2. + <_> + + <_> + 19 1 1 3 -1. + <_> + 19 2 1 1 3. + <_> + + <_> + 7 6 6 6 -1. + <_> + 9 6 2 6 3. + <_> + + <_> + 19 1 1 3 -1. + <_> + 19 2 1 1 3. + <_> + + <_> + 3 13 2 3 -1. + <_> + 3 14 2 1 3. + <_> + + <_> + 8 4 8 12 -1. + <_> + 12 4 4 6 2. + <_> + 8 10 4 6 2. + <_> + + <_> + 5 2 6 3 -1. + <_> + 7 2 2 3 3. + <_> + + <_> + 6 1 9 10 -1. + <_> + 6 6 9 5 2. + <_> + + <_> + 0 4 6 12 -1. + <_> + 2 4 2 12 3. + <_> + + <_> + 15 13 2 3 -1. + <_> + 15 14 2 1 3. + <_> + + <_> + 7 14 5 3 -1. + <_> + 7 15 5 1 3. + <_> + + <_> + 15 13 3 3 -1. + <_> + 15 14 3 1 3. + <_> + + <_> + 6 14 8 3 -1. + <_> + 6 15 8 1 3. + <_> + + <_> + 15 13 3 3 -1. + <_> + 15 14 3 1 3. + <_> + + <_> + 2 13 3 3 -1. + <_> + 2 14 3 1 3. + <_> + + <_> + 4 7 12 12 -1. + <_> + 10 7 6 6 2. + <_> + 4 13 6 6 2. + <_> + + <_> + 9 7 2 6 -1. + <_> + 10 7 1 6 2. + <_> + + <_> + 8 9 5 2 -1. + <_> + 8 10 5 1 2. + <_> + + <_> + 8 6 3 4 -1. + <_> + 9 6 1 4 3. + <_> + + <_> + 9 6 2 8 -1. + <_> + 9 10 2 4 2. + <_> + + <_> + 7 7 3 6 -1. + <_> + 8 7 1 6 3. + <_> + + <_> + 11 3 3 3 -1. + <_> + 12 3 1 3 3. + <_> + + <_> + 5 4 6 1 -1. + <_> + 7 4 2 1 3. + <_> + + <_> + 5 6 10 3 -1. + <_> + 5 7 10 1 3. + <_> + + <_> + 7 3 6 9 -1. + <_> + 7 6 6 3 3. + <_> + + <_> + 6 7 9 1 -1. + <_> + 9 7 3 1 3. + <_> + + <_> + 2 8 16 8 -1. + <_> + 2 12 16 4 2. + <_> + + <_> + 14 6 2 6 -1. + <_> + 14 9 2 3 2. + <_> + + <_> + 1 5 6 15 -1. + <_> + 1 10 6 5 3. + <_> + + <_> + 10 0 6 9 -1. + <_> + 10 3 6 3 3. + <_> + + <_> + 6 6 7 14 -1. + <_> + 6 13 7 7 2. + <_> + + <_> + 13 7 3 6 -1. + <_> + 13 9 3 2 3. + <_> + + <_> + 1 8 15 4 -1. + <_> + 6 8 5 4 3. + <_> + + <_> + 11 2 3 10 -1. + <_> + 11 7 3 5 2. + <_> + + <_> + 3 7 4 6 -1. + <_> + 3 9 4 2 3. + <_> + + <_> + 13 3 6 10 -1. + <_> + 15 3 2 10 3. + <_> + + <_> + 5 7 8 10 -1. + <_> + 5 7 4 5 2. + <_> + 9 12 4 5 2. + <_> + + <_> + 4 4 12 12 -1. + <_> + 10 4 6 6 2. + <_> + 4 10 6 6 2. + <_> + + <_> + 1 4 6 9 -1. + <_> + 3 4 2 9 3. + <_> + + <_> + 11 3 2 5 -1. + <_> + 11 3 1 5 2. + <_> + + <_> + 7 3 2 5 -1. + <_> + 8 3 1 5 2. + <_> + + <_> + 10 14 2 3 -1. + <_> + 10 15 2 1 3. + <_> + + <_> + 5 12 6 2 -1. + <_> + 8 12 3 2 2. + <_> + + <_> + 9 14 2 3 -1. + <_> + 9 15 2 1 3. + <_> + + <_> + 4 11 12 6 -1. + <_> + 4 14 12 3 2. + <_> + + <_> + 11 11 5 9 -1. + <_> + 11 14 5 3 3. + <_> + + <_> + 6 15 3 2 -1. + <_> + 6 16 3 1 2. + <_> + + <_> + 11 0 3 5 -1. + <_> + 12 0 1 5 3. + <_> + + <_> + 5 5 6 7 -1. + <_> + 8 5 3 7 2. + <_> + + <_> + 13 0 1 9 -1. + <_> + 13 3 1 3 3. + <_> + + <_> + 3 2 4 8 -1. + <_> + 3 2 2 4 2. + <_> + 5 6 2 4 2. + <_> + + <_> + 13 12 4 6 -1. + <_> + 13 14 4 2 3. + <_> + + <_> + 3 12 4 6 -1. + <_> + 3 14 4 2 3. + <_> + + <_> + 13 11 3 4 -1. + <_> + 13 13 3 2 2. + <_> + + <_> + 4 4 4 3 -1. + <_> + 4 5 4 1 3. + <_> + + <_> + 7 5 11 8 -1. + <_> + 7 9 11 4 2. + <_> + + <_> + 7 8 3 4 -1. + <_> + 8 8 1 4 3. + <_> + + <_> + 9 1 6 1 -1. + <_> + 11 1 2 1 3. + <_> + + <_> + 5 5 3 3 -1. + <_> + 5 6 3 1 3. + <_> + + <_> + 0 9 20 6 -1. + <_> + 10 9 10 3 2. + <_> + 0 12 10 3 2. + <_> + + <_> + 8 6 3 5 -1. + <_> + 9 6 1 5 3. + <_> + + <_> + 11 0 1 3 -1. + <_> + 11 1 1 1 3. + <_> + + <_> + 4 2 4 2 -1. + <_> + 4 3 4 1 2. + <_> + + <_> + 12 6 4 3 -1. + <_> + 12 7 4 1 3. + <_> + + <_> + 5 0 6 4 -1. + <_> + 7 0 2 4 3. + <_> + + <_> + 9 7 3 8 -1. + <_> + 10 7 1 8 3. + <_> + + <_> + 9 7 2 2 -1. + <_> + 10 7 1 2 2. + <_> + + <_> + 6 7 14 4 -1. + <_> + 13 7 7 2 2. + <_> + 6 9 7 2 2. + <_> + + <_> + 0 5 3 6 -1. + <_> + 0 7 3 2 3. + <_> + + <_> + 13 11 3 4 -1. + <_> + 13 13 3 2 2. + <_> + + <_> + 4 11 3 4 -1. + <_> + 4 13 3 2 2. + <_> + + <_> + 5 9 12 8 -1. + <_> + 11 9 6 4 2. + <_> + 5 13 6 4 2. + <_> + + <_> + 9 12 1 3 -1. + <_> + 9 13 1 1 3. + <_> + + <_> + 10 15 2 4 -1. + <_> + 10 17 2 2 2. + <_> + + <_> + 7 7 6 1 -1. + <_> + 9 7 2 1 3. + <_> + + <_> + 12 3 6 6 -1. + <_> + 15 3 3 3 2. + <_> + 12 6 3 3 2. + <_> + + <_> + 0 4 10 6 -1. + <_> + 0 6 10 2 3. + <_> + + <_> + 8 3 8 14 -1. + <_> + 12 3 4 7 2. + <_> + 8 10 4 7 2. + <_> + + <_> + 4 4 7 15 -1. + <_> + 4 9 7 5 3. + <_> + + <_> + 12 2 6 8 -1. + <_> + 15 2 3 4 2. + <_> + 12 6 3 4 2. + <_> + + <_> + 2 2 6 8 -1. + <_> + 2 2 3 4 2. + <_> + 5 6 3 4 2. + <_> + + <_> + 2 13 18 7 -1. + <_> + 8 13 6 7 3. + <_> + + <_> + 4 3 8 14 -1. + <_> + 4 3 4 7 2. + <_> + 8 10 4 7 2. + <_> + + <_> + 18 1 2 6 -1. + <_> + 18 3 2 2 3. + <_> + + <_> + 9 11 2 3 -1. + <_> + 9 12 2 1 3. + <_> + + <_> + 18 1 2 6 -1. + <_> + 18 3 2 2 3. + <_> + + <_> + 0 1 2 6 -1. + <_> + 0 3 2 2 3. + <_> + + <_> + 1 5 18 6 -1. + <_> + 1 7 18 2 3. + <_> + + <_> + 0 2 6 7 -1. + <_> + 3 2 3 7 2. + <_> + + <_> + 7 3 6 14 -1. + <_> + 7 10 6 7 2. + <_> + + <_> + 3 7 13 10 -1. + <_> + 3 12 13 5 2. + <_> + + <_> + 11 15 2 2 -1. + <_> + 11 16 2 1 2. + <_> + + <_> + 2 11 16 4 -1. + <_> + 2 11 8 2 2. + <_> + 10 13 8 2 2. + <_> + + <_> + 13 7 6 4 -1. + <_> + 16 7 3 2 2. + <_> + 13 9 3 2 2. + <_> + + <_> + 6 10 3 9 -1. + <_> + 6 13 3 3 3. + <_> + + <_> + 14 6 1 6 -1. + <_> + 14 9 1 3 2. + <_> + + <_> + 5 10 4 1 -1. + <_> + 7 10 2 1 2. + <_> + + <_> + 3 8 15 5 -1. + <_> + 8 8 5 5 3. + <_> + + <_> + 1 6 5 4 -1. + <_> + 1 8 5 2 2. + <_> + + <_> + 3 1 17 6 -1. + <_> + 3 3 17 2 3. + <_> + + <_> + 6 7 8 2 -1. + <_> + 10 7 4 2 2. + <_> + + <_> + 9 7 3 2 -1. + <_> + 10 7 1 2 3. + <_> + + <_> + 8 7 3 2 -1. + <_> + 9 7 1 2 3. + <_> + + <_> + 8 9 4 2 -1. + <_> + 8 10 4 1 2. + <_> + + <_> + 8 8 4 3 -1. + <_> + 8 9 4 1 3. + <_> + + <_> + 9 5 6 4 -1. + <_> + 9 5 3 4 2. + <_> + + <_> + 8 13 4 3 -1. + <_> + 8 14 4 1 3. + <_> + + <_> + 4 7 12 6 -1. + <_> + 10 7 6 3 2. + <_> + 4 10 6 3 2. + <_> + + <_> + 8 14 4 3 -1. + <_> + 8 15 4 1 3. + <_> + + <_> + 9 7 3 3 -1. + <_> + 9 8 3 1 3. + <_> + + <_> + 7 4 3 8 -1. + <_> + 8 4 1 8 3. + <_> + + <_> + 10 0 3 6 -1. + <_> + 11 0 1 6 3. + <_> + + <_> + 6 3 4 8 -1. + <_> + 8 3 2 8 2. + <_> + + <_> + 14 3 6 13 -1. + <_> + 14 3 3 13 2. + <_> + + <_> + 8 13 3 6 -1. + <_> + 8 16 3 3 2. + <_> + + <_> + 14 3 6 13 -1. + <_> + 14 3 3 13 2. + <_> + + <_> + 0 7 10 4 -1. + <_> + 0 7 5 2 2. + <_> + 5 9 5 2 2. + <_> + + <_> + 14 3 6 13 -1. + <_> + 14 3 3 13 2. + <_> + + <_> + 0 3 6 13 -1. + <_> + 3 3 3 13 2. + <_> + + <_> + 9 1 4 1 -1. + <_> + 9 1 2 1 2. + <_> + + <_> + 8 0 2 1 -1. + <_> + 9 0 1 1 2. + <_> + + <_> + 10 16 4 4 -1. + <_> + 12 16 2 2 2. + <_> + 10 18 2 2 2. + <_> + + <_> + 9 6 2 3 -1. + <_> + 10 6 1 3 2. + <_> + + <_> + 4 5 12 2 -1. + <_> + 8 5 4 2 3. + <_> + + <_> + 8 7 3 5 -1. + <_> + 9 7 1 5 3. + <_> + + <_> + 6 4 8 6 -1. + <_> + 6 6 8 2 3. + <_> + + <_> + 9 5 2 12 -1. + <_> + 9 11 2 6 2. + <_> + + <_> + 4 6 6 8 -1. + <_> + 4 10 6 4 2. + <_> + + <_> + 12 2 8 5 -1. + <_> + 12 2 4 5 2. + <_> + + <_> + 0 8 18 3 -1. + <_> + 0 9 18 1 3. + <_> + + <_> + 8 12 4 8 -1. + <_> + 8 16 4 4 2. + <_> + + <_> + 0 2 8 5 -1. + <_> + 4 2 4 5 2. + <_> + + <_> + 13 11 3 4 -1. + <_> + 13 13 3 2 2. + <_> + + <_> + 5 11 6 1 -1. + <_> + 7 11 2 1 3. + <_> + + <_> + 11 3 3 1 -1. + <_> + 12 3 1 1 3. + <_> + + <_> + 7 13 5 3 -1. + <_> + 7 14 5 1 3. + <_> + + <_> + 11 11 7 6 -1. + <_> + 11 14 7 3 2. + <_> + + <_> + 2 11 7 6 -1. + <_> + 2 14 7 3 2. + <_> + + <_> + 12 14 2 6 -1. + <_> + 12 16 2 2 3. + <_> + + <_> + 8 14 3 3 -1. + <_> + 8 15 3 1 3. + <_> + + <_> + 11 0 3 5 -1. + <_> + 12 0 1 5 3. + <_> + + <_> + 6 1 4 9 -1. + <_> + 8 1 2 9 2. + <_> + + <_> + 10 3 6 1 -1. + <_> + 12 3 2 1 3. + <_> + + <_> + 8 8 3 4 -1. + <_> + 8 10 3 2 2. + <_> + + <_> + 8 12 4 2 -1. + <_> + 8 13 4 1 2. + <_> + + <_> + 5 18 4 2 -1. + <_> + 5 19 4 1 2. + <_> + + <_> + 2 1 18 6 -1. + <_> + 2 3 18 2 3. + <_> + + <_> + 6 0 3 2 -1. + <_> + 7 0 1 2 3. + <_> + + <_> + 13 8 6 2 -1. + <_> + 16 8 3 1 2. + <_> + 13 9 3 1 2. + <_> + + <_> + 6 10 3 6 -1. + <_> + 6 13 3 3 2. + <_> + + <_> + 0 13 20 4 -1. + <_> + 10 13 10 2 2. + <_> + 0 15 10 2 2. + <_> + + <_> + 7 7 6 5 -1. + <_> + 9 7 2 5 3. + <_> + + <_> + 11 0 2 2 -1. + <_> + 11 1 2 1 2. + <_> + + <_> + 1 8 6 2 -1. + <_> + 1 8 3 1 2. + <_> + 4 9 3 1 2. + <_> + + <_> + 0 2 20 2 -1. + <_> + 10 2 10 1 2. + <_> + 0 3 10 1 2. + <_> + + <_> + 7 14 5 3 -1. + <_> + 7 15 5 1 3. + <_> + + <_> + 7 13 6 6 -1. + <_> + 10 13 3 3 2. + <_> + 7 16 3 3 2. + <_> + + <_> + 9 12 2 3 -1. + <_> + 9 13 2 1 3. + <_> + + <_> + 16 11 1 6 -1. + <_> + 16 13 1 2 3. + <_> + + <_> + 3 11 1 6 -1. + <_> + 3 13 1 2 3. + <_> + + <_> + 4 4 14 12 -1. + <_> + 11 4 7 6 2. + <_> + 4 10 7 6 2. + <_> + + <_> + 5 4 3 3 -1. + <_> + 5 5 3 1 3. + <_> + + <_> + 12 3 3 3 -1. + <_> + 13 3 1 3 3. + <_> + + <_> + 6 6 8 3 -1. + <_> + 6 7 8 1 3. + <_> + + <_> + 12 3 3 3 -1. + <_> + 13 3 1 3 3. + <_> + + <_> + 3 1 4 10 -1. + <_> + 3 1 2 5 2. + <_> + 5 6 2 5 2. + <_> + + <_> + 5 7 10 2 -1. + <_> + 5 7 5 2 2. + <_> + + <_> + 8 7 3 3 -1. + <_> + 9 7 1 3 3. + <_> + + <_> + 15 12 2 3 -1. + <_> + 15 13 2 1 3. + <_> + + <_> + 7 8 3 4 -1. + <_> + 8 8 1 4 3. + <_> + + <_> + 13 4 1 12 -1. + <_> + 13 10 1 6 2. + <_> + + <_> + 4 5 12 12 -1. + <_> + 4 5 6 6 2. + <_> + 10 11 6 6 2. + <_> + + <_> + 7 14 7 3 -1. + <_> + 7 15 7 1 3. + <_> + + <_> + 3 12 2 3 -1. + <_> + 3 13 2 1 3. + <_> + + <_> + 3 2 14 2 -1. + <_> + 10 2 7 1 2. + <_> + 3 3 7 1 2. + <_> + + <_> + 0 1 3 10 -1. + <_> + 1 1 1 10 3. + <_> + + <_> + 9 0 6 5 -1. + <_> + 11 0 2 5 3. + <_> + + <_> + 5 7 6 2 -1. + <_> + 8 7 3 2 2. + <_> + + <_> + 7 1 6 10 -1. + <_> + 7 6 6 5 2. + <_> + + <_> + 1 1 18 3 -1. + <_> + 7 1 6 3 3. + <_> + + <_> + 16 3 3 6 -1. + <_> + 16 5 3 2 3. + <_> + + <_> + 6 3 7 6 -1. + <_> + 6 6 7 3 2. + <_> + + <_> + 4 7 12 2 -1. + <_> + 8 7 4 2 3. + <_> + + <_> + 0 4 17 10 -1. + <_> + 0 9 17 5 2. + <_> + + <_> + 3 4 15 16 -1. + <_> + 3 12 15 8 2. + <_> + + <_> + 7 15 6 4 -1. + <_> + 7 17 6 2 2. + <_> + + <_> + 15 2 4 9 -1. + <_> + 15 2 2 9 2. + <_> + + <_> + 2 3 3 2 -1. + <_> + 2 4 3 1 2. + <_> + + <_> + 13 6 7 9 -1. + <_> + 13 9 7 3 3. + <_> + + <_> + 8 11 4 3 -1. + <_> + 8 12 4 1 3. + <_> + + <_> + 0 2 20 6 -1. + <_> + 10 2 10 3 2. + <_> + 0 5 10 3 2. + <_> + + <_> + 3 2 6 10 -1. + <_> + 3 2 3 5 2. + <_> + 6 7 3 5 2. + <_> + + <_> + 13 10 3 4 -1. + <_> + 13 12 3 2 2. + <_> + + <_> + 4 10 3 4 -1. + <_> + 4 12 3 2 2. + <_> + + <_> + 7 5 6 3 -1. + <_> + 9 5 2 3 3. + <_> + + <_> + 7 6 6 8 -1. + <_> + 7 10 6 4 2. + <_> + + <_> + 0 11 20 6 -1. + <_> + 0 14 20 3 2. + <_> + + <_> + 4 13 4 6 -1. + <_> + 4 13 2 3 2. + <_> + 6 16 2 3 2. + <_> + + <_> + 6 0 8 12 -1. + <_> + 10 0 4 6 2. + <_> + 6 6 4 6 2. + <_> + + <_> + 2 0 15 2 -1. + <_> + 2 1 15 1 2. + <_> + + <_> + 9 12 2 3 -1. + <_> + 9 13 2 1 3. + <_> + + <_> + 3 12 1 2 -1. + <_> + 3 13 1 1 2. + <_> + + <_> + 9 11 2 3 -1. + <_> + 9 12 2 1 3. + <_> + + <_> + 7 3 3 1 -1. + <_> + 8 3 1 1 3. + <_> + + <_> + 17 7 3 6 -1. + <_> + 17 9 3 2 3. + <_> + + <_> + 7 2 3 2 -1. + <_> + 8 2 1 2 3. + <_> + + <_> + 11 4 5 3 -1. + <_> + 11 5 5 1 3. + <_> + + <_> + 4 4 5 3 -1. + <_> + 4 5 5 1 3. + <_> + + <_> + 19 3 1 2 -1. + <_> + 19 4 1 1 2. + <_> + + <_> + 5 5 4 3 -1. + <_> + 5 6 4 1 3. + <_> + + <_> + 17 7 3 6 -1. + <_> + 17 9 3 2 3. + <_> + + <_> + 0 7 3 6 -1. + <_> + 0 9 3 2 3. + <_> + + <_> + 14 2 6 9 -1. + <_> + 14 5 6 3 3. + <_> + + <_> + 0 4 5 6 -1. + <_> + 0 6 5 2 3. + <_> + + <_> + 10 5 6 2 -1. + <_> + 12 5 2 2 3. + <_> + + <_> + 4 5 6 2 -1. + <_> + 6 5 2 2 3. + <_> + + <_> + 8 1 4 6 -1. + <_> + 8 3 4 2 3. + <_> + + <_> + 0 2 3 6 -1. + <_> + 0 4 3 2 3. + <_> + + <_> + 6 6 8 3 -1. + <_> + 6 7 8 1 3. + <_> + + <_> + 0 1 5 9 -1. + <_> + 0 4 5 3 3. + <_> + + <_> + 16 0 4 15 -1. + <_> + 16 0 2 15 2. + <_> + + <_> + 1 10 3 2 -1. + <_> + 1 11 3 1 2. + <_> + + <_> + 14 4 1 10 -1. + <_> + 14 9 1 5 2. + <_> + + <_> + 0 1 4 12 -1. + <_> + 2 1 2 12 2. + <_> + + <_> + 11 11 4 2 -1. + <_> + 11 11 2 2 2. + <_> + + <_> + 5 11 4 2 -1. + <_> + 7 11 2 2 2. + <_> + + <_> + 3 8 15 5 -1. + <_> + 8 8 5 5 3. + <_> + + <_> + 0 0 6 10 -1. + <_> + 3 0 3 10 2. + <_> + + <_> + 11 4 3 2 -1. + <_> + 12 4 1 2 3. + <_> + + <_> + 8 12 3 8 -1. + <_> + 8 16 3 4 2. + <_> + + <_> + 8 14 5 3 -1. + <_> + 8 15 5 1 3. + <_> + + <_> + 7 14 4 3 -1. + <_> + 7 15 4 1 3. + <_> + + <_> + 11 4 3 2 -1. + <_> + 12 4 1 2 3. + <_> + + <_> + 3 15 14 4 -1. + <_> + 3 15 7 2 2. + <_> + 10 17 7 2 2. + <_> + + <_> + 2 2 16 4 -1. + <_> + 10 2 8 2 2. + <_> + 2 4 8 2 2. + <_> + + <_> + 0 8 6 12 -1. + <_> + 3 8 3 12 2. + <_> + + <_> + 5 7 10 2 -1. + <_> + 5 7 5 2 2. + <_> + + <_> + 9 7 2 5 -1. + <_> + 10 7 1 5 2. + <_> + + <_> + 13 7 6 4 -1. + <_> + 16 7 3 2 2. + <_> + 13 9 3 2 2. + <_> + + <_> + 0 13 8 2 -1. + <_> + 0 14 8 1 2. + <_> + + <_> + 13 7 6 4 -1. + <_> + 16 7 3 2 2. + <_> + 13 9 3 2 2. + <_> + + <_> + 1 7 6 4 -1. + <_> + 1 7 3 2 2. + <_> + 4 9 3 2 2. + <_> + + <_> + 12 6 1 12 -1. + <_> + 12 12 1 6 2. + <_> + + <_> + 9 5 2 6 -1. + <_> + 10 5 1 6 2. + <_> + + <_> + 14 12 2 3 -1. + <_> + 14 13 2 1 3. + <_> + + <_> + 4 12 2 3 -1. + <_> + 4 13 2 1 3. + <_> + + <_> + 8 12 4 3 -1. + <_> + 8 13 4 1 3. + <_> + + <_> + 5 2 2 4 -1. + <_> + 5 2 1 2 2. + <_> + 6 4 1 2 2. + <_> + + <_> + 5 5 11 3 -1. + <_> + 5 6 11 1 3. + <_> + + <_> + 7 6 4 12 -1. + <_> + 7 12 4 6 2. + <_> + + <_> + 12 13 8 5 -1. + <_> + 12 13 4 5 2. + <_> + + <_> + 7 6 1 12 -1. + <_> + 7 12 1 6 2. + <_> + + <_> + 1 2 6 3 -1. + <_> + 4 2 3 3 2. + <_> + + <_> + 9 5 6 10 -1. + <_> + 12 5 3 5 2. + <_> + 9 10 3 5 2. + <_> + + <_> + 5 5 8 12 -1. + <_> + 5 5 4 6 2. + <_> + 9 11 4 6 2. + <_> + + <_> + 0 7 20 6 -1. + <_> + 0 9 20 2 3. + <_> + + <_> + 4 2 2 2 -1. + <_> + 4 3 2 1 2. + <_> + + <_> + 4 18 12 2 -1. + <_> + 8 18 4 2 3. + <_> + + <_> + 7 4 4 16 -1. + <_> + 7 12 4 8 2. + <_> + + <_> + 7 6 7 8 -1. + <_> + 7 10 7 4 2. + <_> + + <_> + 6 3 3 1 -1. + <_> + 7 3 1 1 3. + <_> + + <_> + 11 15 2 4 -1. + <_> + 11 17 2 2 2. + <_> + + <_> + 3 5 4 8 -1. + <_> + 3 9 4 4 2. + <_> + + <_> + 7 1 6 12 -1. + <_> + 7 7 6 6 2. + <_> + + <_> + 4 6 6 2 -1. + <_> + 6 6 2 2 3. + <_> + + <_> + 16 4 4 6 -1. + <_> + 16 6 4 2 3. + <_> + + <_> + 3 3 5 2 -1. + <_> + 3 4 5 1 2. + <_> + + <_> + 9 11 2 3 -1. + <_> + 9 12 2 1 3. + <_> + + <_> + 2 16 4 2 -1. + <_> + 2 17 4 1 2. + <_> + + <_> + 7 13 6 6 -1. + <_> + 10 13 3 3 2. + <_> + 7 16 3 3 2. + <_> + + <_> + 7 0 3 4 -1. + <_> + 8 0 1 4 3. + <_> + + <_> + 8 15 4 3 -1. + <_> + 8 16 4 1 3. + <_> + + <_> + 0 4 4 6 -1. + <_> + 0 6 4 2 3. + <_> + + <_> + 5 6 12 3 -1. + <_> + 9 6 4 3 3. + <_> + + <_> + 7 6 6 14 -1. + <_> + 9 6 2 14 3. + <_> + + <_> + 9 7 3 3 -1. + <_> + 10 7 1 3 3. + <_> + + <_> + 6 12 2 4 -1. + <_> + 6 14 2 2 2. + <_> + + <_> + 10 12 7 6 -1. + <_> + 10 14 7 2 3. + <_> + + <_> + 1 0 15 2 -1. + <_> + 1 1 15 1 2. + <_> + + <_> + 14 0 6 6 -1. + <_> + 14 0 3 6 2. + <_> + + <_> + 5 3 3 1 -1. + <_> + 6 3 1 1 3. + <_> + + <_> + 14 0 6 6 -1. + <_> + 14 0 3 6 2. + <_> + + <_> + 0 3 20 10 -1. + <_> + 0 8 20 5 2. + <_> + + <_> + 14 0 6 6 -1. + <_> + 14 0 3 6 2. + <_> + + <_> + 0 0 6 6 -1. + <_> + 3 0 3 6 2. + <_> + + <_> + 19 15 1 2 -1. + <_> + 19 16 1 1 2. + <_> + + <_> + 0 2 4 8 -1. + <_> + 2 2 2 8 2. + <_> + + <_> + 2 1 18 4 -1. + <_> + 11 1 9 2 2. + <_> + 2 3 9 2 2. + <_> + + <_> + 8 12 1 2 -1. + <_> + 8 13 1 1 2. + <_> + + <_> + 5 2 10 6 -1. + <_> + 10 2 5 3 2. + <_> + 5 5 5 3 2. + <_> + + <_> + 9 7 2 4 -1. + <_> + 10 7 1 4 2. + <_> + + <_> + 9 7 3 3 -1. + <_> + 10 7 1 3 3. + <_> + + <_> + 4 5 12 8 -1. + <_> + 8 5 4 8 3. + <_> + + <_> + 15 15 4 3 -1. + <_> + 15 16 4 1 3. + <_> + + <_> + 8 18 3 1 -1. + <_> + 9 18 1 1 3. + <_> + + <_> + 9 13 4 3 -1. + <_> + 9 14 4 1 3. + <_> + + <_> + 7 13 4 3 -1. + <_> + 7 14 4 1 3. + <_> + + <_> + 19 15 1 2 -1. + <_> + 19 16 1 1 2. + <_> + + <_> + 0 15 8 4 -1. + <_> + 0 17 8 2 2. + <_> + + <_> + 9 3 6 4 -1. + <_> + 11 3 2 4 3. + <_> + + <_> + 8 14 4 3 -1. + <_> + 8 15 4 1 3. + <_> + + <_> + 3 14 14 6 -1. + <_> + 3 16 14 2 3. + <_> + + <_> + 6 3 6 6 -1. + <_> + 6 6 6 3 2. + <_> + + <_> + 5 11 10 6 -1. + <_> + 5 14 10 3 2. + <_> + + <_> + 3 10 3 4 -1. + <_> + 4 10 1 4 3. + <_> + + <_> + 13 9 2 2 -1. + <_> + 13 9 1 2 2. + <_> + + <_> + 5 3 6 4 -1. + <_> + 7 3 2 4 3. + <_> + + <_> + 9 7 3 3 -1. + <_> + 10 7 1 3 3. + <_> + + <_> + 2 12 2 3 -1. + <_> + 2 13 2 1 3. + <_> + + <_> + 9 8 3 12 -1. + <_> + 9 12 3 4 3. + <_> + + <_> + 3 14 4 6 -1. + <_> + 3 14 2 3 2. + <_> + 5 17 2 3 2. + <_> + + <_> + 16 15 2 2 -1. + <_> + 16 16 2 1 2. + <_> + + <_> + 2 15 2 2 -1. + <_> + 2 16 2 1 2. + <_> + + <_> + 8 12 4 3 -1. + <_> + 8 13 4 1 3. + <_> + + <_> + 0 7 20 1 -1. + <_> + 10 7 10 1 2. + <_> + + <_> + 7 6 8 3 -1. + <_> + 7 6 4 3 2. + <_> + + <_> + 5 7 8 2 -1. + <_> + 9 7 4 2 2. + <_> + + <_> + 9 7 3 5 -1. + <_> + 10 7 1 5 3. + <_> + + <_> + 8 7 3 5 -1. + <_> + 9 7 1 5 3. + <_> + + <_> + 11 1 3 5 -1. + <_> + 12 1 1 5 3. + <_> + + <_> + 6 2 3 6 -1. + <_> + 7 2 1 6 3. + <_> + + <_> + 14 14 6 5 -1. + <_> + 14 14 3 5 2. + <_> + + <_> + 9 8 2 2 -1. + <_> + 9 9 2 1 2. + <_> + + <_> + 10 7 1 3 -1. + <_> + 10 8 1 1 3. + <_> + + <_> + 6 6 2 2 -1. + <_> + 6 6 1 1 2. + <_> + 7 7 1 1 2. + <_> + + <_> + 2 11 18 4 -1. + <_> + 11 11 9 2 2. + <_> + 2 13 9 2 2. + <_> + + <_> + 6 6 2 2 -1. + <_> + 6 6 1 1 2. + <_> + 7 7 1 1 2. + <_> + + <_> + 0 15 20 2 -1. + <_> + 0 16 20 1 2. + <_> + + <_> + 4 14 2 3 -1. + <_> + 4 15 2 1 3. + <_> + + <_> + 8 14 4 3 -1. + <_> + 8 15 4 1 3. + <_> + + <_> + 8 7 2 3 -1. + <_> + 8 8 2 1 3. + <_> + + <_> + 9 10 2 3 -1. + <_> + 9 11 2 1 3. + <_> + + <_> + 5 4 10 4 -1. + <_> + 5 6 10 2 2. + <_> + + <_> + 9 7 6 4 -1. + <_> + 12 7 3 2 2. + <_> + 9 9 3 2 2. + <_> + + <_> + 4 7 3 6 -1. + <_> + 4 9 3 2 3. + <_> + + <_> + 11 15 4 4 -1. + <_> + 13 15 2 2 2. + <_> + 11 17 2 2 2. + <_> + + <_> + 7 8 4 2 -1. + <_> + 7 9 4 1 2. + <_> + + <_> + 13 1 4 3 -1. + <_> + 13 1 2 3 2. + <_> + + <_> + 5 15 4 4 -1. + <_> + 5 15 2 2 2. + <_> + 7 17 2 2 2. + <_> + + <_> + 9 5 4 7 -1. + <_> + 9 5 2 7 2. + <_> + + <_> + 5 6 8 3 -1. + <_> + 9 6 4 3 2. + <_> + + <_> + 9 9 2 2 -1. + <_> + 9 10 2 1 2. + <_> + + <_> + 7 15 5 3 -1. + <_> + 7 16 5 1 3. + <_> + + <_> + 11 10 4 3 -1. + <_> + 11 10 2 3 2. + <_> + + <_> + 6 9 8 10 -1. + <_> + 6 14 8 5 2. + <_> + + <_> + 10 11 6 2 -1. + <_> + 10 11 3 2 2. + <_> + + <_> + 4 11 6 2 -1. + <_> + 7 11 3 2 2. + <_> + + <_> + 11 3 8 1 -1. + <_> + 11 3 4 1 2. + <_> + + <_> + 6 3 3 2 -1. + <_> + 7 3 1 2 3. + <_> + + <_> + 14 5 6 5 -1. + <_> + 14 5 3 5 2. + <_> + + <_> + 7 5 2 12 -1. + <_> + 7 11 2 6 2. + <_> + + <_> + 8 11 4 3 -1. + <_> + 8 12 4 1 3. + <_> + + <_> + 4 1 2 3 -1. + <_> + 5 1 1 3 2. + <_> + + <_> + 18 3 2 6 -1. + <_> + 18 5 2 2 3. + <_> + + <_> + 0 3 2 6 -1. + <_> + 0 5 2 2 3. + <_> + + <_> + 9 12 2 3 -1. + <_> + 9 13 2 1 3. + <_> + + <_> + 7 13 4 3 -1. + <_> + 7 14 4 1 3. + <_> + + <_> + 18 0 2 6 -1. + <_> + 18 2 2 2 3. + <_> + + <_> + 0 0 2 6 -1. + <_> + 0 2 2 2 3. + <_> + + <_> + 8 14 6 3 -1. + <_> + 8 15 6 1 3. + <_> + + <_> + 7 4 2 4 -1. + <_> + 8 4 1 4 2. + <_> + + <_> + 8 5 4 6 -1. + <_> + 8 7 4 2 3. + <_> + + <_> + 6 4 2 2 -1. + <_> + 7 4 1 2 2. + <_> + + <_> + 3 14 14 4 -1. + <_> + 10 14 7 2 2. + <_> + 3 16 7 2 2. + <_> + + <_> + 6 15 6 2 -1. + <_> + 6 15 3 1 2. + <_> + 9 16 3 1 2. + <_> + + <_> + 14 15 6 2 -1. + <_> + 14 16 6 1 2. + <_> + + <_> + 2 12 12 8 -1. + <_> + 2 16 12 4 2. + <_> + + <_> + 7 7 7 2 -1. + <_> + 7 8 7 1 2. + <_> + + <_> + 0 2 18 2 -1. + <_> + 0 3 18 1 2. + <_> + + <_> + 9 6 2 5 -1. + <_> + 9 6 1 5 2. + <_> + + <_> + 7 5 3 8 -1. + <_> + 8 5 1 8 3. + <_> + + <_> + 9 6 3 4 -1. + <_> + 10 6 1 4 3. + <_> + + <_> + 4 13 3 2 -1. + <_> + 4 14 3 1 2. + <_> + + <_> + 9 4 6 3 -1. + <_> + 11 4 2 3 3. + <_> + + <_> + 5 4 6 3 -1. + <_> + 7 4 2 3 3. + <_> + + <_> + 14 11 5 2 -1. + <_> + 14 12 5 1 2. + <_> + + <_> + 1 2 6 9 -1. + <_> + 3 2 2 9 3. + <_> + + <_> + 14 6 6 13 -1. + <_> + 14 6 3 13 2. + <_> + + <_> + 3 6 14 8 -1. + <_> + 3 6 7 4 2. + <_> + 10 10 7 4 2. + <_> + + <_> + 16 0 4 11 -1. + <_> + 16 0 2 11 2. + <_> + + <_> + 3 4 12 12 -1. + <_> + 3 4 6 6 2. + <_> + 9 10 6 6 2. + <_> + + <_> + 11 4 5 3 -1. + <_> + 11 5 5 1 3. + <_> + + <_> + 4 11 4 2 -1. + <_> + 4 12 4 1 2. + <_> + + <_> + 10 7 2 2 -1. + <_> + 10 7 1 2 2. + <_> + + <_> + 8 7 2 2 -1. + <_> + 9 7 1 2 2. + <_> + + <_> + 9 17 3 2 -1. + <_> + 10 17 1 2 3. + <_> + + <_> + 5 6 3 3 -1. + <_> + 5 7 3 1 3. + <_> + + <_> + 10 0 3 3 -1. + <_> + 11 0 1 3 3. + <_> + + <_> + 5 6 6 2 -1. + <_> + 5 6 3 1 2. + <_> + 8 7 3 1 2. + <_> + + <_> + 12 16 4 3 -1. + <_> + 12 17 4 1 3. + <_> + + <_> + 3 12 3 2 -1. + <_> + 3 13 3 1 2. + <_> + + <_> + 9 12 3 2 -1. + <_> + 9 13 3 1 2. + <_> + + <_> + 1 11 16 4 -1. + <_> + 1 11 8 2 2. + <_> + 9 13 8 2 2. + <_> + + <_> + 12 4 3 3 -1. + <_> + 12 5 3 1 3. + <_> + + <_> + 4 4 5 3 -1. + <_> + 4 5 5 1 3. + <_> + + <_> + 12 16 4 3 -1. + <_> + 12 17 4 1 3. + <_> + + <_> + 5 4 3 3 -1. + <_> + 5 5 3 1 3. + <_> + + <_> + 9 0 2 2 -1. + <_> + 9 1 2 1 2. + <_> + + <_> + 8 9 4 2 -1. + <_> + 8 10 4 1 2. + <_> + + <_> + 8 8 4 3 -1. + <_> + 8 9 4 1 3. + <_> + + <_> + 0 13 6 3 -1. + <_> + 2 13 2 3 3. + <_> + + <_> + 16 14 3 2 -1. + <_> + 16 15 3 1 2. + <_> + + <_> + 1 18 18 2 -1. + <_> + 7 18 6 2 3. + <_> + + <_> + 16 14 3 2 -1. + <_> + 16 15 3 1 2. + <_> + + <_> + 1 14 3 2 -1. + <_> + 1 15 3 1 2. + <_> + + <_> + 7 14 6 3 -1. + <_> + 7 15 6 1 3. + <_> + + <_> + 5 14 8 3 -1. + <_> + 5 15 8 1 3. + <_> + + <_> + 10 6 4 14 -1. + <_> + 10 6 2 14 2. + <_> + + <_> + 6 6 4 14 -1. + <_> + 8 6 2 14 2. + <_> + + <_> + 13 5 2 3 -1. + <_> + 13 6 2 1 3. + <_> + + <_> + 7 16 6 1 -1. + <_> + 9 16 2 1 3. + <_> + + <_> + 9 12 3 3 -1. + <_> + 9 13 3 1 3. + <_> + + <_> + 7 0 3 3 -1. + <_> + 8 0 1 3 3. + <_> + + <_> + 4 0 16 18 -1. + <_> + 4 9 16 9 2. + <_> + + <_> + 1 1 16 14 -1. + <_> + 1 8 16 7 2. + <_> + + <_> + 3 9 15 4 -1. + <_> + 8 9 5 4 3. + <_> + + <_> + 6 12 7 3 -1. + <_> + 6 13 7 1 3. + <_> + + <_> + 14 15 2 3 -1. + <_> + 14 16 2 1 3. + <_> + + <_> + 2 3 16 14 -1. + <_> + 2 3 8 7 2. + <_> + 10 10 8 7 2. + <_> + + <_> + 16 2 4 18 -1. + <_> + 18 2 2 9 2. + <_> + 16 11 2 9 2. + <_> + + <_> + 4 15 2 3 -1. + <_> + 4 16 2 1 3. + <_> + + <_> + 16 2 4 18 -1. + <_> + 18 2 2 9 2. + <_> + 16 11 2 9 2. + <_> + + <_> + 1 1 8 3 -1. + <_> + 1 2 8 1 3. + <_> + + <_> + 8 11 4 3 -1. + <_> + 8 12 4 1 3. + <_> + + <_> + 5 11 5 9 -1. + <_> + 5 14 5 3 3. + <_> + + <_> + 16 0 4 11 -1. + <_> + 16 0 2 11 2. + <_> + + <_> + 7 0 6 1 -1. + <_> + 9 0 2 1 3. + <_> + + <_> + 16 3 3 7 -1. + <_> + 17 3 1 7 3. + <_> + + <_> + 1 3 3 7 -1. + <_> + 2 3 1 7 3. + <_> + + <_> + 7 8 6 12 -1. + <_> + 7 12 6 4 3. + <_> + + <_> + 0 0 4 11 -1. + <_> + 2 0 2 11 2. + <_> + + <_> + 14 0 6 20 -1. + <_> + 14 0 3 20 2. + <_> + + <_> + 0 3 1 2 -1. + <_> + 0 4 1 1 2. + <_> + + <_> + 5 5 10 8 -1. + <_> + 10 5 5 4 2. + <_> + 5 9 5 4 2. + <_> + + <_> + 4 7 12 4 -1. + <_> + 4 7 6 2 2. + <_> + 10 9 6 2 2. + <_> + + <_> + 2 1 6 4 -1. + <_> + 5 1 3 4 2. + <_> + + <_> + 9 7 6 4 -1. + <_> + 12 7 3 2 2. + <_> + 9 9 3 2 2. + <_> + + <_> + 5 6 2 6 -1. + <_> + 5 9 2 3 2. + <_> + + <_> + 9 16 6 4 -1. + <_> + 12 16 3 2 2. + <_> + 9 18 3 2 2. + <_> + + <_> + 9 4 2 12 -1. + <_> + 9 10 2 6 2. + <_> + + <_> + 7 1 6 18 -1. + <_> + 9 1 2 18 3. + <_> + + <_> + 4 12 12 2 -1. + <_> + 8 12 4 2 3. + <_> + + <_> + 8 8 6 2 -1. + <_> + 8 9 6 1 2. + <_> + + <_> + 8 0 3 6 -1. + <_> + 9 0 1 6 3. + <_> + + <_> + 11 18 3 2 -1. + <_> + 11 19 3 1 2. + <_> + + <_> + 1 1 17 4 -1. + <_> + 1 3 17 2 2. + <_> + + <_> + 11 8 4 12 -1. + <_> + 11 8 2 12 2. + <_> + + <_> + 8 14 4 3 -1. + <_> + 8 15 4 1 3. + <_> + + <_> + 12 3 2 17 -1. + <_> + 12 3 1 17 2. + <_> + + <_> + 4 7 6 1 -1. + <_> + 6 7 2 1 3. + <_> + + <_> + 18 3 2 3 -1. + <_> + 18 4 2 1 3. + <_> + + <_> + 8 4 3 4 -1. + <_> + 8 6 3 2 2. + <_> + + <_> + 4 5 12 10 -1. + <_> + 4 10 12 5 2. + <_> + + <_> + 5 18 4 2 -1. + <_> + 7 18 2 2 2. + <_> + + <_> + 17 2 3 6 -1. + <_> + 17 4 3 2 3. + <_> + + <_> + 7 7 6 6 -1. + <_> + 9 7 2 6 3. + <_> + + <_> + 17 2 3 6 -1. + <_> + 17 4 3 2 3. + <_> + + <_> + 8 0 3 4 -1. + <_> + 9 0 1 4 3. + <_> + + <_> + 9 14 2 3 -1. + <_> + 9 15 2 1 3. + <_> + + <_> + 0 12 6 3 -1. + <_> + 0 13 6 1 3. + <_> + + <_> + 8 14 4 3 -1. + <_> + 8 15 4 1 3. + <_> + + <_> + 3 12 2 3 -1. + <_> + 3 13 2 1 3. + <_> + + <_> + 5 6 12 7 -1. + <_> + 9 6 4 7 3. + <_> + + <_> + 0 2 3 6 -1. + <_> + 0 4 3 2 3. + <_> + + <_> + 14 6 1 3 -1. + <_> + 14 7 1 1 3. + <_> + + <_> + 2 0 3 14 -1. + <_> + 3 0 1 14 3. + <_> + + <_> + 12 14 5 6 -1. + <_> + 12 16 5 2 3. + <_> + + <_> + 4 14 5 6 -1. + <_> + 4 16 5 2 3. + <_> + + <_> + 11 10 2 2 -1. + <_> + 12 10 1 1 2. + <_> + 11 11 1 1 2. + <_> + + <_> + 5 0 3 14 -1. + <_> + 6 0 1 14 3. + <_> + + <_> + 10 15 2 3 -1. + <_> + 10 16 2 1 3. + <_> + + <_> + 0 2 2 3 -1. + <_> + 0 3 2 1 3. + <_> + + <_> + 5 11 12 6 -1. + <_> + 5 14 12 3 2. + <_> + + <_> + 6 11 3 9 -1. + <_> + 6 14 3 3 3. + <_> + + <_> + 11 10 2 2 -1. + <_> + 12 10 1 1 2. + <_> + 11 11 1 1 2. + <_> + + <_> + 5 6 1 3 -1. + <_> + 5 7 1 1 3. + <_> + + <_> + 4 9 13 3 -1. + <_> + 4 10 13 1 3. + <_> + + <_> + 1 7 15 6 -1. + <_> + 6 7 5 6 3. + <_> + + <_> + 4 5 12 6 -1. + <_> + 8 5 4 6 3. + <_> + + <_> + 8 10 4 3 -1. + <_> + 8 11 4 1 3. + <_> + + <_> + 15 14 1 3 -1. + <_> + 15 15 1 1 3. + <_> + + <_> + 1 11 5 3 -1. + <_> + 1 12 5 1 3. + <_> + + <_> + 7 1 7 12 -1. + <_> + 7 7 7 6 2. + <_> + + <_> + 0 1 6 10 -1. + <_> + 0 1 3 5 2. + <_> + 3 6 3 5 2. + <_> + + <_> + 16 1 4 3 -1. + <_> + 16 2 4 1 3. + <_> + + <_> + 5 5 2 3 -1. + <_> + 5 6 2 1 3. + <_> + + <_> + 12 2 3 5 -1. + <_> + 13 2 1 5 3. + <_> + + <_> + 0 3 4 6 -1. + <_> + 0 5 4 2 3. + <_> + + <_> + 8 12 4 2 -1. + <_> + 8 13 4 1 2. + <_> + + <_> + 8 18 3 1 -1. + <_> + 9 18 1 1 3. + <_> + + <_> + 11 10 2 2 -1. + <_> + 12 10 1 1 2. + <_> + 11 11 1 1 2. + <_> + + <_> + 7 10 2 2 -1. + <_> + 7 10 1 1 2. + <_> + 8 11 1 1 2. + <_> + + <_> + 11 11 4 4 -1. + <_> + 11 13 4 2 2. + <_> + + <_> + 8 12 3 8 -1. + <_> + 9 12 1 8 3. + <_> + + <_> + 13 0 6 3 -1. + <_> + 13 1 6 1 3. + <_> + + <_> + 8 8 3 4 -1. + <_> + 9 8 1 4 3. + <_> + + <_> + 5 7 10 10 -1. + <_> + 10 7 5 5 2. + <_> + 5 12 5 5 2. + <_> + + <_> + 3 18 8 2 -1. + <_> + 3 18 4 1 2. + <_> + 7 19 4 1 2. + <_> + + <_> + 10 2 6 8 -1. + <_> + 12 2 2 8 3. + <_> + + <_> + 4 2 6 8 -1. + <_> + 6 2 2 8 3. + <_> + + <_> + 11 0 3 7 -1. + <_> + 12 0 1 7 3. + <_> + + <_> + 7 11 2 1 -1. + <_> + 8 11 1 1 2. + <_> + + <_> + 15 14 1 3 -1. + <_> + 15 15 1 1 3. + <_> + + <_> + 7 15 2 2 -1. + <_> + 7 15 1 1 2. + <_> + 8 16 1 1 2. + <_> + + <_> + 15 14 1 3 -1. + <_> + 15 15 1 1 3. + <_> + + <_> + 6 0 3 7 -1. + <_> + 7 0 1 7 3. + <_> + + <_> + 18 1 2 7 -1. + <_> + 18 1 1 7 2. + <_> + + <_> + 2 0 8 20 -1. + <_> + 2 10 8 10 2. + <_> + + <_> + 3 0 15 6 -1. + <_> + 3 2 15 2 3. + <_> + + <_> + 4 3 12 2 -1. + <_> + 4 4 12 1 2. + <_> + + <_> + 16 0 4 5 -1. + <_> + 16 0 2 5 2. + <_> + + <_> + 7 0 3 4 -1. + <_> + 8 0 1 4 3. + <_> + + <_> + 16 0 4 5 -1. + <_> + 16 0 2 5 2. + <_> + + <_> + 1 7 6 13 -1. + <_> + 3 7 2 13 3. + <_> + + <_> + 16 0 4 5 -1. + <_> + 16 0 2 5 2. + <_> + + <_> + 0 0 4 5 -1. + <_> + 2 0 2 5 2. + <_> + + <_> + 14 12 3 6 -1. + <_> + 14 14 3 2 3. + <_> + + <_> + 3 12 3 6 -1. + <_> + 3 14 3 2 3. + <_> + + <_> + 16 1 4 3 -1. + <_> + 16 2 4 1 3. + <_> + + <_> + 8 7 2 10 -1. + <_> + 8 7 1 5 2. + <_> + 9 12 1 5 2. + <_> + + <_> + 11 11 4 4 -1. + <_> + 11 13 4 2 2. + <_> + + <_> + 0 1 4 3 -1. + <_> + 0 2 4 1 3. + <_> + + <_> + 13 4 1 3 -1. + <_> + 13 5 1 1 3. + <_> + + <_> + 7 15 3 5 -1. + <_> + 8 15 1 5 3. + <_> + + <_> + 9 7 3 5 -1. + <_> + 10 7 1 5 3. + <_> + + <_> + 8 7 3 5 -1. + <_> + 9 7 1 5 3. + <_> + + <_> + 10 6 4 14 -1. + <_> + 10 6 2 14 2. + <_> + + <_> + 0 5 5 6 -1. + <_> + 0 7 5 2 3. + <_> + + <_> + 9 5 6 4 -1. + <_> + 9 5 3 4 2. + <_> + + <_> + 0 0 18 10 -1. + <_> + 6 0 6 10 3. + <_> + + <_> + 10 6 4 14 -1. + <_> + 10 6 2 14 2. + <_> + + <_> + 6 6 4 14 -1. + <_> + 8 6 2 14 2. + <_> + + <_> + 13 4 1 3 -1. + <_> + 13 5 1 1 3. + <_> + + <_> + 5 1 2 3 -1. + <_> + 6 1 1 3 2. + <_> + + <_> + 18 1 2 18 -1. + <_> + 19 1 1 9 2. + <_> + 18 10 1 9 2. + <_> + + <_> + 2 1 4 3 -1. + <_> + 2 2 4 1 3. + <_> + + <_> + 18 1 2 18 -1. + <_> + 19 1 1 9 2. + <_> + 18 10 1 9 2. + <_> + + <_> + 1 14 4 6 -1. + <_> + 1 14 2 3 2. + <_> + 3 17 2 3 2. + <_> + + <_> + 10 11 7 6 -1. + <_> + 10 13 7 2 3. + <_> + + <_> + 0 10 6 10 -1. + <_> + 0 10 3 5 2. + <_> + 3 15 3 5 2. + <_> + + <_> + 11 0 3 4 -1. + <_> + 12 0 1 4 3. + <_> + + <_> + 5 10 5 6 -1. + <_> + 5 13 5 3 2. + <_> + + <_> + 14 6 1 8 -1. + <_> + 14 10 1 4 2. + <_> + + <_> + 1 7 18 6 -1. + <_> + 1 7 9 3 2. + <_> + 10 10 9 3 2. + <_> + + <_> + 9 7 2 2 -1. + <_> + 9 7 1 2 2. + <_> + + <_> + 5 9 4 5 -1. + <_> + 7 9 2 5 2. + <_> + + <_> + 7 6 6 3 -1. + <_> + 9 6 2 3 3. + <_> + + <_> + 1 0 18 4 -1. + <_> + 7 0 6 4 3. + <_> + + <_> + 7 15 2 4 -1. + <_> + 7 17 2 2 2. + <_> + + <_> + 1 0 19 9 -1. + <_> + 1 3 19 3 3. + <_> + + <_> + 3 7 3 6 -1. + <_> + 3 9 3 2 3. + <_> + + <_> + 13 7 4 4 -1. + <_> + 15 7 2 2 2. + <_> + 13 9 2 2 2. + <_> + + <_> + 3 7 4 4 -1. + <_> + 3 7 2 2 2. + <_> + 5 9 2 2 2. + <_> + + <_> + 9 6 10 8 -1. + <_> + 9 10 10 4 2. + <_> + + <_> + 3 8 14 12 -1. + <_> + 3 14 14 6 2. + <_> + + <_> + 6 5 10 12 -1. + <_> + 11 5 5 6 2. + <_> + 6 11 5 6 2. + <_> + + <_> + 9 11 2 3 -1. + <_> + 9 12 2 1 3. + <_> + + <_> + 9 5 6 5 -1. + <_> + 9 5 3 5 2. + <_> + + <_> + 9 4 2 4 -1. + <_> + 9 6 2 2 2. + <_> + + <_> + 9 5 6 5 -1. + <_> + 9 5 3 5 2. + <_> + + <_> + 5 5 6 5 -1. + <_> + 8 5 3 5 2. + <_> + + <_> + 11 2 6 1 -1. + <_> + 13 2 2 1 3. + <_> + + <_> + 3 2 6 1 -1. + <_> + 5 2 2 1 3. + <_> + + <_> + 13 5 2 3 -1. + <_> + 13 6 2 1 3. + <_> + + <_> + 0 10 1 4 -1. + <_> + 0 12 1 2 2. + <_> + + <_> + 13 5 2 3 -1. + <_> + 13 6 2 1 3. + <_> + + <_> + 8 18 3 2 -1. + <_> + 9 18 1 2 3. + <_> + + <_> + 6 15 9 2 -1. + <_> + 6 16 9 1 2. + <_> + + <_> + 8 14 4 3 -1. + <_> + 8 15 4 1 3. + <_> + + <_> + 18 4 2 4 -1. + <_> + 18 6 2 2 2. + <_> + + <_> + 5 5 2 3 -1. + <_> + 5 6 2 1 3. + <_> + + <_> + 15 16 3 2 -1. + <_> + 15 17 3 1 2. + <_> + + <_> + 0 0 3 9 -1. + <_> + 0 3 3 3 3. + <_> + + <_> + 9 7 3 3 -1. + <_> + 9 8 3 1 3. + <_> + + <_> + 8 7 3 3 -1. + <_> + 8 8 3 1 3. + <_> + + <_> + 9 5 2 6 -1. + <_> + 9 5 1 6 2. + <_> + + <_> + 8 6 3 4 -1. + <_> + 9 6 1 4 3. + <_> + + <_> + 7 6 8 12 -1. + <_> + 11 6 4 6 2. + <_> + 7 12 4 6 2. + <_> + + <_> + 5 6 8 12 -1. + <_> + 5 6 4 6 2. + <_> + 9 12 4 6 2. + <_> + + <_> + 12 4 3 3 -1. + <_> + 12 5 3 1 3. + <_> + + <_> + 2 16 3 2 -1. + <_> + 2 17 3 1 2. + <_> + + <_> + 12 4 3 3 -1. + <_> + 12 5 3 1 3. + <_> + + <_> + 2 12 6 6 -1. + <_> + 2 14 6 2 3. + <_> + + <_> + 7 13 6 3 -1. + <_> + 7 14 6 1 3. + <_> + + <_> + 6 14 6 3 -1. + <_> + 6 15 6 1 3. + <_> + + <_> + 14 15 5 3 -1. + <_> + 14 16 5 1 3. + <_> + + <_> + 5 4 3 3 -1. + <_> + 5 5 3 1 3. + <_> + + <_> + 14 15 5 3 -1. + <_> + 14 16 5 1 3. + <_> + + <_> + 5 3 6 2 -1. + <_> + 7 3 2 2 3. + <_> + + <_> + 8 15 4 3 -1. + <_> + 8 16 4 1 3. + <_> + + <_> + 1 15 5 3 -1. + <_> + 1 16 5 1 3. + <_> + + <_> + 8 13 4 6 -1. + <_> + 10 13 2 3 2. + <_> + 8 16 2 3 2. + <_> + + <_> + 7 8 3 3 -1. + <_> + 8 8 1 3 3. + <_> + + <_> + 12 0 5 4 -1. + <_> + 12 2 5 2 2. + <_> + + <_> + 0 2 20 2 -1. + <_> + 0 2 10 1 2. + <_> + 10 3 10 1 2. + <_> + + <_> + 1 0 18 4 -1. + <_> + 7 0 6 4 3. + <_> + + <_> + 4 3 6 1 -1. + <_> + 6 3 2 1 3. + <_> + + <_> + 4 18 13 2 -1. + <_> + 4 19 13 1 2. + <_> + + <_> + 2 10 3 6 -1. + <_> + 2 12 3 2 3. + <_> + + <_> + 14 12 6 8 -1. + <_> + 17 12 3 4 2. + <_> + 14 16 3 4 2. + <_> + + <_> + 4 13 10 6 -1. + <_> + 4 13 5 3 2. + <_> + 9 16 5 3 2. + <_> + + <_> + 14 12 1 2 -1. + <_> + 14 13 1 1 2. + <_> + + <_> + 8 13 4 3 -1. + <_> + 8 14 4 1 3. + <_> + + <_> + 14 12 2 2 -1. + <_> + 14 13 2 1 2. + <_> + + <_> + 4 12 2 2 -1. + <_> + 4 13 2 1 2. + <_> + + <_> + 8 12 9 2 -1. + <_> + 8 13 9 1 2. + <_> + + <_> + 9 14 2 3 -1. + <_> + 9 15 2 1 3. + <_> + + <_> + 11 10 3 6 -1. + <_> + 11 13 3 3 2. + <_> + + <_> + 5 6 9 12 -1. + <_> + 5 12 9 6 2. + <_> + + <_> + 11 10 3 6 -1. + <_> + 11 13 3 3 2. + <_> + + <_> + 6 10 3 6 -1. + <_> + 6 13 3 3 2. + <_> + + <_> + 5 4 11 3 -1. + <_> + 5 5 11 1 3. + <_> + + <_> + 7 1 5 10 -1. + <_> + 7 6 5 5 2. + <_> + + <_> + 2 8 18 2 -1. + <_> + 2 9 18 1 2. + <_> + + <_> + 7 17 5 3 -1. + <_> + 7 18 5 1 3. + <_> + + <_> + 5 9 12 1 -1. + <_> + 9 9 4 1 3. + <_> + + <_> + 0 14 6 6 -1. + <_> + 0 14 3 3 2. + <_> + 3 17 3 3 2. + <_> + + <_> + 5 9 12 1 -1. + <_> + 9 9 4 1 3. + <_> + + <_> + 3 9 12 1 -1. + <_> + 7 9 4 1 3. + <_> + + <_> + 14 10 6 7 -1. + <_> + 14 10 3 7 2. + <_> + + <_> + 1 0 16 2 -1. + <_> + 1 1 16 1 2. + <_> + + <_> + 10 9 10 9 -1. + <_> + 10 12 10 3 3. + <_> + + <_> + 0 1 10 2 -1. + <_> + 5 1 5 2 2. + <_> + + <_> + 17 3 2 3 -1. + <_> + 17 4 2 1 3. + <_> + + <_> + 1 3 2 3 -1. + <_> + 1 4 2 1 3. + <_> + + <_> + 9 7 3 6 -1. + <_> + 10 7 1 6 3. + <_> + + <_> + 6 5 4 3 -1. + <_> + 8 5 2 3 2. + <_> + + <_> + 7 5 6 6 -1. + <_> + 9 5 2 6 3. + <_> + + <_> + 3 4 12 12 -1. + <_> + 3 4 6 6 2. + <_> + 9 10 6 6 2. + <_> + + <_> + 9 2 6 15 -1. + <_> + 11 2 2 15 3. + <_> + + <_> + 2 2 6 17 -1. + <_> + 4 2 2 17 3. + <_> + + <_> + 14 10 6 7 -1. + <_> + 14 10 3 7 2. + <_> + + <_> + 0 10 6 7 -1. + <_> + 3 10 3 7 2. + <_> + + <_> + 9 2 6 15 -1. + <_> + 11 2 2 15 3. + <_> + + <_> + 5 2 6 15 -1. + <_> + 7 2 2 15 3. + <_> + + <_> + 17 9 3 6 -1. + <_> + 17 11 3 2 3. + <_> + + <_> + 6 7 6 6 -1. + <_> + 8 7 2 6 3. + <_> + + <_> + 1 10 18 6 -1. + <_> + 10 10 9 3 2. + <_> + 1 13 9 3 2. + <_> + + <_> + 0 9 10 9 -1. + <_> + 0 12 10 3 3. + <_> + + <_> + 8 15 4 3 -1. + <_> + 8 16 4 1 3. + <_> + + <_> + 5 12 3 4 -1. + <_> + 5 14 3 2 2. + <_> + + <_> + 3 3 16 12 -1. + <_> + 3 9 16 6 2. + <_> + + <_> + 1 1 12 12 -1. + <_> + 1 1 6 6 2. + <_> + 7 7 6 6 2. + <_> + + <_> + 10 4 2 4 -1. + <_> + 11 4 1 2 2. + <_> + 10 6 1 2 2. + <_> + + <_> + 0 9 10 2 -1. + <_> + 0 9 5 1 2. + <_> + 5 10 5 1 2. + <_> + + <_> + 9 11 3 3 -1. + <_> + 9 12 3 1 3. + <_> + + <_> + 3 12 9 2 -1. + <_> + 3 13 9 1 2. + <_> + + <_> + 9 9 2 2 -1. + <_> + 9 10 2 1 2. + <_> + + <_> + 3 4 13 6 -1. + <_> + 3 6 13 2 3. + <_> + + <_> + 9 7 6 4 -1. + <_> + 12 7 3 2 2. + <_> + 9 9 3 2 2. + <_> + + <_> + 1 0 6 8 -1. + <_> + 4 0 3 8 2. + <_> + + <_> + 9 5 2 12 -1. + <_> + 9 11 2 6 2. + <_> + + <_> + 4 4 3 10 -1. + <_> + 4 9 3 5 2. + <_> + + <_> + 6 17 8 3 -1. + <_> + 6 18 8 1 3. + <_> + + <_> + 0 5 10 6 -1. + <_> + 0 7 10 2 3. + <_> + + <_> + 13 2 3 2 -1. + <_> + 13 3 3 1 2. + <_> + + <_> + 7 5 4 5 -1. + <_> + 9 5 2 5 2. + <_> + + <_> + 12 14 3 6 -1. + <_> + 12 16 3 2 3. + <_> + + <_> + 1 11 8 2 -1. + <_> + 1 12 8 1 2. + <_> + + <_> + 7 13 6 3 -1. + <_> + 7 14 6 1 3. + <_> + + <_> + 0 5 3 6 -1. + <_> + 0 7 3 2 3. + <_> + + <_> + 13 2 3 2 -1. + <_> + 13 3 3 1 2. + <_> + + <_> + 4 14 4 6 -1. + <_> + 4 14 2 3 2. + <_> + 6 17 2 3 2. + <_> + + <_> + 13 2 3 2 -1. + <_> + 13 3 3 1 2. + <_> + + <_> + 8 2 4 12 -1. + <_> + 8 6 4 4 3. + <_> + + <_> + 14 0 6 8 -1. + <_> + 17 0 3 4 2. + <_> + 14 4 3 4 2. + <_> + + <_> + 7 17 3 2 -1. + <_> + 8 17 1 2 3. + <_> + + <_> + 8 12 4 2 -1. + <_> + 8 13 4 1 2. + <_> + + <_> + 6 0 8 12 -1. + <_> + 6 0 4 6 2. + <_> + 10 6 4 6 2. + <_> + + <_> + 14 0 2 10 -1. + <_> + 15 0 1 5 2. + <_> + 14 5 1 5 2. + <_> + + <_> + 5 3 8 6 -1. + <_> + 5 3 4 3 2. + <_> + 9 6 4 3 2. + <_> + + <_> + 14 0 6 10 -1. + <_> + 17 0 3 5 2. + <_> + 14 5 3 5 2. + <_> + + <_> + 9 14 1 2 -1. + <_> + 9 15 1 1 2. + <_> + + <_> + 15 10 4 3 -1. + <_> + 15 11 4 1 3. + <_> + + <_> + 8 14 2 3 -1. + <_> + 8 15 2 1 3. + <_> + + <_> + 3 13 14 4 -1. + <_> + 10 13 7 2 2. + <_> + 3 15 7 2 2. + <_> + + <_> + 1 10 4 3 -1. + <_> + 1 11 4 1 3. + <_> + + <_> + 9 11 6 1 -1. + <_> + 11 11 2 1 3. + <_> + + <_> + 5 11 6 1 -1. + <_> + 7 11 2 1 3. + <_> + + <_> + 3 5 16 15 -1. + <_> + 3 10 16 5 3. + <_> + + <_> + 6 12 4 2 -1. + <_> + 8 12 2 2 2. + <_> + + <_> + 4 4 12 10 -1. + <_> + 10 4 6 5 2. + <_> + 4 9 6 5 2. + <_> + + <_> + 8 6 3 4 -1. + <_> + 9 6 1 4 3. + <_> + + <_> + 8 12 4 8 -1. + <_> + 10 12 2 4 2. + <_> + 8 16 2 4 2. + <_> + + <_> + 8 14 4 3 -1. + <_> + 8 15 4 1 3. + <_> + + <_> + 12 2 3 2 -1. + <_> + 13 2 1 2 3. + <_> + + <_> + 8 15 3 2 -1. + <_> + 8 16 3 1 2. + <_> + + <_> + 6 0 9 14 -1. + <_> + 9 0 3 14 3. + <_> + + <_> + 9 6 2 3 -1. + <_> + 10 6 1 3 2. + <_> + + <_> + 10 8 2 3 -1. + <_> + 10 9 2 1 3. + <_> + + <_> + 0 9 4 6 -1. + <_> + 0 11 4 2 3. + <_> + + <_> + 6 0 8 2 -1. + <_> + 6 1 8 1 2. + <_> + + <_> + 6 14 7 3 -1. + <_> + 6 15 7 1 3. + <_> + + <_> + 8 10 8 9 -1. + <_> + 8 13 8 3 3. + <_> + + <_> + 5 2 3 2 -1. + <_> + 6 2 1 2 3. + <_> + + <_> + 14 1 6 8 -1. + <_> + 17 1 3 4 2. + <_> + 14 5 3 4 2. + <_> + + <_> + 0 1 6 8 -1. + <_> + 0 1 3 4 2. + <_> + 3 5 3 4 2. + <_> + + <_> + 1 2 18 6 -1. + <_> + 10 2 9 3 2. + <_> + 1 5 9 3 2. + <_> + + <_> + 9 3 2 1 -1. + <_> + 10 3 1 1 2. + <_> + + <_> + 13 2 4 6 -1. + <_> + 15 2 2 3 2. + <_> + 13 5 2 3 2. + <_> + + <_> + 5 4 3 3 -1. + <_> + 5 5 3 1 3. + <_> + + <_> + 13 5 1 3 -1. + <_> + 13 6 1 1 3. + <_> + + <_> + 2 16 5 3 -1. + <_> + 2 17 5 1 3. + <_> + + <_> + 13 2 4 6 -1. + <_> + 15 2 2 3 2. + <_> + 13 5 2 3 2. + <_> + + <_> + 3 2 4 6 -1. + <_> + 3 2 2 3 2. + <_> + 5 5 2 3 2. + <_> + + <_> + 13 5 1 2 -1. + <_> + 13 6 1 1 2. + <_> + + <_> + 5 5 2 2 -1. + <_> + 5 6 2 1 2. + <_> + + <_> + 13 9 2 2 -1. + <_> + 13 9 1 2 2. + <_> + + <_> + 5 9 2 2 -1. + <_> + 6 9 1 2 2. + <_> + + <_> + 13 17 3 2 -1. + <_> + 13 18 3 1 2. + <_> + + <_> + 6 16 4 4 -1. + <_> + 6 16 2 2 2. + <_> + 8 18 2 2 2. + <_> + + <_> + 9 16 2 3 -1. + <_> + 9 17 2 1 3. + <_> + + <_> + 0 13 9 6 -1. + <_> + 0 15 9 2 3. + <_> + + <_> + 9 14 2 6 -1. + <_> + 9 17 2 3 2. + <_> + + <_> + 9 15 2 3 -1. + <_> + 9 16 2 1 3. + <_> + + <_> + 1 10 18 6 -1. + <_> + 1 12 18 2 3. + <_> + + <_> + 8 11 4 2 -1. + <_> + 8 12 4 1 2. + <_> + + <_> + 7 9 6 2 -1. + <_> + 7 10 6 1 2. + <_> + + <_> + 8 8 2 3 -1. + <_> + 8 9 2 1 3. + <_> + + <_> + 17 5 3 4 -1. + <_> + 18 5 1 4 3. + <_> + + <_> + 1 19 18 1 -1. + <_> + 7 19 6 1 3. + <_> + + <_> + 9 0 3 2 -1. + <_> + 10 0 1 2 3. + <_> + + <_> + 1 8 1 6 -1. + <_> + 1 10 1 2 3. + <_> + + <_> + 12 17 8 3 -1. + <_> + 12 17 4 3 2. + <_> + + <_> + 0 5 3 4 -1. + <_> + 1 5 1 4 3. + <_> + + <_> + 9 7 2 3 -1. + <_> + 9 8 2 1 3. + <_> + + <_> + 7 11 2 2 -1. + <_> + 7 11 1 1 2. + <_> + 8 12 1 1 2. + <_> + + <_> + 11 3 2 5 -1. + <_> + 11 3 1 5 2. + <_> + + <_> + 7 3 2 5 -1. + <_> + 8 3 1 5 2. + <_> + + <_> + 15 13 2 3 -1. + <_> + 15 14 2 1 3. + <_> + + <_> + 5 6 2 3 -1. + <_> + 5 7 2 1 3. + <_> + + <_> + 4 19 15 1 -1. + <_> + 9 19 5 1 3. + <_> + + <_> + 1 19 15 1 -1. + <_> + 6 19 5 1 3. + <_> + + <_> + 15 13 2 3 -1. + <_> + 15 14 2 1 3. + <_> + + <_> + 5 0 4 15 -1. + <_> + 7 0 2 15 2. + <_> + + <_> + 9 6 2 5 -1. + <_> + 9 6 1 5 2. + <_> + + <_> + 9 5 2 7 -1. + <_> + 10 5 1 7 2. + <_> + + <_> + 16 11 3 3 -1. + <_> + 16 12 3 1 3. + <_> + + <_> + 1 11 3 3 -1. + <_> + 1 12 3 1 3. + <_> + + <_> + 6 6 8 3 -1. + <_> + 6 7 8 1 3. + <_> + + <_> + 0 15 6 2 -1. + <_> + 0 16 6 1 2. + <_> + + <_> + 1 0 18 6 -1. + <_> + 7 0 6 6 3. + <_> + + <_> + 6 0 3 4 -1. + <_> + 7 0 1 4 3. + <_> + + <_> + 14 10 4 10 -1. + <_> + 16 10 2 5 2. + <_> + 14 15 2 5 2. + <_> + + <_> + 3 2 3 2 -1. + <_> + 4 2 1 2 3. + <_> + + <_> + 11 2 2 2 -1. + <_> + 11 3 2 1 2. + <_> + + <_> + 2 10 4 10 -1. + <_> + 2 10 2 5 2. + <_> + 4 15 2 5 2. + <_> + + <_> + 0 13 20 6 -1. + <_> + 10 13 10 3 2. + <_> + 0 16 10 3 2. + <_> + + <_> + 0 5 2 15 -1. + <_> + 1 5 1 15 2. + <_> + + <_> + 1 7 18 4 -1. + <_> + 10 7 9 2 2. + <_> + 1 9 9 2 2. + <_> + + <_> + 0 0 2 17 -1. + <_> + 1 0 1 17 2. + <_> + + <_> + 2 6 16 6 -1. + <_> + 10 6 8 3 2. + <_> + 2 9 8 3 2. + <_> + + <_> + 8 14 1 3 -1. + <_> + 8 15 1 1 3. + <_> + + <_> + 8 15 4 2 -1. + <_> + 8 16 4 1 2. + <_> + + <_> + 5 2 8 2 -1. + <_> + 5 2 4 1 2. + <_> + 9 3 4 1 2. + <_> + + <_> + 6 11 8 6 -1. + <_> + 6 14 8 3 2. + <_> + + <_> + 9 13 2 2 -1. + <_> + 9 14 2 1 2. + <_> + + <_> + 18 4 2 6 -1. + <_> + 18 6 2 2 3. + <_> + + <_> + 9 12 2 2 -1. + <_> + 9 13 2 1 2. + <_> + + <_> + 18 4 2 6 -1. + <_> + 18 6 2 2 3. + <_> + + <_> + 9 13 1 3 -1. + <_> + 9 14 1 1 3. + <_> + + <_> + 18 4 2 6 -1. + <_> + 18 6 2 2 3. + <_> + + <_> + 0 4 2 6 -1. + <_> + 0 6 2 2 3. + <_> + + <_> + 9 12 3 3 -1. + <_> + 9 13 3 1 3. + <_> + + <_> + 3 13 2 3 -1. + <_> + 3 14 2 1 3. + <_> + + <_> + 13 13 4 3 -1. + <_> + 13 14 4 1 3. + <_> + + <_> + 5 4 3 3 -1. + <_> + 5 5 3 1 3. + <_> + + <_> + 5 2 10 6 -1. + <_> + 5 4 10 2 3. + <_> + + <_> + 3 13 4 3 -1. + <_> + 3 14 4 1 3. + <_> + + <_> + 3 7 15 5 -1. + <_> + 8 7 5 5 3. + <_> + + <_> + 3 7 12 2 -1. + <_> + 7 7 4 2 3. + <_> + + <_> + 10 3 3 9 -1. + <_> + 11 3 1 9 3. + <_> + + <_> + 8 6 4 6 -1. + <_> + 10 6 2 6 2. + <_> + + <_> + 9 7 4 3 -1. + <_> + 9 8 4 1 3. + <_> + + <_> + 0 9 4 9 -1. + <_> + 2 9 2 9 2. + <_> + + <_> + 9 13 3 5 -1. + <_> + 10 13 1 5 3. + <_> + + <_> + 7 7 6 3 -1. + <_> + 9 7 2 3 3. + <_> + + <_> + 9 7 3 5 -1. + <_> + 10 7 1 5 3. + <_> + + <_> + 5 7 8 2 -1. + <_> + 9 7 4 2 2. + <_> + + <_> + 5 9 12 2 -1. + <_> + 9 9 4 2 3. + <_> + + <_> + 5 6 10 3 -1. + <_> + 10 6 5 3 2. + <_> + + <_> + 10 12 3 1 -1. + <_> + 11 12 1 1 3. + <_> + + <_> + 0 1 11 15 -1. + <_> + 0 6 11 5 3. + <_> + + <_> + 1 0 18 6 -1. + <_> + 7 0 6 6 3. + <_> + + <_> + 7 7 6 1 -1. + <_> + 9 7 2 1 3. + <_> + + <_> + 5 16 6 4 -1. + <_> + 5 16 3 2 2. + <_> + 8 18 3 2 2. + <_> + + <_> + 6 5 9 8 -1. + <_> + 6 9 9 4 2. + <_> + + <_> + 5 10 2 6 -1. + <_> + 5 13 2 3 2. + <_> + + <_> + 7 6 8 10 -1. + <_> + 11 6 4 5 2. + <_> + 7 11 4 5 2. + <_> + + <_> + 5 6 8 10 -1. + <_> + 5 6 4 5 2. + <_> + 9 11 4 5 2. + <_> + + <_> + 9 5 2 2 -1. + <_> + 9 6 2 1 2. + <_> + + <_> + 5 12 8 2 -1. + <_> + 5 13 8 1 2. + <_> + + <_> + 10 2 8 2 -1. + <_> + 10 3 8 1 2. + <_> + + <_> + 4 0 2 10 -1. + <_> + 4 0 1 5 2. + <_> + 5 5 1 5 2. + <_> + + <_> + 9 10 2 2 -1. + <_> + 9 11 2 1 2. + <_> + + <_> + 2 8 15 3 -1. + <_> + 2 9 15 1 3. + <_> + + <_> + 8 13 4 3 -1. + <_> + 8 14 4 1 3. + <_> + + <_> + 7 2 3 2 -1. + <_> + 8 2 1 2 3. + <_> + + <_> + 7 13 6 3 -1. + <_> + 7 14 6 1 3. + <_> + + <_> + 9 9 2 2 -1. + <_> + 9 10 2 1 2. + <_> + + <_> + 17 2 3 6 -1. + <_> + 17 4 3 2 3. + <_> + + <_> + 1 5 3 4 -1. + <_> + 2 5 1 4 3. + <_> + + <_> + 14 8 4 6 -1. + <_> + 14 10 4 2 3. + <_> + + <_> + 1 4 3 8 -1. + <_> + 2 4 1 8 3. + <_> + + <_> + 8 13 4 6 -1. + <_> + 8 16 4 3 2. + <_> + + <_> + 3 14 2 2 -1. + <_> + 3 15 2 1 2. + <_> + + <_> + 14 8 4 6 -1. + <_> + 14 10 4 2 3. + <_> + + <_> + 2 8 4 6 -1. + <_> + 2 10 4 2 3. + <_> + + <_> + 10 14 1 6 -1. + <_> + 10 17 1 3 2. + <_> + + <_> + 7 5 3 6 -1. + <_> + 8 5 1 6 3. + <_> + + <_> + 11 2 2 6 -1. + <_> + 12 2 1 3 2. + <_> + 11 5 1 3 2. + <_> + + <_> + 6 6 6 5 -1. + <_> + 8 6 2 5 3. + <_> + + <_> + 17 1 3 6 -1. + <_> + 17 3 3 2 3. + <_> + + <_> + 8 7 3 5 -1. + <_> + 9 7 1 5 3. + <_> + + <_> + 9 18 3 2 -1. + <_> + 10 18 1 2 3. + <_> + + <_> + 8 18 3 2 -1. + <_> + 9 18 1 2 3. + <_> + + <_> + 12 3 5 2 -1. + <_> + 12 4 5 1 2. + <_> + + <_> + 7 1 5 12 -1. + <_> + 7 7 5 6 2. + <_> + + <_> + 1 0 18 4 -1. + <_> + 7 0 6 4 3. + <_> + + <_> + 4 2 2 2 -1. + <_> + 4 3 2 1 2. + <_> + + <_> + 11 14 4 2 -1. + <_> + 13 14 2 1 2. + <_> + 11 15 2 1 2. + <_> + + <_> + 0 2 3 6 -1. + <_> + 0 4 3 2 3. + <_> + + <_> + 9 7 2 3 -1. + <_> + 9 8 2 1 3. + <_> + + <_> + 5 5 1 3 -1. + <_> + 5 6 1 1 3. + <_> + + <_> + 10 10 6 1 -1. + <_> + 10 10 3 1 2. + <_> + + <_> + 4 10 6 1 -1. + <_> + 7 10 3 1 2. + <_> + + <_> + 9 17 3 3 -1. + <_> + 9 18 3 1 3. + <_> + + <_> + 4 14 1 3 -1. + <_> + 4 15 1 1 3. + <_> + + <_> + 12 5 3 3 -1. + <_> + 12 6 3 1 3. + <_> + + <_> + 4 5 12 3 -1. + <_> + 4 6 12 1 3. + <_> + + <_> + 9 8 2 3 -1. + <_> + 9 9 2 1 3. + <_> + + <_> + 4 9 3 3 -1. + <_> + 5 9 1 3 3. + <_> + + <_> + 6 0 9 17 -1. + <_> + 9 0 3 17 3. + <_> + + <_> + 9 12 1 3 -1. + <_> + 9 13 1 1 3. + <_> + + <_> + 9 5 2 15 -1. + <_> + 9 10 2 5 3. + <_> + + <_> + 8 14 2 3 -1. + <_> + 8 15 2 1 3. + <_> + + <_> + 10 14 1 3 -1. + <_> + 10 15 1 1 3. + <_> + + <_> + 7 1 6 5 -1. + <_> + 9 1 2 5 3. + <_> + + <_> + 0 0 20 2 -1. + <_> + 0 0 10 2 2. + <_> + + <_> + 2 13 5 3 -1. + <_> + 2 14 5 1 3. + <_> + + <_> + 9 11 2 3 -1. + <_> + 9 12 2 1 3. + <_> + + <_> + 2 5 9 15 -1. + <_> + 2 10 9 5 3. + <_> + + <_> + 5 0 12 10 -1. + <_> + 11 0 6 5 2. + <_> + 5 5 6 5 2. + <_> + + <_> + 5 1 2 3 -1. + <_> + 6 1 1 3 2. + <_> + + <_> + 10 7 6 1 -1. + <_> + 12 7 2 1 3. + <_> + + <_> + 3 1 2 10 -1. + <_> + 3 1 1 5 2. + <_> + 4 6 1 5 2. + <_> + + <_> + 13 7 2 1 -1. + <_> + 13 7 1 1 2. + <_> + + <_> + 4 13 4 6 -1. + <_> + 4 15 4 2 3. + <_> + + <_> + 13 7 2 1 -1. + <_> + 13 7 1 1 2. + <_> + + <_> + 5 7 2 1 -1. + <_> + 6 7 1 1 2. + <_> + + <_> + 2 12 18 4 -1. + <_> + 11 12 9 2 2. + <_> + 2 14 9 2 2. + <_> + + <_> + 5 7 2 2 -1. + <_> + 5 7 1 1 2. + <_> + 6 8 1 1 2. + <_> + + <_> + 16 3 4 2 -1. + <_> + 16 4 4 1 2. + <_> + + <_> + 0 2 2 18 -1. + <_> + 0 2 1 9 2. + <_> + 1 11 1 9 2. + <_> + + <_> + 1 2 18 4 -1. + <_> + 10 2 9 2 2. + <_> + 1 4 9 2 2. + <_> + + <_> + 9 14 1 3 -1. + <_> + 9 15 1 1 3. + <_> + + <_> + 2 12 18 4 -1. + <_> + 11 12 9 2 2. + <_> + 2 14 9 2 2. + <_> + + <_> + 0 12 18 4 -1. + <_> + 0 12 9 2 2. + <_> + 9 14 9 2 2. + <_> + + <_> + 11 4 5 3 -1. + <_> + 11 5 5 1 3. + <_> + + <_> + 6 4 7 3 -1. + <_> + 6 5 7 1 3. + <_> + + <_> + 13 17 3 3 -1. + <_> + 13 18 3 1 3. + <_> + + <_> + 8 1 3 4 -1. + <_> + 9 1 1 4 3. + <_> + + <_> + 11 4 2 4 -1. + <_> + 11 4 1 4 2. + <_> + + <_> + 0 17 9 3 -1. + <_> + 3 17 3 3 3. + <_> + + <_> + 11 0 2 8 -1. + <_> + 12 0 1 4 2. + <_> + 11 4 1 4 2. + <_> + + <_> + 0 8 6 12 -1. + <_> + 0 8 3 6 2. + <_> + 3 14 3 6 2. + <_> + + <_> + 10 7 4 12 -1. + <_> + 10 13 4 6 2. + <_> + + <_> + 5 3 8 14 -1. + <_> + 5 10 8 7 2. + <_> + + <_> + 14 10 6 1 -1. + <_> + 14 10 3 1 2. + <_> + + <_> + 0 4 10 4 -1. + <_> + 0 6 10 2 2. + <_> + + <_> + 10 0 5 8 -1. + <_> + 10 4 5 4 2. + <_> + + <_> + 8 1 4 8 -1. + <_> + 8 1 2 4 2. + <_> + 10 5 2 4 2. + <_> + + <_> + 9 11 6 1 -1. + <_> + 11 11 2 1 3. + <_> + + <_> + 8 9 3 4 -1. + <_> + 9 9 1 4 3. + <_> + + <_> + 18 4 2 6 -1. + <_> + 18 6 2 2 3. + <_> + + <_> + 8 8 3 4 -1. + <_> + 9 8 1 4 3. + <_> + + <_> + 7 1 13 3 -1. + <_> + 7 2 13 1 3. + <_> + + <_> + 7 13 6 1 -1. + <_> + 9 13 2 1 3. + <_> + + <_> + 12 11 3 6 -1. + <_> + 12 13 3 2 3. + <_> + + <_> + 5 11 6 1 -1. + <_> + 7 11 2 1 3. + <_> + + <_> + 1 4 18 10 -1. + <_> + 10 4 9 5 2. + <_> + 1 9 9 5 2. + <_> + + <_> + 8 6 4 9 -1. + <_> + 8 9 4 3 3. + <_> + + <_> + 8 6 4 3 -1. + <_> + 8 7 4 1 3. + <_> + + <_> + 8 7 3 3 -1. + <_> + 9 7 1 3 3. + <_> + + <_> + 14 15 4 3 -1. + <_> + 14 16 4 1 3. + <_> + + <_> + 5 10 3 10 -1. + <_> + 6 10 1 10 3. + <_> + + <_> + 8 15 4 3 -1. + <_> + 8 16 4 1 3. + <_> + + <_> + 0 8 1 6 -1. + <_> + 0 10 1 2 3. + <_> + + <_> + 10 15 1 3 -1. + <_> + 10 16 1 1 3. + <_> + + <_> + 2 15 4 3 -1. + <_> + 2 16 4 1 3. + <_> + + <_> + 18 3 2 8 -1. + <_> + 19 3 1 4 2. + <_> + 18 7 1 4 2. + <_> + + <_> + 0 3 2 8 -1. + <_> + 0 3 1 4 2. + <_> + 1 7 1 4 2. + <_> + + <_> + 3 7 14 10 -1. + <_> + 10 7 7 5 2. + <_> + 3 12 7 5 2. + <_> + + <_> + 0 7 19 3 -1. + <_> + 0 8 19 1 3. + <_> + + <_> + 12 6 3 3 -1. + <_> + 12 7 3 1 3. + <_> + + <_> + 0 6 1 3 -1. + <_> + 0 7 1 1 3. + <_> + + <_> + 12 6 3 3 -1. + <_> + 12 7 3 1 3. + <_> + + <_> + 5 6 3 3 -1. + <_> + 5 7 3 1 3. + <_> + + <_> + 8 2 4 2 -1. + <_> + 8 3 4 1 2. + <_> + + <_> + 6 3 4 12 -1. + <_> + 8 3 2 12 2. + <_> + + <_> + 13 6 2 3 -1. + <_> + 13 7 2 1 3. + <_> + + <_> + 0 10 20 4 -1. + <_> + 0 12 20 2 2. + <_> + + <_> + 2 0 17 14 -1. + <_> + 2 7 17 7 2. + <_> + + <_> + 0 0 6 10 -1. + <_> + 0 0 3 5 2. + <_> + 3 5 3 5 2. + <_> + + <_> + 14 6 6 4 -1. + <_> + 14 6 3 4 2. + <_> + + <_> + 0 6 6 4 -1. + <_> + 3 6 3 4 2. + <_> + + <_> + 13 2 7 2 -1. + <_> + 13 3 7 1 2. + <_> + + <_> + 0 2 7 2 -1. + <_> + 0 3 7 1 2. + <_> + + <_> + 6 11 14 2 -1. + <_> + 13 11 7 1 2. + <_> + 6 12 7 1 2. + <_> + + <_> + 8 5 2 2 -1. + <_> + 8 5 1 1 2. + <_> + 9 6 1 1 2. + <_> + + <_> + 13 9 2 3 -1. + <_> + 13 9 1 3 2. + <_> + + <_> + 1 1 3 12 -1. + <_> + 2 1 1 12 3. + <_> + + <_> + 17 4 1 3 -1. + <_> + 17 5 1 1 3. + <_> + + <_> + 2 4 1 3 -1. + <_> + 2 5 1 1 3. + <_> + + <_> + 14 5 1 3 -1. + <_> + 14 6 1 1 3. + <_> + + <_> + 7 16 2 3 -1. + <_> + 7 17 2 1 3. + <_> + + <_> + 8 13 4 6 -1. + <_> + 10 13 2 3 2. + <_> + 8 16 2 3 2. + <_> + + <_> + 5 5 1 3 -1. + <_> + 5 6 1 1 3. + <_> + + <_> + 16 0 4 20 -1. + <_> + 16 0 2 20 2. + <_> + + <_> + 5 1 2 6 -1. + <_> + 5 1 1 3 2. + <_> + 6 4 1 3 2. + <_> + + <_> + 5 4 10 4 -1. + <_> + 5 6 10 2 2. + <_> + + <_> + 15 2 4 12 -1. + <_> + 15 2 2 12 2. + <_> + + <_> + 7 6 4 12 -1. + <_> + 7 12 4 6 2. + <_> + + <_> + 14 5 1 8 -1. + <_> + 14 9 1 4 2. + <_> + + <_> + 1 4 14 10 -1. + <_> + 1 4 7 5 2. + <_> + 8 9 7 5 2. + <_> + + <_> + 11 6 6 14 -1. + <_> + 14 6 3 7 2. + <_> + 11 13 3 7 2. + <_> + + <_> + 3 6 6 14 -1. + <_> + 3 6 3 7 2. + <_> + 6 13 3 7 2. + <_> + + <_> + 4 9 15 2 -1. + <_> + 9 9 5 2 3. + <_> + + <_> + 7 14 6 3 -1. + <_> + 7 15 6 1 3. + <_> + + <_> + 6 3 14 4 -1. + <_> + 13 3 7 2 2. + <_> + 6 5 7 2 2. + <_> + + <_> + 1 9 15 2 -1. + <_> + 6 9 5 2 3. + <_> + + <_> + 6 11 8 9 -1. + <_> + 6 14 8 3 3. + <_> + + <_> + 7 4 3 8 -1. + <_> + 8 4 1 8 3. + <_> + + <_> + 14 6 2 6 -1. + <_> + 14 9 2 3 2. + <_> + + <_> + 5 7 6 4 -1. + <_> + 5 7 3 2 2. + <_> + 8 9 3 2 2. + <_> + + <_> + 1 1 18 19 -1. + <_> + 7 1 6 19 3. + <_> + + <_> + 1 2 6 5 -1. + <_> + 4 2 3 5 2. + <_> + + <_> + 12 17 6 2 -1. + <_> + 12 18 6 1 2. + <_> + + <_> + 2 17 6 2 -1. + <_> + 2 18 6 1 2. + <_> + + <_> + 17 3 3 6 -1. + <_> + 17 5 3 2 3. + <_> + + <_> + 8 17 3 3 -1. + <_> + 8 18 3 1 3. + <_> + + <_> + 10 13 2 6 -1. + <_> + 10 16 2 3 2. + <_> + + <_> + 7 13 6 3 -1. + <_> + 7 14 6 1 3. + <_> + + <_> + 17 3 3 6 -1. + <_> + 17 5 3 2 3. + <_> + + <_> + 8 13 2 3 -1. + <_> + 8 14 2 1 3. + <_> + + <_> + 9 3 6 2 -1. + <_> + 11 3 2 2 3. + <_> + + <_> + 0 3 3 6 -1. + <_> + 0 5 3 2 3. + <_> + + <_> + 8 5 4 6 -1. + <_> + 8 7 4 2 3. + <_> + + <_> + 5 5 3 2 -1. + <_> + 5 6 3 1 2. + <_> + + <_> + 10 1 3 4 -1. + <_> + 11 1 1 4 3. + <_> + + <_> + 1 2 5 9 -1. + <_> + 1 5 5 3 3. + <_> + + <_> + 13 6 2 3 -1. + <_> + 13 7 2 1 3. + <_> + + <_> + 0 6 14 3 -1. + <_> + 7 6 7 3 2. + <_> + + <_> + 2 11 18 8 -1. + <_> + 2 15 18 4 2. + <_> + + <_> + 5 6 2 3 -1. + <_> + 5 7 2 1 3. + <_> + + <_> + 10 6 4 2 -1. + <_> + 12 6 2 1 2. + <_> + 10 7 2 1 2. + <_> + + <_> + 6 6 4 2 -1. + <_> + 6 6 2 1 2. + <_> + 8 7 2 1 2. + <_> + + <_> + 10 1 3 4 -1. + <_> + 11 1 1 4 3. + <_> + + <_> + 7 1 2 7 -1. + <_> + 8 1 1 7 2. + <_> + + <_> + 4 2 15 14 -1. + <_> + 4 9 15 7 2. + <_> + + <_> + 8 7 3 2 -1. + <_> + 9 7 1 2 3. + <_> + + <_> + 2 3 18 4 -1. + <_> + 11 3 9 2 2. + <_> + 2 5 9 2 2. + <_> + + <_> + 9 7 2 2 -1. + <_> + 10 7 1 2 2. + <_> + + <_> + 13 9 2 3 -1. + <_> + 13 9 1 3 2. + <_> + + <_> + 5 2 6 2 -1. + <_> + 7 2 2 2 3. + <_> + + <_> + 9 5 2 7 -1. + <_> + 9 5 1 7 2. + <_> + + <_> + 5 9 2 3 -1. + <_> + 6 9 1 3 2. + <_> + + <_> + 6 0 14 18 -1. + <_> + 6 9 14 9 2. + <_> + + <_> + 2 16 6 3 -1. + <_> + 2 17 6 1 3. + <_> + + <_> + 9 7 3 6 -1. + <_> + 10 7 1 6 3. + <_> + + <_> + 7 8 4 3 -1. + <_> + 7 9 4 1 3. + <_> + + <_> + 7 12 6 3 -1. + <_> + 7 13 6 1 3. + <_> + + <_> + 9 12 2 3 -1. + <_> + 9 13 2 1 3. + <_> + + <_> + 7 12 6 2 -1. + <_> + 9 12 2 2 3. + <_> + + <_> + 5 11 4 6 -1. + <_> + 5 14 4 3 2. + <_> + + <_> + 11 12 7 2 -1. + <_> + 11 13 7 1 2. + <_> + + <_> + 6 10 8 6 -1. + <_> + 6 10 4 3 2. + <_> + 10 13 4 3 2. + <_> + + <_> + 11 10 3 4 -1. + <_> + 11 12 3 2 2. + <_> + + <_> + 9 16 2 3 -1. + <_> + 9 17 2 1 3. + <_> + + <_> + 13 3 1 9 -1. + <_> + 13 6 1 3 3. + <_> + + <_> + 1 13 14 6 -1. + <_> + 1 15 14 2 3. + <_> + + <_> + 13 6 1 6 -1. + <_> + 13 9 1 3 2. + <_> + + <_> + 0 4 3 8 -1. + <_> + 1 4 1 8 3. + <_> + + <_> + 18 0 2 18 -1. + <_> + 18 0 1 18 2. + <_> + + <_> + 2 3 6 2 -1. + <_> + 2 4 6 1 2. + <_> + + <_> + 9 0 8 6 -1. + <_> + 9 2 8 2 3. + <_> + + <_> + 6 6 1 6 -1. + <_> + 6 9 1 3 2. + <_> + + <_> + 14 8 6 3 -1. + <_> + 14 9 6 1 3. + <_> + + <_> + 0 0 2 18 -1. + <_> + 1 0 1 18 2. + <_> + + <_> + 1 18 18 2 -1. + <_> + 10 18 9 1 2. + <_> + 1 19 9 1 2. + <_> + + <_> + 3 15 2 2 -1. + <_> + 3 16 2 1 2. + <_> + + <_> + 8 14 5 3 -1. + <_> + 8 15 5 1 3. + <_> + + <_> + 8 14 2 3 -1. + <_> + 8 15 2 1 3. + <_> + + <_> + 12 3 3 3 -1. + <_> + 13 3 1 3 3. + <_> + + <_> + 7 5 6 2 -1. + <_> + 9 5 2 2 3. + <_> + + <_> + 15 5 5 2 -1. + <_> + 15 6 5 1 2. + <_> + + <_> + 0 5 5 2 -1. + <_> + 0 6 5 1 2. + <_> + + <_> + 17 14 1 6 -1. + <_> + 17 17 1 3 2. + <_> + + <_> + 2 9 9 3 -1. + <_> + 5 9 3 3 3. + <_> + + <_> + 12 3 3 3 -1. + <_> + 13 3 1 3 3. + <_> + + <_> + 0 0 4 18 -1. + <_> + 2 0 2 18 2. + <_> + + <_> + 17 6 1 3 -1. + <_> + 17 7 1 1 3. + <_> + + <_> + 2 14 1 6 -1. + <_> + 2 17 1 3 2. + <_> + + <_> + 19 8 1 2 -1. + <_> + 19 9 1 1 2. + <_> + + <_> + 5 3 3 3 -1. + <_> + 6 3 1 3 3. + <_> + + <_> + 9 16 2 3 -1. + <_> + 9 17 2 1 3. + <_> + + <_> + 2 6 1 3 -1. + <_> + 2 7 1 1 3. + <_> + + <_> + 12 4 8 2 -1. + <_> + 16 4 4 1 2. + <_> + 12 5 4 1 2. + <_> + + <_> + 0 4 8 2 -1. + <_> + 0 4 4 1 2. + <_> + 4 5 4 1 2. + <_> + + <_> + 2 16 18 4 -1. + <_> + 2 18 18 2 2. + <_> + + <_> + 7 15 2 4 -1. + <_> + 7 17 2 2 2. + <_> + + <_> + 4 0 14 3 -1. + <_> + 4 1 14 1 3. + <_> + + <_> + 0 0 4 20 -1. + <_> + 2 0 2 20 2. + <_> + + <_> + 12 4 4 8 -1. + <_> + 14 4 2 4 2. + <_> + 12 8 2 4 2. + <_> + + <_> + 6 7 2 2 -1. + <_> + 6 7 1 1 2. + <_> + 7 8 1 1 2. + <_> + + <_> + 10 6 2 3 -1. + <_> + 10 7 2 1 3. + <_> + + <_> + 8 7 3 2 -1. + <_> + 8 8 3 1 2. + <_> + + <_> + 8 2 6 12 -1. + <_> + 8 8 6 6 2. + <_> + + <_> + 4 0 11 12 -1. + <_> + 4 4 11 4 3. + <_> + + <_> + 14 9 6 11 -1. + <_> + 16 9 2 11 3. + <_> + + <_> + 0 14 4 3 -1. + <_> + 0 15 4 1 3. + <_> + + <_> + 9 10 2 3 -1. + <_> + 9 11 2 1 3. + <_> + + <_> + 5 11 3 2 -1. + <_> + 5 12 3 1 2. + <_> + + <_> + 9 15 3 3 -1. + <_> + 10 15 1 3 3. + <_> + + <_> + 8 8 3 4 -1. + <_> + 9 8 1 4 3. + <_> + + <_> + 9 15 3 3 -1. + <_> + 10 15 1 3 3. + <_> + + <_> + 7 7 3 2 -1. + <_> + 8 7 1 2 3. + <_> + + <_> + 2 10 16 4 -1. + <_> + 10 10 8 2 2. + <_> + 2 12 8 2 2. + <_> + + <_> + 2 3 4 17 -1. + <_> + 4 3 2 17 2. + <_> + + <_> + 15 13 2 7 -1. + <_> + 15 13 1 7 2. + <_> + + <_> + 2 2 6 1 -1. + <_> + 5 2 3 1 2. + <_> + + <_> + 5 2 12 4 -1. + <_> + 9 2 4 4 3. + <_> + + <_> + 6 0 8 12 -1. + <_> + 6 0 4 6 2. + <_> + 10 6 4 6 2. + <_> + + <_> + 13 7 2 2 -1. + <_> + 14 7 1 1 2. + <_> + 13 8 1 1 2. + <_> + + <_> + 0 12 20 6 -1. + <_> + 0 14 20 2 3. + <_> + + <_> + 14 7 2 3 -1. + <_> + 14 7 1 3 2. + <_> + + <_> + 0 8 9 12 -1. + <_> + 3 8 3 12 3. + <_> + + <_> + 3 0 16 2 -1. + <_> + 3 0 8 2 2. + <_> + + <_> + 6 15 3 3 -1. + <_> + 6 16 3 1 3. + <_> + + <_> + 8 15 6 3 -1. + <_> + 8 16 6 1 3. + <_> + + <_> + 0 10 1 6 -1. + <_> + 0 12 1 2 3. + <_> + + <_> + 10 9 4 3 -1. + <_> + 10 10 4 1 3. + <_> + + <_> + 9 15 2 3 -1. + <_> + 9 16 2 1 3. + <_> + + <_> + 5 7 10 1 -1. + <_> + 5 7 5 1 2. + <_> + + <_> + 4 0 12 19 -1. + <_> + 10 0 6 19 2. + <_> + + <_> + 0 6 20 6 -1. + <_> + 10 6 10 3 2. + <_> + 0 9 10 3 2. + <_> + + <_> + 3 6 2 2 -1. + <_> + 3 6 1 1 2. + <_> + 4 7 1 1 2. + <_> + + <_> + 15 6 2 2 -1. + <_> + 16 6 1 1 2. + <_> + 15 7 1 1 2. + <_> + + <_> + 3 6 2 2 -1. + <_> + 3 6 1 1 2. + <_> + 4 7 1 1 2. + <_> + + <_> + 14 4 1 12 -1. + <_> + 14 10 1 6 2. + <_> + + <_> + 2 5 16 10 -1. + <_> + 2 5 8 5 2. + <_> + 10 10 8 5 2. + <_> + + <_> + 9 17 3 2 -1. + <_> + 10 17 1 2 3. + <_> + + <_> + 1 4 2 2 -1. + <_> + 1 5 2 1 2. + <_> + + <_> + 5 0 15 5 -1. + <_> + 10 0 5 5 3. + <_> + + <_> + 0 0 15 5 -1. + <_> + 5 0 5 5 3. + <_> + + <_> + 11 2 2 17 -1. + <_> + 11 2 1 17 2. + <_> + + <_> + 7 2 2 17 -1. + <_> + 8 2 1 17 2. + <_> + + <_> + 15 11 2 9 -1. + <_> + 15 11 1 9 2. + <_> + + <_> + 3 11 2 9 -1. + <_> + 4 11 1 9 2. + <_> + + <_> + 5 16 14 4 -1. + <_> + 5 16 7 4 2. + <_> + + <_> + 1 4 18 1 -1. + <_> + 7 4 6 1 3. + <_> + + <_> + 13 7 6 4 -1. + <_> + 16 7 3 2 2. + <_> + 13 9 3 2 2. + <_> + + <_> + 9 8 2 12 -1. + <_> + 9 12 2 4 3. + <_> + + <_> + 12 1 6 6 -1. + <_> + 12 3 6 2 3. + <_> + + <_> + 5 2 6 6 -1. + <_> + 5 2 3 3 2. + <_> + 8 5 3 3 2. + <_> + + <_> + 9 16 6 4 -1. + <_> + 12 16 3 2 2. + <_> + 9 18 3 2 2. + <_> + + <_> + 1 2 18 3 -1. + <_> + 7 2 6 3 3. + <_> + + <_> + 7 4 9 10 -1. + <_> + 7 9 9 5 2. + <_> + + <_> + 5 9 4 4 -1. + <_> + 7 9 2 4 2. + <_> + + <_> + 11 10 3 6 -1. + <_> + 11 13 3 3 2. + <_> + + <_> + 7 11 5 3 -1. + <_> + 7 12 5 1 3. + <_> + + <_> + 7 11 6 6 -1. + <_> + 10 11 3 3 2. + <_> + 7 14 3 3 2. + <_> + + <_> + 0 0 10 9 -1. + <_> + 0 3 10 3 3. + <_> + + <_> + 13 14 1 6 -1. + <_> + 13 16 1 2 3. + <_> + + <_> + 0 2 3 6 -1. + <_> + 0 4 3 2 3. + <_> + + <_> + 8 14 4 3 -1. + <_> + 8 15 4 1 3. + <_> + + <_> + 6 14 1 6 -1. + <_> + 6 16 1 2 3. + <_> + + <_> + 9 15 2 3 -1. + <_> + 9 16 2 1 3. + <_> + + <_> + 6 4 3 3 -1. + <_> + 7 4 1 3 3. + <_> + + <_> + 9 0 11 3 -1. + <_> + 9 1 11 1 3. + <_> + + <_> + 0 6 20 3 -1. + <_> + 0 7 20 1 3. + <_> + + <_> + 10 1 1 2 -1. + <_> + 10 2 1 1 2. + <_> + + <_> + 9 6 2 6 -1. + <_> + 10 6 1 6 2. + <_> + + <_> + 5 8 12 1 -1. + <_> + 9 8 4 1 3. + <_> + + <_> + 3 8 12 1 -1. + <_> + 7 8 4 1 3. + <_> + + <_> + 9 7 3 5 -1. + <_> + 10 7 1 5 3. + <_> + + <_> + 3 9 6 2 -1. + <_> + 6 9 3 2 2. + <_> + + <_> + 12 9 3 3 -1. + <_> + 12 10 3 1 3. + <_> + + <_> + 7 0 6 1 -1. + <_> + 9 0 2 1 3. + <_> + + <_> + 12 9 3 3 -1. + <_> + 12 10 3 1 3. + <_> + + <_> + 7 10 2 1 -1. + <_> + 8 10 1 1 2. + <_> + + <_> + 6 4 9 13 -1. + <_> + 9 4 3 13 3. + <_> + + <_> + 6 8 4 2 -1. + <_> + 6 9 4 1 2. + <_> + + <_> + 16 2 4 6 -1. + <_> + 16 2 2 6 2. + <_> + + <_> + 0 17 6 3 -1. + <_> + 0 18 6 1 3. + <_> + + <_> + 10 10 3 10 -1. + <_> + 10 15 3 5 2. + <_> + + <_> + 8 7 3 5 -1. + <_> + 9 7 1 5 3. + <_> + + <_> + 10 4 4 3 -1. + <_> + 10 4 2 3 2. + <_> + + <_> + 8 4 3 8 -1. + <_> + 9 4 1 8 3. + <_> + + <_> + 6 6 9 13 -1. + <_> + 9 6 3 13 3. + <_> + + <_> + 6 0 8 12 -1. + <_> + 6 0 4 6 2. + <_> + 10 6 4 6 2. + <_> + + <_> + 14 2 6 8 -1. + <_> + 16 2 2 8 3. + <_> + + <_> + 6 0 3 6 -1. + <_> + 7 0 1 6 3. + <_> + + <_> + 14 2 6 8 -1. + <_> + 16 2 2 8 3. + <_> + + <_> + 0 5 6 6 -1. + <_> + 0 8 6 3 2. + <_> + + <_> + 9 12 6 2 -1. + <_> + 12 12 3 1 2. + <_> + 9 13 3 1 2. + <_> + + <_> + 8 17 3 2 -1. + <_> + 9 17 1 2 3. + <_> + + <_> + 11 6 2 2 -1. + <_> + 12 6 1 1 2. + <_> + 11 7 1 1 2. + <_> + + <_> + 1 9 18 2 -1. + <_> + 7 9 6 2 3. + <_> + + <_> + 11 6 2 2 -1. + <_> + 12 6 1 1 2. + <_> + 11 7 1 1 2. + <_> + + <_> + 3 4 12 8 -1. + <_> + 7 4 4 8 3. + <_> + + <_> + 13 11 5 3 -1. + <_> + 13 12 5 1 3. + <_> + + <_> + 9 10 2 3 -1. + <_> + 9 11 2 1 3. + <_> + + <_> + 14 7 2 3 -1. + <_> + 14 7 1 3 2. + <_> + + <_> + 5 4 1 3 -1. + <_> + 5 5 1 1 3. + <_> + + <_> + 13 4 2 3 -1. + <_> + 13 5 2 1 3. + <_> + + <_> + 5 4 2 3 -1. + <_> + 5 5 2 1 3. + <_> + + <_> + 9 8 2 3 -1. + <_> + 9 9 2 1 3. + <_> + + <_> + 8 9 2 2 -1. + <_> + 8 10 2 1 2. + <_> + + <_> + 15 14 1 4 -1. + <_> + 15 16 1 2 2. + <_> + + <_> + 3 12 2 2 -1. + <_> + 3 13 2 1 2. + <_> + + <_> + 12 15 2 2 -1. + <_> + 13 15 1 1 2. + <_> + 12 16 1 1 2. + <_> + + <_> + 9 13 2 2 -1. + <_> + 9 14 2 1 2. + <_> + + <_> + 4 11 14 9 -1. + <_> + 4 14 14 3 3. + <_> + + <_> + 7 13 4 3 -1. + <_> + 7 14 4 1 3. + <_> + + <_> + 15 14 1 4 -1. + <_> + 15 16 1 2 2. + <_> + + <_> + 4 14 1 4 -1. + <_> + 4 16 1 2 2. + <_> + + <_> + 14 0 6 13 -1. + <_> + 16 0 2 13 3. + <_> + + <_> + 4 1 2 12 -1. + <_> + 4 1 1 6 2. + <_> + 5 7 1 6 2. + <_> + + <_> + 11 14 6 6 -1. + <_> + 14 14 3 3 2. + <_> + 11 17 3 3 2. + <_> + + <_> + 3 14 6 6 -1. + <_> + 3 14 3 3 2. + <_> + 6 17 3 3 2. + <_> + + <_> + 14 17 3 2 -1. + <_> + 14 18 3 1 2. + <_> + + <_> + 3 17 3 2 -1. + <_> + 3 18 3 1 2. + <_> + + <_> + 14 0 6 13 -1. + <_> + 16 0 2 13 3. + <_> + + <_> + 0 0 6 13 -1. + <_> + 2 0 2 13 3. + <_> + + <_> + 10 10 7 6 -1. + <_> + 10 12 7 2 3. + <_> + + <_> + 6 15 2 2 -1. + <_> + 6 15 1 1 2. + <_> + 7 16 1 1 2. + <_> + + <_> + 6 11 8 6 -1. + <_> + 10 11 4 3 2. + <_> + 6 14 4 3 2. + <_> + + <_> + 7 6 2 2 -1. + <_> + 7 6 1 1 2. + <_> + 8 7 1 1 2. + <_> + + <_> + 2 2 16 6 -1. + <_> + 10 2 8 3 2. + <_> + 2 5 8 3 2. + <_> + + <_> + 5 4 3 3 -1. + <_> + 5 5 3 1 3. + <_> + + <_> + 11 7 3 10 -1. + <_> + 11 12 3 5 2. + <_> + + <_> + 6 7 3 10 -1. + <_> + 6 12 3 5 2. + <_> + + <_> + 10 7 3 2 -1. + <_> + 11 7 1 2 3. + <_> + + <_> + 8 12 4 2 -1. + <_> + 8 13 4 1 2. + <_> + + <_> + 10 1 1 3 -1. + <_> + 10 2 1 1 3. + <_> + + <_> + 1 2 4 18 -1. + <_> + 1 2 2 9 2. + <_> + 3 11 2 9 2. + <_> + + <_> + 12 4 4 12 -1. + <_> + 12 10 4 6 2. + <_> + + <_> + 0 0 1 6 -1. + <_> + 0 2 1 2 3. + <_> + + <_> + 9 11 2 3 -1. + <_> + 9 12 2 1 3. + <_> + + <_> + 8 7 4 3 -1. + <_> + 8 8 4 1 3. + <_> + + <_> + 10 7 3 2 -1. + <_> + 11 7 1 2 3. + <_> + + <_> + 7 7 3 2 -1. + <_> + 8 7 1 2 3. + <_> + + <_> + 9 4 6 1 -1. + <_> + 11 4 2 1 3. + <_> + + <_> + 8 7 2 3 -1. + <_> + 9 7 1 3 2. + <_> + + <_> + 12 7 8 6 -1. + <_> + 16 7 4 3 2. + <_> + 12 10 4 3 2. + <_> + + <_> + 0 7 8 6 -1. + <_> + 0 7 4 3 2. + <_> + 4 10 4 3 2. + <_> + + <_> + 18 2 2 10 -1. + <_> + 19 2 1 5 2. + <_> + 18 7 1 5 2. + <_> + + <_> + 0 2 6 4 -1. + <_> + 3 2 3 4 2. + <_> + + <_> + 9 4 6 1 -1. + <_> + 11 4 2 1 3. + <_> + + <_> + 7 15 2 2 -1. + <_> + 7 15 1 1 2. + <_> + 8 16 1 1 2. + <_> + + <_> + 11 13 1 6 -1. + <_> + 11 16 1 3 2. + <_> + + <_> + 8 13 1 6 -1. + <_> + 8 16 1 3 2. + <_> + + <_> + 14 3 2 1 -1. + <_> + 14 3 1 1 2. + <_> + + <_> + 8 15 2 3 -1. + <_> + 8 16 2 1 3. + <_> + + <_> + 12 15 7 4 -1. + <_> + 12 17 7 2 2. + <_> + + <_> + 4 14 12 3 -1. + <_> + 4 15 12 1 3. + <_> + + <_> + 10 3 3 2 -1. + <_> + 11 3 1 2 3. + <_> + + <_> + 4 12 2 2 -1. + <_> + 4 13 2 1 2. + <_> + + <_> + 10 11 4 6 -1. + <_> + 10 14 4 3 2. + <_> + + <_> + 7 13 2 2 -1. + <_> + 7 13 1 1 2. + <_> + 8 14 1 1 2. + <_> + + <_> + 4 11 14 4 -1. + <_> + 11 11 7 2 2. + <_> + 4 13 7 2 2. + <_> + + <_> + 1 18 18 2 -1. + <_> + 7 18 6 2 3. + <_> + + <_> + 11 18 2 2 -1. + <_> + 12 18 1 1 2. + <_> + 11 19 1 1 2. + <_> + + <_> + 7 18 2 2 -1. + <_> + 7 18 1 1 2. + <_> + 8 19 1 1 2. + <_> + + <_> + 12 18 8 2 -1. + <_> + 12 19 8 1 2. + <_> + + <_> + 7 14 6 2 -1. + <_> + 7 15 6 1 2. + <_> + + <_> + 8 12 4 8 -1. + <_> + 10 12 2 4 2. + <_> + 8 16 2 4 2. + <_> + + <_> + 4 9 3 3 -1. + <_> + 4 10 3 1 3. + <_> + + <_> + 7 10 6 2 -1. + <_> + 9 10 2 2 3. + <_> + + <_> + 5 0 4 15 -1. + <_> + 7 0 2 15 2. + <_> + + <_> + 8 6 12 14 -1. + <_> + 12 6 4 14 3. + <_> + + <_> + 5 16 3 3 -1. + <_> + 5 17 3 1 3. + <_> + + <_> + 8 1 12 19 -1. + <_> + 12 1 4 19 3. + <_> + + <_> + 3 0 3 2 -1. + <_> + 3 1 3 1 2. + <_> + + <_> + 10 12 4 5 -1. + <_> + 10 12 2 5 2. + <_> + + <_> + 6 12 4 5 -1. + <_> + 8 12 2 5 2. + <_> + + <_> + 11 11 2 2 -1. + <_> + 12 11 1 1 2. + <_> + 11 12 1 1 2. + <_> + + <_> + 0 2 3 6 -1. + <_> + 0 4 3 2 3. + <_> + + <_> + 11 11 2 2 -1. + <_> + 12 11 1 1 2. + <_> + 11 12 1 1 2. + <_> + + <_> + 7 6 4 10 -1. + <_> + 7 11 4 5 2. + <_> + + <_> + 11 11 2 2 -1. + <_> + 12 11 1 1 2. + <_> + 11 12 1 1 2. + <_> + + <_> + 2 13 5 2 -1. + <_> + 2 14 5 1 2. + <_> + + <_> + 11 11 2 2 -1. + <_> + 12 11 1 1 2. + <_> + 11 12 1 1 2. + <_> + + <_> + 7 11 2 2 -1. + <_> + 7 11 1 1 2. + <_> + 8 12 1 1 2. + <_> + + <_> + 14 13 3 3 -1. + <_> + 14 14 3 1 3. + <_> + + <_> + 3 13 3 3 -1. + <_> + 3 14 3 1 3. + <_> + + <_> + 9 14 2 3 -1. + <_> + 9 15 2 1 3. + <_> + + <_> + 8 7 3 3 -1. + <_> + 8 8 3 1 3. + <_> + + <_> + 13 5 3 3 -1. + <_> + 13 6 3 1 3. + <_> + + <_> + 0 9 5 3 -1. + <_> + 0 10 5 1 3. + <_> + + <_> + 13 5 3 3 -1. + <_> + 13 6 3 1 3. + <_> + + <_> + 9 12 2 8 -1. + <_> + 9 12 1 4 2. + <_> + 10 16 1 4 2. + <_> + + <_> + 11 7 2 2 -1. + <_> + 12 7 1 1 2. + <_> + 11 8 1 1 2. + <_> + + <_> + 0 16 6 4 -1. + <_> + 3 16 3 4 2. + <_> + + <_> + 10 6 2 3 -1. + <_> + 10 7 2 1 3. + <_> + + <_> + 9 5 2 6 -1. + <_> + 9 7 2 2 3. + <_> + + <_> + 12 15 8 4 -1. + <_> + 12 15 4 4 2. + <_> + + <_> + 0 14 8 6 -1. + <_> + 4 14 4 6 2. + <_> + + <_> + 9 0 3 2 -1. + <_> + 10 0 1 2 3. + <_> + + <_> + 4 15 4 2 -1. + <_> + 6 15 2 2 2. + <_> + + <_> + 12 7 3 13 -1. + <_> + 13 7 1 13 3. + <_> + + <_> + 5 7 3 13 -1. + <_> + 6 7 1 13 3. + <_> + + <_> + 9 6 3 9 -1. + <_> + 9 9 3 3 3. + <_> + + <_> + 4 4 7 12 -1. + <_> + 4 10 7 6 2. + <_> + + <_> + 12 12 2 2 -1. + <_> + 13 12 1 1 2. + <_> + 12 13 1 1 2. + <_> + + <_> + 6 12 2 2 -1. + <_> + 6 12 1 1 2. + <_> + 7 13 1 1 2. + <_> + + <_> + 8 9 4 2 -1. + <_> + 10 9 2 1 2. + <_> + 8 10 2 1 2. + <_> + + <_> + 3 6 2 2 -1. + <_> + 3 6 1 1 2. + <_> + 4 7 1 1 2. + <_> + + <_> + 16 6 3 2 -1. + <_> + 16 7 3 1 2. + <_> + + <_> + 0 7 19 4 -1. + <_> + 0 9 19 2 2. + <_> + + <_> + 10 2 10 1 -1. + <_> + 10 2 5 1 2. + <_> + + <_> + 9 4 2 12 -1. + <_> + 9 10 2 6 2. + <_> + + <_> + 12 18 4 1 -1. + <_> + 12 18 2 1 2. + <_> + + <_> + 1 7 6 4 -1. + <_> + 1 7 3 2 2. + <_> + 4 9 3 2 2. + <_> + + <_> + 12 0 6 13 -1. + <_> + 14 0 2 13 3. + <_> + + <_> + 2 0 6 13 -1. + <_> + 4 0 2 13 3. + <_> + + <_> + 10 5 8 8 -1. + <_> + 10 9 8 4 2. + <_> + + <_> + 8 3 2 5 -1. + <_> + 9 3 1 5 2. + <_> + + <_> + 8 4 9 1 -1. + <_> + 11 4 3 1 3. + <_> + + <_> + 3 4 9 1 -1. + <_> + 6 4 3 1 3. + <_> + + <_> + 1 0 18 10 -1. + <_> + 7 0 6 10 3. + <_> + + <_> + 7 17 5 3 -1. + <_> + 7 18 5 1 3. + <_> + + <_> + 7 11 6 1 -1. + <_> + 9 11 2 1 3. + <_> + + <_> + 2 2 3 2 -1. + <_> + 2 3 3 1 2. + <_> + + <_> + 8 12 4 2 -1. + <_> + 8 13 4 1 2. + <_> + + <_> + 6 10 3 6 -1. + <_> + 6 13 3 3 2. + <_> + + <_> + 11 4 2 4 -1. + <_> + 11 4 1 4 2. + <_> + + <_> + 7 4 2 4 -1. + <_> + 8 4 1 4 2. + <_> + + <_> + 9 6 2 4 -1. + <_> + 9 6 1 4 2. + <_> + + <_> + 6 13 8 3 -1. + <_> + 6 14 8 1 3. + <_> + + <_> + 9 15 3 4 -1. + <_> + 10 15 1 4 3. + <_> + + <_> + 9 2 2 17 -1. + <_> + 10 2 1 17 2. + <_> + + <_> + 7 0 6 1 -1. + <_> + 9 0 2 1 3. + <_> + + <_> + 8 15 3 4 -1. + <_> + 9 15 1 4 3. + <_> + + <_> + 7 13 7 3 -1. + <_> + 7 14 7 1 3. + <_> + + <_> + 8 16 3 3 -1. + <_> + 9 16 1 3 3. + <_> + + <_> + 6 2 8 10 -1. + <_> + 6 7 8 5 2. + <_> + + <_> + 2 5 8 8 -1. + <_> + 2 9 8 4 2. + <_> + + <_> + 14 16 2 2 -1. + <_> + 14 17 2 1 2. + <_> + + <_> + 4 16 2 2 -1. + <_> + 4 17 2 1 2. + <_> + + <_> + 10 11 4 6 -1. + <_> + 10 14 4 3 2. + <_> + + <_> + 6 11 4 6 -1. + <_> + 6 14 4 3 2. + <_> + + <_> + 10 14 1 3 -1. + <_> + 10 15 1 1 3. + <_> + + <_> + 8 14 4 3 -1. + <_> + 8 15 4 1 3. + <_> + + <_> + 10 0 4 6 -1. + <_> + 12 0 2 3 2. + <_> + 10 3 2 3 2. + <_> + + <_> + 0 3 20 2 -1. + <_> + 0 4 20 1 2. + <_> + + <_> + 12 0 8 2 -1. + <_> + 16 0 4 1 2. + <_> + 12 1 4 1 2. + <_> + + <_> + 2 12 10 8 -1. + <_> + 2 16 10 4 2. + <_> + + <_> + 17 7 2 10 -1. + <_> + 18 7 1 5 2. + <_> + 17 12 1 5 2. + <_> + + <_> + 1 7 2 10 -1. + <_> + 1 7 1 5 2. + <_> + 2 12 1 5 2. + <_> + + <_> + 15 10 3 6 -1. + <_> + 15 12 3 2 3. + <_> + + <_> + 4 4 6 2 -1. + <_> + 6 4 2 2 3. + <_> + + <_> + 0 5 20 6 -1. + <_> + 0 7 20 2 3. + <_> + + <_> + 0 0 8 2 -1. + <_> + 0 0 4 1 2. + <_> + 4 1 4 1 2. + <_> + + <_> + 1 0 18 4 -1. + <_> + 7 0 6 4 3. + <_> + + <_> + 1 13 6 2 -1. + <_> + 1 14 6 1 2. + <_> + + <_> + 10 8 3 4 -1. + <_> + 11 8 1 4 3. + <_> + + <_> + 6 1 6 1 -1. + <_> + 8 1 2 1 3. + <_> + + <_> + 8 14 4 3 -1. + <_> + 8 15 4 1 3. + <_> + + <_> + 1 6 18 2 -1. + <_> + 10 6 9 2 2. + <_> + + <_> + 15 11 1 2 -1. + <_> + 15 12 1 1 2. + <_> + + <_> + 6 5 1 2 -1. + <_> + 6 6 1 1 2. + <_> + + <_> + 13 4 1 3 -1. + <_> + 13 5 1 1 3. + <_> + + <_> + 2 15 1 2 -1. + <_> + 2 16 1 1 2. + <_> + + <_> + 12 4 4 3 -1. + <_> + 12 5 4 1 3. + <_> + + <_> + 0 0 7 3 -1. + <_> + 0 1 7 1 3. + <_> + + <_> + 9 12 6 2 -1. + <_> + 9 12 3 2 2. + <_> + + <_> + 5 4 2 3 -1. + <_> + 5 5 2 1 3. + <_> + + <_> + 18 4 2 3 -1. + <_> + 18 5 2 1 3. + <_> + + <_> + 3 0 8 6 -1. + <_> + 3 2 8 2 3. + <_> + + <_> + 0 2 20 6 -1. + <_> + 10 2 10 3 2. + <_> + 0 5 10 3 2. + <_> + + <_> + 4 7 2 4 -1. + <_> + 5 7 1 4 2. + <_> + + <_> + 3 10 15 2 -1. + <_> + 8 10 5 2 3. + <_> + + <_> + 3 0 12 11 -1. + <_> + 9 0 6 11 2. + <_> + + <_> + 13 0 2 6 -1. + <_> + 13 0 1 6 2. + <_> + + <_> + 0 19 2 1 -1. + <_> + 1 19 1 1 2. + <_> + + <_> + 16 10 4 10 -1. + <_> + 18 10 2 5 2. + <_> + 16 15 2 5 2. + <_> + + <_> + 4 8 10 3 -1. + <_> + 4 9 10 1 3. + <_> + + <_> + 14 12 3 3 -1. + <_> + 14 13 3 1 3. + <_> + + <_> + 0 10 4 10 -1. + <_> + 0 10 2 5 2. + <_> + 2 15 2 5 2. + <_> + + <_> + 18 3 2 6 -1. + <_> + 18 5 2 2 3. + <_> + + <_> + 6 6 1 3 -1. + <_> + 6 7 1 1 3. + <_> + + <_> + 7 7 7 2 -1. + <_> + 7 8 7 1 2. + <_> + + <_> + 0 3 2 6 -1. + <_> + 0 5 2 2 3. + <_> + + <_> + 11 1 3 1 -1. + <_> + 12 1 1 1 3. + <_> + + <_> + 5 0 2 6 -1. + <_> + 6 0 1 6 2. + <_> + + <_> + 1 1 18 14 -1. + <_> + 7 1 6 14 3. + <_> + + <_> + 4 6 8 3 -1. + <_> + 8 6 4 3 2. + <_> + + <_> + 9 12 6 2 -1. + <_> + 9 12 3 2 2. + <_> + + <_> + 5 12 6 2 -1. + <_> + 8 12 3 2 2. + <_> + + <_> + 10 7 3 5 -1. + <_> + 11 7 1 5 3. + <_> + + <_> + 7 7 3 5 -1. + <_> + 8 7 1 5 3. + <_> + + <_> + 13 0 3 10 -1. + <_> + 14 0 1 10 3. + <_> + + <_> + 4 11 3 2 -1. + <_> + 4 12 3 1 2. + <_> + + <_> + 17 3 3 6 -1. + <_> + 18 3 1 6 3. + <_> + + <_> + 1 8 18 10 -1. + <_> + 1 13 18 5 2. + <_> + + <_> + 13 0 3 10 -1. + <_> + 14 0 1 10 3. + <_> + + <_> + 9 14 2 3 -1. + <_> + 9 15 2 1 3. + <_> + + <_> + 16 3 3 7 -1. + <_> + 17 3 1 7 3. + <_> + + <_> + 4 0 3 10 -1. + <_> + 5 0 1 10 3. + <_> + + <_> + 16 3 3 7 -1. + <_> + 17 3 1 7 3. + <_> + + <_> + 0 9 1 2 -1. + <_> + 0 10 1 1 2. + <_> + + <_> + 18 1 2 10 -1. + <_> + 18 1 1 10 2. + <_> + + <_> + 0 1 2 10 -1. + <_> + 1 1 1 10 2. + <_> + + <_> + 10 16 3 4 -1. + <_> + 11 16 1 4 3. + <_> + + <_> + 2 8 3 3 -1. + <_> + 3 8 1 3 3. + <_> + + <_> + 11 0 2 6 -1. + <_> + 12 0 1 3 2. + <_> + 11 3 1 3 2. + <_> + + <_> + 7 0 2 6 -1. + <_> + 7 0 1 3 2. + <_> + 8 3 1 3 2. + <_> + + <_> + 16 3 3 7 -1. + <_> + 17 3 1 7 3. + <_> + + <_> + 1 3 3 7 -1. + <_> + 2 3 1 7 3. + <_> + + <_> + 14 1 6 16 -1. + <_> + 16 1 2 16 3. + <_> + + <_> + 0 1 6 16 -1. + <_> + 2 1 2 16 3. + <_> + + <_> + 2 0 16 8 -1. + <_> + 10 0 8 4 2. + <_> + 2 4 8 4 2. + <_> + + <_> + 6 8 5 3 -1. + <_> + 6 9 5 1 3. + <_> + + <_> + 9 7 3 3 -1. + <_> + 10 7 1 3 3. + <_> + + <_> + 8 8 4 3 -1. + <_> + 8 9 4 1 3. + <_> + + <_> + 9 6 2 4 -1. + <_> + 9 6 1 4 2. + <_> + + <_> + 0 7 15 1 -1. + <_> + 5 7 5 1 3. + <_> + + <_> + 8 2 7 9 -1. + <_> + 8 5 7 3 3. + <_> + + <_> + 1 7 16 4 -1. + <_> + 1 7 8 2 2. + <_> + 9 9 8 2 2. + <_> + + <_> + 6 12 8 2 -1. + <_> + 6 13 8 1 2. + <_> + + <_> + 8 11 3 3 -1. + <_> + 8 12 3 1 3. + <_> + + <_> + 4 5 14 10 -1. + <_> + 11 5 7 5 2. + <_> + 4 10 7 5 2. + <_> + + <_> + 4 12 3 2 -1. + <_> + 4 13 3 1 2. + <_> + + <_> + 9 11 6 1 -1. + <_> + 11 11 2 1 3. + <_> + + <_> + 4 9 7 6 -1. + <_> + 4 11 7 2 3. + <_> + + <_> + 7 10 6 3 -1. + <_> + 7 11 6 1 3. + <_> + + <_> + 9 11 2 2 -1. + <_> + 9 12 2 1 2. + <_> + + <_> + 0 5 20 6 -1. + <_> + 0 7 20 2 3. + <_> + + <_> + 6 4 6 1 -1. + <_> + 8 4 2 1 3. + <_> + + <_> + 9 11 6 1 -1. + <_> + 11 11 2 1 3. + <_> + + <_> + 5 11 6 1 -1. + <_> + 7 11 2 1 3. + <_> + + <_> + 10 16 3 4 -1. + <_> + 11 16 1 4 3. + <_> + + <_> + 8 7 3 3 -1. + <_> + 9 7 1 3 3. + <_> + + <_> + 2 12 16 8 -1. + <_> + 2 16 16 4 2. + <_> + + <_> + 0 15 15 2 -1. + <_> + 0 16 15 1 2. + <_> + + <_> + 15 4 5 6 -1. + <_> + 15 6 5 2 3. + <_> + + <_> + 9 5 2 4 -1. + <_> + 10 5 1 4 2. + <_> + + <_> + 8 10 9 6 -1. + <_> + 8 12 9 2 3. + <_> + + <_> + 2 19 15 1 -1. + <_> + 7 19 5 1 3. + <_> + + <_> + 10 16 3 4 -1. + <_> + 11 16 1 4 3. + <_> + + <_> + 0 15 20 4 -1. + <_> + 0 17 20 2 2. + <_> + + <_> + 10 16 3 4 -1. + <_> + 11 16 1 4 3. + <_> + + <_> + 7 16 3 4 -1. + <_> + 8 16 1 4 3. + <_> + + <_> + 9 16 3 3 -1. + <_> + 9 17 3 1 3. + <_> + + <_> + 8 11 4 6 -1. + <_> + 8 14 4 3 2. + <_> + + <_> + 9 6 2 12 -1. + <_> + 9 10 2 4 3. + <_> + + <_> + 8 17 4 3 -1. + <_> + 8 18 4 1 3. + <_> + + <_> + 9 18 8 2 -1. + <_> + 13 18 4 1 2. + <_> + 9 19 4 1 2. + <_> + + <_> + 1 18 8 2 -1. + <_> + 1 19 8 1 2. + <_> + + <_> + 13 5 6 15 -1. + <_> + 15 5 2 15 3. + <_> + + <_> + 9 8 2 2 -1. + <_> + 9 9 2 1 2. + <_> + + <_> + 9 5 2 3 -1. + <_> + 9 5 1 3 2. + <_> + + <_> + 1 5 6 15 -1. + <_> + 3 5 2 15 3. + <_> + + <_> + 4 1 14 8 -1. + <_> + 11 1 7 4 2. + <_> + 4 5 7 4 2. + <_> + + <_> + 2 4 4 16 -1. + <_> + 2 4 2 8 2. + <_> + 4 12 2 8 2. + <_> + + <_> + 12 4 3 12 -1. + <_> + 12 10 3 6 2. + <_> + + <_> + 4 5 10 12 -1. + <_> + 4 5 5 6 2. + <_> + 9 11 5 6 2. + <_> + + <_> + 9 14 2 3 -1. + <_> + 9 15 2 1 3. + <_> + + <_> + 5 4 2 3 -1. + <_> + 5 5 2 1 3. + <_> + + <_> + 12 2 4 10 -1. + <_> + 14 2 2 5 2. + <_> + 12 7 2 5 2. + <_> + + <_> + 6 4 7 3 -1. + <_> + 6 5 7 1 3. + <_> + + <_> + 2 0 18 2 -1. + <_> + 11 0 9 1 2. + <_> + 2 1 9 1 2. + <_> + + <_> + 0 0 18 2 -1. + <_> + 0 0 9 1 2. + <_> + 9 1 9 1 2. + <_> + + <_> + 13 13 4 6 -1. + <_> + 15 13 2 3 2. + <_> + 13 16 2 3 2. + <_> + + <_> + 3 13 4 6 -1. + <_> + 3 13 2 3 2. + <_> + 5 16 2 3 2. + <_> + + <_> + 10 12 2 6 -1. + <_> + 10 15 2 3 2. + <_> + + <_> + 5 9 10 10 -1. + <_> + 5 9 5 5 2. + <_> + 10 14 5 5 2. + <_> + + <_> + 11 4 4 2 -1. + <_> + 13 4 2 1 2. + <_> + 11 5 2 1 2. + <_> + + <_> + 7 12 6 8 -1. + <_> + 10 12 3 8 2. + <_> + + <_> + 12 2 4 10 -1. + <_> + 14 2 2 5 2. + <_> + 12 7 2 5 2. + <_> + + <_> + 8 11 2 1 -1. + <_> + 9 11 1 1 2. + <_> + + <_> + 10 5 1 12 -1. + <_> + 10 9 1 4 3. + <_> + + <_> + 0 11 6 9 -1. + <_> + 3 11 3 9 2. + <_> + + <_> + 12 2 4 10 -1. + <_> + 14 2 2 5 2. + <_> + 12 7 2 5 2. + <_> + + <_> + 4 2 4 10 -1. + <_> + 4 2 2 5 2. + <_> + 6 7 2 5 2. + <_> + + <_> + 11 4 4 2 -1. + <_> + 13 4 2 1 2. + <_> + 11 5 2 1 2. + <_> + + <_> + 0 14 6 3 -1. + <_> + 0 15 6 1 3. + <_> + + <_> + 11 4 4 2 -1. + <_> + 13 4 2 1 2. + <_> + 11 5 2 1 2. + <_> + + <_> + 6 1 3 2 -1. + <_> + 7 1 1 2 3. + <_> + + <_> + 11 4 4 2 -1. + <_> + 13 4 2 1 2. + <_> + 11 5 2 1 2. + <_> + + <_> + 5 4 4 2 -1. + <_> + 5 4 2 1 2. + <_> + 7 5 2 1 2. + <_> + + <_> + 13 0 2 12 -1. + <_> + 14 0 1 6 2. + <_> + 13 6 1 6 2. + <_> + + <_> + 6 0 3 10 -1. + <_> + 7 0 1 10 3. + <_> + + <_> + 3 0 17 8 -1. + <_> + 3 4 17 4 2. + <_> + + <_> + 0 4 20 4 -1. + <_> + 0 6 20 2 2. + <_> + + <_> + 0 3 8 2 -1. + <_> + 4 3 4 2 2. + <_> + + <_> + 8 11 4 3 -1. + <_> + 8 12 4 1 3. + <_> + + <_> + 5 7 6 4 -1. + <_> + 5 7 3 2 2. + <_> + 8 9 3 2 2. + <_> + + <_> + 8 3 4 9 -1. + <_> + 8 6 4 3 3. + <_> + + <_> + 8 15 1 4 -1. + <_> + 8 17 1 2 2. + <_> + + <_> + 4 5 12 7 -1. + <_> + 8 5 4 7 3. + <_> + + <_> + 4 2 4 10 -1. + <_> + 4 2 2 5 2. + <_> + 6 7 2 5 2. + <_> + + <_> + 3 0 17 2 -1. + <_> + 3 1 17 1 2. + <_> + + <_> + 2 2 16 15 -1. + <_> + 2 7 16 5 3. + <_> + + <_> + 15 2 5 2 -1. + <_> + 15 3 5 1 2. + <_> + + <_> + 9 3 2 2 -1. + <_> + 10 3 1 2 2. + <_> + + <_> + 4 5 16 15 -1. + <_> + 4 10 16 5 3. + <_> + + <_> + 7 13 5 6 -1. + <_> + 7 16 5 3 2. + <_> + + <_> + 10 7 3 2 -1. + <_> + 11 7 1 2 3. + <_> + + <_> + 8 3 3 1 -1. + <_> + 9 3 1 1 3. + <_> + + <_> + 9 16 3 3 -1. + <_> + 9 17 3 1 3. + <_> + + <_> + 0 2 5 2 -1. + <_> + 0 3 5 1 2. + <_> + + <_> + 12 5 4 3 -1. + <_> + 12 6 4 1 3. + <_> + + <_> + 1 7 12 1 -1. + <_> + 5 7 4 1 3. + <_> + + <_> + 7 5 6 14 -1. + <_> + 7 12 6 7 2. + <_> + + <_> + 0 0 8 10 -1. + <_> + 0 0 4 5 2. + <_> + 4 5 4 5 2. + <_> + + <_> + 9 1 3 2 -1. + <_> + 10 1 1 2 3. + <_> + + <_> + 8 1 3 2 -1. + <_> + 9 1 1 2 3. + <_> + + <_> + 12 4 3 3 -1. + <_> + 12 5 3 1 3. + <_> + + <_> + 7 4 6 16 -1. + <_> + 7 12 6 8 2. + <_> + + <_> + 12 4 3 3 -1. + <_> + 12 5 3 1 3. + <_> + + <_> + 2 3 2 6 -1. + <_> + 2 5 2 2 3. + <_> + + <_> + 14 2 6 9 -1. + <_> + 14 5 6 3 3. + <_> + + <_> + 5 4 3 3 -1. + <_> + 5 5 3 1 3. + <_> + + <_> + 9 17 3 2 -1. + <_> + 10 17 1 2 3. + <_> + + <_> + 5 5 2 3 -1. + <_> + 5 6 2 1 3. + <_> + + <_> + 13 11 3 6 -1. + <_> + 13 13 3 2 3. + <_> + + <_> + 3 14 2 6 -1. + <_> + 3 17 2 3 2. + <_> + + <_> + 14 3 6 2 -1. + <_> + 14 4 6 1 2. + <_> + + <_> + 0 8 16 2 -1. + <_> + 0 9 16 1 2. + <_> + + <_> + 14 3 6 2 -1. + <_> + 14 4 6 1 2. + <_> + + <_> + 0 0 5 6 -1. + <_> + 0 2 5 2 3. + <_> + + <_> + 12 5 4 3 -1. + <_> + 12 6 4 1 3. + <_> + + <_> + 4 11 3 6 -1. + <_> + 4 13 3 2 3. + <_> + + <_> + 12 5 4 3 -1. + <_> + 12 6 4 1 3. + <_> + + <_> + 9 5 1 3 -1. + <_> + 9 6 1 1 3. + <_> + + <_> + 12 5 4 3 -1. + <_> + 12 6 4 1 3. + <_> + + <_> + 6 6 8 12 -1. + <_> + 6 12 8 6 2. + <_> + + <_> + 12 5 4 3 -1. + <_> + 12 6 4 1 3. + <_> + + <_> + 5 12 9 2 -1. + <_> + 8 12 3 2 3. + <_> + + <_> + 12 5 4 3 -1. + <_> + 12 6 4 1 3. + <_> + + <_> + 4 5 4 3 -1. + <_> + 4 6 4 1 3. + <_> + + <_> + 6 6 9 2 -1. + <_> + 9 6 3 2 3. + <_> + + <_> + 4 11 1 3 -1. + <_> + 4 12 1 1 3. + <_> + + <_> + 14 12 6 6 -1. + <_> + 14 12 3 6 2. + <_> + + <_> + 7 0 3 7 -1. + <_> + 8 0 1 7 3. + <_> + + <_> + 9 8 3 3 -1. + <_> + 10 8 1 3 3. + <_> + + <_> + 8 8 3 3 -1. + <_> + 9 8 1 3 3. + <_> + + <_> + 5 10 11 3 -1. + <_> + 5 11 11 1 3. + <_> + + <_> + 5 7 10 1 -1. + <_> + 10 7 5 1 2. + <_> + + <_> + 9 7 3 2 -1. + <_> + 10 7 1 2 3. + <_> + + <_> + 8 7 3 2 -1. + <_> + 9 7 1 2 3. + <_> + + <_> + 11 9 4 2 -1. + <_> + 11 9 2 2 2. + <_> + + <_> + 5 9 4 2 -1. + <_> + 7 9 2 2 2. + <_> + + <_> + 14 10 2 4 -1. + <_> + 14 12 2 2 2. + <_> + + <_> + 7 7 3 2 -1. + <_> + 8 7 1 2 3. + <_> + + <_> + 14 17 6 3 -1. + <_> + 14 18 6 1 3. + <_> + + <_> + 4 5 12 12 -1. + <_> + 4 5 6 6 2. + <_> + 10 11 6 6 2. + <_> + + <_> + 6 9 8 8 -1. + <_> + 10 9 4 4 2. + <_> + 6 13 4 4 2. + <_> + + <_> + 0 4 15 4 -1. + <_> + 5 4 5 4 3. + <_> + + <_> + 13 2 4 1 -1. + <_> + 13 2 2 1 2. + <_> + + <_> + 4 12 2 2 -1. + <_> + 4 13 2 1 2. + <_> + + <_> + 8 13 4 3 -1. + <_> + 8 14 4 1 3. + <_> + + <_> + 9 13 2 3 -1. + <_> + 9 14 2 1 3. + <_> + + <_> + 13 11 2 3 -1. + <_> + 13 12 2 1 3. + <_> + + <_> + 7 12 4 4 -1. + <_> + 7 12 2 2 2. + <_> + 9 14 2 2 2. + <_> + + <_> + 10 11 2 2 -1. + <_> + 11 11 1 1 2. + <_> + 10 12 1 1 2. + <_> + + <_> + 8 17 3 2 -1. + <_> + 9 17 1 2 3. + <_> + + <_> + 10 11 2 2 -1. + <_> + 11 11 1 1 2. + <_> + 10 12 1 1 2. + <_> + + <_> + 0 17 6 3 -1. + <_> + 0 18 6 1 3. + <_> + + <_> + 10 11 2 2 -1. + <_> + 11 11 1 1 2. + <_> + 10 12 1 1 2. + <_> + + <_> + 8 11 2 2 -1. + <_> + 8 11 1 1 2. + <_> + 9 12 1 1 2. + <_> + + <_> + 12 5 8 4 -1. + <_> + 12 5 4 4 2. + <_> + + <_> + 0 5 8 4 -1. + <_> + 4 5 4 4 2. + <_> + + <_> + 13 2 4 1 -1. + <_> + 13 2 2 1 2. + <_> + + <_> + 3 2 4 1 -1. + <_> + 5 2 2 1 2. + <_> + + <_> + 10 0 4 2 -1. + <_> + 12 0 2 1 2. + <_> + 10 1 2 1 2. + <_> + + <_> + 7 12 3 1 -1. + <_> + 8 12 1 1 3. + <_> + + <_> + 8 11 4 8 -1. + <_> + 10 11 2 4 2. + <_> + 8 15 2 4 2. + <_> + + <_> + 9 9 2 2 -1. + <_> + 9 10 2 1 2. + <_> + + <_> + 3 18 15 2 -1. + <_> + 3 19 15 1 2. + <_> + + <_> + 2 6 2 12 -1. + <_> + 2 6 1 6 2. + <_> + 3 12 1 6 2. + <_> + + <_> + 9 8 2 3 -1. + <_> + 9 9 2 1 3. + <_> + + <_> + 7 10 3 2 -1. + <_> + 8 10 1 2 3. + <_> + + <_> + 11 11 3 1 -1. + <_> + 12 11 1 1 3. + <_> + + <_> + 6 11 3 1 -1. + <_> + 7 11 1 1 3. + <_> + + <_> + 9 2 4 2 -1. + <_> + 11 2 2 1 2. + <_> + 9 3 2 1 2. + <_> + + <_> + 4 12 2 3 -1. + <_> + 4 13 2 1 3. + <_> + + <_> + 2 1 18 3 -1. + <_> + 8 1 6 3 3. + <_> + + <_> + 5 1 4 14 -1. + <_> + 7 1 2 14 2. + <_> + + <_> + 8 16 12 3 -1. + <_> + 8 16 6 3 2. + <_> + + <_> + 1 17 18 3 -1. + <_> + 7 17 6 3 3. + <_> + + <_> + 9 14 2 6 -1. + <_> + 9 17 2 3 2. + <_> + + <_> + 9 12 1 8 -1. + <_> + 9 16 1 4 2. + <_> + + <_> + 9 14 2 3 -1. + <_> + 9 15 2 1 3. + <_> + + <_> + 9 6 2 12 -1. + <_> + 9 10 2 4 3. + <_> + + <_> + 12 9 3 3 -1. + <_> + 12 10 3 1 3. + <_> + + <_> + 0 1 4 8 -1. + <_> + 2 1 2 8 2. + <_> + + <_> + 9 1 6 2 -1. + <_> + 12 1 3 1 2. + <_> + 9 2 3 1 2. + <_> + + <_> + 1 3 12 14 -1. + <_> + 1 10 12 7 2. + <_> + + <_> + 8 12 4 2 -1. + <_> + 10 12 2 1 2. + <_> + 8 13 2 1 2. + <_> + + <_> + 1 9 10 2 -1. + <_> + 1 9 5 1 2. + <_> + 6 10 5 1 2. + <_> + + <_> + 8 15 4 3 -1. + <_> + 8 16 4 1 3. + <_> + + <_> + 6 8 8 3 -1. + <_> + 6 9 8 1 3. + <_> + + <_> + 9 15 5 3 -1. + <_> + 9 16 5 1 3. + <_> + + <_> + 8 7 4 3 -1. + <_> + 8 8 4 1 3. + <_> + + <_> + 7 7 6 2 -1. + <_> + 7 8 6 1 2. + <_> + + <_> + 5 7 8 2 -1. + <_> + 5 7 4 1 2. + <_> + 9 8 4 1 2. + <_> + + <_> + 12 9 3 3 -1. + <_> + 12 10 3 1 3. + <_> + + <_> + 4 7 4 2 -1. + <_> + 4 8 4 1 2. + <_> + + <_> + 14 2 6 9 -1. + <_> + 14 5 6 3 3. + <_> + + <_> + 4 9 3 3 -1. + <_> + 5 9 1 3 3. + <_> + + <_> + 12 9 3 3 -1. + <_> + 12 10 3 1 3. + <_> + + <_> + 0 2 6 9 -1. + <_> + 0 5 6 3 3. + <_> + + <_> + 17 3 3 6 -1. + <_> + 18 3 1 6 3. + <_> + + <_> + 0 3 3 6 -1. + <_> + 1 3 1 6 3. + <_> + + <_> + 17 14 1 2 -1. + <_> + 17 15 1 1 2. + <_> + + <_> + 4 9 4 3 -1. + <_> + 6 9 2 3 2. + <_> + + <_> + 12 9 3 3 -1. + <_> + 12 10 3 1 3. + <_> + + <_> + 5 9 3 3 -1. + <_> + 5 10 3 1 3. + <_> + + <_> + 9 5 6 8 -1. + <_> + 12 5 3 4 2. + <_> + 9 9 3 4 2. + <_> + + <_> + 5 5 6 8 -1. + <_> + 5 5 3 4 2. + <_> + 8 9 3 4 2. + <_> + + <_> + 16 1 4 6 -1. + <_> + 16 4 4 3 2. + <_> + + <_> + 1 0 6 20 -1. + <_> + 3 0 2 20 3. + <_> + + <_> + 12 11 3 2 -1. + <_> + 13 11 1 2 3. + <_> + + <_> + 5 11 3 2 -1. + <_> + 6 11 1 2 3. + <_> + + <_> + 9 4 6 1 -1. + <_> + 11 4 2 1 3. + <_> + + <_> + 0 0 8 3 -1. + <_> + 4 0 4 3 2. + <_> + + <_> + 15 0 2 5 -1. + <_> + 15 0 1 5 2. + <_> + + <_> + 4 1 3 2 -1. + <_> + 5 1 1 2 3. + <_> + + <_> + 7 0 6 15 -1. + <_> + 9 0 2 15 3. + <_> + + <_> + 6 11 3 1 -1. + <_> + 7 11 1 1 3. + <_> + + <_> + 12 0 3 4 -1. + <_> + 13 0 1 4 3. + <_> + + <_> + 5 4 6 1 -1. + <_> + 7 4 2 1 3. + <_> + + <_> + 12 7 3 2 -1. + <_> + 12 8 3 1 2. + <_> + + <_> + 0 1 4 6 -1. + <_> + 0 4 4 3 2. + <_> + + <_> + 12 7 3 2 -1. + <_> + 12 8 3 1 2. + <_> + + <_> + 2 16 3 3 -1. + <_> + 2 17 3 1 3. + <_> + + <_> + 13 8 6 10 -1. + <_> + 16 8 3 5 2. + <_> + 13 13 3 5 2. + <_> + + <_> + 0 9 5 2 -1. + <_> + 0 10 5 1 2. + <_> + + <_> + 12 11 2 2 -1. + <_> + 13 11 1 1 2. + <_> + 12 12 1 1 2. + <_> + + <_> + 3 15 3 3 -1. + <_> + 3 16 3 1 3. + <_> + + <_> + 12 7 3 2 -1. + <_> + 12 8 3 1 2. + <_> + + <_> + 5 7 3 2 -1. + <_> + 5 8 3 1 2. + <_> + + <_> + 9 5 9 9 -1. + <_> + 9 8 9 3 3. + <_> + + <_> + 5 0 3 7 -1. + <_> + 6 0 1 7 3. + <_> + + <_> + 5 2 12 5 -1. + <_> + 9 2 4 5 3. + <_> + + <_> + 6 11 2 2 -1. + <_> + 6 11 1 1 2. + <_> + 7 12 1 1 2. + <_> + + <_> + 15 15 3 2 -1. + <_> + 15 16 3 1 2. + <_> + + <_> + 2 15 3 2 -1. + <_> + 2 16 3 1 2. + <_> + + <_> + 14 12 6 8 -1. + <_> + 17 12 3 4 2. + <_> + 14 16 3 4 2. + <_> + + <_> + 2 8 15 6 -1. + <_> + 7 8 5 6 3. + <_> + + <_> + 2 2 18 17 -1. + <_> + 8 2 6 17 3. + <_> + + <_> + 5 1 4 1 -1. + <_> + 7 1 2 1 2. + <_> + + <_> + 5 2 12 5 -1. + <_> + 9 2 4 5 3. + <_> + + <_> + 3 2 12 5 -1. + <_> + 7 2 4 5 3. + <_> + + <_> + 4 9 12 4 -1. + <_> + 10 9 6 2 2. + <_> + 4 11 6 2 2. + <_> + + <_> + 5 15 6 2 -1. + <_> + 5 15 3 1 2. + <_> + 8 16 3 1 2. + <_> + + <_> + 10 14 2 3 -1. + <_> + 10 15 2 1 3. + <_> + + <_> + 0 13 20 2 -1. + <_> + 0 13 10 1 2. + <_> + 10 14 10 1 2. + <_> + + <_> + 4 9 12 8 -1. + <_> + 10 9 6 4 2. + <_> + 4 13 6 4 2. + <_> + + <_> + 8 13 3 6 -1. + <_> + 8 16 3 3 2. + <_> + + <_> + 10 12 2 2 -1. + <_> + 10 13 2 1 2. + <_> + + <_> + 9 12 2 2 -1. + <_> + 9 12 1 1 2. + <_> + 10 13 1 1 2. + <_> + + <_> + 4 11 14 4 -1. + <_> + 11 11 7 2 2. + <_> + 4 13 7 2 2. + <_> + + <_> + 8 5 4 2 -1. + <_> + 8 6 4 1 2. + <_> + + <_> + 10 10 6 3 -1. + <_> + 12 10 2 3 3. + <_> + + <_> + 2 14 1 2 -1. + <_> + 2 15 1 1 2. + <_> + + <_> + 13 8 6 12 -1. + <_> + 16 8 3 6 2. + <_> + 13 14 3 6 2. + <_> + + <_> + 1 8 6 12 -1. + <_> + 1 8 3 6 2. + <_> + 4 14 3 6 2. + <_> + + <_> + 10 0 6 10 -1. + <_> + 12 0 2 10 3. + <_> + + <_> + 5 11 8 4 -1. + <_> + 5 11 4 2 2. + <_> + 9 13 4 2 2. + <_> + + <_> + 10 16 8 4 -1. + <_> + 14 16 4 2 2. + <_> + 10 18 4 2 2. + <_> + + <_> + 7 7 6 6 -1. + <_> + 9 7 2 6 3. + <_> + + <_> + 10 2 4 10 -1. + <_> + 10 2 2 10 2. + <_> + + <_> + 6 1 4 9 -1. + <_> + 8 1 2 9 2. + <_> + + <_> + 12 19 2 1 -1. + <_> + 12 19 1 1 2. + <_> + + <_> + 1 2 4 9 -1. + <_> + 3 2 2 9 2. + <_> + + <_> + 7 5 6 4 -1. + <_> + 9 5 2 4 3. + <_> + + <_> + 9 4 2 4 -1. + <_> + 9 6 2 2 2. + <_> + + <_> + 14 5 2 8 -1. + <_> + 14 9 2 4 2. + <_> + + <_> + 7 6 5 12 -1. + <_> + 7 12 5 6 2. + <_> + + <_> + 14 6 2 6 -1. + <_> + 14 9 2 3 2. + <_> + + <_> + 4 6 2 6 -1. + <_> + 4 9 2 3 2. + <_> + + <_> + 8 15 10 4 -1. + <_> + 13 15 5 2 2. + <_> + 8 17 5 2 2. + <_> + + <_> + 6 18 2 2 -1. + <_> + 7 18 1 2 2. + <_> + + <_> + 11 3 6 2 -1. + <_> + 11 4 6 1 2. + <_> + + <_> + 2 0 16 6 -1. + <_> + 2 2 16 2 3. + <_> + + <_> + 11 3 6 2 -1. + <_> + 11 4 6 1 2. + <_> + + <_> + 4 11 10 3 -1. + <_> + 4 12 10 1 3. + <_> + + <_> + 11 3 6 2 -1. + <_> + 11 4 6 1 2. + <_> + + <_> + 3 3 6 2 -1. + <_> + 3 4 6 1 2. + <_> + + <_> + 16 0 4 7 -1. + <_> + 16 0 2 7 2. + <_> + + <_> + 0 14 9 6 -1. + <_> + 0 16 9 2 3. + <_> + + <_> + 9 16 3 3 -1. + <_> + 9 17 3 1 3. + <_> + + <_> + 4 6 6 2 -1. + <_> + 6 6 2 2 3. + <_> + + <_> + 15 11 1 3 -1. + <_> + 15 12 1 1 3. + <_> + + <_> + 5 5 2 3 -1. + <_> + 5 6 2 1 3. + <_> + + <_> + 10 9 2 2 -1. + <_> + 10 10 2 1 2. + <_> + + <_> + 3 1 4 3 -1. + <_> + 5 1 2 3 2. + <_> + + <_> + 16 0 4 7 -1. + <_> + 16 0 2 7 2. + <_> + + <_> + 0 0 20 1 -1. + <_> + 10 0 10 1 2. + <_> + + <_> + 15 11 1 3 -1. + <_> + 15 12 1 1 3. + <_> + + <_> + 0 4 3 4 -1. + <_> + 1 4 1 4 3. + <_> + + <_> + 16 3 3 6 -1. + <_> + 16 5 3 2 3. + <_> + + <_> + 1 3 3 6 -1. + <_> + 1 5 3 2 3. + <_> + + <_> + 6 2 12 6 -1. + <_> + 12 2 6 3 2. + <_> + 6 5 6 3 2. + <_> + + <_> + 8 10 4 3 -1. + <_> + 8 11 4 1 3. + <_> + + <_> + 4 2 14 6 -1. + <_> + 11 2 7 3 2. + <_> + 4 5 7 3 2. + <_> + + <_> + 9 11 2 3 -1. + <_> + 9 12 2 1 3. + <_> + + <_> + 15 13 2 3 -1. + <_> + 15 14 2 1 3. + <_> + + <_> + 8 12 4 3 -1. + <_> + 8 13 4 1 3. + <_> + + <_> + 15 11 1 3 -1. + <_> + 15 12 1 1 3. + <_> + + <_> + 7 13 5 2 -1. + <_> + 7 14 5 1 2. + <_> + + <_> + 7 12 6 3 -1. + <_> + 7 13 6 1 3. + <_> + + <_> + 5 11 4 4 -1. + <_> + 5 13 4 2 2. + <_> + + <_> + 11 4 3 3 -1. + <_> + 12 4 1 3 3. + <_> + + <_> + 6 4 3 3 -1. + <_> + 7 4 1 3 3. + <_> + + <_> + 16 5 3 6 -1. + <_> + 17 5 1 6 3. + <_> + + <_> + 3 6 12 7 -1. + <_> + 7 6 4 7 3. + <_> + + <_> + 16 5 3 6 -1. + <_> + 17 5 1 6 3. + <_> + + <_> + 3 13 2 3 -1. + <_> + 3 14 2 1 3. + <_> + + <_> + 16 5 3 6 -1. + <_> + 17 5 1 6 3. + <_> + + <_> + 1 5 3 6 -1. + <_> + 2 5 1 6 3. + <_> + + <_> + 1 9 18 1 -1. + <_> + 7 9 6 1 3. + <_> + + <_> + 0 9 8 7 -1. + <_> + 4 9 4 7 2. + <_> + + <_> + 12 11 8 2 -1. + <_> + 12 12 8 1 2. + <_> + + <_> + 0 11 8 2 -1. + <_> + 0 12 8 1 2. + <_> + + <_> + 9 13 2 3 -1. + <_> + 9 14 2 1 3. + <_> + + <_> + 4 10 12 4 -1. + <_> + 4 10 6 2 2. + <_> + 10 12 6 2 2. + <_> + + <_> + 9 3 3 7 -1. + <_> + 10 3 1 7 3. + <_> + + <_> + 7 2 3 5 -1. + <_> + 8 2 1 5 3. + <_> + + <_> + 9 12 4 6 -1. + <_> + 11 12 2 3 2. + <_> + 9 15 2 3 2. + <_> + + <_> + 8 7 3 6 -1. + <_> + 9 7 1 6 3. + <_> + + <_> + 15 4 4 2 -1. + <_> + 15 5 4 1 2. + <_> + + <_> + 8 7 3 3 -1. + <_> + 9 7 1 3 3. + <_> + + <_> + 14 2 6 4 -1. + <_> + 14 4 6 2 2. + <_> + + <_> + 7 16 6 1 -1. + <_> + 9 16 2 1 3. + <_> + + <_> + 15 13 2 3 -1. + <_> + 15 14 2 1 3. + <_> + + <_> + 8 7 3 10 -1. + <_> + 9 7 1 10 3. + <_> + + <_> + 11 10 2 6 -1. + <_> + 11 12 2 2 3. + <_> + + <_> + 6 10 4 1 -1. + <_> + 8 10 2 1 2. + <_> + + <_> + 10 9 2 2 -1. + <_> + 10 10 2 1 2. + <_> + + <_> + 8 9 2 2 -1. + <_> + 8 10 2 1 2. + <_> + + <_> + 12 7 2 2 -1. + <_> + 13 7 1 1 2. + <_> + 12 8 1 1 2. + <_> + + <_> + 5 7 2 2 -1. + <_> + 5 7 1 1 2. + <_> + 6 8 1 1 2. + <_> + + <_> + 13 0 3 14 -1. + <_> + 14 0 1 14 3. + <_> + + <_> + 4 0 3 14 -1. + <_> + 5 0 1 14 3. + <_> + + <_> + 13 4 3 14 -1. + <_> + 14 4 1 14 3. + <_> + + <_> + 9 14 2 3 -1. + <_> + 9 15 2 1 3. + <_> + + <_> + 8 14 4 3 -1. + <_> + 8 15 4 1 3. + <_> + + <_> + 4 2 3 16 -1. + <_> + 5 2 1 16 3. + <_> + + <_> + 7 2 8 10 -1. + <_> + 7 7 8 5 2. + <_> + + <_> + 6 14 7 3 -1. + <_> + 6 15 7 1 3. + <_> + + <_> + 9 2 10 12 -1. + <_> + 14 2 5 6 2. + <_> + 9 8 5 6 2. + <_> + + <_> + 6 7 8 2 -1. + <_> + 6 8 8 1 2. + <_> + + <_> + 8 13 4 6 -1. + <_> + 8 16 4 3 2. + <_> + + <_> + 6 6 1 3 -1. + <_> + 6 7 1 1 3. + <_> + + <_> + 16 2 4 6 -1. + <_> + 16 4 4 2 3. + <_> + + <_> + 6 6 4 2 -1. + <_> + 6 6 2 1 2. + <_> + 8 7 2 1 2. + <_> + + <_> + 16 2 4 6 -1. + <_> + 16 4 4 2 3. + <_> + + <_> + 0 2 4 6 -1. + <_> + 0 4 4 2 3. + <_> + + <_> + 9 6 2 6 -1. + <_> + 9 6 1 6 2. + <_> + + <_> + 3 4 6 10 -1. + <_> + 3 9 6 5 2. + <_> + + <_> + 9 5 2 6 -1. + <_> + 9 5 1 6 2. + <_> + + <_> + 3 13 2 3 -1. + <_> + 3 14 2 1 3. + <_> + + <_> + 13 13 3 2 -1. + <_> + 13 14 3 1 2. + <_> + + <_> + 2 16 10 4 -1. + <_> + 2 16 5 2 2. + <_> + 7 18 5 2 2. + <_> + + <_> + 5 6 10 6 -1. + <_> + 10 6 5 3 2. + <_> + 5 9 5 3 2. + <_> + + <_> + 7 14 1 3 -1. + <_> + 7 15 1 1 3. + <_> + + <_> + 14 16 6 3 -1. + <_> + 14 17 6 1 3. + <_> + + <_> + 5 4 3 3 -1. + <_> + 5 5 3 1 3. + <_> + + <_> + 7 4 10 3 -1. + <_> + 7 5 10 1 3. + <_> + + <_> + 0 4 5 4 -1. + <_> + 0 6 5 2 2. + <_> + + <_> + 13 11 3 9 -1. + <_> + 13 14 3 3 3. + <_> + + <_> + 4 11 3 9 -1. + <_> + 4 14 3 3 3. + <_> + + <_> + 9 7 2 1 -1. + <_> + 9 7 1 1 2. + <_> + + <_> + 5 0 6 17 -1. + <_> + 7 0 2 17 3. + <_> + + <_> + 10 3 6 3 -1. + <_> + 10 3 3 3 2. + <_> + + <_> + 2 2 15 4 -1. + <_> + 7 2 5 4 3. + <_> + + <_> + 8 2 8 2 -1. + <_> + 12 2 4 1 2. + <_> + 8 3 4 1 2. + <_> + + <_> + 8 1 3 6 -1. + <_> + 8 3 3 2 3. + <_> + + <_> + 9 17 2 2 -1. + <_> + 9 18 2 1 2. + <_> + + <_> + 0 0 2 14 -1. + <_> + 1 0 1 14 2. + <_> + + <_> + 12 0 7 3 -1. + <_> + 12 1 7 1 3. + <_> + + <_> + 1 14 1 2 -1. + <_> + 1 15 1 1 2. + <_> + + <_> + 14 12 2 8 -1. + <_> + 15 12 1 4 2. + <_> + 14 16 1 4 2. + <_> + + <_> + 1 0 7 3 -1. + <_> + 1 1 7 1 3. + <_> + + <_> + 14 12 2 8 -1. + <_> + 15 12 1 4 2. + <_> + 14 16 1 4 2. + <_> + + <_> + 6 0 8 12 -1. + <_> + 6 0 4 6 2. + <_> + 10 6 4 6 2. + <_> + + <_> + 6 1 8 9 -1. + <_> + 6 4 8 3 3. + <_> + + <_> + 5 2 2 2 -1. + <_> + 5 3 2 1 2. + <_> + + <_> + 13 14 6 6 -1. + <_> + 16 14 3 3 2. + <_> + 13 17 3 3 2. + <_> + + <_> + 0 17 20 2 -1. + <_> + 0 17 10 1 2. + <_> + 10 18 10 1 2. + <_> + + <_> + 10 3 2 6 -1. + <_> + 11 3 1 3 2. + <_> + 10 6 1 3 2. + <_> + + <_> + 5 12 6 2 -1. + <_> + 8 12 3 2 2. + <_> + + <_> + 10 7 6 13 -1. + <_> + 10 7 3 13 2. + <_> + + <_> + 5 15 10 5 -1. + <_> + 10 15 5 5 2. + <_> + + <_> + 10 4 4 10 -1. + <_> + 10 4 2 10 2. + <_> + + <_> + 5 7 2 1 -1. + <_> + 6 7 1 1 2. + <_> + + <_> + 10 3 6 7 -1. + <_> + 10 3 3 7 2. + <_> + + <_> + 4 3 6 7 -1. + <_> + 7 3 3 7 2. + <_> + + <_> + 1 7 18 5 -1. + <_> + 7 7 6 5 3. + <_> + + <_> + 3 17 4 3 -1. + <_> + 5 17 2 3 2. + <_> + + <_> + 8 14 12 6 -1. + <_> + 14 14 6 3 2. + <_> + 8 17 6 3 2. + <_> + + <_> + 0 13 20 4 -1. + <_> + 0 13 10 2 2. + <_> + 10 15 10 2 2. + <_> + + <_> + 4 5 14 2 -1. + <_> + 11 5 7 1 2. + <_> + 4 6 7 1 2. + <_> + + <_> + 1 2 10 12 -1. + <_> + 1 2 5 6 2. + <_> + 6 8 5 6 2. + <_> + + <_> + 6 1 14 3 -1. + <_> + 6 2 14 1 3. + <_> + + <_> + 8 16 2 3 -1. + <_> + 8 17 2 1 3. + <_> + + <_> + 9 17 3 2 -1. + <_> + 10 17 1 2 3. + <_> + + <_> + 5 15 4 2 -1. + <_> + 5 15 2 1 2. + <_> + 7 16 2 1 2. + <_> + + <_> + 10 15 1 3 -1. + <_> + 10 16 1 1 3. + <_> + + <_> + 8 16 4 4 -1. + <_> + 8 16 2 2 2. + <_> + 10 18 2 2 2. + <_> + + <_> + 6 11 8 6 -1. + <_> + 6 14 8 3 2. + <_> + + <_> + 2 13 5 2 -1. + <_> + 2 14 5 1 2. + <_> + + <_> + 13 14 6 6 -1. + <_> + 16 14 3 3 2. + <_> + 13 17 3 3 2. + <_> + + <_> + 1 9 18 4 -1. + <_> + 7 9 6 4 3. + <_> + + <_> + 13 14 6 6 -1. + <_> + 16 14 3 3 2. + <_> + 13 17 3 3 2. + <_> + + <_> + 0 2 1 6 -1. + <_> + 0 4 1 2 3. + <_> + + <_> + 5 0 15 20 -1. + <_> + 5 10 15 10 2. + <_> + + <_> + 1 14 6 6 -1. + <_> + 1 14 3 3 2. + <_> + 4 17 3 3 2. + <_> + + <_> + 8 14 4 6 -1. + <_> + 10 14 2 3 2. + <_> + 8 17 2 3 2. + <_> + + <_> + 7 11 2 1 -1. + <_> + 8 11 1 1 2. + <_> + + <_> + 9 17 3 2 -1. + <_> + 10 17 1 2 3. + <_> + + <_> + 8 17 3 2 -1. + <_> + 9 17 1 2 3. + <_> + + <_> + 12 14 4 6 -1. + <_> + 14 14 2 3 2. + <_> + 12 17 2 3 2. + <_> + + <_> + 4 14 4 6 -1. + <_> + 4 14 2 3 2. + <_> + 6 17 2 3 2. + <_> + + <_> + 13 14 2 6 -1. + <_> + 14 14 1 3 2. + <_> + 13 17 1 3 2. + <_> + + <_> + 5 14 2 6 -1. + <_> + 5 14 1 3 2. + <_> + 6 17 1 3 2. + <_> + + <_> + 7 0 6 12 -1. + <_> + 7 4 6 4 3. + <_> + + <_> + 0 7 12 2 -1. + <_> + 4 7 4 2 3. + <_> + + <_> + 10 3 3 13 -1. + <_> + 11 3 1 13 3. + <_> + + <_> + 7 3 3 13 -1. + <_> + 8 3 1 13 3. + <_> + + <_> + 10 8 6 3 -1. + <_> + 10 9 6 1 3. + <_> + + <_> + 3 11 3 2 -1. + <_> + 4 11 1 2 3. + <_> + + <_> + 13 12 6 8 -1. + <_> + 16 12 3 4 2. + <_> + 13 16 3 4 2. + <_> + + <_> + 7 6 6 5 -1. + <_> + 9 6 2 5 3. + <_> + + <_> + 17 11 2 7 -1. + <_> + 17 11 1 7 2. + <_> + + <_> + 3 13 8 2 -1. + <_> + 7 13 4 2 2. + <_> + + <_> + 6 9 8 3 -1. + <_> + 6 10 8 1 3. + <_> + + <_> + 4 3 4 3 -1. + <_> + 4 4 4 1 3. + <_> + + <_> + 11 3 4 3 -1. + <_> + 11 4 4 1 3. + <_> + + <_> + 1 4 17 12 -1. + <_> + 1 8 17 4 3. + <_> + + <_> + 11 3 4 3 -1. + <_> + 11 4 4 1 3. + <_> + + <_> + 4 8 6 3 -1. + <_> + 4 9 6 1 3. + <_> + + <_> + 12 3 5 3 -1. + <_> + 12 4 5 1 3. + <_> + + <_> + 1 11 2 7 -1. + <_> + 2 11 1 7 2. + <_> + + <_> + 15 12 2 8 -1. + <_> + 16 12 1 4 2. + <_> + 15 16 1 4 2. + <_> + + <_> + 4 8 11 3 -1. + <_> + 4 9 11 1 3. + <_> + + <_> + 9 13 6 2 -1. + <_> + 12 13 3 1 2. + <_> + 9 14 3 1 2. + <_> + + <_> + 6 13 4 3 -1. + <_> + 6 14 4 1 3. + <_> + + <_> + 9 12 3 3 -1. + <_> + 10 12 1 3 3. + <_> + + <_> + 5 3 3 3 -1. + <_> + 5 4 3 1 3. + <_> + + <_> + 9 4 2 3 -1. + <_> + 9 5 2 1 3. + <_> + + <_> + 0 2 16 3 -1. + <_> + 0 3 16 1 3. + <_> + + <_> + 15 12 2 8 -1. + <_> + 16 12 1 4 2. + <_> + 15 16 1 4 2. + <_> + + <_> + 3 12 2 8 -1. + <_> + 3 12 1 4 2. + <_> + 4 16 1 4 2. + <_> + + <_> + 14 13 3 6 -1. + <_> + 14 15 3 2 3. + <_> + + <_> + 3 13 3 6 -1. + <_> + 3 15 3 2 3. + <_> + + <_> + 6 5 10 2 -1. + <_> + 11 5 5 1 2. + <_> + 6 6 5 1 2. + <_> + + <_> + 2 14 14 6 -1. + <_> + 2 17 14 3 2. + <_> + + <_> + 10 14 1 3 -1. + <_> + 10 15 1 1 3. + <_> + + <_> + 4 16 2 2 -1. + <_> + 4 16 1 1 2. + <_> + 5 17 1 1 2. + <_> + + <_> + 10 6 2 3 -1. + <_> + 10 7 2 1 3. + <_> + + <_> + 0 17 20 2 -1. + <_> + 0 17 10 1 2. + <_> + 10 18 10 1 2. + <_> + + <_> + 13 6 1 3 -1. + <_> + 13 7 1 1 3. + <_> + + <_> + 8 13 3 2 -1. + <_> + 9 13 1 2 3. + <_> + + <_> + 12 2 3 3 -1. + <_> + 13 2 1 3 3. + <_> + + <_> + 3 18 2 2 -1. + <_> + 3 18 1 1 2. + <_> + 4 19 1 1 2. + <_> + + <_> + 9 16 3 4 -1. + <_> + 10 16 1 4 3. + <_> + + <_> + 6 6 1 3 -1. + <_> + 6 7 1 1 3. + <_> + + <_> + 13 1 5 2 -1. + <_> + 13 2 5 1 2. + <_> + + <_> + 7 14 6 2 -1. + <_> + 7 14 3 1 2. + <_> + 10 15 3 1 2. + <_> + + <_> + 11 3 3 4 -1. + <_> + 12 3 1 4 3. + <_> + + <_> + 1 13 12 6 -1. + <_> + 5 13 4 6 3. + <_> + + <_> + 14 11 5 2 -1. + <_> + 14 12 5 1 2. + <_> + + <_> + 2 15 14 4 -1. + <_> + 2 15 7 2 2. + <_> + 9 17 7 2 2. + <_> + + <_> + 3 7 14 2 -1. + <_> + 10 7 7 1 2. + <_> + 3 8 7 1 2. + <_> + + <_> + 1 11 4 2 -1. + <_> + 1 12 4 1 2. + <_> + + <_> + 14 0 6 14 -1. + <_> + 16 0 2 14 3. + <_> + + <_> + 4 11 1 3 -1. + <_> + 4 12 1 1 3. + <_> + + <_> + 14 0 6 14 -1. + <_> + 16 0 2 14 3. + <_> + + <_> + 1 10 3 7 -1. + <_> + 2 10 1 7 3. + <_> + + <_> + 8 12 9 2 -1. + <_> + 8 13 9 1 2. + <_> + + <_> + 0 6 20 1 -1. + <_> + 10 6 10 1 2. + <_> + + <_> + 8 4 4 4 -1. + <_> + 8 4 2 4 2. + <_> + + <_> + 0 0 2 2 -1. + <_> + 0 1 2 1 2. + <_> + + <_> + 5 3 10 9 -1. + <_> + 5 6 10 3 3. + <_> + + <_> + 15 2 4 10 -1. + <_> + 15 2 2 10 2. + <_> + + <_> + 8 2 2 7 -1. + <_> + 9 2 1 7 2. + <_> + + <_> + 7 4 12 1 -1. + <_> + 11 4 4 1 3. + <_> + + <_> + 3 4 9 1 -1. + <_> + 6 4 3 1 3. + <_> + + <_> + 15 10 1 4 -1. + <_> + 15 12 1 2 2. + <_> + + <_> + 4 10 6 4 -1. + <_> + 7 10 3 4 2. + <_> + + <_> + 15 9 1 6 -1. + <_> + 15 12 1 3 2. + <_> + + <_> + 7 17 6 3 -1. + <_> + 7 18 6 1 3. + <_> + + <_> + 14 3 2 16 -1. + <_> + 15 3 1 8 2. + <_> + 14 11 1 8 2. + <_> + + <_> + 4 9 1 6 -1. + <_> + 4 12 1 3 2. + <_> + + <_> + 12 1 5 2 -1. + <_> + 12 2 5 1 2. + <_> + + <_> + 6 18 4 2 -1. + <_> + 6 18 2 1 2. + <_> + 8 19 2 1 2. + <_> + + <_> + 2 4 16 10 -1. + <_> + 10 4 8 5 2. + <_> + 2 9 8 5 2. + <_> + + <_> + 6 5 1 10 -1. + <_> + 6 10 1 5 2. + <_> + + <_> + 4 8 15 2 -1. + <_> + 9 8 5 2 3. + <_> + + <_> + 1 8 15 2 -1. + <_> + 6 8 5 2 3. + <_> + + <_> + 9 5 3 6 -1. + <_> + 9 7 3 2 3. + <_> + + <_> + 5 7 8 2 -1. + <_> + 9 7 4 2 2. + <_> + + <_> + 9 11 2 3 -1. + <_> + 9 12 2 1 3. + <_> + + <_> + 1 0 16 3 -1. + <_> + 1 1 16 1 3. + <_> + + <_> + 11 2 7 2 -1. + <_> + 11 3 7 1 2. + <_> + + <_> + 5 1 10 18 -1. + <_> + 5 7 10 6 3. + <_> + + <_> + 17 4 3 2 -1. + <_> + 18 4 1 2 3. + <_> + + <_> + 8 13 1 3 -1. + <_> + 8 14 1 1 3. + <_> + + <_> + 3 14 14 6 -1. + <_> + 3 16 14 2 3. + <_> + + <_> + 0 2 3 4 -1. + <_> + 1 2 1 4 3. + <_> + + <_> + 12 1 5 2 -1. + <_> + 12 2 5 1 2. + <_> + + <_> + 3 1 5 2 -1. + <_> + 3 2 5 1 2. + <_> + + <_> + 10 13 2 3 -1. + <_> + 10 14 2 1 3. + <_> + + <_> + 8 13 2 3 -1. + <_> + 8 14 2 1 3. + <_> + + <_> + 14 12 2 3 -1. + <_> + 14 13 2 1 3. + <_> + + <_> + 7 2 2 3 -1. + <_> + 7 3 2 1 3. + <_> + + <_> + 5 6 10 4 -1. + <_> + 10 6 5 2 2. + <_> + 5 8 5 2 2. + <_> + + <_> + 9 13 1 6 -1. + <_> + 9 16 1 3 2. + <_> + + <_> + 10 12 2 2 -1. + <_> + 11 12 1 1 2. + <_> + 10 13 1 1 2. + <_> + + <_> + 4 12 2 3 -1. + <_> + 4 13 2 1 3. + <_> + + <_> + 14 4 6 6 -1. + <_> + 14 6 6 2 3. + <_> + + <_> + 8 17 2 3 -1. + <_> + 8 18 2 1 3. + <_> + + <_> + 16 4 4 6 -1. + <_> + 16 6 4 2 3. + <_> + + <_> + 0 4 4 6 -1. + <_> + 0 6 4 2 3. + <_> + + <_> + 14 6 2 3 -1. + <_> + 14 6 1 3 2. + <_> + + <_> + 4 9 8 1 -1. + <_> + 8 9 4 1 2. + <_> + + <_> + 8 12 4 3 -1. + <_> + 8 13 4 1 3. + <_> + + <_> + 5 12 10 6 -1. + <_> + 5 14 10 2 3. + <_> + + <_> + 11 12 1 2 -1. + <_> + 11 13 1 1 2. + <_> + + <_> + 8 15 4 2 -1. + <_> + 8 16 4 1 2. + <_> + + <_> + 6 9 8 8 -1. + <_> + 10 9 4 4 2. + <_> + 6 13 4 4 2. + <_> + + <_> + 7 12 4 6 -1. + <_> + 7 12 2 3 2. + <_> + 9 15 2 3 2. + <_> + + <_> + 10 11 3 1 -1. + <_> + 11 11 1 1 3. + <_> + + <_> + 9 7 2 10 -1. + <_> + 9 7 1 5 2. + <_> + 10 12 1 5 2. + <_> + + <_> + 8 0 6 6 -1. + <_> + 10 0 2 6 3. + <_> + + <_> + 3 11 2 6 -1. + <_> + 3 13 2 2 3. + <_> + + <_> + 16 12 1 2 -1. + <_> + 16 13 1 1 2. + <_> + + <_> + 1 14 6 6 -1. + <_> + 1 14 3 3 2. + <_> + 4 17 3 3 2. + <_> + + <_> + 13 1 3 6 -1. + <_> + 14 1 1 6 3. + <_> + + <_> + 8 8 2 2 -1. + <_> + 8 9 2 1 2. + <_> + + <_> + 9 9 3 3 -1. + <_> + 10 9 1 3 3. + <_> + + <_> + 8 7 3 3 -1. + <_> + 8 8 3 1 3. + <_> + + <_> + 14 0 2 3 -1. + <_> + 14 0 1 3 2. + <_> + + <_> + 1 0 18 9 -1. + <_> + 7 0 6 9 3. + <_> + + <_> + 11 5 4 15 -1. + <_> + 11 5 2 15 2. + <_> + + <_> + 5 5 4 15 -1. + <_> + 7 5 2 15 2. + <_> + + <_> + 14 0 2 3 -1. + <_> + 14 0 1 3 2. + <_> + + <_> + 4 0 2 3 -1. + <_> + 5 0 1 3 2. + <_> + + <_> + 11 12 2 2 -1. + <_> + 12 12 1 1 2. + <_> + 11 13 1 1 2. + <_> + + <_> + 7 12 2 2 -1. + <_> + 7 12 1 1 2. + <_> + 8 13 1 1 2. + <_> + + <_> + 12 0 3 4 -1. + <_> + 13 0 1 4 3. + <_> + + <_> + 4 11 3 3 -1. + <_> + 4 12 3 1 3. + <_> + + <_> + 12 7 4 2 -1. + <_> + 12 8 4 1 2. + <_> + + <_> + 8 10 3 2 -1. + <_> + 9 10 1 2 3. + <_> + + <_> + 9 9 3 2 -1. + <_> + 10 9 1 2 3. + <_> + + <_> + 8 9 3 2 -1. + <_> + 9 9 1 2 3. + <_> + + <_> + 12 0 3 4 -1. + <_> + 13 0 1 4 3. + <_> + + <_> + 5 0 3 4 -1. + <_> + 6 0 1 4 3. + <_> + + <_> + 4 14 12 4 -1. + <_> + 10 14 6 2 2. + <_> + 4 16 6 2 2. + <_> + + <_> + 8 13 2 3 -1. + <_> + 8 14 2 1 3. + <_> + + <_> + 10 10 3 8 -1. + <_> + 10 14 3 4 2. + <_> + + <_> + 8 10 4 8 -1. + <_> + 8 10 2 4 2. + <_> + 10 14 2 4 2. + <_> + + <_> + 10 8 3 1 -1. + <_> + 11 8 1 1 3. + <_> + + <_> + 9 12 1 6 -1. + <_> + 9 15 1 3 2. + <_> + + <_> + 10 8 3 1 -1. + <_> + 11 8 1 1 3. + <_> + + <_> + 7 8 3 1 -1. + <_> + 8 8 1 1 3. + <_> + + <_> + 5 2 15 14 -1. + <_> + 5 9 15 7 2. + <_> + + <_> + 2 1 2 10 -1. + <_> + 2 1 1 5 2. + <_> + 3 6 1 5 2. + <_> + + <_> + 14 14 2 3 -1. + <_> + 14 15 2 1 3. + <_> + + <_> + 2 7 3 3 -1. + <_> + 3 7 1 3 3. + <_> + + <_> + 17 4 3 3 -1. + <_> + 17 5 3 1 3. + <_> + + <_> + 0 4 3 3 -1. + <_> + 0 5 3 1 3. + <_> + + <_> + 13 5 6 2 -1. + <_> + 16 5 3 1 2. + <_> + 13 6 3 1 2. + <_> + + <_> + 4 19 12 1 -1. + <_> + 8 19 4 1 3. + <_> + + <_> + 12 12 2 4 -1. + <_> + 12 14 2 2 2. + <_> + + <_> + 3 15 1 3 -1. + <_> + 3 16 1 1 3. + <_> + + <_> + 11 16 6 4 -1. + <_> + 11 16 3 4 2. + <_> + + <_> + 2 10 3 10 -1. + <_> + 3 10 1 10 3. + <_> + + <_> + 12 8 2 4 -1. + <_> + 12 8 1 4 2. + <_> + + <_> + 6 8 2 4 -1. + <_> + 7 8 1 4 2. + <_> + + <_> + 10 14 2 3 -1. + <_> + 10 14 1 3 2. + <_> + + <_> + 5 1 10 3 -1. + <_> + 10 1 5 3 2. + <_> + + <_> + 10 7 3 2 -1. + <_> + 11 7 1 2 3. + <_> + + <_> + 5 6 9 2 -1. + <_> + 8 6 3 2 3. + <_> + + <_> + 9 8 2 2 -1. + <_> + 9 9 2 1 2. + <_> + + <_> + 2 11 16 6 -1. + <_> + 2 11 8 3 2. + <_> + 10 14 8 3 2. + <_> + + <_> + 12 7 2 2 -1. + <_> + 13 7 1 1 2. + <_> + 12 8 1 1 2. + <_> + + <_> + 9 5 2 3 -1. + <_> + 9 6 2 1 3. + <_> + + <_> + 9 7 3 2 -1. + <_> + 10 7 1 2 3. + <_> + + <_> + 5 1 8 12 -1. + <_> + 5 7 8 6 2. + <_> + + <_> + 13 5 2 2 -1. + <_> + 13 6 2 1 2. + <_> + + <_> + 5 5 2 2 -1. + <_> + 5 6 2 1 2. + <_> + + <_> + 12 4 3 3 -1. + <_> + 12 5 3 1 3. + <_> + + <_> + 4 14 2 3 -1. + <_> + 4 15 2 1 3. + <_> + + <_> + 12 4 3 3 -1. + <_> + 12 5 3 1 3. + <_> + + <_> + 5 4 3 3 -1. + <_> + 5 5 3 1 3. + <_> + + <_> + 9 14 2 6 -1. + <_> + 10 14 1 3 2. + <_> + 9 17 1 3 2. + <_> + + <_> + 8 14 3 2 -1. + <_> + 9 14 1 2 3. + <_> + + <_> + 9 5 6 6 -1. + <_> + 11 5 2 6 3. + <_> + + <_> + 5 5 6 6 -1. + <_> + 7 5 2 6 3. + <_> + + <_> + 13 13 1 2 -1. + <_> + 13 14 1 1 2. + <_> + + <_> + 0 2 10 2 -1. + <_> + 0 3 10 1 2. + <_> + + <_> + 13 13 1 2 -1. + <_> + 13 14 1 1 2. + <_> + + <_> + 5 7 2 2 -1. + <_> + 5 7 1 1 2. + <_> + 6 8 1 1 2. + <_> + + <_> + 13 5 2 7 -1. + <_> + 13 5 1 7 2. + <_> + + <_> + 6 13 1 2 -1. + <_> + 6 14 1 1 2. + <_> + + <_> + 11 0 3 7 -1. + <_> + 12 0 1 7 3. + <_> + + <_> + 0 3 2 16 -1. + <_> + 0 3 1 8 2. + <_> + 1 11 1 8 2. + <_> + + <_> + 11 0 3 7 -1. + <_> + 12 0 1 7 3. + <_> + + <_> + 6 0 3 7 -1. + <_> + 7 0 1 7 3. + <_> + + <_> + 11 16 8 4 -1. + <_> + 11 16 4 4 2. + <_> + + <_> + 1 16 8 4 -1. + <_> + 5 16 4 4 2. + <_> + + <_> + 13 5 2 7 -1. + <_> + 13 5 1 7 2. + <_> + + <_> + 5 5 2 7 -1. + <_> + 6 5 1 7 2. + <_> + + <_> + 18 6 2 14 -1. + <_> + 18 13 2 7 2. + <_> + + <_> + 6 10 3 4 -1. + <_> + 6 12 3 2 2. + <_> + + <_> + 14 7 1 2 -1. + <_> + 14 8 1 1 2. + <_> + + <_> + 0 1 18 6 -1. + <_> + 0 1 9 3 2. + <_> + 9 4 9 3 2. + <_> + + <_> + 14 7 1 2 -1. + <_> + 14 8 1 1 2. + <_> + + <_> + 0 6 2 14 -1. + <_> + 0 13 2 7 2. + <_> + + <_> + 17 0 3 12 -1. + <_> + 18 0 1 12 3. + <_> + + <_> + 0 6 18 3 -1. + <_> + 0 7 18 1 3. + <_> + + <_> + 6 0 14 16 -1. + <_> + 6 8 14 8 2. + <_> + + <_> + 0 0 3 12 -1. + <_> + 1 0 1 12 3. + <_> + + <_> + 13 0 3 7 -1. + <_> + 14 0 1 7 3. + <_> + + <_> + 5 7 1 2 -1. + <_> + 5 8 1 1 2. + <_> + + <_> + 14 4 6 6 -1. + <_> + 14 6 6 2 3. + <_> + + <_> + 5 7 7 2 -1. + <_> + 5 8 7 1 2. + <_> + + <_> + 8 6 6 9 -1. + <_> + 8 9 6 3 3. + <_> + + <_> + 5 4 6 1 -1. + <_> + 7 4 2 1 3. + <_> + + <_> + 13 0 6 4 -1. + <_> + 16 0 3 2 2. + <_> + 13 2 3 2 2. + <_> + + <_> + 1 2 18 12 -1. + <_> + 1 6 18 4 3. + <_> + + <_> + 3 2 17 12 -1. + <_> + 3 6 17 4 3. + <_> + + <_> + 5 14 7 3 -1. + <_> + 5 15 7 1 3. + <_> + + <_> + 10 14 1 3 -1. + <_> + 10 15 1 1 3. + <_> + + <_> + 3 14 3 3 -1. + <_> + 3 15 3 1 3. + <_> + + <_> + 14 4 6 6 -1. + <_> + 14 6 6 2 3. + <_> + + <_> + 0 4 6 6 -1. + <_> + 0 6 6 2 3. + <_> + + <_> + 12 5 4 3 -1. + <_> + 12 6 4 1 3. + <_> + + <_> + 4 5 4 3 -1. + <_> + 4 6 4 1 3. + <_> + + <_> + 18 0 2 6 -1. + <_> + 18 2 2 2 3. + <_> + + <_> + 8 1 4 9 -1. + <_> + 10 1 2 9 2. + <_> + + <_> + 6 6 8 2 -1. + <_> + 6 6 4 2 2. + <_> + + <_> + 6 5 4 2 -1. + <_> + 6 5 2 1 2. + <_> + 8 6 2 1 2. + <_> + + <_> + 10 5 2 3 -1. + <_> + 10 6 2 1 3. + <_> + + <_> + 9 5 1 3 -1. + <_> + 9 6 1 1 3. + <_> + + <_> + 9 10 2 2 -1. + <_> + 9 11 2 1 2. + <_> + + <_> + 0 8 4 3 -1. + <_> + 0 9 4 1 3. + <_> + + <_> + 6 0 8 6 -1. + <_> + 6 3 8 3 2. + <_> + + <_> + 1 0 6 4 -1. + <_> + 1 0 3 2 2. + <_> + 4 2 3 2 2. + <_> + + <_> + 13 0 3 7 -1. + <_> + 14 0 1 7 3. + <_> + + <_> + 9 16 2 2 -1. + <_> + 9 17 2 1 2. + <_> + + <_> + 11 4 6 10 -1. + <_> + 11 9 6 5 2. + <_> + + <_> + 0 10 19 2 -1. + <_> + 0 11 19 1 2. + <_> + + <_> + 9 5 8 9 -1. + <_> + 9 8 8 3 3. + <_> + + <_> + 4 0 3 7 -1. + <_> + 5 0 1 7 3. + <_> + + <_> + 8 6 4 12 -1. + <_> + 10 6 2 6 2. + <_> + 8 12 2 6 2. + <_> + + <_> + 0 2 6 4 -1. + <_> + 0 4 6 2 2. + <_> + + <_> + 8 15 4 3 -1. + <_> + 8 16 4 1 3. + <_> + + <_> + 8 0 3 7 -1. + <_> + 9 0 1 7 3. + <_> + + <_> + 9 5 3 4 -1. + <_> + 10 5 1 4 3. + <_> + + <_> + 8 5 3 4 -1. + <_> + 9 5 1 4 3. + <_> + + <_> + 7 6 6 1 -1. + <_> + 9 6 2 1 3. + <_> + + <_> + 7 14 4 4 -1. + <_> + 7 14 2 2 2. + <_> + 9 16 2 2 2. + <_> + + <_> + 13 14 4 6 -1. + <_> + 15 14 2 3 2. + <_> + 13 17 2 3 2. + <_> + + <_> + 7 8 1 8 -1. + <_> + 7 12 1 4 2. + <_> + + <_> + 16 0 2 8 -1. + <_> + 17 0 1 4 2. + <_> + 16 4 1 4 2. + <_> + + <_> + 2 0 2 8 -1. + <_> + 2 0 1 4 2. + <_> + 3 4 1 4 2. + <_> + + <_> + 6 1 14 3 -1. + <_> + 6 2 14 1 3. + <_> + + <_> + 7 9 3 10 -1. + <_> + 7 14 3 5 2. + <_> + + <_> + 9 14 2 2 -1. + <_> + 9 15 2 1 2. + <_> + + <_> + 7 7 6 8 -1. + <_> + 7 11 6 4 2. + <_> + + <_> + 9 7 3 6 -1. + <_> + 9 10 3 3 2. + <_> + + <_> + 7 13 3 3 -1. + <_> + 7 14 3 1 3. + <_> + + <_> + 9 9 2 2 -1. + <_> + 9 10 2 1 2. + <_> + + <_> + 0 1 18 2 -1. + <_> + 6 1 6 2 3. + <_> + + <_> + 7 1 6 14 -1. + <_> + 7 8 6 7 2. + <_> + + <_> + 1 9 18 1 -1. + <_> + 7 9 6 1 3. + <_> + + <_> + 9 7 2 2 -1. + <_> + 9 7 1 2 2. + <_> + + <_> + 9 3 2 9 -1. + <_> + 10 3 1 9 2. + <_> + + <_> + 18 14 2 3 -1. + <_> + 18 15 2 1 3. + <_> + + <_> + 7 11 3 1 -1. + <_> + 8 11 1 1 3. + <_> + + <_> + 10 8 3 4 -1. + <_> + 11 8 1 4 3. + <_> + + <_> + 7 14 3 6 -1. + <_> + 8 14 1 6 3. + <_> + + <_> + 10 8 3 4 -1. + <_> + 11 8 1 4 3. + <_> + + <_> + 7 8 3 4 -1. + <_> + 8 8 1 4 3. + <_> + + <_> + 7 9 6 9 -1. + <_> + 7 12 6 3 3. + <_> + + <_> + 0 14 2 3 -1. + <_> + 0 15 2 1 3. + <_> + + <_> + 11 12 1 2 -1. + <_> + 11 13 1 1 2. + <_> + + <_> + 4 3 8 3 -1. + <_> + 8 3 4 3 2. + <_> + + <_> + 0 4 20 6 -1. + <_> + 0 4 10 6 2. + <_> + + <_> + 9 14 1 3 -1. + <_> + 9 15 1 1 3. + <_> + + <_> + 8 14 4 3 -1. + <_> + 8 15 4 1 3. + <_> + + <_> + 0 15 14 4 -1. + <_> + 0 17 14 2 2. + <_> + + <_> + 1 14 18 6 -1. + <_> + 1 17 18 3 2. + <_> + + <_> + 0 0 10 6 -1. + <_> + 0 0 5 3 2. + <_> + 5 3 5 3 2. + diff --git a/samples/winrt_universal/VideoCaptureXAML/video_capture_xaml/video_capture_xaml.Windows/MainPage.xaml b/samples/winrt_universal/VideoCaptureXAML/video_capture_xaml/video_capture_xaml.Windows/MainPage.xaml new file mode 100644 index 0000000000..a38ad29284 --- /dev/null +++ b/samples/winrt_universal/VideoCaptureXAML/video_capture_xaml/video_capture_xaml.Windows/MainPage.xaml @@ -0,0 +1,25 @@ + + + + + + + + + + \ No newline at end of file diff --git a/samples/winrt_universal/VideoCaptureXAML/video_capture_xaml/video_capture_xaml.Windows/MainPage.xaml.cpp b/samples/winrt_universal/VideoCaptureXAML/video_capture_xaml/video_capture_xaml.Windows/MainPage.xaml.cpp new file mode 100644 index 0000000000..59d76c4478 --- /dev/null +++ b/samples/winrt_universal/VideoCaptureXAML/video_capture_xaml/video_capture_xaml.Windows/MainPage.xaml.cpp @@ -0,0 +1,61 @@ +// +// MainPage.xaml.cpp +// Implementation of the MainPage class. +// + +#include "pch.h" +#include "MainPage.xaml.h" + +#include +#include +#include +#include +#include + +using namespace video_capture_xaml; + +using namespace Platform; +using namespace Windows::Foundation; +using namespace Windows::Foundation::Collections; +using namespace Windows::UI::Xaml; +using namespace Windows::UI::Xaml::Controls; +using namespace Windows::UI::Xaml::Controls::Primitives; +using namespace Windows::UI::Xaml::Data; +using namespace Windows::UI::Xaml::Input; +using namespace Windows::UI::Xaml::Media; +using namespace Windows::UI::Xaml::Navigation; + +// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238 + +using namespace ::Windows::Foundation; +using namespace Windows::UI::Xaml::Media::Imaging; + +namespace video_capture_xaml +{ + // nb. implemented in main.cpp + void cvMain(); + + MainPage::MainPage() + { + InitializeComponent(); + + Window::Current->VisibilityChanged += ref new Windows::UI::Xaml::WindowVisibilityChangedEventHandler(this, &video_capture_xaml::MainPage::OnVisibilityChanged); + + // attach XAML elements + cv::winrt_setFrameContainer(cvImage); + + // start (1) frame-grabbing loop and (2) message loop + // + // 1. Function passed as an argument must implement common OCV reading frames + // pattern (see cv::VideoCapture documentation) AND call cv::winrt_imgshow(). + // 2. Message processing loop required to overcome WinRT container and type + // conversion restrictions. OCV provides default implementation + cv::winrt_startMessageLoop(cvMain); + } +} + +void video_capture_xaml::MainPage::OnVisibilityChanged(Platform::Object ^sender, + Windows::UI::Core::VisibilityChangedEventArgs ^e) +{ + cv::winrt_onVisibilityChanged(e->Visible); +} diff --git a/samples/winrt_universal/VideoCaptureXAML/video_capture_xaml/video_capture_xaml.Windows/MainPage.xaml.h b/samples/winrt_universal/VideoCaptureXAML/video_capture_xaml/video_capture_xaml.Windows/MainPage.xaml.h new file mode 100644 index 0000000000..8d90e6b231 --- /dev/null +++ b/samples/winrt_universal/VideoCaptureXAML/video_capture_xaml/video_capture_xaml.Windows/MainPage.xaml.h @@ -0,0 +1,24 @@ +// +// MainPage.xaml.h +// Declaration of the MainPage class. +// + +#pragma once + +#include "MainPage.g.h" + +namespace video_capture_xaml +{ + /// + /// An empty page that can be used on its own or navigated to within a Frame. + /// + public ref class MainPage sealed + { + public: + MainPage(); + + private: + void OnVisibilityChanged(Platform::Object ^sender, Windows::UI::Core::VisibilityChangedEventArgs ^e); + + }; +} diff --git a/samples/winrt_universal/VideoCaptureXAML/video_capture_xaml/video_capture_xaml.Windows/Package.appxmanifest b/samples/winrt_universal/VideoCaptureXAML/video_capture_xaml/video_capture_xaml.Windows/Package.appxmanifest new file mode 100644 index 0000000000..484b38655c --- /dev/null +++ b/samples/winrt_universal/VideoCaptureXAML/video_capture_xaml/video_capture_xaml.Windows/Package.appxmanifest @@ -0,0 +1,27 @@ + + + + + video_capture_xaml.Windows + daver_000 + Assets\StoreLogo.png + + + 6.3.0 + 6.3.0 + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/samples/winrt_universal/VideoCaptureXAML/video_capture_xaml/video_capture_xaml.Windows/readme.txt b/samples/winrt_universal/VideoCaptureXAML/video_capture_xaml/video_capture_xaml.Windows/readme.txt new file mode 100644 index 0000000000..3a95854d71 --- /dev/null +++ b/samples/winrt_universal/VideoCaptureXAML/video_capture_xaml/video_capture_xaml.Windows/readme.txt @@ -0,0 +1,30 @@ +notes for OpenCV WinRT implementation: + +cvMain() in main.cpp + implements the image processing and OpenCV app control + it is running on a background thread, started by XAML + see file main.cpp + in the Application project + +class VideoCapture_WinRT: + implements the IVideoCapture interface from OpenCV + video is initialized and frames are grabbed on the UI thread + see files cap_winrt.hpp/cpp + +class HighguiBridge, a singleton + implements the OpenCV Highgui functions for XAML (limited at this time), + and also bridges to the UI thread functions for XAML and video operations. + see files cap_winrt_highgui.hpp/cpp + +class Video, a singleton + encapsulates the Media Foundation interface needed for video initialization and grabbing. + called through Highgui and XAML, only on the UI thread + see files cap_winrt_video.hpp/cpp + +threading: + requests from the OpenCV bg thread to the Video/XAML UI thread + are made through HighguiBridge::requestForUIthreadAsync(), which uses + the "progress reporter" method provided by the WinRT class + IAsyncActionWithProgress. Also the bg thread is started by create_async(). + see file MainPage.xaml.cpp + in the Application project diff --git a/samples/winrt_universal/VideoCaptureXAML/video_capture_xaml/video_capture_xaml.Windows/video_capture_xaml.Windows.vcxproj b/samples/winrt_universal/VideoCaptureXAML/video_capture_xaml/video_capture_xaml.Windows/video_capture_xaml.Windows.vcxproj new file mode 100644 index 0000000000..042713afeb --- /dev/null +++ b/samples/winrt_universal/VideoCaptureXAML/video_capture_xaml/video_capture_xaml.Windows/video_capture_xaml.Windows.vcxproj @@ -0,0 +1,200 @@ + + + + + Debug + ARM + + + Debug + Win32 + + + Debug + x64 + + + Release + ARM + + + Release + Win32 + + + Release + x64 + + + + {32fdab94-f87e-4f0a-89a4-9ec10a3b1d3d} + video_capture_xaml + en-US + 12.0 + true + Windows Store + 8.1 + video_capture_xaml.Windows + + + + Application + true + v120 + + + Application + true + v120 + + + Application + true + v120 + + + Application + false + true + v120 + + + Application + false + true + v120 + + + Application + false + true + v120 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + video_capture_xaml.Windows_TemporaryKey.pfx + + + true + $(OPENCV_WINRT_INSTALL_DIR)WS\8.1\x86\x86\vc12\lib;$(VC_LibraryPath_x86);$(WindowsSDK_LibraryPath_x86); + + + false + $(VC_IncludePath);$(WindowsSDK_IncludePath); + + + + /bigobj %(AdditionalOptions) + 4453;28204 + %(AdditionalIncludeDirectories) + + + true + + + %(AdditionalDependencies) + + + + + /bigobj %(AdditionalOptions) + 4453;28204 + + + + + /bigobj %(AdditionalOptions) + 4453;28204 + %(AdditionalIncludeDirectories);$(MSBuildThisFileDirectory) + NotUsing + + + false + + + kernel32.lib;%(AdditionalDependencies) + + + + + /bigobj %(AdditionalOptions) + 4453;28204 + + + + + /bigobj %(AdditionalOptions) + 4453;28204 + + + + + /bigobj %(AdditionalOptions) + 4453;28204 + + + + + MainPage.xaml + + + + + Designer + + + + + Designer + + + + + + + + + + + + MainPage.xaml + + + + + + + + + + + + \ No newline at end of file diff --git a/samples/winrt_universal/VideoCaptureXAML/video_capture_xaml/video_capture_xaml.Windows/video_capture_xaml.Windows.vcxproj.filters b/samples/winrt_universal/VideoCaptureXAML/video_capture_xaml/video_capture_xaml.Windows/video_capture_xaml.Windows.vcxproj.filters new file mode 100644 index 0000000000..a15ba63cd9 --- /dev/null +++ b/samples/winrt_universal/VideoCaptureXAML/video_capture_xaml/video_capture_xaml.Windows/video_capture_xaml.Windows.vcxproj.filters @@ -0,0 +1,46 @@ + + + + + {ef9b8c45-f2b7-4eec-a8b4-a9b340be770b} + bmp;fbx;gif;jpg;jpeg;tga;tiff;tif;png + + + + + + + + + + + + + + + + + + + + Assets + + + Assets + + + Assets + + + Assets + + + + + + + + Assets + + + \ No newline at end of file diff --git a/samples/winrt_universal/VideoCaptureXAML/video_capture_xaml/video_capture_xaml.Windows/video_capture_xaml.Windows_TemporaryKey.pfx b/samples/winrt_universal/VideoCaptureXAML/video_capture_xaml/video_capture_xaml.Windows/video_capture_xaml.Windows_TemporaryKey.pfx new file mode 100644 index 0000000000000000000000000000000000000000..2f87643fc622ee2f71654edf6e93aee9116f379b GIT binary patch literal 2536 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 literal 0 HcmV?d00001 diff --git a/samples/winrt_universal/VideoCaptureXAML/video_capture_xaml/video_capture_xaml.WindowsPhone/Assets/Logo.scale-240.png b/samples/winrt_universal/VideoCaptureXAML/video_capture_xaml/video_capture_xaml.WindowsPhone/Assets/Logo.scale-240.png new file mode 100644 index 0000000000000000000000000000000000000000..76921ca99715449322ce4575b714262598766ebb GIT binary patch literal 2516 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 aeE1)epL)B$w-u`Z0000SK>Qt}(H-q=T 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 gV5~u<%>&ppbSls(D;2H23k0DxD+50(=0|+ + + + + + + + + + \ No newline at end of file diff --git a/samples/winrt_universal/VideoCaptureXAML/video_capture_xaml/video_capture_xaml.WindowsPhone/MainPage.xaml.cpp b/samples/winrt_universal/VideoCaptureXAML/video_capture_xaml/video_capture_xaml.WindowsPhone/MainPage.xaml.cpp new file mode 100644 index 0000000000..7abc535f9b --- /dev/null +++ b/samples/winrt_universal/VideoCaptureXAML/video_capture_xaml/video_capture_xaml.WindowsPhone/MainPage.xaml.cpp @@ -0,0 +1,79 @@ +// +// MainPage.xaml.cpp +// Implementation of the MainPage class. +// + +#include "pch.h" +#include "MainPage.xaml.h" + +#include +#include +#include +#include +#include + +using namespace video_capture_xaml; + +using namespace Platform; +using namespace Windows::Foundation; +using namespace Windows::Foundation::Collections; +using namespace Windows::UI::Xaml; +using namespace Windows::UI::Xaml::Controls; +using namespace Windows::UI::Xaml::Controls::Primitives; +using namespace Windows::UI::Xaml::Data; +using namespace Windows::UI::Xaml::Input; +using namespace Windows::UI::Xaml::Media; +using namespace Windows::UI::Xaml::Navigation; + +// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238 + +using namespace ::Windows::Foundation; +using namespace Windows::UI::Xaml::Media::Imaging; + +namespace video_capture_xaml { + + // nb. implemented in main.cpp + void cvMain(); + + MainPage::MainPage() + { + InitializeComponent(); + + Window::Current->VisibilityChanged += ref new Windows::UI::Xaml::WindowVisibilityChangedEventHandler(this, &video_capture_xaml::MainPage::OnVisibilityChanged); + + // attach XAML elements + cv::winrt_setFrameContainer(cvImage); + + // start (1) frame-grabbing loop and (2) message loop + // + // 1. Function passed as an argument must implement common OCV reading frames + // pattern (see cv::VideoCapture documentation) AND call cv::winrt_imgshow(). + // 2. Message processing loop required to overcome WinRT container and type + // conversion restrictions. OCV provides default implementation + cv::winrt_startMessageLoop(cvMain); + } + + void video_capture_xaml::MainPage::OnVisibilityChanged(Platform::Object ^sender, + Windows::UI::Core::VisibilityChangedEventArgs ^e) + { + cv::winrt_onVisibilityChanged(e->Visible); + } + + /// + /// Invoked when this page is about to be displayed in a Frame. + /// + /// Event data that describes how this page was reached. The Parameter + /// property is typically used to configure the page. + void MainPage::OnNavigatedTo(NavigationEventArgs^ e) + { + (void)e; // Unused parameter + + // TODO: Prepare page for display here. + + // TODO: If your application contains multiple pages, ensure that you are + // handling the hardware Back button by registering for the + // Windows::Phone::UI::Input::HardwareButtons.BackPressed event. + // If you are using the NavigationHelper provided by some templates, + // this event is handled for you. + } +} \ No newline at end of file diff --git a/samples/winrt_universal/VideoCaptureXAML/video_capture_xaml/video_capture_xaml.WindowsPhone/MainPage.xaml.h b/samples/winrt_universal/VideoCaptureXAML/video_capture_xaml/video_capture_xaml.WindowsPhone/MainPage.xaml.h new file mode 100644 index 0000000000..b3f134735e --- /dev/null +++ b/samples/winrt_universal/VideoCaptureXAML/video_capture_xaml/video_capture_xaml.WindowsPhone/MainPage.xaml.h @@ -0,0 +1,28 @@ +// +// MainPage.xaml.h +// Declaration of the MainPage class. +// + +#pragma once + +#include "MainPage.g.h" + +namespace video_capture_xaml +{ + /// + /// An empty page that can be used on its own or navigated to within a Frame. + /// + public ref class MainPage sealed + { + public: + MainPage(); + + protected: + + virtual void OnNavigatedTo(Windows::UI::Xaml::Navigation::NavigationEventArgs^ e) override; + + private: + + void OnVisibilityChanged(Platform::Object ^sender, Windows::UI::Core::VisibilityChangedEventArgs ^e); + }; +} diff --git a/samples/winrt_universal/VideoCaptureXAML/video_capture_xaml/video_capture_xaml.WindowsPhone/Package.appxmanifest b/samples/winrt_universal/VideoCaptureXAML/video_capture_xaml/video_capture_xaml.WindowsPhone/Package.appxmanifest new file mode 100644 index 0000000000..c03f143e3f --- /dev/null +++ b/samples/winrt_universal/VideoCaptureXAML/video_capture_xaml/video_capture_xaml.WindowsPhone/Package.appxmanifest @@ -0,0 +1,46 @@ + + + + + + + + + video_capture_xaml.WindowsPhone + daver_000 + Assets\StoreLogo.png + + + + 6.3.1 + 6.3.1 + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/samples/winrt_universal/VideoCaptureXAML/video_capture_xaml/video_capture_xaml.WindowsPhone/video_capture_xaml.WindowsPhone.vcxproj b/samples/winrt_universal/VideoCaptureXAML/video_capture_xaml/video_capture_xaml.WindowsPhone/video_capture_xaml.WindowsPhone.vcxproj new file mode 100644 index 0000000000..70a878bfd8 --- /dev/null +++ b/samples/winrt_universal/VideoCaptureXAML/video_capture_xaml/video_capture_xaml.WindowsPhone/video_capture_xaml.WindowsPhone.vcxproj @@ -0,0 +1,147 @@ + + + + + Debug + ARM + + + Debug + Win32 + + + Release + ARM + + + Release + Win32 + + + + {d7a82e7f-1535-4eec-aba9-2c8447669d33} + video_capture_xaml + en-US + 12.0 + true + Windows Phone + 8.1 + video_capture_xaml.WindowsPhone + + + + Application + true + v120_wp81 + + + Application + true + v120_wp81 + + + Application + false + true + v120_wp81 + + + Application + false + true + v120_wp81 + + + + + + + + + + + + + + + + + + + + + + + + $(OPENCV_WINRT_INSTALL_DIR)WP\8.1\x86\x86\vc12\lib;$(VC_LibraryPath_x86);$(WindowsPhoneSDK_LibraryPath_x86); + + + $(OPENCV_WINRT_INSTALL_DIR)WP\8.1\ARM\ARM\vc12\lib;$(VC_LibraryPath_ARM);$(WindowsPhoneSDK_LibraryPath_arm); + + + + /bigobj %(AdditionalOptions) + 4453;28204 + ../../../../../modules/core/include;../../../../../modules/flann/include;../../../../../modules/videoio/include;../../../../../modules/hal/include;../../../../../modules/imgproc/include;../../../../../modules/features2d/include;%(AdditionalIncludeDirectories);$(MSBuildThisFileDirectory) + + + opencv_core300d.lib;opencv_imgproc300d.lib;opencv_videoio300d.lib;WindowsPhoneCore.lib;RuntimeObject.lib;PhoneAppModelHost.lib;%(AdditionalDependencies) + + + + + /bigobj %(AdditionalOptions) + 4453;28204 + + + + + /bigobj %(AdditionalOptions) + 4453;28204 + ../../../../../modules/core/include;../../../../../modules/flann/include;../../../../../modules/videoio/include;../../../../../modules/hal/include;../../../../../modules/imgproc/include;../../../../../modules/features2d/include;%(AdditionalIncludeDirectories);$(MSBuildThisFileDirectory) + + + opencv_core300d.lib;opencv_imgproc300d.lib;opencv_videoio300d.lib;WindowsPhoneCore.lib;RuntimeObject.lib;PhoneAppModelHost.lib;%(AdditionalDependencies) + + + + + /bigobj %(AdditionalOptions) + 4453;28204 + + + + + MainPage.xaml + + + + + Designer + + + + + Designer + + + + + + + + + + + + + MainPage.xaml + + + + + + + + + \ No newline at end of file diff --git a/samples/winrt_universal/VideoCaptureXAML/video_capture_xaml/video_capture_xaml.WindowsPhone/video_capture_xaml.WindowsPhone.vcxproj.filters b/samples/winrt_universal/VideoCaptureXAML/video_capture_xaml/video_capture_xaml.WindowsPhone/video_capture_xaml.WindowsPhone.vcxproj.filters new file mode 100644 index 0000000000..ce06419c38 --- /dev/null +++ b/samples/winrt_universal/VideoCaptureXAML/video_capture_xaml/video_capture_xaml.WindowsPhone/video_capture_xaml.WindowsPhone.vcxproj.filters @@ -0,0 +1,42 @@ + + + + + {$guid3$} + bmp;fbx;gif;jpg;jpeg;tga;tiff;tif;png + + + Assets + + + Assets + + + Assets + + + Assets + + + Assets + + + Assets + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/samples/winrt_universal/VideoCaptureXAML/video_capture_xaml/video_capture_xaml.WindowsPhone/video_capture_xaml.WindowsPhone_TemporaryKey.pfx b/samples/winrt_universal/VideoCaptureXAML/video_capture_xaml/video_capture_xaml.WindowsPhone/video_capture_xaml.WindowsPhone_TemporaryKey.pfx new file mode 100644 index 0000000000000000000000000000000000000000..26180417e915ffe3e57052ad261d98d3d5214e1b GIT binary patch literal 2536 zcmY*Z2{hDeAO6o6!we?N$TG4`GDi5@$F*deA@{ROQFCpLean9BGep^=qSVEpY)Qn3 z8buguNQgn%N?nPfuBE=I^L_W8`@ZM5J-_$)o%fvgybnl2u%QqxkcKFNBk*aKX#?L1J7`563+KO7C#aKEv3P>K^klml!7Dw4|9g2 zV7w>eY+}-{rU*izJR>j~Y=pQznWTq8Dw|C2O^qL4eI6I6>rPs~L!~Ln zn-COEoAq@n>6xz$2x7J4TCyp&@$)&_rMjf+^Gc-J?=1du2zUD{ zs93uAi|ec^t7Pz{6djRbCV4;@M{EKE3}cpa{m}e5x-3OJQq;`&U}DV*SE!=oEutlV z`2^8Lx3@@Ce9ZdX;{gW~Y)xUyZ-@9r_}R$ST<_KI_6)5JFk|K~IsJgP(w3w0b&l$q z^DoT@TEaYS%tISd`cw2J)dvn|plHChd9t~`E-{X*`z-Wa0pA^P6@btmbCHMZm_;|ffv8_Ahbe)s@ihX23T7kefr)# zwkjAU*cvrtwrLU3_>HpG#{LwZ%sWUCyktN|iS)dy)i-x5B);nGU#oA!5V~BH0@2Ck z8a|!^4!63fI{O|;vt@^!h~F~iaZ?o?1?Fn_9qzp4daI1hubo2Nq(kPxJ04nkr( zZufoBbuYw?I?6Y)hN?(#p^e#SH#+*b` z8E!gXaF6ja$CP&^bFy>K%o)Q<=!{E&3h{*RMp8Es)G8d0=nS@_t^4VgtWz&rdHQ6I zsnL_Cf&iam7&GrjVzWs7^ zb2Gi^g}D`1{va<_HtC}is=7LV56aTsY;wRadp>ENC`w|uPVf#l7p-5KNH$mCgBR3U7ZM$t{6wu7 z$DHI%-zVGCqQ)+Wp`zix!|sc;~NepYX}8%(C7c9EA=DUm{nV zIvdUHI5J%AZi@t$))=j0;xx#6wG#!?_bsFiC0Xd)6Mmh?-tb^$`)$)Xub+GepSiBT zp5D)OjIFzHxlXazz4XRz^Vgo^Xnn^IhYOpA%~PRZ9lkzBjQe)!ea%Gp+WeBk*} z)tQRjYXpOcv#DpwdW>EzkqW&2jcO)O4${QtkC%B@kP)C$Y|`i(ba+yG z8g@Ckk?kIAoxQ0UbH@tB&2zO@D>%USsd-{vSdrNiorzG?7X zg=F*;`kBYMHKOlg-iN-ot+glUyo#`>eO36;saaF$E@ELF|LpeSs`rp=b(B=&!gv)z zGrfJkq3>g^_9OYuO8S)yLWO|VGug44+}AnukBxyg3F7yozwpS`@nTDwq%I)Wau>$6 z`R;;kw{~Km;HQ zICA_CBpC4FRA!v~cOaC5g>dRH&Y)1h_a{phu={x~ic_8Cj1L28T#MVsnRl+?htwz2xQu0QG(mPD8@B^9giJ9$hkYlx5@uxM zpNaSwZ+$EsCT*Yj5HP0G=osxKZr!&%aeYK*3Pi1m;GD|LNJ|53T-yoD=}VY?c$85?e>NT3}(nCL`W`|rpQm&g zw6I3HA6?=uv1-kc=K^)LEF}!1Cn3XZ{d=1`zw8FTsurnv)z^>jv6s7n>5vkDN_udK zFKzT21qsXTQ}i^%C)ZL|FH#||o?Ihh ze-1k{I6NVt>E)vKmAWJ+jXM>tRByZfc4>M2V5eM?{&9o#*}31O9r;mNnj+uyeDull zS?<-)X7aE2cngGavG_wwyyIivGyUqX(^FGzziQa}oZk<~xeTx4Rvb&u(O#vsJGL!8tp rBdA6k-fy&>;j02e2kBN8Q;l-u@F4htuWDgcYG?i9j}OR^pr7l%dK6wD literal 0 HcmV?d00001 From a5242265d74776d51f2d6dde7f46ecf33d7849f3 Mon Sep 17 00:00:00 2001 From: Dikay900 Date: Mon, 18 May 2015 00:31:39 +0200 Subject: [PATCH 30/31] cleanup after last PR --- modules/objdetect/src/cascadedetect.cpp | 4 ---- modules/objdetect/src/cascadedetect.hpp | 1 - 2 files changed, 5 deletions(-) diff --git a/modules/objdetect/src/cascadedetect.cpp b/modules/objdetect/src/cascadedetect.cpp index cf2d6ca207..63edd0d8c5 100644 --- a/modules/objdetect/src/cascadedetect.cpp +++ b/modules/objdetect/src/cascadedetect.cpp @@ -679,10 +679,6 @@ void HaarEvaluator::computeOptFeatures() copyVectorToUMat(*optfeatures_lbuf, ufbuf); } -bool HaarEvaluator::setImage(InputArray _image, const std::vector& _scales){ - return FeatureEvaluator::setImage(_image, _scales); -} - bool HaarEvaluator::setWindow( Point pt, int scaleIdx ) { const ScaleData& s = getScaleData(scaleIdx); diff --git a/modules/objdetect/src/cascadedetect.hpp b/modules/objdetect/src/cascadedetect.hpp index 156f0468db..4cbf3e9bf0 100644 --- a/modules/objdetect/src/cascadedetect.hpp +++ b/modules/objdetect/src/cascadedetect.hpp @@ -347,7 +347,6 @@ public: virtual Ptr clone() const; virtual int getFeatureType() const { return FeatureEvaluator::HAAR; } - virtual bool setImage(InputArray _image, const std::vector& _scales); virtual bool setWindow(Point p, int scaleIdx); Rect getNormRect() const; int getSquaresOffset() const; From e22979f33425e40e2e4f6e803af329c7eccc1a85 Mon Sep 17 00:00:00 2001 From: Vladislav Vinogradov Date: Mon, 18 May 2015 14:16:55 +0300 Subject: [PATCH 31/31] fix #4343 : cv::cuda::findMinMaxLoc incorrect output for single row matrix --- modules/cudaarithm/test/test_reductions.cpp | 38 +++++++++++++++++++ .../opencv2/cudev/grid/detail/minmaxloc.hpp | 2 +- 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/modules/cudaarithm/test/test_reductions.cpp b/modules/cudaarithm/test/test_reductions.cpp index a95d007b81..9a88549392 100644 --- a/modules/cudaarithm/test/test_reductions.cpp +++ b/modules/cudaarithm/test/test_reductions.cpp @@ -587,6 +587,44 @@ CUDA_TEST_P(MinMaxLoc, WithoutMask) } } +CUDA_TEST_P(MinMaxLoc, OneRowMat) +{ + cv::Mat src = randomMat(cv::Size(size.width, 1), depth); + + double minVal, maxVal; + cv::Point minLoc, maxLoc; + cv::cuda::minMaxLoc(loadMat(src, useRoi), &minVal, &maxVal, &minLoc, &maxLoc); + + double minVal_gold, maxVal_gold; + cv::Point minLoc_gold, maxLoc_gold; + minMaxLocGold(src, &minVal_gold, &maxVal_gold, &minLoc_gold, &maxLoc_gold); + + EXPECT_DOUBLE_EQ(minVal_gold, minVal); + EXPECT_DOUBLE_EQ(maxVal_gold, maxVal); + + expectEqual(src, minLoc_gold, minLoc); + expectEqual(src, maxLoc_gold, maxLoc); +} + +CUDA_TEST_P(MinMaxLoc, OneColumnMat) +{ + cv::Mat src = randomMat(cv::Size(1, size.height), depth); + + double minVal, maxVal; + cv::Point minLoc, maxLoc; + cv::cuda::minMaxLoc(loadMat(src, useRoi), &minVal, &maxVal, &minLoc, &maxLoc); + + double minVal_gold, maxVal_gold; + cv::Point minLoc_gold, maxLoc_gold; + minMaxLocGold(src, &minVal_gold, &maxVal_gold, &minLoc_gold, &maxLoc_gold); + + EXPECT_DOUBLE_EQ(minVal_gold, minVal); + EXPECT_DOUBLE_EQ(maxVal_gold, maxVal); + + expectEqual(src, minLoc_gold, minLoc); + expectEqual(src, maxLoc_gold, maxLoc); +} + CUDA_TEST_P(MinMaxLoc, Async) { cv::Mat src = randomMat(size, depth); diff --git a/modules/cudev/include/opencv2/cudev/grid/detail/minmaxloc.hpp b/modules/cudev/include/opencv2/cudev/grid/detail/minmaxloc.hpp index 793dcc7f0a..eb34d7f487 100644 --- a/modules/cudev/include/opencv2/cudev/grid/detail/minmaxloc.hpp +++ b/modules/cudev/include/opencv2/cudev/grid/detail/minmaxloc.hpp @@ -156,7 +156,7 @@ namespace grid_minmaxloc_detail __host__ void minMaxLoc(const SrcPtr& src, ResType* minVal, ResType* maxVal, int* minLoc, int* maxLoc, const MaskPtr& mask, int rows, int cols, cudaStream_t stream) { dim3 block, grid; - getLaunchCfg(cols, rows, block, grid); + getLaunchCfg(rows, cols, block, grid); const int patch_x = divUp(divUp(cols, grid.x), block.x); const int patch_y = divUp(divUp(rows, grid.y), block.y);