Update from https://crrev.com/312600
TBR=jamesr@chromium.org
Review URL: https://codereview.chromium.org/863253002
diff --git a/DEPS b/DEPS
index be45317..d985ab3 100644
--- a/DEPS
+++ b/DEPS
@@ -21,15 +21,15 @@
'chromium_git': 'https://chromium.googlesource.com',
'dart_svn': 'https://dart.googlecode.com',
'sfntly_revision': '1bdaae8fc788a5ac8936d68bf24f37d977a13dac',
- 'skia_revision': '3e3b58d57a358e2d52bc23ad2409a95d59310100',
+ 'skia_revision': 'faff2c45985a5e0fdb72bdf416d97babecd44833',
# Three lines of non-changing comments so that
# the commit queue can handle CLs rolling Skia
# and V8 without interference from each other.
- 'v8_revision': '3efdae6669030b03a841c8d579655ba1f36b1f87',
+ 'v8_revision': 'c9b8b474d525faf44f9848edf448f913151f297b',
# Three lines of non-changing comments so that
# the commit queue can handle CLs rolling ANGLE
# and whatever else without interference from each other.
- 'angle_revision': '2a30ccefd0c47608380a1621a983bf46685e5ad9',
+ 'angle_revision': 'dd806c2b58aac61f010c7b1c6831f9541209f490',
# Three lines of non-changing comments so that
# the commit queue can handle CLs rolling build tools
# and whatever else without interference from each other.
@@ -133,7 +133,7 @@
'https://boringssl.googlesource.com/boringssl.git' + '@' + Var('boringssl_revision'),
'src/tools/gyp':
- Var('chromium_git') + '/external/gyp.git' + '@' + '194ec65a55edf24c1976d4265f57e8c90ef5bb2f', # from svn revision 2023
+ Var('chromium_git') + '/external/gyp.git' + '@' + 'adb7d24b9fc166f01ab2da50478556b518a9218f', # from svn revision 2023
}
diff --git a/base/BUILD.gn b/base/BUILD.gn
index 065f871..e20b744 100644
--- a/base/BUILD.gn
+++ b/base/BUILD.gn
@@ -40,10 +40,8 @@
"android/fifo_utils.h",
"android/important_file_writer_android.cc",
"android/important_file_writer_android.h",
- "android/locale_utils.cc",
- "android/locale_utils.h",
- "android/scoped_java_ref.cc",
- "android/scoped_java_ref.h",
+ "android/java_handler_thread.cc",
+ "android/java_handler_thread.h",
"android/jni_android.cc",
"android/jni_android.h",
"android/jni_array.cc",
@@ -56,17 +54,21 @@
"android/jni_utils.h",
"android/jni_weak_ref.cc",
"android/jni_weak_ref.h",
+ "android/library_loader/library_load_from_apk_status_codes.h",
"android/library_loader/library_loader_hooks.cc",
"android/library_loader/library_loader_hooks.h",
- "android/library_loader/library_load_from_apk_status_codes.h",
+ "android/locale_utils.cc",
+ "android/locale_utils.h",
"android/memory_pressure_listener_android.cc",
"android/memory_pressure_listener_android.h",
- "android/java_handler_thread.cc",
- "android/java_handler_thread.h",
"android/path_service_android.cc",
"android/path_service_android.h",
"android/path_utils.cc",
"android/path_utils.h",
+ "android/record_histogram.cc",
+ "android/record_histogram.h",
+ "android/scoped_java_ref.cc",
+ "android/scoped_java_ref.h",
"android/sys_utils.cc",
"android/sys_utils.h",
"android/thread_utils.h",
@@ -184,9 +186,6 @@
"deferred_sequenced_task_runner.h",
"environment.cc",
"environment.h",
- "event_recorder.h",
- "event_recorder_stubs.cc",
- "event_recorder_win.cc",
"file_descriptor_posix.h",
"file_version_info.h",
"file_version_info_mac.h",
@@ -857,7 +856,6 @@
# Windows.
if (is_win) {
sources -= [
- "event_recorder_stubs.cc",
"message_loop/message_pump_libevent.cc",
"strings/string16.cc",
@@ -1454,17 +1452,18 @@
"android/java/src/org/chromium/base/FieldTrialList.java",
"android/java/src/org/chromium/base/ImportantFileWriterAndroid.java",
"android/java/src/org/chromium/base/JNIUtils.java",
- "android/java/src/org/chromium/base/library_loader/LibraryLoader.java",
+ "android/java/src/org/chromium/base/JavaHandlerThread.java",
"android/java/src/org/chromium/base/LocaleUtils.java",
"android/java/src/org/chromium/base/MemoryPressureListener.java",
- "android/java/src/org/chromium/base/JavaHandlerThread.java",
"android/java/src/org/chromium/base/PathService.java",
"android/java/src/org/chromium/base/PathUtils.java",
"android/java/src/org/chromium/base/PowerMonitor.java",
- "android/java/src/org/chromium/base/SystemMessageHandler.java",
"android/java/src/org/chromium/base/SysUtils.java",
+ "android/java/src/org/chromium/base/SystemMessageHandler.java",
"android/java/src/org/chromium/base/ThreadUtils.java",
"android/java/src/org/chromium/base/TraceEvent.java",
+ "android/java/src/org/chromium/base/library_loader/LibraryLoader.java",
+ "android/java/src/org/chromium/base/metrics/RecordHistogram.java",
]
jni_package = "base"
}
diff --git a/base/android/base_jni_registrar.cc b/base/android/base_jni_registrar.cc
index c0f0af7..9529b71 100644
--- a/base/android/base_jni_registrar.cc
+++ b/base/android/base_jni_registrar.cc
@@ -20,6 +20,7 @@
#include "base/android/memory_pressure_listener_android.h"
#include "base/android/path_service_android.h"
#include "base/android/path_utils.h"
+#include "base/android/record_histogram.h"
#include "base/android/sys_utils.h"
#include "base/android/thread_utils.h"
#include "base/android/trace_event_binding.h"
@@ -32,28 +33,29 @@
namespace android {
static RegistrationMethod kBaseRegisteredMethods[] = {
- { "ApplicationStatusListener",
- base::android::ApplicationStatusListener::RegisterBindings },
- { "BuildInfo", base::android::BuildInfo::RegisterBindings },
- { "CommandLine", base::android::RegisterCommandLine },
- { "ContentUriUtils", base::RegisterContentUriUtils },
- { "CpuFeatures", base::android::RegisterCpuFeatures },
- { "EventLog", base::android::RegisterEventLog },
- { "FieldTrialList", base::android::RegisterFieldTrialList },
- { "ImportantFileWriterAndroid",
- base::android::RegisterImportantFileWriterAndroid },
- { "JNIUtils", base::android::RegisterJNIUtils },
- { "LocaleUtils", base::android::RegisterLocaleUtils },
- { "MemoryPressureListenerAndroid",
- base::android::MemoryPressureListenerAndroid::Register },
- { "JavaHandlerThread", base::android::JavaHandlerThread::RegisterBindings },
- { "PathService", base::android::RegisterPathService },
- { "PathUtils", base::android::RegisterPathUtils },
- { "SystemMessageHandler", base::MessagePumpForUI::RegisterBindings },
- { "SysUtils", base::android::SysUtils::Register },
- { "PowerMonitor", base::RegisterPowerMonitor },
- { "ThreadUtils", base::RegisterThreadUtils },
- { "TraceEvent", base::android::RegisterTraceEvent },
+ {"ApplicationStatusListener",
+ base::android::ApplicationStatusListener::RegisterBindings},
+ {"BuildInfo", base::android::BuildInfo::RegisterBindings},
+ {"CommandLine", base::android::RegisterCommandLine},
+ {"ContentUriUtils", base::RegisterContentUriUtils},
+ {"CpuFeatures", base::android::RegisterCpuFeatures},
+ {"EventLog", base::android::RegisterEventLog},
+ {"FieldTrialList", base::android::RegisterFieldTrialList},
+ {"ImportantFileWriterAndroid",
+ base::android::RegisterImportantFileWriterAndroid},
+ {"JNIUtils", base::android::RegisterJNIUtils},
+ {"LocaleUtils", base::android::RegisterLocaleUtils},
+ {"MemoryPressureListenerAndroid",
+ base::android::MemoryPressureListenerAndroid::Register},
+ {"JavaHandlerThread", base::android::JavaHandlerThread::RegisterBindings},
+ {"PathService", base::android::RegisterPathService},
+ {"PathUtils", base::android::RegisterPathUtils},
+ {"PowerMonitor", base::RegisterPowerMonitor},
+ {"RecordHistogram", base::android::RegisterRecordHistogram},
+ {"SystemMessageHandler", base::MessagePumpForUI::RegisterBindings},
+ {"SysUtils", base::android::SysUtils::Register},
+ {"ThreadUtils", base::RegisterThreadUtils},
+ {"TraceEvent", base::android::RegisterTraceEvent},
};
bool RegisterJni(JNIEnv* env) {
diff --git a/base/android/java/src/org/chromium/base/metrics/RecordHistogram.java b/base/android/java/src/org/chromium/base/metrics/RecordHistogram.java
new file mode 100644
index 0000000..8295a85
--- /dev/null
+++ b/base/android/java/src/org/chromium/base/metrics/RecordHistogram.java
@@ -0,0 +1,62 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.base.metrics;
+
+import org.chromium.base.JNINamespace;
+import org.chromium.base.VisibleForTesting;
+
+/**
+ * Java API for recording UMA histograms. As opposed to macros used in native code, these calls are
+ * not caching the histogram pointer; also, the JNI calls are relatively costly - avoid calling
+ * these methods in performance-critical code.
+ */
+@JNINamespace("base::android")
+public class RecordHistogram {
+ /**
+ * Records a sample in a boolean UMA histogram of the given name. Boolean histogram has two
+ * buckets, corresponding to success (true) and failure (false).
+ * @param name name of the histogram
+ * @param sample sample to be recorded, either true or false
+ */
+ public static void recordBooleanHistogram(String name, boolean sample) {
+ nativeRecordBooleanHistogram(name, sample);
+ }
+
+ /**
+ * Records a sample in an enumerated histogram of the given name and boundary. Note that
+ * |boundary| identifies the histogram - it should be the same at every invocation.
+ * @param name name of the histogram
+ * @param sample sample to be recorded, at least 0 and at most |boundary| - 1
+ * @param boundary upper bound for legal sample values - all sample values has to be strictly
+ * lower than |boundary|
+ */
+ public static void recordEnumeratedHistogram(String name, int sample, int boundary) {
+ nativeRecordEnumeratedHistogram(name, sample, boundary);
+ }
+
+ /**
+ * Returns the number of samples recorded in the given bucket of the given histogram.
+ * @param name name of the histogram to look up
+ * @param sample the bucket containing this sample value will be looked up
+ */
+ @VisibleForTesting
+ public static int getHistogramValueCountForTesting(String name, int sample) {
+ return nativeGetHistogramValueCountForTesting(name, sample);
+ }
+
+ /**
+ * Initializes the metrics system.
+ */
+ public static void initialize() {
+ nativeInitialize();
+ }
+
+ private static native void nativeRecordBooleanHistogram(String name, boolean sample);
+ private static native void nativeRecordEnumeratedHistogram(
+ String name, int sample, int boundary);
+
+ private static native int nativeGetHistogramValueCountForTesting(String name, int sample);
+ private static native void nativeInitialize();
+}
diff --git a/base/android/javatests/src/org/chromium/base/metrics/RecordHistogramTest.java b/base/android/javatests/src/org/chromium/base/metrics/RecordHistogramTest.java
new file mode 100644
index 0000000..82c1ca9
--- /dev/null
+++ b/base/android/javatests/src/org/chromium/base/metrics/RecordHistogramTest.java
@@ -0,0 +1,78 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.base.metrics;
+
+import android.test.InstrumentationTestCase;
+import android.test.suitebuilder.annotation.SmallTest;
+
+import org.chromium.base.library_loader.LibraryLoader;
+import org.chromium.base.test.util.MetricsUtils.HistogramDelta;
+
+/**
+ * Tests for the Java API for recording UMA histograms.
+ */
+public class RecordHistogramTest extends InstrumentationTestCase {
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ LibraryLoader.ensureInitialized();
+ RecordHistogram.initialize();
+ }
+
+ /**
+ * Tests recording of boolean histograms.
+ */
+ @SmallTest
+ public void testRecordBooleanHistogram() {
+ String histogram = "HelloWorld.BooleanMetric";
+ HistogramDelta falseCount = new HistogramDelta(histogram, 0);
+ HistogramDelta trueCount = new HistogramDelta(histogram, 1);
+ assertEquals(0, trueCount.getDelta());
+ assertEquals(0, falseCount.getDelta());
+
+ RecordHistogram.recordBooleanHistogram(histogram, true);
+ assertEquals(1, trueCount.getDelta());
+ assertEquals(0, falseCount.getDelta());
+
+ RecordHistogram.recordBooleanHistogram(histogram, true);
+ assertEquals(2, trueCount.getDelta());
+ assertEquals(0, falseCount.getDelta());
+
+ RecordHistogram.recordBooleanHistogram(histogram, false);
+ assertEquals(2, trueCount.getDelta());
+ assertEquals(1, falseCount.getDelta());
+ }
+
+ /**
+ * Tests recording of enumerated histograms.
+ */
+ @SmallTest
+ public void testRecordEnumeratedHistogram() {
+ String histogram = "HelloWorld.EnumeratedMetric";
+ HistogramDelta zeroCount = new HistogramDelta(histogram, 0);
+ HistogramDelta oneCount = new HistogramDelta(histogram, 1);
+ HistogramDelta twoCount = new HistogramDelta(histogram, 2);
+ final int boundary = 3;
+
+ assertEquals(0, zeroCount.getDelta());
+ assertEquals(0, oneCount.getDelta());
+ assertEquals(0, twoCount.getDelta());
+
+ RecordHistogram.recordEnumeratedHistogram(histogram, 0, boundary);
+ assertEquals(1, zeroCount.getDelta());
+ assertEquals(0, oneCount.getDelta());
+ assertEquals(0, twoCount.getDelta());
+
+ RecordHistogram.recordEnumeratedHistogram(histogram, 0, boundary);
+ assertEquals(2, zeroCount.getDelta());
+ assertEquals(0, oneCount.getDelta());
+ assertEquals(0, twoCount.getDelta());
+
+ RecordHistogram.recordEnumeratedHistogram(histogram, 2, boundary);
+ assertEquals(2, zeroCount.getDelta());
+ assertEquals(0, oneCount.getDelta());
+ assertEquals(1, twoCount.getDelta());
+ }
+}
diff --git a/base/android/record_histogram.cc b/base/android/record_histogram.cc
new file mode 100644
index 0000000..9a72460
--- /dev/null
+++ b/base/android/record_histogram.cc
@@ -0,0 +1,69 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/android/jni_android.h"
+#include "base/android/jni_string.h"
+#include "base/android/record_histogram.h"
+#include "base/metrics/histogram.h"
+#include "base/metrics/statistics_recorder.h"
+#include "jni/RecordHistogram_jni.h"
+
+namespace base {
+namespace android {
+
+void RecordBooleanHistogram(JNIEnv* env,
+ jclass clazz,
+ jstring j_histogram_name,
+ jboolean j_sample) {
+ std::string histogram_name = ConvertJavaStringToUTF8(env, j_histogram_name);
+ bool sample = static_cast<bool>(j_sample);
+
+ BooleanHistogram::FactoryGet(histogram_name,
+ HistogramBase::kUmaTargetedHistogramFlag)
+ ->AddBoolean(sample);
+}
+
+void RecordEnumeratedHistogram(JNIEnv* env,
+ jclass clazz,
+ jstring j_histogram_name,
+ jint j_sample,
+ jint j_boundary) {
+ std::string histogram_name = ConvertJavaStringToUTF8(env, j_histogram_name);
+ int sample = static_cast<int>(j_sample);
+ int boundary = static_cast<int>(j_boundary);
+
+ LinearHistogram::FactoryGet(histogram_name, 1, boundary, boundary + 1,
+ HistogramBase::kUmaTargetedHistogramFlag)
+ ->Add(sample);
+}
+
+void Initialize(JNIEnv* env, jclass) {
+ StatisticsRecorder::Initialize();
+}
+
+// This backs a Java test util for testing histograms -
+// MetricsUtils.HistogramDelta. It should live in a test-specific file, but we
+// currently can't have test-specific native code packaged in test-specific Java
+// targets - see http://crbug.com/415945.
+jint GetHistogramValueCountForTesting(JNIEnv* env,
+ jclass clazz,
+ jstring histogram_name,
+ jint sample) {
+ HistogramBase* histogram = StatisticsRecorder::FindHistogram(
+ android::ConvertJavaStringToUTF8(env, histogram_name));
+ if (histogram == nullptr) {
+ // No samples have been recorded for this histogram (yet?).
+ return 0;
+ }
+
+ scoped_ptr<HistogramSamples> samples = histogram->SnapshotSamples();
+ return samples->GetCount(static_cast<int>(sample));
+}
+
+bool RegisterRecordHistogram(JNIEnv* env) {
+ return RegisterNativesImpl(env);
+}
+
+} // namespace android
+} // namespace base
diff --git a/base/android/record_histogram.h b/base/android/record_histogram.h
new file mode 100644
index 0000000..caa10f0
--- /dev/null
+++ b/base/android/record_histogram.h
@@ -0,0 +1,18 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef BASE_ANDROID_RECORD_HISTOGRAM_H_
+#define BASE_ANDROID_RECORD_HISTOGRAM_H_
+
+#include <jni.h>
+
+namespace base {
+namespace android {
+
+bool RegisterRecordHistogram(JNIEnv* env);
+
+} // namespace android
+} // namespace base
+
+#endif // BASE_ANDROID_RECORD_HISTOGRAM_H_
diff --git a/base/base.gyp b/base/base.gyp
index 5d26fc4..114cad6 100644
--- a/base/base.gyp
+++ b/base/base.gyp
@@ -230,15 +230,10 @@
}],
],
'sources': [
- 'third_party/xdg_user_dirs/xdg_user_dir_lookup.cc',
- 'third_party/xdg_user_dirs/xdg_user_dir_lookup.h',
'async_socket_io_handler.h',
'async_socket_io_handler_posix.cc',
'async_socket_io_handler_win.cc',
'auto_reset.h',
- 'event_recorder.h',
- 'event_recorder_stubs.cc',
- 'event_recorder_win.cc',
'linux_util.cc',
'linux_util.h',
'message_loop/message_pump_android.cc',
@@ -256,8 +251,10 @@
'posix/file_descriptor_shuffle.cc',
'posix/file_descriptor_shuffle.h',
'sync_socket.h',
- 'sync_socket_win.cc',
'sync_socket_posix.cc',
+ 'sync_socket_win.cc',
+ 'third_party/xdg_user_dirs/xdg_user_dir_lookup.cc',
+ 'third_party/xdg_user_dirs/xdg_user_dir_lookup.h',
],
'includes': [
'../build/android/increase_size_for_speed.gypi',
@@ -1166,15 +1163,10 @@
4267,
],
'sources': [
- 'third_party/xdg_user_dirs/xdg_user_dir_lookup.cc',
- 'third_party/xdg_user_dirs/xdg_user_dir_lookup.h',
'async_socket_io_handler.h',
'async_socket_io_handler_posix.cc',
'async_socket_io_handler_win.cc',
'auto_reset.h',
- 'event_recorder.h',
- 'event_recorder_stubs.cc',
- 'event_recorder_win.cc',
'linux_util.cc',
'linux_util.h',
'md5.cc',
@@ -1186,8 +1178,10 @@
'posix/file_descriptor_shuffle.cc',
'posix/file_descriptor_shuffle.h',
'sync_socket.h',
- 'sync_socket_win.cc',
'sync_socket_posix.cc',
+ 'sync_socket_win.cc',
+ 'third_party/xdg_user_dirs/xdg_user_dir_lookup.cc',
+ 'third_party/xdg_user_dirs/xdg_user_dir_lookup.h',
],
},
{
@@ -1342,17 +1336,18 @@
'android/java/src/org/chromium/base/FieldTrialList.java',
'android/java/src/org/chromium/base/ImportantFileWriterAndroid.java',
'android/java/src/org/chromium/base/JNIUtils.java',
- 'android/java/src/org/chromium/base/library_loader/LibraryLoader.java',
+ 'android/java/src/org/chromium/base/JavaHandlerThread.java',
'android/java/src/org/chromium/base/LocaleUtils.java',
'android/java/src/org/chromium/base/MemoryPressureListener.java',
- 'android/java/src/org/chromium/base/JavaHandlerThread.java',
'android/java/src/org/chromium/base/PathService.java',
'android/java/src/org/chromium/base/PathUtils.java',
'android/java/src/org/chromium/base/PowerMonitor.java',
- 'android/java/src/org/chromium/base/SystemMessageHandler.java',
'android/java/src/org/chromium/base/SysUtils.java',
+ 'android/java/src/org/chromium/base/SystemMessageHandler.java',
'android/java/src/org/chromium/base/ThreadUtils.java',
'android/java/src/org/chromium/base/TraceEvent.java',
+ 'android/java/src/org/chromium/base/library_loader/LibraryLoader.java',
+ 'android/java/src/org/chromium/base/metrics/RecordHistogram.java',
],
'variables': {
'jni_gen_package': 'base',
diff --git a/base/base.gypi b/base/base.gypi
index 349308c..0c6ee7e 100644
--- a/base/base.gypi
+++ b/base/base.gypi
@@ -72,6 +72,8 @@
'android/path_service_android.h',
'android/path_utils.cc',
'android/path_utils.h',
+ 'android/record_histogram.cc',
+ 'android/record_histogram.h',
'android/sys_utils.cc',
'android/sys_utils.h',
'android/thread_utils.h',
@@ -927,7 +929,6 @@
'<(DEPTH)/third_party/wtl/include',
],
'sources!': [
- 'event_recorder_stubs.cc',
'files/file_path_watcher_fsevents.cc',
'files/file_path_watcher_fsevents.h',
'files/file_path_watcher_kqueue.cc',
diff --git a/base/chromeos/memory_pressure_observer_chromeos.cc b/base/chromeos/memory_pressure_observer_chromeos.cc
index 4da7d24..8112c76 100644
--- a/base/chromeos/memory_pressure_observer_chromeos.cc
+++ b/base/chromeos/memory_pressure_observer_chromeos.cc
@@ -24,25 +24,56 @@
kModerateMemoryPressureCooldownMs / kMemoryPressureIntervalMs;
// Threshold constants to emit pressure events.
-const int kMemoryPressureModerateThresholdPercent = 70;
-const int kMemoryPressureCriticalThresholdPercent = 90;
+const int kNormalMemoryPressureModerateThresholdPercent = 60;
+const int kNormalMemoryPressureCriticalThresholdPercent = 90;
+const int kAggressiveMemoryPressureModerateThresholdPercent = 35;
+const int kAggressiveMemoryPressureCriticalThresholdPercent = 70;
+
+// Converts a |MemoryPressureThreshold| value into a used memory percentage for
+// the moderate pressure event.
+int GetModerateMemoryThresholdInPercent(
+ MemoryPressureObserverChromeOS::MemoryPressureThresholds thresholds) {
+ return thresholds == MemoryPressureObserverChromeOS::
+ THRESHOLD_AGGRESSIVE_CACHE_DISCARD ||
+ thresholds == MemoryPressureObserverChromeOS::THRESHOLD_AGGRESSIVE
+ ? kAggressiveMemoryPressureModerateThresholdPercent
+ : kNormalMemoryPressureModerateThresholdPercent;
+}
+
+// Converts a |MemoryPressureThreshold| value into a used memory percentage for
+// the critical pressure event.
+int GetCriticalMemoryThresholdInPercent(
+ MemoryPressureObserverChromeOS::MemoryPressureThresholds thresholds) {
+ return thresholds == MemoryPressureObserverChromeOS::
+ THRESHOLD_AGGRESSIVE_TAB_DISCARD ||
+ thresholds == MemoryPressureObserverChromeOS::THRESHOLD_AGGRESSIVE
+ ? kAggressiveMemoryPressureCriticalThresholdPercent
+ : kNormalMemoryPressureCriticalThresholdPercent;
+}
// Converts free percent of memory into a memory pressure value.
MemoryPressureListener::MemoryPressureLevel GetMemoryPressureLevelFromFillLevel(
- int memory_fill_level) {
- if (memory_fill_level < kMemoryPressureModerateThresholdPercent)
+ int actual_fill_level,
+ int moderate_threshold,
+ int critical_threshold) {
+ if (actual_fill_level < moderate_threshold)
return MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE;
- return memory_fill_level < kMemoryPressureCriticalThresholdPercent ?
- MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE :
- MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL;
+ return actual_fill_level < critical_threshold
+ ? MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE
+ : MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL;
}
} // namespace
-MemoryPressureObserverChromeOS::MemoryPressureObserverChromeOS()
+MemoryPressureObserverChromeOS::MemoryPressureObserverChromeOS(
+ MemoryPressureThresholds thresholds)
: current_memory_pressure_level_(
- MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE),
+ MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE),
moderate_pressure_repeat_count_(0),
+ moderate_pressure_threshold_percent_(
+ GetModerateMemoryThresholdInPercent(thresholds)),
+ critical_pressure_threshold_percent_(
+ GetCriticalMemoryThresholdInPercent(thresholds)),
weak_ptr_factory_(this) {
StartObserving();
}
@@ -74,7 +105,9 @@
MemoryPressureListener::MemoryPressureLevel old_pressure =
current_memory_pressure_level_;
current_memory_pressure_level_ =
- GetMemoryPressureLevelFromFillLevel(GetUsedMemoryInPercent());
+ GetMemoryPressureLevelFromFillLevel(GetUsedMemoryInPercent(),
+ moderate_pressure_threshold_percent_,
+ critical_pressure_threshold_percent_);
// In case there is no memory pressure we do not notify.
if (current_memory_pressure_level_ ==
MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE) {
diff --git a/base/chromeos/memory_pressure_observer_chromeos.h b/base/chromeos/memory_pressure_observer_chromeos.h
index 23b6b34..739b795 100644
--- a/base/chromeos/memory_pressure_observer_chromeos.h
+++ b/base/chromeos/memory_pressure_observer_chromeos.h
@@ -27,7 +27,27 @@
public:
using GetUsedMemoryInPercentCallback = int (*)();
- MemoryPressureObserverChromeOS();
+ // There are two memory pressure events:
+ // MODERATE - which will mainly release caches.
+ // CRITICAL - which will discard tabs.
+ // The |MemoryPressureThresholds| enum selects the strategy of firing these
+ // events: A conservative strategy will keep as much content in memory as
+ // possible (causing the system to swap to zram) and an aggressive strategy
+ // will release memory earlier to avoid swapping.
+ enum MemoryPressureThresholds {
+ // Use the system default.
+ THRESHOLD_DEFAULT = 0,
+ // Try to keep as much content in memory as possible.
+ THRESHOLD_CONSERVATIVE = 1,
+ // Discard caches earlier, allowing to keep more tabs in memory.
+ THRESHOLD_AGGRESSIVE_CACHE_DISCARD = 2,
+ // Discard tabs earlier, allowing the system to get faster.
+ THRESHOLD_AGGRESSIVE_TAB_DISCARD = 3,
+ // Discard caches and tabs earlier to allow the system to be faster.
+ THRESHOLD_AGGRESSIVE = 4
+ };
+
+ explicit MemoryPressureObserverChromeOS(MemoryPressureThresholds thresholds);
virtual ~MemoryPressureObserverChromeOS();
// Redo the memory pressure calculation soon and call again if a critical
@@ -71,6 +91,10 @@
// gets used to count the number of events since the last event occured.
int moderate_pressure_repeat_count_;
+ // The thresholds for moderate and critical pressure.
+ const int moderate_pressure_threshold_percent_;
+ const int critical_pressure_threshold_percent_;
+
base::WeakPtrFactory<MemoryPressureObserverChromeOS> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(MemoryPressureObserverChromeOS);
diff --git a/base/chromeos/memory_pressure_observer_chromeos_unittest.cc b/base/chromeos/memory_pressure_observer_chromeos_unittest.cc
index 8b28957..a227f93 100644
--- a/base/chromeos/memory_pressure_observer_chromeos_unittest.cc
+++ b/base/chromeos/memory_pressure_observer_chromeos_unittest.cc
@@ -42,7 +42,10 @@
class TestMemoryPressureObserver : public MemoryPressureObserverChromeOS {
public:
- TestMemoryPressureObserver() : memory_in_percent_override_(0) {
+ TestMemoryPressureObserver() :
+ MemoryPressureObserverChromeOS(
+ MemoryPressureObserverChromeOS::THRESHOLD_DEFAULT),
+ memory_in_percent_override_(0) {
// Disable any timers which are going on and set a special memory reporting
// function.
StopObserving();
diff --git a/base/debug/trace_event_impl.h b/base/debug/trace_event_impl.h
index c80826c..1b1fce3 100644
--- a/base/debug/trace_event_impl.h
+++ b/base/debug/trace_event_impl.h
@@ -745,7 +745,6 @@
// This lock protects accesses to thread_names_, thread_event_start_times_
// and thread_colors_.
Lock thread_info_lock_;
- int locked_line_;
Mode mode_;
int num_traces_recorded_;
scoped_ptr<TraceBuffer> logged_events_;
diff --git a/base/event_recorder.h b/base/event_recorder.h
deleted file mode 100644
index bff87ed..0000000
--- a/base/event_recorder.h
+++ /dev/null
@@ -1,109 +0,0 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef BASE_EVENT_RECORDER_H_
-#define BASE_EVENT_RECORDER_H_
-
-#include "base/base_export.h"
-#include "base/basictypes.h"
-#include "build/build_config.h"
-
-#if defined(OS_WIN)
-#include <stdio.h>
-#include <string.h>
-#include <windows.h>
-#endif
-
-namespace base {
-
-class FilePath;
-
-// A class for recording and playing back keyboard and mouse input events.
-//
-// Note - if you record events, and the playback with the windows in
-// different sizes or positions, the playback will fail. When
-// recording and playing, you should move the relevant windows
-// to constant sizes and locations.
-// TODO(mbelshe) For now this is a singleton. I believe that this class
-// could be easily modified to:
-// support two simultaneous recorders
-// be playing back events while already recording events.
-// Why? Imagine if the product had a "record a macro" feature.
-// You might be recording globally, while recording or playing back
-// a macro. I don't think two playbacks make sense.
-class BASE_EXPORT EventRecorder {
- public:
- // Get the singleton EventRecorder.
- // We can only handle one recorder/player at a time.
- static EventRecorder* current() {
- if (!current_)
- current_ = new EventRecorder();
- return current_;
- }
-
- // Starts recording events.
- // Will clobber the file if it already exists.
- // Returns true on success, or false if an error occurred.
- bool StartRecording(const FilePath& filename);
-
- // Stops recording.
- void StopRecording();
-
- // Is the EventRecorder currently recording.
- bool is_recording() const { return is_recording_; }
-
- // Plays events previously recorded.
- // Returns true on success, or false if an error occurred.
- bool StartPlayback(const FilePath& filename);
-
- // Stops playback.
- void StopPlayback();
-
- // Is the EventRecorder currently playing.
- bool is_playing() const { return is_playing_; }
-
-#if defined(OS_WIN)
- // C-style callbacks for the EventRecorder.
- // Used for internal purposes only.
- LRESULT RecordWndProc(int nCode, WPARAM wParam, LPARAM lParam);
- LRESULT PlaybackWndProc(int nCode, WPARAM wParam, LPARAM lParam);
-#endif
-
- private:
- // Create a new EventRecorder. Events are saved to the file filename.
- // If the file already exists, it will be deleted before recording
- // starts.
- EventRecorder()
- : is_recording_(false),
- is_playing_(false),
-#if defined(OS_WIN)
- journal_hook_(NULL),
- file_(NULL),
-#endif
- playback_first_msg_time_(0),
- playback_start_time_(0) {
-#if defined(OS_WIN)
- memset(&playback_msg_, 0, sizeof(playback_msg_));
-#endif
- }
- ~EventRecorder();
-
- static EventRecorder* current_; // Our singleton.
-
- bool is_recording_;
- bool is_playing_;
-#if defined(OS_WIN)
- HHOOK journal_hook_;
- FILE* file_;
- EVENTMSG playback_msg_;
-#endif
- int playback_first_msg_time_;
- int playback_start_time_;
-
- DISALLOW_COPY_AND_ASSIGN(EventRecorder);
-};
-
-} // namespace base
-
-#endif // BASE_EVENT_RECORDER_H_
diff --git a/base/event_recorder_stubs.cc b/base/event_recorder_stubs.cc
deleted file mode 100644
index 91f2e07..0000000
--- a/base/event_recorder_stubs.cc
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "base/event_recorder.h"
-
-// This file implements a link stub for EventRecorder that can be used on
-// platforms that don't have a working EventRecorder implementation.
-
-namespace base {
-
-EventRecorder* EventRecorder::current_; // Our singleton.
-
-bool EventRecorder::StartRecording(const FilePath& filename) {
- return true;
-}
-
-void EventRecorder::StopRecording() {
-}
-
-bool EventRecorder::StartPlayback(const FilePath& filename) {
- return false;
-}
-
-void EventRecorder::StopPlayback() {
-}
-
-} // namespace
diff --git a/base/event_recorder_win.cc b/base/event_recorder_win.cc
deleted file mode 100644
index b3076a1..0000000
--- a/base/event_recorder_win.cc
+++ /dev/null
@@ -1,258 +0,0 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <stddef.h>
-#include <windows.h>
-#include <mmsystem.h>
-
-#include "base/event_recorder.h"
-#include "base/files/file_util.h"
-#include "base/logging.h"
-
-// A note about time.
-// For perfect playback of events, you'd like a very accurate timer
-// so that events are played back at exactly the same time that
-// they were recorded. However, windows has a clock which is only
-// granular to ~15ms. We see more consistent event playback when
-// using a higher resolution timer. To do this, we use the
-// timeGetTime API instead of the default GetTickCount() API.
-
-namespace base {
-
-EventRecorder* EventRecorder::current_ = NULL;
-
-LRESULT CALLBACK StaticRecordWndProc(int nCode, WPARAM wParam,
- LPARAM lParam) {
- DCHECK(EventRecorder::current());
- return EventRecorder::current()->RecordWndProc(nCode, wParam, lParam);
-}
-
-LRESULT CALLBACK StaticPlaybackWndProc(int nCode, WPARAM wParam,
- LPARAM lParam) {
- DCHECK(EventRecorder::current());
- return EventRecorder::current()->PlaybackWndProc(nCode, wParam, lParam);
-}
-
-EventRecorder::~EventRecorder() {
- // Try to assert early if the caller deletes the recorder
- // while it is still in use.
- DCHECK(!journal_hook_);
- DCHECK(!is_recording_ && !is_playing_);
-}
-
-bool EventRecorder::StartRecording(const FilePath& filename) {
- if (journal_hook_ != NULL)
- return false;
- if (is_recording_ || is_playing_)
- return false;
-
- // Open the recording file.
- DCHECK(!file_);
- file_ = OpenFile(filename, "wb+");
- if (!file_) {
- DLOG(ERROR) << "EventRecorder could not open log file";
- return false;
- }
-
- // Set the faster clock, if possible.
- ::timeBeginPeriod(1);
-
- // Set the recording hook. JOURNALRECORD can only be used as a global hook.
- journal_hook_ = ::SetWindowsHookEx(WH_JOURNALRECORD, StaticRecordWndProc,
- GetModuleHandle(NULL), 0);
- if (!journal_hook_) {
- DLOG(ERROR) << "EventRecorder Record Hook failed";
- CloseFile(file_);
- return false;
- }
-
- is_recording_ = true;
- return true;
-}
-
-void EventRecorder::StopRecording() {
- if (is_recording_) {
- DCHECK(journal_hook_ != NULL);
-
- if (!::UnhookWindowsHookEx(journal_hook_)) {
- DLOG(ERROR) << "EventRecorder Unhook failed";
- // Nothing else we can really do here.
- return;
- }
-
- ::timeEndPeriod(1);
-
- DCHECK(file_ != NULL);
- CloseFile(file_);
- file_ = NULL;
-
- journal_hook_ = NULL;
- is_recording_ = false;
- }
-}
-
-bool EventRecorder::StartPlayback(const FilePath& filename) {
- if (journal_hook_ != NULL)
- return false;
- if (is_recording_ || is_playing_)
- return false;
-
- // Open the recording file.
- DCHECK(!file_);
- file_ = OpenFile(filename, "rb");
- if (!file_) {
- DLOG(ERROR) << "EventRecorder Playback could not open log file";
- return false;
- }
- // Read the first event from the record.
- if (fread(&playback_msg_, sizeof(EVENTMSG), 1, file_) != 1) {
- DLOG(ERROR) << "EventRecorder Playback has no records!";
- CloseFile(file_);
- return false;
- }
-
- // Set the faster clock, if possible.
- ::timeBeginPeriod(1);
-
- // Playback time is tricky. When playing back, we read a series of events,
- // each with timeouts. Simply subtracting the delta between two timers will
- // lead to fast playback (about 2x speed). The API has two events, one
- // which advances to the next event (HC_SKIP), and another that requests the
- // event (HC_GETNEXT). The same event will be requested multiple times.
- // Each time the event is requested, we must calculate the new delay.
- // To do this, we track the start time of the playback, and constantly
- // re-compute the delay. I mention this only because I saw two examples
- // of how to use this code on the net, and both were broken :-)
- playback_start_time_ = timeGetTime();
- playback_first_msg_time_ = playback_msg_.time;
-
- // Set the hook. JOURNALPLAYBACK can only be used as a global hook.
- journal_hook_ = ::SetWindowsHookEx(WH_JOURNALPLAYBACK, StaticPlaybackWndProc,
- GetModuleHandle(NULL), 0);
- if (!journal_hook_) {
- DLOG(ERROR) << "EventRecorder Playback Hook failed";
- return false;
- }
-
- is_playing_ = true;
-
- return true;
-}
-
-void EventRecorder::StopPlayback() {
- if (is_playing_) {
- DCHECK(journal_hook_ != NULL);
-
- if (!::UnhookWindowsHookEx(journal_hook_)) {
- DLOG(ERROR) << "EventRecorder Unhook failed";
- // Nothing else we can really do here.
- }
-
- DCHECK(file_ != NULL);
- CloseFile(file_);
- file_ = NULL;
-
- ::timeEndPeriod(1);
-
- journal_hook_ = NULL;
- is_playing_ = false;
- }
-}
-
-// Windows callback hook for the recorder.
-LRESULT EventRecorder::RecordWndProc(int nCode, WPARAM wParam, LPARAM lParam) {
- static bool recording_enabled = true;
- EVENTMSG* msg_ptr = NULL;
-
- // The API says we have to do this.
- // See http://msdn2.microsoft.com/en-us/library/ms644983(VS.85).aspx
- if (nCode < 0)
- return ::CallNextHookEx(journal_hook_, nCode, wParam, lParam);
-
- // Check for the break key being pressed and stop recording.
- if (::GetKeyState(VK_CANCEL) & 0x8000) {
- StopRecording();
- return ::CallNextHookEx(journal_hook_, nCode, wParam, lParam);
- }
-
- // The Journal Recorder must stop recording events when system modal
- // dialogs are present. (see msdn link above)
- switch (nCode) {
- case HC_SYSMODALON:
- recording_enabled = false;
- break;
- case HC_SYSMODALOFF:
- recording_enabled = true;
- break;
- }
-
- if (nCode == HC_ACTION && recording_enabled) {
- // Aha - we have an event to record.
- msg_ptr = reinterpret_cast<EVENTMSG*>(lParam);
- msg_ptr->time = timeGetTime();
- fwrite(msg_ptr, sizeof(EVENTMSG), 1, file_);
- fflush(file_);
- }
-
- return CallNextHookEx(journal_hook_, nCode, wParam, lParam);
-}
-
-// Windows callback for the playback mode.
-LRESULT EventRecorder::PlaybackWndProc(int nCode, WPARAM wParam,
- LPARAM lParam) {
- static bool playback_enabled = true;
- int delay = 0;
-
- switch (nCode) {
- // A system modal dialog box is being displayed. Stop playing back
- // messages.
- case HC_SYSMODALON:
- playback_enabled = false;
- break;
-
- // A system modal dialog box is destroyed. We can start playing back
- // messages again.
- case HC_SYSMODALOFF:
- playback_enabled = true;
- break;
-
- // Prepare to copy the next mouse or keyboard event to playback.
- case HC_SKIP:
- if (!playback_enabled)
- break;
-
- // Read the next event from the record.
- if (fread(&playback_msg_, sizeof(EVENTMSG), 1, file_) != 1)
- this->StopPlayback();
- break;
-
- // Copy the mouse or keyboard event to the EVENTMSG structure in lParam.
- case HC_GETNEXT:
- if (!playback_enabled)
- break;
-
- memcpy(reinterpret_cast<void*>(lParam), &playback_msg_,
- sizeof(playback_msg_));
-
- // The return value is the amount of time (in milliseconds) to wait
- // before playing back the next message in the playback queue. Each
- // time this is called, we recalculate the delay relative to our current
- // wall clock.
- delay = (playback_msg_.time - playback_first_msg_time_) -
- (timeGetTime() - playback_start_time_);
- if (delay < 0)
- delay = 0;
- return delay;
-
- // An application has called PeekMessage with wRemoveMsg set to PM_NOREMOVE
- // indicating that the message is not removed from the message queue after
- // PeekMessage processing.
- case HC_NOREMOVE:
- break;
- }
-
- return CallNextHookEx(journal_hook_, nCode, wParam, lParam);
-}
-
-} // namespace base
diff --git a/base/files/file_util_proxy_unittest.cc b/base/files/file_util_proxy_unittest.cc
index 17bbba8..5eb6819 100644
--- a/base/files/file_util_proxy_unittest.cc
+++ b/base/files/file_util_proxy_unittest.cc
@@ -19,8 +19,6 @@
FileUtilProxyTest()
: file_thread_("FileUtilProxyTestFileThread"),
error_(File::FILE_OK),
- created_(false),
- bytes_written_(-1),
weak_factory_(this) {}
void SetUp() override {
@@ -52,11 +50,9 @@
ScopedTempDir dir_;
File::Error error_;
- bool created_;
FilePath path_;
File::Info file_info_;
std::vector<char> buffer_;
- int bytes_written_;
WeakPtrFactory<FileUtilProxyTest> weak_factory_;
};
diff --git a/base/i18n/i18n_constants.cc b/base/i18n/i18n_constants.cc
index 9b8c571..7d2f5fc 100644
--- a/base/i18n/i18n_constants.cc
+++ b/base/i18n/i18n_constants.cc
@@ -8,8 +8,6 @@
const char kCodepageLatin1[] = "ISO-8859-1";
const char kCodepageUTF8[] = "UTF-8";
-const char kCodepageUTF16BE[] = "UTF-16BE";
-const char kCodepageUTF16LE[] = "UTF-16LE";
} // namespace base
diff --git a/base/i18n/i18n_constants.h b/base/i18n/i18n_constants.h
index c2de842..c1bd87d 100644
--- a/base/i18n/i18n_constants.h
+++ b/base/i18n/i18n_constants.h
@@ -12,8 +12,9 @@
// Names of codepages (charsets) understood by icu.
BASE_I18N_EXPORT extern const char kCodepageLatin1[]; // a.k.a. ISO 8859-1
BASE_I18N_EXPORT extern const char kCodepageUTF8[];
-BASE_I18N_EXPORT extern const char kCodepageUTF16BE[];
-BASE_I18N_EXPORT extern const char kCodepageUTF16LE[];
+
+// The other possible options are UTF-16BE and UTF-16LE, but they are unused in
+// Chromium as of this writing.
} // namespace base
diff --git a/base/message_loop/message_loop.cc b/base/message_loop/message_loop.cc
index 8180733..86771e4 100644
--- a/base/message_loop/message_loop.cc
+++ b/base/message_loop/message_loop.cc
@@ -117,8 +117,10 @@
MessageLoop::MessageLoop(Type type)
: type_(type),
+#if defined(OS_WIN)
pending_high_res_tasks_(0),
in_high_res_mode_(false),
+#endif
nestable_tasks_allowed_(true),
#if defined(OS_WIN)
os_modal_loop_(false),
@@ -133,8 +135,10 @@
MessageLoop::MessageLoop(scoped_ptr<MessagePump> pump)
: pump_(pump.Pass()),
type_(TYPE_CUSTOM),
+#if defined(OS_WIN)
pending_high_res_tasks_(0),
in_high_res_mode_(false),
+#endif
nestable_tasks_allowed_(true),
#if defined(OS_WIN)
os_modal_loop_(false),
@@ -422,10 +426,13 @@
void MessageLoop::RunTask(const PendingTask& pending_task) {
DCHECK(nestable_tasks_allowed_);
+#if defined(OS_WIN)
if (pending_task.is_high_res) {
pending_high_res_tasks_--;
- CHECK(pending_high_res_tasks_ >= 0);
+ CHECK_GE(pending_high_res_tasks_, 0);
}
+#endif
+
// Execute the task and assume the worst: It is probably not reentrant.
nestable_tasks_allowed_ = false;
@@ -495,8 +502,12 @@
// load. That reduces the number of locks-per-task significantly when our
// queues get large.
if (work_queue_.empty()) {
+#if defined(OS_WIN)
pending_high_res_tasks_ +=
incoming_task_queue_->ReloadWorkQueue(&work_queue_);
+#else
+ incoming_task_queue_->ReloadWorkQueue(&work_queue_);
+#endif
}
}
@@ -692,8 +703,8 @@
bool MessageLoopForIO::WatchFileDescriptor(int fd,
bool persistent,
Mode mode,
- FileDescriptorWatcher *controller,
- Watcher *delegate) {
+ FileDescriptorWatcher* controller,
+ Watcher* delegate) {
return ToPumpIO(pump_.get())->WatchFileDescriptor(
fd,
persistent,
diff --git a/base/message_loop/message_loop.h b/base/message_loop/message_loop.h
index 32e826d..7c76616 100644
--- a/base/message_loop/message_loop.h
+++ b/base/message_loop/message_loop.h
@@ -106,7 +106,7 @@
TYPE_IO,
#if defined(OS_ANDROID)
TYPE_JAVA,
-#endif // defined(OS_ANDROID)
+#endif // defined(OS_ANDROID)
};
// Normally, it is not necessary to instantiate a MessageLoop. Instead, it
@@ -452,6 +452,7 @@
// this queue is only accessed (push/pop) by our current thread.
TaskQueue work_queue_;
+#if defined(OS_WIN)
// How many high resolution tasks are in the pending task queue. This value
// increases by N every time we call ReloadWorkQueue() and decreases by 1
// every time we call RunTask() if the task needs a high resolution timer.
@@ -459,6 +460,7 @@
// Tracks if we have requested high resolution timers. Its only use is to
// turn off the high resolution timer upon loop destruction.
bool in_high_res_mode_;
+#endif
// Contains delayed tasks, sorted by their 'delayed_run_time' property.
DelayedTaskQueue delayed_work_queue_;
@@ -639,8 +641,8 @@
bool WatchFileDescriptor(int fd,
bool persistent,
Mode mode,
- FileDescriptorWatcher *controller,
- Watcher *delegate);
+ FileDescriptorWatcher* controller,
+ Watcher* delegate);
#endif // defined(OS_IOS) || defined(OS_POSIX)
#endif // !defined(OS_NACL_SFI)
};
diff --git a/base/message_loop/message_pump_win.cc b/base/message_loop/message_pump_win.cc
index a7a1485..a219aa6 100644
--- a/base/message_loop/message_pump_win.cc
+++ b/base/message_loop/message_pump_win.cc
@@ -352,6 +352,11 @@
}
bool MessagePumpForUI::ProcessMessageHelper(const MSG& msg) {
+ // TODO(vadimt): Remove ScopedTracker below once crbug.com/440919 is fixed.
+ tracked_objects::ScopedTracker tracking_profile1(
+ FROM_HERE_WITH_EXPLICIT_FUNCTION(
+ "440919 MessagePumpForUI::ProcessMessageHelper1"));
+
TRACE_EVENT1("base", "MessagePumpForUI::ProcessMessageHelper",
"message", msg.message);
if (WM_QUIT == msg.message) {
@@ -380,12 +385,29 @@
"440919 MessagePumpForUI::ProcessMessageHelper3"));
uint32_t action = MessagePumpDispatcher::POST_DISPATCH_PERFORM_DEFAULT;
- if (state_->dispatcher)
+ if (state_->dispatcher) {
+ // TODO(vadimt): Remove ScopedTracker below once crbug.com/440919 is fixed.
+ tracked_objects::ScopedTracker tracking_profile4(
+ FROM_HERE_WITH_EXPLICIT_FUNCTION(
+ "440919 MessagePumpForUI::ProcessMessageHelper4"));
+
action = state_->dispatcher->Dispatch(msg);
+ }
if (action & MessagePumpDispatcher::POST_DISPATCH_QUIT_LOOP)
state_->should_quit = true;
if (action & MessagePumpDispatcher::POST_DISPATCH_PERFORM_DEFAULT) {
+ // TODO(vadimt): Remove ScopedTracker below once crbug.com/440919 is fixed.
+ tracked_objects::ScopedTracker tracking_profile5(
+ FROM_HERE_WITH_EXPLICIT_FUNCTION(
+ "440919 MessagePumpForUI::ProcessMessageHelper5"));
+
TranslateMessage(&msg);
+
+ // TODO(vadimt): Remove ScopedTracker below once crbug.com/440919 is fixed.
+ tracked_objects::ScopedTracker tracking_profile6(
+ FROM_HERE_WITH_EXPLICIT_FUNCTION(
+ "440919 MessagePumpForUI::ProcessMessageHelper6"));
+
DispatchMessage(&msg);
}
diff --git a/base/process/launch.h b/base/process/launch.h
index eca4f8f..de1bc0a 100644
--- a/base/process/launch.h
+++ b/base/process/launch.h
@@ -291,6 +291,25 @@
// binary. This should not be called in production/released code.
BASE_EXPORT LaunchOptions LaunchOptionsForTest();
+#if defined(OS_LINUX)
+// A wrapper for clone with fork-like behavior, meaning that it returns the
+// child's pid in the parent and 0 in the child. |flags|, |ptid|, and |ctid| are
+// as in the clone system call (the CLONE_VM flag is not supported).
+//
+// This function uses the libc clone wrapper (which updates libc's pid cache)
+// internally, so callers may expect things like getpid() to work correctly
+// after in both the child and parent. An exception is when this code is run
+// under Valgrind. Valgrind does not support the libc clone wrapper, so the libc
+// pid cache may be incorrect after this function is called under Valgrind.
+//
+// As with fork(), callers should be extremely careful when calling this while
+// multiple threads are running, since at the time the fork happened, the
+// threads could have been in any state (potentially holding locks, etc.).
+// Callers should most likely call execve() in the child soon after calling
+// this.
+BASE_EXPORT pid_t ForkWithFlags(unsigned long flags, pid_t* ptid, pid_t* ctid);
+#endif
+
} // namespace base
#endif // BASE_PROCESS_LAUNCH_H_
diff --git a/base/process/launch_posix.cc b/base/process/launch_posix.cc
index 6c9ed3f..ce93d50 100644
--- a/base/process/launch_posix.cc
+++ b/base/process/launch_posix.cc
@@ -7,9 +7,12 @@
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
+#include <sched.h>
+#include <setjmp.h>
#include <signal.h>
#include <stdlib.h>
#include <sys/resource.h>
+#include <sys/syscall.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/wait.h>
@@ -35,8 +38,10 @@
#include "base/strings/stringprintf.h"
#include "base/synchronization/waitable_event.h"
#include "base/third_party/dynamic_annotations/dynamic_annotations.h"
+#include "base/third_party/valgrind/valgrind.h"
#include "base/threading/platform_thread.h"
#include "base/threading/thread_restrictions.h"
+#include "build/build_config.h"
#if defined(OS_LINUX)
#include <sys/prctl.h>
@@ -184,6 +189,54 @@
#endif // !defined(OS_LINUX) ||
// (!defined(__i386__) && !defined(__x86_64__) && !defined(__arm__))
+#if defined(OS_LINUX)
+bool IsRunningOnValgrind() {
+ return RUNNING_ON_VALGRIND;
+}
+
+// This function runs on the stack specified on the clone call. It uses longjmp
+// to switch back to the original stack so the child can return from sys_clone.
+int CloneHelper(void* arg) {
+ jmp_buf* env_ptr = reinterpret_cast<jmp_buf*>(arg);
+ longjmp(*env_ptr, 1);
+
+ // Should not be reached.
+ RAW_CHECK(false);
+ return 1;
+}
+
+// This function is noinline to ensure that stack_buf is below the stack pointer
+// that is saved when setjmp is called below. This is needed because when
+// compiled with FORTIFY_SOURCE, glibc's longjmp checks that the stack is moved
+// upwards. See crbug.com/442912 for more details.
+#if defined(ADDRESS_SANITIZER)
+// Disable AddressSanitizer instrumentation for this function to make sure
+// |stack_buf| is allocated on thread stack instead of ASan's fake stack.
+// Under ASan longjmp() will attempt to clean up the area between the old and
+// new stack pointers and print a warning that may confuse the user.
+__attribute__((no_sanitize_address))
+#endif
+NOINLINE pid_t CloneAndLongjmpInChild(unsigned long flags,
+ pid_t* ptid,
+ pid_t* ctid,
+ jmp_buf* env) {
+ // We use the libc clone wrapper instead of making the syscall
+ // directly because making the syscall may fail to update the libc's
+ // internal pid cache. The libc interface unfortunately requires
+ // specifying a new stack, so we use setjmp/longjmp to emulate
+ // fork-like behavior.
+ char stack_buf[PTHREAD_STACK_MIN];
+#if defined(ARCH_CPU_X86_FAMILY) || defined(ARCH_CPU_ARM_FAMILY) || \
+ defined(ARCH_CPU_MIPS64_FAMILY) || defined(ARCH_CPU_MIPS_FAMILY)
+ // The stack grows downward.
+ void* stack = stack_buf + sizeof(stack_buf);
+#else
+#error "Unsupported architecture"
+#endif
+ return clone(&CloneHelper, stack, flags, env, ptid, nullptr, ctid);
+}
+#endif // defined(OS_LINUX)
+
} // anonymous namespace
// Functor for |ScopedDIR| (below).
@@ -671,4 +724,45 @@
return result == EXECUTE_SUCCESS;
}
+#if defined(OS_LINUX)
+pid_t ForkWithFlags(unsigned long flags, pid_t* ptid, pid_t* ctid) {
+ const bool clone_tls_used = flags & CLONE_SETTLS;
+ const bool invalid_ctid =
+ (flags & (CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID)) && !ctid;
+ const bool invalid_ptid = (flags & CLONE_PARENT_SETTID) && !ptid;
+
+ // We do not support CLONE_VM.
+ const bool clone_vm_used = flags & CLONE_VM;
+
+ if (clone_tls_used || invalid_ctid || invalid_ptid || clone_vm_used) {
+ RAW_LOG(FATAL, "Invalid usage of ForkWithFlags");
+ }
+
+ // Valgrind's clone implementation does not support specifiying a child_stack
+ // without CLONE_VM, so we cannot use libc's clone wrapper when running under
+ // Valgrind. As a result, the libc pid cache may be incorrect under Valgrind.
+ // See crbug.com/442817 for more details.
+ if (IsRunningOnValgrind()) {
+ // See kernel/fork.c in Linux. There is different ordering of sys_clone
+ // parameters depending on CONFIG_CLONE_BACKWARDS* configuration options.
+#if defined(ARCH_CPU_X86_64)
+ return syscall(__NR_clone, flags, nullptr, ptid, ctid, nullptr);
+#elif defined(ARCH_CPU_X86) || defined(ARCH_CPU_ARM_FAMILY) || \
+ defined(ARCH_CPU_MIPS_FAMILY) || defined(ARCH_CPU_MIPS64_FAMILY)
+ // CONFIG_CLONE_BACKWARDS defined.
+ return syscall(__NR_clone, flags, nullptr, ptid, nullptr, ctid);
+#else
+#error "Unsupported architecture"
+#endif
+ }
+
+ jmp_buf env;
+ if (setjmp(env) == 0) {
+ return CloneAndLongjmpInChild(flags, ptid, ctid, &env);
+ }
+
+ return 0;
+}
+#endif // defined(OS_LINUX)
+
} // namespace base
diff --git a/base/process/process.h b/base/process/process.h
index b0fd8d9..d556d8e 100644
--- a/base/process/process.h
+++ b/base/process/process.h
@@ -117,25 +117,6 @@
#endif
};
-#if defined(OS_LINUX)
-// A wrapper for clone with fork-like behavior, meaning that it returns the
-// child's pid in the parent and 0 in the child. |flags|, |ptid|, and |ctid| are
-// as in the clone system call (the CLONE_VM flag is not supported).
-//
-// This function uses the libc clone wrapper (which updates libc's pid cache)
-// internally, so callers may expect things like getpid() to work correctly
-// after in both the child and parent. An exception is when this code is run
-// under Valgrind. Valgrind does not support the libc clone wrapper, so the libc
-// pid cache may be incorrect after this function is called under Valgrind.
-//
-// As with fork(), callers should be extremely careful when calling this while
-// multiple threads are running, since at the time the fork happened, the
-// threads could have been in any state (potentially holding locks, etc.).
-// Callers should most likely call execve() in the child soon after calling
-// this.
-BASE_EXPORT pid_t ForkWithFlags(unsigned long flags, pid_t* ptid, pid_t* ctid);
-#endif
-
} // namespace base
#endif // BASE_PROCESS_PROCESS_PROCESS_H_
diff --git a/base/process/process_linux.cc b/base/process/process_linux.cc
index cfa3ed5..59ee288 100644
--- a/base/process/process_linux.cc
+++ b/base/process/process_linux.cc
@@ -5,21 +5,14 @@
#include "base/process/process.h"
#include <errno.h>
-#include <pthread.h>
-#include <sched.h>
-#include <setjmp.h>
#include <sys/resource.h>
-#include <sys/syscall.h>
-#include "base/compiler_specific.h"
#include "base/files/file_util.h"
#include "base/lazy_instance.h"
#include "base/logging.h"
#include "base/strings/string_split.h"
#include "base/strings/stringprintf.h"
#include "base/synchronization/lock.h"
-#include "base/third_party/valgrind/valgrind.h"
-#include "build/build_config.h"
namespace base {
@@ -85,52 +78,6 @@
bool can_reraise_priority;
};
-bool IsRunningOnValgrind() {
- return RUNNING_ON_VALGRIND;
-}
-
-// This function runs on the stack specified on the clone call. It uses longjmp
-// to switch back to the original stack so the child can return from sys_clone.
-int CloneHelper(void* arg) {
- jmp_buf* env_ptr = reinterpret_cast<jmp_buf*>(arg);
- longjmp(*env_ptr, 1);
-
- // Should not be reached.
- RAW_CHECK(false);
- return 1;
-}
-
-// This function is noinline to ensure that stack_buf is below the stack pointer
-// that is saved when setjmp is called below. This is needed because when
-// compiled with FORTIFY_SOURCE, glibc's longjmp checks that the stack is moved
-// upwards. See crbug.com/442912 for more details.
-#if defined(ADDRESS_SANITIZER)
-// Disable AddressSanitizer instrumentation for this function to make sure
-// |stack_buf| is allocated on thread stack instead of ASan's fake stack.
-// Under ASan longjmp() will attempt to clean up the area between the old and
-// new stack pointers and print a warning that may confuse the user.
-__attribute__((no_sanitize_address))
-#endif
-NOINLINE pid_t CloneAndLongjmpInChild(unsigned long flags,
- pid_t* ptid,
- pid_t* ctid,
- jmp_buf* env) {
- // We use the libc clone wrapper instead of making the syscall
- // directly because making the syscall may fail to update the libc's
- // internal pid cache. The libc interface unfortunately requires
- // specifying a new stack, so we use setjmp/longjmp to emulate
- // fork-like behavior.
- char stack_buf[PTHREAD_STACK_MIN];
-#if defined(ARCH_CPU_X86_FAMILY) || defined(ARCH_CPU_ARM_FAMILY) || \
- defined(ARCH_CPU_MIPS64_FAMILY) || defined(ARCH_CPU_MIPS_FAMILY)
- // The stack grows downward.
- void* stack = stack_buf + sizeof(stack_buf);
-#else
-#error "Unsupported architecture"
-#endif
- return clone(&CloneHelper, stack, flags, env, ptid, nullptr, ctid);
-}
-
} // namespace
// static
@@ -189,43 +136,4 @@
return result == 0;
}
-pid_t ForkWithFlags(unsigned long flags, pid_t* ptid, pid_t* ctid) {
- const bool clone_tls_used = flags & CLONE_SETTLS;
- const bool invalid_ctid =
- (flags & (CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID)) && !ctid;
- const bool invalid_ptid = (flags & CLONE_PARENT_SETTID) && !ptid;
-
- // We do not support CLONE_VM.
- const bool clone_vm_used = flags & CLONE_VM;
-
- if (clone_tls_used || invalid_ctid || invalid_ptid || clone_vm_used) {
- RAW_LOG(FATAL, "Invalid usage of ForkWithFlags");
- }
-
- // Valgrind's clone implementation does not support specifiying a child_stack
- // without CLONE_VM, so we cannot use libc's clone wrapper when running under
- // Valgrind. As a result, the libc pid cache may be incorrect under Valgrind.
- // See crbug.com/442817 for more details.
- if (IsRunningOnValgrind()) {
- // See kernel/fork.c in Linux. There is different ordering of sys_clone
- // parameters depending on CONFIG_CLONE_BACKWARDS* configuration options.
-#if defined(ARCH_CPU_X86_64)
- return syscall(__NR_clone, flags, nullptr, ptid, ctid, nullptr);
-#elif defined(ARCH_CPU_X86) || defined(ARCH_CPU_ARM_FAMILY) || \
- defined(ARCH_CPU_MIPS_FAMILY) || defined(ARCH_CPU_MIPS64_FAMILY)
- // CONFIG_CLONE_BACKWARDS defined.
- return syscall(__NR_clone, flags, nullptr, ptid, nullptr, ctid);
-#else
-#error "Unsupported architecture"
-#endif
- }
-
- jmp_buf env;
- if (setjmp(env) == 0) {
- return CloneAndLongjmpInChild(flags, ptid, ctid, &env);
- }
-
- return 0;
-}
-
} // namespace base
diff --git a/base/process/process_metrics.h b/base/process/process_metrics.h
index d06e018..d011958 100644
--- a/base/process/process_metrics.h
+++ b/base/process/process_metrics.h
@@ -85,17 +85,6 @@
size_t image;
};
-// Free memory (Megabytes marked as free) in the 2G process address space.
-// total : total amount in megabytes marked as free. Maximum value is 2048.
-// largest : size of the largest contiguous amount of memory found. It is
-// always smaller or equal to FreeMBytes::total.
-// largest_ptr: starting address of the largest memory block.
-struct FreeMBytes {
- size_t total;
- size_t largest;
- void* largest_ptr;
-};
-
// Convert a POSIX timeval to microseconds.
BASE_EXPORT int64 TimeValToMicroseconds(const struct timeval& tv);
diff --git a/base/process/process_unittest.cc b/base/process/process_unittest.cc
index 8130726..1a2af50 100644
--- a/base/process/process_unittest.cc
+++ b/base/process/process_unittest.cc
@@ -4,28 +4,13 @@
#include "base/process/process.h"
-#include "base/files/file_path.h"
-#include "base/files/file_util.h"
-#include "base/files/scoped_file.h"
-#include "base/posix/eintr_wrapper.h"
#include "base/process/kill.h"
#include "base/test/multiprocess_test.h"
#include "base/test/test_timeouts.h"
-#include "base/third_party/dynamic_annotations/dynamic_annotations.h"
#include "base/threading/platform_thread.h"
-#include "build/build_config.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/multiprocess_func_list.h"
-#if defined(OS_LINUX)
-#include <errno.h>
-#include <sched.h>
-#include <sys/syscall.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <unistd.h>
-#endif
-
namespace {
#if defined(OS_WIN)
@@ -215,105 +200,4 @@
EXPECT_EQ(old_priority, new_priority);
}
-#if defined(OS_LINUX)
-const int kSuccess = 0;
-
-MULTIPROCESS_TEST_MAIN(CheckPidProcess) {
- const pid_t kInitPid = 1;
- const pid_t pid = syscall(__NR_getpid);
- CHECK(pid == kInitPid);
- CHECK(getpid() == pid);
- return kSuccess;
-}
-
-TEST_F(ProcessTest, CloneFlags) {
- if (RunningOnValgrind() || !PathExists(FilePath("/proc/self/ns/user")) ||
- !PathExists(FilePath("/proc/self/ns/pid"))) {
- // User or PID namespaces are not supported.
- return;
- }
-
- LaunchOptions options;
- options.clone_flags = CLONE_NEWUSER | CLONE_NEWPID;
-
- Process process(SpawnChildWithOptions("CheckPidProcess", options));
- ASSERT_TRUE(process.IsValid());
-
- int exit_code = 42;
- EXPECT_TRUE(process.WaitForExit(&exit_code));
- EXPECT_EQ(kSuccess, exit_code);
-}
-
-TEST(ForkWithFlagsTest, UpdatesPidCache) {
- // The libc clone function, which allows ForkWithFlags to keep the pid cache
- // up to date, does not work on Valgrind.
- if (RunningOnValgrind()) {
- return;
- }
-
- // Warm up the libc pid cache, if there is one.
- ASSERT_EQ(syscall(__NR_getpid), getpid());
-
- pid_t ctid = 0;
- const pid_t pid = ForkWithFlags(SIGCHLD | CLONE_CHILD_SETTID, nullptr, &ctid);
- if (pid == 0) {
- // In child. Check both the raw getpid syscall and the libc getpid wrapper
- // (which may rely on a pid cache).
- RAW_CHECK(syscall(__NR_getpid) == ctid);
- RAW_CHECK(getpid() == ctid);
- _exit(kSuccess);
- }
-
- ASSERT_NE(-1, pid);
- int status = 42;
- ASSERT_EQ(pid, HANDLE_EINTR(waitpid(pid, &status, 0)));
- ASSERT_TRUE(WIFEXITED(status));
- EXPECT_EQ(kSuccess, WEXITSTATUS(status));
-}
-#endif
-
-#if defined(OS_POSIX) && !defined(OS_ANDROID)
-const char kPipeValue = '\xcc';
-
-class ReadFromPipeDelegate : public LaunchOptions::PreExecDelegate {
- public:
- explicit ReadFromPipeDelegate(int fd) : fd_(fd) {}
- ~ReadFromPipeDelegate() override {}
- void RunAsyncSafe() override {
- char c;
- RAW_CHECK(HANDLE_EINTR(read(fd_, &c, 1)) == 1);
- RAW_CHECK(IGNORE_EINTR(close(fd_)) == 0);
- RAW_CHECK(c == kPipeValue);
- }
-
- private:
- int fd_;
- DISALLOW_COPY_AND_ASSIGN(ReadFromPipeDelegate);
-};
-
-TEST_F(ProcessTest, PreExecHook) {
- int pipe_fds[2];
- ASSERT_EQ(0, pipe(pipe_fds));
-
- ScopedFD read_fd(pipe_fds[0]);
- ScopedFD write_fd(pipe_fds[1]);
- base::FileHandleMappingVector fds_to_remap;
- fds_to_remap.push_back(std::make_pair(read_fd.get(), read_fd.get()));
-
- ReadFromPipeDelegate read_from_pipe_delegate(read_fd.get());
- LaunchOptions options;
- options.fds_to_remap = &fds_to_remap;
- options.pre_exec_delegate = &read_from_pipe_delegate;
- Process process(SpawnChildWithOptions("SimpleChildProcess", options));
- ASSERT_TRUE(process.IsValid());
-
- read_fd.reset();
- ASSERT_EQ(1, HANDLE_EINTR(write(write_fd.get(), &kPipeValue, 1)));
-
- int exit_code = 42;
- EXPECT_TRUE(process.WaitForExit(&exit_code));
- EXPECT_EQ(0, exit_code);
-}
-#endif // defined(OS_POSIX) && !defined(OS_ANDROID)
-
} // namespace base
diff --git a/base/process/process_util_unittest.cc b/base/process/process_util_unittest.cc
index 4b2a575..88b4af3 100644
--- a/base/process/process_util_unittest.cc
+++ b/base/process/process_util_unittest.cc
@@ -10,6 +10,8 @@
#include "base/debug/alias.h"
#include "base/debug/stack_trace.h"
#include "base/files/file_path.h"
+#include "base/files/file_util.h"
+#include "base/files/scoped_file.h"
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "base/path_service.h"
@@ -27,21 +29,26 @@
#include "base/third_party/dynamic_annotations/dynamic_annotations.h"
#include "base/threading/platform_thread.h"
#include "base/threading/thread.h"
+#include "build/build_config.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/multiprocess_func_list.h"
#if defined(OS_LINUX)
#include <malloc.h>
#include <sched.h>
+#include <sys/syscall.h>
#endif
#if defined(OS_POSIX)
#include <dlfcn.h>
#include <errno.h>
#include <fcntl.h>
+#include <sched.h>
#include <signal.h>
#include <sys/resource.h>
#include <sys/socket.h>
+#include <sys/types.h>
#include <sys/wait.h>
+#include <unistd.h>
#endif
#if defined(OS_WIN)
#include <windows.h>
@@ -913,4 +920,107 @@
return 0;
}
+#if !defined(OS_ANDROID)
+const char kPipeValue = '\xcc';
+
+class ReadFromPipeDelegate : public base::LaunchOptions::PreExecDelegate {
+ public:
+ explicit ReadFromPipeDelegate(int fd) : fd_(fd) {}
+ ~ReadFromPipeDelegate() override {}
+ void RunAsyncSafe() override {
+ char c;
+ RAW_CHECK(HANDLE_EINTR(read(fd_, &c, 1)) == 1);
+ RAW_CHECK(IGNORE_EINTR(close(fd_)) == 0);
+ RAW_CHECK(c == kPipeValue);
+ }
+
+ private:
+ int fd_;
+ DISALLOW_COPY_AND_ASSIGN(ReadFromPipeDelegate);
+};
+
+TEST_F(ProcessUtilTest, PreExecHook) {
+ int pipe_fds[2];
+ ASSERT_EQ(0, pipe(pipe_fds));
+
+ base::ScopedFD read_fd(pipe_fds[0]);
+ base::ScopedFD write_fd(pipe_fds[1]);
+ base::FileHandleMappingVector fds_to_remap;
+ fds_to_remap.push_back(std::make_pair(read_fd.get(), read_fd.get()));
+
+ ReadFromPipeDelegate read_from_pipe_delegate(read_fd.get());
+ base::LaunchOptions options;
+ options.fds_to_remap = &fds_to_remap;
+ options.pre_exec_delegate = &read_from_pipe_delegate;
+ base::Process process(SpawnChildWithOptions("SimpleChildProcess", options));
+ ASSERT_TRUE(process.IsValid());
+
+ read_fd.reset();
+ ASSERT_EQ(1, HANDLE_EINTR(write(write_fd.get(), &kPipeValue, 1)));
+
+ int exit_code = 42;
+ EXPECT_TRUE(process.WaitForExit(&exit_code));
+ EXPECT_EQ(0, exit_code);
+}
+#endif // !defined(OS_ANDROID)
+
#endif // defined(OS_POSIX)
+
+#if defined(OS_LINUX)
+const int kSuccess = 0;
+
+MULTIPROCESS_TEST_MAIN(CheckPidProcess) {
+ const pid_t kInitPid = 1;
+ const pid_t pid = syscall(__NR_getpid);
+ CHECK(pid == kInitPid);
+ CHECK(getpid() == pid);
+ return kSuccess;
+}
+
+TEST_F(ProcessUtilTest, CloneFlags) {
+ if (RunningOnValgrind() ||
+ !base::PathExists(FilePath("/proc/self/ns/user")) ||
+ !base::PathExists(FilePath("/proc/self/ns/pid"))) {
+ // User or PID namespaces are not supported.
+ return;
+ }
+
+ base::LaunchOptions options;
+ options.clone_flags = CLONE_NEWUSER | CLONE_NEWPID;
+
+ base::Process process(SpawnChildWithOptions("CheckPidProcess", options));
+ ASSERT_TRUE(process.IsValid());
+
+ int exit_code = 42;
+ EXPECT_TRUE(process.WaitForExit(&exit_code));
+ EXPECT_EQ(kSuccess, exit_code);
+}
+
+TEST(ForkWithFlagsTest, UpdatesPidCache) {
+ // The libc clone function, which allows ForkWithFlags to keep the pid cache
+ // up to date, does not work on Valgrind.
+ if (RunningOnValgrind()) {
+ return;
+ }
+
+ // Warm up the libc pid cache, if there is one.
+ ASSERT_EQ(syscall(__NR_getpid), getpid());
+
+ pid_t ctid = 0;
+ const pid_t pid =
+ base::ForkWithFlags(SIGCHLD | CLONE_CHILD_SETTID, nullptr, &ctid);
+ if (pid == 0) {
+ // In child. Check both the raw getpid syscall and the libc getpid wrapper
+ // (which may rely on a pid cache).
+ RAW_CHECK(syscall(__NR_getpid) == ctid);
+ RAW_CHECK(getpid() == ctid);
+ _exit(kSuccess);
+ }
+
+ ASSERT_NE(-1, pid);
+ int status = 42;
+ ASSERT_EQ(pid, HANDLE_EINTR(waitpid(pid, &status, 0)));
+ ASSERT_TRUE(WIFEXITED(status));
+ EXPECT_EQ(kSuccess, WEXITSTATUS(status));
+}
+#endif
diff --git a/base/test/android/javatests/src/org/chromium/base/test/util/MetricsUtils.java b/base/test/android/javatests/src/org/chromium/base/test/util/MetricsUtils.java
new file mode 100644
index 0000000..c4664d6
--- /dev/null
+++ b/base/test/android/javatests/src/org/chromium/base/test/util/MetricsUtils.java
@@ -0,0 +1,43 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.base.test.util;
+
+import org.chromium.base.metrics.RecordHistogram;
+
+/**
+ * Helpers for testing UMA metrics.
+ */
+public class MetricsUtils {
+ /**
+ * Helper class that snapshots the given bucket of the given UMA histogram on its creation,
+ * allowing to inspect the number of samples recorded during its lifetime.
+ */
+ public static class HistogramDelta {
+ private final String mHistogram;
+ private final int mSampleValue;
+
+ private final int mInitialCount;
+
+ private int get() {
+ return RecordHistogram.getHistogramValueCountForTesting(mHistogram, mSampleValue);
+ }
+
+ /**
+ * Snapshots the given bucket of the given histogram.
+ * @param histogram name of the histogram to snapshot
+ * @param sampleValue the bucket that contains this value will be snapshot
+ */
+ public HistogramDelta(String histogram, int sampleValue) {
+ mHistogram = histogram;
+ mSampleValue = sampleValue;
+ mInitialCount = get();
+ }
+
+ /** Returns the number of samples of the snapshot bucket recorded since creation */
+ public int getDelta() {
+ return get() - mInitialCount;
+ }
+ }
+}
diff --git a/base/test/launcher/unit_test_launcher.cc b/base/test/launcher/unit_test_launcher.cc
index 9a8b41f..a31b6db 100644
--- a/base/test/launcher/unit_test_launcher.cc
+++ b/base/test/launcher/unit_test_launcher.cc
@@ -244,325 +244,302 @@
bool UnitTestLauncherDelegate::ShouldRunTest(const std::string& test_case_name,
const std::string& test_name) {
- DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK(thread_checker_.CalledOnValidThread());
- // There is no additional logic to disable specific tests.
- return true;
+ // There is no additional logic to disable specific tests.
+ return true;
+}
+
+size_t UnitTestLauncherDelegate::RunTests(
+ TestLauncher* test_launcher,
+ const std::vector<std::string>& test_names) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+
+ std::vector<std::string> batch;
+ for (size_t i = 0; i < test_names.size(); i++) {
+ batch.push_back(test_names[i]);
+
+ if (batch.size() >= batch_limit_) {
+ RunBatch(test_launcher, batch);
+ batch.clear();
+ }
}
- size_t UnitTestLauncherDelegate::RunTests(
- TestLauncher* test_launcher,
- const std::vector<std::string>& test_names) {
- DCHECK(thread_checker_.CalledOnValidThread());
+ RunBatch(test_launcher, batch);
+ return test_names.size();
+}
+
+size_t UnitTestLauncherDelegate::RetryTests(
+ TestLauncher* test_launcher,
+ const std::vector<std::string>& test_names) {
+ MessageLoop::current()->PostTask(
+ FROM_HERE, Bind(&UnitTestLauncherDelegate::RunSerially, Unretained(this),
+ test_launcher, test_names));
+ return test_names.size();
+}
+
+void UnitTestLauncherDelegate::RunSerially(
+ TestLauncher* test_launcher,
+ const std::vector<std::string>& test_names) {
+ if (test_names.empty())
+ return;
+
+ std::vector<std::string> new_test_names(test_names);
+ std::string test_name(new_test_names.back());
+ new_test_names.pop_back();
+
+ // Create a dedicated temporary directory to store the xml result data
+ // per run to ensure clean state and make it possible to launch multiple
+ // processes in parallel.
+ base::FilePath output_file;
+ CHECK(CreateNewTempDirectory(FilePath::StringType(), &output_file));
+ output_file = output_file.AppendASCII("test_results.xml");
+
+ std::vector<std::string> current_test_names;
+ current_test_names.push_back(test_name);
+ CommandLine cmd_line(
+ GetCommandLineForChildGTestProcess(current_test_names, output_file));
+
+ GTestCallbackState callback_state;
+ callback_state.test_launcher = test_launcher;
+ callback_state.test_names = current_test_names;
+ callback_state.output_file = output_file;
+
+ test_launcher->LaunchChildGTestProcess(
+ cmd_line, std::string(), TestTimeouts::test_launcher_timeout(),
+ use_job_objects_ ? TestLauncher::USE_JOB_OBJECTS : 0,
+ Bind(&UnitTestLauncherDelegate::SerialGTestCallback, Unretained(this),
+ callback_state, new_test_names));
+}
+
+void UnitTestLauncherDelegate::RunBatch(
+ TestLauncher* test_launcher,
+ const std::vector<std::string>& test_names) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+
+ if (test_names.empty())
+ return;
+
+ // Create a dedicated temporary directory to store the xml result data
+ // per run to ensure clean state and make it possible to launch multiple
+ // processes in parallel.
+ base::FilePath output_file;
+ CHECK(CreateNewTempDirectory(FilePath::StringType(), &output_file));
+ output_file = output_file.AppendASCII("test_results.xml");
+
+ CommandLine cmd_line(
+ GetCommandLineForChildGTestProcess(test_names, output_file));
+
+ // Adjust the timeout depending on how many tests we're running
+ // (note that e.g. the last batch of tests will be smaller).
+ // TODO(phajdan.jr): Consider an adaptive timeout, which can change
+ // depending on how many tests ran and how many remain.
+ // Note: do NOT parse child's stdout to do that, it's known to be
+ // unreliable (e.g. buffering issues can mix up the output).
+ base::TimeDelta timeout =
+ test_names.size() * TestTimeouts::test_launcher_timeout();
+
+ GTestCallbackState callback_state;
+ callback_state.test_launcher = test_launcher;
+ callback_state.test_names = test_names;
+ callback_state.output_file = output_file;
+
+ test_launcher->LaunchChildGTestProcess(
+ cmd_line, std::string(), timeout,
+ use_job_objects_ ? TestLauncher::USE_JOB_OBJECTS : 0,
+ Bind(&UnitTestLauncherDelegate::GTestCallback, Unretained(this),
+ callback_state));
+}
+
+void UnitTestLauncherDelegate::GTestCallback(
+ const GTestCallbackState& callback_state,
+ int exit_code,
+ const TimeDelta& elapsed_time,
+ bool was_timeout,
+ const std::string& output) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ std::vector<std::string> tests_to_relaunch;
+ ProcessTestResults(callback_state.test_launcher, callback_state.test_names,
+ callback_state.output_file, output, exit_code, was_timeout,
+ &tests_to_relaunch);
+
+ // Relaunch requested tests in parallel, but only use single
+ // test per batch for more precise results (crashes, test passes
+ // but non-zero exit codes etc).
+ for (size_t i = 0; i < tests_to_relaunch.size(); i++) {
std::vector<std::string> batch;
+ batch.push_back(tests_to_relaunch[i]);
+ RunBatch(callback_state.test_launcher, batch);
+ }
+
+ // The temporary file's directory is also temporary.
+ DeleteFile(callback_state.output_file.DirName(), true);
+}
+
+void UnitTestLauncherDelegate::SerialGTestCallback(
+ const GTestCallbackState& callback_state,
+ const std::vector<std::string>& test_names,
+ int exit_code,
+ const TimeDelta& elapsed_time,
+ bool was_timeout,
+ const std::string& output) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ std::vector<std::string> tests_to_relaunch;
+ bool called_any_callbacks =
+ ProcessTestResults(callback_state.test_launcher,
+ callback_state.test_names, callback_state.output_file,
+ output, exit_code, was_timeout, &tests_to_relaunch);
+
+ // There is only one test, there cannot be other tests to relaunch
+ // due to a crash.
+ DCHECK(tests_to_relaunch.empty());
+
+ // There is only one test, we should have called back with its result.
+ DCHECK(called_any_callbacks);
+
+ // The temporary file's directory is also temporary.
+ DeleteFile(callback_state.output_file.DirName(), true);
+
+ MessageLoop::current()->PostTask(
+ FROM_HERE, Bind(&UnitTestLauncherDelegate::RunSerially, Unretained(this),
+ callback_state.test_launcher, test_names));
+}
+
+// static
+bool UnitTestLauncherDelegate::ProcessTestResults(
+ TestLauncher* test_launcher,
+ const std::vector<std::string>& test_names,
+ const base::FilePath& output_file,
+ const std::string& output,
+ int exit_code,
+ bool was_timeout,
+ std::vector<std::string>* tests_to_relaunch) {
+ std::vector<TestResult> test_results;
+ bool crashed = false;
+ bool have_test_results =
+ ProcessGTestOutput(output_file, &test_results, &crashed);
+
+ bool called_any_callback = false;
+
+ if (have_test_results) {
+ // TODO(phajdan.jr): Check for duplicates and mismatches between
+ // the results we got from XML file and tests we intended to run.
+ std::map<std::string, TestResult> results_map;
+ for (size_t i = 0; i < test_results.size(); i++)
+ results_map[test_results[i].full_name] = test_results[i];
+
+ bool had_interrupted_test = false;
+
+ // Results to be reported back to the test launcher.
+ std::vector<TestResult> final_results;
+
for (size_t i = 0; i < test_names.size(); i++) {
- batch.push_back(test_names[i]);
+ if (ContainsKey(results_map, test_names[i])) {
+ TestResult test_result = results_map[test_names[i]];
+ if (test_result.status == TestResult::TEST_CRASH) {
+ had_interrupted_test = true;
- if (batch.size() >= batch_limit_) {
- RunBatch(test_launcher, batch);
- batch.clear();
- }
- }
-
- RunBatch(test_launcher, batch);
-
- return test_names.size();
- }
-
- size_t UnitTestLauncherDelegate::RetryTests(
- TestLauncher* test_launcher,
- const std::vector<std::string>& test_names) {
- MessageLoop::current()->PostTask(
- FROM_HERE,
- Bind(&UnitTestLauncherDelegate::RunSerially,
- Unretained(this),
- test_launcher,
- test_names));
- return test_names.size();
- }
-
- void UnitTestLauncherDelegate::RunSerially(
- TestLauncher* test_launcher,
- const std::vector<std::string>& test_names) {
- if (test_names.empty())
- return;
-
- std::vector<std::string> new_test_names(test_names);
- std::string test_name(new_test_names.back());
- new_test_names.pop_back();
-
- // Create a dedicated temporary directory to store the xml result data
- // per run to ensure clean state and make it possible to launch multiple
- // processes in parallel.
- base::FilePath output_file;
- CHECK(CreateNewTempDirectory(FilePath::StringType(), &output_file));
- output_file = output_file.AppendASCII("test_results.xml");
-
- std::vector<std::string> current_test_names;
- current_test_names.push_back(test_name);
- CommandLine cmd_line(
- GetCommandLineForChildGTestProcess(current_test_names, output_file));
-
- GTestCallbackState callback_state;
- callback_state.test_launcher = test_launcher;
- callback_state.test_names = current_test_names;
- callback_state.output_file = output_file;
-
- test_launcher->LaunchChildGTestProcess(
- cmd_line,
- std::string(),
- TestTimeouts::test_launcher_timeout(),
- use_job_objects_ ? TestLauncher::USE_JOB_OBJECTS : 0,
- Bind(&UnitTestLauncherDelegate::SerialGTestCallback,
- Unretained(this),
- callback_state,
- new_test_names));
- }
-
- void UnitTestLauncherDelegate::RunBatch(
- TestLauncher* test_launcher,
- const std::vector<std::string>& test_names) {
- DCHECK(thread_checker_.CalledOnValidThread());
-
- if (test_names.empty())
- return;
-
- // Create a dedicated temporary directory to store the xml result data
- // per run to ensure clean state and make it possible to launch multiple
- // processes in parallel.
- base::FilePath output_file;
- CHECK(CreateNewTempDirectory(FilePath::StringType(), &output_file));
- output_file = output_file.AppendASCII("test_results.xml");
-
- CommandLine cmd_line(
- GetCommandLineForChildGTestProcess(test_names, output_file));
-
- // Adjust the timeout depending on how many tests we're running
- // (note that e.g. the last batch of tests will be smaller).
- // TODO(phajdan.jr): Consider an adaptive timeout, which can change
- // depending on how many tests ran and how many remain.
- // Note: do NOT parse child's stdout to do that, it's known to be
- // unreliable (e.g. buffering issues can mix up the output).
- base::TimeDelta timeout =
- test_names.size() * TestTimeouts::test_launcher_timeout();
-
- GTestCallbackState callback_state;
- callback_state.test_launcher = test_launcher;
- callback_state.test_names = test_names;
- callback_state.output_file = output_file;
-
- test_launcher->LaunchChildGTestProcess(
- cmd_line,
- std::string(),
- timeout,
- use_job_objects_ ? TestLauncher::USE_JOB_OBJECTS : 0,
- Bind(&UnitTestLauncherDelegate::GTestCallback,
- Unretained(this),
- callback_state));
- }
-
- void UnitTestLauncherDelegate::GTestCallback(
- const GTestCallbackState& callback_state,
- int exit_code,
- const TimeDelta& elapsed_time,
- bool was_timeout,
- const std::string& output) {
- DCHECK(thread_checker_.CalledOnValidThread());
- std::vector<std::string> tests_to_relaunch;
- ProcessTestResults(callback_state.test_launcher,
- callback_state.test_names,
- callback_state.output_file,
- output,
- exit_code,
- was_timeout,
- &tests_to_relaunch);
-
- // Relaunch requested tests in parallel, but only use single
- // test per batch for more precise results (crashes, test passes
- // but non-zero exit codes etc).
- for (size_t i = 0; i < tests_to_relaunch.size(); i++) {
- std::vector<std::string> batch;
- batch.push_back(tests_to_relaunch[i]);
- RunBatch(callback_state.test_launcher, batch);
- }
-
- // The temporary file's directory is also temporary.
- DeleteFile(callback_state.output_file.DirName(), true);
- }
-
- void UnitTestLauncherDelegate::SerialGTestCallback(
- const GTestCallbackState& callback_state,
- const std::vector<std::string>& test_names,
- int exit_code,
- const TimeDelta& elapsed_time,
- bool was_timeout,
- const std::string& output) {
- DCHECK(thread_checker_.CalledOnValidThread());
- std::vector<std::string> tests_to_relaunch;
- bool called_any_callbacks =
- ProcessTestResults(callback_state.test_launcher,
- callback_state.test_names,
- callback_state.output_file,
- output,
- exit_code,
- was_timeout,
- &tests_to_relaunch);
-
- // There is only one test, there cannot be other tests to relaunch
- // due to a crash.
- DCHECK(tests_to_relaunch.empty());
-
- // There is only one test, we should have called back with its result.
- DCHECK(called_any_callbacks);
-
- // The temporary file's directory is also temporary.
- DeleteFile(callback_state.output_file.DirName(), true);
-
- MessageLoop::current()->PostTask(
- FROM_HERE,
- Bind(&UnitTestLauncherDelegate::RunSerially,
- Unretained(this),
- callback_state.test_launcher,
- test_names));
- }
-
- // static
- bool UnitTestLauncherDelegate::ProcessTestResults(
- TestLauncher* test_launcher,
- const std::vector<std::string>& test_names,
- const base::FilePath& output_file,
- const std::string& output,
- int exit_code,
- bool was_timeout,
- std::vector<std::string>* tests_to_relaunch) {
- std::vector<TestResult> test_results;
- bool crashed = false;
- bool have_test_results =
- ProcessGTestOutput(output_file, &test_results, &crashed);
-
- bool called_any_callback = false;
-
- if (have_test_results) {
- // TODO(phajdan.jr): Check for duplicates and mismatches between
- // the results we got from XML file and tests we intended to run.
- std::map<std::string, TestResult> results_map;
- for (size_t i = 0; i < test_results.size(); i++)
- results_map[test_results[i].full_name] = test_results[i];
-
- bool had_interrupted_test = false;
-
- // Results to be reported back to the test launcher.
- std::vector<TestResult> final_results;
-
- for (size_t i = 0; i < test_names.size(); i++) {
- if (ContainsKey(results_map, test_names[i])) {
- TestResult test_result = results_map[test_names[i]];
- if (test_result.status == TestResult::TEST_CRASH) {
- had_interrupted_test = true;
-
- if (was_timeout) {
- // Fix up the test status: we forcibly kill the child process
- // after the timeout, so from XML results it looks just like
- // a crash.
- test_result.status = TestResult::TEST_TIMEOUT;
- }
- } else if (test_result.status == TestResult::TEST_SUCCESS ||
- test_result.status == TestResult::TEST_FAILURE) {
- // We run multiple tests in a batch with a timeout applied
- // to the entire batch. It is possible that with other tests
- // running quickly some tests take longer than the per-test timeout.
- // For consistent handling of tests independent of order and other
- // factors, mark them as timing out.
- if (test_result.elapsed_time >
- TestTimeouts::test_launcher_timeout()) {
- test_result.status = TestResult::TEST_TIMEOUT;
- }
+ if (was_timeout) {
+ // Fix up the test status: we forcibly kill the child process
+ // after the timeout, so from XML results it looks just like
+ // a crash.
+ test_result.status = TestResult::TEST_TIMEOUT;
}
- test_result.output_snippet =
- GetTestOutputSnippet(test_result, output);
- final_results.push_back(test_result);
- } else if (had_interrupted_test) {
- tests_to_relaunch->push_back(test_names[i]);
- } else {
- // TODO(phajdan.jr): Explicitly pass the info that the test didn't
- // run for a mysterious reason.
- LOG(ERROR) << "no test result for " << test_names[i];
- TestResult test_result;
- test_result.full_name = test_names[i];
- test_result.status = TestResult::TEST_UNKNOWN;
- test_result.output_snippet =
- GetTestOutputSnippet(test_result, output);
- final_results.push_back(test_result);
+ } else if (test_result.status == TestResult::TEST_SUCCESS ||
+ test_result.status == TestResult::TEST_FAILURE) {
+ // We run multiple tests in a batch with a timeout applied
+ // to the entire batch. It is possible that with other tests
+ // running quickly some tests take longer than the per-test timeout.
+ // For consistent handling of tests independent of order and other
+ // factors, mark them as timing out.
+ if (test_result.elapsed_time >
+ TestTimeouts::test_launcher_timeout()) {
+ test_result.status = TestResult::TEST_TIMEOUT;
+ }
}
- }
-
- // TODO(phajdan.jr): Handle the case where processing XML output
- // indicates a crash but none of the test results is marked as crashing.
-
- if (final_results.empty())
- return false;
-
- bool has_non_success_test = false;
- for (size_t i = 0; i < final_results.size(); i++) {
- if (final_results[i].status != TestResult::TEST_SUCCESS) {
- has_non_success_test = true;
- break;
- }
- }
-
- if (!has_non_success_test && exit_code != 0) {
- // This is a bit surprising case: all tests are marked as successful,
- // but the exit code was not zero. This can happen e.g. under memory
- // tools that report leaks this way.
-
- if (final_results.size() == 1) {
- // Easy case. One test only so we know the non-zero exit code
- // was caused by that one test.
- final_results[0].status = TestResult::TEST_FAILURE_ON_EXIT;
- } else {
- // Harder case. Discard the results and request relaunching all
- // tests without batching. This will trigger above branch on
- // relaunch leading to more precise results.
- LOG(WARNING) << "Not sure which test caused non-zero exit code, "
- << "relaunching all of them without batching.";
-
- for (size_t i = 0; i < final_results.size(); i++)
- tests_to_relaunch->push_back(final_results[i].full_name);
-
- return false;
- }
- }
-
- for (size_t i = 0; i < final_results.size(); i++) {
- // Fix the output snippet after possible changes to the test result.
- final_results[i].output_snippet =
- GetTestOutputSnippet(final_results[i], output);
- test_launcher->OnTestFinished(final_results[i]);
- called_any_callback = true;
- }
- } else {
- fprintf(stdout,
- "Failed to get out-of-band test success data, "
- "dumping full stdio below:\n%s\n",
- output.c_str());
- fflush(stdout);
-
- // We do not have reliable details about test results (parsing test
- // stdout is known to be unreliable), apply the executable exit code
- // to all tests.
- // TODO(phajdan.jr): Be smarter about this, e.g. retry each test
- // individually.
- for (size_t i = 0; i < test_names.size(); i++) {
+ test_result.output_snippet = GetTestOutputSnippet(test_result, output);
+ final_results.push_back(test_result);
+ } else if (had_interrupted_test) {
+ tests_to_relaunch->push_back(test_names[i]);
+ } else {
+ // TODO(phajdan.jr): Explicitly pass the info that the test didn't
+ // run for a mysterious reason.
+ LOG(ERROR) << "no test result for " << test_names[i];
TestResult test_result;
test_result.full_name = test_names[i];
test_result.status = TestResult::TEST_UNKNOWN;
- test_launcher->OnTestFinished(test_result);
- called_any_callback = true;
+ test_result.output_snippet = GetTestOutputSnippet(test_result, output);
+ final_results.push_back(test_result);
}
}
- return called_any_callback;
+ // TODO(phajdan.jr): Handle the case where processing XML output
+ // indicates a crash but none of the test results is marked as crashing.
+
+ if (final_results.empty())
+ return false;
+
+ bool has_non_success_test = false;
+ for (size_t i = 0; i < final_results.size(); i++) {
+ if (final_results[i].status != TestResult::TEST_SUCCESS) {
+ has_non_success_test = true;
+ break;
+ }
+ }
+
+ if (!has_non_success_test && exit_code != 0) {
+ // This is a bit surprising case: all tests are marked as successful,
+ // but the exit code was not zero. This can happen e.g. under memory
+ // tools that report leaks this way.
+
+ if (final_results.size() == 1) {
+ // Easy case. One test only so we know the non-zero exit code
+ // was caused by that one test.
+ final_results[0].status = TestResult::TEST_FAILURE_ON_EXIT;
+ } else {
+ // Harder case. Discard the results and request relaunching all
+ // tests without batching. This will trigger above branch on
+ // relaunch leading to more precise results.
+ LOG(WARNING) << "Not sure which test caused non-zero exit code, "
+ << "relaunching all of them without batching.";
+
+ for (size_t i = 0; i < final_results.size(); i++)
+ tests_to_relaunch->push_back(final_results[i].full_name);
+
+ return false;
+ }
+ }
+
+ for (size_t i = 0; i < final_results.size(); i++) {
+ // Fix the output snippet after possible changes to the test result.
+ final_results[i].output_snippet =
+ GetTestOutputSnippet(final_results[i], output);
+ test_launcher->OnTestFinished(final_results[i]);
+ called_any_callback = true;
+ }
+ } else {
+ fprintf(stdout,
+ "Failed to get out-of-band test success data, "
+ "dumping full stdio below:\n%s\n",
+ output.c_str());
+ fflush(stdout);
+
+ // We do not have reliable details about test results (parsing test
+ // stdout is known to be unreliable), apply the executable exit code
+ // to all tests.
+ // TODO(phajdan.jr): Be smarter about this, e.g. retry each test
+ // individually.
+ for (size_t i = 0; i < test_names.size(); i++) {
+ TestResult test_result;
+ test_result.full_name = test_names[i];
+ test_result.status = TestResult::TEST_UNKNOWN;
+ test_launcher->OnTestFinished(test_result);
+ called_any_callback = true;
+ }
}
+ return called_any_callback;
+}
+
} // namespace base
diff --git a/base/tuple.h b/base/tuple.h
index 4408074..41c6a00 100644
--- a/base/tuple.h
+++ b/base/tuple.h
@@ -40,6 +40,50 @@
template <size_t... Ns>
struct MakeIndexSequenceImpl;
+#if defined(_PREFAST_) && defined(OS_WIN)
+
+// Work around VC++ 2013 /analyze internal compiler error:
+// https://connect.microsoft.com/VisualStudio/feedback/details/1053626
+
+template <> struct MakeIndexSequenceImpl<0> {
+ using Type = IndexSequence<>;
+};
+template <> struct MakeIndexSequenceImpl<1> {
+ using Type = IndexSequence<0>;
+};
+template <> struct MakeIndexSequenceImpl<2> {
+ using Type = IndexSequence<0,1>;
+};
+template <> struct MakeIndexSequenceImpl<3> {
+ using Type = IndexSequence<0,1,2>;
+};
+template <> struct MakeIndexSequenceImpl<4> {
+ using Type = IndexSequence<0,1,2,3>;
+};
+template <> struct MakeIndexSequenceImpl<5> {
+ using Type = IndexSequence<0,1,2,3,4>;
+};
+template <> struct MakeIndexSequenceImpl<6> {
+ using Type = IndexSequence<0,1,2,3,4,5>;
+};
+template <> struct MakeIndexSequenceImpl<7> {
+ using Type = IndexSequence<0,1,2,3,4,5,6>;
+};
+template <> struct MakeIndexSequenceImpl<8> {
+ using Type = IndexSequence<0,1,2,3,4,5,6,7>;
+};
+template <> struct MakeIndexSequenceImpl<9> {
+ using Type = IndexSequence<0,1,2,3,4,5,6,7,8>;
+};
+template <> struct MakeIndexSequenceImpl<10> {
+ using Type = IndexSequence<0,1,2,3,4,5,6,7,8,9>;
+};
+template <> struct MakeIndexSequenceImpl<11> {
+ using Type = IndexSequence<0,1,2,3,4,5,6,7,8,9,10>;
+};
+
+#else // defined(WIN) && defined(_PREFAST_)
+
template <size_t... Ns>
struct MakeIndexSequenceImpl<0, Ns...> {
using Type = IndexSequence<Ns...>;
@@ -49,6 +93,8 @@
struct MakeIndexSequenceImpl<N, Ns...>
: MakeIndexSequenceImpl<N - 1, N - 1, Ns...> {};
+#endif // defined(WIN) && defined(_PREFAST_)
+
template <size_t N>
using MakeIndexSequence = typename MakeIndexSequenceImpl<N>::Type;
diff --git a/build/all.gyp b/build/all.gyp
index b890f2c..6856f76 100644
--- a/build/all.gyp
+++ b/build/all.gyp
@@ -203,6 +203,7 @@
}],
],
'dependencies': [
+ '../chrome/tools/crash_service/caps/caps.gyp:*',
'../chrome_elf/chrome_elf.gyp:*',
'../cloud_print/cloud_print.gyp:*',
'../courgette/courgette.gyp:*',
diff --git a/build/android/pylib/base/test_run_factory.py b/build/android/pylib/base/test_run_factory.py
index 3f00caa..8c71ebb 100644
--- a/build/android/pylib/base/test_run_factory.py
+++ b/build/android/pylib/base/test_run_factory.py
@@ -9,7 +9,8 @@
from pylib.local.device import local_device_instrumentation_test_run
from pylib.remote.device import remote_device_environment
from pylib.remote.device import remote_device_gtest_run
-from pylib.remote.device import remote_device_uirobot_run
+from pylib.remote.device import remote_device_instrumentation_test_run
+from pylib.remote.device import remote_device_uirobot_test_run
from pylib.uirobot import uirobot_test_instance
@@ -24,10 +25,14 @@
if isinstance(env, remote_device_environment.RemoteDeviceEnvironment):
if isinstance(test_instance, gtest_test_instance.GtestTestInstance):
- return remote_device_gtest_run.RemoteDeviceGtestRun(env, test_instance)
- # TODO(rnephew): Add remote_device instrumentation test runs.
+ return remote_device_gtest_run.RemoteDeviceGtestTestRun(
+ env, test_instance)
+ if isinstance(test_instance,
+ instrumentation_test_instance.InstrumentationTestInstance):
+ return (remote_device_instrumentation_test_run
+ .RemoteDeviceInstrumentationTestRun(env, test_instance))
if isinstance(test_instance, uirobot_test_instance.UirobotTestInstance):
- return remote_device_uirobot_run.RemoteDeviceUirobotRun(
+ return remote_device_uirobot_test_run.RemoteDeviceUirobotTestRun(
env, test_instance)
diff --git a/build/android/pylib/constants.py b/build/android/pylib/constants.py
index 50dc075..fb574e6 100644
--- a/build/android/pylib/constants.py
+++ b/build/android/pylib/constants.py
@@ -88,7 +88,7 @@
'android_webview_shell': PackageInfo(
'org.chromium.android_webview.shell',
'org.chromium.android_webview.shell.AwShellActivity',
- None,
+ '/data/local/tmp/android-webview-command-line',
None,
'org.chromium.android_webview.test'),
'gtest': PackageInfo(
diff --git a/build/android/pylib/device/device_utils.py b/build/android/pylib/device/device_utils.py
index fe9d2c6..a4ddef1 100644
--- a/build/android/pylib/device/device_utils.py
+++ b/build/android/pylib/device/device_utils.py
@@ -634,9 +634,12 @@
CommandTimeoutError on timeout.
DeviceUnreachableError on missing device.
"""
- # Check that the package exists before clearing it. Necessary because
- # calling pm clear on a package that doesn't exist may never return.
- if self.GetApplicationPath(package):
+ # Check that the package exists before clearing it for android builds below
+ # JB MR2. Necessary because calling pm clear on a package that doesn't exist
+ # may never return.
+ if ((self.build_version_sdk >=
+ constants.ANDROID_SDK_VERSION_CODES.JELLY_BEAN_MR2)
+ or self.GetApplicationPath(package)):
self.RunShellCommand(['pm', 'clear', package], check_return=True)
@decorators.WithTimeoutAndRetriesFromInstance()
diff --git a/build/android/pylib/device/device_utils_test.py b/build/android/pylib/device/device_utils_test.py
index 58dd56a..72ab99c 100755
--- a/build/android/pylib/device/device_utils_test.py
+++ b/build/android/pylib/device/device_utils_test.py
@@ -930,19 +930,35 @@
class DeviceUtilsClearApplicationStateTest(DeviceUtilsNewImplTest):
def testClearApplicationState_packageDoesntExist(self):
- with self.assertCall(
- self.call.device.GetApplicationPath('this.package.does.not.exist'),
- None):
+ with self.assertCalls(
+ (self.call.adb.Shell('getprop ro.build.version.sdk'), '17\n'),
+ (self.call.device.GetApplicationPath('this.package.does.not.exist'),
+ None)):
+ self.device.ClearApplicationState('this.package.does.not.exist')
+
+ def testClearApplicationState_packageDoesntExistOnAndroidJBMR2OrAbove(self):
+ with self.assertCalls(
+ (self.call.adb.Shell('getprop ro.build.version.sdk'), '18\n'),
+ (self.call.adb.Shell('pm clear this.package.does.not.exist'),
+ 'Failed\r\n')):
self.device.ClearApplicationState('this.package.does.not.exist')
def testClearApplicationState_packageExists(self):
with self.assertCalls(
+ (self.call.adb.Shell('getprop ro.build.version.sdk'), '17\n'),
(self.call.device.GetApplicationPath('this.package.exists'),
'/data/app/this.package.exists.apk'),
(self.call.adb.Shell('pm clear this.package.exists'),
'Success\r\n')):
self.device.ClearApplicationState('this.package.exists')
+ def testClearApplicationState_packageExistsOnAndroidJBMR2OrAbove(self):
+ with self.assertCalls(
+ (self.call.adb.Shell('getprop ro.build.version.sdk'), '18\n'),
+ (self.call.adb.Shell('pm clear this.package.exists'),
+ 'Success\r\n')):
+ self.device.ClearApplicationState('this.package.exists')
+
class DeviceUtilsSendKeyEventTest(DeviceUtilsNewImplTest):
diff --git a/build/android/pylib/gtest/test_package_apk.py b/build/android/pylib/gtest/test_package_apk.py
index b4c67e6..cdb6daf 100644
--- a/build/android/pylib/gtest/test_package_apk.py
+++ b/build/android/pylib/gtest/test_package_apk.py
@@ -55,11 +55,11 @@
device.RunShellCommand('rm -f ' + self._GetFifo())
def _WatchFifo(self, device, timeout, logfile=None):
- for i in range(10):
+ for i in range(100):
if device.FileExists(self._GetFifo()):
- logging.info('Fifo created.')
+ logging.info('Fifo created. Slept for %f secs' % (i * 0.5))
break
- time.sleep(i)
+ time.sleep(0.5)
else:
raise device_errors.DeviceUnreachableError(
'Unable to find fifo on device %s ' % self._GetFifo())
@@ -67,14 +67,14 @@
args += ['shell', 'cat', self._GetFifo()]
return pexpect.spawn('adb', args, timeout=timeout, logfile=logfile)
- def _StartActivity(self, device):
+ def _StartActivity(self, device, force_stop=True):
device.StartActivity(
intent.Intent(package=self._package_info.package,
activity=self._package_info.activity,
action='android.intent.action.MAIN'),
# No wait since the runner waits for FIFO creation anyway.
blocking=False,
- force_stop=True)
+ force_stop=force_stop)
#override
def ClearApplicationState(self, device):
@@ -119,7 +119,10 @@
try:
self.tool.SetupEnvironment()
self._ClearFifo(device)
- self._StartActivity(device)
+ # Doesn't need to stop an Activity because ClearApplicationState() is
+ # always called before this call and so it is already stopped at this
+ # point.
+ self._StartActivity(device, force_stop=False)
finally:
self.tool.CleanUpEnvironment()
logfile = android_commands.NewLineNormalizer(sys.stdout)
diff --git a/build/android/pylib/gtest/test_runner.py b/build/android/pylib/gtest/test_runner.py
index fa38c4f..4bb9737 100644
--- a/build/android/pylib/gtest/test_runner.py
+++ b/build/android/pylib/gtest/test_runner.py
@@ -14,6 +14,18 @@
from pylib.local import local_test_server_spawner
from pylib.perf import perf_control
+# Test case statuses.
+RE_RUN = re.compile('\\[ RUN \\] ?(.*)\r\n')
+RE_FAIL = re.compile('\\[ FAILED \\] ?(.*?)( \\((\\d+) ms\\))?\r\r\n')
+RE_OK = re.compile('\\[ OK \\] ?(.*?)( \\((\\d+) ms\\))?\r\r\n')
+
+# Test run statuses.
+RE_PASSED = re.compile('\\[ PASSED \\] ?(.*)\r\n')
+RE_RUNNER_FAIL = re.compile('\\[ RUNNER_FAILED \\] ?(.*)\r\n')
+# Signal handlers are installed before starting tests
+# to output the CRASHED marker when a crash happens.
+RE_CRASH = re.compile('\\[ CRASHED \\](.*)\r\n')
+
def _TestSuiteRequiresMockTestServer(suite_name):
"""Returns True if the test suite requires mock test server."""
@@ -77,45 +89,33 @@
"""
results = base_test_result.TestRunResults()
- # Test case statuses.
- re_run = re.compile('\\[ RUN \\] ?(.*)\r\n')
- re_fail = re.compile('\\[ FAILED \\] ?(.*?)( \\((\\d+) ms\\))?\r\r\n')
- re_ok = re.compile('\\[ OK \\] ?(.*?)( \\((\\d+) ms\\))?\r\r\n')
-
- # Test run statuses.
- re_passed = re.compile('\\[ PASSED \\] ?(.*)\r\n')
- re_runner_fail = re.compile('\\[ RUNNER_FAILED \\] ?(.*)\r\n')
- # Signal handlers are installed before starting tests
- # to output the CRASHED marker when a crash happens.
- re_crash = re.compile('\\[ CRASHED \\](.*)\r\n')
-
log = ''
try:
while True:
full_test_name = None
- found = p.expect([re_run, re_passed, re_runner_fail],
+ found = p.expect([RE_RUN, RE_PASSED, RE_RUNNER_FAIL],
timeout=self._timeout)
- if found == 1: # re_passed
+ if found == 1: # RE_PASSED
break
- elif found == 2: # re_runner_fail
+ elif found == 2: # RE_RUNNER_FAIL
break
- else: # re_run
+ else: # RE_RUN
full_test_name = p.match.group(1).replace('\r', '')
- found = p.expect([re_ok, re_fail, re_crash], timeout=self._timeout)
+ found = p.expect([RE_OK, RE_FAIL, RE_CRASH], timeout=self._timeout)
log = p.before.replace('\r', '')
- if found == 0: # re_ok
+ if found == 0: # RE_OK
if full_test_name == p.match.group(1).replace('\r', ''):
duration_ms = int(p.match.group(3)) if p.match.group(3) else 0
results.AddResult(base_test_result.BaseTestResult(
full_test_name, base_test_result.ResultType.PASS,
duration=duration_ms, log=log))
- elif found == 2: # re_crash
+ elif found == 2: # RE_CRASH
results.AddResult(base_test_result.BaseTestResult(
full_test_name, base_test_result.ResultType.CRASH,
log=log))
break
- else: # re_fail
+ else: # RE_FAIL
duration_ms = int(p.match.group(3)) if p.match.group(3) else 0
results.AddResult(base_test_result.BaseTestResult(
full_test_name, base_test_result.ResultType.FAIL,
diff --git a/build/android/pylib/instrumentation/instrumentation_test_instance.py b/build/android/pylib/instrumentation/instrumentation_test_instance.py
index a87f81a..598967b 100644
--- a/build/android/pylib/instrumentation/instrumentation_test_instance.py
+++ b/build/android/pylib/instrumentation/instrumentation_test_instance.py
@@ -5,6 +5,7 @@
import logging
import os
import pickle
+import re
import sys
from pylib import cmd_helper
@@ -24,6 +25,7 @@
_DEFAULT_ANNOTATIONS = [
'Smoke', 'SmallTest', 'MediumTest', 'LargeTest',
'EnormousTest', 'IntegrationTest']
+_NATIVE_CRASH_RE = re.compile('native crash', re.IGNORECASE)
_PICKLE_FORMAT_VERSION = 10
@@ -270,6 +272,10 @@
self._flags.extend([flag for flag in stripped_lines if flag])
@property
+ def suite(self):
+ return 'instrumentation'
+
+ @property
def apk_under_test(self):
return self._apk_under_test
@@ -459,6 +465,33 @@
return inflated_tests
@staticmethod
+ def GenerateMultiTestResult(errors, statuses):
+ INSTR_STATUS_CODE_START = 1
+ results = []
+ skip_counter = 1
+ for status_code, bundle in statuses:
+ if status_code != INSTR_STATUS_CODE_START:
+ # TODO(rnephew): Make skipped tests still output test name. This is only
+ # there to give skipped tests a unique name so they are counted
+ if 'test_skipped' in bundle:
+ test_name = str(skip_counter)
+ skip_counter += 1
+ else:
+ test_name = '%s#%s' % (
+ ''.join(bundle.get('class', [''])),
+ ''.join(bundle.get('test', [''])))
+
+ results.append(
+ GenerateTestResult(test_name, [(status_code, bundle)], 0, 0))
+ for error in errors:
+ if _NATIVE_CRASH_RE.search(error):
+ results.append(
+ base_test_result.BaseTestResult(
+ 'Crash detected', base_test_result.ResultType.CRASH))
+
+ return results
+
+ @staticmethod
def ParseAmInstrumentRawOutput(raw_output):
return ParseAmInstrumentRawOutput(raw_output)
diff --git a/build/android/pylib/remote/device/remote_device_gtest_run.py b/build/android/pylib/remote/device/remote_device_gtest_run.py
index e5f6990..76d1d45 100644
--- a/build/android/pylib/remote/device/remote_device_gtest_run.py
+++ b/build/android/pylib/remote/device/remote_device_gtest_run.py
@@ -24,7 +24,7 @@
'OnlyOutputFailures')
-class RemoteDeviceGtestRun(remote_device_test_run.RemoteDeviceTestRun):
+class RemoteDeviceGtestTestRun(remote_device_test_run.RemoteDeviceTestRun):
"""Run gtests and uirobot tests on a remote device."""
DEFAULT_RUNNER_PACKAGE = (
diff --git a/build/android/pylib/remote/device/remote_device_instrumentation_test_run.py b/build/android/pylib/remote/device/remote_device_instrumentation_test_run.py
new file mode 100644
index 0000000..5138d46
--- /dev/null
+++ b/build/android/pylib/remote/device/remote_device_instrumentation_test_run.py
@@ -0,0 +1,55 @@
+# Copyright 2015 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""Run specific test on specific environment."""
+
+import logging
+import os
+import tempfile
+
+from pylib.base import base_test_result
+from pylib.remote.device import remote_device_test_run
+from pylib.utils import apk_helper
+
+
+class RemoteDeviceInstrumentationTestRun(
+ remote_device_test_run.RemoteDeviceTestRun):
+ """Run instrumentation tests on a remote device."""
+
+ #override
+ def TestPackage(self):
+ return self._test_instance.test_package
+
+ #override
+ def _TriggerSetUp(self):
+ """Set up the triggering of a test run."""
+ logging.info('Triggering test run.')
+ self._AmInstrumentTestSetup(
+ self._test_instance._apk_under_test, self._test_instance.test_apk,
+ self._test_instance.test_runner, environment_variables={})
+
+ #override
+ def _ParseTestResults(self):
+ logging.info('Parsing results from stdout.')
+ r = base_test_result.TestRunResults()
+
+ if self._results['results']['exception']:
+ r.AddResult(base_test_result.BaseTestResult(
+ self._results['results']['exception'],
+ base_test_result.ResultType.FAIL))
+ return r
+
+ _, errors, parsed_output = self._test_instance.ParseAmInstrumentRawOutput(
+ self._results['results']['output'].splitlines())
+ logging.debug(errors)
+ result = self._test_instance.GenerateMultiTestResult(errors, parsed_output)
+
+ if isinstance(result, base_test_result.BaseTestResult):
+ r.AddResult(result)
+ elif isinstance(result, list):
+ r.AddResults(result)
+ else:
+ raise Exception('Unexpected result type: %s' % type(result).__name__)
+
+ return r
diff --git a/build/android/pylib/remote/device/remote_device_test_run.py b/build/android/pylib/remote/device/remote_device_test_run.py
index 86ee587..c4f75b0 100644
--- a/build/android/pylib/remote/device/remote_device_test_run.py
+++ b/build/android/pylib/remote/device/remote_device_test_run.py
@@ -219,7 +219,7 @@
config['sdcard_files'] = ','.join(sdcard_files)
config['host_test'] = host_test
self._test_id = self._UploadTestToDevice(
- 'robotium', test_with_deps.name)
+ 'robotium', test_with_deps.name, app_id=self._app_id)
else:
self._test_id = self._UploadTestToDevice('robotium', test_path)
@@ -238,7 +238,7 @@
upload_results, 'Unable to upload %s.' % app_path)
return upload_results.json()['response']['app_id']
- def _UploadTestToDevice(self, test_type, test_path):
+ def _UploadTestToDevice(self, test_type, test_path, app_id=None):
"""Upload test to device
Args:
test_type: Type of test that is being uploaded. Ex. uirobot, gtest..
@@ -248,7 +248,7 @@
with appurify_sanitized.SanitizeLogging(self._env.verbose_count,
logging.WARNING):
upload_results = appurify_sanitized.api.tests_upload(
- self._env.token, test_src, 'raw', test_type)
+ self._env.token, test_src, 'raw', test_type, app_id=app_id)
remote_device_helper.TestHttpResponse(upload_results,
'Unable to upload %s.' % test_path)
return upload_results.json()['response']['test_id']
diff --git a/build/android/pylib/remote/device/remote_device_uirobot_run.py b/build/android/pylib/remote/device/remote_device_uirobot_test_run.py
similarity index 91%
rename from build/android/pylib/remote/device/remote_device_uirobot_run.py
rename to build/android/pylib/remote/device/remote_device_uirobot_test_run.py
index 3aee343..7eedaa5 100644
--- a/build/android/pylib/remote/device/remote_device_uirobot_run.py
+++ b/build/android/pylib/remote/device/remote_device_uirobot_test_run.py
@@ -15,7 +15,7 @@
from pylib.remote.device import remote_device_helper
-class RemoteDeviceUirobotRun(remote_device_test_run.RemoteDeviceTestRun):
+class RemoteDeviceUirobotTestRun(remote_device_test_run.RemoteDeviceTestRun):
"""Run uirobot tests on a remote device."""
DEFAULT_RUNNER_TYPE = 'android_robot'
@@ -27,7 +27,7 @@
env: Environment the tests will run in.
test_instance: The test that will be run.
"""
- super(RemoteDeviceUirobotRun, self).__init__(env, test_instance)
+ super(RemoteDeviceUirobotTestRun, self).__init__(env, test_instance)
#override
def TestPackage(self):
diff --git a/build/android/pylib/uirobot/uirobot_test_instance.py b/build/android/pylib/uirobot/uirobot_test_instance.py
index a531b41..edd3200 100644
--- a/build/android/pylib/uirobot/uirobot_test_instance.py
+++ b/build/android/pylib/uirobot/uirobot_test_instance.py
@@ -18,7 +18,7 @@
"""
super(UirobotTestInstance, self).__init__()
self._apk_under_test = os.path.join(
- constants.GetOutDirectory(), args.apk_under_test)
+ constants.GetOutDirectory(), args.app_under_test)
self._minutes = args.minutes
self._package_name = apk_helper.GetPackageName(self._apk_under_test)
self._suite = 'Android Uirobot'
diff --git a/build/android/test_runner.py b/build/android/test_runner.py
index e92f851..4164bd8 100755
--- a/build/android/test_runner.py
+++ b/build/android/test_runner.py
@@ -142,7 +142,7 @@
help='Type of test to run as.')
group.add_argument('--runner-package', default='',
help='Package name of test.')
- group.add_argument('--apk-under-test', default='apks/Chrome.apk',
+ group.add_argument('--app-under-test', default='',
help='APK to run tests on.')
api_secret_group = group.add_mutually_exclusive_group()
@@ -316,6 +316,7 @@
AddCommonOptions(parser)
AddDeviceOptions(parser)
+ AddRemoteDeviceOptions(parser)
def ProcessInstrumentationOptions(args):
diff --git a/build/common.gypi b/build/common.gypi
index 119f5b4..6d3a6ed 100644
--- a/build/common.gypi
+++ b/build/common.gypi
@@ -2058,6 +2058,9 @@
'grit_defines': ['-D', 'scale_factors=2x'],
}],
['OS == "ios"', {
+ 'variables': {
+ 'enable_coverage%': 0,
+ },
'grit_defines': [
'-t', 'ios',
# iOS uses a whitelist to filter resources.
@@ -2073,7 +2076,10 @@
# TODO(sdefresne): Remove the target_subarch check once Apple has
# upstreamed the support for "arm64". http://crbug.com/341453
- ['target_subarch!="arm32" or "<(GENERATOR)"=="xcode"', {
+ # TODO(eugenebut): Remove enable_coverage check once
+ # libclang_rt.profile_ios.a is bundled with Chromium's clang.
+ # http://crbug.com/450379
+ ['target_subarch!="arm32" or enable_coverage or "<(GENERATOR)"=="xcode"', {
'clang_xcode%': 1,
}],
],
@@ -3531,7 +3537,7 @@
},
}],
# TODO(thakis): Enable this everywhere. http://crbug.com/371125
- ['(OS=="linux" or OS=="android") and asan==0 and msan==0 and tsan==0 and use_ozone!=1', {
+ ['(OS=="linux" or OS=="android") and asan==0 and msan==0 and tsan==0 and ubsan==0 and ubsan_vptr==0 and use_ozone!=1', {
'target_defaults': {
'ldflags': [
'-Wl,-z,defs',
diff --git a/build/config/compiler/BUILD.gn b/build/config/compiler/BUILD.gn
index b5c4a90..cc2b7f5 100644
--- a/build/config/compiler/BUILD.gn
+++ b/build/config/compiler/BUILD.gn
@@ -6,6 +6,9 @@
if (cpu_arch == "arm") {
import("//build/config/arm.gni")
}
+if (cpu_arch == "mipsel" || cpu_arch == "mips64el") {
+ import("//build/config/mips.gni")
+}
if (is_posix) {
import("//build/config/gcc/gcc_version.gni")
}
@@ -272,6 +275,51 @@
]
}
}
+ } else if (cpu_arch == "mipsel") {
+ # Don't set the compiler flags for the WebView build. These will come
+ # from the Android build system.
+ if (!is_android_webview_build) {
+ if (mips_arch_variant == "r6") {
+ cflags += [
+ "-mips32r6",
+ "-Wa,-mips32r6",
+ ]
+ if (is_android) {
+ ldflags += [
+ "-mips32r6",
+ "-Wl,-melf32ltsmip",
+ ]
+ }
+ } else if (mips_arch_variant == "r2") {
+ cflags += [
+ "-mips32r2",
+ "-Wa,-mips32r2",
+ ]
+ } else if (mips_arch_variant == "r1") {
+ cflags += [
+ "-mips32",
+ "-Wa,-mips32",
+ ]
+ }
+ }
+ } else if (cpu_arch == "mips64el") {
+ # Don't set the compiler flags for the WebView build. These will come
+ # from the Android build system.
+ if (!is_android_webview_build) {
+ if (mips_arch_variant == "r6") {
+ cflags += [
+ "-mips64r6",
+ "-Wa,-mips64r6",
+ ]
+ ldflags += [ "-mips64r6" ]
+ } else if (mips_arch_variant == "r2") {
+ cflags += [
+ "-mips64r2",
+ "-Wa,-mips64r2",
+ ]
+ ldflags += [ "-mips64r2" ]
+ }
+ }
}
defines += [ "_FILE_OFFSET_BITS=64" ]
@@ -301,8 +349,13 @@
"-Wl,-z,noexecstack",
"-Wl,-z,now",
"-Wl,-z,relro",
- "-Wl,-z,defs",
]
+
+ # TODO(zork): The mipsel build is broken in ffmpeg, guard this flag for now
+ # to hide the breakage. https://crbug.com/450771
+ if (!using_sanitizer && cpu_arch != "mipsel") {
+ ldflags += [ "-Wl,-z,defs" ]
+ }
}
# Linux-specific compiler flags setup.
diff --git a/build/config/mips.gni b/build/config/mips.gni
new file mode 100644
index 0000000..f544d94
--- /dev/null
+++ b/build/config/mips.gni
@@ -0,0 +1,20 @@
+# Copyright 2015 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+# MIPS arch variant.
+if (cpu_arch == "mipsel") {
+ declare_args() {
+ mips_arch_variant = "r1"
+ }
+} else if (cpu_arch == "mips64el") {
+ if (is_android) {
+ declare_args() {
+ mips_arch_variant = "r6"
+ }
+ } else {
+ declare_args() {
+ mips_arch_variant = "r2"
+ }
+ }
+}
diff --git a/build/ios/OWNERS b/build/ios/OWNERS
new file mode 100644
index 0000000..1c3e6c8
--- /dev/null
+++ b/build/ios/OWNERS
@@ -0,0 +1,3 @@
+rohitrao@chromium.org
+stuartmorgan@chromium.org
+
diff --git a/build/ios/coverage.gypi b/build/ios/coverage.gypi
new file mode 100644
index 0000000..afd3cdc
--- /dev/null
+++ b/build/ios/coverage.gypi
@@ -0,0 +1,33 @@
+# Copyright 2014 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+{
+ 'variables': {
+ 'chromium_code': 1,
+ 'enable_coverage%': 0,
+ },
+ 'conditions': [
+ ['OS=="ios" and enable_coverage', {
+ 'target_defaults': {
+ 'defines': [
+ 'ENABLE_TEST_CODE_COVERAGE=1'
+ ],
+ 'link_settings': {
+ 'xcode_settings': {
+ 'OTHER_LDFLAGS': [
+ '-fprofile-arcs',
+ ],
+ },
+ },
+ 'xcode_settings': {
+ 'OTHER_CFLAGS': [
+ '-fprofile-arcs',
+ '-ftest-coverage',
+ ],
+ },
+ },
+ }],
+ ],
+}
+
diff --git a/build/linux/unbundle/openssl.gyp b/build/linux/unbundle/openssl.gyp
deleted file mode 100644
index d832ba7..0000000
--- a/build/linux/unbundle/openssl.gyp
+++ /dev/null
@@ -1,25 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-{
- 'targets': [
- {
- 'target_name': 'openssl',
- 'type': 'none',
- 'direct_dependent_settings': {
- 'cflags': [
- '<!@(pkg-config --cflags openssl)',
- ],
- },
- 'link_settings': {
- 'ldflags': [
- '<!@(pkg-config --libs-only-L --libs-only-other openssl)',
- ],
- 'libraries': [
- '<!@(pkg-config --libs-only-l openssl)',
- ],
- },
- }
- ],
-}
diff --git a/build/linux/unbundle/replace_gyp_files.py b/build/linux/unbundle/replace_gyp_files.py
index a780fc5..d06ae41 100755
--- a/build/linux/unbundle/replace_gyp_files.py
+++ b/build/linux/unbundle/replace_gyp_files.py
@@ -31,7 +31,6 @@
'use_system_libxml': 'third_party/libxml/libxml.gyp',
'use_system_libxnvctrl' : 'third_party/libXNVCtrl/libXNVCtrl.gyp',
'use_system_libxslt': 'third_party/libxslt/libxslt.gyp',
- 'use_system_openssl': 'third_party/boringssl/boringssl.gyp',
'use_system_opus': 'third_party/opus/opus.gyp',
'use_system_protobuf': 'third_party/protobuf/protobuf.gyp',
'use_system_re2': 'third_party/re2/re2.gyp',
diff --git a/cc/debug/rasterize_and_record_benchmark_impl.cc b/cc/debug/rasterize_and_record_benchmark_impl.cc
index c638ddc..5a9577b 100644
--- a/cc/debug/rasterize_and_record_benchmark_impl.cc
+++ b/cc/debug/rasterize_and_record_benchmark_impl.cc
@@ -24,68 +24,45 @@
const int kDefaultRasterizeRepeatCount = 100;
-class BenchmarkRasterTask : public Task {
- public:
- BenchmarkRasterTask(RasterSource* raster_source,
- const gfx::Rect& content_rect,
- float contents_scale,
- size_t repeat_count)
- : raster_source_(raster_source),
- content_rect_(content_rect),
- contents_scale_(contents_scale),
- repeat_count_(repeat_count),
- is_solid_color_(false),
- best_time_(base::TimeDelta::Max()) {}
+void RunBenchmark(RasterSource* raster_source,
+ const gfx::Rect& content_rect,
+ float contents_scale,
+ size_t repeat_count,
+ base::TimeDelta* min_time,
+ bool* is_solid_color) {
+ // Parameters for LapTimer.
+ const int kTimeLimitMillis = 1;
+ const int kWarmupRuns = 0;
+ const int kTimeCheckInterval = 1;
- // Overridden from Task:
- void RunOnWorkerThread() override {
- // Parameters for LapTimer.
- const int kTimeLimitMillis = 1;
- const int kWarmupRuns = 0;
- const int kTimeCheckInterval = 1;
+ *min_time = base::TimeDelta::Max();
+ for (size_t i = 0; i < repeat_count; ++i) {
+ // Run for a minimum amount of time to avoid problems with timer
+ // quantization when the layer is very small.
+ LapTimer timer(kWarmupRuns,
+ base::TimeDelta::FromMilliseconds(kTimeLimitMillis),
+ kTimeCheckInterval);
+ do {
+ SkBitmap bitmap;
+ bitmap.allocPixels(SkImageInfo::MakeN32Premul(content_rect.width(),
+ content_rect.height()));
+ SkCanvas canvas(bitmap);
+ RasterSource::SolidColorAnalysis analysis;
- for (size_t i = 0; i < repeat_count_; ++i) {
- // Run for a minimum amount of time to avoid problems with timer
- // quantization when the layer is very small.
- LapTimer timer(kWarmupRuns,
- base::TimeDelta::FromMilliseconds(kTimeLimitMillis),
- kTimeCheckInterval);
- do {
- SkBitmap bitmap;
- bitmap.allocPixels(SkImageInfo::MakeN32Premul(content_rect_.width(),
- content_rect_.height()));
- SkCanvas canvas(bitmap);
- RasterSource::SolidColorAnalysis analysis;
+ raster_source->PerformSolidColorAnalysis(content_rect, contents_scale,
+ &analysis);
+ raster_source->PlaybackToCanvas(&canvas, content_rect, contents_scale);
- raster_source_->PerformSolidColorAnalysis(content_rect_,
- contents_scale_, &analysis);
- raster_source_->PlaybackToCanvas(&canvas, content_rect_,
- contents_scale_);
+ *is_solid_color = analysis.is_solid_color;
- is_solid_color_ = analysis.is_solid_color;
-
- timer.NextLap();
- } while (!timer.HasTimeLimitExpired());
- base::TimeDelta duration =
- base::TimeDelta::FromMillisecondsD(timer.MsPerLap());
- if (duration < best_time_)
- best_time_ = duration;
- }
+ timer.NextLap();
+ } while (!timer.HasTimeLimitExpired());
+ base::TimeDelta duration =
+ base::TimeDelta::FromMillisecondsD(timer.MsPerLap());
+ if (duration < *min_time)
+ *min_time = duration;
}
-
- bool IsSolidColor() const { return is_solid_color_; }
- base::TimeDelta GetBestTime() const { return best_time_; }
-
- private:
- ~BenchmarkRasterTask() override {}
-
- RasterSource* raster_source_;
- gfx::Rect content_rect_;
- float contents_scale_;
- size_t repeat_count_;
- bool is_solid_color_;
- base::TimeDelta best_time_;
-};
+}
class FixedInvalidationPictureLayerTilingClient
: public PictureLayerTilingClient {
@@ -196,12 +173,6 @@
return;
}
- TaskGraphRunner* task_graph_runner = TileTaskWorkerPool::GetTaskGraphRunner();
- DCHECK(task_graph_runner);
-
- if (!task_namespace_.IsValid())
- task_namespace_ = task_graph_runner->GetNamespaceToken();
-
FixedInvalidationPictureLayerTilingClient client(
layer, gfx::Rect(layer->content_bounds()));
@@ -227,36 +198,17 @@
gfx::Rect content_rect = (*it)->content_rect();
float contents_scale = (*it)->contents_scale();
- scoped_refptr<BenchmarkRasterTask> benchmark_raster_task(
- new BenchmarkRasterTask(raster_source,
- content_rect,
- contents_scale,
- rasterize_repeat_count_));
-
- TaskGraph graph;
-
- graph.nodes.push_back(
- TaskGraph::Node(benchmark_raster_task.get(),
- TileTaskWorkerPool::kBenchmarkTaskPriority, 0u));
-
- task_graph_runner->ScheduleTasks(task_namespace_, &graph);
- task_graph_runner->WaitForTasksToFinishRunning(task_namespace_);
-
- Task::Vector completed_tasks;
- task_graph_runner->CollectCompletedTasks(task_namespace_, &completed_tasks);
- DCHECK_EQ(1u, completed_tasks.size());
- DCHECK_EQ(completed_tasks[0], benchmark_raster_task);
+ base::TimeDelta min_time;
+ bool is_solid_color = false;
+ RunBenchmark(raster_source, content_rect, contents_scale,
+ rasterize_repeat_count_, &min_time, &is_solid_color);
int tile_size = content_rect.width() * content_rect.height();
- base::TimeDelta min_time = benchmark_raster_task->GetBestTime();
- bool is_solid_color = benchmark_raster_task->IsSolidColor();
-
if (layer->contents_opaque())
rasterize_results_.pixels_rasterized_as_opaque += tile_size;
- if (!is_solid_color) {
+ if (!is_solid_color)
rasterize_results_.pixels_rasterized_with_non_solid_color += tile_size;
- }
rasterize_results_.pixels_rasterized += tile_size;
rasterize_results_.total_best_time += min_time;
diff --git a/cc/debug/rasterize_and_record_benchmark_impl.h b/cc/debug/rasterize_and_record_benchmark_impl.h
index 7ca471a..e9ca27d 100644
--- a/cc/debug/rasterize_and_record_benchmark_impl.h
+++ b/cc/debug/rasterize_and_record_benchmark_impl.h
@@ -50,7 +50,6 @@
RasterizeResults rasterize_results_;
int rasterize_repeat_count_;
- NamespaceToken task_namespace_;
};
} // namespace cc
diff --git a/cc/layers/picture_layer_impl.cc b/cc/layers/picture_layer_impl.cc
index 6845a07..3dbce3c 100644
--- a/cc/layers/picture_layer_impl.cc
+++ b/cc/layers/picture_layer_impl.cc
@@ -283,7 +283,7 @@
// normally the same as draw viewport but can be independently overridden by
// embedders like Android WebView with SetExternalDrawConstraints.
gfx::Rect scaled_viewport_for_tile_priority = gfx::ScaleToEnclosingRect(
- GetViewportForTilePriorityInContentSpace(), max_contents_scale);
+ viewport_rect_for_tile_priority_in_content_space_, max_contents_scale);
size_t missing_tile_count = 0u;
size_t on_demand_missing_tile_count = 0u;
@@ -474,8 +474,7 @@
double current_frame_time_in_seconds =
(layer_tree_impl()->CurrentBeginFrameArgs().frame_time -
base::TimeTicks()).InSecondsF();
- gfx::Rect viewport_rect_in_layer_space =
- GetViewportForTilePriorityInContentSpace();
+ UpdateViewportRectForTilePriorityInContentSpace();
// The tiling set can require tiles for activation any of the following
// conditions are true:
@@ -496,13 +495,13 @@
// Pass |occlusion_in_content_space| for |occlusion_in_layer_space| since
// they are the same space in picture layer, as contents scale is always 1.
bool updated = tilings_->UpdateTilePriorities(
- viewport_rect_in_layer_space, ideal_contents_scale_,
+ viewport_rect_for_tile_priority_in_content_space_, ideal_contents_scale_,
current_frame_time_in_seconds, occlusion_in_content_space,
can_require_tiles_for_activation);
return updated;
}
-gfx::Rect PictureLayerImpl::GetViewportForTilePriorityInContentSpace() const {
+void PictureLayerImpl::UpdateViewportRectForTilePriorityInContentSpace() {
// If visible_rect_for_tile_priority_ is empty or
// viewport_rect_for_tile_priority is set to be different from the device
// viewport, try to inverse project the viewport into layer space and use
@@ -510,7 +509,6 @@
gfx::Rect visible_rect_in_content_space = visible_rect_for_tile_priority_;
gfx::Rect viewport_rect_for_tile_priority =
layer_tree_impl()->ViewportRectForTilePriority();
-
if (visible_rect_in_content_space.IsEmpty() ||
layer_tree_impl()->DeviceViewport() != viewport_rect_for_tile_priority) {
gfx::Transform view_to_layer(gfx::Transform::kSkipInitialization);
@@ -521,7 +519,8 @@
view_to_layer, viewport_rect_for_tile_priority));
}
}
- return visible_rect_in_content_space;
+ viewport_rect_for_tile_priority_in_content_space_ =
+ visible_rect_in_content_space;
}
PictureLayerImpl* PictureLayerImpl::GetPendingOrActiveTwinLayer() const {
@@ -1180,8 +1179,8 @@
state->EndArray();
MathUtil::AddToTracedValue("tile_priority_rect",
- GetViewportForTilePriorityInContentSpace(), state);
-
+ viewport_rect_for_tile_priority_in_content_space_,
+ state);
MathUtil::AddToTracedValue("visible_rect", visible_content_rect(), state);
state->BeginArray("pictures");
@@ -1240,7 +1239,7 @@
if (visible_rect_for_tile_priority_.IsEmpty())
return true;
- gfx::Rect rect = GetViewportForTilePriorityInContentSpace();
+ gfx::Rect rect = viewport_rect_for_tile_priority_in_content_space_;
rect.Intersect(visible_rect_for_tile_priority_);
// The high resolution tiling is the only tiling that can mark tiles as
diff --git a/cc/layers/picture_layer_impl.h b/cc/layers/picture_layer_impl.h
index 57947cc..e6554cd 100644
--- a/cc/layers/picture_layer_impl.h
+++ b/cc/layers/picture_layer_impl.h
@@ -119,7 +119,7 @@
float MinimumContentsScale() const;
float MaximumContentsScale() const;
void ResetRasterScale();
- gfx::Rect GetViewportForTilePriorityInContentSpace() const;
+ void UpdateViewportRectForTilePriorityInContentSpace();
PictureLayerImpl* GetRecycledTwinLayer() const;
void SanityCheckTilingState() const;
@@ -173,6 +173,7 @@
// from regular draws. Save a copy of the required draw properties of the last
// frame that has a valid viewport for prioritizing tiles.
gfx::Rect visible_rect_for_tile_priority_;
+ gfx::Rect viewport_rect_for_tile_priority_in_content_space_;
DISALLOW_COPY_AND_ASSIGN(PictureLayerImpl);
};
diff --git a/cc/layers/picture_layer_impl_unittest.cc b/cc/layers/picture_layer_impl_unittest.cc
index 0c22377..0f4bf8d 100644
--- a/cc/layers/picture_layer_impl_unittest.cc
+++ b/cc/layers/picture_layer_impl_unittest.cc
@@ -428,7 +428,7 @@
// Verify the viewport rect for tile priority is used in picture layer tiling.
EXPECT_EQ(viewport_rect_for_tile_priority_in_view_space,
- active_layer_->GetViewportForTilePriorityInContentSpace());
+ active_layer_->viewport_rect_for_tile_priority_in_content_space());
PictureLayerTilingSet* tilings = active_layer_->tilings();
for (size_t i = 0; i < tilings->num_tilings(); i++) {
PictureLayerTiling* tiling = tilings->tiling_at(i);
@@ -470,7 +470,7 @@
screen_to_view, viewport_rect_for_tile_priority));
EXPECT_EQ(viewport_rect_for_tile_priority_in_view_space,
- active_layer_->GetViewportForTilePriorityInContentSpace());
+ active_layer_->viewport_rect_for_tile_priority_in_content_space());
tilings = active_layer_->tilings();
for (size_t i = 0; i < tilings->num_tilings(); i++) {
PictureLayerTiling* tiling = tilings->tiling_at(i);
@@ -564,6 +564,61 @@
EXPECT_EQ(viewport, active_layer_->visible_rect_for_tile_priority());
}
+TEST_F(PictureLayerImplTest, ViewportRectForTilePriorityIsCached) {
+ base::TimeTicks time_ticks;
+ time_ticks += base::TimeDelta::FromMilliseconds(1);
+ host_impl_.SetCurrentBeginFrameArgs(
+ CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, time_ticks));
+ gfx::Size tile_size(100, 100);
+ gfx::Size layer_bounds(400, 400);
+
+ scoped_refptr<FakePicturePileImpl> pending_pile =
+ FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds);
+ scoped_refptr<FakePicturePileImpl> active_pile =
+ FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds);
+
+ SetupTreesWithInvalidation(pending_pile, active_pile, Region());
+
+ SetupDrawPropertiesAndUpdateTiles(active_layer_, 1.f, 1.f, 1.f, 1.f, false);
+
+ time_ticks += base::TimeDelta::FromMilliseconds(200);
+ host_impl_.SetCurrentBeginFrameArgs(
+ CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, time_ticks));
+
+ bool resourceless_software_draw = false;
+ gfx::Rect viewport = gfx::Rect(layer_bounds);
+ gfx::Rect viewport_rect_for_tile_priority(0, 0, 100, 100);
+ gfx::Transform transform, transform_for_tile_priority;
+
+ host_impl_.SetExternalDrawConstraints(
+ transform, viewport, viewport, viewport_rect_for_tile_priority,
+ transform_for_tile_priority, resourceless_software_draw);
+ host_impl_.active_tree()->UpdateDrawProperties();
+
+ EXPECT_EQ(viewport_rect_for_tile_priority,
+ active_layer_->viewport_rect_for_tile_priority_in_content_space());
+
+ time_ticks += base::TimeDelta::FromMilliseconds(200);
+ host_impl_.SetCurrentBeginFrameArgs(
+ CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, time_ticks));
+
+ gfx::Rect another_viewport_rect_for_tile_priority(11, 11, 50, 50);
+ host_impl_.SetExternalDrawConstraints(
+ transform, viewport, viewport, another_viewport_rect_for_tile_priority,
+ transform_for_tile_priority, resourceless_software_draw);
+
+ // Didn't call UpdateDrawProperties yet. The viewport rect for tile priority
+ // should remain to be the previously cached value.
+ EXPECT_EQ(viewport_rect_for_tile_priority,
+ active_layer_->viewport_rect_for_tile_priority_in_content_space());
+ host_impl_.active_tree()->UpdateDrawProperties();
+
+ // Now the UpdateDrawProperties is called. The viewport rect for tile
+ // priority should be the latest value.
+ EXPECT_EQ(another_viewport_rect_for_tile_priority,
+ active_layer_->viewport_rect_for_tile_priority_in_content_space());
+}
+
TEST_F(PictureLayerImplTest, ClonePartialInvalidation) {
gfx::Size tile_size(100, 100);
gfx::Size layer_bounds(400, 400);
@@ -1681,7 +1736,7 @@
// Intersect the two rects. Any tile outside should not be required for
// activation.
gfx::Rect viewport_for_tile_priority =
- pending_layer_->GetViewportForTilePriorityInContentSpace();
+ pending_layer_->viewport_rect_for_tile_priority_in_content_space();
viewport_for_tile_priority.Intersect(pending_layer_->visible_content_rect());
int num_inside = 0;
diff --git a/cc/resources/task_graph_runner_perftest.cc b/cc/resources/task_graph_runner_perftest.cc
index 51dad74..cbd5c5c 100644
--- a/cc/resources/task_graph_runner_perftest.cc
+++ b/cc/resources/task_graph_runner_perftest.cc
@@ -51,12 +51,6 @@
}
void TearDown() override { task_graph_runner_ = nullptr; }
- void AfterTest(const std::string& test_name) {
- // Format matches chrome/test/perf/perf_test.h:PrintResult
- printf(
- "*RESULT %s: %.2f runs/s\n", test_name.c_str(), timer_.LapsPerSecond());
- }
-
void RunBuildTaskGraphTest(const std::string& test_name,
int num_top_level_tasks,
int num_tasks,
diff --git a/cc/resources/video_resource_updater.cc b/cc/resources/video_resource_updater.cc
index f6d08d1..4369e08 100644
--- a/cc/resources/video_resource_updater.cc
+++ b/cc/resources/video_resource_updater.cc
@@ -144,6 +144,7 @@
case media::VideoFrame::YV12A:
case media::VideoFrame::YV16:
case media::VideoFrame::YV12J:
+ case media::VideoFrame::YV12HD:
case media::VideoFrame::YV24:
case media::VideoFrame::NATIVE_TEXTURE:
#if defined(VIDEO_HOLE)
@@ -191,6 +192,7 @@
input_frame_format != media::VideoFrame::I420 &&
input_frame_format != media::VideoFrame::YV12A &&
input_frame_format != media::VideoFrame::YV12J &&
+ input_frame_format != media::VideoFrame::YV12HD &&
input_frame_format != media::VideoFrame::YV16 &&
input_frame_format != media::VideoFrame::YV24) {
NOTREACHED() << input_frame_format;
diff --git a/cc/test/fake_layer_tree_host_client.h b/cc/test/fake_layer_tree_host_client.h
index f256ab1..5f7afa5 100644
--- a/cc/test/fake_layer_tree_host_client.h
+++ b/cc/test/fake_layer_tree_host_client.h
@@ -50,6 +50,7 @@
void DidCommit() override {}
void DidCommitAndDrawFrame() override {}
void DidCompleteSwapBuffers() override {}
+ void DidCompletePageScaleAnimation() override {}
// LayerTreeHostSingleThreadClient implementation.
void DidPostSwapBuffers() override {}
diff --git a/cc/test/fake_layer_tree_host_impl_client.h b/cc/test/fake_layer_tree_host_impl_client.h
index 98aafa0..d7a785b 100644
--- a/cc/test/fake_layer_tree_host_impl_client.h
+++ b/cc/test/fake_layer_tree_host_impl_client.h
@@ -39,6 +39,7 @@
base::TimeDelta delay) override {}
void DidActivateSyncTree() override {}
void DidPrepareTiles() override {}
+ void DidCompletePageScaleAnimationOnImplThread() override {}
};
} // namespace cc
diff --git a/cc/test/fake_picture_layer_impl.cc b/cc/test/fake_picture_layer_impl.cc
index 2d2e329..132160f 100644
--- a/cc/test/fake_picture_layer_impl.cc
+++ b/cc/test/fake_picture_layer_impl.cc
@@ -201,7 +201,7 @@
if (visible_rect_for_tile_priority_.IsEmpty())
return 0;
- gfx::Rect rect = GetViewportForTilePriorityInContentSpace();
+ gfx::Rect rect = viewport_rect_for_tile_priority_in_content_space_;
rect.Intersect(visible_rect_for_tile_priority_);
size_t count = 0;
diff --git a/cc/test/fake_picture_layer_impl.h b/cc/test/fake_picture_layer_impl.h
index 5795d55..a0e16e8 100644
--- a/cc/test/fake_picture_layer_impl.h
+++ b/cc/test/fake_picture_layer_impl.h
@@ -77,7 +77,6 @@
using PictureLayerImpl::CleanUpTilingsOnActiveLayer;
using PictureLayerImpl::CanHaveTilings;
using PictureLayerImpl::MinimumContentsScale;
- using PictureLayerImpl::GetViewportForTilePriorityInContentSpace;
using PictureLayerImpl::SanityCheckTilingState;
using PictureLayerImpl::GetRecycledTwinLayer;
using PictureLayerImpl::UpdateRasterSource;
@@ -108,6 +107,10 @@
return visible_rect_for_tile_priority_;
}
+ gfx::Rect viewport_rect_for_tile_priority_in_content_space() {
+ return viewport_rect_for_tile_priority_in_content_space_;
+ }
+
void set_fixed_tile_size(const gfx::Size& size) { fixed_tile_size_ = size; }
void CreateAllTiles();
diff --git a/cc/test/layer_tree_test.cc b/cc/test/layer_tree_test.cc
index 9653d8d..a40a8c7 100644
--- a/cc/test/layer_tree_test.cc
+++ b/cc/test/layer_tree_test.cc
@@ -373,6 +373,7 @@
void DidPostSwapBuffers() override {}
void DidAbortSwapBuffers() override {}
void ScheduleComposite() override { test_hooks_->ScheduleComposite(); }
+ void DidCompletePageScaleAnimation() override {}
private:
explicit LayerTreeHostClientForTesting(TestHooks* test_hooks)
diff --git a/cc/test/test_gpu_memory_buffer_manager.cc b/cc/test/test_gpu_memory_buffer_manager.cc
index 3583ff3..196922f 100644
--- a/cc/test/test_gpu_memory_buffer_manager.cc
+++ b/cc/test/test_gpu_memory_buffer_manager.cc
@@ -10,12 +10,12 @@
namespace cc {
namespace {
-size_t BytesPerPixel(gfx::GpuMemoryBuffer::Format format) {
+size_t StrideInBytes(size_t width, gfx::GpuMemoryBuffer::Format format) {
switch (format) {
case gfx::GpuMemoryBuffer::RGBA_8888:
case gfx::GpuMemoryBuffer::RGBX_8888:
case gfx::GpuMemoryBuffer::BGRA_8888:
- return 4;
+ return width * 4;
}
NOTREACHED();
@@ -35,7 +35,8 @@
// Overridden from gfx::GpuMemoryBuffer:
void* Map() override {
DCHECK(!mapped_);
- if (!shared_memory_->Map(size_.GetArea() * BytesPerPixel(format_)))
+ if (!shared_memory_->Map(StrideInBytes(size_.width(), format_) *
+ size_.height()))
return NULL;
mapped_ = true;
return shared_memory_->memory();
@@ -48,7 +49,7 @@
bool IsMapped() const override { return mapped_; }
Format GetFormat() const override { return format_; }
uint32 GetStride() const override {
- return size_.width() * BytesPerPixel(format_);
+ return StrideInBytes(size_.width(), format_);
}
gfx::GpuMemoryBufferHandle GetHandle() const override {
gfx::GpuMemoryBufferHandle handle;
@@ -81,7 +82,8 @@
gfx::GpuMemoryBuffer::Format format,
gfx::GpuMemoryBuffer::Usage usage) {
scoped_ptr<base::SharedMemory> shared_memory(new base::SharedMemory);
- if (!shared_memory->CreateAnonymous(size.GetArea() * BytesPerPixel(format)))
+ if (!shared_memory->CreateAnonymous(StrideInBytes(size.width(), format) *
+ size.height()))
return nullptr;
return make_scoped_ptr<gfx::GpuMemoryBuffer>(
new GpuMemoryBufferImpl(size, format, shared_memory.Pass()));
diff --git a/cc/trees/layer_tree_host.cc b/cc/trees/layer_tree_host.cc
index b6e6473..f91cce9 100644
--- a/cc/trees/layer_tree_host.cc
+++ b/cc/trees/layer_tree_host.cc
@@ -130,6 +130,7 @@
background_color_(SK_ColorWHITE),
has_transparent_background_(false),
partial_texture_update_requests_(0),
+ did_complete_scale_animation_(false),
in_paint_layer_contents_(false),
total_frames_used_for_lcd_text_metrics_(0),
id_(s_layer_tree_host_sequence_number.GetNext() + 1),
@@ -183,8 +184,6 @@
LayerTreeHost::~LayerTreeHost() {
TRACE_EVENT0("cc", "LayerTreeHost::~LayerTreeHost");
- overhang_ui_resource_ = nullptr;
-
if (root_layer_.get())
root_layer_->SetLayerTreeHost(NULL);
@@ -360,11 +359,6 @@
sync_tree->set_ui_resource_request_queue(ui_resource_request_queue_);
ui_resource_request_queue_.clear();
}
- if (overhang_ui_resource_) {
- host_impl->SetOverhangUIResource(
- overhang_ui_resource_->id(),
- GetUIResourceSize(overhang_ui_resource_->id()));
- }
DCHECK(!sync_tree->ViewportSizeInvalid());
@@ -403,6 +397,10 @@
void LayerTreeHost::CommitComplete() {
source_frame_number_++;
client_->DidCommit();
+ if (did_complete_scale_animation_) {
+ client_->DidCompletePageScaleAnimation();
+ did_complete_scale_animation_ = false;
+ }
}
void LayerTreeHost::SetOutputSurface(scoped_ptr<OutputSurface> surface) {
@@ -715,23 +713,6 @@
SetNeedsCommit();
}
-void LayerTreeHost::SetOverhangBitmap(const SkBitmap& bitmap) {
- DCHECK(bitmap.width() && bitmap.height());
- DCHECK_EQ(bitmap.bytesPerPixel(), 4);
-
- SkBitmap bitmap_copy;
- if (bitmap.isImmutable()) {
- bitmap_copy = bitmap;
- } else {
- bitmap.copyTo(&bitmap_copy);
- bitmap_copy.setImmutable();
- }
-
- UIResourceBitmap overhang_bitmap(bitmap_copy);
- overhang_bitmap.SetWrapMode(UIResourceBitmap::REPEAT);
- overhang_ui_resource_ = ScopedUIResource::Create(this, overhang_bitmap);
-}
-
void LayerTreeHost::SetVisible(bool visible) {
if (visible_ == visible)
return;
@@ -788,6 +769,10 @@
return result || next_commit_forces_redraw_;
}
+void LayerTreeHost::DidCompletePageScaleAnimation() {
+ did_complete_scale_animation_ = true;
+}
+
static Layer* FindFirstScrollableLayer(Layer* layer) {
if (!layer)
return NULL;
diff --git a/cc/trees/layer_tree_host.h b/cc/trees/layer_tree_host.h
index 9069b9d..68bc1eb 100644
--- a/cc/trees/layer_tree_host.h
+++ b/cc/trees/layer_tree_host.h
@@ -135,6 +135,9 @@
void DeleteContentsTexturesOnImplThread(ResourceProvider* resource_provider);
bool UpdateLayers(ResourceUpdateQueue* queue);
+ // Called when the compositor completed page scale animation.
+ void DidCompletePageScaleAnimation();
+
LayerTreeHostClient* client() { return client_; }
const base::WeakPtr<InputHandler>& GetInputHandler() {
return input_handler_weak_ptr_;
@@ -232,8 +235,6 @@
has_transparent_background_ = transparent;
}
- void SetOverhangBitmap(const SkBitmap& bitmap);
-
PrioritizedResourceManager* contents_texture_manager() const {
return contents_texture_manager_.get();
}
@@ -438,10 +439,6 @@
SkColor background_color_;
bool has_transparent_background_;
- // If set, this texture is used to fill in the parts of the screen not
- // covered by layers.
- scoped_ptr<ScopedUIResource> overhang_ui_resource_;
-
typedef ScopedPtrVector<PrioritizedResource> TextureList;
size_t partial_texture_update_requests_;
@@ -449,6 +446,10 @@
scoped_ptr<PendingPageScaleAnimation> pending_page_scale_animation_;
+ // If set, then page scale animation has completed, but the client hasn't been
+ // notified about it yet.
+ bool did_complete_scale_animation_;
+
bool in_paint_layer_contents_;
static const int kTotalFramesToUseForLCDTextMetrics = 50;
diff --git a/cc/trees/layer_tree_host_client.h b/cc/trees/layer_tree_host_client.h
index a09693f..ac025f2 100644
--- a/cc/trees/layer_tree_host_client.h
+++ b/cc/trees/layer_tree_host_client.h
@@ -49,6 +49,9 @@
virtual void DidCommitAndDrawFrame() = 0;
virtual void DidCompleteSwapBuffers() = 0;
+ // Called when page scale animation has completed.
+ virtual void DidCompletePageScaleAnimation() = 0;
+
// TODO(simonhong): Makes this to pure virtual function when client
// implementation is ready.
virtual void SendBeginFramesToChildren(const BeginFrameArgs& args) {}
diff --git a/cc/trees/layer_tree_host_impl.cc b/cc/trees/layer_tree_host_impl.cc
index 526d456..3fe5f4a 100644
--- a/cc/trees/layer_tree_host_impl.cc
+++ b/cc/trees/layer_tree_host_impl.cc
@@ -220,7 +220,6 @@
max_memory_needed_bytes_(0),
zero_budget_(false),
device_scale_factor_(1.f),
- overhang_ui_resource_id_(0),
resourceless_software_draw_(false),
begin_impl_frame_interval_(BeginFrameArgs::DefaultInterval()),
animation_registrar_(AnimationRegistrar::Create()),
@@ -595,8 +594,6 @@
}
static void AppendQuadsToFillScreen(
- ResourceProvider::ResourceId overhang_resource_id,
- const gfx::SizeF& overhang_resource_scaled_size,
const gfx::Rect& root_scroll_layer_rect,
RenderPass* target_render_pass,
LayerImpl* root_layer,
@@ -609,16 +606,6 @@
if (fill_region.IsEmpty())
return;
- // Divide the fill region into the part to be filled with the overhang
- // resource and the part to be filled with the background color.
- Region screen_background_color_region = fill_region;
- Region overhang_region;
- if (overhang_resource_id) {
- overhang_region = fill_region;
- overhang_region.Subtract(root_scroll_layer_rect);
- screen_background_color_region.Intersect(root_scroll_layer_rect);
- }
-
// Manually create the quad state for the gutter quads, as the root layer
// doesn't have any bounds and so can't generate this itself.
// TODO(danakj): Make the gutter quads generated by the solid color layer
@@ -638,8 +625,7 @@
SkXfermode::kSrcOver_Mode,
sorting_context_id);
- for (Region::Iterator fill_rects(screen_background_color_region);
- fill_rects.has_rect();
+ for (Region::Iterator fill_rects(fill_region); fill_rects.has_rect();
fill_rects.next()) {
gfx::Rect screen_space_rect = fill_rects.rect();
gfx::Rect visible_screen_space_rect = screen_space_rect;
@@ -653,35 +639,6 @@
screen_background_color,
false);
}
- for (Region::Iterator fill_rects(overhang_region);
- fill_rects.has_rect();
- fill_rects.next()) {
- DCHECK(overhang_resource_id);
- gfx::Rect screen_space_rect = fill_rects.rect();
- gfx::Rect opaque_screen_space_rect = screen_space_rect;
- gfx::Rect visible_screen_space_rect = screen_space_rect;
- TextureDrawQuad* tex_quad =
- target_render_pass->CreateAndAppendDrawQuad<TextureDrawQuad>();
- const float vertex_opacity[4] = {1.f, 1.f, 1.f, 1.f};
- tex_quad->SetNew(
- shared_quad_state,
- screen_space_rect,
- opaque_screen_space_rect,
- visible_screen_space_rect,
- overhang_resource_id,
- false,
- gfx::PointF(
- screen_space_rect.x() / overhang_resource_scaled_size.width(),
- screen_space_rect.y() / overhang_resource_scaled_size.height()),
- gfx::PointF(
- screen_space_rect.right() / overhang_resource_scaled_size.width(),
- screen_space_rect.bottom() /
- overhang_resource_scaled_size.height()),
- screen_background_color,
- vertex_opacity,
- false,
- false);
- }
}
DrawResult LayerTreeHostImpl::CalculateRenderPasses(
@@ -894,8 +851,6 @@
if (!active_tree_->has_transparent_background()) {
frame->render_passes.back()->has_transparent_background = false;
AppendQuadsToFillScreen(
- ResourceIdForUIResource(overhang_ui_resource_id_),
- gfx::ScaleSize(overhang_ui_resource_size_, device_scale_factor_),
active_tree_->RootScrollLayerDeviceViewportBounds(),
frame->render_passes.back(),
active_tree_->root_layer(),
@@ -2234,13 +2189,6 @@
active_tree_->set_needs_update_draw_properties();
}
-void LayerTreeHostImpl::SetOverhangUIResource(
- UIResourceId overhang_ui_resource_id,
- const gfx::Size& overhang_ui_resource_size) {
- overhang_ui_resource_id_ = overhang_ui_resource_id;
- overhang_ui_resource_size_ = overhang_ui_resource_size;
-}
-
void LayerTreeHostImpl::SetDeviceScaleFactor(float device_scale_factor) {
if (device_scale_factor == device_scale_factor_)
return;
@@ -3106,6 +3054,7 @@
page_scale_animation_ = nullptr;
client_->SetNeedsCommitOnImplThread();
client_->RenewTreePriority();
+ client_->DidCompletePageScaleAnimationOnImplThread();
} else {
SetNeedsAnimate();
}
diff --git a/cc/trees/layer_tree_host_impl.h b/cc/trees/layer_tree_host_impl.h
index 98d7e4b..2728ff8 100644
--- a/cc/trees/layer_tree_host_impl.h
+++ b/cc/trees/layer_tree_host_impl.h
@@ -108,6 +108,9 @@
virtual void DidActivateSyncTree() = 0;
virtual void DidPrepareTiles() = 0;
+ // Called when page scale animation has completed on the impl thread.
+ virtual void DidCompletePageScaleAnimationOnImplThread() = 0;
+
protected:
virtual ~LayerTreeHostImplClient() {}
};
@@ -356,9 +359,6 @@
void SetViewportSize(const gfx::Size& device_viewport_size);
gfx::Size device_viewport_size() const { return device_viewport_size_; }
- void SetOverhangUIResource(UIResourceId overhang_ui_resource_id,
- const gfx::Size& overhang_ui_resource_size);
-
void SetDeviceScaleFactor(float device_scale_factor);
float device_scale_factor() const { return device_scale_factor_; }
@@ -686,10 +686,6 @@
// pageScaleFactor=1.
float device_scale_factor_;
- // UI resource to use for drawing overhang gutters.
- UIResourceId overhang_ui_resource_id_;
- gfx::Size overhang_ui_resource_size_;
-
// Optional top-level constraints that can be set by the OutputSurface.
// - external_transform_ applies a transform above the root layer
// - external_viewport_ is used DrawProperties, tile management and
diff --git a/cc/trees/layer_tree_host_impl_unittest.cc b/cc/trees/layer_tree_host_impl_unittest.cc
index 6c46d8f..7804f22 100644
--- a/cc/trees/layer_tree_host_impl_unittest.cc
+++ b/cc/trees/layer_tree_host_impl_unittest.cc
@@ -88,6 +88,7 @@
did_request_redraw_(false),
did_request_animate_(false),
did_request_prepare_tiles_(false),
+ did_complete_page_scale_animation_(false),
reduce_memory_result_(true),
current_limit_bytes_(0),
current_priority_cutoff_value_(0) {
@@ -151,6 +152,9 @@
}
void DidActivateSyncTree() override {}
void DidPrepareTiles() override {}
+ void DidCompletePageScaleAnimationOnImplThread() override {
+ did_complete_page_scale_animation_ = true;
+ }
void set_reduce_memory_result(bool reduce_memory_result) {
reduce_memory_result_ = reduce_memory_result;
@@ -394,6 +398,7 @@
bool did_request_redraw_;
bool did_request_animate_;
bool did_request_prepare_tiles_;
+ bool did_complete_page_scale_animation_;
bool reduce_memory_result_;
base::Closure scrollbar_fade_start_;
base::TimeDelta requested_scrollbar_animation_delay_;
@@ -1341,6 +1346,38 @@
ExpectContains(*scroll_info, scroll_layer->id(), gfx::Vector2d(-50, -50));
}
+TEST_F(LayerTreeHostImplTest, PageScaleAnimationCompletedNotification) {
+ SetupScrollAndContentsLayers(gfx::Size(100, 100));
+ host_impl_->SetViewportSize(gfx::Size(50, 50));
+ DrawFrame();
+
+ LayerImpl* scroll_layer = host_impl_->InnerViewportScrollLayer();
+ DCHECK(scroll_layer);
+
+ base::TimeTicks start_time =
+ base::TimeTicks() + base::TimeDelta::FromSeconds(1);
+ base::TimeDelta duration = base::TimeDelta::FromMilliseconds(100);
+ base::TimeTicks halfway_through_animation = start_time + duration / 2;
+ base::TimeTicks end_time = start_time + duration;
+
+ host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, 0.5f, 4.f);
+ scroll_layer->SetScrollOffset(gfx::ScrollOffset(50, 50));
+
+ did_complete_page_scale_animation_ = false;
+ host_impl_->active_tree()->SetPendingPageScaleAnimation(
+ scoped_ptr<PendingPageScaleAnimation>(new PendingPageScaleAnimation(
+ gfx::Vector2d(), false, 2.f, duration)));
+ host_impl_->ActivateSyncTree();
+ host_impl_->Animate(start_time);
+ EXPECT_FALSE(did_complete_page_scale_animation_);
+
+ host_impl_->Animate(halfway_through_animation);
+ EXPECT_FALSE(did_complete_page_scale_animation_);
+
+ host_impl_->Animate(end_time);
+ EXPECT_TRUE(did_complete_page_scale_animation_);
+}
+
class LayerTreeHostImplOverridePhysicalTime : public LayerTreeHostImpl {
public:
LayerTreeHostImplOverridePhysicalTime(
@@ -4717,49 +4754,6 @@
TestLayerIsLargerThanViewport();
}
-TEST_F(LayerTreeHostImplViewportCoveredTest, ViewportCoveredOverhangBitmap) {
- viewport_size_ = gfx::Size(1000, 1000);
-
- bool always_draw = false;
- CreateHostImpl(DefaultSettings(), CreateFakeOutputSurface(always_draw));
-
- host_impl_->SetViewportSize(DipSizeToPixelSize(viewport_size_));
- SetupActiveTreeLayers();
-
- // Specify an overhang bitmap to use.
- bool is_opaque = false;
- UIResourceBitmap ui_resource_bitmap(gfx::Size(2, 2), is_opaque);
- ui_resource_bitmap.SetWrapMode(UIResourceBitmap::REPEAT);
- UIResourceId ui_resource_id = 12345;
- host_impl_->CreateUIResource(ui_resource_id, ui_resource_bitmap);
- host_impl_->SetOverhangUIResource(ui_resource_id, gfx::Size(32, 32));
- set_gutter_quad_material(DrawQuad::TEXTURE_CONTENT);
- set_gutter_texture_size(gfx::Size(32, 32));
-
- TestLayerCoversFullViewport();
- TestEmptyLayer();
- TestLayerInMiddleOfViewport();
- TestLayerIsLargerThanViewport();
-
- // Change the resource size.
- host_impl_->SetOverhangUIResource(ui_resource_id, gfx::Size(128, 16));
- set_gutter_texture_size(gfx::Size(128, 16));
-
- TestLayerCoversFullViewport();
- TestEmptyLayer();
- TestLayerInMiddleOfViewport();
- TestLayerIsLargerThanViewport();
-
- // Change the device scale factor
- host_impl_->SetDeviceScaleFactor(2.f);
- host_impl_->SetViewportSize(DipSizeToPixelSize(viewport_size_));
-
- TestLayerCoversFullViewport();
- TestEmptyLayer();
- TestLayerInMiddleOfViewport();
- TestLayerIsLargerThanViewport();
-}
-
TEST_F(LayerTreeHostImplViewportCoveredTest, ActiveTreeGrowViewportInvalid) {
viewport_size_ = gfx::Size(1000, 1000);
diff --git a/cc/trees/layer_tree_host_unittest_animation.cc b/cc/trees/layer_tree_host_unittest_animation.cc
index 75d8ab0..3868c87 100644
--- a/cc/trees/layer_tree_host_unittest_animation.cc
+++ b/cc/trees/layer_tree_host_unittest_animation.cc
@@ -1043,16 +1043,21 @@
void BeginTest() override { PostSetNeedsCommitToMainThread(); }
- void DidCommit() override {
- Animation* animation =
- scroll_layer_->layer_animation_controller()->GetAnimation(
- Animation::ScrollOffset);
- if (animation) {
- scroll_layer_->layer_animation_controller()->RemoveAnimation(
- animation->id());
- scroll_layer_->SetScrollOffset(final_postion_);
- } else {
- EXPECT_EQ(final_postion_, scroll_layer_->scroll_offset());
+ void BeginMainFrame(const BeginFrameArgs& args) override {
+ switch (layer_tree_host()->source_frame_number()) {
+ case 0:
+ break;
+ case 1: {
+ Animation* animation =
+ scroll_layer_->layer_animation_controller()->GetAnimation(
+ Animation::ScrollOffset);
+ scroll_layer_->layer_animation_controller()->RemoveAnimation(
+ animation->id());
+ scroll_layer_->SetScrollOffset(final_postion_);
+ break;
+ }
+ default:
+ EXPECT_EQ(final_postion_, scroll_layer_->scroll_offset());
}
}
diff --git a/cc/trees/layer_tree_host_unittest_no_message_loop.cc b/cc/trees/layer_tree_host_unittest_no_message_loop.cc
index 3e87b55..75eda92 100644
--- a/cc/trees/layer_tree_host_unittest_no_message_loop.cc
+++ b/cc/trees/layer_tree_host_unittest_no_message_loop.cc
@@ -78,6 +78,7 @@
void DidCommit() override { did_commit_ = true; }
void DidCommitAndDrawFrame() override { did_commit_and_draw_frame_ = true; }
void DidCompleteSwapBuffers() override {}
+ void DidCompletePageScaleAnimation() override {}
// LayerTreeHostSingleThreadClient overrides.
void DidPostSwapBuffers() override {}
diff --git a/cc/trees/single_thread_proxy.cc b/cc/trees/single_thread_proxy.cc
index adc42c9..e29f0d1 100644
--- a/cc/trees/single_thread_proxy.cc
+++ b/cc/trees/single_thread_proxy.cc
@@ -447,6 +447,10 @@
scheduler_on_impl_thread_->DidPrepareTiles();
}
+void SingleThreadProxy::DidCompletePageScaleAnimationOnImplThread() {
+ layer_tree_host_->DidCompletePageScaleAnimation();
+}
+
void SingleThreadProxy::UpdateRendererCapabilitiesOnImplThread() {
DCHECK(IsImplThread());
renderer_capabilities_for_main_thread_ =
diff --git a/cc/trees/single_thread_proxy.h b/cc/trees/single_thread_proxy.h
index bdc1030..a6c348a 100644
--- a/cc/trees/single_thread_proxy.h
+++ b/cc/trees/single_thread_proxy.h
@@ -106,6 +106,7 @@
base::TimeDelta delay) override {}
void DidActivateSyncTree() override;
void DidPrepareTiles() override;
+ void DidCompletePageScaleAnimationOnImplThread() override;
void SetDebugState(const LayerTreeDebugState& debug_state) override {}
void RequestNewOutputSurface();
diff --git a/cc/trees/thread_proxy.cc b/cc/trees/thread_proxy.cc
index 243e603..4b360a4 100644
--- a/cc/trees/thread_proxy.cc
+++ b/cc/trees/thread_proxy.cc
@@ -267,6 +267,11 @@
impl_thread_weak_ptr_));
}
+void ThreadProxy::DidCompletePageScaleAnimation() {
+ DCHECK(IsMainThread());
+ layer_tree_host()->DidCompletePageScaleAnimation();
+}
+
const RendererCapabilities& ThreadProxy::GetRendererCapabilities() const {
DCHECK(IsMainThread());
DCHECK(!layer_tree_host()->output_surface_lost());
@@ -1353,4 +1358,11 @@
impl().scheduler->DidPrepareTiles();
}
+void ThreadProxy::DidCompletePageScaleAnimationOnImplThread() {
+ DCHECK(IsImplThread());
+ Proxy::MainThreadTaskRunner()->PostTask(
+ FROM_HERE, base::Bind(&ThreadProxy::DidCompletePageScaleAnimation,
+ main_thread_weak_ptr_));
+}
+
} // namespace cc
diff --git a/cc/trees/thread_proxy.h b/cc/trees/thread_proxy.h
index f8808f9..0d15b5a 100644
--- a/cc/trees/thread_proxy.h
+++ b/cc/trees/thread_proxy.h
@@ -209,6 +209,7 @@
base::TimeDelta delay) override;
void DidActivateSyncTree() override;
void DidPrepareTiles() override;
+ void DidCompletePageScaleAnimationOnImplThread() override;
// SchedulerClient implementation
void WillBeginImplFrame(const BeginFrameArgs& args) override;
@@ -251,6 +252,7 @@
void DidInitializeOutputSurface(bool success,
const RendererCapabilities& capabilities);
void SendCommitRequestToImplThreadIfNeeded();
+ void DidCompletePageScaleAnimation();
// Called on impl thread.
struct SchedulerStateRequest;
diff --git a/crypto/nss_util.cc b/crypto/nss_util.cc
index 02c9327..5ee7c32 100644
--- a/crypto/nss_util.cc
+++ b/crypto/nss_util.cc
@@ -659,11 +659,11 @@
EnsureNSPRInit();
// We *must* have NSS >= 3.14.3.
- COMPILE_ASSERT(
+ static_assert(
(NSS_VMAJOR == 3 && NSS_VMINOR == 14 && NSS_VPATCH >= 3) ||
(NSS_VMAJOR == 3 && NSS_VMINOR > 14) ||
(NSS_VMAJOR > 3),
- nss_version_check_failed);
+ "nss version check failed");
// Also check the run-time NSS version.
// NSS_VersionCheck is a >= check, not strict equality.
if (!NSS_VersionCheck("3.14.3")) {
diff --git a/gpu/GLES2/gl2chromium_autogen.h b/gpu/GLES2/gl2chromium_autogen.h
index e315a9f..8a0011c 100644
--- a/gpu/GLES2/gl2chromium_autogen.h
+++ b/gpu/GLES2/gl2chromium_autogen.h
@@ -55,6 +55,7 @@
#define glDeleteProgram GLES2_GET_FUN(DeleteProgram)
#define glDeleteRenderbuffers GLES2_GET_FUN(DeleteRenderbuffers)
#define glDeleteSamplers GLES2_GET_FUN(DeleteSamplers)
+#define glDeleteSync GLES2_GET_FUN(DeleteSync)
#define glDeleteShader GLES2_GET_FUN(DeleteShader)
#define glDeleteTextures GLES2_GET_FUN(DeleteTextures)
#define glDeleteTransformFeedbacks GLES2_GET_FUN(DeleteTransformFeedbacks)
@@ -68,6 +69,7 @@
#define glDrawElements GLES2_GET_FUN(DrawElements)
#define glEnable GLES2_GET_FUN(Enable)
#define glEnableVertexAttribArray GLES2_GET_FUN(EnableVertexAttribArray)
+#define glFenceSync GLES2_GET_FUN(FenceSync)
#define glFinish GLES2_GET_FUN(Finish)
#define glFlush GLES2_GET_FUN(Flush)
#define glFramebufferRenderbuffer GLES2_GET_FUN(FramebufferRenderbuffer)
@@ -121,6 +123,7 @@
#define glIsRenderbuffer GLES2_GET_FUN(IsRenderbuffer)
#define glIsSampler GLES2_GET_FUN(IsSampler)
#define glIsShader GLES2_GET_FUN(IsShader)
+#define glIsSync GLES2_GET_FUN(IsSync)
#define glIsTexture GLES2_GET_FUN(IsTexture)
#define glIsTransformFeedback GLES2_GET_FUN(IsTransformFeedback)
#define glLineWidth GLES2_GET_FUN(LineWidth)
diff --git a/gpu/command_buffer/build_gles2_cmd_buffer.py b/gpu/command_buffer/build_gles2_cmd_buffer.py
index 38cbb49..922c1f9 100755
--- a/gpu/command_buffer/build_gles2_cmd_buffer.py
+++ b/gpu/command_buffer/build_gles2_cmd_buffer.py
@@ -1368,6 +1368,27 @@
'GL_UNKNOWN_CONTEXT_RESET_ARB',
],
},
+ 'SyncCondition': {
+ 'type': 'GLenum',
+ 'is_complete': True,
+ 'valid': [
+ #TODO(zmo): avoid using the direct number.
+ '0x9117', # GL_SYNC_GPU_COMMANDS_COMPLETE
+ ],
+ 'invalid': [
+ '0',
+ ],
+ },
+ 'SyncFlags': {
+ 'type': 'GLbitfield',
+ 'is_complete': True,
+ 'valid': [
+ '0',
+ ],
+ 'invalid': [
+ '1',
+ ],
+ },
}
# This table specifies the different pepper interfaces that are supported for
@@ -1815,7 +1836,7 @@
'resource_type': 'Framebuffer',
'resource_types': 'Framebuffers',
},
- 'DeleteProgram': {'type': 'Delete', 'decoder_func': 'DoDeleteProgram'},
+ 'DeleteProgram': { 'type': 'Delete' },
'DeleteRenderbuffers': {
'type': 'DELn',
'gl_test_func': 'glDeleteRenderbuffersEXT',
@@ -1828,7 +1849,13 @@
'resource_types': 'Samplers',
'unsafe': True,
},
- 'DeleteShader': {'type': 'Delete', 'decoder_func': 'DoDeleteShader'},
+ 'DeleteShader': { 'type': 'Delete' },
+ 'DeleteSync': {
+ 'type': 'Delete',
+ 'cmd_args': 'GLuint sync',
+ 'resource_type': 'Sync',
+ 'unsafe': True,
+ },
'DeleteTextures': {
'type': 'DELn',
'resource_type': 'Texture',
@@ -1883,6 +1910,11 @@
'decoder_func': 'DoEnableVertexAttribArray',
'impl_decl': False,
},
+ 'FenceSync': {
+ 'type': 'Create',
+ 'client_test': False,
+ 'unsafe': True,
+ },
'Finish': {
'impl_func': False,
'client_test': False,
@@ -2209,6 +2241,7 @@
'IsEnabled': {
'type': 'Is',
'decoder_func': 'DoIsEnabled',
+ 'client_test': False,
'impl_func': False,
'expectation': False,
},
@@ -2238,6 +2271,13 @@
'expectation': False,
'unsafe': True,
},
+ 'IsSync': {
+ 'type': 'Is',
+ 'id_mapping': [ 'Sync' ],
+ 'cmd_args': 'GLuint sync',
+ 'expectation': False,
+ 'unsafe': True,
+ },
'IsTexture': {
'type': 'Is',
'decoder_func': 'DoIsTexture',
@@ -2398,12 +2438,12 @@
'client_test': False,
},
'ShaderSource': {
- 'type': 'Manual',
+ 'type': 'PUTSTR',
+ 'decoder_func': 'DoShaderSource',
'data_transfer_methods': ['bucket'],
- 'needs_size': True,
'client_test': False,
'cmd_args':
- 'GLuint shader, const char* data',
+ 'GLuint shader, const char** str',
'pepper_args':
'GLuint shader, GLsizei count, const char** str, const GLint* length',
},
@@ -3383,17 +3423,23 @@
file.Write(" // TODO(gman): Compute correct size.\n")
file.Write(" EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);\n")
+ def __WriteIdMapping(self, func, file):
+ """Writes client side / service side ID mapping."""
+ if not func.IsUnsafe() or not func.GetInfo('id_mapping'):
+ return
+ for id_type in func.GetInfo('id_mapping'):
+ file.Write(" group_->Get%sServiceId(%s, &%s);\n" %
+ (id_type, id_type.lower(), id_type.lower()))
+
def WriteImmediateHandlerImplementation (self, func, file):
"""Writes the handler impl for the immediate version of a command."""
- if func.IsUnsafe() and func.GetInfo('id_mapping'):
- for id_type in func.GetInfo('id_mapping'):
- file.Write(" group_->Get%sServiceId(%s, &%s);\n" %
- (id_type, id_type.lower(), id_type.lower()))
+ self.__WriteIdMapping(func, file)
file.Write(" %s(%s);\n" %
(func.GetGLFunctionName(), func.MakeOriginalArgString("")))
def WriteBucketHandlerImplementation (self, func, file):
"""Writes the handler impl for the bucket version of a command."""
+ self.__WriteIdMapping(func, file)
file.Write(" %s(%s);\n" %
(func.GetGLFunctionName(), func.MakeOriginalArgString("")))
@@ -3449,9 +3495,7 @@
self.WriteServiceHandlerFunctionHeader(func, file)
self.WriteHandlerExtensionCheck(func, file)
self.WriteHandlerDeferReadWrite(func, file);
- for arg in func.GetOriginalArgs():
- if arg.IsPointer():
- self.WriteGetDataSizeCode(func, file)
+ for arg in func.GetCmdArgs():
arg.WriteGetCode(file)
func.WriteHandlerValidation(file)
func.WriteHandlerImplementation(file)
@@ -4252,10 +4296,6 @@
"""Overrriden from TypeHandler."""
pass
- def WriteBucketCmdHelper(self, func, file):
- """Overrriden from TypeHandler."""
- pass
-
def WriteCmdHelper(self, func, file):
"""Overrriden from TypeHandler."""
pass
@@ -4942,26 +4982,61 @@
"""Overrriden from TypeHandler."""
func.AddCmdArg(Argument("client_id", 'uint32_t'))
+ def __GetResourceType(self, func):
+ if func.return_type == "GLsync":
+ return "Sync"
+ else:
+ return func.name[6:] # Create*
+
def WriteServiceUnitTest(self, func, file, *extras):
"""Overrriden from TypeHandler."""
valid_test = """
TEST_P(%(test_name)s, %(name)sValidArgs) {
- EXPECT_CALL(*gl_, %(gl_func_name)s(%(gl_args)s))
- .WillOnce(Return(kNewServiceId));
+ %(id_type_cast)sEXPECT_CALL(*gl_, %(gl_func_name)s(%(gl_args)s))
+ .WillOnce(Return(%(const_service_id)s));
SpecializedSetup<cmds::%(name)s, 0>(true);
cmds::%(name)s cmd;
- cmd.Init(%(args)s%(comma)skNewClientId);
+ cmd.Init(%(args)s%(comma)skNewClientId);"""
+ if func.IsUnsafe():
+ valid_test += """
+ decoder_->set_unsafe_es3_apis_enabled(true);"""
+ valid_test += """
EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
- EXPECT_EQ(GL_NO_ERROR, GetGLError());
- EXPECT_TRUE(Get%(resource_type)s(kNewClientId) != NULL);
+ EXPECT_EQ(GL_NO_ERROR, GetGLError());"""
+ if func.IsUnsafe():
+ valid_test += """
+ %(return_type)s service_id = 0;
+ EXPECT_TRUE(Get%(resource_type)sServiceId(kNewClientId, &service_id));
+ EXPECT_EQ(%(const_service_id)s, service_id);
+ decoder_->set_unsafe_es3_apis_enabled(false);
+ EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd));
+}
+"""
+ else:
+ valid_test += """
+ EXPECT_TRUE(Get%(resource_type)s(kNewClientId));
}
"""
comma = ""
- if len(func.GetOriginalArgs()):
- comma =", "
+ cmd_arg_count = 0
+ for arg in func.GetOriginalArgs():
+ if not arg.IsConstant():
+ cmd_arg_count += 1
+ if cmd_arg_count:
+ comma = ", "
+ if func.return_type == 'GLsync':
+ id_type_cast = ("const GLsync kNewServiceIdGLuint = reinterpret_cast"
+ "<GLsync>(kNewServiceId);\n ")
+ const_service_id = "kNewServiceIdGLuint"
+ else:
+ id_type_cast = ""
+ const_service_id = "kNewServiceId"
self.WriteValidUnitTest(func, file, valid_test, {
'comma': comma,
- 'resource_type': func.name[6:],
+ 'resource_type': self.__GetResourceType(func),
+ 'return_type': func.return_type,
+ 'id_type_cast': id_type_cast,
+ 'const_service_id': const_service_id,
}, *extras)
invalid_test = """
TEST_P(%(test_name)s, %(name)sInvalidArgs%(arg_index)d_%(value_index)d) {
@@ -4978,11 +5053,33 @@
def WriteHandlerImplementation (self, func, file):
"""Overrriden from TypeHandler."""
- file.Write(" uint32_t client_id = c.client_id;\n")
- file.Write(" if (!%sHelper(%s)) {\n" %
- (func.name, func.MakeCmdArgString("")))
- file.Write(" return error::kInvalidArguments;\n")
- file.Write(" }\n")
+ if func.IsUnsafe():
+ code = """ uint32_t client_id = c.client_id;
+ %(return_type)s service_id = 0;
+ if (group_->Get%(resource_name)sServiceId(client_id, &service_id)) {
+ return error::kInvalidArguments;
+ }
+ service_id = %(gl_func_name)s(%(gl_args)s);
+ if (service_id) {
+ group_->Add%(resource_name)sId(client_id, service_id);
+ }
+"""
+ else:
+ code = """ uint32_t client_id = c.client_id;
+ if (Get%(resource_name)s(client_id)) {
+ return error::kInvalidArguments;
+ }
+ %(return_type)s service_id = %(gl_func_name)s(%(gl_args)s);
+ if (service_id) {
+ Create%(resource_name)s(client_id, service_id%(gl_args_with_comma)s);
+ }
+"""
+ file.Write(code % {
+ 'resource_name': self.__GetResourceType(func),
+ 'return_type': func.return_type,
+ 'gl_func_name': func.GetGLFunctionName(),
+ 'gl_args': func.MakeOriginalArgString(""),
+ 'gl_args_with_comma': func.MakeOriginalArgString("", True) })
def WriteGLES2Implementation(self, func, file):
"""Overrriden from TypeHandler."""
@@ -4995,14 +5092,21 @@
for arg in func.GetOriginalArgs():
arg.WriteClientSideValidationCode(file, func)
file.Write(" GLuint client_id;\n")
- file.Write(
- " GetIdHandler(id_namespaces::kProgramsAndShaders)->\n")
+ if func.return_type == "GLsync":
+ file.Write(
+ " GetIdHandler(id_namespaces::kSyncs)->\n")
+ else:
+ file.Write(
+ " GetIdHandler(id_namespaces::kProgramsAndShaders)->\n")
file.Write(" MakeIds(this, 0, 1, &client_id);\n")
file.Write(" helper_->%s(%s);\n" %
(func.name, func.MakeCmdArgString("")))
file.Write(' GPU_CLIENT_LOG("returned " << client_id);\n')
file.Write(" CheckGLError();\n")
- file.Write(" return client_id;\n")
+ if func.return_type == "GLsync":
+ file.Write(" return reinterpret_cast<GLsync>(client_id);\n")
+ else:
+ file.Write(" return client_id;\n")
file.Write("}\n")
file.Write("\n")
@@ -5015,6 +5119,9 @@
def WriteServiceImplementation(self, func, file):
"""Overrriden from TypeHandler."""
+ if func.IsUnsafe():
+ TypeHandler.WriteServiceImplementation(self, func, file)
+ # HandleDeleteShader and HandleDeleteProgram are manually written.
pass
def WriteGLES2Implementation(self, func, file):
@@ -5035,6 +5142,25 @@
file.Write("}\n")
file.Write("\n")
+ def WriteHandlerImplementation (self, func, file):
+ """Overrriden from TypeHandler."""
+ assert len(func.GetOriginalArgs()) == 1
+ arg = func.GetOriginalArgs()[0]
+ if func.IsUnsafe():
+ file.Write(""" %(arg_type)s service_id = 0;
+ if (group_->Get%(resource_type)sServiceId(%(arg_name)s, &service_id)) {
+ glDelete%(resource_type)s(service_id);
+ group_->Remove%(resource_type)sId(%(arg_name)s);
+ } else {
+ LOCAL_SET_GL_ERROR(
+ GL_INVALID_VALUE, "gl%(func_name)s", "unknown %(arg_name)s");
+ }
+""" % { 'resource_type': func.GetInfo('resource_type'),
+ 'arg_name': arg.name,
+ 'arg_type': arg.type,
+ 'func_name': func.original_name })
+ else:
+ file.Write(" %sHelper(%s);\n" % (func.original_name, arg.name))
class DELnHandler(TypeHandler):
"""Handler for glDelete___ type functions."""
@@ -6227,6 +6353,160 @@
file.Write("}\n")
file.Write("\n")
+class PUTSTRHandler(ArrayArgTypeHandler):
+ """Handler for functions that pass a string array."""
+
+ def __init__(self):
+ ArrayArgTypeHandler.__init__(self)
+
+ def __GetDataArg(self, func):
+ """Return the argument that points to the 2D char arrays"""
+ for arg in func.GetOriginalArgs():
+ if arg.IsPointer2D():
+ return arg
+ return None
+
+ def __GetLengthArg(self, func):
+ """Return the argument that holds length for each char array"""
+ for arg in func.GetOriginalArgs():
+ if arg.IsPointer() and not arg.IsPointer2D():
+ return arg
+ return None
+
+ def WriteGLES2Implementation(self, func, file):
+ """Overrriden from TypeHandler."""
+ file.Write("%s GLES2Implementation::%s(%s) {\n" %
+ (func.return_type, func.original_name,
+ func.MakeTypedOriginalArgString("")))
+ file.Write(" GPU_CLIENT_SINGLE_THREAD_CHECK();\n")
+ func.WriteDestinationInitalizationValidation(file)
+ self.WriteClientGLCallLog(func, file)
+ data_arg = self.__GetDataArg(func)
+ length_arg = self.__GetLengthArg(func)
+ log_code_block = """ GPU_CLIENT_LOG_CODE_BLOCK({
+ for (GLsizei ii = 0; ii < count; ++ii) {
+ if (%(data)s[ii]) {"""
+ if length_arg == None:
+ log_code_block += """
+ GPU_CLIENT_LOG(" " << ii << ": ---\\n" << %(data)s[ii] << "\\n---");"""
+ else:
+ log_code_block += """
+ if (%(length)s && %(length)s[ii] >= 0) {
+ const std::string my_str(%(data)s[ii], %(length)s[ii]);
+ GPU_CLIENT_LOG(" " << ii << ": ---\\n" << my_str << "\\n---");
+ } else {
+ GPU_CLIENT_LOG(" " << ii << ": ---\\n" << %(data)s[ii] << "\\n---");
+ }"""
+ log_code_block += """
+ } else {
+ GPU_CLIENT_LOG(" " << ii << ": NULL");
+ }
+ }
+ });
+"""
+ file.Write(log_code_block % {
+ 'data': data_arg.name,
+ 'length': length_arg.name if not length_arg == None else ''
+ })
+ for arg in func.GetOriginalArgs():
+ arg.WriteClientSideValidationCode(file, func)
+ size_code_block = """ // Compute the total size.
+ base::CheckedNumeric<size_t> total_size = count;
+ total_size += 1;
+ total_size *= sizeof(GLint);
+ if (!total_size.IsValid()) {
+ SetGLError(GL_INVALID_VALUE, "glShaderSource", "overflow");
+ return;
+ }
+ size_t header_size = total_size.ValueOrDefault(0);
+ std::vector<GLint> header(count + 1);
+ header[0] = static_cast<GLint>(count);
+ for (GLsizei ii = 0; ii < count; ++ii) {
+ GLint len = 0;
+ if (%(data)s[ii]) {"""
+ if length_arg == None:
+ size_code_block += """
+ len = base::static_cast<GLint>(strlen(%(data)s[ii]));"""
+ else:
+ size_code_block += """
+ len = (%(length)s && %(length)s[ii] >= 0) ?
+ %(length)s[ii] : base::checked_cast<GLint>(strlen(%(data)s[ii]));"""
+ size_code_block += """
+ }
+ total_size += len;
+ total_size += 1; // NULL at the end of each char array.
+ if (!total_size.IsValid()) {
+ SetGLError(GL_INVALID_VALUE, "glShaderSource", "overflow");
+ return;
+ }
+ header[ii + 1] = len;
+}
+"""
+ file.Write(size_code_block % {
+ 'data': data_arg.name,
+ 'length': length_arg.name if not length_arg == None else ''
+ })
+ data_code_block = """ // Pack data into a bucket on the service.
+ helper_->SetBucketSize(kResultBucketId, total_size.ValueOrDefault(0));
+ size_t offset = 0;
+ for (GLsizei ii = 0; ii <= count; ++ii) {
+ const char* src = (ii == 0) ? reinterpret_cast<const char*>(&header[0]) :
+ %(data)s[ii - 1];
+ base::CheckedNumeric<size_t> checked_size = (ii == 0) ? header_size :
+ static_cast<size_t>(header[ii]);
+ if (ii > 0) {
+ checked_size += 1; // NULL in the end.
+ }
+ if (!checked_size.IsValid()) {
+ SetGLError(GL_INVALID_VALUE, "glShaderSource", "overflow");
+ return;
+ }
+ size_t size = checked_size.ValueOrDefault(0);
+ while (size) {
+ ScopedTransferBufferPtr buffer(size, helper_, transfer_buffer_);
+ if (!buffer.valid() || buffer.size() == 0) {
+ SetGLError(GL_OUT_OF_MEMORY, "glShaderSource", "too large");
+ return;
+ }
+ size_t copy_size = buffer.size();
+ if (ii > 0 && buffer.size() == size)
+ --copy_size;
+ if (copy_size)
+ memcpy(buffer.address(), src, copy_size);
+ if (copy_size < buffer.size()) {
+ // Append NULL in the end.
+ DCHECK(copy_size + 1 == buffer.size());
+ char* str = reinterpret_cast<char*>(buffer.address());
+ str[copy_size] = 0;
+ }
+ helper_->SetBucketData(kResultBucketId, offset, buffer.size(),
+ buffer.shm_id(), buffer.offset());
+ offset += buffer.size();
+ src += buffer.size();
+ size -= buffer.size();
+ }
+ }
+ DCHECK_EQ(total_size.ValueOrDefault(0), offset);
+"""
+ file.Write(data_code_block % {
+ 'data': data_arg.name,
+ 'length': length_arg.name if not length_arg == None else ''
+ })
+ bucket_cmd_arg_string = ""
+ for arg in func.GetCmdArgs()[0:-2]:
+ if bucket_cmd_arg_string:
+ bucket_cmd_arg_string += ", "
+ bucket_cmd_arg_string += arg.name
+ if bucket_cmd_arg_string:
+ bucket_cmd_arg_string += ", "
+ bucket_cmd_arg_string += 'kResultBucketId'
+ file.Write(" helper_->%sBucket(%s);\n" %
+ (func.name, bucket_cmd_arg_string))
+ file.Write(" helper_->SetBucketSize(kResultBucketId, 0);");
+ file.Write(" CheckGLError();\n")
+ file.Write("}\n")
+ file.Write("\n")
+
class PUTXnHandler(ArrayArgTypeHandler):
"""Handler for glUniform?f functions."""
@@ -6561,8 +6841,10 @@
if func.IsUnsafe():
assert func.GetInfo('id_mapping')
assert len(func.GetInfo('id_mapping')) == 1
+ assert len(args) == 1
id_type = func.GetInfo('id_mapping')[0]
- file.Write(" *result_dst = group_->Get%sServiceId(%s, &%s);\n" %
+ file.Write(" %s service_%s = 0;\n" % (args[0].type, id_type.lower()))
+ file.Write(" *result_dst = group_->Get%sServiceId(%s, &service_%s);\n" %
(id_type, id_type.lower(), id_type.lower()))
else:
file.Write(" *result_dst = %s(%s);\n" %
@@ -6589,13 +6871,15 @@
file.Write(" return %s;\n" % error_value)
file.Write(" }\n")
file.Write(" *result = 0;\n")
- arg_string = func.MakeOriginalArgString("")
- comma = ""
- if len(arg_string) > 0:
- comma = ", "
+ assert len(func.GetOriginalArgs()) == 1
+ id_arg = func.GetOriginalArgs()[0]
+ if id_arg.type == 'GLsync':
+ arg_string = "ToGLuint(%s)" % func.MakeOriginalArgString("")
+ else:
+ arg_string = func.MakeOriginalArgString("")
file.Write(
- " helper_->%s(%s%sGetResultShmId(), GetResultShmOffset());\n" %
- (func.name, arg_string, comma))
+ " helper_->%s(%s, GetResultShmId(), GetResultShmOffset());\n" %
+ (func.name, arg_string))
file.Write(" WaitForCmd();\n")
file.Write(" %s result_value = *result" % func.return_type)
if func.return_type == "GLboolean":
@@ -6619,20 +6903,23 @@
Cmds expected;
ExpectedMemoryInfo result1 =
GetExpectedResultMemory(sizeof(cmds::%(name)s::Result));
- expected.cmd.Init(1, result1.id, result1.offset);
+ expected.cmd.Init(%(cmd_id_value)s, result1.id, result1.offset);
EXPECT_CALL(*command_buffer(), OnFlush())
- .WillOnce(SetMemory(result1.ptr, uint32_t(1)))
+ .WillOnce(SetMemory(result1.ptr, uint32_t(GL_TRUE)))
.RetiresOnSaturation();
- GLboolean result = gl_->%(name)s(1);
+ GLboolean result = gl_->%(name)s(%(gl_id_value)s);
EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
EXPECT_TRUE(result);
}
"""
+ args = func.GetOriginalArgs()
+ assert len(args) == 1
file.Write(code % {
- 'name': func.name,
- })
+ 'name': func.name,
+ 'cmd_id_value': args[0].GetValidClientSideCmdArg(func),
+ 'gl_id_value': args[0].GetValidClientSideArg(func) })
class STRnHandler(TypeHandler):
@@ -6823,6 +7110,10 @@
"""Returns true if argument is a pointer."""
return False
+ def IsPointer2D(self):
+ """Returns true if argument is a 2D pointer."""
+ return False
+
def IsConstant(self):
"""Returns true if the argument has only one valid value."""
return False
@@ -6853,6 +7144,8 @@
return valid_arg
index = func.GetOriginalArgs().index(self)
+ if self.type == 'GLsync':
+ return ("reinterpret_cast<GLsync>(%d)" % (index + 1))
return str(index + 1)
def GetValidClientSideCmdArg(self, func):
@@ -6870,7 +7163,10 @@
def GetValidGLArg(self, func):
"""Gets a valid GL value for this argument."""
- return self.GetValidArg(func)
+ value = self.GetValidArg(func)
+ if self.type == 'GLsync':
+ return ("reinterpret_cast<GLsync>(%s)" % value)
+ return value
def GetValidNonCachedClientSideArg(self, func):
"""Returns a valid value for this argument in a GL call.
@@ -6903,8 +7199,12 @@
def WriteGetCode(self, file):
"""Writes the code to get an argument from a command structure."""
+ if self.type == 'GLsync':
+ my_type = 'GLuint'
+ else:
+ my_type = self.type
file.Write(" %s %s = static_cast<%s>(c.%s);\n" %
- (self.type, self.name, self.type, self.name))
+ (my_type, self.name, my_type, self.name))
def WriteValidationCode(self, file, func):
"""Writes the validation code for an argument."""
@@ -7038,7 +7338,8 @@
class EnumBaseArgument(Argument):
- """Base class for EnumArgument, IntArgument and ValidatedBoolArgument"""
+ """Base class for EnumArgument, IntArgument, BitfieldArgument, and
+ ValidatedBoolArgument."""
def __init__(self, name, gl_type, type, gl_error):
Argument.__init__(self, name, gl_type)
@@ -7154,7 +7455,7 @@
class IntArgument(EnumBaseArgument):
- """A class for a GLint argument that can only except specific values.
+ """A class for a GLint argument that can only accept specific values.
For example glTexImage2D takes a GLint for its internalformat
argument instead of a GLenum.
@@ -7165,7 +7466,7 @@
class ValidatedBoolArgument(EnumBaseArgument):
- """A class for a GLboolean argument that can only except specific values.
+ """A class for a GLboolean argument that can only accept specific values.
For example glUniformMatrix takes a GLboolean for it's transpose but it
must be false.
@@ -7179,6 +7480,18 @@
return 'GLES2Util::GetStringBool(%s)' % self.name
+class BitFieldArgument(EnumBaseArgument):
+ """A class for a GLbitfield argument that can only accept specific values.
+
+ For example glFenceSync takes a GLbitfield for its flags argument bit it
+ must be 0.
+ """
+
+ def __init__(self, name, type):
+ EnumBaseArgument.__init__(self, name, "GLbitfield", type,
+ "GL_INVALID_VALUE")
+
+
class ImmediatePointerArgument(Argument):
"""A class that represents an immediate argument to a function.
@@ -7269,6 +7582,10 @@
"""Returns true if argument is a pointer."""
return True
+ def IsPointer2D(self):
+ """Returns true if argument is a 2D pointer."""
+ return self.type.count('*') == 2
+
def GetPointedType(self):
match = re.match('(const\s+)?(?P<element_type>[\w]+)\s*\*', self.type)
assert match
@@ -7333,7 +7650,9 @@
def GetBucketVersion(self):
"""Overridden from Argument."""
- if self.type == "const char*":
+ if self.type.find('char') >= 0:
+ if self.IsPointer2D():
+ return InputStringArrayBucketArgument(self.name, self.type)
return InputStringBucketArgument(self.name, self.type)
return BucketPointerArgument(self.name, self.type)
@@ -7343,26 +7662,68 @@
class InputStringBucketArgument(Argument):
- """An string input argument where the string is passed in a bucket."""
+ """A string input argument where the string is passed in a bucket."""
def __init__(self, name, type):
Argument.__init__(self, name + "_bucket_id", "uint32_t")
+
+class InputStringArrayBucketArgument(Argument):
+ """A string array input argument where the strings are passed in a bucket."""
+
+ def __init__(self, name, type):
+ Argument.__init__(self, name + "_bucket_id", "uint32_t")
+ self._original_name = name
+
def WriteGetCode(self, file):
"""Overridden from Argument."""
code = """
- Bucket* %(name)s_bucket = GetBucket(c.%(name)s);
- if (!%(name)s_bucket) {
+ const size_t kMinBucketSize = sizeof(GLint);
+ // Each string has at least |length| in the header and a NUL character.
+ const size_t kMinStringSize = sizeof(GLint) + 1;
+ Bucket* bucket = GetBucket(c.%(name)s);
+ if (!bucket) {
return error::kInvalidArguments;
}
- std::string %(name)s_str;
- if (!%(name)s_bucket->GetAsString(&%(name)s_str)) {
+ const size_t bucket_size = bucket->size();
+ if (bucket_size < kMinBucketSize) {
return error::kInvalidArguments;
}
- const char* %(name)s = %(name)s_str.c_str();
+ const char* bucket_data = bucket->GetDataAs<const char*>(0, bucket_size);
+ const GLint* header = reinterpret_cast<const GLint*>(bucket_data);
+ GLsizei count = static_cast<GLsizei>(header[0]);
+ if (count < 0) {
+ return error::kInvalidArguments;
+ }
+ const size_t max_count = (bucket_size - kMinBucketSize) / kMinStringSize;
+ if (max_count < static_cast<size_t>(count)) {
+ return error::kInvalidArguments;
+ }
+ const GLint* length = header + 1;
+ scoped_ptr<const char*[]> strs;
+ if (count > 0)
+ strs.reset(new const char*[count]);
+ const char** %(original_name)s = strs.get();
+ base::CheckedNumeric<size_t> total_size = sizeof(GLint);
+ total_size *= count + 1; // Header size.
+ if (!total_size.IsValid())
+ return error::kInvalidArguments;
+ for (GLsizei ii = 0; ii < count; ++ii) {
+ %(original_name)s[ii] = bucket_data + total_size.ValueOrDefault(0);
+ total_size += length[ii];
+ total_size += 1; // NUL char at the end of each char array.
+ if (!total_size.IsValid() || total_size.ValueOrDefault(0) > bucket_size ||
+ %(original_name)s[ii][length[ii]] != 0) {
+ return error::kInvalidArguments;
+ }
+ }
+ if (total_size.ValueOrDefault(0) != bucket_size) {
+ return error::kInvalidArguments;
+ }
"""
file.Write(code % {
'name': self.name,
+ 'original_name': self._original_name,
})
def GetValidArg(self, func):
@@ -7378,17 +7739,26 @@
def __init__(self, name, type):
match = re.match("(GLid\w+)", type)
self.resource_type = match.group(1)[4:]
- type = type.replace(match.group(1), "GLuint")
+ if self.resource_type == "Sync":
+ type = type.replace(match.group(1), "GLsync")
+ else:
+ type = type.replace(match.group(1), "GLuint")
Argument.__init__(self, name, type)
def WriteGetCode(self, file):
"""Overridden from Argument."""
- file.Write(" %s %s = c.%s;\n" % (self.type, self.name, self.name))
+ if self.type == "GLsync":
+ my_type = "GLuint"
+ else:
+ my_type = self.type
+ file.Write(" %s %s = c.%s;\n" % (my_type, self.name, self.name))
def GetValidArg(self, func):
return "client_%s_id_" % self.resource_type.lower()
def GetValidGLArg(self, func):
+ if self.resource_type == "Sync":
+ return "reinterpret_cast<GLsync>(kService%sId)" % self.resource_type
return "kService%sId" % self.resource_type
@@ -7462,6 +7832,7 @@
'Manual': ManualHandler(),
'PUT': PUTHandler(),
'PUTn': PUTnHandler(),
+ 'PUTSTR': PUTSTRHandler(),
'PUTXn': PUTXnHandler(),
'StateSet': StateSetHandler(),
'StateSetRGBAlpha': StateSetRGBAlphaHandler(),
@@ -7653,7 +8024,7 @@
return arg
return None
- def __MaybePrependComma(self, arg_string, add_comma):
+ def _MaybePrependComma(self, arg_string, add_comma):
"""Adds a comma if arg_string is not empty and add_comma is true."""
comma = ""
if add_comma and len(arg_string):
@@ -7665,14 +8036,14 @@
args = self.GetOriginalArgs()
arg_string = ", ".join(
["%s %s%s" % (arg.type, prefix, arg.name) for arg in args])
- return self.__MaybePrependComma(arg_string, add_comma)
+ return self._MaybePrependComma(arg_string, add_comma)
def MakeOriginalArgString(self, prefix, add_comma = False, separator = ", "):
"""Gets the list of arguments as they are in GL."""
args = self.GetOriginalArgs()
arg_string = separator.join(
["%s%s" % (prefix, arg.name) for arg in args])
- return self.__MaybePrependComma(arg_string, add_comma)
+ return self._MaybePrependComma(arg_string, add_comma)
def MakeTypedHelperArgString(self, prefix, add_comma = False):
"""Gets a list of typed GL arguments after removing unneeded arguments."""
@@ -7683,7 +8054,7 @@
prefix,
arg.name,
) for arg in args if not arg.IsConstant()])
- return self.__MaybePrependComma(arg_string, add_comma)
+ return self._MaybePrependComma(arg_string, add_comma)
def MakeHelperArgString(self, prefix, add_comma = False, separator = ", "):
"""Gets a list of GL arguments after removing unneeded arguments."""
@@ -7691,7 +8062,7 @@
arg_string = separator.join(
["%s%s" % (prefix, arg.name)
for arg in args if not arg.IsConstant()])
- return self.__MaybePrependComma(arg_string, add_comma)
+ return self._MaybePrependComma(arg_string, add_comma)
def MakeTypedPepperArgString(self, prefix):
"""Gets a list of arguments as they need to be for Pepper."""
@@ -7740,28 +8111,28 @@
args = self.GetCmdArgs()
arg_string = ", ".join(
["%s %s%s" % (arg.type, prefix, arg.name) for arg in args])
- return self.__MaybePrependComma(arg_string, add_comma)
+ return self._MaybePrependComma(arg_string, add_comma)
def MakeCmdArgString(self, prefix, add_comma = False):
"""Gets the list of arguments as they need to be for command buffers."""
args = self.GetCmdArgs()
arg_string = ", ".join(
["%s%s" % (prefix, arg.name) for arg in args])
- return self.__MaybePrependComma(arg_string, add_comma)
+ return self._MaybePrependComma(arg_string, add_comma)
def MakeTypedInitString(self, prefix, add_comma = False):
"""Gets a typed list of arguments as they need to be for cmd Init/Set."""
args = self.GetInitArgs()
arg_string = ", ".join(
["%s %s%s" % (arg.type, prefix, arg.name) for arg in args])
- return self.__MaybePrependComma(arg_string, add_comma)
+ return self._MaybePrependComma(arg_string, add_comma)
def MakeInitString(self, prefix, add_comma = False):
"""Gets the list of arguments as they need to be for cmd Init/Set."""
args = self.GetInitArgs()
arg_string = ", ".join(
["%s%s" % (prefix, arg.name) for arg in args])
- return self.__MaybePrependComma(arg_string, add_comma)
+ return self._MaybePrependComma(arg_string, add_comma)
def MakeLogArgString(self):
"""Makes a string of the arguments for the LOG macros"""
@@ -8069,9 +8440,17 @@
self.type_handler.WriteBucketHandlerImplementation(self, file)
def WriteServiceUnitTest(self, file, *extras):
- """Writes the service implementation for a command."""
+ """Overridden from Function"""
self.type_handler.WriteBucketServiceUnitTest(self, file, *extras)
+ def MakeOriginalArgString(self, prefix, add_comma = False, separator = ", "):
+ """Overridden from Function"""
+ args = self.GetOriginalArgs()
+ arg_string = separator.join(
+ ["%s%s" % (prefix, arg.name[0:-10] if arg.name.endswith("_bucket_id")
+ else arg.name) for arg in args])
+ return super(BucketFunction, self)._MaybePrependComma(arg_string, add_comma)
+
def CreateArg(arg_string):
"""Creates an Argument."""
@@ -8092,6 +8471,8 @@
return ResourceIdArgument(arg_parts[-1], " ".join(arg_parts[0:-1]))
elif arg_parts[0].startswith('GLenum') and len(arg_parts[0]) > 6:
return EnumArgument(arg_parts[-1], " ".join(arg_parts[0:-1]))
+ elif arg_parts[0].startswith('GLbitfield') and len(arg_parts[0]) > 10:
+ return BitFieldArgument(arg_parts[-1], " ".join(arg_parts[0:-1]))
elif arg_parts[0].startswith('GLboolean') and len(arg_parts[0]) > 9:
return ValidatedBoolArgument(arg_parts[-1], " ".join(arg_parts[0:-1]))
elif arg_parts[0].startswith('GLboolean'):
diff --git a/gpu/command_buffer/client/gles2_c_lib_autogen.h b/gpu/command_buffer/client/gles2_c_lib_autogen.h
index 597ab2e..cd3bd7f 100644
--- a/gpu/command_buffer/client/gles2_c_lib_autogen.h
+++ b/gpu/command_buffer/client/gles2_c_lib_autogen.h
@@ -205,6 +205,9 @@
void GLES2DeleteSamplers(GLsizei n, const GLuint* samplers) {
gles2::GetGLContext()->DeleteSamplers(n, samplers);
}
+void GLES2DeleteSync(GLsync sync) {
+ gles2::GetGLContext()->DeleteSync(sync);
+}
void GLES2DeleteShader(GLuint shader) {
gles2::GetGLContext()->DeleteShader(shader);
}
@@ -247,6 +250,9 @@
void GLES2EnableVertexAttribArray(GLuint index) {
gles2::GetGLContext()->EnableVertexAttribArray(index);
}
+GLsync GLES2FenceSync(GLenum condition, GLbitfield flags) {
+ return gles2::GetGLContext()->FenceSync(condition, flags);
+}
void GLES2Finish() {
gles2::GetGLContext()->Finish();
}
@@ -467,6 +473,9 @@
GLboolean GLES2IsShader(GLuint shader) {
return gles2::GetGLContext()->IsShader(shader);
}
+GLboolean GLES2IsSync(GLsync sync) {
+ return gles2::GetGLContext()->IsSync(sync);
+}
GLboolean GLES2IsTexture(GLuint texture) {
return gles2::GetGLContext()->IsTexture(texture);
}
@@ -1384,6 +1393,10 @@
reinterpret_cast<GLES2FunctionPointer>(glDeleteSamplers),
},
{
+ "glDeleteSync",
+ reinterpret_cast<GLES2FunctionPointer>(glDeleteSync),
+ },
+ {
"glDeleteShader",
reinterpret_cast<GLES2FunctionPointer>(glDeleteShader),
},
@@ -1436,6 +1449,10 @@
reinterpret_cast<GLES2FunctionPointer>(glEnableVertexAttribArray),
},
{
+ "glFenceSync",
+ reinterpret_cast<GLES2FunctionPointer>(glFenceSync),
+ },
+ {
"glFinish",
reinterpret_cast<GLES2FunctionPointer>(glFinish),
},
@@ -1645,6 +1662,10 @@
reinterpret_cast<GLES2FunctionPointer>(glIsShader),
},
{
+ "glIsSync",
+ reinterpret_cast<GLES2FunctionPointer>(glIsSync),
+ },
+ {
"glIsTexture",
reinterpret_cast<GLES2FunctionPointer>(glIsTexture),
},
diff --git a/gpu/command_buffer/client/gles2_cmd_helper_autogen.h b/gpu/command_buffer/client/gles2_cmd_helper_autogen.h
index dc31b96..8ba8b43 100644
--- a/gpu/command_buffer/client/gles2_cmd_helper_autogen.h
+++ b/gpu/command_buffer/client/gles2_cmd_helper_autogen.h
@@ -427,6 +427,13 @@
}
}
+void DeleteSync(GLuint sync) {
+ gles2::cmds::DeleteSync* c = GetCmdSpace<gles2::cmds::DeleteSync>();
+ if (c) {
+ c->Init(sync);
+ }
+}
+
void DeleteShader(GLuint shader) {
gles2::cmds::DeleteShader* c = GetCmdSpace<gles2::cmds::DeleteShader>();
if (c) {
@@ -529,6 +536,13 @@
}
}
+void FenceSync(uint32_t client_id) {
+ gles2::cmds::FenceSync* c = GetCmdSpace<gles2::cmds::FenceSync>();
+ if (c) {
+ c->Init(client_id);
+ }
+}
+
void Finish() {
gles2::cmds::Finish* c = GetCmdSpace<gles2::cmds::Finish>();
if (c) {
@@ -1042,6 +1056,13 @@
}
}
+void IsSync(GLuint sync, uint32_t result_shm_id, uint32_t result_shm_offset) {
+ gles2::cmds::IsSync* c = GetCmdSpace<gles2::cmds::IsSync>();
+ if (c) {
+ c->Init(sync, result_shm_id, result_shm_offset);
+ }
+}
+
void IsTexture(GLuint texture,
uint32_t result_shm_id,
uint32_t result_shm_offset) {
@@ -1217,11 +1238,11 @@
}
}
-void ShaderSourceBucket(GLuint shader, uint32_t data_bucket_id) {
+void ShaderSourceBucket(GLuint shader, uint32_t str_bucket_id) {
gles2::cmds::ShaderSourceBucket* c =
GetCmdSpace<gles2::cmds::ShaderSourceBucket>();
if (c) {
- c->Init(shader, data_bucket_id);
+ c->Init(shader, str_bucket_id);
}
}
diff --git a/gpu/command_buffer/client/gles2_implementation.cc b/gpu/command_buffer/client/gles2_implementation.cc
index 8307790..6ad46f8 100644
--- a/gpu/command_buffer/client/gles2_implementation.cc
+++ b/gpu/command_buffer/client/gles2_implementation.cc
@@ -17,6 +17,7 @@
#include <sstream>
#include <string>
#include "base/bind.h"
+#include "base/numerics/safe_math.h"
#include "gpu/command_buffer/client/buffer_tracker.h"
#include "gpu/command_buffer/client/gpu_control.h"
#include "gpu/command_buffer/client/program_info_manager.h"
@@ -975,6 +976,20 @@
helper_->DeleteShader(shaders[0]);
}
+void GLES2Implementation::DeleteSyncHelper(GLsync sync) {
+ GLuint sync_uint = ToGLuint(sync);
+ if (!GetIdHandler(id_namespaces::kSyncs)->FreeIds(
+ this, 1, &sync_uint, &GLES2Implementation::DeleteSyncStub)) {
+ SetGLError(
+ GL_INVALID_VALUE,
+ "glDeleteSync", "id not created by this context.");
+ }
+}
+
+void GLES2Implementation::DeleteSyncStub(GLsizei n, const GLuint* syncs) {
+ DCHECK_EQ(1, n);
+ helper_->DeleteSync(syncs[0]);
+}
GLint GLES2Implementation::GetAttribLocationHelper(
GLuint program, const char* name) {
@@ -1190,78 +1205,6 @@
CheckGLError();
}
-void GLES2Implementation::ShaderSource(
- GLuint shader,
- GLsizei count,
- const GLchar* const* source,
- const GLint* length) {
- GPU_CLIENT_SINGLE_THREAD_CHECK();
- GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glShaderSource("
- << shader << ", " << count << ", "
- << static_cast<const void*>(source) << ", "
- << static_cast<const void*>(length) << ")");
- GPU_CLIENT_LOG_CODE_BLOCK({
- for (GLsizei ii = 0; ii < count; ++ii) {
- if (source[ii]) {
- if (length && length[ii] >= 0) {
- std::string str(source[ii], length[ii]);
- GPU_CLIENT_LOG(" " << ii << ": ---\n" << str << "\n---");
- } else {
- GPU_CLIENT_LOG(" " << ii << ": ---\n" << source[ii] << "\n---");
- }
- } else {
- GPU_CLIENT_LOG(" " << ii << ": NULL");
- }
- }
- });
- if (count < 0) {
- SetGLError(GL_INVALID_VALUE, "glShaderSource", "count < 0");
- return;
- }
- if (shader == 0) {
- SetGLError(GL_INVALID_VALUE, "glShaderSource", "shader == 0");
- return;
- }
-
- // Compute the total size.
- uint32 total_size = 1;
- for (GLsizei ii = 0; ii < count; ++ii) {
- if (source[ii]) {
- total_size += (length && length[ii] >= 0) ?
- static_cast<size_t>(length[ii]) : strlen(source[ii]);
- }
- }
-
- // Concatenate all the strings in to a bucket on the service.
- helper_->SetBucketSize(kResultBucketId, total_size);
- uint32 offset = 0;
- for (GLsizei ii = 0; ii <= count; ++ii) {
- const char* src = ii < count ? source[ii] : "";
- if (src) {
- uint32 size = ii < count ?
- (length ? static_cast<size_t>(length[ii]) : strlen(src)) : 1;
- while (size) {
- ScopedTransferBufferPtr buffer(size, helper_, transfer_buffer_);
- if (!buffer.valid()) {
- return;
- }
- memcpy(buffer.address(), src, buffer.size());
- helper_->SetBucketData(kResultBucketId, offset, buffer.size(),
- buffer.shm_id(), buffer.offset());
- offset += buffer.size();
- src += buffer.size();
- size -= buffer.size();
- }
- }
- }
-
- DCHECK_EQ(total_size, offset);
-
- helper_->ShaderSourceBucket(shader, kResultBucketId);
- helper_->SetBucketSize(kResultBucketId, 0);
- CheckGLError();
-}
-
void GLES2Implementation::BufferDataHelper(
GLenum target, GLsizeiptr size, const void* data, GLenum usage) {
if (!ValidateSize("glBufferData", size))
diff --git a/gpu/command_buffer/client/gles2_implementation.h b/gpu/command_buffer/client/gles2_implementation.h
index 730171d..a1b3621 100644
--- a/gpu/command_buffer/client/gles2_implementation.h
+++ b/gpu/command_buffer/client/gles2_implementation.h
@@ -478,6 +478,7 @@
void DeleteSamplersHelper(GLsizei n, const GLuint* samplers);
void DeleteTransformFeedbacksHelper(
GLsizei n, const GLuint* transformfeedbacks);
+ void DeleteSyncHelper(GLsync sync);
void DeleteBuffersStub(GLsizei n, const GLuint* buffers);
void DeleteFramebuffersStub(GLsizei n, const GLuint* framebuffers);
@@ -490,6 +491,7 @@
void DeleteSamplersStub(GLsizei n, const GLuint* samplers);
void DeleteTransformFeedbacksStub(
GLsizei n, const GLuint* transformfeedbacks);
+ void DeleteSyncStub(GLsizei n, const GLuint* syncs);
void BufferDataHelper(
GLenum target, GLsizeiptr size, const void* data, GLenum usage);
diff --git a/gpu/command_buffer/client/gles2_implementation_autogen.h b/gpu/command_buffer/client/gles2_implementation_autogen.h
index 16753ae..0572358 100644
--- a/gpu/command_buffer/client/gles2_implementation_autogen.h
+++ b/gpu/command_buffer/client/gles2_implementation_autogen.h
@@ -163,6 +163,8 @@
void DeleteSamplers(GLsizei n, const GLuint* samplers) override;
+void DeleteSync(GLsync sync) override;
+
void DeleteShader(GLuint shader) override;
void DeleteTextures(GLsizei n, const GLuint* textures) override;
@@ -188,6 +190,8 @@
void Enable(GLenum cap) override;
+GLsync FenceSync(GLenum condition, GLbitfield flags) override;
+
void Finish() override;
void Flush() override;
@@ -349,6 +353,8 @@
GLboolean IsShader(GLuint shader) override;
+GLboolean IsSync(GLsync sync) override;
+
GLboolean IsTexture(GLuint texture) override;
GLboolean IsTransformFeedback(GLuint transformfeedback) override;
diff --git a/gpu/command_buffer/client/gles2_implementation_impl_autogen.h b/gpu/command_buffer/client/gles2_implementation_impl_autogen.h
index 71ad0db..65e38b1 100644
--- a/gpu/command_buffer/client/gles2_implementation_impl_autogen.h
+++ b/gpu/command_buffer/client/gles2_implementation_impl_autogen.h
@@ -546,6 +546,14 @@
CheckGLError();
}
+void GLES2Implementation::DeleteSync(GLsync sync) {
+ GPU_CLIENT_SINGLE_THREAD_CHECK();
+ GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glDeleteSync(" << sync << ")");
+ GPU_CLIENT_DCHECK(sync != 0);
+ DeleteSyncHelper(sync);
+ CheckGLError();
+}
+
void GLES2Implementation::DeleteShader(GLuint shader) {
GPU_CLIENT_SINGLE_THREAD_CHECK();
GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glDeleteShader(" << shader << ")");
@@ -631,6 +639,27 @@
CheckGLError();
}
+GLsync GLES2Implementation::FenceSync(GLenum condition, GLbitfield flags) {
+ GPU_CLIENT_SINGLE_THREAD_CHECK();
+ GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glFenceSync("
+ << GLES2Util::GetStringSyncCondition(condition) << ", "
+ << flags << ")");
+ if (condition != 0x9117) {
+ SetGLError(GL_INVALID_ENUM, "glFenceSync", "condition GL_INVALID_ENUM");
+ return 0;
+ }
+ if (flags != 0) {
+ SetGLError(GL_INVALID_VALUE, "glFenceSync", "flags GL_INVALID_VALUE");
+ return 0;
+ }
+ GLuint client_id;
+ GetIdHandler(id_namespaces::kSyncs)->MakeIds(this, 0, 1, &client_id);
+ helper_->FenceSync(client_id);
+ GPU_CLIENT_LOG("returned " << client_id);
+ CheckGLError();
+ return reinterpret_cast<GLsync>(client_id);
+}
+
void GLES2Implementation::FramebufferRenderbuffer(GLenum target,
GLenum attachment,
GLenum renderbuffertarget,
@@ -1463,6 +1492,24 @@
return result_value;
}
+GLboolean GLES2Implementation::IsSync(GLsync sync) {
+ GPU_CLIENT_SINGLE_THREAD_CHECK();
+ TRACE_EVENT0("gpu", "GLES2Implementation::IsSync");
+ GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glIsSync(" << sync << ")");
+ typedef cmds::IsSync::Result Result;
+ Result* result = GetResultAs<Result*>();
+ if (!result) {
+ return GL_FALSE;
+ }
+ *result = 0;
+ helper_->IsSync(ToGLuint(sync), GetResultShmId(), GetResultShmOffset());
+ WaitForCmd();
+ GLboolean result_value = *result != 0;
+ GPU_CLIENT_LOG("returned " << result_value);
+ CheckGLError();
+ return result_value;
+}
+
GLboolean GLES2Implementation::IsTexture(GLuint texture) {
GPU_CLIENT_SINGLE_THREAD_CHECK();
TRACE_EVENT0("gpu", "GLES2Implementation::IsTexture");
@@ -1646,6 +1693,104 @@
CheckGLError();
}
+void GLES2Implementation::ShaderSource(GLuint shader,
+ GLsizei count,
+ const GLchar* const* str,
+ const GLint* length) {
+ GPU_CLIENT_SINGLE_THREAD_CHECK();
+ GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glShaderSource(" << shader << ", "
+ << count << ", " << static_cast<const void*>(str) << ", "
+ << static_cast<const void*>(length) << ")");
+ GPU_CLIENT_LOG_CODE_BLOCK({
+ for (GLsizei ii = 0; ii < count; ++ii) {
+ if (str[ii]) {
+ if (length && length[ii] >= 0) {
+ const std::string my_str(str[ii], length[ii]);
+ GPU_CLIENT_LOG(" " << ii << ": ---\n" << my_str << "\n---");
+ } else {
+ GPU_CLIENT_LOG(" " << ii << ": ---\n" << str[ii] << "\n---");
+ }
+ } else {
+ GPU_CLIENT_LOG(" " << ii << ": NULL");
+ }
+ }
+ });
+ if (count < 0) {
+ SetGLError(GL_INVALID_VALUE, "glShaderSource", "count < 0");
+ return;
+ }
+ // Compute the total size.
+ base::CheckedNumeric<size_t> total_size = count;
+ total_size += 1;
+ total_size *= sizeof(GLint);
+ if (!total_size.IsValid()) {
+ SetGLError(GL_INVALID_VALUE, "glShaderSource", "overflow");
+ return;
+ }
+ size_t header_size = total_size.ValueOrDefault(0);
+ std::vector<GLint> header(count + 1);
+ header[0] = static_cast<GLint>(count);
+ for (GLsizei ii = 0; ii < count; ++ii) {
+ GLint len = 0;
+ if (str[ii]) {
+ len = (length && length[ii] >= 0)
+ ? length[ii]
+ : base::checked_cast<GLint>(strlen(str[ii]));
+ }
+ total_size += len;
+ total_size += 1; // NULL at the end of each char array.
+ if (!total_size.IsValid()) {
+ SetGLError(GL_INVALID_VALUE, "glShaderSource", "overflow");
+ return;
+ }
+ header[ii + 1] = len;
+ }
+ // Pack data into a bucket on the service.
+ helper_->SetBucketSize(kResultBucketId, total_size.ValueOrDefault(0));
+ size_t offset = 0;
+ for (GLsizei ii = 0; ii <= count; ++ii) {
+ const char* src =
+ (ii == 0) ? reinterpret_cast<const char*>(&header[0]) : str[ii - 1];
+ base::CheckedNumeric<size_t> checked_size =
+ (ii == 0) ? header_size : static_cast<size_t>(header[ii]);
+ if (ii > 0) {
+ checked_size += 1; // NULL in the end.
+ }
+ if (!checked_size.IsValid()) {
+ SetGLError(GL_INVALID_VALUE, "glShaderSource", "overflow");
+ return;
+ }
+ size_t size = checked_size.ValueOrDefault(0);
+ while (size) {
+ ScopedTransferBufferPtr buffer(size, helper_, transfer_buffer_);
+ if (!buffer.valid() || buffer.size() == 0) {
+ SetGLError(GL_OUT_OF_MEMORY, "glShaderSource", "too large");
+ return;
+ }
+ size_t copy_size = buffer.size();
+ if (ii > 0 && buffer.size() == size)
+ --copy_size;
+ if (copy_size)
+ memcpy(buffer.address(), src, copy_size);
+ if (copy_size < buffer.size()) {
+ // Append NULL in the end.
+ DCHECK(copy_size + 1 == buffer.size());
+ char* str = reinterpret_cast<char*>(buffer.address());
+ str[copy_size] = 0;
+ }
+ helper_->SetBucketData(kResultBucketId, offset, buffer.size(),
+ buffer.shm_id(), buffer.offset());
+ offset += buffer.size();
+ src += buffer.size();
+ size -= buffer.size();
+ }
+ }
+ DCHECK_EQ(total_size.ValueOrDefault(0), offset);
+ helper_->ShaderSourceBucket(shader, kResultBucketId);
+ helper_->SetBucketSize(kResultBucketId, 0);
+ CheckGLError();
+}
+
void GLES2Implementation::StencilFunc(GLenum func, GLint ref, GLuint mask) {
GPU_CLIENT_SINGLE_THREAD_CHECK();
GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glStencilFunc("
diff --git a/gpu/command_buffer/client/gles2_implementation_unittest.cc b/gpu/command_buffer/client/gles2_implementation_unittest.cc
index 29e86df..c69886a 100644
--- a/gpu/command_buffer/client/gles2_implementation_unittest.cc
+++ b/gpu/command_buffer/client/gles2_implementation_unittest.cc
@@ -901,51 +901,92 @@
const GLuint kShaderId = 456;
const char* kString1 = "foobar";
const char* kString2 = "barfoo";
- const size_t kString1Size = strlen(kString1);
- const size_t kString2Size = strlen(kString2);
- const size_t kString3Size = 1; // Want the NULL;
- const size_t kSourceSize = kString1Size + kString2Size + kString3Size;
+ const size_t kString1Size = strlen(kString1) + 1;
+ const size_t kString2Size = strlen(kString2) + 1;
+ const size_t kHeaderSize = sizeof(GLint) * 3;
+ const size_t kSourceSize = kHeaderSize + kString1Size + kString2Size;
+ const size_t kPaddedHeaderSize =
+ transfer_buffer_->RoundToAlignment(kHeaderSize);
const size_t kPaddedString1Size =
transfer_buffer_->RoundToAlignment(kString1Size);
const size_t kPaddedString2Size =
transfer_buffer_->RoundToAlignment(kString2Size);
- const size_t kPaddedString3Size =
- transfer_buffer_->RoundToAlignment(kString3Size);
struct Cmds {
cmd::SetBucketSize set_bucket_size;
- cmd::SetBucketData set_bucket_data1;
+ cmd::SetBucketData set_bucket_header;
cmd::SetToken set_token1;
- cmd::SetBucketData set_bucket_data2;
+ cmd::SetBucketData set_bucket_data1;
cmd::SetToken set_token2;
- cmd::SetBucketData set_bucket_data3;
+ cmd::SetBucketData set_bucket_data2;
cmd::SetToken set_token3;
cmds::ShaderSourceBucket shader_source_bucket;
cmd::SetBucketSize clear_bucket_size;
};
+ ExpectedMemoryInfo mem0 = GetExpectedMemory(kPaddedHeaderSize);
ExpectedMemoryInfo mem1 = GetExpectedMemory(kPaddedString1Size);
ExpectedMemoryInfo mem2 = GetExpectedMemory(kPaddedString2Size);
- ExpectedMemoryInfo mem3 = GetExpectedMemory(kPaddedString3Size);
Cmds expected;
expected.set_bucket_size.Init(kBucketId, kSourceSize);
- expected.set_bucket_data1.Init(
- kBucketId, 0, kString1Size, mem1.id, mem1.offset);
+ expected.set_bucket_header.Init(
+ kBucketId, 0, kHeaderSize, mem0.id, mem0.offset);
expected.set_token1.Init(GetNextToken());
- expected.set_bucket_data2.Init(
- kBucketId, kString1Size, kString2Size, mem2.id, mem2.offset);
+ expected.set_bucket_data1.Init(
+ kBucketId, kHeaderSize, kString1Size, mem1.id, mem1.offset);
expected.set_token2.Init(GetNextToken());
- expected.set_bucket_data3.Init(
- kBucketId, kString1Size + kString2Size,
- kString3Size, mem3.id, mem3.offset);
+ expected.set_bucket_data2.Init(
+ kBucketId, kHeaderSize + kString1Size, kString2Size, mem2.id,
+ mem2.offset);
expected.set_token3.Init(GetNextToken());
expected.shader_source_bucket.Init(kShaderId, kBucketId);
expected.clear_bucket_size.Init(kBucketId, 0);
- const char* strings[] = {
+ const char* kStrings[] = {
kString1,
kString2,
};
- gl_->ShaderSource(kShaderId, 2, strings, NULL);
+ gl_->ShaderSource(kShaderId, 2, kStrings, NULL);
+ EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
+}
+
+TEST_F(GLES2ImplementationTest, ShaderSourceWithLength) {
+ const uint32 kBucketId = GLES2Implementation::kResultBucketId;
+ const GLuint kShaderId = 456;
+ const char* kString = "foobar******";
+ const size_t kStringSize = 6; // We only need "foobar".
+ const size_t kHeaderSize = sizeof(GLint) * 2;
+ const size_t kSourceSize = kHeaderSize + kStringSize + 1;
+ const size_t kPaddedHeaderSize =
+ transfer_buffer_->RoundToAlignment(kHeaderSize);
+ const size_t kPaddedStringSize =
+ transfer_buffer_->RoundToAlignment(kStringSize + 1);
+
+ struct Cmds {
+ cmd::SetBucketSize set_bucket_size;
+ cmd::SetBucketData set_bucket_header;
+ cmd::SetToken set_token1;
+ cmd::SetBucketData set_bucket_data;
+ cmd::SetToken set_token2;
+ cmds::ShaderSourceBucket shader_source_bucket;
+ cmd::SetBucketSize clear_bucket_size;
+ };
+
+ ExpectedMemoryInfo mem0 = GetExpectedMemory(kPaddedHeaderSize);
+ ExpectedMemoryInfo mem1 = GetExpectedMemory(kPaddedStringSize);
+
+ Cmds expected;
+ expected.set_bucket_size.Init(kBucketId, kSourceSize);
+ expected.set_bucket_header.Init(
+ kBucketId, 0, kHeaderSize, mem0.id, mem0.offset);
+ expected.set_token1.Init(GetNextToken());
+ expected.set_bucket_data.Init(
+ kBucketId, kHeaderSize, kStringSize + 1, mem1.id, mem1.offset);
+ expected.set_token2.Init(GetNextToken());
+ expected.shader_source_bucket.Init(kShaderId, kBucketId);
+ expected.clear_bucket_size.Init(kBucketId, 0);
+ const char* kStrings[] = { kString };
+ const GLint kLength[] = { kStringSize };
+ gl_->ShaderSource(kShaderId, 1, kStrings, kLength);
EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
}
@@ -3514,6 +3555,29 @@
EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
}
+TEST_F(GLES2ImplementationTest, IsEnabled) {
+ // If we use a valid enum, its state is cached on client side, so no command
+ // is actually generated, and this test will fail.
+ // TODO(zmo): it seems we never need the command. Maybe remove it.
+ GLenum kCap = 1;
+ struct Cmds {
+ cmds::IsEnabled cmd;
+ };
+
+ Cmds expected;
+ ExpectedMemoryInfo result1 =
+ GetExpectedResultMemory(sizeof(cmds::IsEnabled::Result));
+ expected.cmd.Init(kCap, result1.id, result1.offset);
+
+ EXPECT_CALL(*command_buffer(), OnFlush())
+ .WillOnce(SetMemory(result1.ptr, uint32_t(kCap)))
+ .RetiresOnSaturation();
+
+ GLboolean result = gl_->IsEnabled(kCap);
+ EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
+ EXPECT_TRUE(result);
+}
+
TEST_F(GLES2ImplementationManualInitTest, LoseContextOnOOM) {
ContextInitOptions init_options;
init_options.lose_context_when_out_of_memory = true;
diff --git a/gpu/command_buffer/client/gles2_implementation_unittest_autogen.h b/gpu/command_buffer/client/gles2_implementation_unittest_autogen.h
index a327aee..4d44ad7 100644
--- a/gpu/command_buffer/client/gles2_implementation_unittest_autogen.h
+++ b/gpu/command_buffer/client/gles2_implementation_unittest_autogen.h
@@ -174,13 +174,13 @@
Cmds expected;
ExpectedMemoryInfo result1 =
GetExpectedResultMemory(sizeof(cmds::CheckFramebufferStatus::Result));
- expected.cmd.Init(1, result1.id, result1.offset);
+ expected.cmd.Init(GL_FRAMEBUFFER, result1.id, result1.offset);
EXPECT_CALL(*command_buffer(), OnFlush())
- .WillOnce(SetMemory(result1.ptr, uint32_t(1)))
+ .WillOnce(SetMemory(result1.ptr, uint32_t(GL_TRUE)))
.RetiresOnSaturation();
- GLboolean result = gl_->CheckFramebufferStatus(1);
+ GLboolean result = gl_->CheckFramebufferStatus(GL_FRAMEBUFFER);
EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
EXPECT_TRUE(result);
}
@@ -429,6 +429,17 @@
EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
}
+TEST_F(GLES2ImplementationTest, DeleteSync) {
+ struct Cmds {
+ cmds::DeleteSync cmd;
+ };
+ Cmds expected;
+ expected.cmd.Init(1);
+
+ gl_->DeleteSync(reinterpret_cast<GLsync>(1));
+ EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
+}
+
TEST_F(GLES2ImplementationTest, DeleteShader) {
struct Cmds {
cmds::DeleteShader cmd;
@@ -1058,7 +1069,7 @@
expected.cmd.Init(1, result1.id, result1.offset);
EXPECT_CALL(*command_buffer(), OnFlush())
- .WillOnce(SetMemory(result1.ptr, uint32_t(1)))
+ .WillOnce(SetMemory(result1.ptr, uint32_t(GL_TRUE)))
.RetiresOnSaturation();
GLboolean result = gl_->IsBuffer(1);
@@ -1066,25 +1077,6 @@
EXPECT_TRUE(result);
}
-TEST_F(GLES2ImplementationTest, IsEnabled) {
- struct Cmds {
- cmds::IsEnabled cmd;
- };
-
- Cmds expected;
- ExpectedMemoryInfo result1 =
- GetExpectedResultMemory(sizeof(cmds::IsEnabled::Result));
- expected.cmd.Init(1, result1.id, result1.offset);
-
- EXPECT_CALL(*command_buffer(), OnFlush())
- .WillOnce(SetMemory(result1.ptr, uint32_t(1)))
- .RetiresOnSaturation();
-
- GLboolean result = gl_->IsEnabled(1);
- EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
- EXPECT_TRUE(result);
-}
-
TEST_F(GLES2ImplementationTest, IsFramebuffer) {
struct Cmds {
cmds::IsFramebuffer cmd;
@@ -1096,7 +1088,7 @@
expected.cmd.Init(1, result1.id, result1.offset);
EXPECT_CALL(*command_buffer(), OnFlush())
- .WillOnce(SetMemory(result1.ptr, uint32_t(1)))
+ .WillOnce(SetMemory(result1.ptr, uint32_t(GL_TRUE)))
.RetiresOnSaturation();
GLboolean result = gl_->IsFramebuffer(1);
@@ -1115,7 +1107,7 @@
expected.cmd.Init(1, result1.id, result1.offset);
EXPECT_CALL(*command_buffer(), OnFlush())
- .WillOnce(SetMemory(result1.ptr, uint32_t(1)))
+ .WillOnce(SetMemory(result1.ptr, uint32_t(GL_TRUE)))
.RetiresOnSaturation();
GLboolean result = gl_->IsProgram(1);
@@ -1134,7 +1126,7 @@
expected.cmd.Init(1, result1.id, result1.offset);
EXPECT_CALL(*command_buffer(), OnFlush())
- .WillOnce(SetMemory(result1.ptr, uint32_t(1)))
+ .WillOnce(SetMemory(result1.ptr, uint32_t(GL_TRUE)))
.RetiresOnSaturation();
GLboolean result = gl_->IsRenderbuffer(1);
@@ -1153,7 +1145,7 @@
expected.cmd.Init(1, result1.id, result1.offset);
EXPECT_CALL(*command_buffer(), OnFlush())
- .WillOnce(SetMemory(result1.ptr, uint32_t(1)))
+ .WillOnce(SetMemory(result1.ptr, uint32_t(GL_TRUE)))
.RetiresOnSaturation();
GLboolean result = gl_->IsSampler(1);
@@ -1172,7 +1164,7 @@
expected.cmd.Init(1, result1.id, result1.offset);
EXPECT_CALL(*command_buffer(), OnFlush())
- .WillOnce(SetMemory(result1.ptr, uint32_t(1)))
+ .WillOnce(SetMemory(result1.ptr, uint32_t(GL_TRUE)))
.RetiresOnSaturation();
GLboolean result = gl_->IsShader(1);
@@ -1180,6 +1172,25 @@
EXPECT_TRUE(result);
}
+TEST_F(GLES2ImplementationTest, IsSync) {
+ struct Cmds {
+ cmds::IsSync cmd;
+ };
+
+ Cmds expected;
+ ExpectedMemoryInfo result1 =
+ GetExpectedResultMemory(sizeof(cmds::IsSync::Result));
+ expected.cmd.Init(1, result1.id, result1.offset);
+
+ EXPECT_CALL(*command_buffer(), OnFlush())
+ .WillOnce(SetMemory(result1.ptr, uint32_t(GL_TRUE)))
+ .RetiresOnSaturation();
+
+ GLboolean result = gl_->IsSync(reinterpret_cast<GLsync>(1));
+ EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
+ EXPECT_TRUE(result);
+}
+
TEST_F(GLES2ImplementationTest, IsTexture) {
struct Cmds {
cmds::IsTexture cmd;
@@ -1191,7 +1202,7 @@
expected.cmd.Init(1, result1.id, result1.offset);
EXPECT_CALL(*command_buffer(), OnFlush())
- .WillOnce(SetMemory(result1.ptr, uint32_t(1)))
+ .WillOnce(SetMemory(result1.ptr, uint32_t(GL_TRUE)))
.RetiresOnSaturation();
GLboolean result = gl_->IsTexture(1);
@@ -1210,7 +1221,7 @@
expected.cmd.Init(1, result1.id, result1.offset);
EXPECT_CALL(*command_buffer(), OnFlush())
- .WillOnce(SetMemory(result1.ptr, uint32_t(1)))
+ .WillOnce(SetMemory(result1.ptr, uint32_t(GL_TRUE)))
.RetiresOnSaturation();
GLboolean result = gl_->IsTransformFeedback(1);
@@ -2516,7 +2527,7 @@
expected.cmd.Init(1, result1.id, result1.offset);
EXPECT_CALL(*command_buffer(), OnFlush())
- .WillOnce(SetMemory(result1.ptr, uint32_t(1)))
+ .WillOnce(SetMemory(result1.ptr, uint32_t(GL_TRUE)))
.RetiresOnSaturation();
GLboolean result = gl_->IsVertexArrayOES(1);
@@ -2628,7 +2639,7 @@
expected.cmd.Init(1, result1.id, result1.offset);
EXPECT_CALL(*command_buffer(), OnFlush())
- .WillOnce(SetMemory(result1.ptr, uint32_t(1)))
+ .WillOnce(SetMemory(result1.ptr, uint32_t(GL_TRUE)))
.RetiresOnSaturation();
GLboolean result = gl_->IsValuebufferCHROMIUM(1);
diff --git a/gpu/command_buffer/client/gles2_interface_autogen.h b/gpu/command_buffer/client/gles2_interface_autogen.h
index 42262ce..fe0da5b 100644
--- a/gpu/command_buffer/client/gles2_interface_autogen.h
+++ b/gpu/command_buffer/client/gles2_interface_autogen.h
@@ -121,6 +121,7 @@
virtual void DeleteProgram(GLuint program) = 0;
virtual void DeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers) = 0;
virtual void DeleteSamplers(GLsizei n, const GLuint* samplers) = 0;
+virtual void DeleteSync(GLsync sync) = 0;
virtual void DeleteShader(GLuint shader) = 0;
virtual void DeleteTextures(GLsizei n, const GLuint* textures) = 0;
virtual void DeleteTransformFeedbacks(GLsizei n, const GLuint* ids) = 0;
@@ -137,6 +138,7 @@
const void* indices) = 0;
virtual void Enable(GLenum cap) = 0;
virtual void EnableVertexAttribArray(GLuint index) = 0;
+virtual GLsync FenceSync(GLenum condition, GLbitfield flags) = 0;
virtual void Finish() = 0;
virtual void Flush() = 0;
virtual void FramebufferRenderbuffer(GLenum target,
@@ -254,6 +256,7 @@
virtual GLboolean IsRenderbuffer(GLuint renderbuffer) = 0;
virtual GLboolean IsSampler(GLuint sampler) = 0;
virtual GLboolean IsShader(GLuint shader) = 0;
+virtual GLboolean IsSync(GLsync sync) = 0;
virtual GLboolean IsTexture(GLuint texture) = 0;
virtual GLboolean IsTransformFeedback(GLuint transformfeedback) = 0;
virtual void LineWidth(GLfloat width) = 0;
diff --git a/gpu/command_buffer/client/gles2_interface_stub_autogen.h b/gpu/command_buffer/client/gles2_interface_stub_autogen.h
index 974bf39..76e09b1 100644
--- a/gpu/command_buffer/client/gles2_interface_stub_autogen.h
+++ b/gpu/command_buffer/client/gles2_interface_stub_autogen.h
@@ -120,6 +120,7 @@
void DeleteProgram(GLuint program) override;
void DeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers) override;
void DeleteSamplers(GLsizei n, const GLuint* samplers) override;
+void DeleteSync(GLsync sync) override;
void DeleteShader(GLuint shader) override;
void DeleteTextures(GLsizei n, const GLuint* textures) override;
void DeleteTransformFeedbacks(GLsizei n, const GLuint* ids) override;
@@ -136,6 +137,7 @@
const void* indices) override;
void Enable(GLenum cap) override;
void EnableVertexAttribArray(GLuint index) override;
+GLsync FenceSync(GLenum condition, GLbitfield flags) override;
void Finish() override;
void Flush() override;
void FramebufferRenderbuffer(GLenum target,
@@ -249,6 +251,7 @@
GLboolean IsRenderbuffer(GLuint renderbuffer) override;
GLboolean IsSampler(GLuint sampler) override;
GLboolean IsShader(GLuint shader) override;
+GLboolean IsSync(GLsync sync) override;
GLboolean IsTexture(GLuint texture) override;
GLboolean IsTransformFeedback(GLuint transformfeedback) override;
void LineWidth(GLfloat width) override;
diff --git a/gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h b/gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h
index ce953d7..eddbe91 100644
--- a/gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h
+++ b/gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h
@@ -178,6 +178,8 @@
void GLES2InterfaceStub::DeleteSamplers(GLsizei /* n */,
const GLuint* /* samplers */) {
}
+void GLES2InterfaceStub::DeleteSync(GLsync /* sync */) {
+}
void GLES2InterfaceStub::DeleteShader(GLuint /* shader */) {
}
void GLES2InterfaceStub::DeleteTextures(GLsizei /* n */,
@@ -213,6 +215,10 @@
}
void GLES2InterfaceStub::EnableVertexAttribArray(GLuint /* index */) {
}
+GLsync GLES2InterfaceStub::FenceSync(GLenum /* condition */,
+ GLbitfield /* flags */) {
+ return 0;
+}
void GLES2InterfaceStub::Finish() {
}
void GLES2InterfaceStub::Flush() {
@@ -417,6 +423,9 @@
GLboolean GLES2InterfaceStub::IsShader(GLuint /* shader */) {
return 0;
}
+GLboolean GLES2InterfaceStub::IsSync(GLsync /* sync */) {
+ return 0;
+}
GLboolean GLES2InterfaceStub::IsTexture(GLuint /* texture */) {
return 0;
}
diff --git a/gpu/command_buffer/client/gles2_trace_implementation_autogen.h b/gpu/command_buffer/client/gles2_trace_implementation_autogen.h
index 1f8008b..d878d1e 100644
--- a/gpu/command_buffer/client/gles2_trace_implementation_autogen.h
+++ b/gpu/command_buffer/client/gles2_trace_implementation_autogen.h
@@ -120,6 +120,7 @@
void DeleteProgram(GLuint program) override;
void DeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers) override;
void DeleteSamplers(GLsizei n, const GLuint* samplers) override;
+void DeleteSync(GLsync sync) override;
void DeleteShader(GLuint shader) override;
void DeleteTextures(GLsizei n, const GLuint* textures) override;
void DeleteTransformFeedbacks(GLsizei n, const GLuint* ids) override;
@@ -136,6 +137,7 @@
const void* indices) override;
void Enable(GLenum cap) override;
void EnableVertexAttribArray(GLuint index) override;
+GLsync FenceSync(GLenum condition, GLbitfield flags) override;
void Finish() override;
void Flush() override;
void FramebufferRenderbuffer(GLenum target,
@@ -249,6 +251,7 @@
GLboolean IsRenderbuffer(GLuint renderbuffer) override;
GLboolean IsSampler(GLuint sampler) override;
GLboolean IsShader(GLuint shader) override;
+GLboolean IsSync(GLsync sync) override;
GLboolean IsTexture(GLuint texture) override;
GLboolean IsTransformFeedback(GLuint transformfeedback) override;
void LineWidth(GLfloat width) override;
diff --git a/gpu/command_buffer/client/gles2_trace_implementation_impl_autogen.h b/gpu/command_buffer/client/gles2_trace_implementation_impl_autogen.h
index ed5c148..deb7f84 100644
--- a/gpu/command_buffer/client/gles2_trace_implementation_impl_autogen.h
+++ b/gpu/command_buffer/client/gles2_trace_implementation_impl_autogen.h
@@ -302,6 +302,11 @@
gl_->DeleteSamplers(n, samplers);
}
+void GLES2TraceImplementation::DeleteSync(GLsync sync) {
+ TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::DeleteSync");
+ gl_->DeleteSync(sync);
+}
+
void GLES2TraceImplementation::DeleteShader(GLuint shader) {
TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::DeleteShader");
gl_->DeleteShader(shader);
@@ -374,6 +379,11 @@
gl_->EnableVertexAttribArray(index);
}
+GLsync GLES2TraceImplementation::FenceSync(GLenum condition, GLbitfield flags) {
+ TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::FenceSync");
+ return gl_->FenceSync(condition, flags);
+}
+
void GLES2TraceImplementation::Finish() {
TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::Finish");
gl_->Finish();
@@ -725,6 +735,11 @@
return gl_->IsShader(shader);
}
+GLboolean GLES2TraceImplementation::IsSync(GLsync sync) {
+ TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::IsSync");
+ return gl_->IsSync(sync);
+}
+
GLboolean GLES2TraceImplementation::IsTexture(GLuint texture) {
TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::IsTexture");
return gl_->IsTexture(texture);
diff --git a/gpu/command_buffer/cmd_buffer_functions.txt b/gpu/command_buffer/cmd_buffer_functions.txt
index 71e99e1..c595307 100644
--- a/gpu/command_buffer/cmd_buffer_functions.txt
+++ b/gpu/command_buffer/cmd_buffer_functions.txt
@@ -46,6 +46,7 @@
GL_APICALL void GL_APIENTRY glDeleteProgram (GLidProgram program);
GL_APICALL void GL_APIENTRY glDeleteRenderbuffers (GLsizeiNotNegative n, const GLuint* renderbuffers);
GL_APICALL void GL_APIENTRY glDeleteSamplers (GLsizeiNotNegative n, const GLuint* samplers);
+GL_APICALL void GL_APIENTRY glDeleteSync (GLidSync sync);
GL_APICALL void GL_APIENTRY glDeleteShader (GLidShader shader);
GL_APICALL void GL_APIENTRY glDeleteTextures (GLsizeiNotNegative n, const GLuint* textures);
GL_APICALL void GL_APIENTRY glDeleteTransformFeedbacks (GLsizeiNotNegative n, const GLuint* ids);
@@ -59,6 +60,7 @@
GL_APICALL void GL_APIENTRY glDrawElements (GLenumDrawMode mode, GLsizei count, GLenumIndexType type, const void* indices);
GL_APICALL void GL_APIENTRY glEnable (GLenumCapability cap);
GL_APICALL void GL_APIENTRY glEnableVertexAttribArray (GLuint index);
+GL_APICALL GLsync GL_APIENTRY glFenceSync (GLenumSyncCondition condition, GLbitfieldSyncFlags flags);
GL_APICALL void GL_APIENTRY glFinish (void);
GL_APICALL void GL_APIENTRY glFlush (void);
GL_APICALL void GL_APIENTRY glFramebufferRenderbuffer (GLenumFrameBufferTarget target, GLenumAttachment attachment, GLenumRenderBufferTarget renderbuffertarget, GLidRenderbuffer renderbuffer);
@@ -111,6 +113,7 @@
GL_APICALL GLboolean GL_APIENTRY glIsRenderbuffer (GLidRenderbuffer renderbuffer);
GL_APICALL GLboolean GL_APIENTRY glIsSampler (GLidSampler sampler);
GL_APICALL GLboolean GL_APIENTRY glIsShader (GLidShader shader);
+GL_APICALL GLboolean GL_APIENTRY glIsSync (GLidSync sync);
GL_APICALL GLboolean GL_APIENTRY glIsTexture (GLidTexture texture);
GL_APICALL GLboolean GL_APIENTRY glIsTransformFeedback (GLidTransformFeedback transformfeedback);
GL_APICALL void GL_APIENTRY glLineWidth (GLfloat width);
diff --git a/gpu/command_buffer/common/gles2_cmd_format.h b/gpu/command_buffer/common/gles2_cmd_format.h
index b23cae3..55fa4a1 100644
--- a/gpu/command_buffer/common/gles2_cmd_format.h
+++ b/gpu/command_buffer/common/gles2_cmd_format.h
@@ -42,6 +42,7 @@
typedef void GLvoid;
typedef khronos_intptr_t GLintptr;
typedef khronos_ssize_t GLsizeiptr;
+typedef struct __GLsync *GLsync;
namespace gpu {
namespace gles2 {
@@ -63,6 +64,7 @@
kValuebuffers,
kSamplers,
kTransformFeedbacks,
+ kSyncs,
kNumIdNamespaces
};
diff --git a/gpu/command_buffer/common/gles2_cmd_format_autogen.h b/gpu/command_buffer/common/gles2_cmd_format_autogen.h
index eb35d4a..c57a48c 100644
--- a/gpu/command_buffer/common/gles2_cmd_format_autogen.h
+++ b/gpu/command_buffer/common/gles2_cmd_format_autogen.h
@@ -2071,6 +2071,38 @@
static_assert(offsetof(DeleteSamplersImmediate, n) == 4,
"offset of DeleteSamplersImmediate n should be 4");
+struct DeleteSync {
+ typedef DeleteSync ValueType;
+ static const CommandId kCmdId = kDeleteSync;
+ static const cmd::ArgFlags kArgFlags = cmd::kFixed;
+ static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
+
+ static uint32_t ComputeSize() {
+ return static_cast<uint32_t>(sizeof(ValueType)); // NOLINT
+ }
+
+ void SetHeader() { header.SetCmd<ValueType>(); }
+
+ void Init(GLuint _sync) {
+ SetHeader();
+ sync = _sync;
+ }
+
+ void* Set(void* cmd, GLuint _sync) {
+ static_cast<ValueType*>(cmd)->Init(_sync);
+ return NextCmdAddress<ValueType>(cmd);
+ }
+
+ gpu::CommandHeader header;
+ uint32_t sync;
+};
+
+static_assert(sizeof(DeleteSync) == 8, "size of DeleteSync should be 8");
+static_assert(offsetof(DeleteSync, header) == 0,
+ "offset of DeleteSync header should be 0");
+static_assert(offsetof(DeleteSync, sync) == 4,
+ "offset of DeleteSync sync should be 4");
+
struct DeleteShader {
typedef DeleteShader ValueType;
static const CommandId kCmdId = kDeleteShader;
@@ -2539,6 +2571,40 @@
static_assert(offsetof(EnableVertexAttribArray, index) == 4,
"offset of EnableVertexAttribArray index should be 4");
+struct FenceSync {
+ typedef FenceSync ValueType;
+ static const CommandId kCmdId = kFenceSync;
+ static const cmd::ArgFlags kArgFlags = cmd::kFixed;
+ static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
+
+ static uint32_t ComputeSize() {
+ return static_cast<uint32_t>(sizeof(ValueType)); // NOLINT
+ }
+
+ void SetHeader() { header.SetCmd<ValueType>(); }
+
+ void Init(uint32_t _client_id) {
+ SetHeader();
+ client_id = _client_id;
+ }
+
+ void* Set(void* cmd, uint32_t _client_id) {
+ static_cast<ValueType*>(cmd)->Init(_client_id);
+ return NextCmdAddress<ValueType>(cmd);
+ }
+
+ gpu::CommandHeader header;
+ uint32_t client_id;
+ static const uint32_t condition = 0x9117;
+ static const uint32_t flags = 0;
+};
+
+static_assert(sizeof(FenceSync) == 8, "size of FenceSync should be 8");
+static_assert(offsetof(FenceSync, header) == 0,
+ "offset of FenceSync header should be 0");
+static_assert(offsetof(FenceSync, client_id) == 4,
+ "offset of FenceSync client_id should be 4");
+
struct Finish {
typedef Finish ValueType;
static const CommandId kCmdId = kFinish;
@@ -5134,6 +5200,53 @@
static_assert(offsetof(IsShader, result_shm_offset) == 12,
"offset of IsShader result_shm_offset should be 12");
+struct IsSync {
+ typedef IsSync ValueType;
+ static const CommandId kCmdId = kIsSync;
+ static const cmd::ArgFlags kArgFlags = cmd::kFixed;
+ static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
+
+ typedef uint32_t Result;
+
+ static uint32_t ComputeSize() {
+ return static_cast<uint32_t>(sizeof(ValueType)); // NOLINT
+ }
+
+ void SetHeader() { header.SetCmd<ValueType>(); }
+
+ void Init(GLuint _sync,
+ uint32_t _result_shm_id,
+ uint32_t _result_shm_offset) {
+ SetHeader();
+ sync = _sync;
+ result_shm_id = _result_shm_id;
+ result_shm_offset = _result_shm_offset;
+ }
+
+ void* Set(void* cmd,
+ GLuint _sync,
+ uint32_t _result_shm_id,
+ uint32_t _result_shm_offset) {
+ static_cast<ValueType*>(cmd)
+ ->Init(_sync, _result_shm_id, _result_shm_offset);
+ return NextCmdAddress<ValueType>(cmd);
+ }
+
+ gpu::CommandHeader header;
+ uint32_t sync;
+ uint32_t result_shm_id;
+ uint32_t result_shm_offset;
+};
+
+static_assert(sizeof(IsSync) == 16, "size of IsSync should be 16");
+static_assert(offsetof(IsSync, header) == 0,
+ "offset of IsSync header should be 0");
+static_assert(offsetof(IsSync, sync) == 4, "offset of IsSync sync should be 4");
+static_assert(offsetof(IsSync, result_shm_id) == 8,
+ "offset of IsSync result_shm_id should be 8");
+static_assert(offsetof(IsSync, result_shm_offset) == 12,
+ "offset of IsSync result_shm_offset should be 12");
+
struct IsTexture {
typedef IsTexture ValueType;
static const CommandId kCmdId = kIsTexture;
@@ -5964,20 +6077,20 @@
void SetHeader() { header.SetCmd<ValueType>(); }
- void Init(GLuint _shader, uint32_t _data_bucket_id) {
+ void Init(GLuint _shader, uint32_t _str_bucket_id) {
SetHeader();
shader = _shader;
- data_bucket_id = _data_bucket_id;
+ str_bucket_id = _str_bucket_id;
}
- void* Set(void* cmd, GLuint _shader, uint32_t _data_bucket_id) {
- static_cast<ValueType*>(cmd)->Init(_shader, _data_bucket_id);
+ void* Set(void* cmd, GLuint _shader, uint32_t _str_bucket_id) {
+ static_cast<ValueType*>(cmd)->Init(_shader, _str_bucket_id);
return NextCmdAddress<ValueType>(cmd);
}
gpu::CommandHeader header;
uint32_t shader;
- uint32_t data_bucket_id;
+ uint32_t str_bucket_id;
};
static_assert(sizeof(ShaderSourceBucket) == 12,
@@ -5986,8 +6099,8 @@
"offset of ShaderSourceBucket header should be 0");
static_assert(offsetof(ShaderSourceBucket, shader) == 4,
"offset of ShaderSourceBucket shader should be 4");
-static_assert(offsetof(ShaderSourceBucket, data_bucket_id) == 8,
- "offset of ShaderSourceBucket data_bucket_id should be 8");
+static_assert(offsetof(ShaderSourceBucket, str_bucket_id) == 8,
+ "offset of ShaderSourceBucket str_bucket_id should be 8");
struct StencilFunc {
typedef StencilFunc ValueType;
diff --git a/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h b/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h
index 319ce6e..7f1e991 100644
--- a/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h
+++ b/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h
@@ -675,6 +675,16 @@
// TODO(gman): Check that ids were inserted;
}
+TEST_F(GLES2FormatTest, DeleteSync) {
+ cmds::DeleteSync& cmd = *GetBufferAs<cmds::DeleteSync>();
+ void* next_cmd = cmd.Set(&cmd, static_cast<GLuint>(11));
+ EXPECT_EQ(static_cast<uint32_t>(cmds::DeleteSync::kCmdId),
+ cmd.header.command);
+ EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
+ EXPECT_EQ(static_cast<GLuint>(11), cmd.sync);
+ CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
+}
+
TEST_F(GLES2FormatTest, DeleteShader) {
cmds::DeleteShader& cmd = *GetBufferAs<cmds::DeleteShader>();
void* next_cmd = cmd.Set(&cmd, static_cast<GLuint>(11));
@@ -832,6 +842,15 @@
CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
}
+TEST_F(GLES2FormatTest, FenceSync) {
+ cmds::FenceSync& cmd = *GetBufferAs<cmds::FenceSync>();
+ void* next_cmd = cmd.Set(&cmd, static_cast<uint32_t>(11));
+ EXPECT_EQ(static_cast<uint32_t>(cmds::FenceSync::kCmdId), cmd.header.command);
+ EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
+ EXPECT_EQ(static_cast<uint32_t>(11), cmd.client_id);
+ CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
+}
+
TEST_F(GLES2FormatTest, Finish) {
cmds::Finish& cmd = *GetBufferAs<cmds::Finish>();
void* next_cmd = cmd.Set(&cmd);
@@ -1607,6 +1626,19 @@
CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
}
+TEST_F(GLES2FormatTest, IsSync) {
+ cmds::IsSync& cmd = *GetBufferAs<cmds::IsSync>();
+ void* next_cmd =
+ cmd.Set(&cmd, static_cast<GLuint>(11), static_cast<uint32_t>(12),
+ static_cast<uint32_t>(13));
+ EXPECT_EQ(static_cast<uint32_t>(cmds::IsSync::kCmdId), cmd.header.command);
+ EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
+ EXPECT_EQ(static_cast<GLuint>(11), cmd.sync);
+ EXPECT_EQ(static_cast<uint32_t>(12), cmd.result_shm_id);
+ EXPECT_EQ(static_cast<uint32_t>(13), cmd.result_shm_offset);
+ CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
+}
+
TEST_F(GLES2FormatTest, IsTexture) {
cmds::IsTexture& cmd = *GetBufferAs<cmds::IsTexture>();
void* next_cmd =
@@ -1875,7 +1907,7 @@
cmd.header.command);
EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
EXPECT_EQ(static_cast<GLuint>(11), cmd.shader);
- EXPECT_EQ(static_cast<uint32_t>(12), cmd.data_bucket_id);
+ EXPECT_EQ(static_cast<uint32_t>(12), cmd.str_bucket_id);
CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
}
diff --git a/gpu/command_buffer/common/gles2_cmd_ids_autogen.h b/gpu/command_buffer/common/gles2_cmd_ids_autogen.h
index b3ca924..0c999f4 100644
--- a/gpu/command_buffer/common/gles2_cmd_ids_autogen.h
+++ b/gpu/command_buffer/common/gles2_cmd_ids_autogen.h
@@ -56,220 +56,223 @@
OP(DeleteProgram) /* 297 */ \
OP(DeleteRenderbuffersImmediate) /* 298 */ \
OP(DeleteSamplersImmediate) /* 299 */ \
- OP(DeleteShader) /* 300 */ \
- OP(DeleteTexturesImmediate) /* 301 */ \
- OP(DeleteTransformFeedbacksImmediate) /* 302 */ \
- OP(DepthFunc) /* 303 */ \
- OP(DepthMask) /* 304 */ \
- OP(DepthRangef) /* 305 */ \
- OP(DetachShader) /* 306 */ \
- OP(Disable) /* 307 */ \
- OP(DisableVertexAttribArray) /* 308 */ \
- OP(DrawArrays) /* 309 */ \
- OP(DrawElements) /* 310 */ \
- OP(Enable) /* 311 */ \
- OP(EnableVertexAttribArray) /* 312 */ \
- OP(Finish) /* 313 */ \
- OP(Flush) /* 314 */ \
- OP(FramebufferRenderbuffer) /* 315 */ \
- OP(FramebufferTexture2D) /* 316 */ \
- OP(FramebufferTextureLayer) /* 317 */ \
- OP(FrontFace) /* 318 */ \
- OP(GenBuffersImmediate) /* 319 */ \
- OP(GenerateMipmap) /* 320 */ \
- OP(GenFramebuffersImmediate) /* 321 */ \
- OP(GenRenderbuffersImmediate) /* 322 */ \
- OP(GenSamplersImmediate) /* 323 */ \
- OP(GenTexturesImmediate) /* 324 */ \
- OP(GenTransformFeedbacksImmediate) /* 325 */ \
- OP(GetActiveAttrib) /* 326 */ \
- OP(GetActiveUniform) /* 327 */ \
- OP(GetAttachedShaders) /* 328 */ \
- OP(GetAttribLocation) /* 329 */ \
- OP(GetBooleanv) /* 330 */ \
- OP(GetBufferParameteriv) /* 331 */ \
- OP(GetError) /* 332 */ \
- OP(GetFloatv) /* 333 */ \
- OP(GetFramebufferAttachmentParameteriv) /* 334 */ \
- OP(GetIntegerv) /* 335 */ \
- OP(GetInternalformativ) /* 336 */ \
- OP(GetProgramiv) /* 337 */ \
- OP(GetProgramInfoLog) /* 338 */ \
- OP(GetRenderbufferParameteriv) /* 339 */ \
- OP(GetSamplerParameterfv) /* 340 */ \
- OP(GetSamplerParameteriv) /* 341 */ \
- OP(GetShaderiv) /* 342 */ \
- OP(GetShaderInfoLog) /* 343 */ \
- OP(GetShaderPrecisionFormat) /* 344 */ \
- OP(GetShaderSource) /* 345 */ \
- OP(GetString) /* 346 */ \
- OP(GetTexParameterfv) /* 347 */ \
- OP(GetTexParameteriv) /* 348 */ \
- OP(GetUniformfv) /* 349 */ \
- OP(GetUniformiv) /* 350 */ \
- OP(GetUniformLocation) /* 351 */ \
- OP(GetVertexAttribfv) /* 352 */ \
- OP(GetVertexAttribiv) /* 353 */ \
- OP(GetVertexAttribPointerv) /* 354 */ \
- OP(Hint) /* 355 */ \
- OP(InvalidateFramebufferImmediate) /* 356 */ \
- OP(InvalidateSubFramebufferImmediate) /* 357 */ \
- OP(IsBuffer) /* 358 */ \
- OP(IsEnabled) /* 359 */ \
- OP(IsFramebuffer) /* 360 */ \
- OP(IsProgram) /* 361 */ \
- OP(IsRenderbuffer) /* 362 */ \
- OP(IsSampler) /* 363 */ \
- OP(IsShader) /* 364 */ \
- OP(IsTexture) /* 365 */ \
- OP(IsTransformFeedback) /* 366 */ \
- OP(LineWidth) /* 367 */ \
- OP(LinkProgram) /* 368 */ \
- OP(PauseTransformFeedback) /* 369 */ \
- OP(PixelStorei) /* 370 */ \
- OP(PolygonOffset) /* 371 */ \
- OP(ReadBuffer) /* 372 */ \
- OP(ReadPixels) /* 373 */ \
- OP(ReleaseShaderCompiler) /* 374 */ \
- OP(RenderbufferStorage) /* 375 */ \
- OP(ResumeTransformFeedback) /* 376 */ \
- OP(SampleCoverage) /* 377 */ \
- OP(SamplerParameterf) /* 378 */ \
- OP(SamplerParameterfvImmediate) /* 379 */ \
- OP(SamplerParameteri) /* 380 */ \
- OP(SamplerParameterivImmediate) /* 381 */ \
- OP(Scissor) /* 382 */ \
- OP(ShaderBinary) /* 383 */ \
- OP(ShaderSourceBucket) /* 384 */ \
- OP(StencilFunc) /* 385 */ \
- OP(StencilFuncSeparate) /* 386 */ \
- OP(StencilMask) /* 387 */ \
- OP(StencilMaskSeparate) /* 388 */ \
- OP(StencilOp) /* 389 */ \
- OP(StencilOpSeparate) /* 390 */ \
- OP(TexImage2D) /* 391 */ \
- OP(TexImage3D) /* 392 */ \
- OP(TexParameterf) /* 393 */ \
- OP(TexParameterfvImmediate) /* 394 */ \
- OP(TexParameteri) /* 395 */ \
- OP(TexParameterivImmediate) /* 396 */ \
- OP(TexStorage3D) /* 397 */ \
- OP(TexSubImage2D) /* 398 */ \
- OP(TexSubImage3D) /* 399 */ \
- OP(Uniform1f) /* 400 */ \
- OP(Uniform1fvImmediate) /* 401 */ \
- OP(Uniform1i) /* 402 */ \
- OP(Uniform1ivImmediate) /* 403 */ \
- OP(Uniform1ui) /* 404 */ \
- OP(Uniform1uivImmediate) /* 405 */ \
- OP(Uniform2f) /* 406 */ \
- OP(Uniform2fvImmediate) /* 407 */ \
- OP(Uniform2i) /* 408 */ \
- OP(Uniform2ivImmediate) /* 409 */ \
- OP(Uniform2ui) /* 410 */ \
- OP(Uniform2uivImmediate) /* 411 */ \
- OP(Uniform3f) /* 412 */ \
- OP(Uniform3fvImmediate) /* 413 */ \
- OP(Uniform3i) /* 414 */ \
- OP(Uniform3ivImmediate) /* 415 */ \
- OP(Uniform3ui) /* 416 */ \
- OP(Uniform3uivImmediate) /* 417 */ \
- OP(Uniform4f) /* 418 */ \
- OP(Uniform4fvImmediate) /* 419 */ \
- OP(Uniform4i) /* 420 */ \
- OP(Uniform4ivImmediate) /* 421 */ \
- OP(Uniform4ui) /* 422 */ \
- OP(Uniform4uivImmediate) /* 423 */ \
- OP(UniformMatrix2fvImmediate) /* 424 */ \
- OP(UniformMatrix2x3fvImmediate) /* 425 */ \
- OP(UniformMatrix2x4fvImmediate) /* 426 */ \
- OP(UniformMatrix3fvImmediate) /* 427 */ \
- OP(UniformMatrix3x2fvImmediate) /* 428 */ \
- OP(UniformMatrix3x4fvImmediate) /* 429 */ \
- OP(UniformMatrix4fvImmediate) /* 430 */ \
- OP(UniformMatrix4x2fvImmediate) /* 431 */ \
- OP(UniformMatrix4x3fvImmediate) /* 432 */ \
- OP(UseProgram) /* 433 */ \
- OP(ValidateProgram) /* 434 */ \
- OP(VertexAttrib1f) /* 435 */ \
- OP(VertexAttrib1fvImmediate) /* 436 */ \
- OP(VertexAttrib2f) /* 437 */ \
- OP(VertexAttrib2fvImmediate) /* 438 */ \
- OP(VertexAttrib3f) /* 439 */ \
- OP(VertexAttrib3fvImmediate) /* 440 */ \
- OP(VertexAttrib4f) /* 441 */ \
- OP(VertexAttrib4fvImmediate) /* 442 */ \
- OP(VertexAttribI4i) /* 443 */ \
- OP(VertexAttribI4ivImmediate) /* 444 */ \
- OP(VertexAttribI4ui) /* 445 */ \
- OP(VertexAttribI4uivImmediate) /* 446 */ \
- OP(VertexAttribIPointer) /* 447 */ \
- OP(VertexAttribPointer) /* 448 */ \
- OP(Viewport) /* 449 */ \
- OP(BlitFramebufferCHROMIUM) /* 450 */ \
- OP(RenderbufferStorageMultisampleCHROMIUM) /* 451 */ \
- OP(RenderbufferStorageMultisampleEXT) /* 452 */ \
- OP(FramebufferTexture2DMultisampleEXT) /* 453 */ \
- OP(TexStorage2DEXT) /* 454 */ \
- OP(GenQueriesEXTImmediate) /* 455 */ \
- OP(DeleteQueriesEXTImmediate) /* 456 */ \
- OP(BeginQueryEXT) /* 457 */ \
- OP(BeginTransformFeedback) /* 458 */ \
- OP(EndQueryEXT) /* 459 */ \
- OP(EndTransformFeedback) /* 460 */ \
- OP(InsertEventMarkerEXT) /* 461 */ \
- OP(PushGroupMarkerEXT) /* 462 */ \
- OP(PopGroupMarkerEXT) /* 463 */ \
- OP(GenVertexArraysOESImmediate) /* 464 */ \
- OP(DeleteVertexArraysOESImmediate) /* 465 */ \
- OP(IsVertexArrayOES) /* 466 */ \
- OP(BindVertexArrayOES) /* 467 */ \
- OP(SwapBuffers) /* 468 */ \
- OP(GetMaxValueInBufferCHROMIUM) /* 469 */ \
- OP(EnableFeatureCHROMIUM) /* 470 */ \
- OP(ResizeCHROMIUM) /* 471 */ \
- OP(GetRequestableExtensionsCHROMIUM) /* 472 */ \
- OP(RequestExtensionCHROMIUM) /* 473 */ \
- OP(GetProgramInfoCHROMIUM) /* 474 */ \
- OP(GetTranslatedShaderSourceANGLE) /* 475 */ \
- OP(PostSubBufferCHROMIUM) /* 476 */ \
- OP(TexImageIOSurface2DCHROMIUM) /* 477 */ \
- OP(CopyTextureCHROMIUM) /* 478 */ \
- OP(DrawArraysInstancedANGLE) /* 479 */ \
- OP(DrawElementsInstancedANGLE) /* 480 */ \
- OP(VertexAttribDivisorANGLE) /* 481 */ \
- OP(GenMailboxCHROMIUM) /* 482 */ \
- OP(ProduceTextureCHROMIUMImmediate) /* 483 */ \
- OP(ProduceTextureDirectCHROMIUMImmediate) /* 484 */ \
- OP(ConsumeTextureCHROMIUMImmediate) /* 485 */ \
- OP(CreateAndConsumeTextureCHROMIUMImmediate) /* 486 */ \
- OP(BindUniformLocationCHROMIUMBucket) /* 487 */ \
- OP(GenValuebuffersCHROMIUMImmediate) /* 488 */ \
- OP(DeleteValuebuffersCHROMIUMImmediate) /* 489 */ \
- OP(IsValuebufferCHROMIUM) /* 490 */ \
- OP(BindValuebufferCHROMIUM) /* 491 */ \
- OP(SubscribeValueCHROMIUM) /* 492 */ \
- OP(PopulateSubscribedValuesCHROMIUM) /* 493 */ \
- OP(UniformValuebufferCHROMIUM) /* 494 */ \
- OP(BindTexImage2DCHROMIUM) /* 495 */ \
- OP(ReleaseTexImage2DCHROMIUM) /* 496 */ \
- OP(TraceBeginCHROMIUM) /* 497 */ \
- OP(TraceEndCHROMIUM) /* 498 */ \
- OP(AsyncTexSubImage2DCHROMIUM) /* 499 */ \
- OP(AsyncTexImage2DCHROMIUM) /* 500 */ \
- OP(WaitAsyncTexImage2DCHROMIUM) /* 501 */ \
- OP(WaitAllAsyncTexImage2DCHROMIUM) /* 502 */ \
- OP(DiscardFramebufferEXTImmediate) /* 503 */ \
- OP(LoseContextCHROMIUM) /* 504 */ \
- OP(InsertSyncPointCHROMIUM) /* 505 */ \
- OP(WaitSyncPointCHROMIUM) /* 506 */ \
- OP(DrawBuffersEXTImmediate) /* 507 */ \
- OP(DiscardBackbufferCHROMIUM) /* 508 */ \
- OP(ScheduleOverlayPlaneCHROMIUM) /* 509 */ \
- OP(SwapInterval) /* 510 */ \
- OP(MatrixLoadfCHROMIUMImmediate) /* 511 */ \
- OP(MatrixLoadIdentityCHROMIUM) /* 512 */ \
- OP(BlendBarrierKHR) /* 513 */
+ OP(DeleteSync) /* 300 */ \
+ OP(DeleteShader) /* 301 */ \
+ OP(DeleteTexturesImmediate) /* 302 */ \
+ OP(DeleteTransformFeedbacksImmediate) /* 303 */ \
+ OP(DepthFunc) /* 304 */ \
+ OP(DepthMask) /* 305 */ \
+ OP(DepthRangef) /* 306 */ \
+ OP(DetachShader) /* 307 */ \
+ OP(Disable) /* 308 */ \
+ OP(DisableVertexAttribArray) /* 309 */ \
+ OP(DrawArrays) /* 310 */ \
+ OP(DrawElements) /* 311 */ \
+ OP(Enable) /* 312 */ \
+ OP(EnableVertexAttribArray) /* 313 */ \
+ OP(FenceSync) /* 314 */ \
+ OP(Finish) /* 315 */ \
+ OP(Flush) /* 316 */ \
+ OP(FramebufferRenderbuffer) /* 317 */ \
+ OP(FramebufferTexture2D) /* 318 */ \
+ OP(FramebufferTextureLayer) /* 319 */ \
+ OP(FrontFace) /* 320 */ \
+ OP(GenBuffersImmediate) /* 321 */ \
+ OP(GenerateMipmap) /* 322 */ \
+ OP(GenFramebuffersImmediate) /* 323 */ \
+ OP(GenRenderbuffersImmediate) /* 324 */ \
+ OP(GenSamplersImmediate) /* 325 */ \
+ OP(GenTexturesImmediate) /* 326 */ \
+ OP(GenTransformFeedbacksImmediate) /* 327 */ \
+ OP(GetActiveAttrib) /* 328 */ \
+ OP(GetActiveUniform) /* 329 */ \
+ OP(GetAttachedShaders) /* 330 */ \
+ OP(GetAttribLocation) /* 331 */ \
+ OP(GetBooleanv) /* 332 */ \
+ OP(GetBufferParameteriv) /* 333 */ \
+ OP(GetError) /* 334 */ \
+ OP(GetFloatv) /* 335 */ \
+ OP(GetFramebufferAttachmentParameteriv) /* 336 */ \
+ OP(GetIntegerv) /* 337 */ \
+ OP(GetInternalformativ) /* 338 */ \
+ OP(GetProgramiv) /* 339 */ \
+ OP(GetProgramInfoLog) /* 340 */ \
+ OP(GetRenderbufferParameteriv) /* 341 */ \
+ OP(GetSamplerParameterfv) /* 342 */ \
+ OP(GetSamplerParameteriv) /* 343 */ \
+ OP(GetShaderiv) /* 344 */ \
+ OP(GetShaderInfoLog) /* 345 */ \
+ OP(GetShaderPrecisionFormat) /* 346 */ \
+ OP(GetShaderSource) /* 347 */ \
+ OP(GetString) /* 348 */ \
+ OP(GetTexParameterfv) /* 349 */ \
+ OP(GetTexParameteriv) /* 350 */ \
+ OP(GetUniformfv) /* 351 */ \
+ OP(GetUniformiv) /* 352 */ \
+ OP(GetUniformLocation) /* 353 */ \
+ OP(GetVertexAttribfv) /* 354 */ \
+ OP(GetVertexAttribiv) /* 355 */ \
+ OP(GetVertexAttribPointerv) /* 356 */ \
+ OP(Hint) /* 357 */ \
+ OP(InvalidateFramebufferImmediate) /* 358 */ \
+ OP(InvalidateSubFramebufferImmediate) /* 359 */ \
+ OP(IsBuffer) /* 360 */ \
+ OP(IsEnabled) /* 361 */ \
+ OP(IsFramebuffer) /* 362 */ \
+ OP(IsProgram) /* 363 */ \
+ OP(IsRenderbuffer) /* 364 */ \
+ OP(IsSampler) /* 365 */ \
+ OP(IsShader) /* 366 */ \
+ OP(IsSync) /* 367 */ \
+ OP(IsTexture) /* 368 */ \
+ OP(IsTransformFeedback) /* 369 */ \
+ OP(LineWidth) /* 370 */ \
+ OP(LinkProgram) /* 371 */ \
+ OP(PauseTransformFeedback) /* 372 */ \
+ OP(PixelStorei) /* 373 */ \
+ OP(PolygonOffset) /* 374 */ \
+ OP(ReadBuffer) /* 375 */ \
+ OP(ReadPixels) /* 376 */ \
+ OP(ReleaseShaderCompiler) /* 377 */ \
+ OP(RenderbufferStorage) /* 378 */ \
+ OP(ResumeTransformFeedback) /* 379 */ \
+ OP(SampleCoverage) /* 380 */ \
+ OP(SamplerParameterf) /* 381 */ \
+ OP(SamplerParameterfvImmediate) /* 382 */ \
+ OP(SamplerParameteri) /* 383 */ \
+ OP(SamplerParameterivImmediate) /* 384 */ \
+ OP(Scissor) /* 385 */ \
+ OP(ShaderBinary) /* 386 */ \
+ OP(ShaderSourceBucket) /* 387 */ \
+ OP(StencilFunc) /* 388 */ \
+ OP(StencilFuncSeparate) /* 389 */ \
+ OP(StencilMask) /* 390 */ \
+ OP(StencilMaskSeparate) /* 391 */ \
+ OP(StencilOp) /* 392 */ \
+ OP(StencilOpSeparate) /* 393 */ \
+ OP(TexImage2D) /* 394 */ \
+ OP(TexImage3D) /* 395 */ \
+ OP(TexParameterf) /* 396 */ \
+ OP(TexParameterfvImmediate) /* 397 */ \
+ OP(TexParameteri) /* 398 */ \
+ OP(TexParameterivImmediate) /* 399 */ \
+ OP(TexStorage3D) /* 400 */ \
+ OP(TexSubImage2D) /* 401 */ \
+ OP(TexSubImage3D) /* 402 */ \
+ OP(Uniform1f) /* 403 */ \
+ OP(Uniform1fvImmediate) /* 404 */ \
+ OP(Uniform1i) /* 405 */ \
+ OP(Uniform1ivImmediate) /* 406 */ \
+ OP(Uniform1ui) /* 407 */ \
+ OP(Uniform1uivImmediate) /* 408 */ \
+ OP(Uniform2f) /* 409 */ \
+ OP(Uniform2fvImmediate) /* 410 */ \
+ OP(Uniform2i) /* 411 */ \
+ OP(Uniform2ivImmediate) /* 412 */ \
+ OP(Uniform2ui) /* 413 */ \
+ OP(Uniform2uivImmediate) /* 414 */ \
+ OP(Uniform3f) /* 415 */ \
+ OP(Uniform3fvImmediate) /* 416 */ \
+ OP(Uniform3i) /* 417 */ \
+ OP(Uniform3ivImmediate) /* 418 */ \
+ OP(Uniform3ui) /* 419 */ \
+ OP(Uniform3uivImmediate) /* 420 */ \
+ OP(Uniform4f) /* 421 */ \
+ OP(Uniform4fvImmediate) /* 422 */ \
+ OP(Uniform4i) /* 423 */ \
+ OP(Uniform4ivImmediate) /* 424 */ \
+ OP(Uniform4ui) /* 425 */ \
+ OP(Uniform4uivImmediate) /* 426 */ \
+ OP(UniformMatrix2fvImmediate) /* 427 */ \
+ OP(UniformMatrix2x3fvImmediate) /* 428 */ \
+ OP(UniformMatrix2x4fvImmediate) /* 429 */ \
+ OP(UniformMatrix3fvImmediate) /* 430 */ \
+ OP(UniformMatrix3x2fvImmediate) /* 431 */ \
+ OP(UniformMatrix3x4fvImmediate) /* 432 */ \
+ OP(UniformMatrix4fvImmediate) /* 433 */ \
+ OP(UniformMatrix4x2fvImmediate) /* 434 */ \
+ OP(UniformMatrix4x3fvImmediate) /* 435 */ \
+ OP(UseProgram) /* 436 */ \
+ OP(ValidateProgram) /* 437 */ \
+ OP(VertexAttrib1f) /* 438 */ \
+ OP(VertexAttrib1fvImmediate) /* 439 */ \
+ OP(VertexAttrib2f) /* 440 */ \
+ OP(VertexAttrib2fvImmediate) /* 441 */ \
+ OP(VertexAttrib3f) /* 442 */ \
+ OP(VertexAttrib3fvImmediate) /* 443 */ \
+ OP(VertexAttrib4f) /* 444 */ \
+ OP(VertexAttrib4fvImmediate) /* 445 */ \
+ OP(VertexAttribI4i) /* 446 */ \
+ OP(VertexAttribI4ivImmediate) /* 447 */ \
+ OP(VertexAttribI4ui) /* 448 */ \
+ OP(VertexAttribI4uivImmediate) /* 449 */ \
+ OP(VertexAttribIPointer) /* 450 */ \
+ OP(VertexAttribPointer) /* 451 */ \
+ OP(Viewport) /* 452 */ \
+ OP(BlitFramebufferCHROMIUM) /* 453 */ \
+ OP(RenderbufferStorageMultisampleCHROMIUM) /* 454 */ \
+ OP(RenderbufferStorageMultisampleEXT) /* 455 */ \
+ OP(FramebufferTexture2DMultisampleEXT) /* 456 */ \
+ OP(TexStorage2DEXT) /* 457 */ \
+ OP(GenQueriesEXTImmediate) /* 458 */ \
+ OP(DeleteQueriesEXTImmediate) /* 459 */ \
+ OP(BeginQueryEXT) /* 460 */ \
+ OP(BeginTransformFeedback) /* 461 */ \
+ OP(EndQueryEXT) /* 462 */ \
+ OP(EndTransformFeedback) /* 463 */ \
+ OP(InsertEventMarkerEXT) /* 464 */ \
+ OP(PushGroupMarkerEXT) /* 465 */ \
+ OP(PopGroupMarkerEXT) /* 466 */ \
+ OP(GenVertexArraysOESImmediate) /* 467 */ \
+ OP(DeleteVertexArraysOESImmediate) /* 468 */ \
+ OP(IsVertexArrayOES) /* 469 */ \
+ OP(BindVertexArrayOES) /* 470 */ \
+ OP(SwapBuffers) /* 471 */ \
+ OP(GetMaxValueInBufferCHROMIUM) /* 472 */ \
+ OP(EnableFeatureCHROMIUM) /* 473 */ \
+ OP(ResizeCHROMIUM) /* 474 */ \
+ OP(GetRequestableExtensionsCHROMIUM) /* 475 */ \
+ OP(RequestExtensionCHROMIUM) /* 476 */ \
+ OP(GetProgramInfoCHROMIUM) /* 477 */ \
+ OP(GetTranslatedShaderSourceANGLE) /* 478 */ \
+ OP(PostSubBufferCHROMIUM) /* 479 */ \
+ OP(TexImageIOSurface2DCHROMIUM) /* 480 */ \
+ OP(CopyTextureCHROMIUM) /* 481 */ \
+ OP(DrawArraysInstancedANGLE) /* 482 */ \
+ OP(DrawElementsInstancedANGLE) /* 483 */ \
+ OP(VertexAttribDivisorANGLE) /* 484 */ \
+ OP(GenMailboxCHROMIUM) /* 485 */ \
+ OP(ProduceTextureCHROMIUMImmediate) /* 486 */ \
+ OP(ProduceTextureDirectCHROMIUMImmediate) /* 487 */ \
+ OP(ConsumeTextureCHROMIUMImmediate) /* 488 */ \
+ OP(CreateAndConsumeTextureCHROMIUMImmediate) /* 489 */ \
+ OP(BindUniformLocationCHROMIUMBucket) /* 490 */ \
+ OP(GenValuebuffersCHROMIUMImmediate) /* 491 */ \
+ OP(DeleteValuebuffersCHROMIUMImmediate) /* 492 */ \
+ OP(IsValuebufferCHROMIUM) /* 493 */ \
+ OP(BindValuebufferCHROMIUM) /* 494 */ \
+ OP(SubscribeValueCHROMIUM) /* 495 */ \
+ OP(PopulateSubscribedValuesCHROMIUM) /* 496 */ \
+ OP(UniformValuebufferCHROMIUM) /* 497 */ \
+ OP(BindTexImage2DCHROMIUM) /* 498 */ \
+ OP(ReleaseTexImage2DCHROMIUM) /* 499 */ \
+ OP(TraceBeginCHROMIUM) /* 500 */ \
+ OP(TraceEndCHROMIUM) /* 501 */ \
+ OP(AsyncTexSubImage2DCHROMIUM) /* 502 */ \
+ OP(AsyncTexImage2DCHROMIUM) /* 503 */ \
+ OP(WaitAsyncTexImage2DCHROMIUM) /* 504 */ \
+ OP(WaitAllAsyncTexImage2DCHROMIUM) /* 505 */ \
+ OP(DiscardFramebufferEXTImmediate) /* 506 */ \
+ OP(LoseContextCHROMIUM) /* 507 */ \
+ OP(InsertSyncPointCHROMIUM) /* 508 */ \
+ OP(WaitSyncPointCHROMIUM) /* 509 */ \
+ OP(DrawBuffersEXTImmediate) /* 510 */ \
+ OP(DiscardBackbufferCHROMIUM) /* 511 */ \
+ OP(ScheduleOverlayPlaneCHROMIUM) /* 512 */ \
+ OP(SwapInterval) /* 513 */ \
+ OP(MatrixLoadfCHROMIUMImmediate) /* 514 */ \
+ OP(MatrixLoadIdentityCHROMIUM) /* 515 */ \
+ OP(BlendBarrierKHR) /* 516 */
enum CommandId {
kStartPoint = cmd::kLastCommonId, // All GLES2 commands start after this.
diff --git a/gpu/command_buffer/common/gles2_cmd_utils_autogen.h b/gpu/command_buffer/common/gles2_cmd_utils_autogen.h
index 8820225..02e4440 100644
--- a/gpu/command_buffer/common/gles2_cmd_utils_autogen.h
+++ b/gpu/command_buffer/common/gles2_cmd_utils_autogen.h
@@ -62,6 +62,7 @@
static std::string GetStringStencilOp(uint32_t value);
static std::string GetStringStringType(uint32_t value);
static std::string GetStringSubscriptionTarget(uint32_t value);
+static std::string GetStringSyncCondition(uint32_t value);
static std::string GetStringTexture3DTarget(uint32_t value);
static std::string GetStringTextureBindTarget(uint32_t value);
static std::string GetStringTextureFormat(uint32_t value);
diff --git a/gpu/command_buffer/common/gles2_cmd_utils_implementation_autogen.h b/gpu/command_buffer/common/gles2_cmd_utils_implementation_autogen.h
index b28c5e5..765cce6 100644
--- a/gpu/command_buffer/common/gles2_cmd_utils_implementation_autogen.h
+++ b/gpu/command_buffer/common/gles2_cmd_utils_implementation_autogen.h
@@ -5092,6 +5092,14 @@
arraysize(string_table), value);
}
+std::string GLES2Util::GetStringSyncCondition(uint32_t value) {
+ static const EnumToString string_table[] = {
+ {0x9117, "0x9117"},
+ };
+ return GLES2Util::GetQualifiedEnumString(string_table,
+ arraysize(string_table), value);
+}
+
std::string GLES2Util::GetStringTexture3DTarget(uint32_t value) {
static const EnumToString string_table[] = {
{GL_TEXTURE_3D, "GL_TEXTURE_3D"},
diff --git a/gpu/command_buffer/service/context_group.h b/gpu/command_buffer/service/context_group.h
index 8eeaf53..248fa19 100644
--- a/gpu/command_buffer/service/context_group.h
+++ b/gpu/command_buffer/service/context_group.h
@@ -5,7 +5,6 @@
#ifndef GPU_COMMAND_BUFFER_SERVICE_CONTEXT_GROUP_H_
#define GPU_COMMAND_BUFFER_SERVICE_CONTEXT_GROUP_H_
-#include <map>
#include <string>
#include <vector>
#include "base/basictypes.h"
@@ -184,7 +183,7 @@
}
bool GetSamplerServiceId(GLuint client_id, GLuint* service_id) const {
- std::map<GLuint, GLuint>::const_iterator iter =
+ base::hash_map<GLuint, GLuint>::const_iterator iter =
samplers_id_map_.find(client_id);
if (iter == samplers_id_map_.end())
return false;
@@ -203,7 +202,7 @@
bool GetTransformFeedbackServiceId(
GLuint client_id, GLuint* service_id) const {
- std::map<GLuint, GLuint>::const_iterator iter =
+ base::hash_map<GLuint, GLuint>::const_iterator iter =
transformfeedbacks_id_map_.find(client_id);
if (iter == transformfeedbacks_id_map_.end())
return false;
@@ -216,6 +215,24 @@
transformfeedbacks_id_map_.erase(client_id);
}
+ void AddSyncId(GLuint client_id, GLsync service_id) {
+ syncs_id_map_[client_id] = service_id;
+ }
+
+ bool GetSyncServiceId(GLuint client_id, GLsync* service_id) const {
+ base::hash_map<GLuint, GLsync>::const_iterator iter =
+ syncs_id_map_.find(client_id);
+ if (iter == syncs_id_map_.end())
+ return false;
+ if (service_id)
+ *service_id = iter->second;
+ return true;
+ }
+
+ void RemoveSyncId(GLuint client_id) {
+ syncs_id_map_.erase(client_id);
+ }
+
private:
friend class base::RefCounted<ContextGroup>;
~ContextGroup();
@@ -267,8 +284,9 @@
std::vector<base::WeakPtr<gles2::GLES2Decoder> > decoders_;
// Mappings from client side IDs to service side IDs.
- std::map<GLuint, GLuint> samplers_id_map_;
- std::map<GLuint, GLuint> transformfeedbacks_id_map_;
+ base::hash_map<GLuint, GLuint> samplers_id_map_;
+ base::hash_map<GLuint, GLuint> transformfeedbacks_id_map_;
+ base::hash_map<GLuint, GLsync> syncs_id_map_;
GLenum draw_buffer_;
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc
index f56d47b..5fb0fa8 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
@@ -1170,9 +1170,9 @@
GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
const std::string& name_str);
- // Helper for glShaderSource.
- error::Error ShaderSourceHelper(
- GLuint client_id, const char* data, uint32 data_size);
+ // Wrapper for glShaderSource.
+ void DoShaderSource(
+ GLuint client_id, GLsizei count, const char** data, const GLint* length);
// Clear any textures used by the current program.
bool ClearUnclearedTextures();
@@ -1278,12 +1278,6 @@
void GetVertexAttribHelper(
const VertexAttrib* attrib, GLenum pname, GLint* param);
- // Wrapper for glCreateProgram
- bool CreateProgramHelper(GLuint client_id);
-
- // Wrapper for glCreateShader
- bool CreateShaderHelper(GLenum type, GLuint client_id);
-
// Wrapper for glActiveTexture
void DoActiveTexture(GLenum texture_unit);
@@ -4049,28 +4043,6 @@
buffer_manager()->RemoveBuffer(client_id);
}
-bool GLES2DecoderImpl::CreateProgramHelper(GLuint client_id) {
- if (GetProgram(client_id)) {
- return false;
- }
- GLuint service_id = glCreateProgram();
- if (service_id != 0) {
- CreateProgram(client_id, service_id);
- }
- return true;
-}
-
-bool GLES2DecoderImpl::CreateShaderHelper(GLenum type, GLuint client_id) {
- if (GetShader(client_id)) {
- return false;
- }
- GLuint service_id = glCreateShader(type);
- if (service_id != 0) {
- CreateShader(client_id, service_id, type);
- }
- return true;
-}
-
void GLES2DecoderImpl::DoFinish() {
glFinish();
ProcessPendingReadPixels();
@@ -7066,35 +7038,19 @@
return max_vertex_accessed;
}
-// Calls glShaderSource for the various versions of the ShaderSource command.
-// Assumes that data / data_size points to a piece of memory that is in range
-// of whatever context it came from (shared memory, immediate memory, bucket
-// memory.)
-error::Error GLES2DecoderImpl::ShaderSourceHelper(
- GLuint client_id, const char* data, uint32 data_size) {
- std::string str(data, data + data_size);
+void GLES2DecoderImpl::DoShaderSource(
+ GLuint client_id, GLsizei count, const char** data, const GLint* length) {
+ std::string str;
+ for (GLsizei ii = 0; ii < count; ++ii) {
+ str.append(data[ii]);
+ }
Shader* shader = GetShaderInfoNotProgram(client_id, "glShaderSource");
if (!shader) {
- return error::kNoError;
+ return;
}
// Note: We don't actually call glShaderSource here. We wait until
// the call to glCompileShader.
shader->set_source(str);
- return error::kNoError;
-}
-
-error::Error GLES2DecoderImpl::HandleShaderSourceBucket(
- uint32 immediate_data_size,
- const void* cmd_data) {
- const gles2::cmds::ShaderSourceBucket& c =
- *static_cast<const gles2::cmds::ShaderSourceBucket*>(cmd_data);
- Bucket* bucket = GetBucket(c.data_bucket_id);
- if (!bucket || bucket->size() == 0) {
- return error::kInvalidArguments;
- }
- return ShaderSourceHelper(
- c.shader, bucket->GetDataAs<const char*>(0, bucket->size() - 1),
- bucket->size() - 1);
}
void GLES2DecoderImpl::DoCompileShader(GLuint client_id) {
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h b/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h
index 7766b0d..a1947f4 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h
@@ -703,9 +703,13 @@
*static_cast<const gles2::cmds::CreateProgram*>(cmd_data);
(void)c;
uint32_t client_id = c.client_id;
- if (!CreateProgramHelper(client_id)) {
+ if (GetProgram(client_id)) {
return error::kInvalidArguments;
}
+ GLuint service_id = glCreateProgram();
+ if (service_id) {
+ CreateProgram(client_id, service_id);
+ }
return error::kNoError;
}
@@ -720,9 +724,13 @@
return error::kNoError;
}
uint32_t client_id = c.client_id;
- if (!CreateShaderHelper(type, client_id)) {
+ if (GetShader(client_id)) {
return error::kInvalidArguments;
}
+ GLuint service_id = glCreateShader(type);
+ if (service_id) {
+ CreateShader(client_id, service_id, type);
+ }
return error::kNoError;
}
@@ -831,6 +839,24 @@
return error::kNoError;
}
+error::Error GLES2DecoderImpl::HandleDeleteSync(uint32_t immediate_data_size,
+ const void* cmd_data) {
+ if (!unsafe_es3_apis_enabled())
+ return error::kUnknownCommand;
+ const gles2::cmds::DeleteSync& c =
+ *static_cast<const gles2::cmds::DeleteSync*>(cmd_data);
+ (void)c;
+ GLuint sync = c.sync;
+ GLsync service_id = 0;
+ if (group_->GetSyncServiceId(sync, &service_id)) {
+ glDeleteSync(service_id);
+ group_->RemoveSyncId(sync);
+ } else {
+ LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glDeleteSync", "unknown sync");
+ }
+ return error::kNoError;
+}
+
error::Error GLES2DecoderImpl::HandleDeleteTexturesImmediate(
uint32_t immediate_data_size,
const void* cmd_data) {
@@ -982,6 +1008,27 @@
return error::kNoError;
}
+error::Error GLES2DecoderImpl::HandleFenceSync(uint32_t immediate_data_size,
+ const void* cmd_data) {
+ if (!unsafe_es3_apis_enabled())
+ return error::kUnknownCommand;
+ const gles2::cmds::FenceSync& c =
+ *static_cast<const gles2::cmds::FenceSync*>(cmd_data);
+ (void)c;
+ GLenum condition = static_cast<GLenum>(c.condition);
+ GLbitfield flags = static_cast<GLbitfield>(c.flags);
+ uint32_t client_id = c.client_id;
+ GLsync service_id = 0;
+ if (group_->GetSyncServiceId(client_id, &service_id)) {
+ return error::kInvalidArguments;
+ }
+ service_id = glFenceSync(condition, flags);
+ if (service_id) {
+ group_->AddSyncId(client_id, service_id);
+ }
+ return error::kNoError;
+}
+
error::Error GLES2DecoderImpl::HandleFinish(uint32_t immediate_data_size,
const void* cmd_data) {
const gles2::cmds::Finish& c =
@@ -2044,7 +2091,8 @@
if (!result_dst) {
return error::kOutOfBounds;
}
- *result_dst = group_->GetSamplerServiceId(sampler, &sampler);
+ GLuint service_sampler = 0;
+ *result_dst = group_->GetSamplerServiceId(sampler, &service_sampler);
return error::kNoError;
}
@@ -2064,6 +2112,25 @@
return error::kNoError;
}
+error::Error GLES2DecoderImpl::HandleIsSync(uint32_t immediate_data_size,
+ const void* cmd_data) {
+ if (!unsafe_es3_apis_enabled())
+ return error::kUnknownCommand;
+ const gles2::cmds::IsSync& c =
+ *static_cast<const gles2::cmds::IsSync*>(cmd_data);
+ (void)c;
+ GLuint sync = c.sync;
+ typedef cmds::IsSync::Result Result;
+ Result* result_dst = GetSharedMemoryAs<Result*>(
+ c.result_shm_id, c.result_shm_offset, sizeof(*result_dst));
+ if (!result_dst) {
+ return error::kOutOfBounds;
+ }
+ GLsync service_sync = 0;
+ *result_dst = group_->GetSyncServiceId(sync, &service_sync);
+ return error::kNoError;
+}
+
error::Error GLES2DecoderImpl::HandleIsTexture(uint32_t immediate_data_size,
const void* cmd_data) {
const gles2::cmds::IsTexture& c =
@@ -2095,8 +2162,9 @@
if (!result_dst) {
return error::kOutOfBounds;
}
- *result_dst = group_->GetTransformFeedbackServiceId(transformfeedback,
- &transformfeedback);
+ GLuint service_transformfeedback = 0;
+ *result_dst = group_->GetTransformFeedbackServiceId(
+ transformfeedback, &service_transformfeedback);
return error::kNoError;
}
@@ -2353,6 +2421,60 @@
return error::kNoError;
}
+error::Error GLES2DecoderImpl::HandleShaderSourceBucket(
+ uint32_t immediate_data_size,
+ const void* cmd_data) {
+ const gles2::cmds::ShaderSourceBucket& c =
+ *static_cast<const gles2::cmds::ShaderSourceBucket*>(cmd_data);
+ (void)c;
+ GLuint shader = static_cast<GLuint>(c.shader);
+
+ const size_t kMinBucketSize = sizeof(GLint);
+ // Each string has at least |length| in the header and a NUL character.
+ const size_t kMinStringSize = sizeof(GLint) + 1;
+ Bucket* bucket = GetBucket(c.str_bucket_id);
+ if (!bucket) {
+ return error::kInvalidArguments;
+ }
+ const size_t bucket_size = bucket->size();
+ if (bucket_size < kMinBucketSize) {
+ return error::kInvalidArguments;
+ }
+ const char* bucket_data = bucket->GetDataAs<const char*>(0, bucket_size);
+ const GLint* header = reinterpret_cast<const GLint*>(bucket_data);
+ GLsizei count = static_cast<GLsizei>(header[0]);
+ if (count < 0) {
+ return error::kInvalidArguments;
+ }
+ const size_t max_count = (bucket_size - kMinBucketSize) / kMinStringSize;
+ if (max_count < static_cast<size_t>(count)) {
+ return error::kInvalidArguments;
+ }
+ const GLint* length = header + 1;
+ scoped_ptr<const char* []> strs;
+ if (count > 0)
+ strs.reset(new const char* [count]);
+ const char** str = strs.get();
+ base::CheckedNumeric<size_t> total_size = sizeof(GLint);
+ total_size *= count + 1; // Header size.
+ if (!total_size.IsValid())
+ return error::kInvalidArguments;
+ for (GLsizei ii = 0; ii < count; ++ii) {
+ str[ii] = bucket_data + total_size.ValueOrDefault(0);
+ total_size += length[ii];
+ total_size += 1; // NUL char at the end of each char array.
+ if (!total_size.IsValid() || total_size.ValueOrDefault(0) > bucket_size ||
+ str[ii][length[ii]] != 0) {
+ return error::kInvalidArguments;
+ }
+ }
+ if (total_size.ValueOrDefault(0) != bucket_size) {
+ return error::kInvalidArguments;
+ }
+ DoShaderSource(shader, count, str, length);
+ return error::kNoError;
+}
+
error::Error GLES2DecoderImpl::HandleStencilFunc(uint32_t immediate_data_size,
const void* cmd_data) {
const gles2::cmds::StencilFunc& c =
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_1.cc b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_1.cc
index db1c62f..381bb0c 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_1.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_1.cc
@@ -252,33 +252,6 @@
base::Bind(&ShaderCacheCb));
};
-template <>
-void GLES2DecoderTestBase::SpecializedSetup<cmds::GetVertexAttribfv, 0>(
- bool valid) {
- DoBindBuffer(GL_ARRAY_BUFFER, client_buffer_id_, kServiceBufferId);
- DoVertexAttribPointer(1, 1, GL_FLOAT, 0, 0);
- if (valid) {
- EXPECT_CALL(*gl_, GetError())
- .WillOnce(Return(GL_NO_ERROR))
- .WillOnce(Return(GL_NO_ERROR))
- .RetiresOnSaturation();
- }
-};
-
-template <>
-void GLES2DecoderTestBase::SpecializedSetup<cmds::GetVertexAttribiv, 0>(
- bool valid) {
- DoBindBuffer(GL_ARRAY_BUFFER, client_buffer_id_, kServiceBufferId);
- DoVertexAttribPointer(1, 1, GL_FLOAT, 0, 0);
- if (valid) {
- EXPECT_CALL(*gl_, GetError())
- .WillOnce(Return(GL_NO_ERROR))
- .WillOnce(Return(GL_NO_ERROR))
- .RetiresOnSaturation();
- }
-};
-
-
#include "gpu/command_buffer/service/gles2_cmd_decoder_unittest_1_autogen.h"
} // namespace gles2
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_1_autogen.h b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_1_autogen.h
index 7794274..0a78a60 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_1_autogen.h
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_1_autogen.h
@@ -558,7 +558,7 @@
cmd.Init(kNewClientId);
EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
EXPECT_EQ(GL_NO_ERROR, GetGLError());
- EXPECT_TRUE(GetProgram(kNewClientId) != NULL);
+ EXPECT_TRUE(GetProgram(kNewClientId));
}
TEST_P(GLES2DecoderTest1, CreateShaderValidArgs) {
@@ -569,7 +569,7 @@
cmd.Init(GL_VERTEX_SHADER, kNewClientId);
EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
EXPECT_EQ(GL_NO_ERROR, GetGLError());
- EXPECT_TRUE(GetShader(kNewClientId) != NULL);
+ EXPECT_TRUE(GetShader(kNewClientId));
}
TEST_P(GLES2DecoderTest1, CreateShaderInvalidArgs0_0) {
@@ -692,6 +692,18 @@
EXPECT_EQ(error::kUnknownCommand, ExecuteImmediateCmd(cmd, sizeof(temp)));
}
+TEST_P(GLES2DecoderTest1, DeleteSyncValidArgs) {
+ EXPECT_CALL(*gl_, DeleteSync(reinterpret_cast<GLsync>(kServiceSyncId)));
+ SpecializedSetup<cmds::DeleteSync, 0>(true);
+ cmds::DeleteSync cmd;
+ cmd.Init(client_sync_id_);
+ decoder_->set_unsafe_es3_apis_enabled(true);
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+ EXPECT_EQ(GL_NO_ERROR, GetGLError());
+ decoder_->set_unsafe_es3_apis_enabled(false);
+ EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd));
+}
+
TEST_P(GLES2DecoderTest1, DeleteShaderValidArgs) {
EXPECT_CALL(*gl_, DeleteShader(kServiceShaderId));
SpecializedSetup<cmds::DeleteShader, 0>(true);
@@ -862,6 +874,22 @@
EXPECT_EQ(GL_NO_ERROR, GetGLError());
}
+TEST_P(GLES2DecoderTest1, FenceSyncValidArgs) {
+ const GLsync kNewServiceIdGLuint = reinterpret_cast<GLsync>(kNewServiceId);
+ EXPECT_CALL(*gl_, FenceSync(0x9117, 0)).WillOnce(Return(kNewServiceIdGLuint));
+ SpecializedSetup<cmds::FenceSync, 0>(true);
+ cmds::FenceSync cmd;
+ cmd.Init(kNewClientId);
+ decoder_->set_unsafe_es3_apis_enabled(true);
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+ EXPECT_EQ(GL_NO_ERROR, GetGLError());
+ GLsync service_id = 0;
+ EXPECT_TRUE(GetSyncServiceId(kNewClientId, &service_id));
+ EXPECT_EQ(kNewServiceIdGLuint, service_id);
+ decoder_->set_unsafe_es3_apis_enabled(false);
+ EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd));
+}
+
TEST_P(GLES2DecoderTest1, FinishValidArgs) {
EXPECT_CALL(*gl_, Finish());
SpecializedSetup<cmds::Finish, 0>(true);
@@ -1917,83 +1945,4 @@
// TODO(gman): GetUniformLocation
-TEST_P(GLES2DecoderTest1, GetVertexAttribfvValidArgs) {
- SpecializedSetup<cmds::GetVertexAttribfv, 0>(true);
- typedef cmds::GetVertexAttribfv::Result Result;
- Result* result = static_cast<Result*>(shared_memory_address_);
- result->size = 0;
- cmds::GetVertexAttribfv cmd;
- cmd.Init(1, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, shared_memory_id_,
- shared_memory_offset_);
- EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
- EXPECT_EQ(decoder_->GetGLES2Util()->GLGetNumValuesReturned(
- GL_VERTEX_ATTRIB_ARRAY_NORMALIZED),
- result->GetNumResults());
- EXPECT_EQ(GL_NO_ERROR, GetGLError());
-}
-
-TEST_P(GLES2DecoderTest1, GetVertexAttribfvInvalidArgs2_0) {
- EXPECT_CALL(*gl_, GetVertexAttribfv(_, _, _)).Times(0);
- SpecializedSetup<cmds::GetVertexAttribfv, 0>(false);
- cmds::GetVertexAttribfv::Result* result =
- static_cast<cmds::GetVertexAttribfv::Result*>(shared_memory_address_);
- result->size = 0;
- cmds::GetVertexAttribfv cmd;
- cmd.Init(1, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, kInvalidSharedMemoryId, 0);
- EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
- EXPECT_EQ(0u, result->size);
-}
-
-TEST_P(GLES2DecoderTest1, GetVertexAttribfvInvalidArgs2_1) {
- EXPECT_CALL(*gl_, GetVertexAttribfv(_, _, _)).Times(0);
- SpecializedSetup<cmds::GetVertexAttribfv, 0>(false);
- cmds::GetVertexAttribfv::Result* result =
- static_cast<cmds::GetVertexAttribfv::Result*>(shared_memory_address_);
- result->size = 0;
- cmds::GetVertexAttribfv cmd;
- cmd.Init(1, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, shared_memory_id_,
- kInvalidSharedMemoryOffset);
- EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
- EXPECT_EQ(0u, result->size);
-}
-
-TEST_P(GLES2DecoderTest1, GetVertexAttribivValidArgs) {
- SpecializedSetup<cmds::GetVertexAttribiv, 0>(true);
- typedef cmds::GetVertexAttribiv::Result Result;
- Result* result = static_cast<Result*>(shared_memory_address_);
- result->size = 0;
- cmds::GetVertexAttribiv cmd;
- cmd.Init(1, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, shared_memory_id_,
- shared_memory_offset_);
- EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
- EXPECT_EQ(decoder_->GetGLES2Util()->GLGetNumValuesReturned(
- GL_VERTEX_ATTRIB_ARRAY_NORMALIZED),
- result->GetNumResults());
- EXPECT_EQ(GL_NO_ERROR, GetGLError());
-}
-
-TEST_P(GLES2DecoderTest1, GetVertexAttribivInvalidArgs2_0) {
- EXPECT_CALL(*gl_, GetVertexAttribiv(_, _, _)).Times(0);
- SpecializedSetup<cmds::GetVertexAttribiv, 0>(false);
- cmds::GetVertexAttribiv::Result* result =
- static_cast<cmds::GetVertexAttribiv::Result*>(shared_memory_address_);
- result->size = 0;
- cmds::GetVertexAttribiv cmd;
- cmd.Init(1, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, kInvalidSharedMemoryId, 0);
- EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
- EXPECT_EQ(0u, result->size);
-}
-
-TEST_P(GLES2DecoderTest1, GetVertexAttribivInvalidArgs2_1) {
- EXPECT_CALL(*gl_, GetVertexAttribiv(_, _, _)).Times(0);
- SpecializedSetup<cmds::GetVertexAttribiv, 0>(false);
- cmds::GetVertexAttribiv::Result* result =
- static_cast<cmds::GetVertexAttribiv::Result*>(shared_memory_address_);
- result->size = 0;
- cmds::GetVertexAttribiv cmd;
- cmd.Init(1, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, shared_memory_id_,
- kInvalidSharedMemoryOffset);
- EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
- EXPECT_EQ(0u, result->size);
-}
#endif // GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_DECODER_UNITTEST_1_AUTOGEN_H_
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_2.cc b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_2.cc
index 5d0ce3f..cfd1c1a 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_2.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_2.cc
@@ -518,6 +518,33 @@
DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
};
+template <>
+void GLES2DecoderTestBase::SpecializedSetup<cmds::GetVertexAttribiv, 0>(
+ bool valid) {
+ DoBindBuffer(GL_ARRAY_BUFFER, client_buffer_id_, kServiceBufferId);
+ DoVertexAttribPointer(1, 1, GL_FLOAT, 0, 0);
+ if (valid) {
+ EXPECT_CALL(*gl_, GetError())
+ .WillOnce(Return(GL_NO_ERROR))
+ .WillOnce(Return(GL_NO_ERROR))
+ .RetiresOnSaturation();
+ }
+};
+
+template <>
+void GLES2DecoderTestBase::SpecializedSetup<cmds::GetVertexAttribfv, 0>(
+ bool valid) {
+ DoBindBuffer(GL_ARRAY_BUFFER, client_buffer_id_, kServiceBufferId);
+ DoVertexAttribPointer(1, 1, GL_FLOAT, 0, 0);
+ if (valid) {
+ EXPECT_CALL(*gl_, GetError())
+ .WillOnce(Return(GL_NO_ERROR))
+ .WillOnce(Return(GL_NO_ERROR))
+ .RetiresOnSaturation();
+ }
+};
+
+
#include "gpu/command_buffer/service/gles2_cmd_decoder_unittest_2_autogen.h"
TEST_P(GLES2DecoderTest2, AcceptsUniform_GL_INT) {
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_2_autogen.h b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_2_autogen.h
index aa387be..8670cbc 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_2_autogen.h
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_2_autogen.h
@@ -12,6 +12,85 @@
#ifndef GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_DECODER_UNITTEST_2_AUTOGEN_H_
#define GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_DECODER_UNITTEST_2_AUTOGEN_H_
+TEST_P(GLES2DecoderTest2, GetVertexAttribfvValidArgs) {
+ SpecializedSetup<cmds::GetVertexAttribfv, 0>(true);
+ typedef cmds::GetVertexAttribfv::Result Result;
+ Result* result = static_cast<Result*>(shared_memory_address_);
+ result->size = 0;
+ cmds::GetVertexAttribfv cmd;
+ cmd.Init(1, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, shared_memory_id_,
+ shared_memory_offset_);
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+ EXPECT_EQ(decoder_->GetGLES2Util()->GLGetNumValuesReturned(
+ GL_VERTEX_ATTRIB_ARRAY_NORMALIZED),
+ result->GetNumResults());
+ EXPECT_EQ(GL_NO_ERROR, GetGLError());
+}
+
+TEST_P(GLES2DecoderTest2, GetVertexAttribfvInvalidArgs2_0) {
+ EXPECT_CALL(*gl_, GetVertexAttribfv(_, _, _)).Times(0);
+ SpecializedSetup<cmds::GetVertexAttribfv, 0>(false);
+ cmds::GetVertexAttribfv::Result* result =
+ static_cast<cmds::GetVertexAttribfv::Result*>(shared_memory_address_);
+ result->size = 0;
+ cmds::GetVertexAttribfv cmd;
+ cmd.Init(1, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, kInvalidSharedMemoryId, 0);
+ EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
+ EXPECT_EQ(0u, result->size);
+}
+
+TEST_P(GLES2DecoderTest2, GetVertexAttribfvInvalidArgs2_1) {
+ EXPECT_CALL(*gl_, GetVertexAttribfv(_, _, _)).Times(0);
+ SpecializedSetup<cmds::GetVertexAttribfv, 0>(false);
+ cmds::GetVertexAttribfv::Result* result =
+ static_cast<cmds::GetVertexAttribfv::Result*>(shared_memory_address_);
+ result->size = 0;
+ cmds::GetVertexAttribfv cmd;
+ cmd.Init(1, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, shared_memory_id_,
+ kInvalidSharedMemoryOffset);
+ EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
+ EXPECT_EQ(0u, result->size);
+}
+
+TEST_P(GLES2DecoderTest2, GetVertexAttribivValidArgs) {
+ SpecializedSetup<cmds::GetVertexAttribiv, 0>(true);
+ typedef cmds::GetVertexAttribiv::Result Result;
+ Result* result = static_cast<Result*>(shared_memory_address_);
+ result->size = 0;
+ cmds::GetVertexAttribiv cmd;
+ cmd.Init(1, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, shared_memory_id_,
+ shared_memory_offset_);
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+ EXPECT_EQ(decoder_->GetGLES2Util()->GLGetNumValuesReturned(
+ GL_VERTEX_ATTRIB_ARRAY_NORMALIZED),
+ result->GetNumResults());
+ EXPECT_EQ(GL_NO_ERROR, GetGLError());
+}
+
+TEST_P(GLES2DecoderTest2, GetVertexAttribivInvalidArgs2_0) {
+ EXPECT_CALL(*gl_, GetVertexAttribiv(_, _, _)).Times(0);
+ SpecializedSetup<cmds::GetVertexAttribiv, 0>(false);
+ cmds::GetVertexAttribiv::Result* result =
+ static_cast<cmds::GetVertexAttribiv::Result*>(shared_memory_address_);
+ result->size = 0;
+ cmds::GetVertexAttribiv cmd;
+ cmd.Init(1, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, kInvalidSharedMemoryId, 0);
+ EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
+ EXPECT_EQ(0u, result->size);
+}
+
+TEST_P(GLES2DecoderTest2, GetVertexAttribivInvalidArgs2_1) {
+ EXPECT_CALL(*gl_, GetVertexAttribiv(_, _, _)).Times(0);
+ SpecializedSetup<cmds::GetVertexAttribiv, 0>(false);
+ cmds::GetVertexAttribiv::Result* result =
+ static_cast<cmds::GetVertexAttribiv::Result*>(shared_memory_address_);
+ result->size = 0;
+ cmds::GetVertexAttribiv cmd;
+ cmd.Init(1, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, shared_memory_id_,
+ kInvalidSharedMemoryOffset);
+ EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
+ EXPECT_EQ(0u, result->size);
+}
// TODO(gman): GetVertexAttribPointerv
TEST_P(GLES2DecoderTest2, HintValidArgs) {
@@ -180,6 +259,28 @@
EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
}
+TEST_P(GLES2DecoderTest2, IsSyncValidArgs) {
+ SpecializedSetup<cmds::IsSync, 0>(true);
+ cmds::IsSync cmd;
+ cmd.Init(client_sync_id_, shared_memory_id_, shared_memory_offset_);
+ decoder_->set_unsafe_es3_apis_enabled(true);
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+ EXPECT_EQ(GL_NO_ERROR, GetGLError());
+ decoder_->set_unsafe_es3_apis_enabled(false);
+ EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd));
+}
+
+TEST_P(GLES2DecoderTest2, IsSyncInvalidArgsBadSharedMemoryId) {
+ SpecializedSetup<cmds::IsSync, 0>(false);
+ decoder_->set_unsafe_es3_apis_enabled(true);
+ cmds::IsSync cmd;
+ cmd.Init(client_sync_id_, kInvalidSharedMemoryId, shared_memory_offset_);
+ EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
+ cmd.Init(client_sync_id_, shared_memory_id_, kInvalidSharedMemoryOffset);
+ EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
+ decoder_->set_unsafe_es3_apis_enabled(true);
+}
+
TEST_P(GLES2DecoderTest2, IsTextureValidArgs) {
SpecializedSetup<cmds::IsTexture, 0>(true);
cmds::IsTexture cmd;
@@ -1322,30 +1423,4 @@
// TODO(gman): VertexAttribPointer
-TEST_P(GLES2DecoderTest2, ViewportValidArgs) {
- EXPECT_CALL(*gl_, Viewport(1, 2, 3, 4));
- SpecializedSetup<cmds::Viewport, 0>(true);
- cmds::Viewport cmd;
- cmd.Init(1, 2, 3, 4);
- EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
- EXPECT_EQ(GL_NO_ERROR, GetGLError());
-}
-
-TEST_P(GLES2DecoderTest2, ViewportInvalidArgs2_0) {
- EXPECT_CALL(*gl_, Viewport(_, _, _, _)).Times(0);
- SpecializedSetup<cmds::Viewport, 0>(false);
- cmds::Viewport cmd;
- cmd.Init(1, 2, -1, 4);
- EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
- EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
-}
-
-TEST_P(GLES2DecoderTest2, ViewportInvalidArgs3_0) {
- EXPECT_CALL(*gl_, Viewport(_, _, _, _)).Times(0);
- SpecializedSetup<cmds::Viewport, 0>(false);
- cmds::Viewport cmd;
- cmd.Init(1, 2, 3, -1);
- EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
- EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
-}
#endif // GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_DECODER_UNITTEST_2_AUTOGEN_H_
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_3_autogen.h b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_3_autogen.h
index ba2f4c2..bd1163d 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_3_autogen.h
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_3_autogen.h
@@ -12,6 +12,32 @@
#ifndef GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_DECODER_UNITTEST_3_AUTOGEN_H_
#define GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_DECODER_UNITTEST_3_AUTOGEN_H_
+TEST_P(GLES2DecoderTest3, ViewportValidArgs) {
+ EXPECT_CALL(*gl_, Viewport(1, 2, 3, 4));
+ SpecializedSetup<cmds::Viewport, 0>(true);
+ cmds::Viewport cmd;
+ cmd.Init(1, 2, 3, 4);
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+ EXPECT_EQ(GL_NO_ERROR, GetGLError());
+}
+
+TEST_P(GLES2DecoderTest3, ViewportInvalidArgs2_0) {
+ EXPECT_CALL(*gl_, Viewport(_, _, _, _)).Times(0);
+ SpecializedSetup<cmds::Viewport, 0>(false);
+ cmds::Viewport cmd;
+ cmd.Init(1, 2, -1, 4);
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+ EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
+}
+
+TEST_P(GLES2DecoderTest3, ViewportInvalidArgs3_0) {
+ EXPECT_CALL(*gl_, Viewport(_, _, _, _)).Times(0);
+ SpecializedSetup<cmds::Viewport, 0>(false);
+ cmds::Viewport cmd;
+ cmd.Init(1, 2, 3, -1);
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+ EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
+}
// TODO(gman): TexStorage2DEXT
// TODO(gman): GenQueriesEXTImmediate
// TODO(gman): DeleteQueriesEXTImmediate
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc
index c75354a..07d1eaf 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc
@@ -100,6 +100,7 @@
client_vertexarray_id_(124),
client_valuebuffer_id_(125),
client_transformfeedback_id_(126),
+ client_sync_id_(127),
service_renderbuffer_id_(0),
service_renderbuffer_valid_(false),
ignore_cached_state_for_test_(GetParam()),
@@ -430,6 +431,7 @@
.WillOnce(SetArgumentPointee<1>(kServiceTransformFeedbackId))
.RetiresOnSaturation();
GenHelper<cmds::GenTransformFeedbacksImmediate>(client_transformfeedback_id_);
+ DoFenceSync(client_sync_id_, kServiceSyncId);
if (reset_unsafe_es3_apis_enabled) {
decoder_->set_unsafe_es3_apis_enabled(false);
}
@@ -536,6 +538,17 @@
EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
}
+void GLES2DecoderTestBase::DoFenceSync(
+ GLuint client_id, GLuint service_id) {
+ EXPECT_CALL(*gl_, FenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0))
+ .Times(1)
+ .WillOnce(Return(reinterpret_cast<GLsync>(service_id)))
+ .RetiresOnSaturation();
+ cmds::FenceSync cmd;
+ cmd.Init(client_id);
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+}
+
void GLES2DecoderTestBase::SetBucketAsCString(
uint32 bucket_id, const char* str) {
uint32 size = str ? (strlen(str) + 1) : 0;
@@ -551,6 +564,39 @@
}
}
+void GLES2DecoderTestBase::SetBucketAsCStrings(
+ uint32 bucket_id, GLsizei count, const char** str,
+ GLsizei count_in_header, char str_end) {
+ uint32_t header_size = sizeof(GLint) * (count + 1);
+ uint32_t total_size = header_size;
+ scoped_ptr<GLint[]> header(new GLint[count + 1]);
+ header[0] = static_cast<GLint>(count_in_header);
+ for (GLsizei ii = 0; ii < count; ++ii) {
+ header[ii + 1] = str && str[ii] ? strlen(str[ii]) : 0;
+ total_size += header[ii + 1] + 1;
+ }
+ cmd::SetBucketSize cmd1;
+ cmd1.Init(bucket_id, total_size);
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd1));
+ memcpy(shared_memory_address_, header.get(), header_size);
+ uint32_t offset = header_size;
+ for (GLsizei ii = 0; ii < count; ++ii) {
+ if (str && str[ii]) {
+ size_t str_len = strlen(str[ii]);
+ memcpy(reinterpret_cast<char*>(shared_memory_address_) + offset,
+ str[ii], str_len);
+ offset += str_len;
+ }
+ memcpy(reinterpret_cast<char*>(shared_memory_address_) + offset,
+ &str_end, 1);
+ offset += 1;
+ }
+ cmd::SetBucketData cmd2;
+ cmd2.Init(bucket_id, 0, total_size, kSharedMemoryId, kSharedMemoryOffset);
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
+ ClearSharedMemory();
+}
+
void GLES2DecoderTestBase::SetupClearTextureExpectations(
GLuint service_id,
GLuint old_service_id,
@@ -1274,6 +1320,7 @@
const GLuint GLES2DecoderTestBase::kServiceQueryId;
const GLuint GLES2DecoderTestBase::kServiceVertexArrayId;
const GLuint GLES2DecoderTestBase::kServiceTransformFeedbackId;
+const GLuint GLES2DecoderTestBase::kServiceSyncId;
const int32 GLES2DecoderTestBase::kSharedMemoryId;
const size_t GLES2DecoderTestBase::kSharedBufferSize;
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h
index fa144a7..3159483 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h
@@ -142,6 +142,10 @@
return group_->GetTransformFeedbackServiceId(client_id, service_id);
}
+ bool GetSyncServiceId(GLuint client_id, GLsync* service_id) const {
+ return group_->GetSyncServiceId(client_id, service_id);
+ }
+
// This name doesn't match the underlying function, but doing it this way
// prevents the need to special-case the unit test generation
VertexAttribManager* GetVertexArrayInfo(GLuint client_id) {
@@ -164,8 +168,13 @@
void DoCreateProgram(GLuint client_id, GLuint service_id);
void DoCreateShader(GLenum shader_type, GLuint client_id, GLuint service_id);
+ void DoFenceSync(GLuint client_id, GLuint service_id);
void SetBucketAsCString(uint32 bucket_id, const char* str);
+ // If we want a valid bucket, just set |count_in_header| as |count|,
+ // and set |str_end| as 0.
+ void SetBucketAsCStrings(uint32 bucket_id, GLsizei count, const char** str,
+ GLsizei count_in_header, char str_end);
void set_memory_tracker(MemoryTracker* memory_tracker) {
memory_tracker_ = memory_tracker;
@@ -444,6 +453,7 @@
static const GLuint kServiceQueryId = 309;
static const GLuint kServiceVertexArrayId = 310;
static const GLuint kServiceTransformFeedbackId = 311;
+ static const GLuint kServiceSyncId = 312;
static const int32 kSharedMemoryId = 401;
static const size_t kSharedBufferSize = 2048;
@@ -543,6 +553,7 @@
GLuint client_vertexarray_id_;
GLuint client_valuebuffer_id_;
GLuint client_transformfeedback_id_;
+ GLuint client_sync_id_;
uint32 shared_memory_id_;
uint32 shared_memory_offset_;
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_programs.cc b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_programs.cc
index e663bdf..fefaacf 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_programs.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_programs.cc
@@ -693,9 +693,10 @@
TEST_P(GLES2DecoderTest, ShaderSourceBucketAndGetShaderSourceValidArgs) {
const uint32 kInBucketId = 123;
const uint32 kOutBucketId = 125;
- const char kSource[] = "hello";
- const uint32 kSourceSize = sizeof(kSource) - 1;
- SetBucketAsCString(kInBucketId, kSource);
+ const char kSource0[] = "hello";
+ const char* kSource[] = { kSource0 };
+ const char kValidStrEnd = 0;
+ SetBucketAsCStrings(kInBucketId, 1, kSource, 1, kValidStrEnd);
ShaderSourceBucket cmd;
cmd.Init(client_shader_id_, kInBucketId);
EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
@@ -705,27 +706,27 @@
EXPECT_EQ(error::kNoError, ExecuteCmd(get_cmd));
CommonDecoder::Bucket* bucket = decoder_->GetBucket(kOutBucketId);
ASSERT_TRUE(bucket != NULL);
- EXPECT_EQ(kSourceSize + 1, bucket->size());
- EXPECT_EQ(
- 0, memcmp(bucket->GetData(0, bucket->size()), kSource, bucket->size()));
+ EXPECT_EQ(sizeof(kSource0), bucket->size());
+ EXPECT_EQ(0, memcmp(bucket->GetData(0, bucket->size()),
+ kSource0, bucket->size()));
}
TEST_P(GLES2DecoderTest, ShaderSourceBucketInvalidArgs) {
const uint32 kBucketId = 123;
- const char kSource[] = "hello";
- const uint32 kSourceSize = sizeof(kSource) - 1;
- memcpy(shared_memory_address_, kSource, kSourceSize);
+ const char kSource0[] = "hello";
+ const char* kSource[] = { kSource0 };
+ const char kValidStrEnd = 0;
ShaderSourceBucket cmd;
// Test no bucket.
- cmd.Init(client_texture_id_, kBucketId);
+ cmd.Init(client_shader_id_, kBucketId);
EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
// Test invalid client.
- SetBucketAsCString(kBucketId, kSource);
+ SetBucketAsCStrings(kBucketId, 1, kSource, 1, kValidStrEnd);
cmd.Init(kInvalidClientId, kBucketId);
EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
#if GLES2_TEST_SHADER_VS_PROGRAM_IDS
- SetBucketAsCString(kBucketId, kSource);
+ SetBucketAsCStrings(kBucketId, 1, kSource);
cmd.Init(
client_program_id_, kBucketId);
EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
@@ -735,14 +736,55 @@
TEST_P(GLES2DecoderTest, ShaderSourceStripComments) {
const uint32 kInBucketId = 123;
- const char kSource[] = "hello/*te\ast*/world//a\ab";
- SetBucketAsCString(kInBucketId, kSource);
+ const char kSource0[] = "hello/*te\ast*/world//a\ab";
+ const char* kSource[] = { kSource0 };
+ const char kValidStrEnd = 0;
+ SetBucketAsCStrings(kInBucketId, 1, kSource, 1, kValidStrEnd);
ShaderSourceBucket cmd;
cmd.Init(client_shader_id_, kInBucketId);
EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
EXPECT_EQ(GL_NO_ERROR, GetGLError());
}
+TEST_P(GLES2DecoderTest, ShaderSourceInvalidHeader) {
+ const uint32 kInBucketId = 123;
+ const char kSource0[] = "hello";
+ const char* kSource[] = { kSource0 };
+ const char kValidStrEnd = 0;
+ const GLsizei kCount = 1;
+ const GLsizei kTests[] = {
+ kCount + 1,
+ 0,
+ std::numeric_limits<GLsizei>::max(),
+ -1,
+ kCount
+ };
+ size_t kTestCount = 5;
+ for (size_t ii = 0; ii < kTestCount; ++ii) {
+ SetBucketAsCStrings(kInBucketId, 1, kSource, kTests[ii], kValidStrEnd);
+ ShaderSourceBucket cmd;
+ cmd.Init(client_shader_id_, kInBucketId);
+ if (kTests[ii] == kCount) {
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+ } else {
+ EXPECT_EQ(error::kInvalidArguments, ExecuteCmd(cmd));
+ }
+ }
+ EXPECT_EQ(GL_NO_ERROR, GetGLError());
+}
+
+TEST_P(GLES2DecoderTest, ShaderSourceInvalidStringEnding) {
+ const uint32 kInBucketId = 123;
+ const char kSource0[] = "hello";
+ const char* kSource[] = { kSource0 };
+ const char kInvalidStrEnd = '*';
+ SetBucketAsCStrings(kInBucketId, 1, kSource, 1, kInvalidStrEnd);
+ ShaderSourceBucket cmd;
+ cmd.Init(client_shader_id_, kInBucketId);
+ EXPECT_EQ(error::kInvalidArguments, ExecuteCmd(cmd));
+ EXPECT_EQ(GL_NO_ERROR, GetGLError());
+}
+
TEST_P(GLES2DecoderWithShaderTest, Uniform1iValidArgs) {
EXPECT_CALL(*gl_, Uniform1i(kUniform1RealLocation, 2));
Uniform1i cmd;
diff --git a/gpu/command_buffer/tests/gl_manager.cc b/gpu/command_buffer/tests/gl_manager.cc
index 1075c42..8f4b330 100644
--- a/gpu/command_buffer/tests/gl_manager.cc
+++ b/gpu/command_buffer/tests/gl_manager.cc
@@ -38,11 +38,11 @@
namespace gpu {
namespace {
-size_t BytesPerPixel(gfx::GpuMemoryBuffer::Format format) {
+size_t StrideInBytes(size_t width, gfx::GpuMemoryBuffer::Format format) {
switch (format) {
case gfx::GpuMemoryBuffer::RGBA_8888:
case gfx::GpuMemoryBuffer::BGRA_8888:
- return 4;
+ return width * 4;
case gfx::GpuMemoryBuffer::RGBX_8888:
NOTREACHED();
return 0;
@@ -72,7 +72,7 @@
bool IsMapped() const override { return mapped_; }
Format GetFormat() const override { return format_; }
uint32 GetStride() const override {
- return size_.width() * BytesPerPixel(format_);
+ return StrideInBytes(size_.width(), format_);
}
gfx::GpuMemoryBufferHandle GetHandle() const override {
NOTREACHED();
@@ -134,7 +134,8 @@
scoped_ptr<gfx::GpuMemoryBuffer> GLManager::CreateGpuMemoryBuffer(
const gfx::Size& size,
gfx::GpuMemoryBuffer::Format format) {
- std::vector<unsigned char> data(size.GetArea() * BytesPerPixel(format), 0);
+ std::vector<unsigned char> data(
+ StrideInBytes(size.width(), format) * size.height(), 0);
scoped_refptr<base::RefCountedBytes> bytes(new base::RefCountedBytes(data));
return make_scoped_ptr<gfx::GpuMemoryBuffer>(
new GpuMemoryBufferImpl(bytes.get(), size, format));
diff --git a/mojo/services/network/public/cpp/udp_socket_wrapper.cc b/mojo/services/network/public/cpp/udp_socket_wrapper.cc
index f82b330..8d8b7ea 100644
--- a/mojo/services/network/public/cpp/udp_socket_wrapper.cc
+++ b/mojo/services/network/public/cpp/udp_socket_wrapper.cc
@@ -85,6 +85,12 @@
socket_->Bind(addr.Pass(), callback);
}
+void UDPSocketWrapper::Connect(
+ NetAddressPtr remote_addr,
+ const Callback<void(NetworkErrorPtr, NetAddressPtr)>& callback) {
+ socket_->Connect(remote_addr.Pass(), callback);
+}
+
void UDPSocketWrapper::SetSendBufferSize(uint32_t size,
const ErrorCallback& callback) {
socket_->SetSendBufferSize(size, callback);
diff --git a/mojo/services/network/public/cpp/udp_socket_wrapper.h b/mojo/services/network/public/cpp/udp_socket_wrapper.h
index 32204d7..650f98e 100644
--- a/mojo/services/network/public/cpp/udp_socket_wrapper.h
+++ b/mojo/services/network/public/cpp/udp_socket_wrapper.h
@@ -43,6 +43,9 @@
void Bind(NetAddressPtr addr,
const Callback<void(NetworkErrorPtr, NetAddressPtr)>& callback);
+ void Connect(NetAddressPtr remote_addr,
+ const Callback<void(NetworkErrorPtr, NetAddressPtr)>& callback);
+
void SetSendBufferSize(uint32_t size, const ErrorCallback& callback);
void SetReceiveBufferSize(uint32_t size, const ErrorCallback& callback);
@@ -51,10 +54,13 @@
// |callback| before it returns, and the return value is set to true.
// Otherwise, the return value is set to false and the callback will be run
// asynchronously.
+ // If the socket is connected, the net address pointer passed into the
+ // callback is set to null.
bool ReceiveFrom(const ReceiveCallback& callback);
// This method is aware of the max pending send requests allowed by the
// service, and caches send requests locally if necessary.
+ // |dest_addr| is allowed to be null if the socket is connected.
void SendTo(NetAddressPtr dest_addr,
Array<uint8_t> data,
const ErrorCallback& callback);
diff --git a/mojo/services/network/public/interfaces/network_service.mojom b/mojo/services/network/public/interfaces/network_service.mojom
index 062285d..23bdebc 100644
--- a/mojo/services/network/public/interfaces/network_service.mojom
+++ b/mojo/services/network/public/interfaces/network_service.mojom
@@ -13,7 +13,7 @@
import "network/public/interfaces/url_loader.mojom";
import "network/public/interfaces/web_socket.mojom";
-// TODO Darin suggfests that this should probably be two classes. One for
+// TODO Darin suggests that this should probably be two classes. One for
// high-level origin-build requests like WebSockets and HTTP, and the other for
// non-origin-bound low-level stuff like DNS, UDP, and TCP.
interface NetworkService {
diff --git a/mojo/services/network/public/interfaces/udp_socket.mojom b/mojo/services/network/public/interfaces/udp_socket.mojom
index 677e25d..0ea08a5 100644
--- a/mojo/services/network/public/interfaces/udp_socket.mojom
+++ b/mojo/services/network/public/interfaces/udp_socket.mojom
@@ -20,13 +20,13 @@
[Client=UDPSocketClient]
interface UDPSocket {
// Allows the socket to share the local address to which it will be bound with
- // other processes. Should be called before Bind()/Connect().
+ // other processes. Should be called before Bind().
// (This is equivalent to SO_REUSEADDR of the POSIX socket API.)
AllowAddressReuse() => (NetworkError result);
// Binds the socket to the given address. The socket must not be bound or
// connected.
- // |bound_addr| is non-NULL on success. It might not be the same as |addr|.
+ // |bound_addr| is non-null on success. It might not be the same as |addr|.
// For example, if port 0 is used in |addr|, an available port is picked and
// returned in |bound_addr|.
Bind(NetAddress addr) => (NetworkError result, NetAddress? bound_addr);
@@ -34,7 +34,7 @@
// Connects the socket to the remote address. The socket must not be bound or
// connected.
- // |local_addr| is non-NULL on success.
+ // |local_addr| is non-null on success.
Connect(NetAddress remote_addr) => (NetworkError result,
NetAddress? local_addr);
@@ -97,7 +97,7 @@
ReceiveMore(uint32 datagram_number);
// Sends data to the specified destination. The socket must be bound or
- // connected. |dest_addr| is allowed to be NULL if the socket is connected.
+ // connected. |dest_addr| is allowed to be null if the socket is connected.
// On success, |result.code| is a non-negative number indicating how many
// bytes have been written. Otherwise, it is a network error code, including
// (but not limited to):
@@ -109,7 +109,7 @@
};
interface UDPSocketClient {
- // On success, |data| is non-NULL, |src_addr| is non-NULL if the socket is
+ // On success, |data| is non-null, |src_addr| is non-null if the socket is
// not connected, |result.code| is a non-negative number indicating how many
// bytes have been received. On failure, |result.code| is a network error
// code.
diff --git a/mojo/services/network/udp_socket_apptest.cc b/mojo/services/network/udp_socket_apptest.cc
index 079ed8f..86f3387 100644
--- a/mojo/services/network/udp_socket_apptest.cc
+++ b/mojo/services/network/udp_socket_apptest.cc
@@ -222,6 +222,62 @@
Array<uint8_t> data_;
};
+struct ReceiveResult {
+ NetworkErrorPtr result;
+ NetAddressPtr addr;
+ Array<uint8_t> data;
+};
+
+class UDPSocketClientImpl : public UDPSocketClient {
+ public:
+ UDPSocketClientImpl() : run_loop_(nullptr), expected_receive_count_(0) {}
+
+ ~UDPSocketClientImpl() override {
+ while (!results_.empty()) {
+ delete results_.front();
+ results_.pop();
+ }
+ }
+
+ std::queue<ReceiveResult*>* results() {
+ return &results_;
+ }
+
+ void WaitForReceiveResults(size_t count) {
+ if (results_.size() == count)
+ return;
+
+ expected_receive_count_ = count;
+ base::RunLoop run_loop;
+ run_loop_ = &run_loop;
+ run_loop.Run();
+ run_loop_ = nullptr;
+ }
+
+ private:
+ void OnReceived(NetworkErrorPtr result,
+ NetAddressPtr src_addr,
+ Array<uint8_t> data) override {
+ ReceiveResult* entry = new ReceiveResult();
+ entry->result = result.Pass();
+ entry->addr = src_addr.Pass();
+ entry->data = data.Pass();
+
+ results_.push(entry);
+
+ if (results_.size() == expected_receive_count_ && run_loop_) {
+ expected_receive_count_ = 0;
+ run_loop_->Quit();
+ }
+ }
+
+ base::RunLoop* run_loop_;
+ std::queue<ReceiveResult*> results_;
+ size_t expected_receive_count_;
+
+ DISALLOW_COPY_AND_ASSIGN(UDPSocketClientImpl);
+};
+
class UDPSocketAppTest : public test::ApplicationTestBase {
public:
UDPSocketAppTest() {}
@@ -234,70 +290,14 @@
application_impl()->ConnectToApplication("mojo:network_service");
connection->ConnectToService(&network_service_);
- network_service_->CreateUDPSocket(GetProxy(&udp_socket_));
- udp_socket_.set_client(&udp_socket_client_);
+ network_service_->CreateUDPSocket(GetProxy(&socket_));
+ socket_.set_client(&receiver_);
}
protected:
- struct ReceiveResult {
- NetworkErrorPtr result;
- NetAddressPtr addr;
- Array<uint8_t> data;
- };
-
- class UDPSocketClientImpl : public UDPSocketClient {
- public:
-
- UDPSocketClientImpl() : run_loop_(nullptr), expected_receive_count_(0) {}
-
- ~UDPSocketClientImpl() override {
- while (!results_.empty()) {
- delete results_.front();
- results_.pop();
- }
- }
-
- void OnReceived(NetworkErrorPtr result,
- NetAddressPtr src_addr,
- Array<uint8_t> data) override {
- ReceiveResult* entry = new ReceiveResult();
- entry->result = result.Pass();
- entry->addr = src_addr.Pass();
- entry->data = data.Pass();
-
- results_.push(entry);
-
- if (results_.size() == expected_receive_count_ && run_loop_) {
- expected_receive_count_ = 0;
- run_loop_->Quit();
- }
- }
-
- base::RunLoop* run_loop_;
- std::queue<ReceiveResult*> results_;
- size_t expected_receive_count_;
-
- DISALLOW_COPY_AND_ASSIGN(UDPSocketClientImpl);
- };
-
- std::queue<ReceiveResult*>* GetReceiveResults() {
- return &udp_socket_client_.results_;
- }
-
- void WaitForReceiveResults(size_t count) {
- if (GetReceiveResults()->size() == count)
- return;
-
- udp_socket_client_.expected_receive_count_ = count;
- base::RunLoop run_loop;
- udp_socket_client_.run_loop_ = &run_loop;
- run_loop.Run();
- udp_socket_client_.run_loop_ = nullptr;
- }
-
NetworkServicePtr network_service_;
- UDPSocketPtr udp_socket_;
- UDPSocketClientImpl udp_socket_client_;
+ UDPSocketPtr socket_;
+ UDPSocketClientImpl receiver_;
DISALLOW_COPY_AND_ASSIGN(UDPSocketAppTest);
};
@@ -306,58 +306,58 @@
TEST_F(UDPSocketAppTest, Settings) {
TestCallback callback1;
- udp_socket_->AllowAddressReuse(callback1.callback());
+ socket_->AllowAddressReuse(callback1.callback());
callback1.WaitForResult();
EXPECT_EQ(net::OK, callback1.result()->code);
// Should fail because the socket hasn't been bound.
TestCallback callback2;
- udp_socket_->SetSendBufferSize(1024, callback2.callback());
+ socket_->SetSendBufferSize(1024, callback2.callback());
callback2.WaitForResult();
EXPECT_NE(net::OK, callback2.result()->code);
// Should fail because the socket hasn't been bound.
TestCallback callback3;
- udp_socket_->SetReceiveBufferSize(2048, callback3.callback());
+ socket_->SetReceiveBufferSize(2048, callback3.callback());
callback3.WaitForResult();
EXPECT_NE(net::OK, callback3.result()->code);
TestCallbackWithAddress callback4;
- udp_socket_->Bind(GetLocalHostWithAnyPort(), callback4.callback());
+ socket_->Bind(GetLocalHostWithAnyPort(), callback4.callback());
callback4.WaitForResult();
EXPECT_EQ(net::OK, callback4.result()->code);
EXPECT_NE(0u, callback4.net_address()->ipv4->port);
// Should fail because the socket has been bound.
TestCallback callback5;
- udp_socket_->AllowAddressReuse(callback5.callback());
+ socket_->AllowAddressReuse(callback5.callback());
callback5.WaitForResult();
EXPECT_NE(net::OK, callback5.result()->code);
TestCallback callback6;
- udp_socket_->SetSendBufferSize(1024, callback6.callback());
+ socket_->SetSendBufferSize(1024, callback6.callback());
callback6.WaitForResult();
EXPECT_EQ(net::OK, callback6.result()->code);
TestCallback callback7;
- udp_socket_->SetReceiveBufferSize(2048, callback7.callback());
+ socket_->SetReceiveBufferSize(2048, callback7.callback());
callback7.WaitForResult();
EXPECT_EQ(net::OK, callback7.result()->code);
TestCallbackWithUint32 callback8;
- udp_socket_->NegotiateMaxPendingSendRequests(0, callback8.callback());
+ socket_->NegotiateMaxPendingSendRequests(0, callback8.callback());
callback8.WaitForResult();
EXPECT_GT(callback8.result(), 0u);
TestCallbackWithUint32 callback9;
- udp_socket_->NegotiateMaxPendingSendRequests(16, callback9.callback());
+ socket_->NegotiateMaxPendingSendRequests(16, callback9.callback());
callback9.WaitForResult();
EXPECT_GT(callback9.result(), 0u);
}
TEST_F(UDPSocketAppTest, TestReadWrite) {
TestCallbackWithAddress callback1;
- udp_socket_->Bind(GetLocalHostWithAnyPort(), callback1.callback());
+ socket_->Bind(GetLocalHostWithAnyPort(), callback1.callback());
callback1.WaitForResult();
ASSERT_EQ(net::OK, callback1.result()->code);
ASSERT_NE(0u, callback1.net_address()->ipv4->port);
@@ -377,7 +377,7 @@
const size_t kDatagramCount = 6;
const size_t kDatagramSize = 255;
- udp_socket_->ReceiveMore(kDatagramCount);
+ socket_->ReceiveMore(kDatagramCount);
for (size_t i = 0; i < kDatagramCount; ++i) {
TestCallback callback;
@@ -389,10 +389,10 @@
EXPECT_EQ(255, callback.result()->code);
}
- WaitForReceiveResults(kDatagramCount);
+ receiver_.WaitForReceiveResults(kDatagramCount);
for (size_t i = 0; i < kDatagramCount; ++i) {
- scoped_ptr<ReceiveResult> result(GetReceiveResults()->front());
- GetReceiveResults()->pop();
+ scoped_ptr<ReceiveResult> result(receiver_.results()->front());
+ receiver_.results()->pop();
EXPECT_EQ(static_cast<int>(kDatagramSize), result->result->code);
EXPECT_TRUE(result->addr.Equals(client_addr));
@@ -401,11 +401,85 @@
}
}
-TEST_F(UDPSocketAppTest, TestUDPSocketWrapper) {
- UDPSocketWrapper udp_socket(udp_socket_.Pass(), 4, 4);
+TEST_F(UDPSocketAppTest, TestConnectedReadWrite) {
+ TestCallbackWithAddress callback1;
+ socket_->Bind(GetLocalHostWithAnyPort(), callback1.callback());
+ callback1.WaitForResult();
+ ASSERT_EQ(net::OK, callback1.result()->code);
+ ASSERT_NE(0u, callback1.net_address()->ipv4->port);
+
+ NetAddressPtr server_addr = callback1.net_address().Clone();
+
+ UDPSocketPtr client_socket;
+ network_service_->CreateUDPSocket(GetProxy(&client_socket));
+ UDPSocketClientImpl client_socket_receiver;
+ client_socket.set_client(&client_socket_receiver);
+
+ TestCallbackWithAddress callback2;
+ client_socket->Connect(server_addr.Clone(), callback2.callback());
+ callback2.WaitForResult();
+ ASSERT_EQ(net::OK, callback2.result()->code);
+ ASSERT_NE(0u, callback2.net_address()->ipv4->port);
+
+ NetAddressPtr client_addr = callback2.net_address().Clone();
+
+ const size_t kDatagramCount = 6;
+ const size_t kDatagramSize = 255;
+
+ // Test send using a connected socket.
+ socket_->ReceiveMore(kDatagramCount);
+
+ for (size_t i = 0; i < kDatagramCount; ++i) {
+ TestCallback callback;
+ client_socket->SendTo(
+ nullptr,
+ CreateTestMessage(static_cast<uint8_t>(i), kDatagramSize),
+ callback.callback());
+ callback.WaitForResult();
+ EXPECT_EQ(255, callback.result()->code);
+ }
+
+ receiver_.WaitForReceiveResults(kDatagramCount);
+ for (size_t i = 0; i < kDatagramCount; ++i) {
+ scoped_ptr<ReceiveResult> result(receiver_.results()->front());
+ receiver_.results()->pop();
+
+ EXPECT_EQ(static_cast<int>(kDatagramSize), result->result->code);
+ EXPECT_TRUE(result->addr.Equals(client_addr));
+ EXPECT_TRUE(result->data.Equals(
+ CreateTestMessage(static_cast<uint8_t>(i), kDatagramSize)));
+ }
+
+ // Test receive using a connected socket.
+ client_socket->ReceiveMore(kDatagramCount);
+
+ for (size_t i = 0; i < kDatagramCount; ++i) {
+ TestCallback callback;
+ socket_->SendTo(
+ client_addr.Clone(),
+ CreateTestMessage(static_cast<uint8_t>(i), kDatagramSize),
+ callback.callback());
+ callback.WaitForResult();
+ EXPECT_EQ(255, callback.result()->code);
+ }
+
+ client_socket_receiver.WaitForReceiveResults(kDatagramCount);
+ for (size_t i = 0; i < kDatagramCount; ++i) {
+ scoped_ptr<ReceiveResult> result(client_socket_receiver.results()->front());
+ client_socket_receiver.results()->pop();
+
+ EXPECT_EQ(static_cast<int>(kDatagramSize), result->result->code);
+ EXPECT_FALSE(result->addr);
+ EXPECT_TRUE(result->data.Equals(
+ CreateTestMessage(static_cast<uint8_t>(i), kDatagramSize)));
+ }
+}
+
+TEST_F(UDPSocketAppTest, TestWrapperReadWrite) {
+ UDPSocketWrapper socket(socket_.Pass(), 4, 4);
TestCallbackWithAddress callback1;
- udp_socket.Bind(GetLocalHostWithAnyPort(), callback1.callback());
+ socket.Bind(GetLocalHostWithAnyPort(), callback1.callback());
callback1.WaitForResult();
ASSERT_EQ(net::OK, callback1.result()->code);
ASSERT_NE(0u, callback1.net_address()->ipv4->port);
@@ -438,7 +512,7 @@
CreateTestMessage(static_cast<uint8_t>(j), kDatagramSize),
send_callbacks[j].callback());
- udp_socket.ReceiveFrom(receive_callbacks[j].callback());
+ socket.ReceiveFrom(receive_callbacks[j].callback());
}
receive_callbacks[i - 1].WaitForResult();
@@ -453,5 +527,84 @@
}
}
+TEST_F(UDPSocketAppTest, TestWrapperConnectedReadWrite) {
+ UDPSocketWrapper socket(socket_.Pass(), 4, 4);
+
+ TestCallbackWithAddress callback1;
+ socket.Bind(GetLocalHostWithAnyPort(), callback1.callback());
+ callback1.WaitForResult();
+ ASSERT_EQ(net::OK, callback1.result()->code);
+ ASSERT_NE(0u, callback1.net_address()->ipv4->port);
+
+ NetAddressPtr server_addr = callback1.net_address().Clone();
+
+ UDPSocketPtr raw_client_socket;
+ network_service_->CreateUDPSocket(GetProxy(&raw_client_socket));
+ UDPSocketWrapper client_socket(raw_client_socket.Pass(), 4, 4);
+
+ TestCallbackWithAddress callback2;
+ client_socket.Connect(server_addr.Pass(), callback2.callback());
+ callback2.WaitForResult();
+ ASSERT_EQ(net::OK, callback2.result()->code);
+ ASSERT_NE(0u, callback2.net_address()->ipv4->port);
+
+ NetAddressPtr client_addr = callback2.net_address().Clone();
+
+ const size_t kDatagramCount = 16;
+ const size_t kDatagramSize = 255;
+
+ // Test send using a connected socket.
+ for (size_t i = 1; i < kDatagramCount; ++i) {
+ scoped_ptr<TestCallback[]> send_callbacks(new TestCallback[i]);
+ scoped_ptr<TestReceiveCallback[]> receive_callbacks(
+ new TestReceiveCallback[i]);
+
+ for (size_t j = 0; j < i; ++j) {
+ client_socket.SendTo(
+ nullptr,
+ CreateTestMessage(static_cast<uint8_t>(j), kDatagramSize),
+ send_callbacks[j].callback());
+
+ socket.ReceiveFrom(receive_callbacks[j].callback());
+ }
+
+ receive_callbacks[i - 1].WaitForResult();
+
+ for (size_t j = 0; j < i; ++j) {
+ EXPECT_EQ(static_cast<int>(kDatagramSize),
+ receive_callbacks[j].result()->code);
+ EXPECT_TRUE(receive_callbacks[j].src_addr().Equals(client_addr));
+ EXPECT_TRUE(receive_callbacks[j].data().Equals(
+ CreateTestMessage(static_cast<uint8_t>(j), kDatagramSize)));
+ }
+ }
+
+ // Test receive using a connected socket.
+ for (size_t i = 1; i < kDatagramCount; ++i) {
+ scoped_ptr<TestCallback[]> send_callbacks(new TestCallback[i]);
+ scoped_ptr<TestReceiveCallback[]> receive_callbacks(
+ new TestReceiveCallback[i]);
+
+ for (size_t j = 0; j < i; ++j) {
+ socket.SendTo(
+ client_addr.Clone(),
+ CreateTestMessage(static_cast<uint8_t>(j), kDatagramSize),
+ send_callbacks[j].callback());
+
+ client_socket.ReceiveFrom(receive_callbacks[j].callback());
+ }
+
+ receive_callbacks[i - 1].WaitForResult();
+
+ for (size_t j = 0; j < i; ++j) {
+ EXPECT_EQ(static_cast<int>(kDatagramSize),
+ receive_callbacks[j].result()->code);
+ EXPECT_FALSE(receive_callbacks[j].src_addr());
+ EXPECT_TRUE(receive_callbacks[j].data().Equals(
+ CreateTestMessage(static_cast<uint8_t>(j), kDatagramSize)));
+ }
+ }
+}
+
} // namespace service
} // namespace mojo
diff --git a/mojo/services/network/udp_socket_impl.cc b/mojo/services/network/udp_socket_impl.cc
index b4438be..524136a 100644
--- a/mojo/services/network/udp_socket_impl.cc
+++ b/mojo/services/network/udp_socket_impl.cc
@@ -16,6 +16,8 @@
#include "mojo/services/network/net_address_type_converters.h"
#include "net/base/io_buffer.h"
#include "net/base/net_errors.h"
+#include "net/base/rand_callback.h"
+#include "net/udp/datagram_socket.h"
namespace mojo {
@@ -33,8 +35,10 @@
UDPSocketImpl::PendingSendRequest::~PendingSendRequest() {}
UDPSocketImpl::UDPSocketImpl()
- : socket_(nullptr, net::NetLog::Source()),
- bound_(false),
+ : socket_(net::DatagramSocket::DEFAULT_BIND, net::RandIntCallback(),
+ nullptr, net::NetLog::Source()),
+ state_(NOT_BOUND_OR_CONNECTED),
+ allow_address_reuse_(false),
remaining_recv_slots_(0),
max_pending_send_requests_(kDefaultMaxPendingSendRequests) {
}
@@ -45,60 +49,123 @@
void UDPSocketImpl::AllowAddressReuse(
const Callback<void(NetworkErrorPtr)>& callback) {
- if (bound_) {
+ if (IsBoundOrConnected()) {
callback.Run(MakeNetworkError(net::ERR_FAILED));
return;
}
- socket_.AllowAddressReuse();
+ allow_address_reuse_ = true;
callback.Run(MakeNetworkError(net::OK));
}
void UDPSocketImpl::Bind(
NetAddressPtr addr,
const Callback<void(NetworkErrorPtr, NetAddressPtr)>& callback) {
- if (bound_) {
- callback.Run(MakeNetworkError(net::ERR_FAILED), NetAddressPtr());
+ int net_result = net::OK;
+ bool opened = false;
+
+ do {
+ if (IsBoundOrConnected()) {
+ net_result = net::ERR_FAILED;
+ break;
+ }
+
+ net::IPEndPoint ip_end_point = addr.To<net::IPEndPoint>();
+ if (ip_end_point.GetFamily() == net::ADDRESS_FAMILY_UNSPECIFIED) {
+ net_result = net::ERR_ADDRESS_INVALID;
+ break;
+ }
+
+ net_result = socket_.Open(ip_end_point.GetFamily());
+ if (net_result != net::OK)
+ break;
+ opened = true;
+
+ if (allow_address_reuse_) {
+ net_result = socket_.AllowAddressReuse();
+ if (net_result != net::OK)
+ break;
+ }
+
+ net_result = socket_.Bind(ip_end_point);
+ if (net_result != net::OK)
+ break;
+
+ net::IPEndPoint bound_ip_end_point;
+ net_result = socket_.GetLocalAddress(&bound_ip_end_point);
+ if (net_result != net::OK)
+ break;
+
+ state_ = BOUND;
+ callback.Run(MakeNetworkError(net_result),
+ NetAddress::From(bound_ip_end_point));
+
+ if (remaining_recv_slots_ > 0) {
+ DCHECK(!recvfrom_buffer_.get());
+ DoRecvFrom();
+ }
return;
- }
+ } while (false);
- net::IPEndPoint ip_end_point = addr.To<net::IPEndPoint>();
- if (ip_end_point.GetFamily() == net::ADDRESS_FAMILY_UNSPECIFIED) {
- callback.Run(MakeNetworkError(net::ERR_ADDRESS_INVALID), NetAddressPtr());
- return;
- }
-
- int net_result = socket_.Listen(ip_end_point);
- if (net_result != net::OK) {
- callback.Run(MakeNetworkError(net_result), NetAddressPtr());
- return;
- }
-
- net::IPEndPoint bound_ip_end_point;
- NetAddressPtr bound_addr;
- net_result = socket_.GetLocalAddress(&bound_ip_end_point);
- if (net_result == net::OK)
- bound_addr = NetAddress::From(bound_ip_end_point);
-
- bound_ = true;
- callback.Run(MakeNetworkError(net::OK), bound_addr.Pass());
-
- if (remaining_recv_slots_ > 0) {
- DCHECK(!recvfrom_buffer_.get());
- DoRecvFrom();
- }
+ DCHECK(net_result != net::OK);
+ if (opened)
+ socket_.Close();
+ callback.Run(MakeNetworkError(net_result), nullptr);
}
void UDPSocketImpl::Connect(
NetAddressPtr remote_addr,
const Callback<void(NetworkErrorPtr, NetAddressPtr)>& callback) {
- // TODO(yzshen): Implement it.
+ int net_result = net::OK;
+ bool opened = false;
+
+ do {
+ if (IsBoundOrConnected()) {
+ net_result = net::ERR_FAILED;
+ break;
+ }
+
+ net::IPEndPoint ip_end_point = remote_addr.To<net::IPEndPoint>();
+ if (ip_end_point.GetFamily() == net::ADDRESS_FAMILY_UNSPECIFIED) {
+ net_result = net::ERR_ADDRESS_INVALID;
+ break;
+ }
+
+ net_result = socket_.Open(ip_end_point.GetFamily());
+ if (net_result != net::OK)
+ break;
+ opened = true;
+
+ net_result = socket_.Connect(ip_end_point);
+ if (net_result != net::OK)
+ break;
+
+ net::IPEndPoint local_ip_end_point;
+ net_result = socket_.GetLocalAddress(&local_ip_end_point);
+ if (net_result != net::OK)
+ break;
+
+ state_ = CONNECTED;
+ callback.Run(MakeNetworkError(net_result),
+ NetAddress::From(local_ip_end_point));
+
+ if (remaining_recv_slots_ > 0) {
+ DCHECK(!recvfrom_buffer_.get());
+ DoRecvFrom();
+ }
+ return;
+ } while (false);
+
+ DCHECK(net_result != net::OK);
+ if (opened)
+ socket_.Close();
+ callback.Run(MakeNetworkError(net_result), nullptr);
}
void UDPSocketImpl::SetSendBufferSize(
uint32_t size,
const Callback<void(NetworkErrorPtr)>& callback) {
- if (!bound_) {
+ if (!IsBoundOrConnected()) {
callback.Run(MakeNetworkError(net::ERR_FAILED));
return;
}
@@ -113,7 +180,7 @@
void UDPSocketImpl::SetReceiveBufferSize(
uint32_t size,
const Callback<void(NetworkErrorPtr)>& callback) {
- if (!bound_) {
+ if (!IsBoundOrConnected()) {
callback.Run(MakeNetworkError(net::ERR_FAILED));
return;
}
@@ -158,7 +225,7 @@
remaining_recv_slots_ += datagram_number;
- if (bound_ && !recvfrom_buffer_.get()) {
+ if (IsBoundOrConnected() && !recvfrom_buffer_.get()) {
DCHECK_EQ(datagram_number, remaining_recv_slots_);
DoRecvFrom();
}
@@ -167,10 +234,14 @@
void UDPSocketImpl::SendTo(NetAddressPtr dest_addr,
Array<uint8_t> data,
const Callback<void(NetworkErrorPtr)>& callback) {
- if (!bound_) {
+ if (!IsBoundOrConnected()) {
callback.Run(MakeNetworkError(net::ERR_FAILED));
return;
}
+ if (state_ == BOUND && !dest_addr) {
+ callback.Run(MakeNetworkError(net::ERR_INVALID_ARGUMENT));
+ return;
+ }
if (sendto_buffer_.get()) {
if (pending_send_requests_.size() >= max_pending_send_requests_) {
@@ -192,7 +263,7 @@
}
void UDPSocketImpl::DoRecvFrom() {
- DCHECK(bound_);
+ DCHECK(IsBoundOrConnected());
DCHECK(!recvfrom_buffer_.get());
DCHECK_GT(remaining_recv_slots_, 0u);
@@ -204,7 +275,7 @@
int net_result = socket_.RecvFrom(
recvfrom_buffer_.get(),
kMaxReadSize,
- &recvfrom_address_,
+ state_ == BOUND ? &recvfrom_address_ : nullptr,
base::Bind(&UDPSocketImpl::OnRecvFromCompleted, base::Unretained(this)));
if (net_result != net::ERR_IO_PENDING)
OnRecvFromCompleted(net_result);
@@ -213,15 +284,9 @@
void UDPSocketImpl::DoSendTo(NetAddressPtr addr,
Array<uint8_t> data,
const Callback<void(NetworkErrorPtr)>& callback) {
- DCHECK(bound_);
+ DCHECK(IsBoundOrConnected());
DCHECK(!sendto_buffer_.get());
- net::IPEndPoint ip_end_point = addr.To<net::IPEndPoint>();
- if (ip_end_point.GetFamily() == net::ADDRESS_FAMILY_UNSPECIFIED) {
- callback.Run(MakeNetworkError(net::ERR_ADDRESS_INVALID));
- return;
- }
-
if (data.size() > kMaxWriteSize) {
callback.Run(MakeNetworkError(net::ERR_INVALID_ARGUMENT));
return;
@@ -230,13 +295,27 @@
if (data.size() > 0)
memcpy(sendto_buffer_->data(), &data.storage()[0], data.size());
- // It is safe to use base::Unretained(this) because |socket_| is owned by this
- // object. If this object gets destroyed (and so does |socket_|), the callback
- // won't be called.
- int net_result = socket_.SendTo(sendto_buffer_.get(), sendto_buffer_->size(),
- ip_end_point,
- base::Bind(&UDPSocketImpl::OnSendToCompleted,
- base::Unretained(this), callback));
+ int net_result = net::OK;
+ if (addr) {
+ net::IPEndPoint ip_end_point = addr.To<net::IPEndPoint>();
+ if (ip_end_point.GetFamily() == net::ADDRESS_FAMILY_UNSPECIFIED) {
+ callback.Run(MakeNetworkError(net::ERR_ADDRESS_INVALID));
+ return;
+ }
+
+ // It is safe to use base::Unretained(this) because |socket_| is owned by
+ // this object. If this object gets destroyed (and so does |socket_|), the
+ // callback won't be called.
+ net_result = socket_.SendTo(sendto_buffer_.get(), sendto_buffer_->size(),
+ ip_end_point,
+ base::Bind(&UDPSocketImpl::OnSendToCompleted,
+ base::Unretained(this), callback));
+ } else {
+ DCHECK(state_ == CONNECTED);
+ net_result = socket_.Write(sendto_buffer_.get(), sendto_buffer_->size(),
+ base::Bind(&UDPSocketImpl::OnSendToCompleted,
+ base::Unretained(this), callback));
+ }
if (net_result != net::ERR_IO_PENDING)
OnSendToCompleted(callback, net_result);
}
@@ -247,7 +326,9 @@
NetAddressPtr net_address;
Array<uint8_t> array;
if (net_result >= 0) {
- net_address = NetAddress::From(recvfrom_address_);
+ if (state_ == BOUND)
+ net_address = NetAddress::From(recvfrom_address_);
+
std::vector<uint8_t> data(net_result);
if (net_result > 0)
memcpy(&data[0], recvfrom_buffer_->data(), net_result);
diff --git a/mojo/services/network/udp_socket_impl.h b/mojo/services/network/udp_socket_impl.h
index 8028d1c..f5d3f82 100644
--- a/mojo/services/network/udp_socket_impl.h
+++ b/mojo/services/network/udp_socket_impl.h
@@ -12,7 +12,7 @@
#include "mojo/public/cpp/bindings/interface_impl.h"
#include "mojo/services/network/public/interfaces/udp_socket.mojom.h"
#include "net/base/ip_endpoint.h"
-#include "net/udp/udp_server_socket.h"
+#include "net/udp/udp_socket.h"
namespace net {
class IOBuffer;
@@ -57,6 +57,12 @@
const Callback<void(NetworkErrorPtr)>& callback) override;
private:
+ enum State {
+ NOT_BOUND_OR_CONNECTED,
+ BOUND,
+ CONNECTED
+ };
+
struct PendingSendRequest {
PendingSendRequest();
~PendingSendRequest();
@@ -75,13 +81,19 @@
void OnSendToCompleted(const Callback<void(NetworkErrorPtr)>& callback,
int net_result);
- net::UDPServerSocket socket_;
+ bool IsBoundOrConnected() const {
+ return state_ == BOUND || state_ == CONNECTED;
+ }
- bool bound_;
+ net::UDPSocket socket_;
- // Non-NULL when there is a pending RecvFrom operation on |socket_|.
+ State state_;
+
+ bool allow_address_reuse_;
+
+ // Non-null when there is a pending RecvFrom operation on |socket_|.
scoped_refptr<net::IOBuffer> recvfrom_buffer_;
- // Non-NULL when there is a pending SendTo operation on |socket_|.
+ // Non-null when there is a pending SendTo operation on |socket_|.
scoped_refptr<net::IOBufferWithSize> sendto_buffer_;
net::IPEndPoint recvfrom_address_;
diff --git a/net/http/transport_security_state_static.h b/net/http/transport_security_state_static.h
index 65ffd2c..0d71685 100644
--- a/net/http/transport_security_state_static.h
+++ b/net/http/transport_security_state_static.h
@@ -725,1199 +725,1200 @@
0xfc, 0x59, 0x76, 0x4b, 0x74, 0xca, 0x3a, 0x2d, 0x3e, 0x2d, 0x8b, 0x4f,
0x6b, 0xdc, 0xf0, 0x68, 0x85, 0xe4, 0xba, 0x4c, 0xc3, 0x66, 0x37, 0x85,
0x5f, 0xa4, 0x73, 0xbf, 0x80, 0x74, 0xb6, 0x74, 0x79, 0x35, 0x5e, 0x8d,
- 0x4f, 0x6b, 0x69, 0xa3, 0xa7, 0xff, 0x23, 0x8f, 0xab, 0x5f, 0xd1, 0x59,
- 0x82, 0x74, 0xd8, 0xec, 0x74, 0x52, 0x21, 0x36, 0x43, 0x89, 0x73, 0xbf,
- 0x80, 0x74, 0x3b, 0xe7, 0x91, 0xe4, 0xba, 0x7d, 0xbc, 0xd6, 0x3c, 0xe9,
- 0xfc, 0xfb, 0xb5, 0xfa, 0xd7, 0xeb, 0x7d, 0x6c, 0xe9, 0xe4, 0xba, 0x76,
- 0x74, 0xee, 0x38, 0xe0, 0xa9, 0xf6, 0x0e, 0xb7, 0x45, 0x2c, 0xbf, 0x9f,
- 0x66, 0x9c, 0xad, 0x1d, 0x1c, 0xa2, 0x6f, 0xb4, 0x01, 0x34, 0x9e, 0xde,
- 0x66, 0x1d, 0x3f, 0xf7, 0x68, 0xe7, 0x4d, 0xb2, 0x7f, 0xde, 0xb9, 0xd3,
- 0xfe, 0x4f, 0x2c, 0x2d, 0x76, 0x45, 0x1d, 0x3f, 0x53, 0xaf, 0x5f, 0x57,
- 0x3a, 0x7a, 0xb9, 0xab, 0x0e, 0x8a, 0x54, 0x65, 0x69, 0x32, 0x43, 0x8f,
- 0xae, 0x62, 0xe0, 0xfe, 0xd3, 0x04, 0xf3, 0x45, 0xf3, 0xf5, 0x70, 0xd5,
- 0xca, 0x1d, 0x39, 0xbd, 0xec, 0xe9, 0xff, 0xff, 0xc2, 0x36, 0xb7, 0x91,
- 0xae, 0x76, 0x8e, 0x74, 0xbd, 0x5a, 0xff, 0xd7, 0x07, 0x4f, 0x93, 0x5e,
- 0xb5, 0x87, 0x4f, 0xff, 0xea, 0xb5, 0xf7, 0x55, 0x0f, 0x47, 0x64, 0xdd,
- 0x89, 0x5f, 0x3a, 0x7f, 0xff, 0xdc, 0x74, 0x1a, 0x0d, 0xa0, 0xd7, 0xb6,
- 0xeb, 0xa6, 0x71, 0x5e, 0x4e, 0x9f, 0xd6, 0xbe, 0xfe, 0x7d, 0x6b, 0x4e,
- 0x9f, 0xd9, 0xc7, 0xae, 0x36, 0xb0, 0xe8, 0x64, 0x6f, 0x23, 0x90, 0x9c,
- 0x4f, 0x77, 0xa4, 0xb0, 0xe9, 0xff, 0x36, 0x58, 0xca, 0x16, 0xb7, 0xb3,
- 0xa1, 0x95, 0x3b, 0x53, 0xea, 0x14, 0x7e, 0x34, 0x3c, 0x2d, 0x12, 0x39,
- 0xbd, 0x79, 0xd3, 0xe6, 0xee, 0xf6, 0x68, 0xe9, 0xd9, 0xab, 0x9d, 0x37,
- 0xb6, 0x1d, 0x38, 0x74, 0xe3, 0xcd, 0x9f, 0xc6, 0xe7, 0xef, 0x43, 0xa7,
- 0x36, 0xf0, 0x74, 0x31, 0xf3, 0x21, 0x9c, 0xff, 0xfb, 0xd6, 0xd7, 0x41,
- 0xf5, 0xdb, 0xa5, 0x6b, 0xaa, 0xb4, 0x74, 0xff, 0xdb, 0x6f, 0x3d, 0x34,
- 0x39, 0xa6, 0xd1, 0xd3, 0xfb, 0xa5, 0xaf, 0x4d, 0xfa, 0xa3, 0xa3, 0xb3,
- 0xfd, 0x14, 0x69, 0xff, 0x7d, 0xce, 0x97, 0x64, 0xb3, 0x34, 0x74, 0x31,
- 0xf1, 0xfa, 0x45, 0x3f, 0xff, 0xfd, 0xe8, 0xdf, 0xe2, 0xce, 0x74, 0xf1,
- 0xa4, 0x7d, 0x5b, 0xaa, 0x74, 0x35, 0x73, 0xa4, 0xc7, 0x4f, 0xe7, 0xe7,
- 0xd2, 0xed, 0x69, 0xd3, 0xff, 0xff, 0xf9, 0x3b, 0xb8, 0xd6, 0x5b, 0xd3,
- 0x9d, 0xfb, 0xd0, 0x6a, 0xd7, 0xd7, 0xb6, 0x0d, 0x65, 0xa7, 0x4e, 0xcc,
- 0x03, 0x45, 0x31, 0x14, 0x8b, 0xc0, 0x84, 0xb4, 0xff, 0xa8, 0x6d, 0x7d,
- 0xf4, 0xdf, 0x70, 0xe9, 0xd4, 0x9d, 0x9d, 0x2a, 0x3a, 0x75, 0xa3, 0x5d,
- 0x9a, 0xa7, 0x43, 0x70, 0x88, 0x9e, 0xc6, 0x99, 0xcf, 0x6b, 0x4e, 0x9f,
- 0xca, 0xe7, 0x6d, 0x65, 0x70, 0x74, 0x5a, 0x7a, 0x38, 0x39, 0x3f, 0xff,
- 0x86, 0x83, 0x5a, 0x6d, 0x5d, 0xc1, 0xae, 0x3a, 0x33, 0xba, 0x3a, 0x7f,
- 0xc0, 0xca, 0xdd, 0x5e, 0x90, 0x4e, 0x86, 0x45, 0x0e, 0xd9, 0xe7, 0xdf,
- 0x67, 0x4d, 0xf3, 0xa7, 0xec, 0x1e, 0x9c, 0xb0, 0x9d, 0x14, 0x7e, 0xe8,
- 0x45, 0xe9, 0x44, 0x58, 0xbc, 0xf2, 0xf1, 0x7e, 0x61, 0x85, 0xe4, 0x80,
- 0x23, 0x40, 0xb4, 0x89, 0x21, 0x06, 0xe0, 0x7f, 0xe1, 0xdc, 0xa8, 0x62,
- 0x0b, 0x96, 0xa3, 0x3a, 0x9f, 0xf7, 0x9f, 0xe7, 0x1d, 0x33, 0x9c, 0xb0,
- 0xe9, 0xea, 0x1f, 0x3d, 0x73, 0xa7, 0xff, 0xff, 0xdb, 0x4d, 0x6e, 0xbe,
- 0xce, 0xba, 0x2b, 0xd7, 0x6e, 0x95, 0x6b, 0xeb, 0xd1, 0xee, 0xe7, 0x4b,
- 0x48, 0x8b, 0x5b, 0x93, 0x4f, 0xff, 0xaa, 0xb6, 0x81, 0xba, 0xe9, 0x7f,
- 0x76, 0xdd, 0x73, 0xa7, 0xff, 0xb5, 0xba, 0xef, 0xa2, 0x9a, 0xb5, 0xcd,
- 0x09, 0xd3, 0xfd, 0x6f, 0x45, 0x35, 0x0e, 0xba, 0x8e, 0x95, 0xe9, 0x11,
- 0xd8, 0xa3, 0x24, 0x14, 0xc3, 0xb5, 0x0e, 0x79, 0xf3, 0xda, 0xd7, 0xdc,
- 0xe9, 0xff, 0xff, 0xff, 0x50, 0xf9, 0xe8, 0x9b, 0xf5, 0x6e, 0x26, 0x99,
- 0x43, 0x9e, 0x76, 0x8b, 0xad, 0xdb, 0xdb, 0x72, 0x54, 0xff, 0xff, 0xc0,
- 0x9c, 0x73, 0xef, 0xfa, 0x7a, 0xd6, 0x5c, 0x37, 0xee, 0xed, 0xce, 0x0e,
- 0x9b, 0xdb, 0x2d, 0x4d, 0x11, 0x0a, 0x2f, 0x0a, 0x18, 0x65, 0x5d, 0x7b,
- 0x8c, 0xd8, 0x63, 0x71, 0x9f, 0xfc, 0xa0, 0xe9, 0xbc, 0x7d, 0x2b, 0x07,
- 0xb3, 0xa7, 0xff, 0xc8, 0x3a, 0xdd, 0x3b, 0x69, 0xca, 0xeb, 0xe0, 0xf6,
- 0x74, 0xff, 0xcc, 0x36, 0x0d, 0x3a, 0xbf, 0xad, 0x69, 0xd1, 0x74, 0x50,
- 0xfa, 0xb7, 0x3d, 0x5a, 0xa7, 0x70, 0xe9, 0xdd, 0x55, 0xb3, 0xa6, 0xae,
- 0x4e, 0x8b, 0x13, 0x68, 0x7c, 0x3a, 0xee, 0x49, 0xa2, 0x57, 0x43, 0xd3,
- 0xe4, 0xd5, 0xeb, 0xb3, 0xa7, 0xee, 0x58, 0x77, 0x8f, 0x3a, 0x73, 0x72,
- 0xc7, 0x4f, 0xcf, 0xad, 0x5f, 0x1c, 0xe8, 0x78, 0xea, 0x2c, 0x87, 0xa2,
- 0xd5, 0xc6, 0xe9, 0xf9, 0xdb, 0x79, 0xd7, 0x6e, 0xce, 0x9f, 0xdf, 0x70,
- 0x6b, 0x79, 0xa3, 0xa2, 0x8f, 0x99, 0x0d, 0x27, 0xe6, 0xee, 0xb5, 0xe2,
- 0xc3, 0xa1, 0xe7, 0xa0, 0x24, 0x13, 0xfd, 0xad, 0xd3, 0xf0, 0x6a, 0xd3,
- 0xa7, 0xff, 0xf8, 0x73, 0xbb, 0xd9, 0x48, 0x3a, 0x1a, 0x75, 0xd2, 0xfc,
- 0x09, 0xd0, 0x28, 0xa0, 0xd1, 0xbc, 0xff, 0x92, 0x9c, 0xe9, 0x76, 0xde,
- 0x75, 0xce, 0x9f, 0xd9, 0x6d, 0xf7, 0x59, 0xf3, 0xa3, 0x93, 0xf5, 0xd2,
- 0x1c, 0xff, 0x57, 0xec, 0x64, 0xfd, 0x09, 0xd2, 0x51, 0xdd, 0x0d, 0xb4,
- 0xe1, 0xae, 0x4e, 0x86, 0x37, 0xb6, 0x91, 0x4f, 0xd6, 0xde, 0xa8, 0x7c,
- 0x9d, 0x3c, 0xaf, 0x0d, 0xd9, 0xd1, 0x47, 0xa4, 0x85, 0xd3, 0xbd, 0xb7,
- 0xb3, 0xa1, 0x93, 0xdf, 0xa8, 0x4b, 0xa4, 0x25, 0xbe, 0xe6, 0x24, 0x13,
- 0xfb, 0x49, 0x65, 0x6f, 0xdd, 0x1d, 0x27, 0x0e, 0x9f, 0xab, 0xda, 0xd8,
- 0x58, 0x74, 0xd5, 0x6b, 0x1b, 0xeb, 0x88, 0xcf, 0xdb, 0xc7, 0xab, 0xe8,
- 0x74, 0xf9, 0x3b, 0xfd, 0x5a, 0x74, 0x79, 0x47, 0x92, 0x39, 0x76, 0x59,
- 0xe9, 0x64, 0xff, 0xfd, 0xf7, 0xee, 0x9c, 0xdb, 0x0f, 0x91, 0xad, 0x6f,
- 0xd3, 0xa7, 0xff, 0xf2, 0x55, 0xaf, 0xbe, 0xb6, 0xca, 0x64, 0xe7, 0xa3,
- 0x3b, 0xa3, 0xa7, 0xff, 0xff, 0xde, 0x8f, 0x4e, 0x32, 0xd7, 0xff, 0x3b,
- 0xe9, 0x7f, 0x5a, 0xdd, 0xd2, 0x0d, 0x79, 0x3a, 0x7f, 0xfd, 0xef, 0xff,
- 0x5a, 0xbe, 0xd2, 0xba, 0x6f, 0xb6, 0x3a, 0x29, 0x1c, 0x9b, 0x84, 0x64,
- 0xff, 0xf3, 0xdd, 0xb7, 0x4c, 0x2e, 0x0d, 0x6a, 0xf8, 0x74, 0xff, 0xfb,
- 0x9a, 0x57, 0x47, 0x6d, 0x35, 0xdc, 0x7e, 0x7e, 0xc3, 0xa7, 0xfa, 0x86,
- 0xce, 0x9d, 0xe6, 0x38, 0x74, 0xff, 0x7e, 0xc6, 0xb2, 0xcf, 0x7f, 0x61,
- 0xd3, 0xfd, 0xe8, 0xf4, 0xbf, 0xbd, 0x5e, 0xfc, 0xe8, 0x63, 0xff, 0xb9,
- 0xf4, 0xff, 0xeb, 0x3a, 0x5f, 0x7e, 0xf4, 0xd5, 0xee, 0xdf, 0x3a, 0x7f,
- 0xff, 0xd5, 0x6d, 0xd2, 0xb8, 0xe9, 0xba, 0xd5, 0xea, 0xce, 0x94, 0x9c,
- 0x9d, 0x14, 0x8c, 0x24, 0x51, 0x8b, 0x15, 0xef, 0x04, 0x69, 0x96, 0x93,
- 0xa2, 0x82, 0x97, 0x6f, 0x0b, 0xad, 0x43, 0x8e, 0x7f, 0xd9, 0xfd, 0xd6,
- 0x98, 0x53, 0xb3, 0xa7, 0xfa, 0xb8, 0xb5, 0xf7, 0xe9, 0xa4, 0x3a, 0x7f,
- 0xff, 0xcc, 0x0c, 0xae, 0x8e, 0x6d, 0x07, 0x9e, 0x9e, 0x00, 0x6b, 0x74,
- 0x74, 0x02, 0x39, 0xc4, 0xf1, 0xd8, 0xf2, 0x79, 0x34, 0x8c, 0x74, 0xff,
- 0xff, 0xe1, 0x4f, 0x3b, 0xc7, 0x3a, 0x0f, 0xae, 0xdd, 0x2a, 0xd7, 0xd7,
- 0xa3, 0xdd, 0xce, 0x9f, 0x6d, 0x18, 0x6c, 0x3a, 0x6d, 0x32, 0x91, 0x52,
- 0xea, 0x10, 0x70, 0xf4, 0x7e, 0xa4, 0x32, 0x21, 0x97, 0xbb, 0x6a, 0x70,
- 0xed, 0x23, 0x5d, 0xc8, 0xcb, 0xa7, 0xb5, 0x7c, 0xec, 0xe9, 0xff, 0xb6,
- 0x9d, 0x13, 0xfe, 0xd9, 0x9f, 0x03, 0xa7, 0x93, 0x79, 0x61, 0xd3, 0xce,
- 0x9b, 0x4c, 0x74, 0xfd, 0xbc, 0xb3, 0xa3, 0xf4, 0x74, 0xfb, 0x3e, 0x36,
- 0xa1, 0xd0, 0x87, 0xad, 0xa3, 0x08, 0xa4, 0xc8, 0xbc, 0x91, 0x02, 0x32,
- 0x10, 0xe9, 0xe2, 0x7b, 0xc7, 0xb9, 0x73, 0xa7, 0xff, 0xe4, 0xff, 0x4a,
- 0x4a, 0x1f, 0x3b, 0x4a, 0x55, 0x01, 0xd3, 0xff, 0xfc, 0x96, 0x7d, 0x95,
- 0x7f, 0x5b, 0xa3, 0x7d, 0xb9, 0xdb, 0x28, 0xe8, 0xa4, 0x61, 0x7d, 0x66,
- 0x7f, 0xff, 0xf7, 0xfe, 0x96, 0x74, 0xdd, 0x68, 0x59, 0xcd, 0xd5, 0x8d,
- 0x6e, 0xbd, 0x03, 0xa7, 0xff, 0xfe, 0x6f, 0x3b, 0x6e, 0x83, 0x5e, 0xf9,
- 0xe9, 0x6b, 0xee, 0x83, 0xe1, 0xac, 0x3a, 0x7d, 0x6d, 0xd2, 0x84, 0xe8,
- 0xa4, 0x51, 0x7a, 0xf9, 0x08, 0x9a, 0x0e, 0xe3, 0x1e, 0x9f, 0xf9, 0xf7,
- 0x4f, 0x3b, 0x64, 0xb1, 0xbc, 0x9d, 0x3f, 0xc3, 0xeb, 0x83, 0x5b, 0xcd,
- 0x1d, 0x3f, 0xdc, 0xed, 0xb8, 0xe7, 0x78, 0xa3, 0xa7, 0xff, 0xfb, 0x3f,
- 0xba, 0xd2, 0x50, 0xd9, 0x76, 0xa1, 0xe7, 0x6c, 0x74, 0xf6, 0xba, 0x59,
- 0xf3, 0xa2, 0xd4, 0x44, 0x63, 0x1c, 0xff, 0xee, 0x30, 0x6c, 0x57, 0xa9,
- 0xca, 0x0a, 0x1d, 0x3f, 0x39, 0x6b, 0xfd, 0x6d, 0x1d, 0x3f, 0xdb, 0xc5,
- 0x0d, 0x6f, 0x34, 0x74, 0xf5, 0x7f, 0xbe, 0x0e, 0x86, 0x44, 0x4d, 0xcc,
- 0x34, 0x6d, 0x3f, 0x56, 0xbf, 0xfa, 0x79, 0xd3, 0xf0, 0xd6, 0xc6, 0x80,
- 0xe9, 0xe1, 0xab, 0xf4, 0x70, 0xf5, 0x74, 0x59, 0x1c, 0xae, 0x41, 0x84,
- 0x6c, 0x76, 0x94, 0xa2, 0x3f, 0xce, 0x37, 0x0c, 0x3b, 0x91, 0xea, 0x1a,
- 0x6e, 0xa1, 0x09, 0x3f, 0xf0, 0x8d, 0x74, 0xfd, 0x6c, 0x69, 0xc3, 0xa1,
- 0x97, 0x91, 0x2a, 0x75, 0xa7, 0x21, 0x31, 0x3e, 0x16, 0x56, 0x72, 0x74,
- 0xfe, 0xa7, 0x37, 0x5a, 0x6e, 0x4e, 0x9f, 0xff, 0xfe, 0xdd, 0x6a, 0xf8,
- 0xe7, 0x41, 0xab, 0x5f, 0x5e, 0xd8, 0x35, 0xce, 0xd1, 0xc3, 0xa6, 0xf7,
- 0xc9, 0xd1, 0xf4, 0x4d, 0xea, 0x10, 0x53, 0xf5, 0x58, 0x35, 0x6d, 0xce,
- 0x9f, 0xfd, 0xfb, 0x5f, 0x7a, 0x55, 0xad, 0xbd, 0xb1, 0xd2, 0xb9, 0xd1,
- 0xe9, 0xed, 0xf8, 0x4b, 0x9f, 0xcc, 0xa1, 0xad, 0xe6, 0x8e, 0x9e, 0xe8,
- 0x16, 0x70, 0x74, 0xff, 0xff, 0xb4, 0x2d, 0xdd, 0xaf, 0xbf, 0xad, 0xa1,
- 0xae, 0x52, 0xbe, 0xe1, 0xd0, 0x8a, 0xa3, 0x1c, 0x26, 0xc8, 0x67, 0x09,
- 0x45, 0xe1, 0x11, 0xe9, 0x2b, 0xa3, 0x0f, 0x04, 0xb3, 0xe7, 0xa7, 0xea,
- 0xd3, 0xa7, 0xd5, 0x7b, 0x2b, 0x83, 0xa2, 0xd3, 0xcf, 0xd9, 0x3c, 0xff,
- 0xf9, 0x2c, 0xa0, 0xe7, 0x69, 0x5e, 0x7a, 0x79, 0xf5, 0x8e, 0x9e, 0x76,
- 0xd5, 0x6c, 0xe9, 0xff, 0xff, 0x9d, 0xad, 0x7e, 0x5b, 0xd0, 0x7d, 0x76,
- 0xe9, 0x56, 0xbe, 0xbd, 0x1e, 0xee, 0x74, 0x58, 0x8a, 0x5a, 0x24, 0x9f,
- 0xff, 0xff, 0x35, 0xb7, 0xf5, 0xad, 0xe9, 0xba, 0xe7, 0xa0, 0xd7, 0xbe,
- 0x7a, 0x5f, 0xbe, 0xd3, 0x47, 0x4f, 0x98, 0x6d, 0xcb, 0x0e, 0x9f, 0xff,
- 0xff, 0xfd, 0x4a, 0xa0, 0x6d, 0xb2, 0xb5, 0x57, 0xbb, 0x7f, 0xec, 0x35,
- 0x65, 0x7b, 0x7f, 0x5c, 0x16, 0x51, 0xd3, 0xfd, 0xdd, 0x72, 0x35, 0xbc,
- 0xd1, 0xd3, 0xfa, 0xcf, 0x5b, 0x4a, 0x4d, 0x1d, 0x3f, 0xe6, 0xf2, 0xed,
- 0xed, 0x0b, 0x9e, 0x14, 0x74, 0x51, 0xfd, 0x5a, 0x69, 0x3f, 0xfd, 0x5a,
- 0xe6, 0xab, 0xbb, 0xf4, 0xfd, 0xf9, 0xb9, 0xd3, 0xd6, 0x20, 0xe8, 0xe8,
- 0x65, 0x7d, 0x54, 0x46, 0x91, 0x80, 0x7c, 0x8d, 0x50, 0x91, 0xd9, 0x3e,
- 0x42, 0x8c, 0x61, 0x65, 0x72, 0x2f, 0x55, 0x27, 0x73, 0xd1, 0xc3, 0xa7,
- 0xff, 0xad, 0x78, 0xb7, 0x45, 0x0b, 0x79, 0xd2, 0x58, 0x74, 0x51, 0xf9,
- 0xa1, 0x04, 0xfd, 0x63, 0x8f, 0xeb, 0x3f, 0x61, 0xd3, 0xe5, 0x27, 0x35,
- 0xc9, 0xd2, 0x70, 0xe9, 0x99, 0x47, 0x4b, 0x47, 0x47, 0xcd, 0x2e, 0x0a,
- 0xc7, 0x27, 0xad, 0xb3, 0x69, 0xed, 0x5f, 0x2d, 0x3a, 0x67, 0x30, 0xe9,
- 0xfd, 0xb4, 0xfd, 0xaf, 0x16, 0x3a, 0x3a, 0xda, 0x68, 0x2c, 0x6d, 0x4f,
- 0xc8, 0x46, 0xa2, 0x2f, 0x45, 0xa7, 0xf5, 0xd2, 0xde, 0x30, 0x7b, 0x3a,
- 0x7f, 0xfc, 0xdf, 0x60, 0xa5, 0x30, 0x3d, 0x2f, 0xea, 0x8e, 0x87, 0x11,
- 0x0d, 0xd4, 0x69, 0x3f, 0x7e, 0x9b, 0xcb, 0x09, 0xd3, 0x87, 0x14, 0x74,
- 0xdd, 0xb1, 0xd0, 0xf3, 0xdc, 0x42, 0xc1, 0x1a, 0x87, 0x79, 0xda, 0x11,
- 0xf5, 0x90, 0xf0, 0x69, 0x4b, 0x76, 0x3d, 0xbc, 0xb3, 0x99, 0x52, 0x75,
- 0x3d, 0xa7, 0xe6, 0x19, 0x61, 0x2f, 0x92, 0xd8, 0xe9, 0x12, 0x30, 0x87,
- 0x21, 0xb5, 0xf9, 0x54, 0x0a, 0x8d, 0x0f, 0x73, 0xe5, 0xb9, 0x1b, 0x90,
- 0xcf, 0x47, 0x5e, 0x56, 0x4e, 0xa7, 0x2e, 0x5d, 0x46, 0x23, 0xd5, 0x1b,
- 0x0f, 0x88, 0x71, 0x3b, 0x42, 0x0e, 0x7f, 0xfe, 0xf4, 0x17, 0x6e, 0xbe,
- 0xd5, 0x6f, 0x59, 0xce, 0x67, 0x93, 0xa1, 0x6a, 0x8c, 0x92, 0x3c, 0xe9,
- 0xfc, 0xba, 0xf8, 0x66, 0x01, 0xa2, 0x9d, 0x9f, 0x7c, 0x33, 0x00, 0xd1,
- 0x51, 0xcf, 0xfb, 0x1e, 0xba, 0xf8, 0x66, 0x01, 0xa2, 0x68, 0x92, 0xe8,
- 0xfe, 0x14, 0x63, 0x3f, 0x97, 0x5f, 0x0c, 0xc0, 0x34, 0x55, 0xf3, 0xef,
- 0x86, 0x60, 0x1a, 0x2b, 0x69, 0xfe, 0x7a, 0xeb, 0xe1, 0x98, 0x06, 0x89,
- 0x06, 0x4b, 0xa3, 0xf3, 0xc3, 0x19, 0xff, 0x97, 0x8f, 0x5d, 0x7c, 0x33,
- 0x00, 0xd1, 0x21, 0xcf, 0xf9, 0xfb, 0x6d, 0x5d, 0xdd, 0x5d, 0xde, 0x13,
- 0xa7, 0xd5, 0x43, 0xdd, 0xce, 0x9f, 0x7c, 0x33, 0x00, 0xd1, 0x62, 0x4f,
- 0xab, 0xec, 0x3e, 0x4e, 0x9f, 0x78, 0xea, 0xaf, 0xb1, 0xd3, 0xae, 0xc2,
- 0x74, 0xb6, 0xc7, 0x8a, 0x85, 0x73, 0xff, 0x35, 0x5e, 0x87, 0x94, 0xed,
- 0x84, 0xe9, 0xc2, 0xd6, 0x1d, 0x27, 0x89, 0xee, 0x7a, 0x83, 0x3b, 0xa9,
- 0x3b, 0x3a, 0x7c, 0x8e, 0xbd, 0xcb, 0x9d, 0x3f, 0xf3, 0xaf, 0x6a, 0xde,
- 0x5d, 0x6e, 0xb1, 0xc3, 0xa6, 0x67, 0x9d, 0x14, 0x7c, 0x1f, 0x4b, 0x9f,
- 0xd5, 0xf7, 0xf7, 0x54, 0xe1, 0xd3, 0xec, 0x7f, 0x8d, 0xb1, 0xd3, 0xf5,
- 0xef, 0xf4, 0xe3, 0xae, 0x74, 0x32, 0x23, 0x50, 0xcf, 0x0a, 0x27, 0xff,
- 0x9e, 0xca, 0x67, 0xf2, 0x2d, 0xbc, 0xaf, 0x9d, 0x3f, 0x80, 0x69, 0xd0,
- 0xd5, 0xce, 0x8b, 0x4f, 0xfb, 0x69, 0xb3, 0xfb, 0xb6, 0xad, 0x20, 0xf0,
- 0x54, 0xfa, 0xb7, 0x6e, 0x75, 0xce, 0x9e, 0xee, 0xec, 0x27, 0x4f, 0xef,
- 0xef, 0x12, 0xe8, 0xe8, 0xe8, 0x63, 0xd4, 0xa2, 0x18, 0x14, 0x4f, 0xdd,
- 0xfe, 0x7e, 0xcb, 0x34, 0xd6, 0xbc, 0xe9, 0xff, 0x0b, 0x27, 0x3a, 0x1c,
- 0xb6, 0xe7, 0x43, 0xbc, 0xba, 0x71, 0xca, 0x4d, 0x13, 0x79, 0x31, 0x06,
- 0xcb, 0x61, 0x04, 0x85, 0x0e, 0x0f, 0xfe, 0x11, 0x3b, 0x85, 0x76, 0x42,
- 0xaf, 0xb2, 0x3b, 0xc3, 0x47, 0x44, 0x5e, 0x0b, 0xa7, 0xfe, 0xda, 0x36,
- 0xb7, 0x9e, 0x68, 0x7b, 0x3a, 0x7f, 0xfa, 0xad, 0x7e, 0xbd, 0xb1, 0x7b,
- 0xc5, 0x25, 0xce, 0x9b, 0x6b, 0xa4, 0x4b, 0x0a, 0x24, 0x2d, 0x3b, 0x46,
- 0x8e, 0x1e, 0x7f, 0x2e, 0xbe, 0x19, 0x80, 0x68, 0xb3, 0x66, 0xae, 0x4e,
- 0x9f, 0xf6, 0x3d, 0x75, 0xf0, 0xcc, 0x03, 0x45, 0x01, 0x25, 0xd1, 0xee,
- 0xa8, 0x5a, 0x6f, 0x76, 0x74, 0xfd, 0x76, 0x50, 0xb3, 0x87, 0x4b, 0x67,
- 0x4e, 0xf0, 0x2e, 0x1d, 0x35, 0x6a, 0x8d, 0x77, 0x62, 0x11, 0xda, 0x21,
- 0x85, 0x6a, 0x6e, 0x97, 0x3a, 0x7f, 0xb7, 0x5f, 0xd0, 0xb2, 0xae, 0x74,
- 0xf0, 0x66, 0x01, 0xa2, 0xdf, 0x9f, 0xbc, 0x6b, 0x03, 0x3e, 0x74, 0x7c,
- 0xf6, 0x3b, 0x2b, 0x9e, 0xa1, 0x47, 0x0e, 0x9f, 0x69, 0xf7, 0xf1, 0x73,
- 0xa7, 0xe7, 0x5e, 0x34, 0x2d, 0xd9, 0xd3, 0xee, 0x5b, 0xaf, 0xea, 0x8e,
- 0x86, 0x3d, 0xe4, 0x31, 0x9e, 0xc4, 0x1d, 0x1d, 0x3f, 0xbd, 0xb6, 0xec,
- 0x14, 0xa3, 0xa7, 0xb7, 0xe7, 0x95, 0x1d, 0x35, 0x3c, 0xe8, 0xa3, 0x74,
- 0x24, 0xb2, 0x5b, 0xbc, 0xab, 0xf5, 0xa1, 0x3a, 0xf2, 0x3e, 0x46, 0x2a,
- 0x11, 0xe8, 0x47, 0xf2, 0x0d, 0xc2, 0x23, 0xb2, 0x01, 0x1f, 0xd3, 0x6c,
- 0xff, 0xb1, 0xeb, 0xaf, 0x86, 0x60, 0x1a, 0x29, 0x49, 0xfe, 0x7a, 0xeb,
- 0xe1, 0x98, 0x06, 0x89, 0x3a, 0x4b, 0x52, 0x22, 0x71, 0x1e, 0x19, 0xf1,
- 0xa4, 0x2c, 0x8d, 0xb3, 0x9b, 0x6d, 0x91, 0x45, 0x41, 0x0b, 0x44, 0x27,
- 0xeb, 0xc2, 0xbd, 0xc2, 0x65, 0x4f, 0x9c, 0xec, 0xa7, 0xb8, 0x4c, 0xde,
- 0x59, 0x23, 0xa8, 0xce, 0xe7, 0xdf, 0x0c, 0xc0, 0x34, 0x43, 0xf3, 0xfe,
- 0xc7, 0xae, 0xbe, 0x19, 0x80, 0x68, 0x94, 0xe4, 0xba, 0x3f, 0x85, 0x18,
- 0xcf, 0xe5, 0xd7, 0xc3, 0x30, 0x0d, 0x11, 0x3c, 0xfe, 0x5d, 0x7c, 0x33,
- 0x00, 0xd1, 0x18, 0xcf, 0xfe, 0x5a, 0xb1, 0xeb, 0xaf, 0x86, 0x60, 0x1a,
- 0x27, 0x98, 0x64, 0x79, 0x58, 0x4e, 0xf3, 0xcd, 0x9e, 0x4f, 0xbe, 0x19,
- 0x80, 0x68, 0x88, 0x27, 0xfd, 0x8f, 0x5d, 0x7c, 0x33, 0x00, 0xd1, 0x2a,
- 0x49, 0x74, 0x7f, 0x0a, 0x31, 0x9f, 0xcb, 0xaf, 0x86, 0x60, 0x1a, 0x22,
- 0x89, 0xfc, 0xba, 0xf8, 0x66, 0x01, 0xa2, 0x32, 0x9f, 0xfc, 0xb5, 0x63,
- 0xd7, 0x5f, 0x0c, 0xc0, 0x34, 0x4c, 0xb3, 0xf9, 0x75, 0xf0, 0xcc, 0x03,
- 0x45, 0x49, 0x3f, 0x97, 0x5f, 0x0c, 0xc0, 0x34, 0x57, 0x53, 0xf9, 0x75,
- 0xf0, 0xcc, 0x03, 0x45, 0x8b, 0x3f, 0xf2, 0xb1, 0xeb, 0xaf, 0x86, 0x60,
- 0x1a, 0x27, 0xa9, 0xfe, 0xe1, 0x78, 0xc9, 0xd4, 0x8e, 0xc7, 0x42, 0xd1,
- 0x14, 0xc9, 0xb3, 0xf7, 0x5a, 0xf5, 0xa4, 0xf6, 0xe7, 0x4f, 0x7d, 0x5a,
- 0xb4, 0xe9, 0xc1, 0x5b, 0x2a, 0x72, 0x9a, 0xe7, 0x4f, 0xff, 0xdb, 0x1c,
- 0xf2, 0x9f, 0x67, 0xbe, 0xaf, 0xdf, 0x6c, 0x74, 0xff, 0xfd, 0xf4, 0x76,
- 0xc5, 0x2d, 0xbf, 0xf4, 0x76, 0x0f, 0x6c, 0x3a, 0x7c, 0x09, 0xbf, 0x0a,
- 0x3a, 0x7f, 0xf6, 0x5c, 0x6b, 0xb5, 0xed, 0x03, 0x3e, 0x74, 0xfb, 0x5b,
- 0x65, 0x01, 0xd3, 0xff, 0x87, 0xa3, 0x30, 0xb2, 0xba, 0x74, 0xdf, 0x51,
- 0xd3, 0x65, 0xa7, 0x4f, 0xec, 0xbe, 0x6f, 0xd1, 0xb0, 0xe8, 0x13, 0xc9,
- 0xf4, 0x5a, 0x2c, 0x54, 0x50, 0x83, 0x7f, 0x5c, 0x53, 0x0e, 0xca, 0x05,
- 0x1f, 0x44, 0xce, 0xd0, 0x99, 0x9c, 0x39, 0xa3, 0xa7, 0x0a, 0x5c, 0xe9,
- 0x70, 0xef, 0x9b, 0x46, 0x1a, 0x9e, 0xfb, 0xac, 0x51, 0xd1, 0x47, 0x9e,
- 0x85, 0x93, 0xfe, 0x4d, 0xe6, 0x99, 0xcb, 0xa2, 0x8e, 0x9f, 0x0f, 0x94,
- 0xab, 0x9d, 0x3f, 0xf5, 0x71, 0x9d, 0xd0, 0x6f, 0x3b, 0xb9, 0xd0, 0x87,
- 0xd6, 0x24, 0xf3, 0x94, 0xdb, 0x3a, 0x78, 0x79, 0xe9, 0xe4, 0xe9, 0xfa,
- 0xaf, 0xc6, 0x0d, 0x87, 0x45, 0x1f, 0x76, 0x0d, 0x89, 0x34, 0xfb, 0xdf,
- 0x37, 0xe5, 0x8e, 0x8a, 0x47, 0x2a, 0x42, 0x3b, 0x65, 0x93, 0xff, 0xff,
- 0xb6, 0xc9, 0xff, 0xb7, 0x8d, 0x20, 0xfa, 0xfa, 0xbf, 0x3e, 0xe7, 0xde,
- 0x74, 0xfa, 0xce, 0x7e, 0x9c, 0x1d, 0x3f, 0x73, 0x9f, 0xef, 0xaa, 0x8e,
- 0x9f, 0xf0, 0xa3, 0xf5, 0xba, 0xfa, 0x5c, 0xe9, 0xff, 0x65, 0x76, 0xc3,
- 0x9c, 0xd7, 0x93, 0xa1, 0xe7, 0xf5, 0xd9, 0xe4, 0xfe, 0xcb, 0x6f, 0xad,
- 0x57, 0x5c, 0xe9, 0xff, 0xcd, 0x56, 0xeb, 0x6d, 0xa1, 0x6e, 0xee, 0x74,
- 0xeb, 0xed, 0x47, 0x46, 0x8f, 0x97, 0xd4, 0x99, 0xfb, 0xdb, 0xea, 0xf5,
- 0xa3, 0xa7, 0x71, 0xc7, 0x05, 0x4f, 0xfe, 0xd2, 0x6a, 0xfb, 0x4e, 0xaf,
- 0x1f, 0x67, 0x94, 0xb2, 0xfe, 0x11, 0x15, 0x5e, 0xa6, 0xc3, 0xd5, 0x7f,
- 0x53, 0xd2, 0x15, 0x7e, 0x15, 0x6a, 0x23, 0x18, 0x4e, 0x6a, 0x19, 0xb3,
- 0xfd, 0x6b, 0xef, 0x7a, 0xe7, 0x34, 0x74, 0xa8, 0xe8, 0x63, 0xc9, 0xf2,
- 0x75, 0x3e, 0xe3, 0x4d, 0x6f, 0x07, 0x4e, 0x0e, 0x36, 0x74, 0xfe, 0x6c,
- 0xfe, 0xf8, 0xce, 0x4a, 0x9b, 0x8e, 0x0a, 0x8e, 0x4f, 0x2f, 0x83, 0x39,
- 0xda, 0x4e, 0xb9, 0x4b, 0x34, 0x93, 0xde, 0xbf, 0xdd, 0x1d, 0x17, 0x3d,
- 0x3e, 0xa2, 0xf9, 0xb8, 0xb9, 0xd2, 0xa3, 0xa5, 0x6d, 0x1a, 0x6d, 0x0b,
- 0xcf, 0xfd, 0x7b, 0xf2, 0x2d, 0xce, 0xdb, 0x57, 0x3a, 0x18, 0xfb, 0x3d,
- 0x27, 0x9f, 0xf6, 0x93, 0xf9, 0xdb, 0xb6, 0xab, 0x67, 0x4f, 0xec, 0xfe,
- 0xae, 0x29, 0xe4, 0xe8, 0x7a, 0x25, 0x90, 0x8b, 0x10, 0x67, 0x52, 0x7c,
- 0xe9, 0xec, 0xfb, 0x3c, 0xe8, 0xb0, 0xdd, 0x28, 0x6a, 0x7f, 0xcd, 0x6e,
- 0xd9, 0x41, 0xb4, 0x70, 0xe8, 0xa3, 0xe0, 0xf9, 0x14, 0xfd, 0xa6, 0xff,
- 0x34, 0x27, 0x4f, 0xee, 0x76, 0xc3, 0xc6, 0x5a, 0x74, 0xff, 0xc9, 0xce,
- 0xd8, 0x1b, 0xbc, 0x1e, 0xce, 0x9f, 0xff, 0xf2, 0x2b, 0x06, 0xd7, 0xaf,
- 0x8a, 0x47, 0x54, 0x35, 0xce, 0x3c, 0xf1, 0x7a, 0xc3, 0x26, 0x39, 0x85,
- 0x97, 0x34, 0xf5, 0x0e, 0x7f, 0xfa, 0xb5, 0x7a, 0x73, 0x6c, 0xea, 0xb7,
- 0xb6, 0x3a, 0x7f, 0xff, 0xfc, 0x95, 0x6d, 0xd2, 0xb8, 0xe9, 0x56, 0xbe,
- 0xe9, 0xab, 0xa5, 0xbc, 0xf3, 0xed, 0x87, 0x4f, 0xff, 0x90, 0x79, 0xe9,
- 0xe3, 0x49, 0x7c, 0x41, 0xf5, 0xe7, 0x40, 0xa6, 0x67, 0xa5, 0x07, 0x50,
- 0x8b, 0x9b, 0x39, 0x3a, 0x7e, 0xfe, 0x5f, 0x78, 0xf3, 0xa5, 0x69, 0xd3,
- 0x27, 0x07, 0x4d, 0xe3, 0xb3, 0xa1, 0xc3, 0x5f, 0xd8, 0xb4, 0xe7, 0xe7,
- 0x27, 0x4d, 0xc7, 0x07, 0x43, 0xd1, 0xb3, 0x42, 0xc0, 0x58, 0x88, 0x17,
- 0x23, 0xe0, 0x72, 0x76, 0xbc, 0x76, 0x52, 0xcf, 0x56, 0x7f, 0xff, 0xf6,
- 0x9b, 0x9d, 0xfb, 0x9e, 0x55, 0x9c, 0xd5, 0x0f, 0x9b, 0xde, 0x87, 0xb3,
- 0xa2, 0xd4, 0x56, 0x21, 0x84, 0xff, 0x56, 0xb6, 0xdf, 0xd5, 0x01, 0xd3,
- 0x9b, 0xee, 0x1d, 0x14, 0xaa, 0x1b, 0x25, 0x08, 0x89, 0x1f, 0x51, 0xb4,
- 0xeb, 0xe3, 0x87, 0x4f, 0x56, 0xb1, 0xd8, 0xe8, 0xb4, 0xdf, 0x88, 0xe4,
- 0xff, 0xd5, 0xff, 0xd3, 0x9b, 0xab, 0xe0, 0x9d, 0x3f, 0x85, 0xbf, 0xe8,
- 0x6d, 0x8e, 0x9f, 0x27, 0x9d, 0xe3, 0xce, 0x9f, 0x91, 0x95, 0x65, 0x70,
- 0x74, 0xdc, 0x70, 0x74, 0x01, 0xf6, 0xfc, 0xa3, 0x82, 0xd9, 0xfe, 0xa7,
- 0x31, 0xcc, 0xb5, 0xf7, 0x29, 0x66, 0xbe, 0x7f, 0xaa, 0xbb, 0xa7, 0x1a,
- 0xdb, 0x9d, 0x3f, 0xfa, 0x87, 0xba, 0xda, 0x5b, 0x7d, 0xfb, 0x73, 0xa7,
- 0xe1, 0xce, 0xf9, 0xa1, 0x3a, 0x7e, 0x52, 0x75, 0x57, 0xfc, 0x9d, 0x3b,
- 0x8e, 0x38, 0x2a, 0x7f, 0xe6, 0xf8, 0xfb, 0x9e, 0x29, 0xc6, 0x51, 0xcb,
- 0x2f, 0xe3, 0xae, 0xa9, 0xad, 0xc8, 0x66, 0x8a, 0x55, 0xce, 0x74, 0x97,
- 0xe9, 0x67, 0x0a, 0x13, 0xff, 0xec, 0xe6, 0xa8, 0x7c, 0xf8, 0x16, 0x1b,
- 0x13, 0xe7, 0x4e, 0xcf, 0xd8, 0x79, 0x04, 0xa7, 0x9f, 0x56, 0xbc, 0xf2,
- 0x09, 0x4e, 0xba, 0x72, 0x79, 0x04, 0xa6, 0xe3, 0x83, 0xc8, 0x25, 0x00,
- 0x8a, 0x67, 0x0a, 0x74, 0x5f, 0xc1, 0x4c, 0xd9, 0xa2, 0xc8, 0x24, 0x59,
- 0xbe, 0x9f, 0xab, 0x75, 0x43, 0xe4, 0xe9, 0xd8, 0x3d, 0xa9, 0x39, 0x91,
- 0x8c, 0xeb, 0x46, 0x73, 0xdd, 0x55, 0x9b, 0x3a, 0x55, 0xd7, 0x3e, 0xae,
- 0xd1, 0xe7, 0xf3, 0x8f, 0xf6, 0xcd, 0x25, 0x85, 0x4f, 0xe4, 0x7f, 0xb9,
- 0x7d, 0xa1, 0xd2, 0x79, 0x53, 0xb3, 0xf6, 0x15, 0x05, 0x43, 0x1b, 0x60,
- 0x10, 0x50, 0xe4, 0xf0, 0xb7, 0x60, 0x52, 0xcd, 0x64, 0x32, 0x31, 0x2a,
- 0x12, 0x93, 0xde, 0xe7, 0xde, 0x74, 0x94, 0x74, 0xd4, 0xfe, 0x4d, 0x93,
- 0x84, 0x53, 0xee, 0x29, 0xc4, 0x51, 0xd3, 0xf0, 0x33, 0x8f, 0x6e, 0xca,
- 0x92, 0x1d, 0x3f, 0xd6, 0x7a, 0xfe, 0x77, 0xee, 0x09, 0xd3, 0xf2, 0x32,
- 0xac, 0xae, 0x0e, 0x9f, 0x55, 0x8a, 0xa5, 0x1d, 0x3a, 0xe9, 0xf3, 0xa0,
- 0x4f, 0x0b, 0x44, 0xf3, 0xf0, 0xe7, 0x7d, 0xfb, 0x73, 0xa7, 0xe4, 0xf3,
- 0xe1, 0x94, 0xbe, 0x53, 0x0a, 0xa0, 0xff, 0x9e, 0x5d, 0xbf, 0x44, 0x31,
- 0x49, 0xe8, 0x21, 0x40, 0xc6, 0x6f, 0x3c, 0x35, 0x67, 0xa7, 0x43, 0xd5,
- 0xe9, 0xd1, 0x66, 0xe1, 0xf6, 0x2b, 0x17, 0x8f, 0xfb, 0x46, 0x93, 0xff,
- 0xeb, 0x3f, 0xfa, 0xe7, 0x15, 0xbc, 0xd0, 0xb3, 0x87, 0x4f, 0xff, 0xfe,
- 0xf7, 0xfe, 0xb8, 0x39, 0xdd, 0xef, 0x5e, 0x6b, 0xdf, 0xe7, 0x2d, 0xb6,
- 0x3a, 0x77, 0x1c, 0x70, 0x54, 0xcf, 0x62, 0x96, 0x5f, 0xc3, 0x26, 0x2d,
- 0x62, 0xb7, 0xe1, 0x39, 0x3f, 0x58, 0xe3, 0xfa, 0xcf, 0xd8, 0x74, 0xf6,
- 0xf2, 0xde, 0x0e, 0x9f, 0x59, 0xf4, 0x65, 0x1d, 0x3f, 0xfc, 0xde, 0x34,
- 0x2d, 0xde, 0x6b, 0xbf, 0x02, 0xf3, 0xa3, 0xad, 0xa3, 0x4d, 0x0d, 0xb0,
- 0x8f, 0x44, 0xf3, 0xbc, 0x72, 0xe1, 0xd3, 0x9e, 0x82, 0x74, 0xfd, 0xa6,
- 0x70, 0x7d, 0xb9, 0xd1, 0x61, 0xf4, 0x3c, 0x83, 0x43, 0x53, 0x65, 0xce,
- 0x9b, 0xd7, 0x70, 0xe8, 0x13, 0x63, 0xe8, 0xac, 0xd8, 0xb7, 0x79, 0xbe,
- 0xea, 0x77, 0x66, 0xdd, 0x6b, 0x11, 0xb4, 0xa4, 0x2b, 0x21, 0xfa, 0xf2,
- 0x0e, 0x63, 0x8d, 0xa9, 0x66, 0x3e, 0x61, 0x76, 0x04, 0x76, 0x95, 0x24,
- 0x37, 0x9c, 0x8d, 0x37, 0xf0, 0xc8, 0x54, 0x67, 0xbb, 0x97, 0xed, 0x90,
- 0x85, 0x12, 0x1b, 0xca, 0xad, 0xd4, 0xf2, 0x3f, 0xb1, 0xbc, 0x75, 0x46,
- 0x13, 0xe2, 0x15, 0x2e, 0xcc, 0x33, 0xff, 0x96, 0xac, 0x7a, 0xeb, 0xe1,
- 0x98, 0x06, 0x8a, 0x2a, 0x7f, 0x2e, 0xbe, 0x19, 0x80, 0x68, 0xba, 0x27,
- 0xfe, 0x5e, 0x3d, 0x75, 0xf0, 0xcc, 0x03, 0x44, 0x97, 0x3f, 0x97, 0x5f,
- 0x0c, 0xc0, 0x34, 0x5e, 0x50, 0xce, 0x90, 0x8a, 0xc2, 0x77, 0x9e, 0x51,
- 0xe0, 0x29, 0xb8, 0x78, 0xa3, 0xcd, 0xc3, 0x18, 0x6b, 0xf0, 0xcb, 0xc7,
- 0x9d, 0xa5, 0x3f, 0x4f, 0x1d, 0x26, 0xcf, 0xfe, 0x5a, 0xb1, 0xeb, 0xaf,
- 0x86, 0x60, 0x1a, 0x25, 0x99, 0xbd, 0xd9, 0xd3, 0xc1, 0x98, 0x06, 0x88,
- 0xce, 0x7e, 0x46, 0x55, 0x95, 0xc1, 0xd3, 0x0b, 0xce, 0x92, 0x8e, 0x9f,
- 0x27, 0xf7, 0x8b, 0xf9, 0xe9, 0x28, 0xb7, 0xc0, 0xac, 0xfd, 0x8f, 0x4f,
- 0xe7, 0xce, 0x9f, 0xfa, 0xe9, 0xed, 0xe8, 0x7d, 0x7d, 0x5c, 0xe9, 0xd7,
- 0x6b, 0x4e, 0x8f, 0xa6, 0xaa, 0xa7, 0xd1, 0x4d, 0xb9, 0x5e, 0x91, 0x27,
- 0xfe, 0xd2, 0x7f, 0x3b, 0xe9, 0x6b, 0xd9, 0x47, 0x4f, 0x85, 0x9f, 0x7c,
- 0x3a, 0x10, 0xfb, 0x1d, 0x23, 0xce, 0xcf, 0x0f, 0x3a, 0x7f, 0xfb, 0xdd,
- 0x5e, 0xd7, 0xb0, 0xf7, 0x7e, 0x9e, 0x89, 0xd3, 0x9b, 0x4c, 0x74, 0x93,
- 0x93, 0xef, 0x74, 0xab, 0x3f, 0xd9, 0x6d, 0xc6, 0xbf, 0xcb, 0x1d, 0x3f,
- 0xf5, 0x2b, 0x49, 0xc5, 0xdb, 0x79, 0xd7, 0x3a, 0x7f, 0xdb, 0x64, 0xda,
- 0x30, 0xb9, 0xe9, 0xd3, 0xfa, 0xae, 0xda, 0xbe, 0xd0, 0xe9, 0x2d, 0xde,
- 0x57, 0xd1, 0x51, 0xb6, 0x39, 0x0b, 0x6d, 0x91, 0xe4, 0x23, 0x3b, 0x2a,
- 0x13, 0x8b, 0xa3, 0xf5, 0x1e, 0xcf, 0xfe, 0x5a, 0xb1, 0xeb, 0xaf, 0x86,
- 0x60, 0x1a, 0x26, 0x99, 0xff, 0xcb, 0x56, 0x3d, 0x75, 0xf0, 0xcc, 0x03,
- 0x44, 0xe3, 0x3f, 0xf9, 0x6a, 0xc7, 0xae, 0xbe, 0x19, 0x80, 0x68, 0xa0,
- 0x67, 0xdf, 0x0c, 0xc0, 0x34, 0x5c, 0x13, 0x32, 0x1d, 0x3f, 0x85, 0xec,
- 0x9c, 0xd2, 0x8e, 0x92, 0xe8, 0xfd, 0xb6, 0x63, 0xe8, 0xa4, 0xfe, 0x45,
- 0xf8, 0x6e, 0xeb, 0x83, 0xa7, 0xf9, 0xeb, 0xaf, 0x86, 0x60, 0x1a, 0x24,
- 0x99, 0x2f, 0x67, 0xef, 0x86, 0xb3, 0xec, 0x5f, 0x3c, 0x76, 0x74, 0x58,
- 0xbe, 0x88, 0xf9, 0xc3, 0xb0, 0x84, 0xeb, 0x8a, 0x7d, 0xa9, 0xde, 0x19,
- 0x3a, 0x85, 0x63, 0xa2, 0x79, 0xff, 0x79, 0xc5, 0xd7, 0xc3, 0x30, 0x0d,
- 0x16, 0xa4, 0xff, 0xb1, 0xeb, 0xaf, 0x86, 0x60, 0x1a, 0x25, 0x58, 0x3a,
- 0x4b, 0xf2, 0x89, 0xa5, 0x24, 0xbb, 0x23, 0xcf, 0xe5, 0xd7, 0xc3, 0x30,
- 0x0d, 0x11, 0x4c, 0xfe, 0x5d, 0x7c, 0x33, 0x00, 0xd1, 0x1a, 0x4d, 0xee,
- 0xce, 0x9e, 0x0c, 0xc0, 0x34, 0x53, 0xf3, 0x69, 0x8e, 0x8f, 0x9e, 0x06,
- 0x8a, 0xe7, 0xfe, 0xf7, 0x5f, 0xf5, 0xcb, 0x86, 0x39, 0x73, 0xa7, 0xfe,
- 0xa7, 0x3d, 0x1b, 0x2e, 0x18, 0xe5, 0xce, 0x92, 0xdd, 0xe4, 0xc1, 0xe9,
- 0x5c, 0x48, 0xb4, 0x91, 0x3f, 0xf9, 0x6a, 0xc7, 0xae, 0xbe, 0x19, 0x80,
- 0x68, 0x9a, 0xa7, 0xf2, 0xeb, 0xe1, 0x98, 0x06, 0x8a, 0xee, 0x78, 0x33,
- 0x00, 0xd1, 0x5f, 0x4e, 0xe3, 0x8e, 0x0a, 0x90, 0x94, 0xb2, 0xfe, 0x3e,
- 0x7d, 0x0a, 0x4a, 0x9c, 0xf6, 0xb4, 0xe9, 0xce, 0x56, 0xce, 0x9f, 0xf5,
- 0x6f, 0x8c, 0xd5, 0xda, 0xac, 0x3a, 0x5a, 0x3a, 0x7f, 0x93, 0xf5, 0x62,
- 0x3e, 0xb9, 0x3a, 0x3e, 0x79, 0x18, 0x21, 0x25, 0xd2, 0x60, 0x2e, 0x11,
- 0x60, 0xe0, 0x8e, 0x5e, 0x10, 0xd3, 0xff, 0x96, 0xac, 0x7a, 0xeb, 0xe1,
- 0x98, 0x06, 0x89, 0xee, 0x7f, 0x2e, 0xbe, 0x19, 0x80, 0x68, 0xb8, 0x67,
- 0xfe, 0x5e, 0x3d, 0x75, 0xf0, 0xcc, 0x03, 0x44, 0x9f, 0x0c, 0xba, 0x53,
- 0x61, 0xdb, 0xcf, 0x3c, 0xc6, 0x86, 0x08, 0xee, 0x29, 0xfe, 0x3a, 0x5d,
- 0xaa, 0x5d, 0x4d, 0xd1, 0xe4, 0xfe, 0x5d, 0x7c, 0x33, 0x00, 0xd1, 0x15,
- 0x4f, 0xe5, 0xd7, 0xc3, 0x30, 0x0d, 0x14, 0xcc, 0xff, 0xe5, 0xab, 0x1e,
- 0xba, 0xf8, 0x66, 0x01, 0xa2, 0x67, 0x9f, 0xfc, 0xb5, 0x63, 0xd7, 0x5f,
- 0x0c, 0xc0, 0x34, 0x51, 0xb1, 0x62, 0x63, 0xdc, 0x9e, 0x79, 0x3c, 0xd2,
- 0x9c, 0xff, 0xcb, 0xc7, 0xae, 0xbe, 0x19, 0x80, 0x68, 0x8e, 0xa6, 0xf7,
- 0x67, 0x4f, 0xc9, 0x43, 0xcd, 0x58, 0x74, 0xfb, 0xe1, 0x98, 0x06, 0x8a,
- 0x6a, 0x7f, 0xf6, 0xd3, 0x57, 0xcb, 0x69, 0xc6, 0xdd, 0xce, 0x9f, 0xf9,
- 0xfb, 0x41, 0xb2, 0xfe, 0xb7, 0xdc, 0x3a, 0x66, 0xf2, 0x74, 0xfc, 0x8c,
- 0xab, 0x2b, 0x83, 0xa7, 0xff, 0xab, 0x5b, 0xa7, 0xff, 0x07, 0x5b, 0xc7,
- 0x9d, 0x33, 0x76, 0x74, 0xfe, 0xcb, 0x58, 0x10, 0x17, 0xf4, 0x48, 0x09,
- 0x6f, 0x84, 0xd8, 0xda, 0x3f, 0xaf, 0x0a, 0x79, 0x2d, 0xde, 0x54, 0x55,
- 0xc8, 0xbd, 0x16, 0x01, 0x8d, 0xa9, 0x5a, 0x8d, 0x12, 0x7d, 0xf0, 0xcc,
- 0x03, 0x45, 0x55, 0x3f, 0xec, 0x7a, 0xeb, 0xe1, 0x98, 0x06, 0x89, 0xb6,
- 0x4b, 0xa3, 0xf8, 0x51, 0x8c, 0xfe, 0x5d, 0x7c, 0x33, 0x00, 0xd1, 0x5f,
- 0xcf, 0xe5, 0xd7, 0xc3, 0x30, 0x0d, 0x16, 0x34, 0xfb, 0xe1, 0x98, 0x06,
- 0x8b, 0x56, 0x7f, 0xd8, 0xf5, 0xd7, 0xc3, 0x30, 0x0d, 0x14, 0x14, 0x97,
- 0x47, 0xf0, 0xa3, 0x19, 0xf7, 0xc3, 0x30, 0x0d, 0x17, 0x14, 0xf6, 0x3b,
- 0x25, 0x87, 0x4f, 0x3b, 0x3b, 0x20, 0x1d, 0x3f, 0x99, 0x58, 0xe9, 0xbe,
- 0xec, 0x74, 0x97, 0x48, 0xb1, 0xd9, 0x8e, 0x12, 0x68, 0x9a, 0x7d, 0xf0,
- 0xcc, 0x03, 0x45, 0xd3, 0x3e, 0x61, 0xce, 0x58, 0xe9, 0x2e, 0x8f, 0x59,
- 0x0c, 0x67, 0xff, 0xe5, 0x2e, 0x9e, 0xdf, 0xef, 0xa5, 0xf6, 0xca, 0xc1,
- 0x3a, 0x7f, 0xfe, 0xd8, 0xfb, 0x9d, 0x7a, 0x7e, 0xeb, 0xcd, 0x72, 0xe7,
- 0xa7, 0x4c, 0x14, 0x74, 0x31, 0xfb, 0xf9, 0x63, 0x9f, 0xf3, 0xeb, 0xff,
- 0xc7, 0xd9, 0x5c, 0x1d, 0x38, 0x71, 0x7f, 0x3e, 0x2d, 0x11, 0xcf, 0xfb,
- 0xed, 0x6e, 0xf2, 0xfa, 0x6e, 0x0e, 0x9b, 0xdd, 0x9d, 0x3e, 0x1a, 0xde,
- 0x68, 0xe9, 0xf9, 0xf9, 0x4e, 0x9b, 0x93, 0xa1, 0xdf, 0x3d, 0x3e, 0xb5,
- 0x12, 0xcf, 0xdd, 0xe3, 0x8f, 0x4d, 0x1d, 0x3f, 0xff, 0xcd, 0xce, 0xea,
- 0xdd, 0x0e, 0x6f, 0xbc, 0xbd, 0xf3, 0xe0, 0x74, 0xfe, 0xaa, 0xaf, 0x3e,
- 0x71, 0xe7, 0x47, 0x94, 0x4d, 0x69, 0x9a, 0x7f, 0xff, 0xb6, 0xc3, 0xed,
- 0xf6, 0x97, 0xd6, 0xeb, 0x94, 0xbd, 0x09, 0xd3, 0xc1, 0x98, 0x06, 0x89,
- 0x32, 0x7c, 0x1d, 0x69, 0xd6, 0x75, 0xb7, 0x7c, 0xe9, 0xfd, 0x56, 0xeb,
- 0x58, 0xfb, 0x9d, 0x0c, 0x7e, 0x3f, 0x3e, 0x87, 0xa6, 0x45, 0xf6, 0x55,
- 0x42, 0x72, 0x7e, 0xe7, 0xb7, 0x7e, 0xfd, 0xf5, 0x1d, 0x3f, 0xfb, 0x69,
- 0xab, 0x41, 0x3f, 0x77, 0x1b, 0x0e, 0x9f, 0x56, 0x91, 0x58, 0x74, 0xff,
- 0x36, 0xf4, 0x96, 0x29, 0x80, 0xe9, 0xff, 0xf6, 0x07, 0xdb, 0x63, 0x5a,
- 0xa5, 0xf1, 0xc7, 0x05, 0x43, 0xd1, 0x63, 0x72, 0x5d, 0x1b, 0xcf, 0xc0,
- 0x1e, 0x80, 0xb1, 0xd3, 0xff, 0xbd, 0x1c, 0xd3, 0x7e, 0xfb, 0x61, 0xd1,
- 0xd3, 0xb8, 0xe3, 0x82, 0xa7, 0xef, 0xe5, 0x8a, 0x4b, 0x94, 0xb2, 0xfe,
- 0x7d, 0x4a, 0xfd, 0x75, 0xce, 0x9f, 0x26, 0xac, 0xae, 0x0e, 0x9f, 0xe6,
- 0x0d, 0x8f, 0xba, 0x6b, 0x9d, 0x3f, 0xfe, 0xd6, 0xe9, 0xfd, 0x03, 0x69,
- 0xab, 0x41, 0x3e, 0x74, 0x7d, 0x16, 0xaa, 0x28, 0x13, 0x79, 0xfe, 0xac,
- 0xef, 0xa5, 0x73, 0x8f, 0x3a, 0x7f, 0xf6, 0x59, 0xb4, 0x61, 0xa7, 0x13,
- 0xe8, 0x74, 0x52, 0x2c, 0x34, 0x5f, 0xc1, 0xd4, 0xf8, 0x6b, 0x79, 0xa3,
- 0xa7, 0xfc, 0xf6, 0x1b, 0x3c, 0x7c, 0x7d, 0x79, 0xd1, 0xd7, 0x3e, 0x67,
- 0x09, 0x67, 0xb5, 0x65, 0x72, 0x74, 0xff, 0x27, 0x9f, 0x1f, 0xed, 0x49,
- 0x73, 0xa1, 0xc3, 0xe0, 0xea, 0x23, 0x9d, 0xc7, 0x1c, 0x1d, 0x3f, 0xfe,
- 0xa5, 0x68, 0x5b, 0xba, 0xe6, 0xf4, 0xa6, 0x02, 0x96, 0x5f, 0xc5, 0x26,
- 0x5c, 0x90, 0x87, 0xda, 0x2c, 0x90, 0xe9, 0xfb, 0x6d, 0xd0, 0x12, 0xc3,
- 0xa7, 0xef, 0xe7, 0xc5, 0x9e, 0x74, 0x3b, 0xb3, 0xe8, 0xe4, 0x3f, 0xe5,
- 0xd3, 0x3d, 0x6e, 0xf3, 0x24, 0xcf, 0xac, 0x6a, 0x62, 0xf7, 0xc3, 0x22,
- 0xa3, 0x47, 0xf2, 0x6c, 0x07, 0x36, 0xc3, 0xe9, 0x0c, 0x1c, 0x2a, 0xc6,
- 0x71, 0x3c, 0xbc, 0x71, 0xfa, 0x8f, 0x13, 0xc4, 0x27, 0x27, 0xff, 0x7e,
- 0xb8, 0xe7, 0x74, 0xe0, 0xd7, 0xde, 0x74, 0xef, 0xd7, 0x5c, 0xe9, 0x57,
- 0xcf, 0xa9, 0x49, 0x73, 0xff, 0x56, 0xc5, 0xac, 0xf1, 0xbd, 0xe7, 0x5c,
- 0xe9, 0xfb, 0x01, 0x7c, 0x71, 0xc1, 0xd2, 0x5d, 0x33, 0x3a, 0x42, 0x33,
- 0x5f, 0x99, 0x65, 0x25, 0xc8, 0x63, 0x71, 0xb9, 0x3b, 0xa4, 0x98, 0x7b,
- 0x66, 0xdf, 0xcc, 0xa7, 0x7b, 0x61, 0xc5, 0xf2, 0x75, 0x1e, 0x77, 0x0b,
- 0x4b, 0xc3, 0x63, 0x50, 0x97, 0xf6, 0x9a, 0x1f, 0x3f, 0x97, 0x5f, 0x0c,
- 0xc0, 0x34, 0x46, 0xb3, 0xef, 0x86, 0x60, 0x1a, 0x2a, 0x59, 0xb0, 0x0d,
- 0x10, 0xd4, 0x97, 0x47, 0xa5, 0x86, 0x33, 0xff, 0x2f, 0x1e, 0xba, 0xf8,
- 0x66, 0x01, 0xa2, 0x3e, 0x9f, 0x7c, 0x33, 0x00, 0xd1, 0x63, 0xcf, 0xf0,
- 0xe7, 0x9d, 0xa3, 0x0d, 0x87, 0x49, 0x74, 0x7d, 0x2e, 0x18, 0xce, 0xeb,
- 0x45, 0x79, 0x3a, 0x7e, 0x77, 0xc6, 0xb7, 0x9a, 0x3a, 0x7f, 0x87, 0x3b,
- 0xbe, 0x6b, 0x58, 0x74, 0xf7, 0x6a, 0x4f, 0x9d, 0x3f, 0xff, 0xcd, 0xf1,
- 0xae, 0x6b, 0x7b, 0x40, 0xda, 0x6a, 0xf9, 0x69, 0xd0, 0x88, 0x86, 0xd9,
- 0x14, 0xec, 0xc0, 0x34, 0x5a, 0x13, 0xfe, 0xce, 0x1d, 0x83, 0x3f, 0x65,
- 0x70, 0x74, 0x01, 0xf4, 0x7c, 0x9a, 0x7f, 0xff, 0xf9, 0x3f, 0xbc, 0x14,
- 0x6d, 0x26, 0xda, 0xfb, 0xab, 0xfe, 0x82, 0xb4, 0x74, 0x7d, 0x13, 0x1b,
- 0x21, 0x9f, 0x9d, 0x78, 0xd0, 0xb7, 0x67, 0x4f, 0x9b, 0x55, 0xb6, 0x3a,
- 0x7f, 0xfa, 0xb5, 0x7a, 0x73, 0x6c, 0xea, 0xb7, 0xb6, 0x3a, 0x2c, 0x3f,
- 0x51, 0x25, 0x86, 0x46, 0x45, 0x42, 0x9a, 0x7f, 0xdd, 0xb0, 0x6d, 0x1c,
- 0xcc, 0xb0, 0xe9, 0xfe, 0x4f, 0x45, 0xff, 0x6a, 0xe4, 0xe9, 0xff, 0xfe,
- 0xdd, 0x3c, 0x36, 0x9b, 0x6a, 0xfb, 0xf4, 0x2c, 0xab, 0x9d, 0x2a, 0xba,
- 0x26, 0xf4, 0x71, 0x3e, 0xd6, 0xf0, 0x7c, 0x9d, 0x3f, 0xc3, 0xed, 0x9c,
- 0xee, 0x85, 0x8e, 0x98, 0x6a, 0x8f, 0x84, 0x0a, 0x27, 0xf5, 0x6d, 0xc4,
- 0xda, 0x28, 0xe9, 0xfc, 0xfa, 0xfd, 0xc5, 0xac, 0x3a, 0x75, 0x6f, 0x0e,
- 0x9f, 0x39, 0xcf, 0xbe, 0x89, 0xd1, 0xc9, 0xe2, 0xe0, 0xd4, 0xff, 0x55,
- 0x71, 0x40, 0x15, 0xc1, 0xd1, 0x49, 0x80, 0xda, 0x65, 0x8e, 0xf7, 0x22,
- 0x9e, 0xad, 0xe6, 0x8e, 0x9f, 0x90, 0x7d, 0x7d, 0x5c, 0xe9, 0xff, 0xfe,
- 0x41, 0xf5, 0xf5, 0x7e, 0x95, 0xa6, 0xb7, 0xbc, 0xde, 0xd0, 0xe8, 0xf2,
- 0x89, 0x4d, 0x16, 0x49, 0x6e, 0xf2, 0xf7, 0x47, 0x58, 0x4a, 0xc6, 0x1c,
- 0xc2, 0xf6, 0xa3, 0x22, 0xdc, 0x3a, 0xfb, 0x26, 0x18, 0x6c, 0xde, 0x11,
- 0x3a, 0x8c, 0xaf, 0xa8, 0xf7, 0xc4, 0x2d, 0x27, 0xe7, 0x64, 0xe4, 0x59,
- 0xc3, 0xa7, 0xab, 0x79, 0xa3, 0xa4, 0xef, 0xd1, 0xe8, 0x09, 0x84, 0xfb,
- 0xe1, 0x98, 0x06, 0x8b, 0x5a, 0x7f, 0xd8, 0xf5, 0xd7, 0xc3, 0x30, 0x0d,
- 0x14, 0x1c, 0x97, 0xd6, 0x22, 0x8e, 0x8a, 0xd4, 0x63, 0x3f, 0xf9, 0x6a,
- 0xc7, 0xae, 0xbe, 0x19, 0x80, 0x68, 0xa2, 0xe7, 0xf2, 0xeb, 0xe1, 0x98,
- 0x06, 0x8b, 0xaa, 0x1e, 0xcb, 0x17, 0x08, 0x47, 0x21, 0x32, 0xa1, 0x6d,
- 0xb9, 0xf1, 0x0e, 0xe3, 0xd4, 0xb9, 0xd6, 0x94, 0xe7, 0xdf, 0x0c, 0xc0,
- 0x34, 0x44, 0x33, 0xb7, 0x5c, 0x9d, 0x25, 0xd1, 0xe6, 0xda, 0x63, 0x3f,
- 0x97, 0x5f, 0x0c, 0xc0, 0x34, 0x46, 0xd3, 0xf9, 0x75, 0xf0, 0xcc, 0x03,
- 0x45, 0x37, 0x3f, 0x97, 0x5f, 0x0c, 0xc0, 0x34, 0x54, 0x13, 0xf9, 0x75,
- 0xf0, 0xcc, 0x03, 0x45, 0x4d, 0x3e, 0xf8, 0x66, 0x01, 0xa2, 0xb0, 0x9f,
- 0x27, 0x1c, 0xfb, 0xf3, 0xa7, 0xf9, 0xeb, 0xaf, 0x86, 0x60, 0x1a, 0x23,
- 0xf9, 0xd4, 0xd6, 0x1d, 0x25, 0xd2, 0x2e, 0x00, 0xc7, 0x0a, 0x85, 0x0a,
- 0x7f, 0xf2, 0xd5, 0x8f, 0x5d, 0x7c, 0x33, 0x00, 0xd1, 0x37, 0xcf, 0xfc,
- 0xac, 0x7a, 0xeb, 0xe1, 0x98, 0x06, 0x89, 0xfa, 0x7d, 0xd6, 0xdd, 0xfe,
- 0xaa, 0xb4, 0xe9, 0x6c, 0xe8, 0x77, 0x47, 0x8d, 0xe9, 0xb4, 0xff, 0x75,
- 0xad, 0xbc, 0xd6, 0xb3, 0x38, 0x3a, 0x7d, 0xd3, 0xcf, 0xf0, 0x0e, 0x9f,
- 0x75, 0x8e, 0xef, 0xbf, 0x2c, 0x74, 0xff, 0xf3, 0x33, 0x33, 0x33, 0x33,
- 0x35, 0xb7, 0x3a, 0x7d, 0xf4, 0xb3, 0x14, 0x54, 0xdc, 0x70, 0x54, 0x51,
- 0xbf, 0xe0, 0x9e, 0x5e, 0x94, 0xb3, 0x43, 0x0c, 0x8c, 0xab, 0xc2, 0xa6,
- 0x7f, 0xfe, 0xa5, 0x5f, 0x5f, 0xcb, 0x39, 0xdb, 0x5f, 0x5e, 0xec, 0xe9,
- 0xf6, 0x06, 0xd3, 0xe7, 0x4f, 0xff, 0xfe, 0x1c, 0xf2, 0x9f, 0x67, 0xf4,
- 0xda, 0x2b, 0x96, 0xe9, 0xd5, 0xee, 0xd3, 0xe7, 0x4f, 0x63, 0xd2, 0xd3,
- 0xa3, 0x94, 0xc9, 0x3e, 0xbd, 0xb2, 0x51, 0x84, 0x04, 0xff, 0xf9, 0xd9,
- 0xad, 0x7e, 0x0f, 0x7d, 0x3b, 0x4f, 0xa7, 0x93, 0xa7, 0xac, 0x52, 0x3c,
- 0xe9, 0xf5, 0xc7, 0xdc, 0x79, 0xd3, 0xfb, 0x6c, 0xa5, 0xf7, 0xdb, 0x1d,
- 0x2f, 0xb1, 0xfe, 0xd1, 0x12, 0x13, 0xcf, 0xf9, 0xad, 0xe7, 0xc3, 0x75,
- 0xf7, 0xed, 0xce, 0x97, 0x5c, 0xe9, 0xaf, 0x47, 0x42, 0x1a, 0x9e, 0xc5,
- 0x27, 0xfe, 0xe5, 0xb5, 0x97, 0xad, 0xed, 0x14, 0x74, 0xed, 0x23, 0x87,
- 0x43, 0x1e, 0xfd, 0xd0, 0xe1, 0x95, 0xd5, 0xa4, 0x69, 0x6e, 0x21, 0xfe,
- 0x1b, 0x4a, 0x32, 0x17, 0x0d, 0x42, 0x02, 0x73, 0x9e, 0x14, 0x74, 0xff,
- 0x56, 0xaf, 0x5a, 0xdd, 0x76, 0x74, 0x61, 0xeb, 0x88, 0xfc, 0xd8, 0x27,
- 0x47, 0xcd, 0xa2, 0x88, 0x27, 0x71, 0xc7, 0x07, 0x4f, 0x58, 0x28, 0xc5,
- 0x2c, 0xbf, 0x9a, 0xd7, 0x9d, 0x3f, 0xbc, 0xb6, 0xaf, 0xbc, 0xf4, 0xe9,
- 0x90, 0x0e, 0x95, 0xac, 0x7c, 0x1e, 0x45, 0xf4, 0x6b, 0x0c, 0x98, 0x36,
- 0xd0, 0x3d, 0x84, 0x7c, 0xff, 0xd6, 0x7b, 0xdd, 0x0f, 0xae, 0x36, 0xb0,
- 0xe9, 0xff, 0x9b, 0x7e, 0x39, 0xd2, 0x53, 0x8c, 0xa3, 0xa7, 0x9b, 0x57,
- 0x03, 0x44, 0x1d, 0x3f, 0x66, 0xdb, 0xaf, 0xeb, 0xce, 0x8f, 0xa3, 0xad,
- 0x48, 0xfa, 0x46, 0x74, 0x5b, 0x37, 0xf9, 0x3a, 0x6e, 0x38, 0x3a, 0x1e,
- 0x6b, 0xf8, 0x17, 0x9e, 0xbb, 0x23, 0xa2, 0x96, 0x68, 0xa7, 0xd7, 0xf1,
- 0xcf, 0x77, 0x3a, 0x10, 0xf7, 0xbc, 0x19, 0x4e, 0xe3, 0x8e, 0x0a, 0x82,
- 0x96, 0x5f, 0xcf, 0x27, 0x08, 0xe1, 0x50, 0x06, 0xed, 0x06, 0x61, 0x13,
- 0x8a, 0xdc, 0x3b, 0x85, 0xf6, 0x70, 0xa5, 0xce, 0x9e, 0xe7, 0x07, 0xb3,
- 0xa7, 0xfe, 0x61, 0xec, 0x5a, 0xd7, 0x18, 0x7b, 0x3a, 0x11, 0x10, 0x1d,
- 0x8d, 0x5c, 0x8a, 0x7c, 0xd5, 0xfd, 0xa1, 0xd3, 0xdc, 0xd2, 0xba, 0xe7,
- 0x43, 0x87, 0x96, 0xe8, 0x96, 0x7e, 0xd5, 0x38, 0x2c, 0xa3, 0xc4, 0x05,
- 0x3e, 0xc1, 0xe7, 0x6c, 0x68, 0x80, 0x96, 0x6e, 0x67, 0xef, 0xb3, 0xf2,
- 0xde, 0x0e, 0x9f, 0xe6, 0xfd, 0x9d, 0x29, 0xc4, 0x51, 0xd3, 0xca, 0x6a,
- 0x51, 0xd3, 0xe6, 0xed, 0x2d, 0xb9, 0xd3, 0xfb, 0xee, 0x5d, 0x07, 0x48,
- 0x74, 0xf5, 0xbd, 0xfd, 0x8a, 0x9b, 0x8e, 0x0a, 0x86, 0x37, 0x7c, 0x11,
- 0xcf, 0xd9, 0xf7, 0xbc, 0x50, 0xa5, 0x9a, 0x18, 0x65, 0x52, 0xd4, 0xf6,
- 0x8b, 0xdf, 0x43, 0xd9, 0x76, 0x1d, 0x89, 0x06, 0x8a, 0x3d, 0x84, 0x74,
- 0xfb, 0xdd, 0x7b, 0x9e, 0x0d, 0x10, 0x3c, 0xff, 0xb7, 0xed, 0x8d, 0xd1,
- 0xb4, 0xdc, 0x9d, 0x3b, 0x3f, 0x61, 0xd3, 0x71, 0xc1, 0xd3, 0xfb, 0xe9,
- 0x4e, 0xbc, 0x3d, 0x60, 0x6d, 0x38, 0x1c, 0x8e, 0x51, 0x87, 0xf7, 0x69,
- 0xff, 0x86, 0xbc, 0xef, 0x1f, 0xe3, 0x2d, 0x63, 0xa1, 0x8f, 0xaa, 0x89,
- 0x27, 0xff, 0x52, 0x95, 0x8f, 0xaf, 0x86, 0x60, 0x1a, 0x21, 0x88, 0xd9,
- 0xf9, 0x09, 0x04, 0xfb, 0xe1, 0x98, 0x06, 0x88, 0x2a, 0x76, 0xd9, 0x47,
- 0x45, 0x1e, 0x62, 0x18, 0xcf, 0x6a, 0xed, 0xd9, 0x53, 0xb3, 0xf6, 0x15,
- 0x3d, 0xe8, 0xe7, 0x92, 0xa7, 0xf2, 0x59, 0x5a, 0xbb, 0x76, 0x54, 0x15,
- 0x3f, 0x50, 0x36, 0xd9, 0x45, 0x4d, 0xc7, 0x05, 0x4f, 0xc2, 0xc3, 0x62,
- 0x7c, 0xa8, 0xa4, 0xc2, 0xc0, 0x89, 0x43, 0x9b, 0x23, 0xec, 0xcc, 0x42,
- 0xb8, 0x2a, 0xf0, 0x31, 0x32, 0x7c, 0xa5, 0x9f, 0x9c, 0xb1, 0xe9, 0xe2,
- 0x6e, 0x39, 0xe9, 0xff, 0x33, 0xf0, 0x6a, 0xff, 0x6b, 0x9d, 0x3f, 0xda,
- 0xdb, 0x3a, 0xe5, 0xbb, 0x63, 0xa7, 0xf9, 0xad, 0x7f, 0x53, 0x05, 0x28,
- 0xe8, 0x63, 0xf5, 0xd9, 0xdc, 0xff, 0xfc, 0xe6, 0x63, 0xf3, 0x7d, 0x2a,
- 0xcf, 0x75, 0xee, 0x78, 0x34, 0x5f, 0x73, 0xe4, 0xd0, 0xd3, 0xce, 0x9f,
- 0xf0, 0xa3, 0xf5, 0xba, 0xfa, 0x5c, 0xe9, 0xfd, 0xae, 0xfc, 0x0b, 0xf7,
- 0x47, 0x88, 0x06, 0x76, 0x7d, 0xe7, 0x88, 0x06, 0x28, 0xfa, 0xbd, 0x42,
- 0x9b, 0x1e, 0x78, 0x80, 0x67, 0xb0, 0x6d, 0x79, 0xe2, 0x01, 0x9f, 0xc8,
- 0x1b, 0xae, 0xfb, 0x63, 0xc4, 0x03, 0x39, 0x07, 0x93, 0xc4, 0x03, 0x1c,
- 0xa2, 0xdd, 0x44, 0x5b, 0x2e, 0x74, 0x7f, 0x3b, 0xed, 0xa3, 0xc4, 0x03,
- 0x07, 0x88, 0x06, 0x66, 0x51, 0xe2, 0x01, 0x8e, 0x4d, 0xca, 0x0b, 0xcf,
- 0x22, 0xb9, 0x63, 0xc4, 0x03, 0x3b, 0x58, 0x07, 0x88, 0x06, 0x7f, 0xc3,
- 0x8f, 0x5e, 0xd0, 0x33, 0xe7, 0x88, 0x06, 0x6c, 0xe4, 0xf1, 0x00, 0xcf,
- 0xe1, 0xce, 0x2f, 0x76, 0xec, 0xf1, 0x00, 0xcf, 0x93, 0xce, 0x0f, 0x67,
- 0x88, 0x06, 0x64, 0xb9, 0xe2, 0x01, 0x8f, 0x9e, 0xbe, 0x8d, 0x67, 0xda,
- 0x16, 0xb5, 0xe6, 0x88, 0x06, 0x6e, 0xd8, 0xf1, 0x00, 0xac, 0xda, 0x4f,
- 0x91, 0x95, 0x9c, 0x9e, 0x20, 0x19, 0xef, 0x70, 0x40, 0xf1, 0x00, 0xce,
- 0x6f, 0x81, 0xe2, 0x01, 0x9f, 0xf5, 0x5b, 0x7e, 0x5a, 0x87, 0xbb, 0x9e,
- 0x20, 0x19, 0xf7, 0xb8, 0xf7, 0xb1, 0xe2, 0x01, 0x8a, 0x44, 0x06, 0xd3,
- 0x26, 0xff, 0x67, 0x88, 0x06, 0x1e, 0xaa, 0x43, 0x92, 0x3a, 0x84, 0xba,
- 0x2b, 0x6c, 0xcf, 0xb3, 0x3b, 0x96, 0xea, 0x14, 0xfe, 0x91, 0x4f, 0xab,
- 0x57, 0xcb, 0x4f, 0x10, 0x0c, 0xfe, 0xe5, 0x81, 0xcf, 0xb6, 0x8f, 0x10,
- 0x0f, 0x26, 0xd2, 0x77, 0xdb, 0x83, 0xc4, 0x03, 0x00, 0x7f, 0x5f, 0x51,
- 0x9e, 0x41, 0x7d, 0xcf, 0x10, 0x0c, 0xfd, 0x8e, 0x3e, 0xad, 0x79, 0xe2,
- 0x01, 0x8a, 0x44, 0x4f, 0x64, 0x3e, 0x96, 0xcf, 0xf6, 0xda, 0xeb, 0xbf,
- 0xbf, 0xec, 0xf1, 0x00, 0xc9, 0x0f, 0x10, 0x0c, 0xd9, 0x67, 0x27, 0xc9,
- 0xb4, 0x89, 0xbf, 0xd9, 0xe2, 0x01, 0x9f, 0x66, 0xae, 0x96, 0x9e, 0x20,
- 0x19, 0xf9, 0x07, 0xd7, 0xd5, 0xcf, 0x10, 0x0c, 0x32, 0x24, 0x44, 0x93,
- 0x46, 0x91, 0xcb, 0x20, 0x36, 0xa1, 0xb2, 0xe2, 0x07, 0xd8, 0x76, 0x43,
- 0x85, 0xdd, 0x93, 0xde, 0x56, 0xc6, 0xa3, 0xc2, 0xea, 0x84, 0xaf, 0x88,
- 0x60, 0x4e, 0xcc, 0x03, 0x44, 0x02, 0xb4, 0x5f, 0x4f, 0x79, 0x77, 0x7c,
- 0xa8, 0xe9, 0xff, 0x9e, 0x34, 0x1b, 0x4e, 0xfb, 0xf5, 0xc3, 0xa6, 0xed,
- 0x8a, 0x97, 0x92, 0xa7, 0x6d, 0xac, 0x3a, 0x6e, 0x38, 0x2a, 0x10, 0xf7,
- 0x3a, 0xe2, 0xce, 0x09, 0x70, 0x39, 0x39, 0x49, 0x72, 0x96, 0x78, 0x31,
- 0x63, 0x2c, 0x21, 0xe4, 0xa1, 0x49, 0x71, 0x43, 0x8c, 0x2b, 0xee, 0x1c,
- 0x73, 0xf9, 0x35, 0xe1, 0xd3, 0xa6, 0xb9, 0xd3, 0xf7, 0xdc, 0x7b, 0x7e,
- 0xc3, 0xa7, 0xfc, 0xfb, 0xf4, 0x1a, 0x53, 0x7f, 0xc9, 0xd3, 0xff, 0x7f,
- 0x79, 0x4f, 0x6f, 0xf7, 0xe1, 0x47, 0x4f, 0xde, 0x38, 0xfa, 0x56, 0xca,
- 0x9e, 0x73, 0x78, 0xe1, 0xd3, 0xea, 0x71, 0xed, 0x69, 0xd3, 0xd4, 0x2c,
- 0xf2, 0xa3, 0xe7, 0xd4, 0x24, 0x6e, 0xc5, 0x10, 0xc9, 0xc0, 0x51, 0x7a,
- 0x20, 0xed, 0x1b, 0x21, 0x33, 0x3c, 0x83, 0xab, 0x9d, 0x3b, 0xd7, 0x72,
- 0xe7, 0x4f, 0xfd, 0xda, 0xa8, 0x36, 0x9c, 0xef, 0xdf, 0x27, 0x4f, 0xee,
- 0x5a, 0xdb, 0xd5, 0xba, 0x3a, 0x7f, 0x9b, 0x48, 0x09, 0xcb, 0x68, 0xe9,
- 0xb5, 0x7a, 0x3e, 0xbf, 0x9a, 0xcf, 0xe7, 0xd5, 0xfc, 0x5f, 0x54, 0x74,
- 0x32, 0x66, 0xc8, 0x45, 0x90, 0xb3, 0xf4, 0xb6, 0x7d, 0x8e, 0xb9, 0xe5,
- 0x8e, 0x9a, 0xf7, 0x3a, 0x77, 0x1c, 0x70, 0x74, 0xdd, 0xe1, 0x4b, 0x2f,
- 0xe3, 0xe7, 0xb5, 0x73, 0x59, 0xff, 0x55, 0xc7, 0x3c, 0xb8, 0x28, 0xe1,
- 0xd3, 0xb3, 0xba, 0x2a, 0x1e, 0x98, 0x02, 0xa1, 0x09, 0xb2, 0x2e, 0xa3,
- 0xf9, 0xfd, 0xa1, 0xab, 0x7b, 0xf0, 0xf3, 0xa7, 0xf8, 0x69, 0xd5, 0x2f,
- 0x8e, 0x38, 0x2a, 0x72, 0xb3, 0x47, 0x46, 0xcf, 0x5d, 0xd1, 0xe4, 0xfa,
- 0x9c, 0x7b, 0x3c, 0xe8, 0x64, 0xc7, 0x91, 0x1b, 0x21, 0x1b, 0xa2, 0x49,
- 0xf9, 0xdc, 0x4f, 0xb7, 0xc4, 0xe9, 0xff, 0xd5, 0xce, 0x2a, 0xad, 0x7d,
- 0x77, 0x5c, 0x9d, 0x36, 0xf0, 0xe9, 0x9c, 0xb9, 0xd3, 0xea, 0x74, 0x83,
- 0xcd, 0x1a, 0xcf, 0x02, 0xb1, 0xd1, 0x16, 0xeb, 0x77, 0x9e, 0xe6, 0xb7,
- 0x87, 0x4f, 0xfc, 0xd4, 0x2f, 0xdd, 0x08, 0xb7, 0x07, 0x49, 0x3e, 0x88,
- 0x61, 0x25, 0xd1, 0x0c, 0x58, 0xdc, 0x40, 0x3e, 0x3d, 0x7e, 0x65, 0x18,
- 0xf9, 0x2f, 0x08, 0x58, 0x21, 0x0f, 0xe9, 0x6e, 0xca, 0x68, 0xdc, 0x77,
- 0x1d, 0xa6, 0x0c, 0x6a, 0xda, 0x94, 0xbf, 0xea, 0x03, 0xa8, 0xdb, 0x67,
- 0xfa, 0xbe, 0x2d, 0xa7, 0xd6, 0xce, 0x9f, 0x87, 0xba, 0xe7, 0x1e, 0x74,
- 0xfb, 0x1f, 0xd3, 0x94, 0x3a, 0x7d, 0xe1, 0xc7, 0xb7, 0x5c, 0xa8, 0x64,
- 0x5d, 0x51, 0xb6, 0xcb, 0x7c, 0x14, 0xcf, 0xfd, 0xe4, 0x7d, 0xcf, 0x15,
- 0x74, 0x61, 0x3a, 0x77, 0x52, 0x72, 0x74, 0x7c, 0xf9, 0x14, 0x8b, 0x2f,
- 0x06, 0x88, 0x16, 0x5a, 0x35, 0x02, 0x92, 0x4d, 0x1b, 0xce, 0x07, 0xe7,
- 0xfc, 0x9d, 0x5b, 0x4f, 0x0b, 0xef, 0xb6, 0x2a, 0x7f, 0xff, 0x6d, 0xbf,
- 0xdd, 0x3a, 0x4b, 0xde, 0x84, 0x30, 0x7b, 0x3a, 0x7f, 0xeb, 0xe5, 0xbd,
- 0x14, 0xd4, 0x3a, 0xea, 0x3a, 0x36, 0x8a, 0x8d, 0x30, 0x43, 0x26, 0x1e,
- 0x90, 0xec, 0x9f, 0xff, 0xef, 0xd9, 0x48, 0xe6, 0x63, 0xee, 0xca, 0xe7,
- 0x6c, 0x20, 0x74, 0xeb, 0x05, 0xe7, 0x43, 0x2a, 0x3c, 0x52, 0xf6, 0xe3,
- 0x36, 0xc2, 0x7f, 0x59, 0x67, 0xf3, 0xdc, 0xa1, 0xcd, 0xd1, 0xd3, 0xff,
- 0xbe, 0x03, 0x4e, 0x86, 0x9b, 0xed, 0x73, 0xa7, 0xf6, 0x39, 0xba, 0x55,
- 0x5c, 0xe8, 0xa3, 0xf9, 0x74, 0x8f, 0x3f, 0x27, 0x9d, 0x55, 0x28, 0xe9,
- 0xf5, 0x72, 0x9f, 0xb9, 0xd3, 0xff, 0xd7, 0xd5, 0xa0, 0x9b, 0xe8, 0xed,
- 0x5b, 0x45, 0x1d, 0x26, 0xb0, 0xfe, 0xf8, 0x27, 0x84, 0x47, 0xa6, 0xc8,
- 0xf5, 0x0a, 0x89, 0xff, 0x0a, 0x78, 0xb6, 0x9d, 0x5a, 0xde, 0x0e, 0x9d,
- 0xce, 0x7c, 0xe9, 0xf7, 0x78, 0x34, 0xec, 0x74, 0x31, 0xe2, 0xfa, 0x39,
- 0x39, 0x56, 0xb8, 0x74, 0xff, 0xca, 0xba, 0x9b, 0x96, 0xff, 0xad, 0xd9,
- 0xd0, 0xc7, 0xc8, 0x83, 0xd0, 0xca, 0xc0, 0x5f, 0x1c, 0xf5, 0x1a, 0x5e,
- 0x11, 0x3a, 0x84, 0x34, 0xff, 0xe7, 0xa6, 0xe9, 0xc4, 0x73, 0xd7, 0x6f,
- 0x6e, 0x74, 0xf9, 0xac, 0x67, 0x66, 0x3a, 0x7e, 0xf7, 0xc6, 0xea, 0xdb,
- 0x9d, 0x3f, 0xff, 0xfe, 0xfb, 0x68, 0x70, 0x12, 0xee, 0x27, 0xc1, 0xaf,
- 0xa6, 0xb5, 0xbc, 0x55, 0xce, 0x9f, 0xff, 0xff, 0xf5, 0xef, 0x5a, 0xde,
- 0x2a, 0xff, 0xfa, 0x5b, 0xac, 0xcf, 0x35, 0x4e, 0x7b, 0xa6, 0xe2, 0xd6,
- 0x3a, 0x19, 0x31, 0xfc, 0x84, 0x0c, 0xf7, 0x79, 0x6d, 0xce, 0x9b, 0x8e,
- 0x0e, 0x8b, 0x9b, 0xbe, 0x08, 0xe7, 0xc9, 0xbc, 0xad, 0x94, 0xb3, 0x45,
- 0x16, 0xaa, 0x82, 0xda, 0x83, 0xb8, 0x52, 0x31, 0xa8, 0x5e, 0x10, 0x93,
- 0xb8, 0xe3, 0x82, 0xa7, 0x9f, 0xaa, 0x02, 0x96, 0x5f, 0xcf, 0xab, 0x94,
- 0xee, 0xe7, 0xbb, 0xfa, 0x59, 0xf3, 0xe4, 0x12, 0xf9, 0xbf, 0x73, 0xa7,
- 0x3a, 0x60, 0x3a, 0x18, 0xd9, 0x20, 0xb4, 0xfc, 0x36, 0xdd, 0xca, 0xd1,
- 0xd3, 0xff, 0xc3, 0xa7, 0x2b, 0xf5, 0x8a, 0x6d, 0xa7, 0x27, 0x4f, 0xac,
- 0xeb, 0xa5, 0x5a, 0x74, 0xf9, 0x2e, 0xd6, 0x28, 0xf6, 0x7e, 0xcf, 0x9b,
- 0x3f, 0xdf, 0xa7, 0xb3, 0xf6, 0x6c, 0x79, 0xec, 0xfd, 0x9e, 0xf5, 0xf5,
- 0x73, 0xd9, 0xfb, 0x1c, 0x9e, 0x88, 0x91, 0x4f, 0x9a, 0xaf, 0x42, 0x7b,
- 0x3f, 0x60, 0xf6, 0x7e, 0xcd, 0x9a, 0x3d, 0x9f, 0xaa, 0x2d, 0xe4, 0xf1,
- 0x3f, 0x9f, 0x52, 0x27, 0xab, 0xa9, 0x3b, 0x3d, 0x9f, 0xb0, 0x7b, 0x3f,
- 0x66, 0xed, 0x8f, 0x67, 0xec, 0xff, 0x57, 0x79, 0xfa, 0x75, 0x5c, 0x9e,
- 0xcf, 0xd9, 0xfa, 0xb6, 0x97, 0xf6, 0xc3, 0xd9, 0xfb, 0x1d, 0xa2, 0x94,
- 0x48, 0xee, 0x8f, 0x3d, 0xfb, 0x1b, 0x47, 0xb3, 0xf6, 0x0f, 0x67, 0xed,
- 0x1a, 0xf9, 0xb8, 0xe0, 0xf6, 0x7e, 0xc3, 0xd5, 0x8a, 0x72, 0x69, 0x50,
- 0x86, 0xb6, 0x13, 0x7f, 0x28, 0x51, 0x8d, 0xe1, 0x79, 0xa5, 0xfe, 0x09,
- 0xa7, 0xa9, 0xed, 0xe4, 0xb6, 0x7e, 0x96, 0x89, 0x19, 0xff, 0x50, 0x73,
- 0x5f, 0xe3, 0x36, 0xe1, 0xd3, 0x3e, 0xc2, 0xa2, 0xc4, 0x4c, 0x5a, 0x84,
- 0x27, 0xf1, 0xf5, 0xc9, 0xac, 0x9c, 0x69, 0x9f, 0xff, 0x3f, 0xec, 0xeb,
- 0x1c, 0x6e, 0x76, 0xca, 0xc7, 0x0e, 0x9f, 0xce, 0xd9, 0x74, 0xbb, 0x94,
- 0x74, 0x5a, 0x88, 0xdf, 0xac, 0x43, 0x2f, 0x35, 0xbd, 0x62, 0x87, 0xd0,
- 0xbb, 0x27, 0x3a, 0x3d, 0x85, 0xd4, 0xff, 0xbc, 0xb5, 0xa2, 0xdb, 0xdf,
- 0xa0, 0x74, 0xfc, 0x39, 0xe7, 0x78, 0xf3, 0xa7, 0x71, 0xc7, 0x05, 0x4e,
- 0xf0, 0xdd, 0x94, 0xb2, 0xfe, 0x7f, 0xc3, 0x8f, 0xf1, 0xfa, 0x75, 0x9f,
- 0x3a, 0x7f, 0x87, 0x3b, 0xe8, 0xf6, 0xee, 0xd3, 0xa3, 0x94, 0xcd, 0x54,
- 0x81, 0xda, 0x60, 0x96, 0xe9, 0x02, 0x7f, 0xc2, 0x29, 0xeb, 0xb9, 0x7e,
- 0xa6, 0xd1, 0xd3, 0xb8, 0xe3, 0x82, 0xc4, 0x20, 0x9f, 0x7c, 0x33, 0x00,
- 0xb1, 0x08, 0x16, 0x6b, 0x67, 0x71, 0xc7, 0x05, 0x88, 0x3d, 0x05, 0x88,
- 0x3c, 0xb3, 0x5b, 0x33, 0x2a, 0x91, 0x2e, 0x0d, 0xf3, 0xed, 0x36, 0x99,
- 0x47, 0x4f, 0x0a, 0x37, 0x93, 0xa7, 0x78, 0x6e, 0xce, 0x8b, 0x0d, 0xfa,
- 0x88, 0x67, 0xc0, 0xdb, 0x65, 0x15, 0x3e, 0x1c, 0x11, 0xa2, 0xa6, 0xa0,
- 0x2a, 0x6e, 0x38, 0x2a, 0x28, 0xfd, 0x2e, 0x4b, 0xa2, 0x3e, 0x05, 0x27,
- 0xf0, 0xf8, 0x6e, 0xf7, 0x4e, 0xc5, 0x2c, 0xde, 0x43, 0x26, 0xfc, 0x8c,
- 0xb9, 0x0d, 0x29, 0xff, 0x9b, 0xbb, 0xd5, 0x73, 0x83, 0x9e, 0x4e, 0x9f,
- 0xff, 0x5a, 0xfb, 0xf0, 0xdf, 0xdb, 0x26, 0xd8, 0x50, 0xe8, 0xda, 0x26,
- 0x31, 0x12, 0x7f, 0x5f, 0xc2, 0xaf, 0xc6, 0x5a, 0x74, 0x32, 0xe1, 0x1d,
- 0x26, 0x24, 0x61, 0x3f, 0x8e, 0xab, 0x21, 0x97, 0x72, 0x29, 0xdc, 0x71,
- 0xc1, 0x53, 0xdd, 0xe0, 0xf2, 0x52, 0xcb, 0xf9, 0xfb, 0xc5, 0x7e, 0xa9,
- 0xc3, 0xa1, 0xe7, 0xbf, 0x73, 0x19, 0xff, 0xe1, 0xb7, 0xa5, 0xbd, 0xb0,
- 0x86, 0x58, 0x38, 0x74, 0xff, 0xff, 0xff, 0x6a, 0xfe, 0x2f, 0xd3, 0x78,
- 0x9a, 0x4d, 0x82, 0x74, 0x7a, 0x6f, 0x07, 0x4f, 0xaf, 0xd1, 0xd3, 0xff,
- 0xd4, 0xcb, 0xe4, 0x5b, 0xd0, 0xaf, 0x29, 0xf3, 0xa7, 0x9d, 0xb7, 0xdb,
- 0xa3, 0xa1, 0xe7, 0xef, 0x89, 0xf3, 0xff, 0x9f, 0x5f, 0xed, 0x49, 0x7f,
- 0x17, 0x6a, 0x3a, 0x79, 0x39, 0xa5, 0x1d, 0x0c, 0xa8, 0x35, 0xe4, 0x54,
- 0xa3, 0x91, 0x86, 0x89, 0x0f, 0xa9, 0x73, 0xf7, 0x5e, 0xe8, 0x36, 0xbc,
- 0xe9, 0xff, 0x67, 0xfa, 0x93, 0x75, 0x96, 0xf6, 0x74, 0xff, 0xaf, 0x76,
- 0xfe, 0x99, 0x7c, 0xa1, 0xd3, 0xfe, 0x1c, 0x73, 0x79, 0xff, 0xa7, 0x27,
- 0x45, 0x23, 0xb8, 0x0c, 0x51, 0x05, 0x47, 0xd3, 0xcf, 0xf1, 0x4e, 0x1d,
- 0x3e, 0xff, 0x35, 0x42, 0x74, 0xff, 0xdd, 0x74, 0xad, 0xb3, 0xab, 0xed,
- 0xad, 0x3a, 0x30, 0xfb, 0xee, 0x4d, 0x3f, 0xd4, 0x3f, 0xab, 0xd2, 0x6c,
- 0xe9, 0xff, 0xea, 0xd5, 0xe9, 0xcd, 0xb3, 0xaa, 0xde, 0xd8, 0xe9, 0xea,
- 0xd2, 0x5c, 0xe9, 0xf9, 0xdd, 0x38, 0x2e, 0xf5, 0x9e, 0x9d, 0x17, 0x3d,
- 0xbd, 0x10, 0x47, 0x29, 0x91, 0x81, 0x08, 0x9a, 0xea, 0x15, 0x73, 0xff,
- 0xc9, 0x7a, 0xe7, 0x57, 0x4f, 0x3b, 0xc1, 0x43, 0xa7, 0xff, 0xf0, 0xea,
- 0xb6, 0x8d, 0xa4, 0xed, 0x9e, 0xbe, 0x38, 0xe0, 0xa9, 0xee, 0x6a, 0xbc,
- 0x95, 0x3d, 0x9d, 0xe6, 0x8e, 0x9c, 0xf1, 0xf4, 0xd1, 0x0c, 0xce, 0xe3,
- 0x8e, 0x0a, 0x9d, 0x42, 0x05, 0x2c, 0xbf, 0x9f, 0xf5, 0x59, 0x5c, 0xe3,
- 0xc5, 0xac, 0x3a, 0x3b, 0x3e, 0x61, 0x28, 0x9f, 0xcf, 0x1a, 0xd6, 0xbd,
- 0xb0, 0xe8, 0x64, 0xea, 0xac, 0x62, 0xe4, 0x8e, 0xd2, 0x1f, 0xc2, 0xbb,
- 0x08, 0xa7, 0x93, 0x48, 0xc7, 0x4f, 0xef, 0x6b, 0xfd, 0xf6, 0x82, 0x74,
- 0xff, 0xf3, 0xd3, 0x9d, 0xf8, 0xbd, 0x7c, 0x33, 0x00, 0xd1, 0x06, 0x4f,
- 0xfe, 0xfe, 0x3a, 0xa1, 0x0d, 0xa7, 0x7e, 0x34, 0x74, 0x32, 0x2a, 0x3d,
- 0x5c, 0x8d, 0xa3, 0xff, 0x50, 0xdc, 0x9b, 0x7e, 0x9d, 0x3d, 0xf4, 0xe3,
- 0xae, 0x74, 0x21, 0xbd, 0xb8, 0xbc, 0xfe, 0xea, 0xab, 0xf5, 0x57, 0xd8,
- 0xe8, 0x7a, 0x7b, 0x49, 0x18, 0xf5, 0xd9, 0x74, 0x41, 0x3f, 0xfc, 0xc3,
- 0x67, 0x47, 0x10, 0x6b, 0x9a, 0x1f, 0x27, 0x4e, 0x6f, 0xb8, 0x74, 0x32,
- 0xf8, 0xa7, 0x27, 0x55, 0x1d, 0xb0, 0x21, 0x24, 0x7f, 0x39, 0x28, 0xe3,
- 0xd4, 0x3e, 0xa5, 0x29, 0xf6, 0x2b, 0x2a, 0xe7, 0x4f, 0xff, 0x03, 0x5e,
- 0xec, 0xaa, 0xd2, 0x5f, 0x78, 0x74, 0xfe, 0x11, 0x67, 0xa9, 0x90, 0xe9,
- 0xfd, 0xa4, 0x74, 0x9a, 0x7b, 0x15, 0x25, 0x1d, 0x3f, 0x50, 0xf9, 0xfb,
- 0x2d, 0x0f, 0x0f, 0xc1, 0x9c, 0x52, 0x60, 0x88, 0x99, 0x77, 0x29, 0xef,
- 0xfb, 0x6b, 0xce, 0x9f, 0xc2, 0xf1, 0xa5, 0x30, 0x1d, 0x39, 0x5c, 0xd1,
- 0xd0, 0xc7, 0xdf, 0x44, 0x98, 0x5f, 0x3b, 0x49, 0x61, 0xd3, 0xfe, 0xf7,
- 0x57, 0xf1, 0xfe, 0xd4, 0x97, 0x3a, 0x7f, 0x5d, 0xac, 0xa1, 0x4f, 0x27,
- 0x4f, 0xfc, 0xc3, 0x9b, 0x6e, 0xd7, 0xfb, 0xdc, 0xa8, 0xe5, 0x17, 0x34,
- 0x86, 0xa3, 0x39, 0xf6, 0xd1, 0x2d, 0xb9, 0xd3, 0xff, 0xea, 0xe7, 0xa6,
- 0x25, 0x5d, 0xac, 0xa1, 0x4f, 0x27, 0x41, 0x53, 0xf5, 0xfc, 0x37, 0xd9,
- 0x45, 0x41, 0x50, 0x54, 0x15, 0x05, 0x43, 0xcf, 0x81, 0x02, 0xbb, 0x2e,
- 0xf4, 0x2b, 0xa8, 0x29, 0xd8, 0x2a, 0x6d, 0xd1, 0x53, 0xf6, 0x66, 0x9c,
- 0x65, 0x15, 0xd0, 0xb5, 0x93, 0xb8, 0x54, 0x15, 0x05, 0x43, 0xcb, 0x44,
- 0x0a, 0x82, 0xa0, 0xa8, 0x2a, 0x0a, 0x82, 0xa0, 0xa8, 0xb0, 0xde, 0x72,
- 0x14, 0x81, 0x5d, 0x85, 0x5c, 0x29, 0xd0, 0x54, 0x15, 0x05, 0x43, 0xcb,
- 0x4b, 0x85, 0x41, 0x50, 0x54, 0x15, 0x05, 0x43, 0xcd, 0x47, 0x61, 0x5a,
- 0x0a, 0x76, 0x0a, 0x82, 0xa0, 0xa8, 0x2a, 0x0a, 0x8b, 0x0d, 0x47, 0x90,
- 0xaf, 0x85, 0x6c, 0x2a, 0x5e, 0x4a, 0x82, 0xa0, 0xa8, 0x2a, 0x0a, 0x8e,
- 0x4d, 0x45, 0xa1, 0x5d, 0x85, 0x7a, 0x15, 0x05, 0x41, 0x50, 0x54, 0xfb,
- 0x6d, 0xdd, 0xe8, 0xa8, 0x2a, 0x1e, 0x79, 0xe0, 0x15, 0xb0, 0xac, 0x0a,
- 0xec, 0x9e, 0x40, 0x54, 0x15, 0x05, 0x41, 0x50, 0x54, 0x3c, 0xd4, 0x5a,
- 0x14, 0x81, 0x4e, 0x82, 0xa0, 0xa8, 0x2a, 0x0a, 0x82, 0xa1, 0xe6, 0xa3,
- 0x90, 0xad, 0x85, 0x08, 0x54, 0xb6, 0x54, 0x15, 0x05, 0x49, 0xe5, 0x41,
- 0x56, 0x96, 0x10, 0x54, 0x15, 0x05, 0x41, 0x51, 0x61, 0xf3, 0x3c, 0x2b,
- 0xc8, 0xd0, 0x0d, 0x38, 0x15, 0xd8, 0x56, 0x82, 0xa5, 0x45, 0x41, 0x50,
- 0x54, 0x9e, 0x54, 0x15, 0x69, 0x61, 0x05, 0x41, 0x50, 0xc7, 0xa4, 0xf0,
- 0xa4, 0x1a, 0xf8, 0xd2, 0x82, 0xa0, 0xa8, 0x2a, 0x0a, 0x82, 0xa0, 0xa8,
- 0x63, 0x65, 0x68, 0x57, 0xc2, 0x94, 0x14, 0x21, 0x50, 0x54, 0x15, 0x05,
- 0x47, 0xcb, 0xeb, 0x85, 0x68, 0x2a, 0x0a, 0x82, 0xa0, 0xa8, 0x51, 0x7c,
- 0x21, 0x5a, 0x0a, 0x92, 0x8a, 0x82, 0xa0, 0xa8, 0xec, 0xb4, 0xf4, 0x2a,
- 0x0a, 0x82, 0xa0, 0xa8, 0x2a, 0x18, 0xd4, 0x38, 0x15, 0xb0, 0xaf, 0x42,
- 0xa1, 0x97, 0xec, 0x6c, 0x72, 0x79, 0xef, 0x25, 0x34, 0xb6, 0x0d, 0xb6,
- 0xa4, 0x23, 0x3f, 0x5c, 0xf9, 0xc3, 0xaf, 0xc2, 0x39, 0x49, 0x1b, 0x37,
- 0xc6, 0x5e, 0xce, 0xc5, 0xda, 0xec, 0xfa, 0x61, 0xf5, 0xe5, 0xd3, 0x2f,
- 0x09, 0x7d, 0x45, 0x9e, 0x09, 0x1d, 0x92, 0xa7, 0xcf, 0x16, 0xab, 0x94,
- 0xb4, 0xd6, 0x27, 0x23, 0x28, 0xa9, 0xe4, 0x0c, 0xf9, 0xd3, 0x93, 0x9a,
- 0x3a, 0x73, 0x78, 0x5d, 0xa8, 0x8c, 0xf9, 0xc6, 0xc6, 0xb4, 0x3f, 0x3f,
- 0xb6, 0x9c, 0x73, 0xf6, 0xb0, 0xe8, 0xb5, 0x10, 0xce, 0x28, 0xcd, 0xdb,
- 0x1d, 0x3f, 0x7f, 0x07, 0xc3, 0x76, 0x74, 0xd9, 0xf3, 0xa4, 0x87, 0x01,
- 0x6b, 0x20, 0x3a, 0x4a, 0x3a, 0x6e, 0xa5, 0xa2, 0x25, 0x7e, 0x2d, 0xb4,
- 0x3c, 0x1d, 0xf0, 0x1f, 0x3f, 0xdb, 0x65, 0x53, 0x8c, 0x36, 0x1d, 0x14,
- 0x89, 0x1e, 0xd6, 0x67, 0xe5, 0x27, 0x56, 0x0f, 0x67, 0x4f, 0xff, 0x37,
- 0x4c, 0xff, 0xf3, 0xb6, 0x5f, 0x1c, 0x70, 0x74, 0x32, 0x20, 0xfd, 0x2f,
- 0x8b, 0x1b, 0x00, 0x47, 0xc6, 0x53, 0xcc, 0x27, 0x80, 0xb1, 0x21, 0xaa,
- 0xe1, 0x82, 0x89, 0xf2, 0x95, 0xa2, 0x31, 0xa5, 0xea, 0x14, 0xd3, 0xf9,
- 0x87, 0x58, 0x3e, 0xd1, 0xd3, 0xf3, 0xc5, 0x1f, 0xba, 0x3a, 0x7d, 0x62,
- 0x7d, 0x9e, 0x74, 0x7c, 0xf4, 0x84, 0xae, 0x7f, 0xdb, 0x6f, 0xf6, 0x35,
- 0xc6, 0x76, 0x74, 0xea, 0xa7, 0x0e, 0x95, 0x6c, 0xf6, 0xbb, 0x3f, 0x9f,
- 0xbd, 0xff, 0xaa, 0xc1, 0x3a, 0x79, 0x4d, 0x56, 0x1d, 0x3e, 0xa7, 0x42,
- 0xd6, 0x9d, 0x08, 0x79, 0x37, 0x21, 0x9e, 0x61, 0xd0, 0x1d, 0x26, 0xa4,
- 0xd6, 0x85, 0xee, 0xe5, 0x1a, 0x77, 0xea, 0x21, 0x9e, 0xf7, 0x3e, 0xf3,
- 0xa7, 0x9b, 0xd7, 0x72, 0xe5, 0x4f, 0x9e, 0xbe, 0x38, 0xe0, 0xe8, 0x13,
- 0xd2, 0xf4, 0x9e, 0x39, 0x44, 0xb5, 0x3a, 0x42, 0x95, 0x73, 0x77, 0x1e,
- 0xe7, 0xb0, 0xe7, 0x9f, 0xbf, 0xef, 0x74, 0x20, 0x74, 0xff, 0x58, 0x34,
- 0xfd, 0xd7, 0x77, 0x3a, 0x7b, 0x9e, 0x59, 0xd1, 0xd3, 0xff, 0xdb, 0x65,
- 0x03, 0x6a, 0xbe, 0x19, 0x80, 0x68, 0xbe, 0x27, 0x67, 0xec, 0x34, 0x5f,
- 0xf0, 0xc8, 0x80, 0x05, 0x79, 0xfd, 0xc6, 0x6a, 0xed, 0x56, 0x1d, 0x3f,
- 0xf3, 0xad, 0x79, 0x61, 0x7d, 0x6d, 0x14, 0x74, 0xfd, 0x5c, 0x78, 0xde,
- 0x68, 0xe9, 0xff, 0xf6, 0xbc, 0x3d, 0x9d, 0x20, 0xf7, 0xf4, 0x65, 0x51,
- 0x53, 0xdb, 0xf1, 0x6e, 0x8e, 0x8b, 0x11, 0x57, 0x45, 0xe0, 0xaf, 0x36,
- 0xa8, 0xe9, 0xf7, 0xd2, 0xcc, 0x51, 0xa6, 0x13, 0x9e, 0xd7, 0xad, 0x86,
- 0x98, 0x4e, 0x6e, 0xd8, 0xd4, 0x09, 0xcf, 0xe1, 0xcf, 0x3a, 0x6f, 0xf6,
- 0x6a, 0x04, 0xe7, 0xf5, 0xeb, 0x69, 0x7f, 0x6c, 0x34, 0xc2, 0x73, 0x57,
- 0x26, 0x98, 0x4e, 0x6e, 0x38, 0x3c, 0xc2, 0x71, 0x49, 0xa7, 0xda, 0x68,
- 0x85, 0xca, 0x23, 0xba, 0x0b, 0xa4, 0x1e, 0x08, 0xe5, 0xa2, 0xcc, 0x26,
- 0x59, 0xf3, 0xc9, 0x2d, 0x4f, 0xeb, 0x88, 0xf2, 0xe3, 0x15, 0xa5, 0xde,
- 0x1e, 0x3a, 0x94, 0x53, 0x38, 0x7b, 0x51, 0xd3, 0xfc, 0xde, 0xe8, 0x51,
- 0xd7, 0x85, 0x1d, 0x38, 0x6a, 0xf4, 0x7b, 0x1f, 0x1c, 0x86, 0x5d, 0x43,
- 0xe4, 0xe4, 0x21, 0x4b, 0xb2, 0x1d, 0x4b, 0x7e, 0x75, 0x09, 0x59, 0xf7,
- 0x35, 0xf4, 0xf2, 0x74, 0xf8, 0x6b, 0xc5, 0x38, 0x74, 0xff, 0x6f, 0x15,
- 0xb4, 0x6b, 0x5e, 0x74, 0xfd, 0xe0, 0x5f, 0xd5, 0x96, 0x1d, 0x08, 0x7d,
- 0x5d, 0x9c, 0x40, 0xa2, 0xd3, 0x50, 0x92, 0x9f, 0xf5, 0x66, 0xdc, 0x41,
- 0xdd, 0x5a, 0x74, 0x32, 0xf8, 0xed, 0x4e, 0xb8, 0x23, 0x66, 0x43, 0x74,
- 0x49, 0xe7, 0xff, 0x2b, 0x57, 0x41, 0xb5, 0xfa, 0x4b, 0xa1, 0xd3, 0xff,
- 0xf8, 0x6a, 0xda, 0xbe, 0x0e, 0xd1, 0xb5, 0xbf, 0x71, 0x47, 0x4f, 0xc3,
- 0xea, 0x93, 0x6c, 0x74, 0xff, 0xfb, 0x07, 0x59, 0x9b, 0x16, 0xd5, 0xf8,
- 0xad, 0x9d, 0x3f, 0xeb, 0x30, 0x6f, 0xad, 0xa3, 0x5c, 0xe9, 0xdf, 0xbd,
- 0xcf, 0x10, 0x1c, 0xff, 0xef, 0xb6, 0xdb, 0xa5, 0x7c, 0x33, 0x00, 0xd1,
- 0x01, 0xac, 0xd4, 0xc6, 0x23, 0x2b, 0xc3, 0x34, 0x76, 0x9a, 0x06, 0xa3,
- 0x1c, 0x8a, 0x4e, 0x5d, 0x23, 0x6c, 0x9e, 0x1d, 0x77, 0xe9, 0xd3, 0xff,
- 0xf3, 0xea, 0xe9, 0xff, 0xa2, 0xbc, 0x6b, 0x75, 0xc6, 0x8e, 0x8a, 0x44,
- 0x06, 0x11, 0xcf, 0xff, 0xf6, 0x3e, 0x85, 0xc7, 0xd5, 0xaf, 0xf0, 0xdd,
- 0xaf, 0x8e, 0x38, 0x2a, 0x36, 0x88, 0xe1, 0x21, 0x9f, 0xcd, 0x5f, 0x0c,
- 0xc0, 0x34, 0x41, 0x33, 0xfc, 0xda, 0xaf, 0x86, 0x60, 0x1a, 0x2f, 0x99,
- 0xf2, 0x3a, 0x1a, 0xbf, 0x27, 0xf8, 0x07, 0x73, 0xfb, 0xdd, 0xf5, 0x6d,
- 0x03, 0x67, 0x4f, 0xfa, 0xcc, 0xb7, 0xaa, 0xb4, 0x38, 0xe8, 0xe9, 0xdc,
- 0x71, 0xc1, 0x53, 0xed, 0xd0, 0x67, 0xca, 0x59, 0x7f, 0x3f, 0xff, 0x9c,
- 0xfb, 0x3a, 0xe9, 0xe7, 0x3a, 0x78, 0x72, 0xfd, 0x2a, 0xdd, 0x1d, 0x1a,
- 0x45, 0x27, 0x83, 0x48, 0xb1, 0x32, 0xb1, 0x8c, 0x1a, 0x7f, 0xeb, 0x14,
- 0xd6, 0xdc, 0x6a, 0xcf, 0x0f, 0x3a, 0x7f, 0xfb, 0xc5, 0xa3, 0xd0, 0x36,
- 0x9d, 0xf6, 0xdf, 0x79, 0xd3, 0xfe, 0xf6, 0xed, 0x43, 0xa7, 0x7f, 0x80,
- 0x3a, 0x77, 0x1c, 0x70, 0x54, 0xfe, 0xf1, 0xdb, 0x0d, 0x5b, 0xa2, 0x96,
- 0x5f, 0xcf, 0xff, 0xce, 0xe7, 0x40, 0xda, 0x73, 0xcd, 0x71, 0xd3, 0x57,
- 0xab, 0x0e, 0x96, 0x6d, 0x15, 0x7e, 0xa2, 0x43, 0xd5, 0xce, 0xf2, 0x7e,
- 0x91, 0xb0, 0xfc, 0xa9, 0x49, 0x02, 0xab, 0xa8, 0xc3, 0x67, 0xdb, 0xad,
- 0x38, 0xf3, 0xa7, 0xfd, 0x5a, 0x6f, 0xdf, 0x6c, 0x3a, 0x3c, 0x41, 0x13,
- 0xf9, 0xab, 0xe1, 0x98, 0x06, 0x88, 0x21, 0x67, 0x93, 0x3f, 0x66, 0xff,
- 0xf4, 0xe0, 0xe9, 0xfb, 0xaf, 0xcf, 0x18, 0x2f, 0x3a, 0x04, 0xf7, 0xfd,
- 0x2d, 0x8d, 0xa6, 0x7d, 0xdb, 0x88, 0xc2, 0xae, 0x7f, 0x98, 0x75, 0xe2,
- 0xb7, 0x96, 0x9d, 0x3f, 0xfd, 0x9c, 0x6a, 0xb6, 0xc9, 0xa1, 0xad, 0xa1,
- 0xd0, 0xf4, 0x42, 0x89, 0xcc, 0xff, 0x6d, 0xbf, 0xa1, 0x6a, 0xb4, 0xe9,
- 0xff, 0xfe, 0x4b, 0x19, 0xf7, 0xff, 0xd2, 0xd7, 0x1f, 0x9f, 0x55, 0x5a,
- 0x74, 0xf6, 0xb7, 0x43, 0xca, 0x28, 0x36, 0x6f, 0x3f, 0x78, 0x55, 0xf8,
- 0xcb, 0x4e, 0x86, 0x3e, 0xbd, 0x1d, 0x4f, 0x23, 0x89, 0xc1, 0xd3, 0xff,
- 0xef, 0x6c, 0x16, 0xad, 0xad, 0xb5, 0x5b, 0xf7, 0xe7, 0x4f, 0xab, 0x57,
- 0xf1, 0x7e, 0x4f, 0xe3, 0xc1, 0x14, 0xfc, 0x1b, 0x4e, 0xa4, 0xf2, 0x74,
- 0xfc, 0xa6, 0xeb, 0xee, 0xac, 0x3a, 0x7f, 0xff, 0xf9, 0x35, 0x8a, 0xc1,
- 0xed, 0xe9, 0x7f, 0x55, 0xb4, 0x6d, 0x6f, 0xdc, 0x51, 0xd1, 0xca, 0x37,
- 0x90, 0xc3, 0x0c, 0x67, 0xe1, 0xee, 0x94, 0xdb, 0x3a, 0x77, 0xfc, 0x5c,
- 0xe9, 0xff, 0x60, 0x85, 0x7c, 0x33, 0x00, 0xd1, 0x08, 0xc3, 0x1f, 0x1f,
- 0xa3, 0xd3, 0xff, 0x9a, 0xad, 0xf1, 0xa4, 0x1f, 0x5f, 0x57, 0x3a, 0x7f,
- 0xfb, 0x32, 0xcf, 0x15, 0xbc, 0x52, 0xf8, 0xe3, 0x83, 0xa3, 0x94, 0x4f,
- 0xb8, 0x97, 0x3f, 0xdc, 0xb5, 0xee, 0xd6, 0x57, 0x07, 0x45, 0x1e, 0xfe,
- 0x12, 0xce, 0xe3, 0x8e, 0x0a, 0x9f, 0xea, 0xef, 0x3f, 0x4e, 0xab, 0x92,
- 0x96, 0x5f, 0xcd, 0xc7, 0x05, 0x4e, 0xe3, 0x8e, 0x0a, 0x9f, 0xb2, 0xce,
- 0x76, 0xd7, 0x29, 0x65, 0xfc, 0x0a, 0x2f, 0x78, 0x49, 0xea, 0x37, 0x9f,
- 0x02, 0x73, 0xe1, 0x45, 0x2c, 0xd9, 0xce, 0xe3, 0x8e, 0x0a, 0x9d, 0x76,
- 0xf9, 0x4b, 0x2f, 0xe5, 0xda, 0x22, 0x0b, 0x4b, 0x13, 0xf7, 0x22, 0xcf,
- 0xc0, 0x3a, 0x7f, 0x78, 0xff, 0x28, 0xe9, 0xb9, 0x3a, 0x7f, 0xed, 0xe3,
- 0xc7, 0x3c, 0xb8, 0x28, 0xe1, 0xd3, 0xf6, 0xe9, 0xd5, 0x6a, 0xe7, 0x40,
- 0x1f, 0x9e, 0x91, 0x63, 0xe8, 0xf7, 0xd9, 0x58, 0xc2, 0xae, 0x19, 0x35,
- 0x4a, 0x8c, 0x82, 0x75, 0xbd, 0x6b, 0xbb, 0xa3, 0xa7, 0xff, 0x57, 0x5f,
- 0x07, 0xba, 0x06, 0xdb, 0x28, 0xe9, 0xf8, 0x12, 0xfb, 0x47, 0x0a, 0x9f,
- 0xc3, 0x56, 0xbe, 0xe9, 0xe4, 0xe9, 0xec, 0xcf, 0xf9, 0x3a, 0x3a, 0x1e,
- 0xb5, 0x86, 0x93, 0xcd, 0x8a, 0x74, 0x54, 0xee, 0x38, 0xe0, 0xa9, 0xff,
- 0xef, 0x0d, 0xdd, 0x50, 0xeb, 0x68, 0xc3, 0x61, 0x4b, 0x2f, 0xe5, 0x40,
- 0x89, 0xf5, 0x20, 0xc3, 0x27, 0xc6, 0xf2, 0xcb, 0x52, 0x92, 0x10, 0x5b,
- 0x86, 0x24, 0xff, 0xf9, 0x54, 0x0c, 0x39, 0xab, 0xf3, 0xee, 0x7d, 0xe7,
- 0x4f, 0x9b, 0x57, 0x75, 0x47, 0x43, 0x1f, 0xe6, 0x95, 0x27, 0xff, 0x91,
- 0xd5, 0x0f, 0x23, 0x9c, 0x50, 0xe7, 0x93, 0xa7, 0xff, 0xfb, 0x9d, 0xa7,
- 0x14, 0xec, 0x8a, 0xcd, 0x5f, 0xd7, 0xd5, 0xba, 0x3a, 0x29, 0x17, 0x98,
- 0xa1, 0x0c, 0xda, 0xde, 0xd8, 0x92, 0xf8, 0xfd, 0x79, 0x8c, 0xda, 0xa7,
- 0x0e, 0xd2, 0x3a, 0xf7, 0x21, 0x77, 0xf8, 0xcb, 0x55, 0x09, 0x9d, 0xc6,
- 0x45, 0x85, 0xfd, 0xc2, 0x3c, 0x63, 0x20, 0xbc, 0xb0, 0x5d, 0x4a, 0x0b,
- 0xf6, 0x1a, 0x1c, 0x43, 0x76, 0x73, 0xa6, 0x13, 0xa7, 0xff, 0xa8, 0x57,
- 0xaf, 0x29, 0x6d, 0xf7, 0x5d, 0xe1, 0xd2, 0xb5, 0xe7, 0xdb, 0xc8, 0xe4,
- 0xfd, 0xb7, 0x13, 0x68, 0xa3, 0xa7, 0xfc, 0x2d, 0xad, 0xe7, 0x79, 0x6d,
- 0xce, 0x9c, 0xe7, 0xbf, 0x3a, 0x7f, 0xd8, 0x9f, 0xab, 0x57, 0xc7, 0x1c,
- 0x1d, 0x18, 0x7b, 0xf7, 0x1e, 0x9f, 0xfe, 0x16, 0x7f, 0x4f, 0x1a, 0x41,
- 0xf5, 0xf5, 0x73, 0xa2, 0x93, 0x3d, 0x02, 0xdd, 0xc2, 0x77, 0xb2, 0x19,
- 0xfc, 0xc2, 0xf1, 0xaa, 0xec, 0xe9, 0xfc, 0xfa, 0xfd, 0xc5, 0xac, 0x3a,
- 0x7f, 0xfa, 0xb4, 0xc2, 0x15, 0xad, 0xa7, 0xfb, 0x03, 0xa7, 0xf3, 0x2a,
- 0xf7, 0xc1, 0xb0, 0xe9, 0xf6, 0x5e, 0x87, 0x47, 0x4e, 0xd6, 0x75, 0xce,
- 0x9f, 0xda, 0xda, 0x2f, 0xbc, 0x43, 0xa3, 0x94, 0x7a, 0x6d, 0x30, 0x4c,
- 0xb4, 0x4b, 0xe8, 0xfc, 0xfe, 0xf7, 0xb6, 0xda, 0x63, 0xce, 0x9f, 0xe0,
- 0xad, 0x33, 0xa4, 0x1e, 0xce, 0x9f, 0xff, 0xbd, 0x6d, 0x5e, 0x87, 0xa7,
- 0xd9, 0x39, 0x1c, 0x79, 0xd0, 0x88, 0x93, 0x13, 0x89, 0xff, 0xf8, 0x6a,
- 0xfe, 0xf4, 0xad, 0xe0, 0xd3, 0x8f, 0x6b, 0x4e, 0x9f, 0xf5, 0x5f, 0xda,
- 0xf8, 0x66, 0x01, 0xa2, 0x06, 0x9e, 0xd6, 0xf1, 0xfd, 0x11, 0x48, 0x2b,
- 0x90, 0xc9, 0x80, 0x54, 0x31, 0x67, 0xfd, 0x9f, 0xa1, 0xee, 0xfa, 0xbd,
- 0xa7, 0x4f, 0xff, 0xff, 0xd5, 0xad, 0xe0, 0xf9, 0xe9, 0x7f, 0xe6, 0x69,
- 0xd5, 0x73, 0xd2, 0x95, 0x83, 0x6b, 0xcf, 0x10, 0x5c, 0xff, 0xb3, 0x3c,
- 0x86, 0x73, 0xd3, 0xcf, 0x07, 0x88, 0x2e, 0x7f, 0xed, 0xa6, 0xd1, 0x87,
- 0x5d, 0x3c, 0xf0, 0x78, 0x82, 0xe7, 0xf3, 0x20, 0xeb, 0xa7, 0x9e, 0x0f,
- 0x10, 0x5c, 0xfc, 0xaa, 0xe7, 0xa7, 0x9e, 0x0f, 0x10, 0x5c, 0xff, 0xff,
- 0x60, 0x8a, 0x2b, 0xa5, 0xc3, 0x69, 0xf4, 0xf3, 0x65, 0x70, 0x78, 0x82,
- 0xe6, 0xb7, 0xa7, 0x29, 0xce, 0x82, 0x8f, 0xd5, 0x31, 0x0c, 0x50, 0x21,
- 0x95, 0x68, 0x6c, 0xfc, 0x65, 0x1c, 0xcf, 0xe4, 0x6f, 0x37, 0xd5, 0xed,
- 0x3a, 0x7b, 0x3f, 0xde, 0x1d, 0x3f, 0xf6, 0xd3, 0x68, 0xc3, 0xae, 0x9e,
- 0x78, 0x3c, 0x41, 0x73, 0xfc, 0xe5, 0xc1, 0x2c, 0xe9, 0xe7, 0x83, 0xc4,
- 0x17, 0x3e, 0xd5, 0xd9, 0x5d, 0x01, 0x14, 0x1e, 0x15, 0x27, 0xff, 0x74,
- 0x0d, 0xa0, 0x36, 0xaf, 0xd3, 0xcf, 0x07, 0x88, 0x2e, 0x7f, 0xff, 0xe1,
- 0x14, 0x57, 0x4f, 0x6b, 0xa5, 0xc3, 0x69, 0xf4, 0xf3, 0x65, 0x70, 0x78,
- 0x82, 0xe2, 0x93, 0x23, 0xb5, 0x0f, 0x17, 0x27, 0xfb, 0x69, 0xf4, 0xf3,
- 0x65, 0x70, 0x78, 0x82, 0xe7, 0xff, 0xb3, 0x2d, 0x7d, 0xf6, 0x9c, 0xf2,
- 0xdf, 0x62, 0xa7, 0xfd, 0x4f, 0x7f, 0xb7, 0xf8, 0xd9, 0xd4, 0x78, 0x82,
- 0xe0, 0x11, 0xd1, 0xf4, 0x8b, 0xa8, 0x4f, 0xf8, 0x13, 0xfa, 0xce, 0xef,
- 0xd3, 0x83, 0xc4, 0x17, 0x3f, 0x6d, 0x37, 0xb4, 0xec, 0xd0, 0x05, 0xcf,
- 0xab, 0xbe, 0x9e, 0x78, 0x3c, 0x41, 0x73, 0x56, 0x80, 0xfd, 0x36, 0x75,
- 0x16, 0xa3, 0xba, 0xf0, 0xc2, 0x9f, 0x95, 0x5c, 0xf4, 0xf3, 0xc1, 0xe2,
- 0x0b, 0x9f, 0xf0, 0x6d, 0x3e, 0x9e, 0x6c, 0xae, 0x0f, 0x10, 0x5c, 0xd5,
- 0xd3, 0x11, 0x1b, 0x74, 0x09, 0xfd, 0xea, 0x2b, 0x06, 0xd7, 0x9e, 0x20,
- 0xb9, 0xff, 0x52, 0x3a, 0xa1, 0xae, 0x71, 0xe7, 0x88, 0x2d, 0x47, 0x81,
- 0x1c, 0xaf, 0x02, 0xfc, 0xdf, 0xb3, 0x51, 0x8f, 0x92, 0xf1, 0x8c, 0x6a,
- 0x31, 0xdf, 0x61, 0x6d, 0xc3, 0x7c, 0xfb, 0xbb, 0xf7, 0xdb, 0x1a, 0x20,
- 0xb5, 0xa2, 0x3a, 0x7f, 0xd4, 0xfd, 0xe3, 0xdd, 0x9d, 0xbd, 0xb0, 0xe9,
- 0xca, 0x67, 0x9d, 0x3e, 0xae, 0x77, 0xef, 0x07, 0x4b, 0xf8, 0x78, 0xa2,
- 0x37, 0x39, 0x3a, 0xa8, 0xe9, 0xd9, 0xfe, 0xce, 0x95, 0xac, 0x6e, 0x74,
- 0x3b, 0x3f, 0x55, 0x99, 0xb6, 0xeb, 0x9d, 0x08, 0x8b, 0x6c, 0x5f, 0x12,
- 0x79, 0xd9, 0xfb, 0x0e, 0x9b, 0xb6, 0x3a, 0x79, 0x19, 0x54, 0x74, 0x1d,
- 0x3f, 0x67, 0x9d, 0x37, 0xfb, 0x3a, 0x39, 0x37, 0x22, 0x15, 0x3f, 0xff,
- 0x99, 0x39, 0x16, 0xf4, 0x35, 0x41, 0xcb, 0x07, 0x85, 0x1d, 0x37, 0x6c,
- 0x74, 0xcd, 0xe4, 0xe9, 0xfe, 0xad, 0x5d, 0x95, 0xe2, 0x9c, 0x3a, 0x7f,
- 0x5e, 0xb6, 0x97, 0xf6, 0xc3, 0xa6, 0xe3, 0x82, 0xa7, 0xf8, 0x69, 0xd6,
- 0x3e, 0xe9, 0xc9, 0xd0, 0x09, 0xfb, 0xa0, 0xe7, 0xc5, 0x94, 0xb1, 0xb2,
- 0x1e, 0xd8, 0x1d, 0xc1, 0x61, 0x17, 0xb9, 0xd7, 0x06, 0x9e, 0x06, 0x27,
- 0x71, 0xc7, 0x05, 0x49, 0x45, 0x2c, 0xbf, 0x9f, 0x63, 0x99, 0x9f, 0x29,
- 0x68, 0xdd, 0xf1, 0x0b, 0xe9, 0xfd, 0x6e, 0x9a, 0xb7, 0x56, 0x1d, 0x0c,
- 0xd9, 0xd2, 0x54, 0x6c, 0xfe, 0x50, 0xad, 0x30, 0x48, 0xc9, 0xbe, 0x97,
- 0xb8, 0xf1, 0xb2, 0x93, 0x14, 0x29, 0x37, 0x8d, 0x07, 0xd9, 0x60, 0x2e,
- 0x93, 0x27, 0xa8, 0x1b, 0x47, 0x4f, 0x52, 0xab, 0x47, 0x4f, 0xfd, 0xbf,
- 0x6c, 0xf5, 0x7b, 0x40, 0xcf, 0x9d, 0x3d, 0x96, 0x78, 0x79, 0xd0, 0xc8,
- 0xa9, 0xb4, 0x7f, 0x44, 0x0e, 0xc8, 0xd3, 0xf0, 0xfb, 0xca, 0xb1, 0xe7,
- 0x4f, 0xff, 0x5a, 0xf1, 0x6e, 0x8a, 0x16, 0xf3, 0xa4, 0xb0, 0xe9, 0xfd,
- 0x7d, 0x3a, 0xa1, 0xae, 0x4e, 0x86, 0x45, 0xaa, 0x17, 0x62, 0x9c, 0xec,
- 0xe9, 0xe0, 0xe9, 0xff, 0xe1, 0x7f, 0x4a, 0xe5, 0x2f, 0x6e, 0xbd, 0xcb,
- 0x9d, 0x3e, 0xe9, 0xb6, 0xfb, 0xce, 0x8e, 0x88, 0x9b, 0xa1, 0xfe, 0x14,
- 0xe7, 0xeb, 0x1c, 0x7f, 0x59, 0xfb, 0x0e, 0x99, 0xf6, 0x1d, 0x3e, 0xdd,
- 0x23, 0xee, 0x74, 0xff, 0xf6, 0xdb, 0xc2, 0xf4, 0x39, 0xdd, 0xee, 0xdd,
- 0x95, 0x3f, 0xbb, 0xaf, 0x86, 0x60, 0x1e, 0x20, 0x49, 0xda, 0x4b, 0x0e,
- 0x87, 0xa3, 0x47, 0x92, 0x6f, 0xa9, 0x28, 0xf6, 0x67, 0x67, 0x9d, 0x3d,
- 0xab, 0x30, 0x4e, 0x9e, 0xb6, 0xf9, 0xa3, 0xa2, 0xc3, 0xdc, 0xa1, 0x9d,
- 0x90, 0xcf, 0xe1, 0xce, 0x2f, 0x76, 0xec, 0xe9, 0xdc, 0x71, 0xc1, 0xea,
- 0xfa, 0x9d, 0x83, 0xc9, 0x6a, 0xfa, 0x2c, 0xd6, 0x47, 0x28, 0x98, 0xed,
- 0x7e, 0x7f, 0xfd, 0x42, 0x9e, 0x57, 0x7d, 0x6f, 0xdc, 0x7b, 0xd8, 0xe8,
- 0xb0, 0xfe, 0xfc, 0x92, 0xcf, 0xb0, 0x45, 0x14, 0x74, 0x75, 0xb5, 0x68,
- 0x6f, 0x36, 0xa8, 0x74, 0x24, 0x26, 0xb2, 0x34, 0x21, 0x25, 0x9f, 0x26,
- 0x9b, 0x57, 0x2a, 0x78, 0x1b, 0x57, 0x2a, 0x6e, 0x38, 0x2a, 0x1e, 0x7b,
- 0xd4, 0x4d, 0xc1, 0x04, 0xd5, 0xc1, 0x4b, 0x35, 0xf3, 0xff, 0xea, 0xd3,
- 0x05, 0x50, 0xeb, 0x68, 0xc3, 0x61, 0xd1, 0xd9, 0xfb, 0x70, 0x4d, 0x3f,
- 0xff, 0x99, 0xd2, 0x0f, 0x7d, 0x35, 0x7a, 0x0d, 0xe0, 0xea, 0xe7, 0x4f,
- 0xd6, 0xbf, 0x7e, 0xb7, 0xce, 0x9f, 0xf5, 0x53, 0x9f, 0xaf, 0x54, 0xd7,
- 0x3a, 0x1c, 0x3e, 0xdf, 0x97, 0xce, 0x7e, 0x7c, 0xe9, 0xf3, 0xeb, 0x55,
- 0xc9, 0x52, 0x47, 0x0f, 0x0b, 0x43, 0x73, 0xda, 0xf3, 0x5b, 0x3a, 0x6e,
- 0xd8, 0xe9, 0xbb, 0x63, 0xa7, 0xde, 0xbe, 0x85, 0x68, 0x6b, 0x3b, 0x16,
- 0x86, 0x44, 0x68, 0xa7, 0xcf, 0xfd, 0xad, 0xd2, 0xbc, 0x37, 0x75, 0x6e,
- 0x8e, 0x9f, 0xd6, 0x82, 0x7f, 0xc3, 0x72, 0x74, 0xf7, 0x6a, 0xc7, 0xdc,
- 0xff, 0x34, 0x8f, 0x3b, 0xaa, 0xad, 0x3a, 0x7b, 0xbf, 0xa7, 0xce, 0x86,
- 0x3f, 0xbc, 0x3a, 0xe0, 0x7e, 0x7a, 0xfe, 0xdb, 0xa3, 0xa7, 0x71, 0xc7,
- 0x05, 0x4f, 0xab, 0xc8, 0xfb, 0x72, 0x96, 0x5f, 0xcf, 0xa9, 0x7c, 0x71,
- 0xc1, 0xd0, 0xc7, 0xc5, 0xa3, 0x89, 0xff, 0xa8, 0x6a, 0xe1, 0xb4, 0x06,
- 0x13, 0xa7, 0xb8, 0xc1, 0x79, 0xd3, 0xfd, 0xa6, 0xb7, 0xbc, 0xde, 0xd0,
- 0xe9, 0x6c, 0xe8, 0xa3, 0xc9, 0x03, 0x99, 0xdc, 0x71, 0xc1, 0x53, 0xf2,
- 0x67, 0x9d, 0xa6, 0x8a, 0x59, 0x7f, 0x3e, 0xae, 0xea, 0x9c, 0x3a, 0x57,
- 0xe8, 0x8a, 0x2f, 0x9f, 0x89, 0xe4, 0xde, 0xbf, 0x94, 0xd0, 0xea, 0x30,
- 0xc9, 0x26, 0xd3, 0xb8, 0x18, 0xe0, 0x61, 0x97, 0x7f, 0xde, 0x49, 0x50,
- 0xcf, 0xf2, 0xcb, 0xf8, 0x5a, 0xee, 0x31, 0x8c, 0x2e, 0xbc, 0x29, 0x75,
- 0x1e, 0xcc, 0xfc, 0xca, 0xff, 0xf3, 0x47, 0x4f, 0xff, 0x22, 0xad, 0x7d,
- 0xfa, 0x50, 0x8d, 0x27, 0x67, 0x46, 0xcf, 0xf3, 0x45, 0x92, 0x5b, 0xbd,
- 0x09, 0xf8, 0x77, 0x76, 0x53, 0xd6, 0xa4, 0x1e, 0xb4, 0x2a, 0x69, 0xca,
- 0xab, 0x25, 0x02, 0xbe, 0x55, 0x5f, 0x32, 0xd2, 0xaa, 0xb9, 0x01, 0xf3,
- 0x1d, 0xb8, 0x4a, 0xdd, 0xb6, 0x5a, 0x92, 0x4a, 0xdc, 0x72, 0x7d, 0x2b,
- 0xf3, 0xb7, 0x8a, 0x95, 0xe5, 0xba, 0x42, 0xf6, 0x56, 0x11, 0x7d, 0xcb,
- 0x99, 0x19, 0xf5, 0xcb, 0xd6, 0xc2, 0x5a, 0xad, 0x54, 0x3d, 0x8d, 0xf1,
- 0xd4, 0x3d, 0x78, 0x86, 0x47, 0x54, 0xb7, 0x5f, 0x13, 0xed, 0xae, 0xd1,
- 0x8b, 0xc2, 0xe1, 0x44, 0xf0, 0xfc, 0x50, 0x0d, 0x4f, 0xe5, 0xd7, 0xc3,
- 0x30, 0x0d, 0x17, 0x1c, 0xfe, 0x5d, 0x7c, 0x33, 0x00, 0xd1, 0x75, 0xcf,
- 0xfc, 0xbc, 0x7a, 0xeb, 0xe1, 0x98, 0x06, 0x89, 0x46, 0x1a, 0x14, 0xba,
- 0xef, 0x28, 0xe4, 0xf3, 0xc9, 0xe0, 0x1e, 0x24, 0x3d, 0x3a, 0xe7, 0xf9,
- 0x8a, 0x2c, 0xbb, 0x9c, 0x68, 0xf1, 0xd8, 0xf2, 0x7f, 0xf2, 0xd5, 0x8f,
- 0x5d, 0x7c, 0x33, 0x00, 0xd1, 0x2d, 0x4f, 0xbe, 0x19, 0x80, 0x68, 0x8d,
- 0xe7, 0xfd, 0x8f, 0x5d, 0x7c, 0x33, 0x00, 0xd1, 0x2f, 0xc9, 0x74, 0x7f,
- 0x0a, 0x31, 0x9f, 0xcb, 0xaf, 0x86, 0x60, 0x1a, 0x2a, 0xb9, 0xfe, 0xf3,
- 0x43, 0x56, 0xeb, 0x14, 0x74, 0xdc, 0xa1, 0xd3, 0xf5, 0x7c, 0x33, 0x00,
- 0xd1, 0x20, 0x47, 0x43, 0xcc, 0x58, 0xb4, 0xfa, 0xf8, 0x39, 0x69, 0xd0,
- 0xf3, 0xca, 0xb4, 0x92, 0x7f, 0xf5, 0x39, 0xbc, 0x56, 0xb6, 0xda, 0xf5,
- 0x47, 0x47, 0x94, 0xcf, 0x72, 0x19, 0xfe, 0x08, 0xe7, 0xfe, 0x1a, 0xb1,
- 0x7d, 0x4c, 0x23, 0x5a, 0x3a, 0x16, 0x7f, 0xbf, 0x39, 0x9f, 0xcb, 0xaf,
- 0x86, 0x60, 0x1a, 0x2c, 0x89, 0xfc, 0xba, 0xf8, 0x66, 0x01, 0xa2, 0xd7,
- 0x9f, 0xcb, 0xaf, 0x86, 0x60, 0x1a, 0x2e, 0x49, 0xf7, 0xc3, 0x30, 0x0d,
- 0x17, 0x64, 0xff, 0xb1, 0xeb, 0xaf, 0x86, 0x60, 0x1a, 0x28, 0xe9, 0x2e,
- 0x8f, 0xe1, 0x46, 0x32, 0x79, 0xd3, 0xef, 0x86, 0x60, 0x1a, 0x29, 0x59,
- 0xff, 0xff, 0xed, 0xb5, 0x8d, 0xb4, 0x75, 0x9c, 0xed, 0x16, 0x1b, 0x47,
- 0x36, 0xd6, 0x51, 0xd3, 0x3d, 0x74, 0x8b, 0x07, 0x0c, 0x66, 0x5a, 0xad,
- 0x47, 0x7e, 0x43, 0x02, 0x2c, 0x5d, 0x80, 0x7c, 0x32, 0xed, 0x27, 0x48,
- 0xfd, 0x94, 0x45, 0xd9, 0xe5, 0xcf, 0x35, 0x0b, 0x47, 0x51, 0x8b, 0x4f,
- 0xf3, 0xd7, 0x5f, 0x0c, 0xc0, 0x34, 0x47, 0x13, 0xfc, 0x8b, 0xaf, 0x86,
- 0x60, 0x1a, 0x2b, 0x59, 0x2f, 0x11, 0x07, 0xa4, 0x29, 0xff, 0xcb, 0x56,
- 0x3d, 0x75, 0xf0, 0xcc, 0x03, 0x44, 0xb7, 0x35, 0x5a, 0x74, 0xfe, 0xe6,
- 0x94, 0xa6, 0x4b, 0x9d, 0x16, 0x9e, 0x42, 0x0b, 0x4e, 0xdf, 0x2f, 0x3a,
- 0x73, 0xd4, 0x07, 0x4f, 0xff, 0xdb, 0xcb, 0x7b, 0xe7, 0x78, 0xfa, 0xb8,
- 0xfb, 0x9e, 0x0e, 0x83, 0x44, 0x37, 0x3f, 0xec, 0x7a, 0xeb, 0xe1, 0x98,
- 0x06, 0x89, 0x82, 0x60, 0xa3, 0xa6, 0xf7, 0xb2, 0xa1, 0x0d, 0x67, 0xc5,
- 0x27, 0xf0, 0xd6, 0xb4, 0xdf, 0xb9, 0xd2, 0x5b, 0x27, 0x29, 0x61, 0x17,
- 0x23, 0xb4, 0x36, 0x0b, 0xea, 0x17, 0xd3, 0x9f, 0x82, 0x09, 0xca, 0xf7,
- 0xe5, 0x4f, 0xfb, 0x1e, 0xba, 0xf8, 0x66, 0x01, 0xa2, 0x63, 0x92, 0xd0,
- 0xf9, 0x14, 0x3b, 0x3f, 0x35, 0xfa, 0x6a, 0xb6, 0x74, 0xe6, 0x1b, 0x0e,
- 0x9f, 0xff, 0xfe, 0x7d, 0xf7, 0x5e, 0xf1, 0x7d, 0xd0, 0x55, 0xfa, 0x55,
- 0xaf, 0xba, 0x0a, 0x1d, 0x3c, 0x19, 0x80, 0x68, 0xac, 0x67, 0xfd, 0xd5,
- 0x5a, 0x1a, 0xf5, 0x87, 0x47, 0x47, 0x94, 0xcc, 0x80, 0xba, 0xd1, 0xbf,
- 0xbf, 0xe8, 0xae, 0x7f, 0xf3, 0x0e, 0xbc, 0xfa, 0xc3, 0x40, 0xdf, 0x3a,
- 0x7f, 0xb9, 0xdd, 0x5e, 0xd7, 0xb6, 0xce, 0x9f, 0xe6, 0xb5, 0xee, 0x3f,
- 0x3f, 0x61, 0xd1, 0x47, 0xea, 0x87, 0x53, 0xfe, 0xae, 0x7e, 0x9e, 0xd9,
- 0xdd, 0xde, 0x74, 0xff, 0xff, 0xc3, 0xed, 0x94, 0x1d, 0x07, 0xd7, 0x6e,
- 0x95, 0x6b, 0xeb, 0xd1, 0xee, 0xe7, 0x4f, 0xee, 0xb7, 0x63, 0x8f, 0xeb,
- 0x3f, 0x61, 0xd3, 0xff, 0xa9, 0xcd, 0xe2, 0xb5, 0xb6, 0xd7, 0xaa, 0x3a,
- 0x76, 0xd1, 0x74, 0xa9, 0xd4, 0x13, 0x77, 0x0b, 0xd1, 0x20, 0xd2, 0x17,
- 0x53, 0xe7, 0x84, 0x29, 0xbc, 0x76, 0x74, 0xde, 0xb8, 0x74, 0xfb, 0x06,
- 0xcf, 0x6e, 0x74, 0x76, 0x7b, 0x22, 0x33, 0x71, 0x89, 0xf7, 0xb6, 0xd8,
- 0xde, 0x4e, 0x9f, 0x2a, 0x85, 0x9e, 0x74, 0xf3, 0x7f, 0x04, 0xe9, 0xeb,
- 0xdd, 0xbb, 0x3a, 0x18, 0xf9, 0xb6, 0x4b, 0xc0, 0xfc, 0xf9, 0x9f, 0xdf,
- 0xaf, 0x3a, 0x73, 0x0b, 0xce, 0x87, 0x0f, 0x0f, 0x45, 0x33, 0xb7, 0xe1,
- 0x47, 0x4f, 0xcc, 0xaa, 0x14, 0xf2, 0x74, 0xae, 0x74, 0x21, 0xbc, 0xc2,
- 0xc9, 0xbb, 0x62, 0xa6, 0xe3, 0x82, 0xa1, 0x0d, 0x77, 0x02, 0xd3, 0xfb,
- 0x1e, 0x35, 0xad, 0xa1, 0x4b, 0x34, 0x33, 0xdc, 0xe5, 0xb7, 0x3a, 0x73,
- 0x0b, 0x87, 0x4c, 0x2c, 0x74, 0x38, 0x6b, 0xfe, 0x37, 0x3f, 0xf7, 0x94,
- 0x10, 0xbb, 0x2b, 0x2d, 0xd1, 0xd3, 0xbb, 0xa7, 0x63, 0xa3, 0xc9, 0xf1,
- 0xfd, 0x12, 0x5e, 0x4e, 0x9b, 0xfe, 0x4e, 0x84, 0x35, 0x5e, 0x04, 0xa7,
- 0xff, 0x93, 0x4c, 0xf4, 0xd6, 0xea, 0xdd, 0x7a, 0xc7, 0x43, 0x27, 0x2d,
- 0x4a, 0x49, 0x08, 0x5d, 0xa7, 0x61, 0x14, 0x1d, 0x25, 0x1d, 0x2d, 0xe8,
- 0xba, 0x74, 0x15, 0x3f, 0x76, 0xdb, 0xa7, 0x58, 0x74, 0xfc, 0x9a, 0xad,
- 0xe7, 0x93, 0xa7, 0x71, 0xc7, 0x05, 0x4f, 0xfd, 0x41, 0xcb, 0x59, 0xe2,
- 0xb7, 0x96, 0x94, 0xb2, 0xfe, 0x79, 0x3e, 0xed, 0xc9, 0xd2, 0xf9, 0xd3,
- 0xe5, 0x26, 0xbb, 0xc3, 0xa2, 0xc3, 0xdc, 0xeb, 0x92, 0xfa, 0x21, 0x3f,
- 0x81, 0x2e, 0x34, 0xeb, 0x0e, 0x9a, 0xb4, 0x74, 0x5a, 0x78, 0xdb, 0x31,
- 0x9e, 0xd0, 0xd3, 0xce, 0x9f, 0xfc, 0x97, 0xdd, 0x72, 0x34, 0xe8, 0x6a,
- 0xe7, 0x47, 0xcf, 0xa7, 0x44, 0x12, 0x5b, 0x2f, 0x6b, 0x58, 0x5f, 0xcc,
- 0x24, 0xa9, 0xc9, 0x08, 0xfe, 0xb4, 0xa6, 0xed, 0xc7, 0xad, 0x8c, 0xdd,
- 0x94, 0x3b, 0x85, 0xc2, 0x99, 0x78, 0x58, 0xe9, 0xef, 0xc4, 0x23, 0x27,
- 0xdf, 0x0c, 0xc0, 0x34, 0x56, 0xf3, 0xfe, 0xc7, 0xae, 0xbe, 0x19, 0x80,
- 0x68, 0x9c, 0x24, 0xba, 0x3f, 0x85, 0x18, 0xcd, 0xee, 0xce, 0x9f, 0x7c,
- 0x33, 0x00, 0xd1, 0x68, 0xcf, 0xcd, 0x83, 0xef, 0x34, 0x74, 0xc9, 0xe4,
- 0xe9, 0xff, 0xf5, 0x8d, 0xa6, 0xe7, 0xed, 0xbc, 0xb8, 0xd7, 0x67, 0x4f,
- 0xf9, 0xad, 0xce, 0xbe, 0xc7, 0x3a, 0xf6, 0x1d, 0x0c, 0x89, 0xbd, 0xaa,
- 0xca, 0x9c, 0x46, 0xa5, 0xe1, 0x65, 0x25, 0xbb, 0xc9, 0xbb, 0x50, 0xba,
- 0x8c, 0x77, 0x18, 0x04, 0xf0, 0x66, 0x01, 0xa2, 0xda, 0x9f, 0xb6, 0xca,
- 0x64, 0xe4, 0xe9, 0x57, 0xcf, 0x5f, 0x45, 0x73, 0xfc, 0xbf, 0x3e, 0x73,
- 0xfc, 0xfa, 0x27, 0x42, 0xcf, 0x97, 0xb2, 0x79, 0xfc, 0xba, 0xf8, 0x66,
- 0x01, 0xa2, 0xe5, 0x9f, 0xcb, 0xaf, 0x86, 0x60, 0x1a, 0x2e, 0xd8, 0x66,
- 0xcd, 0x62, 0xc2, 0x87, 0xca, 0x2f, 0xe6, 0x1b, 0xbe, 0x65, 0xe7, 0x24,
- 0xfd, 0x6f, 0x5e, 0x36, 0x7d, 0xc7, 0x3a, 0x31, 0x85, 0x5c, 0x8f, 0x47,
- 0x93, 0xf9, 0x75, 0xf0, 0xcc, 0x03, 0x45, 0x4f, 0x32, 0x68, 0xe9, 0xe0,
- 0xcc, 0x03, 0x45, 0x73, 0x3f, 0x97, 0x5f, 0x0c, 0xc0, 0x34, 0x59, 0xd1,
- 0xf3, 0xe7, 0xd9, 0x5c, 0xff, 0xf5, 0x69, 0xaf, 0xd3, 0xdb, 0xe9, 0x9c,
- 0x71, 0x0e, 0x9f, 0xf6, 0xd3, 0xfc, 0xee, 0x90, 0x7c, 0x9d, 0x3e, 0xf8,
- 0x66, 0x01, 0xa2, 0x42, 0x9f, 0xe4, 0xb6, 0xfa, 0x16, 0x55, 0xce, 0x99,
- 0xeb, 0xa3, 0xe9, 0xec, 0xc6, 0x79, 0xde, 0xdb, 0x28, 0xe9, 0xfd, 0x5b,
- 0xbd, 0xeb, 0xf6, 0x1d, 0x25, 0xf2, 0xa8, 0x82, 0x9f, 0x10, 0x89, 0xc5,
- 0x3c, 0x85, 0x45, 0xcb, 0xb4, 0x4d, 0x3f, 0xf9, 0x6a, 0xc7, 0xae, 0xbe,
- 0x19, 0x80, 0x68, 0x9f, 0x20, 0x15, 0x8f, 0xf5, 0xe5, 0x2e, 0x6d, 0xc2,
- 0x7d, 0xf0, 0xcc, 0x03, 0x45, 0x65, 0x3f, 0xec, 0x7a, 0xeb, 0xe1, 0x98,
- 0x06, 0x89, 0xba, 0x64, 0x5d, 0x1f, 0xc2, 0x8c, 0x67, 0xdf, 0x0c, 0xc0,
- 0x34, 0x4a, 0xd3, 0xfd, 0xe7, 0x69, 0xd3, 0xd0, 0xab, 0x9d, 0x3e, 0x5a,
- 0xb1, 0xeb, 0xa3, 0xed, 0xc3, 0x19, 0xff, 0x25, 0xfd, 0x50, 0xa3, 0xaf,
- 0x70, 0xe9, 0xfc, 0x2d, 0xfa, 0x75, 0x8a, 0x3a, 0x1e, 0x7e, 0x48, 0x81,
- 0x3e, 0xf8, 0x66, 0x01, 0xa2, 0x5c, 0x9f, 0xe4, 0xc7, 0xe8, 0x59, 0x57,
- 0x3a, 0x79, 0xd2, 0x0b, 0x1d, 0x3e, 0x5a, 0xb1, 0xeb, 0x64, 0x54, 0xd1,
- 0x0e, 0xcc, 0x70, 0xda, 0x7f, 0xe5, 0xe3, 0xd7, 0x5f, 0x0c, 0xc0, 0x34,
- 0x47, 0x73, 0xfd, 0xad, 0xd3, 0xd7, 0x83, 0x73, 0xa7, 0xee, 0xb0, 0x58,
- 0x28, 0x4e, 0x9b, 0xdd, 0x9d, 0x3f, 0x3b, 0xe3, 0x5b, 0xcd, 0x1d, 0x3f,
- 0xab, 0x8b, 0xb0, 0xea, 0xe7, 0x4f, 0xbe, 0x19, 0x80, 0x68, 0xa8, 0x67,
- 0xb7, 0xaa, 0xb0, 0xe9, 0xf5, 0x59, 0x82, 0xe8, 0xe9, 0xff, 0xff, 0xfc,
- 0xcf, 0xe9, 0xad, 0xa3, 0x5f, 0xa5, 0x7a, 0x0c, 0xeb, 0xa5, 0x7f, 0xf4,
- 0xeb, 0xdc, 0xd9, 0xd1, 0x48, 0xe1, 0x12, 0x2b, 0x94, 0x4f, 0xff, 0xf7,
- 0xb9, 0xd7, 0x4b, 0x37, 0x89, 0xa6, 0xda, 0x6a, 0xf5, 0xc9, 0xd2, 0x5b,
- 0xbe, 0xa9, 0x45, 0xde, 0x2e, 0xeb, 0x05, 0xec, 0x30, 0xa3, 0x2d, 0x46,
- 0x25, 0xd4, 0x5d, 0x3e, 0xf8, 0x66, 0x01, 0xa2, 0xa8, 0x9f, 0xf6, 0x3d,
- 0x75, 0xf0, 0xcc, 0x03, 0x44, 0xd7, 0x25, 0xd1, 0xfc, 0x28, 0xc6, 0x7f,
- 0x2e, 0xbe, 0x19, 0x80, 0x68, 0xab, 0x27, 0xfe, 0x5e, 0x3d, 0x75, 0xf0,
- 0xcc, 0x03, 0x44, 0x89, 0x3e, 0xf8, 0x66, 0x01, 0xa2, 0xd2, 0x9f, 0xf6,
- 0x3d, 0x75, 0xf0, 0xcc, 0x03, 0x44, 0xfb, 0x25, 0xd1, 0xfc, 0x28, 0xc6,
- 0x7f, 0xf2, 0xd5, 0x8f, 0x5d, 0x7c, 0x33, 0x00, 0xd1, 0x42, 0x4f, 0xb6,
- 0x96, 0x37, 0xce, 0x9f, 0x7c, 0x33, 0x00, 0xd1, 0x47, 0xcf, 0xf8, 0x59,
- 0xc6, 0x16, 0x73, 0x6c, 0x74, 0xff, 0xfd, 0x5c, 0xed, 0xbc, 0x2f, 0x43,
- 0x9d, 0xde, 0xed, 0xd9, 0x53, 0xe5, 0xab, 0x1e, 0xb6, 0x47, 0x95, 0x13,
- 0xe8, 0xc7, 0xa8, 0xf2, 0x19, 0x90, 0xdf, 0x64, 0x6b, 0x0f, 0x57, 0xa4,
- 0xdf, 0x32, 0xa2, 0x02, 0x1f, 0x96, 0x93, 0xb8, 0x79, 0xb8, 0x62, 0xf6,
- 0x4f, 0xa8, 0xd1, 0x67, 0xf2, 0xeb, 0xe1, 0x98, 0x06, 0x88, 0x8a, 0x7e,
- 0xaf, 0x86, 0x60, 0x1a, 0x22, 0xb9, 0xfe, 0xeb, 0xae, 0xbe, 0x19, 0x80,
- 0x68, 0xae, 0x21, 0x67, 0xf9, 0x86, 0xd3, 0xd5, 0xbc, 0xd1, 0xd3, 0xfa,
- 0x93, 0xfd, 0xf7, 0xed, 0xce, 0x93, 0xbe, 0x27, 0xab, 0x72, 0x09, 0xff,
- 0xfb, 0x57, 0x4d, 0xe2, 0x3d, 0x07, 0x5e, 0xef, 0xf4, 0x74, 0xfb, 0xe1,
- 0x98, 0x06, 0x8a, 0x7a, 0x7e, 0xab, 0xf4, 0x1c, 0x79, 0xd1, 0xd6, 0x23,
- 0x8d, 0x8b, 0x29, 0x64, 0x4c, 0x67, 0xff, 0x63, 0xd7, 0xc8, 0xe7, 0x17,
- 0xbb, 0x76, 0x74, 0x2d, 0x11, 0x5c, 0x9f, 0xce, 0x5f, 0x34, 0x74, 0xf9,
- 0x9f, 0xdf, 0xaf, 0x3a, 0x78, 0x33, 0x00, 0xd1, 0x59, 0xc3, 0x87, 0xa9,
- 0xf2, 0x99, 0xfa, 0xc5, 0x30, 0xbe, 0xe7, 0x4e, 0x6b, 0x10, 0xe9, 0xf6,
- 0xbb, 0xf0, 0x2f, 0x3a, 0x77, 0xb9, 0x73, 0xa7, 0xd4, 0xe5, 0x9e, 0xf6,
- 0x74, 0x97, 0x48, 0xdc, 0xf9, 0x1e, 0xcb, 0x70, 0x6c, 0x4a, 0xbc, 0x0e,
- 0x4f, 0xfc, 0xbc, 0x7a, 0xeb, 0xe1, 0x98, 0x06, 0x89, 0x16, 0x7e, 0xaf,
- 0x86, 0x60, 0x1a, 0x2c, 0x99, 0xff, 0xda, 0xbf, 0x8b, 0xae, 0xac, 0x41,
- 0x7d, 0xce, 0x85, 0xa2, 0x0a, 0x8d, 0xa7, 0xf2, 0xeb, 0xe1, 0x98, 0x06,
- 0x8b, 0x62, 0x75, 0x5e, 0x8e, 0x9e, 0x0c, 0xc0, 0x34, 0x5b, 0x73, 0xd7,
- 0xb3, 0x3e, 0x74, 0x7c, 0xf3, 0x74, 0x57, 0x25, 0xbd, 0x11, 0x34, 0xcf,
- 0x3a, 0xcd, 0xa1, 0xd3, 0xfe, 0xeb, 0x3a, 0xc7, 0x77, 0xad, 0xd0, 0xb7,
- 0x67, 0x4f, 0xcc, 0x2f, 0xe7, 0xd5, 0x1d, 0x3e, 0xf8, 0x66, 0x01, 0xa2,
- 0xf0, 0x9e, 0xd7, 0x55, 0x6c, 0xe9, 0xff, 0x9b, 0xc2, 0xad, 0x7e, 0xa8,
- 0x75, 0x73, 0xa7, 0xd4, 0x3d, 0xbb, 0x31, 0xd3, 0xe6, 0xf1, 0xee, 0x5c,
- 0xe9, 0xda, 0x6e, 0xce, 0x92, 0xfa, 0xc4, 0xe8, 0x7a, 0xd4, 0x39, 0x62,
- 0x75, 0x17, 0x5a, 0x63, 0xb2, 0x4e, 0xd1, 0x84, 0xa7, 0x45, 0x33, 0x92,
- 0xad, 0x3a, 0x7d, 0xf0, 0xcc, 0x03, 0x45, 0xe9, 0x3f, 0xe1, 0xcd, 0x3d,
- 0xbc, 0xe9, 0x2c, 0x3a, 0x7d, 0x4a, 0xde, 0x72, 0x74, 0x97, 0xca, 0x2c,
- 0xa8, 0x6f, 0xc1, 0x8b, 0xb1, 0xfc, 0x33, 0x25, 0xce, 0xc8, 0x5c, 0x54,
- 0x7c, 0x60, 0x48, 0x91, 0xa6, 0x7d, 0x71, 0x50, 0xcf, 0xec, 0x88, 0x61,
- 0x8b, 0xec, 0x79, 0x3c, 0x46, 0x8b, 0x37, 0xbb, 0x3a, 0x7a, 0xb7, 0x9a,
- 0x3a, 0x7f, 0x52, 0x7f, 0xbe, 0xfd, 0xb9, 0xd2, 0x77, 0xc4, 0xf5, 0x6e,
- 0x41, 0x3e, 0x4d, 0x35, 0xb6, 0x1d, 0x3e, 0xf8, 0x66, 0x01, 0xa2, 0x23,
- 0x9f, 0xfe, 0xdf, 0xb7, 0xbd, 0x28, 0x69, 0xd7, 0x46, 0x77, 0x47, 0x4f,
- 0xf9, 0xed, 0x67, 0xeb, 0x5a, 0x4d, 0x1d, 0x3f, 0xd5, 0xfa, 0xbd, 0x60,
- 0xd8, 0x74, 0xff, 0xff, 0x36, 0xf1, 0x34, 0xdb, 0x1a, 0xd6, 0xd3, 0x74,
- 0x9c, 0x1d, 0x35, 0x8a, 0x2a, 0x6e, 0x38, 0x2a, 0x7f, 0xcb, 0x0d, 0xa3,
- 0x9b, 0x6b, 0x17, 0xd9, 0xaf, 0xe0, 0x5e, 0x79, 0xd3, 0x69, 0x8e, 0x87,
- 0x9f, 0xd2, 0x2c, 0x4f, 0xdd, 0x71, 0xad, 0xe6, 0x8e, 0x9f, 0x9b, 0xcd,
- 0x0a, 0x79, 0x3a, 0x7e, 0xad, 0x3b, 0x6a, 0xb6, 0x74, 0x52, 0x23, 0x04,
- 0xbe, 0xe5, 0xd3, 0xff, 0xf0, 0x2f, 0xf8, 0x29, 0xa5, 0xfd, 0xb4, 0x39,
- 0xd9, 0xd0, 0xef, 0x2b, 0xfc, 0xeb, 0x1b, 0x18, 0xb2, 0x8a, 0x00, 0xc6,
- 0xd5, 0x94, 0x3e, 0xf9, 0xb6, 0x46, 0x17, 0xa8, 0x56, 0xba, 0x2e, 0x9f,
- 0x7c, 0x33, 0x00, 0xd1, 0x17, 0x4f, 0xb5, 0xdf, 0x81, 0x79, 0x52, 0x5d,
- 0x1e, 0xde, 0x18, 0xc2, 0xd3, 0x2e, 0x7c, 0x61, 0x13, 0xff, 0x2b, 0x1e,
- 0xba, 0xf8, 0x66, 0x01, 0xa2, 0x66, 0x9f, 0xba, 0xd1, 0xdd, 0xbb, 0xf7,
- 0x6d, 0x1d, 0x3a, 0xd6, 0xb9, 0xd3, 0x81, 0x14, 0x74, 0xdd, 0x5d, 0x6c,
- 0xe9, 0xfb, 0x55, 0x65, 0x76, 0xe1, 0xd1, 0xd6, 0xcf, 0x39, 0xc1, 0xf9,
- 0xf0, 0x66, 0xd1, 0xc3, 0xa7, 0xff, 0xdd, 0xda, 0xfd, 0xfa, 0xdf, 0x5e,
- 0xd0, 0x33, 0xe7, 0x4f, 0xfc, 0xec, 0x9a, 0x40, 0x4e, 0x75, 0x40, 0x74,
- 0xff, 0xff, 0x7b, 0x82, 0x03, 0x5c, 0xef, 0xde, 0x9b, 0x67, 0xfd, 0xac,
- 0x3a, 0x19, 0x30, 0x4a, 0x57, 0xda, 0x24, 0xff, 0xfb, 0x94, 0x1b, 0x2a,
- 0xe9, 0x9b, 0x5f, 0x1c, 0x70, 0x54, 0xfd, 0x6b, 0xef, 0xdf, 0xae, 0x1d,
- 0x3c, 0x19, 0x80, 0x68, 0xb3, 0xe7, 0xfc, 0x9b, 0x67, 0xa6, 0x9b, 0x57,
- 0x3a, 0x7f, 0xf9, 0x3f, 0xbc, 0xe9, 0x4e, 0x86, 0xaf, 0x42, 0x74, 0xee,
- 0x38, 0xe0, 0xa9, 0xff, 0x63, 0xee, 0x34, 0x1c, 0xd7, 0xca, 0x59, 0x7f,
- 0x3f, 0xcd, 0xb4, 0xe4, 0x73, 0x1c, 0x3a, 0x7f, 0x90, 0x79, 0xf1, 0xcf,
- 0xba, 0xb9, 0xd0, 0x0a, 0x87, 0x9c, 0x58, 0xf9, 0x92, 0x8a, 0xf6, 0x79,
- 0xdb, 0x76, 0x92, 0xdd, 0x1b, 0xcf, 0xf7, 0xf3, 0x8d, 0xa3, 0x7d, 0x8e,
- 0x9f, 0xff, 0xff, 0xaa, 0xbb, 0xbd, 0x50, 0xf9, 0xf1, 0xf1, 0x6a, 0xda,
- 0xee, 0x35, 0x62, 0xa9, 0x47, 0x4e, 0xbb, 0x58, 0x74, 0xee, 0xaa, 0xd9,
- 0xd0, 0xf4, 0x61, 0xde, 0x11, 0x3a, 0x1c, 0x9d, 0xbf, 0x78, 0x3a, 0x77,
- 0x7e, 0x81, 0xd3, 0xb5, 0x5e, 0x0e, 0x8e, 0x4f, 0x62, 0xd1, 0xe4, 0x1d,
- 0x9f, 0xbe, 0x8e, 0xa8, 0x6e, 0x74, 0xfb, 0x62, 0xd5, 0xf3, 0x27, 0xfc,
- 0x9f, 0x7d, 0x7e, 0xcf, 0x73, 0x93, 0x44, 0x1a, 0xb3, 0x4b, 0x3e, 0xc0,
- 0x45, 0x31, 0xd3, 0xf3, 0xf6, 0x39, 0x6e, 0x8e, 0x95, 0x01, 0xe8, 0x89,
- 0x24, 0xff, 0xd4, 0x36, 0xea, 0xbe, 0x96, 0x62, 0x8e, 0x99, 0x04, 0xe9,
- 0xfb, 0x38, 0xd5, 0x6f, 0x4c, 0x7a, 0xfe, 0x50, 0xe1, 0x93, 0xc2, 0x7a,
- 0x95, 0x42, 0xb8, 0x5f, 0x27, 0xef, 0xd7, 0x37, 0xdb, 0x1d, 0x3f, 0xff,
- 0xbd, 0x1c, 0xf3, 0xd3, 0xc0, 0xe6, 0xae, 0x96, 0xed, 0x38, 0x3a, 0x7f,
- 0xca, 0xad, 0x5f, 0xc5, 0xf1, 0xf4, 0x74, 0xfd, 0x7b, 0xb7, 0xf4, 0xc7,
- 0x2c, 0xdf, 0xcf, 0x6e, 0x91, 0xd1, 0xd3, 0xf5, 0xd3, 0xf5, 0xef, 0xce,
- 0x84, 0x44, 0x5e, 0xcf, 0x34, 0x45, 0x32, 0x9d, 0xf3, 0x45, 0xf9, 0x3f,
- 0xf3, 0xf5, 0xeb, 0xde, 0xad, 0x69, 0x94, 0x74, 0xff, 0xc9, 0x43, 0x55,
- 0x7e, 0x8f, 0xba, 0x8e, 0x8b, 0x51, 0x13, 0x74, 0x69, 0x91, 0xc3, 0xa7,
- 0x69, 0x2c, 0x3a, 0x70, 0xb0, 0x1d, 0x1d, 0x0f, 0x2d, 0x42, 0xc2, 0x39,
- 0x0c, 0x9b, 0xff, 0x25, 0xf5, 0x0b, 0x1c, 0x6f, 0x9f, 0xff, 0xf9, 0xd9,
- 0xb6, 0x8a, 0x5b, 0x8f, 0xcf, 0xf8, 0xda, 0x5b, 0x70, 0x4b, 0x0e, 0x9f,
- 0xb3, 0xed, 0xbf, 0x1c, 0x9d, 0x3d, 0xc6, 0x55, 0xce, 0x9f, 0xe7, 0xab,
- 0x1f, 0xab, 0xb7, 0x93, 0xa1, 0x8f, 0x6f, 0x08, 0x67, 0xaa, 0xe8, 0x27,
- 0x46, 0x23, 0x24, 0x61, 0x15, 0xe9, 0x04, 0xf7, 0x8f, 0x72, 0xe7, 0x4f,
- 0xce, 0xda, 0xac, 0x10, 0x3a, 0x7f, 0xaf, 0xda, 0x5b, 0x6b, 0xeb, 0x47,
- 0x46, 0xcf, 0xa3, 0x45, 0xb0, 0xc8, 0xae, 0xa8, 0x46, 0x4c, 0xe7, 0xa7,
- 0x49, 0x47, 0x45, 0xa6, 0xa1, 0xdc, 0x18, 0x9f, 0xd9, 0x96, 0xbc, 0x5b,
- 0x93, 0xa7, 0xff, 0x0a, 0x35, 0xc7, 0x1f, 0xd2, 0xf5, 0xf3, 0xa7, 0xff,
- 0xfd, 0xb4, 0xb7, 0x55, 0x6e, 0xbf, 0xf6, 0xd7, 0x7e, 0x05, 0xfb, 0xa3,
- 0xa7, 0xb9, 0xe7, 0x04, 0xe9, 0xff, 0x66, 0xc1, 0x33, 0xa5, 0xf3, 0x67,
- 0x43, 0x26, 0xe1, 0xc9, 0x3d, 0x19, 0x02, 0x42, 0x38, 0x6c, 0x8a, 0x7f,
- 0xea, 0x1b, 0x75, 0x5f, 0x4b, 0x31, 0x47, 0x4f, 0xab, 0x4f, 0x56, 0xce,
- 0x9f, 0x5b, 0x71, 0x65, 0x1d, 0x0c, 0x89, 0x1b, 0xa1, 0xfa, 0x4f, 0x37,
- 0x7b, 0x3a, 0x7e, 0xb1, 0xc7, 0xf5, 0x9f, 0xb0, 0xe9, 0xfd, 0xe7, 0x75,
- 0xad, 0xa6, 0x8e, 0x99, 0x3e, 0x74, 0x75, 0xb3, 0xff, 0x43, 0x6d, 0x9a,
- 0x4f, 0xfd, 0xcb, 0x73, 0xf6, 0xd2, 0x02, 0x72, 0x74, 0xfd, 0xbf, 0x6c,
- 0x73, 0x68, 0x74, 0x72, 0x7e, 0x9b, 0x44, 0x92, 0xfa, 0xdb, 0x64, 0x10,
- 0xef, 0x1f, 0xbb, 0xb1, 0xc6, 0x68, 0xb0, 0xa7, 0x98, 0xca, 0xaa, 0x52,
- 0x6f, 0x97, 0x6b, 0x61, 0xf4, 0x90, 0x8d, 0x72, 0x3f, 0x2f, 0xa0, 0x28,
- 0xb7, 0x72, 0xac, 0x31, 0x07, 0xb8, 0xd0, 0x46, 0x1c, 0x57, 0x8e, 0xfb,
- 0x50, 0xe6, 0xe0, 0xc3, 0xaa, 0x12, 0xde, 0x21, 0x51, 0x0b, 0x6c, 0xf9,
- 0x37, 0x59, 0x2a, 0xcf, 0xfe, 0x5a, 0xb1, 0xeb, 0xaf, 0x86, 0x60, 0x1a,
- 0x26, 0xc9, 0xfc, 0xba, 0xf8, 0x66, 0x01, 0xa2, 0xad, 0x9f, 0xcf, 0x7f,
- 0xba, 0x16, 0x79, 0xd3, 0xd5, 0xbc, 0xd1, 0xd2, 0x77, 0xe8, 0xf4, 0xc4,
- 0xce, 0x7d, 0xf0, 0xcc, 0x03, 0x45, 0x69, 0x3f, 0xfc, 0x0d, 0xfa, 0xef,
- 0x15, 0x8f, 0x64, 0x03, 0xa7, 0xff, 0x9f, 0x7a, 0x16, 0x56, 0x56, 0xb4,
- 0xca, 0x3a, 0x6d, 0x69, 0x91, 0x2f, 0x89, 0x73, 0xf9, 0x9d, 0x78, 0xd0,
- 0xb7, 0x67, 0x4f, 0xd6, 0x56, 0xd2, 0x94, 0x74, 0xff, 0x53, 0xb0, 0xb7,
- 0x16, 0xbe, 0xe7, 0x4f, 0xe7, 0xd6, 0xb0, 0x7b, 0xf4, 0xe9, 0x2f, 0xac,
- 0x4f, 0xc6, 0x8a, 0xd2, 0x19, 0x1b, 0x2d, 0xc3, 0x61, 0x2c, 0xd1, 0xe4,
- 0xfe, 0x5d, 0x7c, 0x33, 0x00, 0xd1, 0x60, 0x4f, 0xbe, 0x19, 0x80, 0x68,
- 0x9d, 0x67, 0xff, 0xf6, 0xda, 0xce, 0x69, 0x4b, 0xbd, 0xeb, 0x69, 0x7f,
- 0x6c, 0x3a, 0x7c, 0xb5, 0x63, 0xd7, 0x48, 0x95, 0x70, 0xc6, 0x7f, 0x3e,
- 0xeb, 0xf3, 0xe5, 0x94, 0x74, 0xfb, 0xe1, 0x98, 0x06, 0x8b, 0x66, 0x7f,
- 0xdd, 0xb5, 0xd7, 0xb4, 0x0c, 0xf9, 0xd2, 0x5d, 0x1f, 0x76, 0x18, 0xcf,
- 0x06, 0x60, 0x1a, 0x2e, 0x69, 0x28, 0xe8, 0xf9, 0xbb, 0xe0, 0xae, 0x67,
- 0x14, 0x74, 0x97, 0x46, 0xe7, 0x82, 0x29, 0xfc, 0xba, 0xf8, 0x66, 0x01,
- 0xa2, 0xef, 0x9e, 0x5f, 0x9e, 0x7b, 0x3a, 0x19, 0xba, 0x5d, 0xaa, 0xd0,
- 0x38, 0x0c, 0xad, 0x53, 0x49, 0x50, 0x1f, 0x71, 0x54, 0x34, 0x71, 0x03,
- 0xb8, 0x52, 0xde, 0x13, 0x5a, 0x27, 0xf0, 0x79, 0x3e, 0xbd, 0xd5, 0x8f,
- 0x3a, 0x7f, 0xeb, 0x43, 0xdc, 0xb7, 0x55, 0x43, 0xe4, 0xe9, 0xc3, 0x8b,
- 0x63, 0xed, 0xd1, 0x3c, 0xfe, 0x1b, 0x29, 0xdb, 0x4d, 0xe4, 0xe9, 0xf7,
- 0xc3, 0x30, 0x0d, 0x12, 0xbc, 0xff, 0x87, 0x38, 0xe7, 0x6d, 0x65, 0x70,
- 0x74, 0xff, 0xfc, 0xfa, 0x4e, 0xe9, 0x49, 0xab, 0xb2, 0xb2, 0xdd, 0x1d,
- 0x3d, 0xee, 0x7d, 0xe7, 0x4f, 0xff, 0xe4, 0xd6, 0x2b, 0x07, 0xbd, 0xf1,
- 0x83, 0x60, 0x25, 0x87, 0x47, 0x28, 0x82, 0xc2, 0x28, 0xe5, 0x33, 0xfa,
- 0x40, 0xdc, 0x37, 0x27, 0x63, 0xd6, 0xc9, 0xee, 0xd1, 0xbd, 0xe3, 0x70,
- 0x9d, 0xa6, 0xe4, 0xa9, 0xff, 0xdb, 0xc4, 0xd3, 0x3d, 0x3f, 0x67, 0xbd,
- 0x95, 0x3f, 0xb0, 0x17, 0xcf, 0xdd, 0xc5, 0xb1, 0xf3, 0xdc, 0x72, 0x4b,
- 0x05, 0x61, 0x4a, 0x94, 0x1c, 0xea, 0x15, 0xb3, 0xff, 0x96, 0xac, 0x7a,
- 0xeb, 0xe1, 0x98, 0x06, 0x89, 0x86, 0x7f, 0xf0, 0xb3, 0xa1, 0x6b, 0x57,
- 0xd6, 0xdd, 0xdd, 0xde, 0x74, 0xff, 0xef, 0xe7, 0x6b, 0xf3, 0xa7, 0xf0,
- 0xd7, 0x79, 0xd3, 0x52, 0xf9, 0x45, 0x2f, 0x85, 0x79, 0xff, 0x9d, 0xfa,
- 0xb5, 0xfe, 0xe6, 0x85, 0x9e, 0x74, 0xfe, 0x6c, 0xb3, 0x5e, 0x73, 0xe7,
- 0x4f, 0xb3, 0xef, 0xc5, 0x1d, 0x02, 0x7b, 0x5e, 0x9a, 0x4f, 0xca, 0x6a,
- 0x1d, 0x75, 0x1d, 0x2b, 0x9d, 0x3e, 0x6a, 0x1d, 0x75, 0x1d, 0x3f, 0x6d,
- 0x35, 0x7c, 0xb7, 0xa1, 0xf3, 0x38, 0x5c, 0xa1, 0x09, 0xff, 0xff, 0x0d,
- 0x70, 0xed, 0xaa, 0xdf, 0x41, 0xab, 0x12, 0x86, 0xd7, 0xdc, 0xe9, 0xff,
- 0xe6, 0xd0, 0xe7, 0x7b, 0xa4, 0xe7, 0xdd, 0x5c, 0xe9, 0xf9, 0xd7, 0x8d,
- 0x0b, 0x76, 0x74, 0xff, 0xe6, 0xd7, 0x6c, 0xfa, 0xb7, 0x56, 0x7b, 0xc1,
- 0xd0, 0xc7, 0xfe, 0x86, 0x33, 0xf5, 0xd3, 0xca, 0xb3, 0x47, 0x4f, 0xff,
- 0xfb, 0xf4, 0xe9, 0x87, 0x5d, 0x3c, 0x0b, 0x6f, 0x13, 0x4d, 0xab, 0x9d,
- 0x2a, 0xb5, 0x13, 0x9f, 0x2e, 0x9f, 0xff, 0x6c, 0x6b, 0x5b, 0x4a, 0xb7,
- 0x54, 0xe9, 0xae, 0x74, 0xe6, 0xef, 0xc1, 0xd1, 0x47, 0xe6, 0x2a, 0xb3,
- 0xd9, 0xe3, 0x9a, 0x3a, 0x4b, 0xeb, 0x17, 0x16, 0xb9, 0x85, 0x18, 0x42,
- 0x21, 0xc5, 0x5f, 0xb8, 0x6e, 0x19, 0xe3, 0x0b, 0xcd, 0x42, 0x73, 0xd2,
- 0x09, 0xf7, 0xc3, 0x30, 0x0d, 0x15, 0x74, 0xff, 0x3d, 0x75, 0xf0, 0xcc,
- 0x03, 0x44, 0x79, 0x25, 0xd1, 0xf9, 0xe1, 0x8c, 0xfe, 0x5d, 0x7c, 0x33,
- 0x00, 0xd1, 0x60, 0xcf, 0xe5, 0xd7, 0xc3, 0x30, 0x0d, 0x16, 0x54, 0xfe,
- 0x5d, 0x7c, 0x33, 0x00, 0xd1, 0x69, 0xcf, 0xea, 0xbf, 0x4f, 0xff, 0xdd,
- 0x9d, 0x3c, 0x19, 0x80, 0x68, 0xb7, 0x27, 0xfe, 0x6a, 0xfd, 0x0f, 0x4d,
- 0xd5, 0xbc, 0x1d, 0x1f, 0x3f, 0x0b, 0x95, 0xcf, 0xf3, 0x0f, 0xaa, 0x6b,
- 0xe9, 0x0e, 0x9f, 0xd9, 0x96, 0x72, 0xd5, 0xf3, 0xa7, 0xfd, 0x8f, 0x5d,
- 0x7c, 0x33, 0x00, 0xd1, 0x43, 0xcf, 0xfc, 0xac, 0xe5, 0xb9, 0xda, 0x0a,
- 0x28, 0xe9, 0xff, 0xbd, 0x7e, 0xf3, 0xf6, 0xe9, 0x92, 0xc3, 0xa7, 0xfd,
- 0xef, 0xfb, 0xfe, 0x0e, 0xab, 0xb3, 0xa7, 0xeb, 0xe5, 0xb7, 0xd2, 0x1d,
- 0x3f, 0x0f, 0x59, 0x5f, 0x6b, 0x9d, 0x3f, 0xff, 0x57, 0x3b, 0x6f, 0x0b,
- 0xd0, 0xe7, 0x77, 0xbb, 0x76, 0x54, 0x96, 0xf5, 0x5f, 0x95, 0x0a, 0x64,
- 0x22, 0x70, 0xdd, 0x46, 0x58, 0x8f, 0xda, 0x1d, 0xd1, 0xb4, 0x81, 0xe9,
- 0x6f, 0x51, 0x84, 0xfe, 0x5d, 0x7c, 0x33, 0x00, 0xd1, 0x79, 0xc3, 0x32,
- 0xe6, 0xde, 0x8b, 0xcc, 0x3e, 0x2a, 0x72, 0x2e, 0xd8, 0xc6, 0x7e, 0x4c,
- 0xa3, 0xcd, 0x9e, 0x0c, 0xb3, 0x87, 0x50, 0xa8, 0x9f, 0xcb, 0xaf, 0x86,
- 0x60, 0x1a, 0x29, 0x69, 0xfc, 0xba, 0xf8, 0x66, 0x01, 0xa2, 0xc2, 0x9f,
- 0xcb, 0xaf, 0x86, 0x60, 0x1a, 0x2c, 0xb9, 0xe5, 0xf9, 0xeb, 0x47, 0x74,
- 0x74, 0xe5, 0xf8, 0x51, 0xd3, 0xc0, 0xb6, 0xb8, 0x1e, 0x7f, 0xa6, 0x33,
- 0xff, 0x96, 0xac, 0x7a, 0xeb, 0xe1, 0x98, 0x06, 0x8a, 0x32, 0x7f, 0x2d,
- 0x9d, 0x37, 0xdb, 0xb3, 0xa1, 0xe9, 0xe1, 0x7c, 0xf1, 0x47, 0x99, 0x08,
- 0xbb, 0x9c, 0x69, 0x4e, 0x7f, 0xe5, 0xe3, 0xd7, 0x5f, 0x0c, 0xc0, 0x34,
- 0x47, 0x33, 0xff, 0x96, 0xac, 0x7a, 0xeb, 0xe1, 0x98, 0x06, 0x89, 0xca,
- 0x7f, 0x2e, 0xbe, 0x19, 0x80, 0x68, 0xb3, 0x27, 0xfb, 0xbf, 0xb6, 0xb7,
- 0x96, 0xbc, 0xe9, 0xfd, 0x57, 0xff, 0xea, 0xdb, 0x9d, 0x25, 0xb1, 0xf6,
- 0xbc, 0xea, 0x7f, 0x2e, 0xbe, 0x19, 0x80, 0x68, 0xb7, 0x67, 0xff, 0x2d,
- 0x58, 0xf5, 0xd7, 0xc3, 0x30, 0x0d, 0x14, 0x84, 0xff, 0xcb, 0xc7, 0xae,
- 0xbe, 0x19, 0x80, 0x68, 0x94, 0xa2, 0xc5, 0x49, 0x8e, 0x26, 0xa9, 0x4f,
- 0xb8, 0x54, 0x89, 0x3e, 0x8f, 0x1d, 0x94, 0xe7, 0xfd, 0x8f, 0x5d, 0x7c,
- 0x33, 0x00, 0xd1, 0x3b, 0x4f, 0xff, 0x93, 0x9f, 0x54, 0xce, 0xd9, 0xc8,
- 0xb0, 0xd0, 0x1d, 0x25, 0xa9, 0x13, 0xb8, 0x8f, 0x3f, 0xf6, 0x2b, 0x74,
- 0x19, 0xb6, 0xf0, 0xf3, 0xa7, 0xfe, 0x1a, 0xde, 0x59, 0x57, 0x1c, 0xb4,
- 0xe9, 0xba, 0x97, 0xca, 0x21, 0x6e, 0x87, 0x0a, 0x47, 0x07, 0x54, 0x2b,
- 0x67, 0xdf, 0x0c, 0xc0, 0x34, 0x45, 0x93, 0xfe, 0xc7, 0xae, 0xbe, 0x19,
- 0x80, 0x68, 0x97, 0x67, 0xff, 0xea, 0xe7, 0x6d, 0xe1, 0x7a, 0x1c, 0xee,
- 0xf7, 0x6e, 0xca, 0x92, 0xe9, 0x1a, 0xca, 0x31, 0xea, 0x47, 0x9f, 0xfc,
- 0xb5, 0x63, 0xd7, 0x5f, 0x0c, 0xc0, 0x34, 0x4c, 0x53, 0xef, 0x86, 0x60,
- 0x1a, 0x2a, 0x99, 0x51, 0xd1, 0x47, 0x81, 0xe4, 0xc6, 0x7f, 0xff, 0xf7,
- 0xf3, 0x76, 0xbe, 0xb4, 0xbd, 0xe5, 0xfe, 0x9c, 0x6b, 0x69, 0xf7, 0x9d,
- 0x0b, 0x44, 0xe6, 0x11, 0xcf, 0xfe, 0x5a, 0xb1, 0xeb, 0xaf, 0x86, 0x60,
- 0x1a, 0x27, 0x49, 0xfc, 0x99, 0xf6, 0x7e, 0x3a, 0x3a, 0x7c, 0xe3, 0x38,
- 0xd7, 0x3a, 0x7e, 0xe2, 0x91, 0xd5, 0x09, 0xd0, 0x87, 0xab, 0x72, 0x89,
- 0xc9, 0xb6, 0x39, 0x66, 0x86, 0x7f, 0xef, 0x6f, 0xa6, 0xb5, 0x7e, 0xb8,
- 0x8a, 0x3a, 0x14, 0x7e, 0x5b, 0x2a, 0x9f, 0xf6, 0x3d, 0x75, 0xf0, 0xcc,
- 0x03, 0x44, 0xef, 0x3e, 0xd7, 0xb8, 0xa4, 0x2a, 0x4b, 0xe5, 0x3a, 0xaa,
- 0x8c, 0x69, 0x44, 0x58, 0x8f, 0x3f, 0xf9, 0x6a, 0xc7, 0xae, 0xbe, 0x19,
- 0x80, 0x68, 0xa1, 0x67, 0xff, 0x2d, 0x58, 0xf5, 0xd7, 0xc3, 0x30, 0x0d,
- 0x14, 0x94, 0xff, 0xfe, 0xab, 0xaf, 0xc5, 0x39, 0xbc, 0x56, 0xb6, 0xda,
- 0xf5, 0x47, 0x45, 0x8b, 0x9b, 0x2f, 0x38, 0x08, 0xcb, 0xfe, 0x44, 0xa8,
- 0xff, 0x7b, 0x49, 0xf5, 0x4f, 0xa9, 0x4e, 0x7f, 0x2e, 0xbe, 0x19, 0x80,
- 0x68, 0x89, 0x27, 0xff, 0x2d, 0x58, 0xf5, 0xd7, 0xc3, 0x30, 0x0d, 0x12,
- 0xf4, 0xfb, 0xfd, 0xa9, 0x2e, 0x74, 0xee, 0xdb, 0x47, 0x4f, 0xfd, 0x8e,
- 0x5d, 0x9d, 0x66, 0xda, 0xd7, 0x0e, 0x84, 0x44, 0x5b, 0x85, 0x1f, 0x1c,
- 0x9f, 0xe4, 0xc1, 0xf7, 0x4e, 0x37, 0x93, 0xa7, 0xdf, 0x0c, 0xc0, 0x34,
- 0x52, 0xf3, 0xe1, 0xd5, 0x95, 0xc1, 0xd3, 0xfd, 0xdd, 0xfe, 0xd6, 0xbd,
- 0x14, 0x74, 0xff, 0x65, 0x9d, 0x2c, 0xf5, 0xc6, 0xeb, 0x9d, 0x35, 0x3d,
- 0x8f, 0xf3, 0xd3, 0xa9, 0x9f, 0x47, 0x4e, 0x6e, 0xee, 0x74, 0x72, 0x6c,
- 0x78, 0x15, 0x9f, 0xf9, 0x15, 0x9c, 0xf8, 0x71, 0xec, 0x36, 0x9d, 0x3d,
- 0x74, 0xe3, 0x47, 0x46, 0xcf, 0xa7, 0x48, 0xf3, 0xfd, 0x9b, 0xc7, 0x13,
- 0xed, 0x61, 0xd3, 0xe7, 0x64, 0x53, 0x5c, 0xe9, 0xf6, 0x3a, 0xaf, 0xdc,
- 0xe9, 0x37, 0x27, 0xa2, 0xa2, 0x99, 0x2d, 0x95, 0x7e, 0x72, 0x61, 0x47,
- 0x56, 0x98, 0xb9, 0x0a, 0x4d, 0xaf, 0x64, 0x23, 0x2e, 0x45, 0xa8, 0x44,
- 0xcf, 0xe5, 0xd7, 0xc3, 0x30, 0x0d, 0x14, 0xe4, 0xff, 0x93, 0xf9, 0x7d,
- 0xd5, 0x08, 0x1d, 0x3f, 0xea, 0xdb, 0x7e, 0x97, 0xc7, 0x1c, 0x15, 0x32,
- 0x70, 0x74, 0xd6, 0x2f, 0x94, 0x48, 0x75, 0x1d, 0x3b, 0x20, 0x4f, 0xbe,
- 0x19, 0x80, 0x68, 0xaf, 0x27, 0xff, 0xea, 0xe7, 0x6d, 0xe1, 0x7a, 0x1c,
- 0xee, 0xf7, 0x6e, 0xca, 0x92, 0xe9, 0x11, 0xfd, 0x46, 0x33, 0xff, 0x2f,
- 0x1e, 0xba, 0xf8, 0x66, 0x01, 0xa2, 0x47, 0x9c, 0x9d, 0xb1, 0xd3, 0x82,
- 0x94, 0x52, 0xcb, 0xb9, 0xf7, 0xc3, 0x30, 0x0d, 0x12, 0x44, 0xf2, 0xf1,
- 0xeb, 0x63, 0xda, 0xa2, 0x99, 0xff, 0x97, 0x8f, 0x5d, 0x7c, 0x33, 0x00,
- 0xd1, 0x25, 0x4f, 0xbe, 0x19, 0x80, 0x68, 0xbc, 0x67, 0xd7, 0xbe, 0xa8,
- 0x0e, 0x9f, 0xe7, 0xae, 0xbe, 0x19, 0x80, 0x68, 0x93, 0x64, 0xba, 0x44,
- 0xcf, 0xcc, 0x70, 0x9a, 0x19, 0x91, 0x11, 0x61, 0xe3, 0xe5, 0xed, 0x73,
- 0x09, 0x54, 0x86, 0x63, 0x90, 0xd3, 0x51, 0x5e, 0xe1, 0x85, 0xa3, 0x7f,
- 0x61, 0xcd, 0x0d, 0x1e, 0x20, 0x4d, 0x91, 0xd9, 0x3e, 0x53, 0xd7, 0x32,
- 0x8c, 0x2a, 0xf1, 0xbb, 0x3c, 0xca, 0x5e, 0x0b, 0x49, 0xaf, 0x6d, 0x20,
- 0x49, 0x27, 0x94, 0xba, 0xf1, 0xde, 0x39, 0x59, 0xd8, 0xfe, 0x97, 0x84,
- 0xac, 0x53, 0x58, 0x6e, 0x78, 0xe3, 0x2b, 0x47, 0x6e, 0xe5, 0xf7, 0x3b,
- 0x90, 0xb4, 0x1a, 0x48, 0x45, 0xe9, 0x45, 0xfa, 0xb4, 0x09, 0x3e, 0xd3,
- 0xf6, 0xdd, 0x4a, 0x71, 0xe2, 0x55, 0x47, 0x54, 0x7d, 0xbe, 0x27, 0x76,
- 0x9d, 0xa9, 0x21, 0xb0,
+ 0x4f, 0x6b, 0x69, 0xa3, 0xa7, 0xff, 0xfe, 0xdf, 0xbc, 0xa5, 0x7d, 0xc1,
+ 0xa7, 0x5b, 0xae, 0x5a, 0xf7, 0x6f, 0x27, 0x4f, 0xfe, 0x47, 0x1f, 0x56,
+ 0xbf, 0xa2, 0xb3, 0x04, 0xe9, 0xb1, 0xd8, 0xe8, 0xa4, 0x7d, 0x81, 0x0e,
+ 0xdd, 0xf1, 0x2e, 0x77, 0xf0, 0x0e, 0x87, 0x7c, 0xf5, 0x3c, 0x9d, 0x4f,
+ 0xb7, 0x9a, 0xc7, 0x9d, 0x3f, 0x9f, 0x76, 0xbf, 0x5a, 0xfd, 0x6f, 0xad,
+ 0x9d, 0x3c, 0x97, 0x4e, 0xce, 0x9d, 0xc7, 0x1c, 0x15, 0x3e, 0xc1, 0xd6,
+ 0xe8, 0xa5, 0x97, 0xf3, 0xec, 0xd3, 0x95, 0xa3, 0xa3, 0x94, 0x4d, 0xf6,
+ 0x80, 0x26, 0x93, 0xdb, 0xcc, 0xc3, 0xa7, 0xfe, 0xed, 0x1c, 0xe9, 0xb6,
+ 0x4f, 0xfb, 0xd7, 0x3a, 0x7f, 0xc9, 0xe5, 0x85, 0xae, 0xc8, 0xa3, 0xa7,
+ 0xea, 0x75, 0xeb, 0xea, 0xe7, 0x4f, 0x57, 0x35, 0x61, 0xd1, 0x4a, 0x8c,
+ 0xad, 0x26, 0x48, 0x71, 0xf5, 0xcc, 0x5c, 0x1f, 0xda, 0x60, 0x9e, 0x68,
+ 0xbe, 0x7e, 0xae, 0x1a, 0xb9, 0x43, 0xa7, 0x37, 0xbd, 0x9d, 0x3f, 0xff,
+ 0xf8, 0x46, 0xd6, 0xf2, 0x35, 0xce, 0xd1, 0xce, 0x97, 0xab, 0x5f, 0xfa,
+ 0xe0, 0xe9, 0xf2, 0x6b, 0xd6, 0xb0, 0xe9, 0xff, 0xfd, 0x56, 0xbe, 0xea,
+ 0xa1, 0xe8, 0xec, 0x9b, 0xb1, 0x2b, 0xe7, 0x4f, 0xff, 0xfb, 0x8e, 0x83,
+ 0x41, 0xb4, 0x1a, 0xf6, 0xdd, 0x74, 0xce, 0x2b, 0xc9, 0xd3, 0xfa, 0xd7,
+ 0xdf, 0xcf, 0xad, 0x69, 0xd3, 0xfb, 0x38, 0xf5, 0xc6, 0xd6, 0x1d, 0x0c,
+ 0x8d, 0xe4, 0x72, 0x13, 0x89, 0xee, 0xf4, 0x96, 0x1d, 0x3f, 0xe6, 0xcb,
+ 0x19, 0x42, 0xd6, 0xf6, 0x74, 0x32, 0xa7, 0x6a, 0x7d, 0x42, 0x8f, 0xc6,
+ 0x87, 0x85, 0xa2, 0x47, 0x37, 0xaf, 0x3a, 0x7c, 0xdd, 0xde, 0xcd, 0x1d,
+ 0x3b, 0x35, 0x73, 0xa6, 0xf6, 0xc3, 0xa7, 0x0e, 0x9c, 0x79, 0xb3, 0xf8,
+ 0xdc, 0xfd, 0xe8, 0x74, 0xe6, 0xde, 0x0e, 0x86, 0x3e, 0x64, 0x33, 0x9f,
+ 0xff, 0x7a, 0xda, 0xe8, 0x3e, 0xbb, 0x74, 0xad, 0x75, 0x56, 0x8e, 0x9f,
+ 0xfb, 0x6d, 0xe7, 0xa6, 0x87, 0x34, 0xda, 0x3a, 0x7f, 0x74, 0xb5, 0xe9,
+ 0xbf, 0x54, 0x74, 0x76, 0x7f, 0xa2, 0x8d, 0x3f, 0xef, 0xb9, 0xd2, 0xec,
+ 0x96, 0x66, 0x8e, 0x86, 0x3e, 0x3f, 0x48, 0xa7, 0xff, 0xff, 0xbd, 0x1b,
+ 0xfc, 0x59, 0xce, 0x9e, 0x34, 0x8f, 0xab, 0x75, 0x4e, 0x86, 0xae, 0x74,
+ 0x98, 0xe9, 0xfc, 0xfc, 0xfa, 0x5d, 0xad, 0x3a, 0x7f, 0xff, 0xff, 0x27,
+ 0x77, 0x1a, 0xcb, 0x7a, 0x73, 0xbf, 0x7a, 0x0d, 0x5a, 0xfa, 0xf6, 0xc1,
+ 0xac, 0xb4, 0xe9, 0xd9, 0x80, 0x68, 0xa6, 0x22, 0x91, 0x78, 0x10, 0x96,
+ 0x9f, 0xf5, 0x0d, 0xaf, 0xbe, 0x9b, 0xee, 0x1d, 0x3a, 0x93, 0xb3, 0xa5,
+ 0x47, 0x4e, 0xb4, 0x6b, 0xb3, 0x54, 0xe8, 0x6e, 0x11, 0x13, 0xd8, 0xd3,
+ 0x39, 0xed, 0x69, 0xd3, 0xf9, 0x5c, 0xed, 0xac, 0xae, 0x0e, 0x8b, 0x4f,
+ 0x47, 0x07, 0x27, 0xff, 0xf0, 0xd0, 0x6b, 0x4d, 0xab, 0xb8, 0x35, 0xc7,
+ 0x46, 0x77, 0x47, 0x4f, 0xf8, 0x19, 0x5b, 0xab, 0xd2, 0x09, 0xd0, 0xc8,
+ 0xa1, 0xdb, 0x3c, 0xfb, 0xec, 0xe9, 0xbe, 0x74, 0xfd, 0x83, 0xd3, 0x96,
+ 0x13, 0xa2, 0x8f, 0xdd, 0x08, 0xbd, 0x28, 0x8b, 0x17, 0x9e, 0x5e, 0x2f,
+ 0xcc, 0x30, 0xbc, 0x90, 0x04, 0x68, 0x16, 0x91, 0x24, 0x20, 0xdc, 0x0f,
+ 0xfc, 0x3b, 0x95, 0x0c, 0x41, 0x72, 0xd4, 0x67, 0x53, 0xfe, 0xf3, 0xfc,
+ 0xe3, 0xa6, 0x73, 0x96, 0x1d, 0x3d, 0x43, 0xe7, 0xae, 0x74, 0xff, 0xff,
+ 0xfb, 0x69, 0xad, 0xd7, 0xd9, 0xd7, 0x45, 0x7a, 0xed, 0xd2, 0xad, 0x7d,
+ 0x7a, 0x3d, 0xdc, 0xe9, 0x69, 0x11, 0x6b, 0x72, 0x69, 0xff, 0xf5, 0x56,
+ 0xd0, 0x37, 0x5d, 0x2f, 0xee, 0xdb, 0xae, 0x74, 0xff, 0xf6, 0xb7, 0x5d,
+ 0xf4, 0x53, 0x56, 0xb9, 0xa1, 0x3a, 0x7f, 0xad, 0xe8, 0xa6, 0xa1, 0xd7,
+ 0x51, 0xd2, 0xbd, 0x22, 0x3b, 0x14, 0x64, 0x82, 0x98, 0x76, 0xa1, 0xcf,
+ 0x3e, 0x7b, 0x5a, 0xfb, 0x9d, 0x3f, 0xff, 0xff, 0xea, 0x1f, 0x3d, 0x13,
+ 0x7e, 0xad, 0xc4, 0xd3, 0x28, 0x73, 0xce, 0xd1, 0x75, 0xbb, 0x7b, 0x6e,
+ 0x4a, 0x9f, 0xff, 0xf8, 0x13, 0x8e, 0x7d, 0xff, 0x4f, 0x5a, 0xcb, 0x86,
+ 0xfd, 0xdd, 0xb9, 0xc1, 0xd3, 0x7b, 0x65, 0xa9, 0xa2, 0x21, 0x45, 0xe1,
+ 0x43, 0x0c, 0xab, 0xaf, 0x71, 0x9b, 0x0c, 0x6e, 0x33, 0xff, 0x94, 0x1d,
+ 0x37, 0x8f, 0xa5, 0x60, 0xf6, 0x74, 0xff, 0xf9, 0x07, 0x5b, 0xa7, 0x6d,
+ 0x39, 0x5d, 0x7c, 0x1e, 0xce, 0x9f, 0xf9, 0x86, 0xc1, 0xa7, 0x57, 0xf5,
+ 0xad, 0x3a, 0x2e, 0x8a, 0x1f, 0x56, 0xe7, 0xab, 0x54, 0xee, 0x1d, 0x3b,
+ 0xaa, 0xb6, 0x74, 0xd5, 0xc9, 0xd1, 0x62, 0x6d, 0x0f, 0x87, 0x5d, 0xc9,
+ 0x34, 0x4a, 0xe8, 0x7a, 0x7c, 0x9a, 0xbd, 0x76, 0x74, 0xfd, 0xcb, 0x0e,
+ 0xf1, 0xe7, 0x4e, 0x6e, 0x58, 0xe9, 0xf9, 0xf5, 0xab, 0xe3, 0x9d, 0x0f,
+ 0x1d, 0x45, 0x90, 0xf4, 0x5a, 0xb8, 0xdd, 0x3f, 0x3b, 0x6f, 0x3a, 0xed,
+ 0xd9, 0xd3, 0xfb, 0xee, 0x0d, 0x6f, 0x34, 0x74, 0x51, 0xf3, 0x21, 0xa4,
+ 0xfc, 0xdd, 0xd6, 0xbc, 0x58, 0x74, 0x3c, 0xf4, 0x04, 0x82, 0x7f, 0xb5,
+ 0xba, 0x7e, 0x0d, 0x5a, 0x74, 0xff, 0xff, 0x0e, 0x77, 0x7b, 0x29, 0x07,
+ 0x43, 0x4e, 0xba, 0x5f, 0x81, 0x3a, 0x05, 0x14, 0x1a, 0x37, 0x9f, 0xf2,
+ 0x53, 0x9d, 0x2e, 0xdb, 0xce, 0xb9, 0xd3, 0xfb, 0x2d, 0xbe, 0xeb, 0x3e,
+ 0x74, 0x72, 0x7e, 0xba, 0x43, 0x9f, 0xea, 0xfd, 0x8c, 0x9f, 0xa1, 0x3a,
+ 0x4a, 0x3b, 0xa1, 0xb6, 0x9c, 0x35, 0xc9, 0xd0, 0xc6, 0xf6, 0xd2, 0x29,
+ 0xfa, 0xdb, 0xd5, 0x0f, 0x93, 0xa7, 0x95, 0xe1, 0xbb, 0x3a, 0x28, 0xf4,
+ 0x90, 0xba, 0x77, 0xb6, 0xf6, 0x74, 0x32, 0x7b, 0xf5, 0x09, 0x74, 0x84,
+ 0xb7, 0xdc, 0xc4, 0x82, 0x7f, 0x69, 0x2c, 0xad, 0xfb, 0xa3, 0xa4, 0xe1,
+ 0xd3, 0xf5, 0x7b, 0x5b, 0x0b, 0x0e, 0x9a, 0xad, 0x63, 0x7d, 0x71, 0x19,
+ 0xfb, 0x78, 0xf5, 0x7d, 0x0e, 0x9f, 0x27, 0x7f, 0xab, 0x4e, 0x8f, 0x28,
+ 0xf2, 0x47, 0x2e, 0xcb, 0x3d, 0x2c, 0x9f, 0xff, 0xbe, 0xfd, 0xd3, 0x9b,
+ 0x61, 0xf2, 0x35, 0xad, 0xfa, 0x74, 0xff, 0xfe, 0x4a, 0xb5, 0xf7, 0xd6,
+ 0xd9, 0x4c, 0x9c, 0xf4, 0x67, 0x74, 0x74, 0xff, 0xff, 0xfb, 0xd1, 0xe9,
+ 0xc6, 0x5a, 0xff, 0xe7, 0x7d, 0x2f, 0xeb, 0x5b, 0xba, 0x41, 0xaf, 0x27,
+ 0x4f, 0xff, 0xbd, 0xff, 0xeb, 0x57, 0xda, 0x57, 0x4d, 0xf6, 0xc7, 0x45,
+ 0x23, 0x93, 0x70, 0x8c, 0x9f, 0xfe, 0x7b, 0xb6, 0xe9, 0x85, 0xc1, 0xad,
+ 0x5f, 0x0e, 0x9f, 0xff, 0x73, 0x4a, 0xe8, 0xed, 0xa6, 0xbb, 0x8f, 0xcf,
+ 0xd8, 0x74, 0xff, 0x50, 0xd9, 0xd3, 0xbc, 0xc7, 0x0e, 0x9f, 0xef, 0xd8,
+ 0xd6, 0x59, 0xef, 0xec, 0x3a, 0x7f, 0xbd, 0x1e, 0x97, 0xf7, 0xab, 0xdf,
+ 0x9d, 0x0c, 0x7f, 0xf7, 0x3e, 0x9f, 0xfd, 0x67, 0x4b, 0xef, 0xde, 0x9a,
+ 0xbd, 0xdb, 0xe7, 0x4f, 0xff, 0xfa, 0xad, 0xba, 0x57, 0x1d, 0x37, 0x5a,
+ 0xbd, 0x59, 0xd2, 0x93, 0x93, 0xa2, 0x91, 0x84, 0x8a, 0x31, 0x62, 0xbd,
+ 0xe0, 0x8d, 0x32, 0xd2, 0x74, 0x50, 0x52, 0xed, 0xe1, 0x75, 0xa8, 0x71,
+ 0xcf, 0xfb, 0x3f, 0xba, 0xd3, 0x0a, 0x76, 0x74, 0xff, 0x57, 0x16, 0xbe,
+ 0xfd, 0x34, 0x87, 0x4f, 0xff, 0xf9, 0x81, 0x95, 0xd1, 0xcd, 0xa0, 0xf3,
+ 0xd3, 0xc0, 0x0d, 0x6e, 0x8e, 0x80, 0x47, 0x38, 0x9e, 0x3b, 0x1e, 0x4f,
+ 0x26, 0x91, 0x8e, 0x9f, 0xff, 0xfc, 0x29, 0xe7, 0x78, 0xe7, 0x41, 0xf5,
+ 0xdb, 0xa5, 0x5a, 0xfa, 0xf4, 0x7b, 0xb9, 0xd3, 0xed, 0xa3, 0x0d, 0x87,
+ 0x4d, 0xa6, 0x52, 0x2a, 0x5d, 0x42, 0x0e, 0x1e, 0x8f, 0xd4, 0x86, 0x44,
+ 0x32, 0xf7, 0x6d, 0x4e, 0x1d, 0xa4, 0x6b, 0xb9, 0x19, 0x74, 0xf6, 0xaf,
+ 0x9d, 0x9d, 0x3f, 0xf6, 0xd3, 0xa2, 0x7f, 0xdb, 0x33, 0xe0, 0x74, 0xf2,
+ 0x6f, 0x2c, 0x3a, 0x79, 0xd3, 0x69, 0x8e, 0x9f, 0xb7, 0x96, 0x74, 0x7e,
+ 0x8e, 0x9f, 0x67, 0xc6, 0xd4, 0x3a, 0x10, 0xf5, 0xb4, 0x61, 0x14, 0x99,
+ 0x17, 0x92, 0x20, 0x46, 0x42, 0x1d, 0x3c, 0x4f, 0x78, 0xf7, 0x2e, 0x74,
+ 0xff, 0xfc, 0x9f, 0xe9, 0x49, 0x43, 0xe7, 0x69, 0x4a, 0xa0, 0x3a, 0x7f,
+ 0xff, 0x92, 0xcf, 0xb2, 0xaf, 0xeb, 0x74, 0x6f, 0xb7, 0x3b, 0x65, 0x1d,
+ 0x14, 0x8c, 0x2f, 0xac, 0xcf, 0xff, 0xfe, 0xff, 0xd2, 0xce, 0x9b, 0xad,
+ 0x0b, 0x39, 0xba, 0xb1, 0xad, 0xd7, 0xa0, 0x74, 0xff, 0xff, 0xcd, 0xe7,
+ 0x6d, 0xd0, 0x6b, 0xdf, 0x3d, 0x2d, 0x7d, 0xd0, 0x7c, 0x35, 0x87, 0x4f,
+ 0xad, 0xba, 0x50, 0x9d, 0x14, 0x8a, 0x2f, 0x5f, 0x21, 0x13, 0x41, 0xdc,
+ 0x63, 0xd3, 0xff, 0x3e, 0xe9, 0xe7, 0x6c, 0x96, 0x37, 0x93, 0xa7, 0xf8,
+ 0x7d, 0x70, 0x6b, 0x79, 0xa3, 0xa7, 0xfb, 0x9d, 0xb7, 0x1c, 0xef, 0x14,
+ 0x74, 0xff, 0xff, 0x67, 0xf7, 0x5a, 0x4a, 0x1b, 0x2e, 0xd4, 0x3c, 0xed,
+ 0x8e, 0x9e, 0xd7, 0x4b, 0x3e, 0x74, 0x5a, 0x88, 0x8c, 0x63, 0x9f, 0xfd,
+ 0xc6, 0x0d, 0x8a, 0xf5, 0x39, 0x41, 0x43, 0xa7, 0xe7, 0x2d, 0x7f, 0xad,
+ 0xa3, 0xa7, 0xfb, 0x78, 0xa1, 0xad, 0xe6, 0x8e, 0x9e, 0xaf, 0xf7, 0xc1,
+ 0xd0, 0xc8, 0x89, 0xb9, 0x86, 0x8d, 0xa7, 0xea, 0xd7, 0xff, 0x4f, 0x3a,
+ 0x7e, 0x1a, 0xd8, 0xd0, 0x1d, 0x3c, 0x35, 0x7e, 0x8e, 0x1e, 0xae, 0x8b,
+ 0x23, 0x95, 0xc8, 0x30, 0x8d, 0x8e, 0xd2, 0x94, 0x47, 0xf9, 0xc6, 0xe1,
+ 0x87, 0x72, 0x3d, 0x43, 0x4d, 0xd4, 0x21, 0x27, 0xfe, 0x11, 0xae, 0x9f,
+ 0xad, 0x8d, 0x38, 0x74, 0x32, 0xf2, 0x25, 0x4e, 0xb4, 0xe4, 0x26, 0x27,
+ 0xc2, 0xca, 0xce, 0x4e, 0x9f, 0xd4, 0xe6, 0xeb, 0x4d, 0xc9, 0xd3, 0xff,
+ 0xff, 0xdb, 0xad, 0x5f, 0x1c, 0xe8, 0x35, 0x6b, 0xeb, 0xdb, 0x06, 0xb9,
+ 0xda, 0x38, 0x74, 0xde, 0xf9, 0x3a, 0x3e, 0x89, 0xbd, 0x42, 0x0a, 0x7e,
+ 0xab, 0x06, 0xad, 0xb9, 0xd3, 0xff, 0xbf, 0x6b, 0xef, 0x4a, 0xb5, 0xb7,
+ 0xb6, 0x3a, 0x57, 0x3a, 0x3d, 0x3d, 0xbf, 0x09, 0x73, 0xf9, 0x94, 0x35,
+ 0xbc, 0xd1, 0xd3, 0xdd, 0x02, 0xce, 0x0e, 0x9f, 0xff, 0xf6, 0x85, 0xbb,
+ 0xb5, 0xf7, 0xf5, 0xb4, 0x35, 0xca, 0x57, 0xdc, 0x3a, 0x11, 0x54, 0x63,
+ 0x84, 0xd9, 0x0c, 0xe1, 0x28, 0xbc, 0x22, 0x3d, 0x25, 0x74, 0x61, 0xe0,
+ 0x96, 0x7c, 0xf4, 0xfd, 0x5a, 0x74, 0xfa, 0xaf, 0x65, 0x70, 0x74, 0x5a,
+ 0x79, 0xfb, 0x27, 0x9f, 0xff, 0x25, 0x94, 0x1c, 0xed, 0x2b, 0xcf, 0x4f,
+ 0x3e, 0xb1, 0xd3, 0xce, 0xda, 0xad, 0x9d, 0x3f, 0xff, 0xf3, 0xb5, 0xaf,
+ 0xcb, 0x7a, 0x0f, 0xae, 0xdd, 0x2a, 0xd7, 0xd7, 0xa3, 0xdd, 0xce, 0x8b,
+ 0x11, 0x4b, 0x44, 0x93, 0xff, 0xff, 0xe6, 0xb6, 0xfe, 0xb5, 0xbd, 0x37,
+ 0x5c, 0xf4, 0x1a, 0xf7, 0xcf, 0x4b, 0xf7, 0xda, 0x68, 0xe9, 0xf3, 0x0d,
+ 0xb9, 0x61, 0xd3, 0xff, 0xff, 0xff, 0xa9, 0x54, 0x0d, 0xb6, 0x56, 0xaa,
+ 0xf7, 0x6f, 0xfd, 0x86, 0xac, 0xaf, 0x6f, 0xeb, 0x82, 0xca, 0x3a, 0x7f,
+ 0xbb, 0xae, 0x46, 0xb7, 0x9a, 0x3a, 0x7f, 0x59, 0xeb, 0x69, 0x49, 0xa3,
+ 0xa7, 0xfc, 0xde, 0x5d, 0xbd, 0xa1, 0x73, 0xc2, 0x8e, 0x8a, 0x3f, 0xab,
+ 0x4d, 0x27, 0xff, 0xab, 0x5c, 0xd5, 0x77, 0x7e, 0x9f, 0xbf, 0x37, 0x3a,
+ 0x7a, 0xc4, 0x1d, 0x1d, 0x0c, 0xaf, 0xaa, 0x88, 0xd2, 0x30, 0x0f, 0x91,
+ 0xaa, 0x12, 0x3b, 0x27, 0xc8, 0x51, 0x8c, 0x2c, 0xae, 0x45, 0xea, 0xa4,
+ 0xee, 0x7a, 0x38, 0x74, 0xff, 0xf5, 0xaf, 0x16, 0xe8, 0xa1, 0x6f, 0x3a,
+ 0x4b, 0x0e, 0x8a, 0x3f, 0x34, 0x20, 0x9f, 0xac, 0x71, 0xfd, 0x67, 0xec,
+ 0x3a, 0x7c, 0xa4, 0xe6, 0xb9, 0x3a, 0x4e, 0x1d, 0x33, 0x28, 0xe9, 0x68,
+ 0xe8, 0xf9, 0xa5, 0xc1, 0x58, 0xe4, 0xf5, 0xb6, 0x6d, 0x3d, 0xab, 0xe5,
+ 0xa7, 0x4c, 0xe6, 0x1d, 0x3f, 0xb6, 0x9f, 0xb5, 0xe2, 0xc7, 0x47, 0x5b,
+ 0x4d, 0x05, 0x8d, 0xa9, 0xf9, 0x08, 0xd4, 0x45, 0xe8, 0xb4, 0xfe, 0xba,
+ 0x5b, 0xc6, 0x0f, 0x67, 0x4f, 0xff, 0x9b, 0xec, 0x14, 0xa6, 0x07, 0xa5,
+ 0xfd, 0x51, 0xd0, 0xe2, 0x21, 0xba, 0x8d, 0x27, 0xef, 0xd3, 0x79, 0x61,
+ 0x3a, 0x70, 0xe2, 0x8e, 0x9b, 0xb6, 0x3a, 0x1e, 0x7b, 0x88, 0x58, 0x23,
+ 0x50, 0xef, 0x3b, 0x4a, 0x6e, 0xb2, 0x37, 0x36, 0x94, 0xb7, 0x63, 0xdb,
+ 0xcb, 0x39, 0x95, 0x27, 0x53, 0xda, 0x7e, 0x61, 0x96, 0x12, 0xf9, 0x2d,
+ 0x8e, 0x91, 0x23, 0x08, 0x72, 0x1b, 0x5f, 0x95, 0x40, 0xa8, 0xd0, 0xf7,
+ 0x3e, 0x5b, 0x91, 0xb9, 0x0c, 0xf4, 0x75, 0xe5, 0x64, 0xea, 0x72, 0xe5,
+ 0xd4, 0x62, 0x3d, 0x51, 0xb0, 0xf8, 0x87, 0x13, 0xb4, 0x20, 0xe7, 0xff,
+ 0xef, 0x41, 0x76, 0xeb, 0xed, 0x56, 0xf5, 0x9c, 0xe6, 0x79, 0x3a, 0x16,
+ 0xa8, 0xcd, 0x23, 0xcf, 0x9f, 0xcb, 0xaf, 0x86, 0x60, 0x1a, 0x29, 0xd9,
+ 0xf7, 0xc3, 0x30, 0x0d, 0x15, 0x1c, 0xff, 0xb1, 0xeb, 0xaf, 0x86, 0x60,
+ 0x1a, 0x26, 0x89, 0x2e, 0x8f, 0xe1, 0x46, 0x33, 0xf9, 0x75, 0xf0, 0xcc,
+ 0x03, 0x45, 0x5f, 0x3e, 0xf8, 0x66, 0x01, 0xa2, 0xb6, 0x9f, 0xe7, 0xae,
+ 0xbe, 0x19, 0x80, 0x68, 0x90, 0x64, 0xba, 0x3f, 0x3c, 0x31, 0x9f, 0xf9,
+ 0x78, 0xf5, 0xd7, 0xc3, 0x30, 0x0d, 0x12, 0x1c, 0xff, 0x9f, 0xb6, 0xd5,
+ 0xdd, 0xd5, 0xdd, 0xe1, 0x3a, 0x7d, 0x54, 0x3d, 0xdc, 0xe9, 0xf7, 0xc3,
+ 0x30, 0x0d, 0x16, 0x24, 0xfa, 0xbe, 0xc3, 0xe4, 0xe9, 0xf7, 0x8e, 0xaa,
+ 0xfb, 0x1d, 0x3a, 0xec, 0x27, 0x4b, 0x6c, 0x78, 0xa8, 0x57, 0x3f, 0xf3,
+ 0x55, 0xe8, 0x79, 0x4e, 0xd8, 0x4e, 0x9c, 0x2d, 0x61, 0xd2, 0x78, 0x9e,
+ 0xe7, 0xa8, 0x33, 0xba, 0x93, 0xb3, 0xa7, 0xc8, 0xeb, 0xdc, 0xb9, 0xd3,
+ 0xff, 0x3a, 0xf6, 0xad, 0xe5, 0xd6, 0xeb, 0x1c, 0x3a, 0x66, 0x79, 0xd1,
+ 0x47, 0xc1, 0xf4, 0xb9, 0xfd, 0x5f, 0x7f, 0x75, 0x4e, 0x1d, 0x3e, 0xc7,
+ 0xf8, 0xdb, 0x1d, 0x3f, 0x5e, 0xff, 0x4e, 0x3a, 0xe7, 0x43, 0x22, 0x35,
+ 0x0c, 0xf0, 0xa2, 0x7f, 0xf9, 0xec, 0xa6, 0x7f, 0x22, 0xdb, 0xca, 0xf9,
+ 0xd3, 0xf8, 0x06, 0x9d, 0x0d, 0x5c, 0xe8, 0xb4, 0xff, 0xb6, 0x9b, 0x3f,
+ 0xbb, 0x6a, 0xd2, 0x0f, 0x05, 0x4f, 0xab, 0x76, 0xe7, 0x5c, 0xe9, 0xee,
+ 0xee, 0xc2, 0x74, 0xfe, 0xfe, 0xf1, 0x2e, 0x8e, 0x8e, 0x86, 0x3d, 0x4a,
+ 0x21, 0x81, 0x44, 0xfd, 0xdf, 0xe7, 0xec, 0xb3, 0x4d, 0x6b, 0xce, 0x9f,
+ 0xf0, 0xb2, 0x73, 0xa1, 0xcb, 0x6e, 0x74, 0x3b, 0xcb, 0xa7, 0x1c, 0xa4,
+ 0xd1, 0x37, 0x93, 0x10, 0x6c, 0xb6, 0x10, 0x48, 0x50, 0xe0, 0xff, 0xe1,
+ 0x13, 0xb8, 0x57, 0x64, 0x2a, 0xfb, 0x23, 0xbc, 0x34, 0x74, 0x45, 0xe0,
+ 0xba, 0x7f, 0xed, 0xa3, 0x6b, 0x79, 0xe6, 0x87, 0xb3, 0xa7, 0xff, 0xaa,
+ 0xd7, 0xeb, 0xdb, 0x17, 0xbc, 0x52, 0x5c, 0xe9, 0xb6, 0xba, 0x44, 0xb0,
+ 0xa2, 0x42, 0xd3, 0xb4, 0x68, 0xe1, 0xe7, 0xf2, 0xeb, 0xe1, 0x98, 0x06,
+ 0x8b, 0x36, 0x6a, 0xe4, 0xe9, 0xff, 0x63, 0xd7, 0x5f, 0x0c, 0xc0, 0x34,
+ 0x50, 0x12, 0x5d, 0x1e, 0xea, 0x85, 0xa6, 0xf7, 0x67, 0x4f, 0xd7, 0x65,
+ 0x0b, 0x38, 0x74, 0xb6, 0x74, 0xef, 0x02, 0xe1, 0xd3, 0x56, 0xa8, 0xd7,
+ 0x76, 0x21, 0x1d, 0xa2, 0x18, 0x56, 0xa6, 0xe9, 0x73, 0xa7, 0xfb, 0x75,
+ 0xfd, 0x0b, 0x2a, 0xe7, 0x4f, 0x06, 0x60, 0x1a, 0x2d, 0xf9, 0xfb, 0xc6,
+ 0xb0, 0x33, 0xe7, 0x47, 0xcf, 0x63, 0xb2, 0xb9, 0xea, 0x14, 0x70, 0xe9,
+ 0xf6, 0x9f, 0x7f, 0x17, 0x3a, 0x7e, 0x75, 0xe3, 0x42, 0xdd, 0x9d, 0x3e,
+ 0xe5, 0xba, 0xfe, 0xa8, 0xe8, 0x63, 0xde, 0x43, 0x19, 0xec, 0x41, 0xd1,
+ 0xd3, 0xfb, 0xdb, 0x6e, 0xc1, 0x4a, 0x3a, 0x7b, 0x7e, 0x79, 0x51, 0xd3,
+ 0x53, 0xce, 0x8a, 0x37, 0x42, 0x4b, 0x25, 0xbb, 0xca, 0xbf, 0x5a, 0x13,
+ 0xaf, 0x23, 0xe4, 0x62, 0xa1, 0x1e, 0x84, 0x7f, 0x20, 0xdc, 0x22, 0x3b,
+ 0x20, 0x11, 0xfd, 0x36, 0xcf, 0xfb, 0x1e, 0xba, 0xf8, 0x66, 0x01, 0xa2,
+ 0x94, 0x9f, 0xe7, 0xae, 0xbe, 0x19, 0x80, 0x68, 0x93, 0xa4, 0xb5, 0x22,
+ 0x27, 0x11, 0xe1, 0x9f, 0x1c, 0x52, 0xc8, 0xdb, 0x39, 0xb6, 0xe9, 0x94,
+ 0x54, 0x10, 0xb4, 0x42, 0x7e, 0xbc, 0x2b, 0xdc, 0x26, 0x54, 0xf9, 0xce,
+ 0xca, 0x7b, 0x84, 0xcd, 0xe5, 0x92, 0x3a, 0x8c, 0xee, 0x7d, 0xf0, 0xcc,
+ 0x03, 0x44, 0x3f, 0x3f, 0xec, 0x7a, 0xeb, 0xe1, 0x98, 0x06, 0x89, 0x4e,
+ 0x4b, 0xa3, 0xf8, 0x51, 0x8c, 0xfe, 0x5d, 0x7c, 0x33, 0x00, 0xd1, 0x13,
+ 0xcf, 0xe5, 0xd7, 0xc3, 0x30, 0x0d, 0x11, 0x8c, 0xff, 0xe5, 0xab, 0x1e,
+ 0xba, 0xf8, 0x66, 0x01, 0xa2, 0x79, 0x86, 0x47, 0x95, 0x84, 0xef, 0x3c,
+ 0xd9, 0xe4, 0xfb, 0xe1, 0x98, 0x06, 0x88, 0x82, 0x7f, 0xd8, 0xf5, 0xd7,
+ 0xc3, 0x30, 0x0d, 0x12, 0xa4, 0x97, 0x47, 0xf0, 0xa3, 0x19, 0xfc, 0xba,
+ 0xf8, 0x66, 0x01, 0xa2, 0x28, 0x9f, 0xcb, 0xaf, 0x86, 0x60, 0x1a, 0x23,
+ 0x29, 0xff, 0xcb, 0x56, 0x3d, 0x75, 0xf0, 0xcc, 0x03, 0x44, 0xcb, 0x3f,
+ 0x97, 0x5f, 0x0c, 0xc0, 0x34, 0x54, 0x93, 0xf9, 0x75, 0xf0, 0xcc, 0x03,
+ 0x45, 0x75, 0x3f, 0x97, 0x5f, 0x0c, 0xc0, 0x34, 0x58, 0xb3, 0xff, 0x2b,
+ 0x1e, 0xba, 0xf8, 0x66, 0x01, 0xa2, 0x7a, 0x9f, 0xee, 0x17, 0x8c, 0x9d,
+ 0x48, 0xec, 0x74, 0x2d, 0x11, 0x4c, 0x9b, 0x3f, 0x75, 0xaf, 0x5a, 0x4f,
+ 0x6e, 0x74, 0xf7, 0xd5, 0xab, 0x4e, 0x9c, 0x15, 0xb2, 0xa7, 0x29, 0xae,
+ 0x74, 0xff, 0xfd, 0xb1, 0xcf, 0x29, 0xf6, 0x7b, 0xea, 0xfd, 0xf6, 0xc7,
+ 0x4f, 0xff, 0xdf, 0x47, 0x6c, 0x52, 0xdb, 0xff, 0x47, 0x60, 0xf6, 0xc3,
+ 0xa7, 0xc0, 0x9b, 0xf0, 0xa3, 0xa7, 0xff, 0x65, 0xc6, 0xbb, 0x5e, 0xd0,
+ 0x33, 0xe7, 0x4f, 0xb5, 0xb6, 0x50, 0x1d, 0x3f, 0xf8, 0x7a, 0x33, 0x0b,
+ 0x2b, 0xa7, 0x4d, 0xf5, 0x1d, 0x36, 0x5a, 0x74, 0xfe, 0xcb, 0xe6, 0xfd,
+ 0x1b, 0x0e, 0x81, 0x3c, 0x9f, 0x45, 0xa2, 0xc5, 0x45, 0x08, 0x37, 0xf5,
+ 0xc5, 0x30, 0xec, 0xa0, 0x51, 0xf4, 0x4c, 0xed, 0x09, 0x99, 0xc3, 0x9a,
+ 0x3a, 0x70, 0xa5, 0xce, 0x97, 0x0e, 0xf9, 0xb4, 0x61, 0xa9, 0xef, 0xba,
+ 0xc5, 0x1d, 0x14, 0x79, 0xe8, 0x59, 0x3f, 0xe4, 0xde, 0x69, 0x9c, 0xba,
+ 0x28, 0xe9, 0xf0, 0xf9, 0x4a, 0xb9, 0xd3, 0xff, 0x57, 0x19, 0xdd, 0x06,
+ 0xf3, 0xbb, 0x9d, 0x08, 0x7d, 0x62, 0x4f, 0x39, 0x4d, 0xb3, 0xa7, 0x87,
+ 0x9e, 0x9e, 0x4e, 0x9f, 0xaa, 0xfc, 0x60, 0xd8, 0x74, 0x51, 0xf7, 0x60,
+ 0xd8, 0x93, 0x4f, 0xbd, 0xf3, 0x7e, 0x58, 0xe8, 0xa4, 0x72, 0xa4, 0x23,
+ 0xb6, 0x59, 0x3f, 0xff, 0xfb, 0x6c, 0x9f, 0xfb, 0x78, 0xd2, 0x0f, 0xaf,
+ 0xab, 0xf3, 0xee, 0x7d, 0xe7, 0x4f, 0xac, 0xe7, 0xe9, 0xc1, 0xd3, 0xf7,
+ 0x39, 0xfe, 0xfa, 0xa8, 0xe9, 0xff, 0x0a, 0x3f, 0x5b, 0xaf, 0xa5, 0xce,
+ 0x9f, 0xf6, 0x57, 0x6c, 0x39, 0xcd, 0x79, 0x3a, 0x1e, 0x7f, 0x5d, 0x9e,
+ 0x4f, 0xec, 0xb6, 0xfa, 0xd5, 0x75, 0xce, 0x9f, 0xfc, 0xd5, 0x6e, 0xb6,
+ 0xda, 0x16, 0xee, 0xe7, 0x4e, 0xbe, 0xd4, 0x74, 0x68, 0xf9, 0x7d, 0x49,
+ 0x9f, 0xbd, 0xbe, 0xaf, 0x5a, 0x3a, 0x77, 0x1c, 0x70, 0x54, 0xff, 0xed,
+ 0x26, 0xaf, 0xb4, 0xea, 0xf1, 0xf6, 0x79, 0x4b, 0x2f, 0xe1, 0x11, 0x55,
+ 0xea, 0x6c, 0x3d, 0x57, 0xf5, 0x3d, 0x21, 0x57, 0xe1, 0x56, 0xa2, 0x31,
+ 0x84, 0xe6, 0xa1, 0x9b, 0x3f, 0xd6, 0xbe, 0xf7, 0xae, 0x73, 0x47, 0x4a,
+ 0x8e, 0x86, 0x3c, 0x9f, 0x27, 0x53, 0xee, 0x34, 0xd6, 0xf0, 0x74, 0xe0,
+ 0xe3, 0x67, 0x4f, 0xe6, 0xcf, 0xef, 0x8c, 0xe4, 0xa9, 0xb8, 0xe0, 0xa8,
+ 0xe4, 0xf2, 0xf8, 0x33, 0x9d, 0xa4, 0xeb, 0x94, 0xb3, 0x49, 0x3d, 0xeb,
+ 0xfd, 0xd1, 0xd1, 0x73, 0xd3, 0xea, 0x2f, 0x9b, 0x8b, 0x9d, 0x2a, 0x3a,
+ 0x56, 0xd1, 0xa6, 0xd0, 0xbc, 0xff, 0xd7, 0xbf, 0x22, 0xdc, 0xed, 0xb5,
+ 0x73, 0xa1, 0x8f, 0xb3, 0xd2, 0x79, 0xff, 0x69, 0x3f, 0x9d, 0xbb, 0x6a,
+ 0xb6, 0x74, 0xfe, 0xcf, 0xea, 0xe2, 0x9e, 0x4e, 0x87, 0xa2, 0x59, 0x08,
+ 0xb1, 0x06, 0x75, 0x27, 0xce, 0x9e, 0xcf, 0xb3, 0xce, 0x8b, 0x0d, 0xd2,
+ 0x86, 0xa7, 0xfc, 0xd6, 0xed, 0x94, 0x1b, 0x47, 0x0e, 0x8a, 0x3e, 0x0f,
+ 0x91, 0x4f, 0xda, 0x6f, 0xf3, 0x42, 0x74, 0xfe, 0xe7, 0x6c, 0x3c, 0x65,
+ 0xa7, 0x4f, 0xfc, 0x9c, 0xed, 0x81, 0xbb, 0xc1, 0xec, 0xe9, 0xff, 0xff,
+ 0x22, 0xb0, 0x6d, 0x7a, 0xf8, 0xa4, 0x75, 0x43, 0x5c, 0xe3, 0xcf, 0x17,
+ 0xac, 0x32, 0x63, 0x98, 0x59, 0x73, 0x4f, 0x50, 0xe7, 0xff, 0xab, 0x57,
+ 0xa7, 0x36, 0xce, 0xab, 0x7b, 0x63, 0xa7, 0xff, 0xff, 0xc9, 0x56, 0xdd,
+ 0x2b, 0x8e, 0x95, 0x6b, 0xee, 0x9a, 0xba, 0x5b, 0xcf, 0x3e, 0xd8, 0x74,
+ 0xff, 0xf9, 0x07, 0x9e, 0x9e, 0x34, 0x97, 0xc4, 0x1f, 0x5e, 0x74, 0x0a,
+ 0x66, 0x7a, 0x50, 0x75, 0x08, 0xb9, 0xb3, 0x93, 0xa7, 0xef, 0xe5, 0xf7,
+ 0x8f, 0x3a, 0x56, 0x9d, 0x32, 0x70, 0x74, 0xde, 0x3b, 0x3a, 0x1c, 0x35,
+ 0xfd, 0x8b, 0x4e, 0x7e, 0x72, 0x74, 0xdc, 0x70, 0x74, 0x3d, 0x1b, 0x34,
+ 0x2c, 0x05, 0x88, 0x81, 0x72, 0x3e, 0x07, 0x27, 0x6b, 0xc7, 0x65, 0x2c,
+ 0xf5, 0x67, 0xff, 0xff, 0x69, 0xb9, 0xdf, 0xb9, 0xe5, 0x59, 0xcd, 0x50,
+ 0xf9, 0xbd, 0xe8, 0x7b, 0x3a, 0x2d, 0x45, 0x62, 0x18, 0x4f, 0xf5, 0x6b,
+ 0x6d, 0xfd, 0x50, 0x1d, 0x39, 0xbe, 0xe1, 0xd1, 0x4a, 0xa1, 0xb2, 0x50,
+ 0x88, 0x91, 0xf5, 0x1b, 0x4e, 0xbe, 0x38, 0x74, 0xf5, 0x6b, 0x1d, 0x8e,
+ 0x8b, 0x4d, 0xf8, 0x8e, 0x4f, 0xfd, 0x5f, 0xfd, 0x39, 0xba, 0xbe, 0x09,
+ 0xd3, 0xf8, 0x5b, 0xfe, 0x86, 0xd8, 0xe9, 0xf2, 0x79, 0xde, 0x3c, 0xe9,
+ 0xf9, 0x19, 0x56, 0x57, 0x07, 0x4d, 0xc7, 0x07, 0x40, 0x1f, 0x6f, 0xca,
+ 0x38, 0x2d, 0x9f, 0xea, 0x73, 0x1c, 0xcb, 0x5f, 0x72, 0x96, 0x6b, 0xe7,
+ 0xfa, 0xab, 0xba, 0x71, 0xad, 0xb9, 0xd3, 0xff, 0xa8, 0x7b, 0xad, 0xa5,
+ 0xb7, 0xdf, 0xb7, 0x3a, 0x7e, 0x1c, 0xef, 0x9a, 0x13, 0xa7, 0xe5, 0x27,
+ 0x55, 0x7f, 0xc9, 0xd3, 0xb8, 0xe3, 0x82, 0xa7, 0xfe, 0x6f, 0x8f, 0xb9,
+ 0xe2, 0x9c, 0x65, 0x1c, 0xb2, 0xfe, 0x3a, 0xea, 0x9a, 0xdc, 0x86, 0x68,
+ 0xa5, 0x5c, 0xe7, 0x49, 0x7e, 0x96, 0x70, 0xa1, 0x3f, 0xfe, 0xce, 0x6a,
+ 0x87, 0xcf, 0x81, 0x61, 0xb1, 0x3e, 0x74, 0xec, 0xfd, 0x87, 0x90, 0x4a,
+ 0x79, 0xf5, 0x6b, 0xcf, 0x20, 0x94, 0xeb, 0xa7, 0x27, 0x90, 0x4a, 0x6e,
+ 0x38, 0x3c, 0x82, 0x50, 0x08, 0xa6, 0x70, 0xa7, 0x45, 0xfc, 0x14, 0xcd,
+ 0x9a, 0x2c, 0x82, 0x45, 0x9b, 0xe9, 0xfa, 0xb7, 0x54, 0x3e, 0x4e, 0x9d,
+ 0x83, 0xda, 0x93, 0x99, 0x18, 0xce, 0xb4, 0x67, 0x3d, 0xd5, 0x59, 0xb3,
+ 0xa5, 0x5d, 0x73, 0xea, 0xed, 0x1e, 0x7f, 0x38, 0xff, 0x6c, 0xd2, 0x58,
+ 0x54, 0xfe, 0x47, 0xfb, 0x97, 0xda, 0x1d, 0x27, 0x95, 0x3b, 0x3f, 0x61,
+ 0x50, 0x54, 0x31, 0xb6, 0x01, 0x05, 0x0e, 0x4f, 0x0b, 0x76, 0x05, 0x2c,
+ 0xd6, 0x43, 0x23, 0x12, 0xa1, 0x29, 0x3d, 0xee, 0x7d, 0xe7, 0x49, 0x47,
+ 0x4d, 0x4f, 0xe4, 0xd9, 0x38, 0x45, 0x3e, 0xe2, 0x9c, 0x45, 0x1d, 0x3f,
+ 0x03, 0x38, 0xf6, 0xec, 0xa9, 0x21, 0xd3, 0xfd, 0x67, 0xaf, 0xe7, 0x7e,
+ 0xe0, 0x9d, 0x3f, 0x23, 0x2a, 0xca, 0xe0, 0xe9, 0xf5, 0x58, 0xaa, 0x51,
+ 0xd3, 0xae, 0x9f, 0x3a, 0x04, 0xf0, 0xb4, 0x4f, 0x3f, 0x0e, 0x77, 0xdf,
+ 0xb7, 0x3a, 0x7e, 0x4f, 0x3e, 0x19, 0x4b, 0xe5, 0x30, 0xaa, 0x0f, 0xf9,
+ 0xe5, 0xdb, 0xf4, 0x43, 0x14, 0x9e, 0x82, 0x14, 0x0c, 0x66, 0xf3, 0xc3,
+ 0x56, 0x7a, 0x74, 0x3d, 0x5e, 0x9d, 0x16, 0x6e, 0x1f, 0x62, 0xb1, 0x78,
+ 0xff, 0xb4, 0x69, 0x3f, 0xfe, 0xb3, 0xff, 0xae, 0x71, 0x5b, 0xcd, 0x0b,
+ 0x38, 0x74, 0xff, 0xff, 0xef, 0x7f, 0xeb, 0x83, 0x9d, 0xde, 0xf5, 0xe6,
+ 0xbd, 0xfe, 0x72, 0xdb, 0x63, 0xa7, 0x71, 0xc7, 0x05, 0x4c, 0xf6, 0x29,
+ 0x65, 0xfc, 0x32, 0x62, 0xd6, 0x2b, 0x7e, 0x13, 0x93, 0xf5, 0x8e, 0x3f,
+ 0xac, 0xfd, 0x87, 0x4f, 0x6f, 0x2d, 0xe0, 0xe9, 0xf5, 0x9f, 0x46, 0x51,
+ 0xd3, 0xff, 0xcd, 0xe3, 0x42, 0xdd, 0xe6, 0xbb, 0xf0, 0x2f, 0x3a, 0x3a,
+ 0xda, 0x34, 0xd0, 0xdb, 0x08, 0xf4, 0x4f, 0x3b, 0xc7, 0x2e, 0x1d, 0x39,
+ 0xe8, 0x27, 0x4f, 0xda, 0x67, 0x07, 0xdb, 0x9d, 0x16, 0x1f, 0x43, 0xc8,
+ 0x34, 0x35, 0x36, 0x5c, 0xe9, 0xbd, 0x77, 0x0e, 0x81, 0x36, 0x3e, 0x8a,
+ 0xcd, 0x8b, 0x77, 0x9b, 0xee, 0xa7, 0x76, 0x6d, 0xd6, 0xb1, 0x1b, 0x4a,
+ 0x42, 0xb2, 0x1f, 0xaf, 0x20, 0xe6, 0x38, 0xda, 0x96, 0x63, 0xe6, 0x17,
+ 0x60, 0x47, 0x69, 0x52, 0x43, 0x79, 0xc8, 0xd3, 0x7f, 0x0c, 0x85, 0x46,
+ 0x7b, 0xb9, 0x7e, 0xd9, 0x08, 0x51, 0x21, 0xbc, 0xaa, 0xdd, 0x4f, 0x23,
+ 0xfb, 0x1b, 0xc7, 0x54, 0x61, 0x3e, 0x21, 0x52, 0xec, 0xc3, 0x3f, 0xf9,
+ 0x6a, 0xc7, 0xae, 0xbe, 0x19, 0x80, 0x68, 0xa2, 0xa7, 0xf2, 0xeb, 0xe1,
+ 0x98, 0x06, 0x8b, 0xa2, 0x7f, 0xe5, 0xe3, 0xd7, 0x5f, 0x0c, 0xc0, 0x34,
+ 0x49, 0x73, 0xf9, 0x75, 0xf0, 0xcc, 0x03, 0x45, 0xe5, 0x0c, 0xe9, 0x08,
+ 0xac, 0x27, 0x79, 0xe5, 0x1e, 0x02, 0x9b, 0x87, 0x8a, 0x3c, 0xdc, 0x31,
+ 0x86, 0xbf, 0x0c, 0xbc, 0x79, 0xda, 0x53, 0xf4, 0xf1, 0xd2, 0x6c, 0xff,
+ 0xe5, 0xab, 0x1e, 0xba, 0xf8, 0x66, 0x01, 0xa2, 0x59, 0x9b, 0xdd, 0x9d,
+ 0x3c, 0x19, 0x80, 0x68, 0x8c, 0xe7, 0xe4, 0x65, 0x59, 0x5c, 0x1d, 0x30,
+ 0xbc, 0xe9, 0x28, 0xe9, 0xf2, 0x7f, 0x78, 0xbf, 0x9e, 0x92, 0x8b, 0x7c,
+ 0x0a, 0xcf, 0xd8, 0xf4, 0xfe, 0x7c, 0xe9, 0xff, 0xae, 0x9e, 0xde, 0x87,
+ 0xd7, 0xd5, 0xce, 0x9d, 0x76, 0xb4, 0xe8, 0xfa, 0x6a, 0xaa, 0x7d, 0x14,
+ 0xdb, 0x95, 0xe9, 0x12, 0x7f, 0xed, 0x27, 0xf3, 0xbe, 0x96, 0xbd, 0x94,
+ 0x74, 0xf8, 0x59, 0xf7, 0xc3, 0xa1, 0x0f, 0xb1, 0xd2, 0x3c, 0xec, 0xf0,
+ 0xf3, 0xa7, 0xff, 0xbd, 0xd5, 0xed, 0x7b, 0x0f, 0x77, 0xe9, 0xe8, 0x9d,
+ 0x39, 0xb4, 0xc7, 0x49, 0x39, 0x3e, 0xf7, 0x4a, 0xb3, 0xfd, 0x96, 0xdc,
+ 0x6b, 0xfc, 0xb1, 0xd3, 0xff, 0x52, 0xb4, 0x9c, 0x5d, 0xb7, 0x9d, 0x73,
+ 0xa7, 0xfd, 0xb6, 0x4d, 0xa3, 0x0b, 0x9e, 0x9d, 0x3f, 0xaa, 0xed, 0xab,
+ 0xed, 0x0e, 0x92, 0xdd, 0xe5, 0x7d, 0x15, 0x1b, 0x63, 0x90, 0xb6, 0xd9,
+ 0x1e, 0x42, 0x33, 0xb2, 0xa1, 0x38, 0xba, 0x3f, 0x51, 0xec, 0xff, 0xe5,
+ 0xab, 0x1e, 0xba, 0xf8, 0x66, 0x01, 0xa2, 0x69, 0x9f, 0xfc, 0xb5, 0x63,
+ 0xd7, 0x5f, 0x0c, 0xc0, 0x34, 0x4e, 0x33, 0xff, 0x96, 0xac, 0x7a, 0xeb,
+ 0xe1, 0x98, 0x06, 0x8a, 0x06, 0x7d, 0xf0, 0xcc, 0x03, 0x45, 0xc1, 0x33,
+ 0x21, 0xd3, 0xf8, 0x5e, 0xc9, 0xcd, 0x28, 0xe9, 0x2e, 0x8f, 0xdb, 0x66,
+ 0x3e, 0x8a, 0x4f, 0xe4, 0x5f, 0x86, 0xee, 0xb8, 0x3a, 0x7f, 0x9e, 0xba,
+ 0xf8, 0x66, 0x01, 0xa2, 0x49, 0x92, 0xf6, 0x7e, 0xf8, 0x6b, 0x3e, 0xc5,
+ 0xf3, 0xc7, 0x67, 0x45, 0x8b, 0xe8, 0x8f, 0x9c, 0x3b, 0x08, 0x4e, 0xb8,
+ 0xa7, 0xda, 0x9d, 0xe1, 0x93, 0xa8, 0x56, 0x3a, 0x27, 0x9f, 0xf7, 0x9c,
+ 0x5d, 0x7c, 0x33, 0x00, 0xd1, 0x6a, 0x4f, 0xfb, 0x1e, 0xba, 0xf8, 0x66,
+ 0x01, 0xa2, 0x55, 0x83, 0xa4, 0xbf, 0x28, 0x9a, 0x52, 0x4b, 0xb2, 0x3c,
+ 0xfe, 0x5d, 0x7c, 0x33, 0x00, 0xd1, 0x14, 0xcf, 0xe5, 0xd7, 0xc3, 0x30,
+ 0x0d, 0x11, 0xa4, 0xde, 0xec, 0xe9, 0xe0, 0xcc, 0x03, 0x45, 0x3f, 0x36,
+ 0x98, 0xe8, 0xf9, 0xe0, 0x68, 0xae, 0x7f, 0xef, 0x75, 0xff, 0x5c, 0xb8,
+ 0x63, 0x97, 0x3a, 0x7f, 0xea, 0x73, 0xd1, 0xb2, 0xe1, 0x8e, 0x5c, 0xe9,
+ 0x2d, 0xde, 0x4c, 0x1e, 0x95, 0xc4, 0x8b, 0x49, 0x13, 0xff, 0x96, 0xac,
+ 0x7a, 0xeb, 0xe1, 0x98, 0x06, 0x89, 0xaa, 0x7f, 0x2e, 0xbe, 0x19, 0x80,
+ 0x68, 0xae, 0xe7, 0x83, 0x30, 0x0d, 0x15, 0xf4, 0xee, 0x38, 0xe0, 0xa9,
+ 0x09, 0x4b, 0x2f, 0xe3, 0xe7, 0xd0, 0xa4, 0xa9, 0xcf, 0x6b, 0x4e, 0x9c,
+ 0xe5, 0x6c, 0xe9, 0xff, 0x56, 0xf8, 0xcd, 0x5d, 0xaa, 0xc3, 0xa5, 0xa3,
+ 0xa7, 0xf9, 0x3f, 0x56, 0x23, 0xeb, 0x93, 0xa3, 0xe7, 0x91, 0x82, 0x12,
+ 0x5d, 0x26, 0x02, 0xe1, 0x16, 0x0e, 0x08, 0xe5, 0xe1, 0x0d, 0x3f, 0xf9,
+ 0x6a, 0xc7, 0xae, 0xbe, 0x19, 0x80, 0x68, 0x9e, 0xe7, 0xf2, 0xeb, 0xe1,
+ 0x98, 0x06, 0x8b, 0x86, 0x7f, 0xe5, 0xe3, 0xd7, 0x5f, 0x0c, 0xc0, 0x34,
+ 0x49, 0xf0, 0xcb, 0xa5, 0x36, 0x1d, 0xbc, 0xf3, 0xcc, 0x68, 0x60, 0x8e,
+ 0xe2, 0x9f, 0xe3, 0xa5, 0xda, 0xa5, 0xd4, 0xdd, 0x1e, 0x4f, 0xe5, 0xd7,
+ 0xc3, 0x30, 0x0d, 0x11, 0x54, 0xfe, 0x5d, 0x7c, 0x33, 0x00, 0xd1, 0x4c,
+ 0xcf, 0xfe, 0x5a, 0xb1, 0xeb, 0xaf, 0x86, 0x60, 0x1a, 0x26, 0x79, 0xff,
+ 0xcb, 0x56, 0x3d, 0x75, 0xf0, 0xcc, 0x03, 0x45, 0x1b, 0x16, 0x26, 0x3d,
+ 0xc9, 0xe7, 0x93, 0xcd, 0x29, 0xcf, 0xfc, 0xbc, 0x7a, 0xeb, 0xe1, 0x98,
+ 0x06, 0x88, 0xea, 0x6f, 0x76, 0x74, 0xfc, 0x94, 0x3c, 0xd5, 0x87, 0x4f,
+ 0xbe, 0x19, 0x80, 0x68, 0xa6, 0xa7, 0xff, 0x6d, 0x35, 0x7c, 0xb6, 0x9c,
+ 0x6d, 0xdc, 0xe9, 0xff, 0x9f, 0xb4, 0x1b, 0x2f, 0xeb, 0x7d, 0xc3, 0xa6,
+ 0x6f, 0x27, 0x4f, 0xc8, 0xca, 0xb2, 0xb8, 0x3a, 0x7f, 0xfa, 0xb5, 0xba,
+ 0x7f, 0xf0, 0x75, 0xbc, 0x79, 0xd3, 0x37, 0x67, 0x4f, 0xec, 0xb5, 0x81,
+ 0x01, 0x7f, 0x44, 0x80, 0x96, 0xf8, 0x4d, 0x8d, 0xa3, 0xfa, 0xf0, 0xa7,
+ 0x92, 0xdd, 0xe5, 0x45, 0x5c, 0x8b, 0xd1, 0x60, 0x18, 0xda, 0x95, 0xa8,
+ 0xd1, 0x27, 0xdf, 0x0c, 0xc0, 0x34, 0x55, 0x53, 0xfe, 0xc7, 0xae, 0xbe,
+ 0x19, 0x80, 0x68, 0x9b, 0x64, 0xba, 0x3f, 0x85, 0x18, 0xcf, 0xe5, 0xd7,
+ 0xc3, 0x30, 0x0d, 0x15, 0xfc, 0xfe, 0x5d, 0x7c, 0x33, 0x00, 0xd1, 0x63,
+ 0x4f, 0xbe, 0x19, 0x80, 0x68, 0xb5, 0x67, 0xfd, 0x8f, 0x5d, 0x7c, 0x33,
+ 0x00, 0xd1, 0x41, 0x49, 0x74, 0x7f, 0x0a, 0x31, 0x9f, 0x7c, 0x33, 0x00,
+ 0xd1, 0x71, 0x4f, 0x63, 0xb2, 0x58, 0x74, 0xf3, 0xb3, 0xb2, 0x01, 0xd3,
+ 0xf9, 0x95, 0x8e, 0x9b, 0xee, 0xc7, 0x49, 0x74, 0x8b, 0x1d, 0x98, 0xe1,
+ 0x26, 0x89, 0xa7, 0xdf, 0x0c, 0xc0, 0x34, 0x5d, 0x33, 0xe6, 0x1c, 0xe5,
+ 0x8e, 0x92, 0xe8, 0xf5, 0x90, 0xc6, 0x7f, 0xfe, 0x52, 0xe9, 0xed, 0xfe,
+ 0xfa, 0x5f, 0x6c, 0xac, 0x13, 0xa7, 0xff, 0xed, 0x8f, 0xb9, 0xd7, 0xa7,
+ 0xee, 0xbc, 0xd7, 0x2e, 0x7a, 0x74, 0xc1, 0x47, 0x43, 0x1f, 0xbf, 0x96,
+ 0x39, 0xff, 0x3e, 0xbf, 0xfc, 0x7d, 0x95, 0xc1, 0xd3, 0x87, 0x17, 0xf3,
+ 0xe2, 0xd1, 0x1c, 0xff, 0xbe, 0xd6, 0xef, 0x2f, 0xa6, 0xe0, 0xe9, 0xbd,
+ 0xd9, 0xd3, 0xe1, 0xad, 0xe6, 0x8e, 0x9f, 0x9f, 0x94, 0xe9, 0xb9, 0x3a,
+ 0x1d, 0xf3, 0xd3, 0xeb, 0x51, 0x2c, 0xfd, 0xde, 0x38, 0xf4, 0xd1, 0xd3,
+ 0xff, 0xfc, 0xdc, 0xee, 0xad, 0xd0, 0xe6, 0xfb, 0xcb, 0xdf, 0x3e, 0x07,
+ 0x4f, 0xea, 0xaa, 0xf3, 0xe7, 0x1e, 0x74, 0x79, 0x44, 0xd6, 0x99, 0xa7,
+ 0xff, 0xfb, 0x6c, 0x3e, 0xdf, 0x69, 0x7d, 0x6e, 0xb9, 0x4b, 0xd0, 0x9d,
+ 0x3c, 0x19, 0x80, 0x68, 0x93, 0x27, 0xc1, 0xd6, 0x9d, 0x67, 0x5b, 0x77,
+ 0xce, 0x9f, 0xd5, 0x6e, 0xb5, 0x8f, 0xb9, 0xd0, 0xc7, 0xe3, 0xf3, 0xe8,
+ 0x7a, 0x64, 0x5f, 0x65, 0x54, 0x27, 0x27, 0xee, 0x7b, 0x77, 0xef, 0xdf,
+ 0x51, 0xd3, 0xff, 0xb6, 0x9a, 0xb4, 0x13, 0xf7, 0x71, 0xb0, 0xe9, 0xf5,
+ 0x69, 0x15, 0x87, 0x4f, 0xf3, 0x6f, 0x49, 0x62, 0x98, 0x0e, 0x9f, 0xff,
+ 0x60, 0x7d, 0xb6, 0x35, 0xaa, 0x5f, 0x1c, 0x70, 0x54, 0x3d, 0x16, 0x37,
+ 0x25, 0xd1, 0xbc, 0xfc, 0x01, 0xe8, 0x0b, 0x1d, 0x3f, 0xfb, 0xd1, 0xcd,
+ 0x37, 0xef, 0xb6, 0x1d, 0x1d, 0x3b, 0x8e, 0x38, 0x2a, 0x7e, 0xfe, 0x58,
+ 0xa4, 0xb9, 0x4b, 0x2f, 0xe7, 0xd4, 0xaf, 0xd7, 0x5c, 0xe9, 0xf2, 0x6a,
+ 0xca, 0xe0, 0xe9, 0xfe, 0x60, 0xd8, 0xfb, 0xa6, 0xb9, 0xd3, 0xff, 0xed,
+ 0x6e, 0x9f, 0xd0, 0x36, 0x9a, 0xb4, 0x13, 0xe7, 0x47, 0xd1, 0x6a, 0xa2,
+ 0x81, 0x37, 0x9f, 0xea, 0xce, 0xfa, 0x57, 0x38, 0xf3, 0xa7, 0xff, 0x65,
+ 0x9b, 0x46, 0x1a, 0x71, 0x3e, 0x87, 0x45, 0x22, 0xc3, 0x45, 0xfc, 0x1d,
+ 0x4f, 0x86, 0xb7, 0x9a, 0x3a, 0x7f, 0xcf, 0x61, 0xb3, 0xc7, 0xc7, 0xd7,
+ 0x9d, 0x1d, 0x73, 0xe6, 0x70, 0x96, 0x7b, 0x56, 0x57, 0x27, 0x4f, 0xf2,
+ 0x79, 0xf1, 0xfe, 0xd4, 0x97, 0x3a, 0x1c, 0x3e, 0x0e, 0xa2, 0x39, 0xdc,
+ 0x71, 0xc1, 0xd3, 0xff, 0xea, 0x56, 0x85, 0xbb, 0xae, 0x6f, 0x4a, 0x60,
+ 0x29, 0x65, 0xfc, 0x52, 0x65, 0xc9, 0x08, 0x7d, 0xa2, 0xc9, 0x0e, 0x9f,
+ 0xb6, 0xdd, 0x01, 0x2c, 0x3a, 0x7e, 0xfe, 0x7c, 0x59, 0xe7, 0x43, 0xbb,
+ 0x3e, 0x8e, 0x43, 0xfe, 0x5d, 0x33, 0xd6, 0xef, 0x32, 0x4c, 0xfa, 0xc6,
+ 0xa6, 0x2f, 0x7c, 0x32, 0x2a, 0x34, 0x7f, 0x26, 0xc0, 0x73, 0x6c, 0x3e,
+ 0x90, 0xc1, 0xc2, 0xac, 0x67, 0x13, 0xcb, 0xc7, 0x1f, 0xa8, 0xf1, 0x3c,
+ 0x42, 0x72, 0x7f, 0xf7, 0xeb, 0x8e, 0x77, 0x4e, 0x0d, 0x7d, 0xe7, 0x4e,
+ 0xfd, 0x75, 0xce, 0x95, 0x7c, 0xfa, 0x94, 0x97, 0x3f, 0xf5, 0x6c, 0x5a,
+ 0xcf, 0x1b, 0xde, 0x75, 0xce, 0x9f, 0xb0, 0x17, 0xc7, 0x1c, 0x1d, 0x25,
+ 0xd3, 0x33, 0xa4, 0x23, 0x35, 0xf9, 0x96, 0x52, 0x5c, 0x86, 0x37, 0x1b,
+ 0x93, 0xba, 0x49, 0x87, 0xb6, 0x6d, 0xfc, 0xca, 0x77, 0xb6, 0x1c, 0x5f,
+ 0x27, 0x51, 0xe7, 0x70, 0xb4, 0xbc, 0x36, 0x35, 0x09, 0x7f, 0x69, 0xa1,
+ 0xf3, 0xf9, 0x75, 0xf0, 0xcc, 0x03, 0x44, 0x6b, 0x3e, 0xf8, 0x66, 0x01,
+ 0xa2, 0xa5, 0x9b, 0x00, 0xd1, 0x0d, 0x49, 0x74, 0x7a, 0x58, 0x63, 0x3f,
+ 0xf2, 0xf1, 0xeb, 0xaf, 0x86, 0x60, 0x1a, 0x23, 0xe9, 0xf7, 0xc3, 0x30,
+ 0x0d, 0x16, 0x3c, 0xff, 0x0e, 0x79, 0xda, 0x30, 0xd8, 0x74, 0x97, 0x47,
+ 0xd2, 0xe1, 0x8c, 0xee, 0xb4, 0x57, 0x93, 0xa7, 0xe7, 0x7c, 0x6b, 0x79,
+ 0xa3, 0xa7, 0xf8, 0x73, 0xbb, 0xe6, 0xb5, 0x87, 0x4f, 0x76, 0xa4, 0xf9,
+ 0xd3, 0xff, 0xfc, 0xdf, 0x1a, 0xe6, 0xb7, 0xb4, 0x0d, 0xa6, 0xaf, 0x96,
+ 0x9d, 0x08, 0x88, 0x6d, 0x91, 0x4e, 0xcc, 0x03, 0x45, 0xa1, 0x3f, 0xec,
+ 0xe1, 0xd8, 0x33, 0xf6, 0x57, 0x07, 0x40, 0x1f, 0x47, 0xc9, 0xa7, 0xff,
+ 0xff, 0x93, 0xfb, 0xc1, 0x46, 0xd2, 0x6d, 0xaf, 0xba, 0xbf, 0xe8, 0x2b,
+ 0x47, 0x47, 0xd1, 0x31, 0xb2, 0x19, 0xf9, 0xd7, 0x8d, 0x0b, 0x76, 0x74,
+ 0xf9, 0xb5, 0x5b, 0x63, 0xa7, 0xff, 0xab, 0x57, 0xa7, 0x36, 0xce, 0xab,
+ 0x7b, 0x63, 0xa2, 0xc3, 0xf5, 0x12, 0x58, 0x64, 0x64, 0x54, 0x29, 0xa7,
+ 0xfd, 0xdb, 0x06, 0xd1, 0xcc, 0xcb, 0x0e, 0x9f, 0xe4, 0xf4, 0x5f, 0xf6,
+ 0xae, 0x4e, 0x9f, 0xff, 0xed, 0xd3, 0xc3, 0x69, 0xb6, 0xaf, 0xbf, 0x42,
+ 0xca, 0xb9, 0xd2, 0xab, 0xa2, 0x6f, 0x47, 0x13, 0xed, 0x6f, 0x07, 0xc9,
+ 0xd3, 0xfc, 0x3e, 0xd9, 0xce, 0xe8, 0x58, 0xe9, 0x86, 0xa8, 0xf8, 0x40,
+ 0xa2, 0x7f, 0x56, 0xdc, 0x4d, 0xa2, 0x8e, 0x9f, 0xcf, 0xaf, 0xdc, 0x5a,
+ 0xc3, 0xa7, 0x56, 0xf0, 0xe9, 0xf3, 0x9c, 0xfb, 0xe8, 0x9d, 0x1c, 0x9e,
+ 0x2e, 0x0d, 0x4f, 0xf5, 0x57, 0x14, 0x01, 0x5c, 0x1d, 0x14, 0x98, 0x0d,
+ 0xa6, 0x58, 0xef, 0x72, 0x29, 0xea, 0xde, 0x68, 0xe9, 0xf9, 0x07, 0xd7,
+ 0xd5, 0xce, 0x9f, 0xff, 0xe4, 0x1f, 0x5f, 0x57, 0xe9, 0x5a, 0x6b, 0x7b,
+ 0xcd, 0xed, 0x0e, 0x8f, 0x28, 0x94, 0xd1, 0x64, 0x96, 0xef, 0x2f, 0x74,
+ 0x75, 0x84, 0xac, 0x61, 0xcc, 0x2f, 0x6a, 0x32, 0x2d, 0xc3, 0xaf, 0xb2,
+ 0x61, 0x86, 0xcd, 0xe1, 0x13, 0xa8, 0xca, 0xfa, 0x8f, 0x7c, 0x42, 0xd2,
+ 0x7e, 0x76, 0x4e, 0x45, 0x9c, 0x3a, 0x7a, 0xb7, 0x9a, 0x3a, 0x4e, 0xfd,
+ 0x1e, 0x80, 0x98, 0x4f, 0xbe, 0x19, 0x80, 0x68, 0xb5, 0xa7, 0xfd, 0x8f,
+ 0x5d, 0x7c, 0x33, 0x00, 0xd1, 0x41, 0xc9, 0x7d, 0x62, 0x28, 0xe8, 0xad,
+ 0x46, 0x33, 0xff, 0x96, 0xac, 0x7a, 0xeb, 0xe1, 0x98, 0x06, 0x8a, 0x2e,
+ 0x7f, 0x2e, 0xbe, 0x19, 0x80, 0x68, 0xba, 0xa1, 0xec, 0xb1, 0x70, 0x84,
+ 0x72, 0x13, 0x2a, 0x16, 0xdb, 0x9f, 0x10, 0xee, 0x3d, 0x4b, 0x9d, 0x69,
+ 0x4e, 0x7d, 0xf0, 0xcc, 0x03, 0x44, 0x43, 0x3b, 0x75, 0xc9, 0xd2, 0x5d,
+ 0x1e, 0x6d, 0xa6, 0x33, 0xf9, 0x75, 0xf0, 0xcc, 0x03, 0x44, 0x6d, 0x3f,
+ 0x97, 0x5f, 0x0c, 0xc0, 0x34, 0x53, 0x73, 0xf9, 0x75, 0xf0, 0xcc, 0x03,
+ 0x45, 0x41, 0x3f, 0x97, 0x5f, 0x0c, 0xc0, 0x34, 0x54, 0xd3, 0xef, 0x86,
+ 0x60, 0x1a, 0x2b, 0x09, 0xf2, 0x71, 0xcf, 0xbf, 0x3a, 0x7f, 0x9e, 0xba,
+ 0xf8, 0x66, 0x01, 0xa2, 0x3f, 0x9d, 0x4d, 0x61, 0xd2, 0x5d, 0x22, 0xe0,
+ 0x0c, 0x70, 0xa8, 0x50, 0xa7, 0xff, 0x2d, 0x58, 0xf5, 0xd7, 0xc3, 0x30,
+ 0x0d, 0x13, 0x7c, 0xff, 0xca, 0xc7, 0xae, 0xbe, 0x19, 0x80, 0x68, 0x9f,
+ 0xa7, 0xdd, 0x6d, 0xdf, 0xea, 0xab, 0x4e, 0x96, 0xce, 0x87, 0x74, 0x78,
+ 0xde, 0x9b, 0x4f, 0xf7, 0x5a, 0xdb, 0xcd, 0x6b, 0x33, 0x83, 0xa7, 0xdd,
+ 0x3c, 0xff, 0x00, 0xe9, 0xf7, 0x58, 0xee, 0xfb, 0xf2, 0xc7, 0x4f, 0xff,
+ 0x33, 0x33, 0x33, 0x33, 0x33, 0x5b, 0x73, 0xa7, 0xdf, 0x4b, 0x31, 0x45,
+ 0x4d, 0xc7, 0x05, 0x45, 0x1b, 0xfe, 0x09, 0xe5, 0xe9, 0x4b, 0x34, 0x30,
+ 0xc8, 0xca, 0xbc, 0x2a, 0x67, 0xff, 0xea, 0x55, 0xf5, 0xfc, 0xb3, 0x9d,
+ 0xb5, 0xf5, 0xee, 0xce, 0x9f, 0x60, 0x6d, 0x3e, 0x74, 0xff, 0xff, 0xe1,
+ 0xcf, 0x29, 0xf6, 0x7f, 0x4d, 0xa2, 0xb9, 0x6e, 0x9d, 0x5e, 0xed, 0x3e,
+ 0x74, 0xf6, 0x3d, 0x2d, 0x3a, 0x39, 0x4c, 0x93, 0xeb, 0xdb, 0x25, 0x18,
+ 0x40, 0x4f, 0xff, 0x9d, 0x9a, 0xd7, 0xe0, 0xf7, 0xd3, 0xb4, 0xfa, 0x79,
+ 0x3a, 0x7a, 0xc5, 0x23, 0xce, 0x9f, 0x5c, 0x7d, 0xc7, 0x9d, 0x3f, 0xb6,
+ 0xca, 0x5f, 0x7d, 0xb1, 0xd2, 0xfb, 0x1f, 0xed, 0x11, 0x21, 0x3c, 0xff,
+ 0x9a, 0xde, 0x7c, 0x37, 0x5f, 0x7e, 0xdc, 0xe9, 0x75, 0xce, 0x9a, 0xf4,
+ 0x74, 0x21, 0xa9, 0xec, 0x52, 0x7f, 0xee, 0x5b, 0x59, 0x7a, 0xde, 0xd1,
+ 0x47, 0x4e, 0xd2, 0x38, 0x74, 0x31, 0xef, 0xdd, 0x0e, 0x19, 0x5d, 0x5a,
+ 0x46, 0x96, 0xe2, 0x1f, 0xe1, 0xb4, 0xa3, 0x21, 0x70, 0xd4, 0x20, 0x27,
+ 0x39, 0xe1, 0x47, 0x4f, 0xf5, 0x6a, 0xf5, 0xad, 0xd7, 0x67, 0x46, 0x1e,
+ 0xb8, 0x8f, 0xcd, 0x82, 0x74, 0x7c, 0xda, 0x28, 0x82, 0x77, 0x1c, 0x70,
+ 0x74, 0xf5, 0x82, 0x8c, 0x52, 0xcb, 0xf9, 0xad, 0x79, 0xd3, 0xfb, 0xcb,
+ 0x6a, 0xfb, 0xcf, 0x4e, 0x99, 0x00, 0xe9, 0x5a, 0xc7, 0xc1, 0xe4, 0x5f,
+ 0x46, 0xb0, 0xc9, 0x83, 0x6d, 0x03, 0xd8, 0x47, 0xcf, 0xfd, 0x67, 0xbd,
+ 0xd0, 0xfa, 0xe3, 0x6b, 0x0e, 0x9f, 0xf9, 0xb7, 0xe3, 0x9d, 0x25, 0x38,
+ 0xca, 0x3a, 0x79, 0xb5, 0x70, 0x34, 0x41, 0xd3, 0xf6, 0x6d, 0xba, 0xfe,
+ 0xbc, 0xe8, 0xfa, 0x3a, 0xd4, 0x8f, 0xa4, 0x67, 0x45, 0xb3, 0x7f, 0x93,
+ 0xa6, 0xe3, 0x83, 0xa1, 0xe6, 0xbf, 0x81, 0x79, 0xeb, 0xb2, 0x3a, 0x29,
+ 0x66, 0x8a, 0x7d, 0x7f, 0x1c, 0xf7, 0x73, 0xa1, 0x0f, 0x7b, 0xc1, 0x94,
+ 0xee, 0x38, 0xe0, 0xa8, 0x29, 0x65, 0xfc, 0xf2, 0x70, 0x8e, 0x15, 0x00,
+ 0x6e, 0xd0, 0x66, 0x11, 0x38, 0xad, 0xc3, 0xb8, 0x5f, 0x67, 0x0a, 0x5c,
+ 0xe9, 0xee, 0x70, 0x7b, 0x3a, 0x7f, 0xe6, 0x1e, 0xc5, 0xad, 0x71, 0x87,
+ 0xb3, 0xa1, 0x11, 0x01, 0xd8, 0xd5, 0xc8, 0xa7, 0xcd, 0x5f, 0xda, 0x1d,
+ 0x3d, 0xcd, 0x2b, 0xae, 0x74, 0x38, 0x79, 0x6e, 0x89, 0x67, 0xed, 0x53,
+ 0x82, 0xca, 0x3c, 0x40, 0x53, 0xec, 0x1e, 0x76, 0xc6, 0x88, 0x09, 0x66,
+ 0xe6, 0x7e, 0xfb, 0x3f, 0x2d, 0xe0, 0xe9, 0xfe, 0x6f, 0xd9, 0xd2, 0x9c,
+ 0x45, 0x1d, 0x3c, 0xa6, 0xa5, 0x1d, 0x3e, 0x6e, 0xd2, 0xdb, 0x9d, 0x3f,
+ 0xbe, 0xe5, 0xd0, 0x74, 0x87, 0x4f, 0x5b, 0xdf, 0xd8, 0xa9, 0xb8, 0xe0,
+ 0xa8, 0x63, 0x77, 0xc1, 0x1c, 0xfd, 0x9f, 0x7b, 0xc5, 0x0a, 0x59, 0xa1,
+ 0x86, 0x55, 0x2d, 0x4f, 0x68, 0xbd, 0xf4, 0x3d, 0x97, 0x61, 0xd8, 0x90,
+ 0x68, 0xa3, 0xd8, 0x47, 0x4f, 0xbd, 0xd7, 0xb9, 0xe0, 0xd1, 0x03, 0xcf,
+ 0xfb, 0x7e, 0xd8, 0xdd, 0x1b, 0x4d, 0xc9, 0xd3, 0xb3, 0xf6, 0x1d, 0x37,
+ 0x1c, 0x1d, 0x3f, 0xbe, 0x94, 0xeb, 0xc3, 0xd6, 0x06, 0xd3, 0x81, 0xc8,
+ 0xe5, 0x18, 0x7f, 0x76, 0x9f, 0xf8, 0x6b, 0xce, 0xf1, 0xfe, 0x32, 0xd6,
+ 0x3a, 0x18, 0xfa, 0xa8, 0x92, 0x7f, 0xf5, 0x29, 0x58, 0xfa, 0xf8, 0x66,
+ 0x01, 0xa2, 0x18, 0x8d, 0x9f, 0x90, 0x90, 0x4f, 0xbe, 0x19, 0x80, 0x68,
+ 0x82, 0xa7, 0x6d, 0x94, 0x74, 0x51, 0xe6, 0x21, 0x8c, 0xf6, 0xae, 0xdd,
+ 0x95, 0x3b, 0x3f, 0x61, 0x53, 0xde, 0x8e, 0x79, 0x2a, 0x7f, 0x25, 0x95,
+ 0xab, 0xb7, 0x65, 0x41, 0x53, 0xf5, 0x03, 0x6d, 0x94, 0x54, 0xdc, 0x70,
+ 0x54, 0xfc, 0x2c, 0x36, 0x27, 0xca, 0x8a, 0x4c, 0x2c, 0x08, 0x94, 0x39,
+ 0xb2, 0x3e, 0xcc, 0xc4, 0x2b, 0x82, 0xaf, 0x03, 0x13, 0x27, 0xca, 0x59,
+ 0xf9, 0xcb, 0x1e, 0x9e, 0x26, 0xe3, 0x9e, 0x9f, 0xf3, 0x3f, 0x06, 0xaf,
+ 0xf6, 0xb9, 0xd3, 0xfd, 0xad, 0xb3, 0xae, 0x5b, 0xb6, 0x3a, 0x7f, 0x9a,
+ 0xd7, 0xf5, 0x30, 0x52, 0x8e, 0x86, 0x3f, 0x5d, 0x9d, 0xcf, 0xff, 0xce,
+ 0x66, 0x3f, 0x37, 0xd2, 0xac, 0xf7, 0x5e, 0xe7, 0x83, 0x45, 0xf7, 0x3e,
+ 0x4d, 0x0d, 0x3c, 0xe9, 0xff, 0x0a, 0x3f, 0x5b, 0xaf, 0xa5, 0xce, 0x9f,
+ 0xda, 0xef, 0xc0, 0xbf, 0x74, 0x78, 0x80, 0x67, 0x67, 0xde, 0x78, 0x80,
+ 0x62, 0x8f, 0xab, 0xd4, 0x29, 0xb1, 0xe7, 0x88, 0x06, 0x7b, 0x06, 0xd7,
+ 0x9e, 0x20, 0x19, 0xfc, 0x81, 0xba, 0xef, 0xb6, 0x3c, 0x40, 0x33, 0x90,
+ 0x79, 0x3c, 0x40, 0x31, 0xca, 0x2d, 0xd4, 0x45, 0xb2, 0xe7, 0x47, 0xf3,
+ 0xbe, 0xda, 0x3c, 0x40, 0x30, 0x78, 0x80, 0x66, 0x65, 0x1e, 0x20, 0x18,
+ 0xe4, 0xdc, 0xa0, 0xbc, 0xf2, 0x2b, 0x96, 0x3c, 0x40, 0x33, 0xb5, 0x80,
+ 0x78, 0x80, 0x67, 0xfc, 0x38, 0xf5, 0xed, 0x03, 0x3e, 0x78, 0x80, 0x66,
+ 0xce, 0x4f, 0x10, 0x0c, 0xfe, 0x1c, 0xe2, 0xf7, 0x6e, 0xcf, 0x10, 0x0c,
+ 0xf9, 0x3c, 0xe0, 0xf6, 0x78, 0x80, 0x66, 0x4b, 0x9e, 0x20, 0x18, 0xf9,
+ 0xeb, 0xe8, 0xd6, 0x7d, 0xa1, 0x6b, 0x5e, 0x68, 0x80, 0x66, 0xed, 0x8f,
+ 0x10, 0x0a, 0xcd, 0xa4, 0xf9, 0x19, 0x59, 0xc9, 0xe2, 0x01, 0x9e, 0xf7,
+ 0x04, 0x0f, 0x10, 0x0c, 0xe6, 0xf8, 0x1e, 0x20, 0x19, 0xff, 0x55, 0xb7,
+ 0xe5, 0xa8, 0x7b, 0xb9, 0xe2, 0x01, 0x9f, 0x7b, 0x8f, 0x7b, 0x1e, 0x20,
+ 0x18, 0xa4, 0x40, 0x6d, 0x32, 0x6f, 0xf6, 0x78, 0x80, 0x61, 0xea, 0xa4,
+ 0x39, 0x23, 0xa8, 0x4b, 0xa2, 0xb6, 0xcc, 0xfb, 0x33, 0xb9, 0x6e, 0xa1,
+ 0x4f, 0xe9, 0x14, 0xfa, 0xb5, 0x7c, 0xb4, 0xf1, 0x00, 0xcf, 0xee, 0x58,
+ 0x1c, 0xfb, 0x68, 0xf1, 0x00, 0xf2, 0x6d, 0x27, 0x7d, 0xb8, 0x3c, 0x40,
+ 0x30, 0x07, 0xf5, 0xf5, 0x19, 0xe4, 0x17, 0xdc, 0xf1, 0x00, 0xcf, 0xd8,
+ 0xe3, 0xea, 0xd7, 0x9e, 0x20, 0x18, 0xa4, 0x44, 0xf6, 0x43, 0xe9, 0x6c,
+ 0xff, 0x6d, 0xae, 0xbb, 0xfb, 0xfe, 0xcf, 0x10, 0x0c, 0x90, 0xf1, 0x00,
+ 0xcd, 0x96, 0x72, 0x7c, 0x9b, 0x48, 0x9b, 0xfd, 0x9e, 0x20, 0x19, 0xf6,
+ 0x6a, 0xe9, 0x69, 0xe2, 0x01, 0x9f, 0x90, 0x7d, 0x7d, 0x5c, 0xf1, 0x00,
+ 0xc3, 0x22, 0x44, 0x49, 0x34, 0x69, 0x1c, 0xb2, 0x03, 0x6a, 0x1b, 0x2e,
+ 0x20, 0x7d, 0x87, 0x64, 0x38, 0x5d, 0xd9, 0x3d, 0xe5, 0x6c, 0x6a, 0x3c,
+ 0x2e, 0xa8, 0x4a, 0xf8, 0x86, 0x04, 0xec, 0xc0, 0x34, 0x40, 0x2b, 0x45,
+ 0xf4, 0xf7, 0x97, 0x77, 0xca, 0x8e, 0x9f, 0xf9, 0xe3, 0x41, 0xb4, 0xef,
+ 0xbf, 0x5c, 0x3a, 0x6e, 0xd8, 0xa9, 0x79, 0x2a, 0x76, 0xda, 0xc3, 0xa6,
+ 0xe3, 0x82, 0xa1, 0x0f, 0x73, 0xae, 0x2c, 0xe0, 0x97, 0x03, 0x93, 0x94,
+ 0x97, 0x29, 0x67, 0x83, 0x16, 0x32, 0xc2, 0x1e, 0x4a, 0x14, 0x97, 0x14,
+ 0x38, 0xc2, 0xbe, 0xe1, 0xc7, 0x3f, 0x93, 0x5e, 0x1d, 0x3a, 0x6b, 0x9d,
+ 0x3f, 0x7d, 0xc7, 0xb7, 0xec, 0x3a, 0x7f, 0xcf, 0xbf, 0x41, 0xa5, 0x37,
+ 0xfc, 0x9d, 0x3f, 0xf7, 0xf7, 0x94, 0xf6, 0xff, 0x7e, 0x14, 0x74, 0xfd,
+ 0xe3, 0x8f, 0xa5, 0x6c, 0xa9, 0xe7, 0x37, 0x8e, 0x1d, 0x3e, 0xa7, 0x1e,
+ 0xd6, 0x9d, 0x3d, 0x42, 0xcf, 0x2a, 0x3e, 0x7d, 0x42, 0x46, 0xec, 0x51,
+ 0x0c, 0x9c, 0x05, 0x17, 0xa2, 0x0e, 0xd1, 0xb2, 0x13, 0x33, 0xc8, 0x3a,
+ 0xb9, 0xd3, 0xbd, 0x77, 0x2e, 0x74, 0xff, 0xdd, 0xaa, 0x83, 0x69, 0xce,
+ 0xfd, 0xf2, 0x74, 0xfe, 0xe5, 0xad, 0xbd, 0x5b, 0xa3, 0xa7, 0xf9, 0xb4,
+ 0x80, 0x9c, 0xb6, 0x8e, 0x9b, 0x57, 0xa3, 0xeb, 0xf9, 0xac, 0xfe, 0x7d,
+ 0x5f, 0xc5, 0xf5, 0x47, 0x43, 0x26, 0x6c, 0x84, 0x59, 0x0b, 0x3f, 0x4b,
+ 0x67, 0xd8, 0xeb, 0x9e, 0x58, 0xe9, 0xaf, 0x73, 0xa7, 0x71, 0xc7, 0x07,
+ 0x4d, 0xde, 0x14, 0xb2, 0xfe, 0x3e, 0x7b, 0x57, 0x35, 0x9f, 0xf5, 0x5c,
+ 0x73, 0xcb, 0x82, 0x8e, 0x1d, 0x3b, 0x3b, 0xa2, 0xa1, 0xe9, 0x80, 0x2a,
+ 0x10, 0x9b, 0x22, 0xea, 0x3f, 0x9f, 0xda, 0x1a, 0xb7, 0xbf, 0x0f, 0x3a,
+ 0x7f, 0x86, 0x9d, 0x52, 0xf8, 0xe3, 0x82, 0xa7, 0x2b, 0x34, 0x74, 0x6c,
+ 0xf5, 0xdd, 0x1e, 0x4f, 0xa9, 0xc7, 0xb3, 0xce, 0x86, 0x4c, 0x79, 0x11,
+ 0xb2, 0x11, 0xba, 0x24, 0x9f, 0x9d, 0xc4, 0xfb, 0x7c, 0x4e, 0x9f, 0xfd,
+ 0x5c, 0xe2, 0xaa, 0xd7, 0xd7, 0x75, 0xc9, 0xd3, 0x6f, 0x0e, 0x99, 0xcb,
+ 0x9d, 0x3e, 0xa7, 0x48, 0x3c, 0xd1, 0xac, 0xf0, 0x2b, 0x1d, 0x11, 0x6e,
+ 0xb7, 0x79, 0xee, 0x6b, 0x78, 0x74, 0xff, 0xcd, 0x42, 0xfd, 0xd0, 0x8b,
+ 0x70, 0x74, 0x93, 0xe8, 0x86, 0x12, 0x5d, 0x10, 0xc5, 0x8d, 0xc4, 0x03,
+ 0xe3, 0xd7, 0xe6, 0x51, 0x8f, 0x92, 0xf0, 0x85, 0x82, 0x10, 0xfe, 0x96,
+ 0xec, 0xa6, 0x8d, 0xc7, 0x71, 0xda, 0x60, 0xc6, 0xad, 0xa9, 0x4b, 0xfe,
+ 0xa0, 0x3a, 0x8d, 0xb6, 0x7f, 0xab, 0xe2, 0xda, 0x7d, 0x6c, 0xe9, 0xf8,
+ 0x7b, 0xae, 0x71, 0xe7, 0x4f, 0xb1, 0xfd, 0x39, 0x43, 0xa7, 0xde, 0x1c,
+ 0x7b, 0x75, 0xca, 0x86, 0x45, 0xd5, 0x1b, 0x6c, 0xb7, 0xc1, 0x4c, 0xff,
+ 0xde, 0x47, 0xdc, 0xf1, 0x57, 0x46, 0x13, 0xa7, 0x75, 0x27, 0x27, 0x47,
+ 0xcf, 0x91, 0x48, 0xb2, 0xf0, 0x68, 0x81, 0x65, 0xa3, 0x50, 0x29, 0x24,
+ 0xd1, 0xbc, 0xe0, 0x7e, 0x7f, 0xc9, 0xd5, 0xb4, 0xf0, 0xbe, 0xfb, 0x62,
+ 0xa7, 0xff, 0xf6, 0xdb, 0xfd, 0xd3, 0xa4, 0xbd, 0xe8, 0x43, 0x07, 0xb3,
+ 0xa7, 0xfe, 0xbe, 0x5b, 0xd1, 0x4d, 0x43, 0xae, 0xa3, 0xa3, 0x68, 0xa8,
+ 0xd3, 0x04, 0x32, 0x61, 0xe9, 0x0e, 0xc9, 0xff, 0xfe, 0xfd, 0x94, 0x8e,
+ 0x66, 0x3e, 0xec, 0xae, 0x76, 0xc2, 0x07, 0x4e, 0xb0, 0x5e, 0x74, 0x32,
+ 0xa3, 0xc5, 0x2f, 0x6e, 0x33, 0x6c, 0x27, 0xf5, 0x96, 0x7f, 0x3d, 0xca,
+ 0x1c, 0xdd, 0x1d, 0x3f, 0xfb, 0xe0, 0x34, 0xe8, 0x69, 0xbe, 0xd7, 0x3a,
+ 0x7f, 0x63, 0x9b, 0xa5, 0x55, 0xce, 0x8a, 0x3f, 0x97, 0x48, 0xf3, 0xf2,
+ 0x79, 0xd5, 0x52, 0x8e, 0x9f, 0x57, 0x29, 0xfb, 0x9d, 0x3f, 0xfd, 0x7d,
+ 0x5a, 0x09, 0xbe, 0x8e, 0xd5, 0xb4, 0x51, 0xd2, 0x6b, 0x0f, 0xef, 0x82,
+ 0x78, 0x44, 0x7a, 0x6c, 0x8f, 0x50, 0xa8, 0x9f, 0xf0, 0xa7, 0x8b, 0x69,
+ 0xd5, 0xad, 0xe0, 0xe9, 0xdc, 0xe7, 0xce, 0x9f, 0x77, 0x83, 0x4e, 0xc7,
+ 0x43, 0x1e, 0x2f, 0xa3, 0x93, 0x95, 0x6b, 0x87, 0x4f, 0xfc, 0xab, 0xa9,
+ 0xb9, 0x6f, 0xfa, 0xdd, 0x9d, 0x0c, 0x7c, 0x88, 0x3d, 0x0c, 0xac, 0x05,
+ 0xf1, 0xcf, 0x51, 0xa5, 0xe1, 0x13, 0xa8, 0x43, 0x4f, 0xfe, 0x7a, 0x6e,
+ 0x9c, 0x47, 0x3d, 0x76, 0xf6, 0xe7, 0x4f, 0x9a, 0xc6, 0x76, 0x63, 0xa7,
+ 0xef, 0x7c, 0x6e, 0xad, 0xb9, 0xd3, 0xff, 0xff, 0xef, 0xb6, 0x87, 0x01,
+ 0x2e, 0xe2, 0x7c, 0x1a, 0xfa, 0x6b, 0x5b, 0xc5, 0x5c, 0xe9, 0xff, 0xff,
+ 0xff, 0x5e, 0xf5, 0xad, 0xe2, 0xaf, 0xff, 0xa5, 0xba, 0xcc, 0xf3, 0x54,
+ 0xe7, 0xba, 0x6e, 0x2d, 0x63, 0xa1, 0x93, 0x1f, 0xc8, 0x40, 0xcf, 0x77,
+ 0x96, 0xdc, 0xe9, 0xb8, 0xe0, 0xe8, 0xb9, 0xbb, 0xe0, 0x8e, 0x7c, 0x9b,
+ 0xca, 0xd9, 0x4b, 0x34, 0x51, 0x6a, 0xa8, 0x2d, 0xa8, 0x3b, 0x85, 0x23,
+ 0x1a, 0x85, 0xe1, 0x09, 0x3b, 0x8e, 0x38, 0x2a, 0x79, 0xfa, 0xa0, 0x29,
+ 0x65, 0xfc, 0xfa, 0xb9, 0x4e, 0xee, 0x7b, 0xbf, 0xa5, 0x9f, 0x3e, 0x41,
+ 0x2f, 0x9b, 0xf7, 0x3a, 0x73, 0xa6, 0x03, 0xa1, 0x8d, 0x92, 0x0b, 0x4f,
+ 0xc3, 0x6d, 0xdc, 0xad, 0x1d, 0x3f, 0xfc, 0x3a, 0x72, 0xbf, 0x58, 0xa6,
+ 0xda, 0x72, 0x74, 0xfa, 0xce, 0xba, 0x55, 0xa7, 0x4f, 0x92, 0xed, 0x62,
+ 0x8f, 0x67, 0xec, 0xf9, 0xb3, 0xfd, 0xfa, 0x7b, 0x3f, 0x66, 0xc7, 0x9e,
+ 0xcf, 0xd9, 0xef, 0x5f, 0x57, 0x3d, 0x9f, 0xb1, 0xc9, 0xe8, 0x89, 0x14,
+ 0xf9, 0xaa, 0xf4, 0x27, 0xb3, 0xf6, 0x0f, 0x67, 0xec, 0xd9, 0xa3, 0xd9,
+ 0xfa, 0xa2, 0xde, 0x4f, 0x13, 0xf9, 0xf5, 0x22, 0x7a, 0xba, 0x93, 0xb3,
+ 0xd9, 0xfb, 0x07, 0xb3, 0xf6, 0x6e, 0xd8, 0xf6, 0x7e, 0xcf, 0xf5, 0x77,
+ 0x9f, 0xa7, 0x55, 0xc9, 0xec, 0xfd, 0x9f, 0xab, 0x69, 0x7f, 0x6c, 0x3d,
+ 0x9f, 0xb1, 0xda, 0x29, 0x44, 0x8e, 0xe8, 0xf3, 0xdf, 0xb1, 0xb4, 0x7b,
+ 0x3f, 0x60, 0xf6, 0x7e, 0xd1, 0xaf, 0x9b, 0x8e, 0x0f, 0x67, 0xec, 0x3d,
+ 0x58, 0xa7, 0x26, 0x95, 0x08, 0x6b, 0x61, 0x37, 0xf2, 0x85, 0x18, 0xde,
+ 0x17, 0x9a, 0x5f, 0xe0, 0x9a, 0x7a, 0x9e, 0xde, 0x4b, 0x67, 0xe9, 0x68,
+ 0x91, 0x9f, 0xf5, 0x07, 0x35, 0xfe, 0x33, 0x6e, 0x1d, 0x33, 0xec, 0x2a,
+ 0x2c, 0x44, 0xc5, 0xa8, 0x42, 0x7f, 0x1f, 0x5c, 0x9a, 0xc9, 0xc6, 0x99,
+ 0xff, 0xf3, 0xfe, 0xce, 0xb1, 0xc6, 0xe7, 0x6c, 0xac, 0x70, 0xe9, 0xfc,
+ 0xed, 0x97, 0x4b, 0xb9, 0x47, 0x45, 0xa8, 0x8d, 0xfa, 0xc4, 0x32, 0xf3,
+ 0x5b, 0xd6, 0x28, 0x7d, 0x0b, 0xb2, 0x73, 0xa3, 0xd8, 0x5d, 0x4f, 0xfb,
+ 0xcb, 0x5a, 0x2d, 0xbd, 0xfa, 0x07, 0x4f, 0xc3, 0x9e, 0x77, 0x8f, 0x3a,
+ 0x77, 0x1c, 0x70, 0x54, 0xef, 0x0d, 0xd9, 0x4b, 0x2f, 0xe7, 0xfc, 0x38,
+ 0xff, 0x1f, 0xa7, 0x59, 0xf3, 0xa7, 0xf8, 0x73, 0xbe, 0x8f, 0x6e, 0xed,
+ 0x3a, 0x39, 0x4c, 0xd5, 0x48, 0x1d, 0xa6, 0x09, 0x6e, 0x90, 0x27, 0xfc,
+ 0x22, 0x9e, 0xbb, 0x97, 0xea, 0x6d, 0x1d, 0x3b, 0x8e, 0x38, 0x2c, 0x42,
+ 0x09, 0xf7, 0xc3, 0x30, 0x0b, 0x10, 0x81, 0x66, 0xb6, 0x77, 0x1c, 0x70,
+ 0x58, 0x83, 0xd0, 0x58, 0x83, 0xcb, 0x35, 0xb3, 0x32, 0xa9, 0x12, 0xe0,
+ 0xdf, 0x3e, 0xd3, 0x69, 0x94, 0x74, 0xf0, 0xa3, 0x79, 0x3a, 0x77, 0x86,
+ 0xec, 0xe8, 0xb0, 0xdf, 0xa8, 0x86, 0x7c, 0x0d, 0xb6, 0x51, 0x53, 0xe1,
+ 0xc1, 0x1a, 0x2a, 0x6a, 0x02, 0xa6, 0xe3, 0x82, 0xa2, 0x8f, 0xd2, 0xe4,
+ 0xba, 0x23, 0xe0, 0x52, 0x7f, 0x0f, 0x86, 0xef, 0x74, 0xec, 0x52, 0xcd,
+ 0xe4, 0x32, 0x6f, 0xc8, 0xcb, 0x90, 0xd2, 0x9f, 0xf9, 0xbb, 0xbd, 0x57,
+ 0x38, 0x39, 0xe4, 0xe9, 0xff, 0xf5, 0xaf, 0xbf, 0x0d, 0xfd, 0xb2, 0x6d,
+ 0x85, 0x0e, 0x8d, 0xa2, 0x63, 0x11, 0x27, 0xf5, 0xfc, 0x2a, 0xfc, 0x65,
+ 0xa7, 0x43, 0x2e, 0x11, 0xd2, 0x62, 0x46, 0x13, 0xf8, 0xea, 0xb2, 0x19,
+ 0x77, 0x22, 0x9d, 0xc7, 0x1c, 0x15, 0x3d, 0xde, 0x0f, 0x25, 0x2c, 0xbf,
+ 0x9f, 0xbc, 0x57, 0xea, 0x9c, 0x3a, 0x1e, 0x7b, 0xf7, 0x31, 0x9f, 0xfe,
+ 0x1b, 0x7a, 0x5b, 0xdb, 0x08, 0x65, 0x83, 0x87, 0x4f, 0xff, 0xff, 0xf6,
+ 0xaf, 0xe2, 0xfd, 0x37, 0x89, 0xa4, 0xd8, 0x27, 0x47, 0xa6, 0xf0, 0x74,
+ 0xfa, 0xfd, 0x1d, 0x3f, 0xfd, 0x4c, 0xbe, 0x45, 0xbd, 0x0a, 0xf2, 0x9f,
+ 0x3a, 0x79, 0xdb, 0x7d, 0xba, 0x3a, 0x1e, 0x7e, 0xf8, 0x9f, 0x3f, 0xf9,
+ 0xf5, 0xfe, 0xd4, 0x97, 0xf1, 0x76, 0xa3, 0xa7, 0x93, 0x9a, 0x51, 0xd0,
+ 0xca, 0x83, 0x5e, 0x45, 0x4a, 0x39, 0x18, 0x68, 0x90, 0xfa, 0x97, 0x3f,
+ 0x75, 0xee, 0x83, 0x6b, 0xce, 0x9f, 0xf6, 0x7f, 0xa9, 0x37, 0x59, 0x6f,
+ 0x67, 0x4f, 0xfa, 0xf7, 0x6f, 0xe9, 0x97, 0xca, 0x1d, 0x3f, 0xe1, 0xc7,
+ 0x37, 0x9f, 0xfa, 0x72, 0x74, 0x52, 0x3b, 0x80, 0xc5, 0x10, 0x54, 0x7d,
+ 0x3c, 0xff, 0x14, 0xe1, 0xd3, 0xef, 0xf3, 0x54, 0x27, 0x4f, 0xfd, 0xd7,
+ 0x4a, 0xdb, 0x3a, 0xbe, 0xda, 0xd3, 0xa3, 0x0f, 0xbe, 0xe4, 0xd3, 0xfd,
+ 0x43, 0xfa, 0xbd, 0x26, 0xce, 0x9f, 0xfe, 0xad, 0x5e, 0x9c, 0xdb, 0x3a,
+ 0xad, 0xed, 0x8e, 0x9e, 0xad, 0x25, 0xce, 0x9f, 0x9d, 0xd3, 0x82, 0xef,
+ 0x59, 0xe9, 0xd1, 0x73, 0xdb, 0xd1, 0x04, 0x72, 0x99, 0x18, 0x10, 0x89,
+ 0xae, 0xa1, 0x57, 0x3f, 0xfc, 0x97, 0xae, 0x75, 0x74, 0xf3, 0xbc, 0x14,
+ 0x3a, 0x7f, 0xff, 0x0e, 0xab, 0x68, 0xda, 0x4e, 0xd9, 0xeb, 0xe3, 0x8e,
+ 0x0a, 0x9e, 0xe6, 0xab, 0xc9, 0x53, 0xd9, 0xde, 0x68, 0xe9, 0xcf, 0x1f,
+ 0x4d, 0x10, 0xcc, 0xee, 0x38, 0xe0, 0xa9, 0xd4, 0x20, 0x52, 0xcb, 0xf9,
+ 0xff, 0x55, 0x95, 0xce, 0x3c, 0x5a, 0xc3, 0xa3, 0xb3, 0xe6, 0x12, 0x89,
+ 0xfc, 0xf1, 0xad, 0x6b, 0xdb, 0x0e, 0x86, 0x4e, 0xaa, 0xc6, 0x2e, 0x48,
+ 0xed, 0x21, 0xfc, 0x2b, 0xb0, 0x8a, 0x79, 0x34, 0x8c, 0x74, 0xfe, 0xf6,
+ 0xbf, 0xdf, 0x68, 0x27, 0x4f, 0xff, 0x3d, 0x39, 0xdf, 0x8b, 0xd7, 0xc3,
+ 0x30, 0x0d, 0x10, 0x64, 0xff, 0xef, 0xe3, 0xaa, 0x10, 0xda, 0x77, 0xe3,
+ 0x47, 0x43, 0x22, 0xa3, 0xd5, 0xc8, 0xda, 0x3f, 0xf5, 0x0d, 0xc9, 0xb7,
+ 0xe9, 0xd3, 0xdf, 0x4e, 0x3a, 0xe7, 0x42, 0x1b, 0xdb, 0x8b, 0xcf, 0xee,
+ 0xaa, 0xbf, 0x55, 0x7d, 0x8e, 0x87, 0xa7, 0xb4, 0x91, 0x8f, 0x5d, 0x97,
+ 0x44, 0x13, 0xff, 0xcc, 0x36, 0x74, 0x71, 0x06, 0xb9, 0xa1, 0xf2, 0x74,
+ 0xe6, 0xfb, 0x87, 0x43, 0x2f, 0x8a, 0x72, 0x75, 0x51, 0xdb, 0x02, 0x12,
+ 0x47, 0xf3, 0x92, 0x8e, 0x3d, 0x43, 0xea, 0x52, 0x9f, 0x62, 0xb2, 0xae,
+ 0x74, 0xff, 0xf0, 0x35, 0xee, 0xca, 0xad, 0x25, 0xf7, 0x87, 0x4f, 0xe1,
+ 0x16, 0x7a, 0x99, 0x0e, 0x9f, 0xda, 0x47, 0x49, 0xa7, 0xb1, 0x52, 0x51,
+ 0xd3, 0xf5, 0x0f, 0x9f, 0xb2, 0xd0, 0xf0, 0xfc, 0x19, 0xc5, 0x26, 0x08,
+ 0x89, 0x97, 0x72, 0x9e, 0xff, 0xb6, 0xbc, 0xe9, 0xfc, 0x2f, 0x1a, 0x53,
+ 0x01, 0xd3, 0x95, 0xcd, 0x1d, 0x0c, 0x7d, 0xf4, 0x49, 0x85, 0xf3, 0xb4,
+ 0x96, 0x1d, 0x3f, 0xef, 0x75, 0x7f, 0x1f, 0xed, 0x49, 0x73, 0xa7, 0xf5,
+ 0xda, 0xca, 0x14, 0xf2, 0x74, 0xff, 0xcc, 0x39, 0xb6, 0xed, 0x7f, 0xbd,
+ 0xca, 0x8e, 0x51, 0x73, 0x48, 0x6a, 0x33, 0x9f, 0x6d, 0x12, 0xdb, 0x9d,
+ 0x3f, 0xfe, 0xae, 0x7a, 0x62, 0x55, 0xda, 0xca, 0x14, 0xf2, 0x74, 0x15,
+ 0x3f, 0x5f, 0xc3, 0x7d, 0x94, 0x54, 0x15, 0x05, 0x41, 0x50, 0x54, 0x3c,
+ 0xf8, 0x10, 0x2b, 0xb2, 0xef, 0x42, 0xba, 0x82, 0x9d, 0x82, 0xa6, 0xdd,
+ 0x15, 0x3f, 0x66, 0x69, 0xc6, 0x51, 0x5d, 0x0b, 0x59, 0x3b, 0x85, 0x41,
+ 0x50, 0x54, 0x3c, 0xb4, 0x40, 0xa8, 0x2a, 0x0a, 0x82, 0xa0, 0xa8, 0x2a,
+ 0x0a, 0x8b, 0x0d, 0xe7, 0x21, 0x48, 0x15, 0xd8, 0x55, 0xc2, 0x9d, 0x05,
+ 0x41, 0x50, 0x54, 0x3c, 0xb4, 0xb8, 0x54, 0x15, 0x05, 0x41, 0x50, 0x54,
+ 0x3c, 0xd4, 0x76, 0x15, 0xa0, 0xa7, 0x60, 0xa8, 0x2a, 0x0a, 0x82, 0xa0,
+ 0xa8, 0xb0, 0xd4, 0x79, 0x0a, 0xf8, 0x56, 0xc2, 0xa5, 0xe4, 0xa8, 0x2a,
+ 0x0a, 0x82, 0xa0, 0xa8, 0xe4, 0xd4, 0x5a, 0x15, 0xd8, 0x57, 0xa1, 0x50,
+ 0x54, 0x15, 0x05, 0x4f, 0xb6, 0xdd, 0xde, 0x8a, 0x82, 0xa1, 0xe7, 0x9e,
+ 0x01, 0x5b, 0x0a, 0xc0, 0xae, 0xc9, 0xe4, 0x05, 0x41, 0x50, 0x54, 0x15,
+ 0x05, 0x43, 0xcd, 0x45, 0xa1, 0x48, 0x14, 0xe8, 0x2a, 0x0a, 0x82, 0xa0,
+ 0xa8, 0x2a, 0x1e, 0x6a, 0x39, 0x0a, 0xd8, 0x50, 0x85, 0x4b, 0x65, 0x41,
+ 0x50, 0x54, 0x9e, 0x54, 0x15, 0x69, 0x61, 0x05, 0x41, 0x50, 0x54, 0x15,
+ 0x16, 0x1f, 0x33, 0xc2, 0xbc, 0x8d, 0x00, 0xd3, 0x81, 0x5d, 0x85, 0x68,
+ 0x2a, 0x54, 0x54, 0x15, 0x05, 0x49, 0xe5, 0x41, 0x56, 0x96, 0x10, 0x54,
+ 0x15, 0x0c, 0x7a, 0x4f, 0x0a, 0x41, 0xaf, 0x8d, 0x28, 0x2a, 0x0a, 0x82,
+ 0xa0, 0xa8, 0x2a, 0x0a, 0x86, 0x36, 0x56, 0x85, 0x7c, 0x29, 0x41, 0x42,
+ 0x15, 0x05, 0x41, 0x50, 0x54, 0x7c, 0xbe, 0xb8, 0x56, 0x82, 0xa0, 0xa8,
+ 0x2a, 0x0a, 0x85, 0x17, 0xc2, 0x15, 0xa0, 0xa9, 0x28, 0xa8, 0x2a, 0x0a,
+ 0x8e, 0xcb, 0x4f, 0x42, 0xa0, 0xa8, 0x2a, 0x0a, 0x82, 0xa1, 0x8d, 0x43,
+ 0x81, 0x5b, 0x0a, 0xf4, 0x2a, 0x19, 0x7e, 0xc6, 0xc7, 0x27, 0x9e, 0xf2,
+ 0x53, 0x4b, 0x60, 0xdb, 0x6a, 0x42, 0x33, 0xf5, 0xcf, 0x9c, 0x3a, 0xfc,
+ 0x23, 0x94, 0x91, 0xb3, 0x7c, 0x65, 0xec, 0xec, 0x5d, 0xae, 0xcf, 0xa6,
+ 0x1f, 0x5e, 0x5d, 0x32, 0xf0, 0x97, 0xd4, 0x59, 0xe0, 0x91, 0xd9, 0x2a,
+ 0x7c, 0xf1, 0x6a, 0xb9, 0x4b, 0x4d, 0x62, 0x72, 0x32, 0x8a, 0x9e, 0x40,
+ 0xcf, 0x9d, 0x39, 0x39, 0xa3, 0xa7, 0x37, 0x85, 0xda, 0x88, 0xcf, 0x9c,
+ 0x6c, 0x6b, 0x43, 0xf3, 0xfb, 0x69, 0xc7, 0x3f, 0x6b, 0x0e, 0x8b, 0x51,
+ 0x0c, 0xe2, 0x8c, 0xdd, 0xb1, 0xd3, 0xf7, 0xf0, 0x7c, 0x37, 0x67, 0x4d,
+ 0x9f, 0x3a, 0x48, 0x70, 0x16, 0xb2, 0x03, 0xa4, 0xa3, 0xa6, 0xea, 0x5a,
+ 0x22, 0x57, 0xe2, 0xdb, 0x43, 0xc1, 0xdf, 0x01, 0xf3, 0xfd, 0xb6, 0x55,
+ 0x38, 0xc3, 0x61, 0xd1, 0x48, 0x91, 0xed, 0x66, 0x7e, 0x52, 0x75, 0x60,
+ 0xf6, 0x74, 0xff, 0xf3, 0x74, 0xcf, 0xff, 0x3b, 0x65, 0xf1, 0xc7, 0x07,
+ 0x43, 0x22, 0x0f, 0xd2, 0xf8, 0xb1, 0xb0, 0x04, 0x7c, 0x65, 0x3c, 0xc2,
+ 0x78, 0x0b, 0x12, 0x1a, 0xae, 0x18, 0x28, 0x9f, 0x29, 0x5a, 0x23, 0x1a,
+ 0x5e, 0xa1, 0x4d, 0x3f, 0x98, 0x75, 0x83, 0xed, 0x1d, 0x3f, 0x3c, 0x51,
+ 0xfb, 0xa3, 0xa7, 0xd6, 0x27, 0xd9, 0xe7, 0x47, 0xcf, 0x48, 0x4a, 0xe7,
+ 0xfd, 0xb6, 0xff, 0x63, 0x5c, 0x67, 0x67, 0x4e, 0xaa, 0x70, 0xe9, 0x56,
+ 0xcf, 0x6b, 0xb3, 0xf9, 0xfb, 0xdf, 0xfa, 0xac, 0x13, 0xa7, 0x94, 0xd5,
+ 0x61, 0xd3, 0xea, 0x74, 0x2d, 0x69, 0xd0, 0x87, 0x93, 0x72, 0x19, 0xe6,
+ 0x1d, 0x01, 0xd2, 0x6a, 0x4d, 0x68, 0x5e, 0xee, 0x51, 0xa7, 0x7e, 0xa2,
+ 0x19, 0xef, 0x73, 0xef, 0x3a, 0x79, 0xbd, 0x77, 0x2e, 0x54, 0xf9, 0xeb,
+ 0xe3, 0x8e, 0x0e, 0x81, 0x3d, 0x2f, 0x49, 0xe3, 0x94, 0x4b, 0x53, 0xa4,
+ 0x29, 0x57, 0x37, 0x71, 0xee, 0x7b, 0x0e, 0x79, 0xfb, 0xfe, 0xf7, 0x42,
+ 0x07, 0x4f, 0xf5, 0x83, 0x4f, 0xdd, 0x77, 0x73, 0xa7, 0xb9, 0xe5, 0x9d,
+ 0x1d, 0x3f, 0xfd, 0xb6, 0x50, 0x36, 0xab, 0xe1, 0x98, 0x06, 0x8b, 0xe2,
+ 0x76, 0x7e, 0xc3, 0x45, 0xff, 0x0c, 0x88, 0x00, 0x57, 0x9f, 0xdc, 0x66,
+ 0xae, 0xd5, 0x61, 0xd3, 0xff, 0x3a, 0xd7, 0x96, 0x17, 0xd6, 0xd1, 0x47,
+ 0x4f, 0xd5, 0xc7, 0x8d, 0xe6, 0x8e, 0x9f, 0xff, 0x6b, 0xc3, 0xd9, 0xd2,
+ 0x0f, 0x7f, 0x46, 0x55, 0x15, 0x3d, 0xbf, 0x16, 0xe8, 0xe8, 0xb1, 0x15,
+ 0x74, 0x5e, 0x0a, 0xf3, 0x6a, 0x8e, 0x9f, 0x7d, 0x2c, 0xc5, 0x1a, 0x61,
+ 0x39, 0xed, 0x7a, 0xd8, 0x69, 0x84, 0xe6, 0xed, 0x8d, 0x40, 0x9c, 0xfe,
+ 0x1c, 0xf3, 0xa6, 0xff, 0x66, 0xa0, 0x4e, 0x7f, 0x5e, 0xb6, 0x97, 0xf6,
+ 0xc3, 0x4c, 0x27, 0x35, 0x72, 0x69, 0x84, 0xe6, 0xe3, 0x83, 0xcc, 0x27,
+ 0x14, 0x9a, 0x7d, 0xa6, 0x88, 0x5c, 0xa2, 0x3b, 0xa0, 0xba, 0x41, 0xe0,
+ 0x8e, 0x5a, 0x2c, 0xc2, 0x65, 0x9f, 0x3c, 0x92, 0xd4, 0xfe, 0xb8, 0x8f,
+ 0x2e, 0x31, 0x5a, 0x5d, 0xe1, 0xe3, 0xa9, 0x45, 0x33, 0x87, 0xb5, 0x1d,
+ 0x3f, 0xcd, 0xee, 0x85, 0x1d, 0x78, 0x51, 0xd3, 0x86, 0xaf, 0x47, 0xb1,
+ 0xf1, 0xc8, 0x65, 0xd4, 0x3e, 0x4e, 0x42, 0x14, 0xbb, 0x21, 0xd4, 0xb7,
+ 0xe7, 0x50, 0x95, 0x9f, 0x73, 0x5f, 0x4f, 0x27, 0x4f, 0x86, 0xbc, 0x53,
+ 0x87, 0x4f, 0xf6, 0xf1, 0x5b, 0x46, 0xb5, 0xe7, 0x4f, 0xde, 0x05, 0xfd,
+ 0x59, 0x61, 0xd0, 0x87, 0xd5, 0xd9, 0xc4, 0x0a, 0x2d, 0x35, 0x09, 0x29,
+ 0xff, 0x56, 0x6d, 0xc4, 0x1d, 0xd5, 0xa7, 0x43, 0x2f, 0x8e, 0xd4, 0xeb,
+ 0x82, 0x36, 0x64, 0x37, 0x44, 0x9e, 0x7f, 0xf2, 0xb5, 0x74, 0x1b, 0x5f,
+ 0xa4, 0xba, 0x1d, 0x3f, 0xff, 0x86, 0xad, 0xab, 0xe0, 0xed, 0x1b, 0x5b,
+ 0xf7, 0x14, 0x74, 0xfc, 0x3e, 0xa9, 0x36, 0xc7, 0x4f, 0xff, 0xb0, 0x75,
+ 0x99, 0xb1, 0x6d, 0x5f, 0x8a, 0xd9, 0xd3, 0xfe, 0xb3, 0x06, 0xfa, 0xda,
+ 0x35, 0xce, 0x9d, 0xfb, 0xdc, 0xf1, 0x01, 0xcf, 0xfe, 0xfb, 0x6d, 0xba,
+ 0x57, 0xc3, 0x30, 0x0d, 0x10, 0x1a, 0xcd, 0x4c, 0x62, 0x32, 0xbc, 0x33,
+ 0x47, 0x69, 0xa0, 0x6a, 0x31, 0xc8, 0xa4, 0xe5, 0xd2, 0x36, 0xc9, 0xe1,
+ 0xd7, 0x7e, 0x9d, 0x3f, 0xff, 0x3e, 0xae, 0x9f, 0xfa, 0x2b, 0xc6, 0xb7,
+ 0x5c, 0x68, 0xe8, 0xa4, 0x40, 0x61, 0x1c, 0xff, 0xff, 0x63, 0xe8, 0x5c,
+ 0x7d, 0x5a, 0xff, 0x0d, 0xda, 0xf8, 0xe3, 0x82, 0xa3, 0x68, 0x8e, 0x12,
+ 0x19, 0xfc, 0xd5, 0xf0, 0xcc, 0x03, 0x44, 0x13, 0x3f, 0xcd, 0xaa, 0xf8,
+ 0x66, 0x01, 0xa2, 0xf9, 0x9f, 0x23, 0xa1, 0xab, 0xf2, 0x7f, 0x80, 0x77,
+ 0x3f, 0xbd, 0xdf, 0x56, 0xd0, 0x36, 0x74, 0xff, 0xac, 0xcb, 0x7a, 0xab,
+ 0x43, 0x8e, 0x8e, 0x9d, 0xc7, 0x1c, 0x15, 0x3e, 0xdd, 0x06, 0x7c, 0xa5,
+ 0x97, 0xf3, 0xff, 0xf9, 0xcf, 0xb3, 0xae, 0x9e, 0x73, 0xa7, 0x87, 0x2f,
+ 0xd2, 0xad, 0xd1, 0xd1, 0xa4, 0x52, 0x78, 0x34, 0x8b, 0x13, 0x2b, 0x18,
+ 0xc1, 0xa7, 0xfe, 0xb1, 0x4d, 0x6d, 0xc6, 0xac, 0xf0, 0xf3, 0xa7, 0xff,
+ 0xbc, 0x5a, 0x3d, 0x03, 0x69, 0xdf, 0x6d, 0xf7, 0x9d, 0x3f, 0xef, 0x6e,
+ 0xd4, 0x3a, 0x77, 0xf8, 0x03, 0xa7, 0x71, 0xc7, 0x05, 0x4f, 0xef, 0x1d,
+ 0xb0, 0xd5, 0xba, 0x29, 0x65, 0xfc, 0xff, 0xfc, 0xee, 0x74, 0x0d, 0xa7,
+ 0x3c, 0xd7, 0x1d, 0x35, 0x7a, 0xb0, 0xe9, 0x66, 0xd1, 0x57, 0xea, 0x24,
+ 0x3d, 0x5c, 0xef, 0x27, 0xe9, 0x1b, 0x0f, 0xca, 0x94, 0x90, 0x2a, 0xba,
+ 0x8c, 0x36, 0x7d, 0xba, 0xd3, 0x8f, 0x3a, 0x7f, 0xd5, 0xa6, 0xfd, 0xf6,
+ 0xc3, 0xa3, 0xc4, 0x11, 0x3f, 0x9a, 0xbe, 0x19, 0x80, 0x68, 0x82, 0x16,
+ 0x79, 0x33, 0xf6, 0x6f, 0xff, 0x4e, 0x0e, 0x9f, 0xba, 0xfc, 0xf1, 0x82,
+ 0xf3, 0xa0, 0x4f, 0x7f, 0xd2, 0xd8, 0xda, 0x67, 0xdd, 0xb8, 0x8c, 0x2a,
+ 0xe7, 0xf9, 0x87, 0x5e, 0x2b, 0x79, 0x69, 0xd3, 0xff, 0xd9, 0xc6, 0xab,
+ 0x6c, 0x9a, 0x1a, 0xda, 0x1d, 0x0f, 0x44, 0x28, 0x9c, 0xcf, 0xf6, 0xdb,
+ 0xfa, 0x16, 0xab, 0x4e, 0x9f, 0xff, 0xe4, 0xb1, 0x9f, 0x7f, 0xfd, 0x2d,
+ 0x71, 0xf9, 0xf5, 0x55, 0xa7, 0x4f, 0x6b, 0x74, 0x3c, 0xa2, 0x83, 0x66,
+ 0xf3, 0xf7, 0x85, 0x5f, 0x8c, 0xb4, 0xe8, 0x63, 0xeb, 0xd1, 0xd4, 0xf2,
+ 0x38, 0x9c, 0x1d, 0x3f, 0xfe, 0xf6, 0xc1, 0x6a, 0xda, 0xdb, 0x55, 0xbf,
+ 0x7e, 0x74, 0xfa, 0xb5, 0x7f, 0x17, 0xe4, 0xfe, 0x3c, 0x11, 0x4f, 0xc1,
+ 0xb4, 0xea, 0x4f, 0x27, 0x4f, 0xca, 0x6e, 0xbe, 0xea, 0xc3, 0xa7, 0xff,
+ 0xff, 0x93, 0x58, 0xac, 0x1e, 0xde, 0x97, 0xf5, 0x5b, 0x46, 0xd6, 0xfd,
+ 0xc5, 0x1d, 0x1c, 0xa3, 0x79, 0x0c, 0x30, 0xc6, 0x7e, 0x1e, 0xe9, 0x4d,
+ 0xb3, 0xa7, 0x7f, 0xc5, 0xce, 0x9f, 0xf6, 0x08, 0x57, 0xc3, 0x30, 0x0d,
+ 0x10, 0x8c, 0x31, 0xf1, 0xfa, 0x3d, 0x3f, 0xf9, 0xaa, 0xdf, 0x1a, 0x41,
+ 0xf5, 0xf5, 0x73, 0xa7, 0xff, 0xb3, 0x2c, 0xf1, 0x5b, 0xc5, 0x2f, 0x8e,
+ 0x38, 0x3a, 0x39, 0x44, 0xfb, 0x89, 0x73, 0xfd, 0xcb, 0x5e, 0xed, 0x65,
+ 0x70, 0x74, 0x51, 0xef, 0xe1, 0x2c, 0xee, 0x38, 0xe0, 0xa9, 0xfe, 0xae,
+ 0xf3, 0xf4, 0xea, 0xb9, 0x29, 0x65, 0xfc, 0xdc, 0x70, 0x54, 0xee, 0x38,
+ 0xe0, 0xa9, 0xfb, 0x2c, 0xe7, 0x6d, 0x72, 0x96, 0x5f, 0xc0, 0xa2, 0xf7,
+ 0x84, 0x9e, 0xa3, 0x79, 0xf0, 0x27, 0x3e, 0x14, 0x52, 0xcd, 0x9c, 0xee,
+ 0x38, 0xe0, 0xa9, 0xd7, 0x6f, 0x94, 0xb2, 0xfe, 0x5d, 0xa2, 0x20, 0xb4,
+ 0xb1, 0x3f, 0x72, 0x2c, 0xfc, 0x03, 0xa7, 0xf7, 0x8f, 0xf2, 0x8e, 0x9b,
+ 0x93, 0xa7, 0xfe, 0xde, 0x3c, 0x73, 0xcb, 0x82, 0x8e, 0x1d, 0x3f, 0x6e,
+ 0x9d, 0x56, 0xae, 0x74, 0x01, 0xf9, 0xe9, 0x16, 0x3e, 0x8f, 0x7d, 0x95,
+ 0x8c, 0x2a, 0xe1, 0x93, 0x54, 0xa8, 0xc8, 0x27, 0x5b, 0xd6, 0xbb, 0xba,
+ 0x3a, 0x7f, 0xf5, 0x75, 0xf0, 0x7b, 0xa0, 0x6d, 0xb2, 0x8e, 0x9f, 0x81,
+ 0x2f, 0xb4, 0x70, 0xa9, 0xfc, 0x35, 0x6b, 0xee, 0x9e, 0x4e, 0x9e, 0xcc,
+ 0xff, 0x93, 0xa3, 0xa1, 0xeb, 0x58, 0x69, 0x3c, 0xd8, 0xa7, 0x45, 0x4e,
+ 0xe3, 0x8e, 0x0a, 0x9f, 0xfe, 0xf0, 0xdd, 0xd5, 0x0e, 0xb6, 0x8c, 0x36,
+ 0x14, 0xb2, 0xfe, 0x54, 0x08, 0x9f, 0x52, 0x0c, 0x32, 0x7c, 0x6f, 0x2c,
+ 0xb5, 0x29, 0x21, 0x05, 0xb8, 0x62, 0x4f, 0xff, 0x95, 0x40, 0xc3, 0x9a,
+ 0xbf, 0x3e, 0xe7, 0xde, 0x74, 0xf9, 0xb5, 0x77, 0x54, 0x74, 0x31, 0xfe,
+ 0x69, 0x52, 0x7f, 0xf9, 0x1d, 0x50, 0xf2, 0x39, 0xc5, 0x0e, 0x79, 0x3a,
+ 0x7f, 0xff, 0xb9, 0xda, 0x71, 0x4e, 0xc8, 0xac, 0xd5, 0xfd, 0x7d, 0x5b,
+ 0xa3, 0xa2, 0x91, 0x79, 0x8a, 0x10, 0xcd, 0xad, 0xed, 0x89, 0x2f, 0x8f,
+ 0xd7, 0x98, 0xcd, 0xaa, 0x70, 0xed, 0x23, 0xaf, 0x72, 0x17, 0x7f, 0x8c,
+ 0xb5, 0x50, 0x99, 0xdc, 0x64, 0x58, 0x5f, 0xdc, 0x23, 0xc6, 0x32, 0x0b,
+ 0xcb, 0x05, 0xd4, 0xa0, 0xbf, 0x61, 0xa1, 0xc4, 0x37, 0x67, 0x3a, 0x61,
+ 0x3a, 0x7f, 0xfa, 0x85, 0x7a, 0xf2, 0x96, 0xdf, 0x75, 0xde, 0x1d, 0x2b,
+ 0x5e, 0x7d, 0xbc, 0x8e, 0x4f, 0xdb, 0x71, 0x36, 0x8a, 0x3a, 0x7f, 0xc2,
+ 0xda, 0xde, 0x77, 0x96, 0xdc, 0xe9, 0xce, 0x7b, 0xf3, 0xa7, 0xfd, 0x89,
+ 0xfa, 0xb5, 0x7c, 0x71, 0xc1, 0xd1, 0x87, 0xbf, 0x71, 0xe9, 0xff, 0xe1,
+ 0x67, 0xf4, 0xf1, 0xa4, 0x1f, 0x5f, 0x57, 0x3a, 0x29, 0x33, 0xd0, 0x2d,
+ 0xdc, 0x27, 0x7b, 0x21, 0x9f, 0xcc, 0x2f, 0x1a, 0xae, 0xce, 0x9f, 0xcf,
+ 0xaf, 0xdc, 0x5a, 0xc3, 0xa7, 0xff, 0xab, 0x4c, 0x21, 0x5a, 0xda, 0x7f,
+ 0xb0, 0x3a, 0x7f, 0x32, 0xaf, 0x7c, 0x1b, 0x0e, 0x9f, 0x65, 0xe8, 0x74,
+ 0x74, 0xed, 0x67, 0x5c, 0xe9, 0xfd, 0xad, 0xa2, 0xfb, 0xc4, 0x3a, 0x39,
+ 0x47, 0xa6, 0xd3, 0x04, 0xcb, 0x44, 0xbe, 0x8f, 0xcf, 0xef, 0x7b, 0x6d,
+ 0xa6, 0x3c, 0xe9, 0xfe, 0x0a, 0xd3, 0x3a, 0x41, 0xec, 0xe9, 0xff, 0xfb,
+ 0xd6, 0xd5, 0xe8, 0x7a, 0x7d, 0x93, 0x91, 0xc7, 0x9d, 0x08, 0x89, 0x31,
+ 0x38, 0x9f, 0xff, 0x86, 0xaf, 0xef, 0x4a, 0xde, 0x0d, 0x38, 0xf6, 0xb4,
+ 0xe9, 0xff, 0x55, 0xfd, 0xaf, 0x86, 0x60, 0x1a, 0x20, 0x69, 0xed, 0x6f,
+ 0x1f, 0xd1, 0x14, 0x82, 0xb9, 0x0c, 0x98, 0x05, 0x43, 0x16, 0x7f, 0xd9,
+ 0xfa, 0x1e, 0xef, 0xab, 0xda, 0x74, 0xff, 0xff, 0xfd, 0x5a, 0xde, 0x0f,
+ 0x9e, 0x97, 0xfe, 0x66, 0x9d, 0x57, 0x3d, 0x29, 0x58, 0x36, 0xbc, 0xf1,
+ 0x05, 0xcf, 0xfb, 0x33, 0xc8, 0x67, 0x3d, 0x3c, 0xf0, 0x78, 0x82, 0xe7,
+ 0xfe, 0xda, 0x6d, 0x18, 0x75, 0xd3, 0xcf, 0x07, 0x88, 0x2e, 0x7f, 0x32,
+ 0x0e, 0xba, 0x79, 0xe0, 0xf1, 0x05, 0xcf, 0xca, 0xae, 0x7a, 0x79, 0xe0,
+ 0xf1, 0x05, 0xcf, 0xff, 0xf6, 0x08, 0xa2, 0xba, 0x5c, 0x36, 0x9f, 0x4f,
+ 0x36, 0x57, 0x07, 0x88, 0x2e, 0x6b, 0x7a, 0x72, 0x9c, 0xe8, 0x28, 0xfd,
+ 0x53, 0x10, 0xc5, 0x02, 0x19, 0x56, 0x86, 0xcf, 0xc6, 0x51, 0xcc, 0xfe,
+ 0x46, 0xf3, 0x7d, 0x5e, 0xd3, 0xa7, 0xb3, 0xfd, 0xe1, 0xd3, 0xff, 0x6d,
+ 0x36, 0x8c, 0x3a, 0xe9, 0xe7, 0x83, 0xc4, 0x17, 0x3f, 0xce, 0x5c, 0x12,
+ 0xce, 0x9e, 0x78, 0x3c, 0x41, 0x73, 0xed, 0x5d, 0x95, 0xd0, 0x11, 0x41,
+ 0xe1, 0x52, 0x7f, 0xf7, 0x40, 0xda, 0x03, 0x6a, 0xfd, 0x3c, 0xf0, 0x78,
+ 0x82, 0xe7, 0xff, 0xfe, 0x11, 0x45, 0x74, 0xf6, 0xba, 0x5c, 0x36, 0x9f,
+ 0x4f, 0x36, 0x57, 0x07, 0x88, 0x2e, 0x29, 0x32, 0x3b, 0x50, 0xf1, 0x72,
+ 0x7f, 0xb6, 0x9f, 0x4f, 0x36, 0x57, 0x07, 0x88, 0x2e, 0x7f, 0xfb, 0x32,
+ 0xd7, 0xdf, 0x69, 0xcf, 0x2d, 0xf6, 0x2a, 0x7f, 0xd4, 0xf7, 0xfb, 0x7f,
+ 0x8d, 0x9d, 0x47, 0x88, 0x2e, 0x01, 0x1d, 0x1f, 0x48, 0xba, 0x84, 0xff,
+ 0x81, 0x3f, 0xac, 0xee, 0xfd, 0x38, 0x3c, 0x41, 0x73, 0xf6, 0xd3, 0x7b,
+ 0x4e, 0xcd, 0x00, 0x5c, 0xfa, 0xbb, 0xe9, 0xe7, 0x83, 0xc4, 0x17, 0x35,
+ 0x68, 0x0f, 0xd3, 0x67, 0x51, 0x6a, 0x3b, 0xaf, 0x0c, 0x29, 0xf9, 0x55,
+ 0xcf, 0x4f, 0x3c, 0x1e, 0x20, 0xb9, 0xff, 0x06, 0xd3, 0xe9, 0xe6, 0xca,
+ 0xe0, 0xf1, 0x05, 0xcd, 0x5d, 0x31, 0x11, 0xb7, 0x40, 0x9f, 0xde, 0xa2,
+ 0xb0, 0x6d, 0x79, 0xe2, 0x0b, 0x9f, 0xf5, 0x23, 0xaa, 0x1a, 0xe7, 0x1e,
+ 0x78, 0x82, 0xd4, 0x78, 0x11, 0xca, 0xf0, 0x2f, 0xcd, 0xfb, 0x35, 0x18,
+ 0xf9, 0x2f, 0x18, 0xc6, 0xa3, 0x1d, 0xf6, 0x16, 0xdc, 0x37, 0xcf, 0xbb,
+ 0xbf, 0x7d, 0xb1, 0xa2, 0x0b, 0x5a, 0x23, 0xa7, 0xfd, 0x4f, 0xde, 0x3d,
+ 0xd9, 0xdb, 0xdb, 0x0e, 0x9c, 0xa6, 0x79, 0xd3, 0xea, 0xe7, 0x7e, 0xf0,
+ 0x74, 0xbf, 0x87, 0x8a, 0x23, 0x73, 0x93, 0xaa, 0x8e, 0x9d, 0x9f, 0xec,
+ 0xe9, 0x5a, 0xc6, 0xe7, 0x43, 0xb3, 0xf5, 0x59, 0x9b, 0x6e, 0xb9, 0xd0,
+ 0x88, 0xb6, 0xc5, 0xf1, 0x27, 0x9d, 0x9f, 0xb0, 0xe9, 0xbb, 0x63, 0xa7,
+ 0x91, 0x95, 0x47, 0x41, 0xd3, 0xf6, 0x79, 0xd3, 0x7f, 0xb3, 0xa3, 0x93,
+ 0x72, 0x21, 0x53, 0xff, 0xf9, 0x93, 0x91, 0x6f, 0x43, 0x54, 0x1c, 0xb0,
+ 0x78, 0x51, 0xd3, 0x76, 0xc7, 0x4c, 0xde, 0x4e, 0x9f, 0xea, 0xd5, 0xd9,
+ 0x5e, 0x29, 0xc3, 0xa7, 0xf5, 0xeb, 0x69, 0x7f, 0x6c, 0x3a, 0x6e, 0x38,
+ 0x2a, 0x7f, 0x86, 0x9d, 0x63, 0xee, 0x9c, 0x9d, 0x00, 0x9f, 0xba, 0x0e,
+ 0x7c, 0x59, 0x4b, 0x1b, 0x21, 0xed, 0x81, 0xdc, 0x16, 0x11, 0x7b, 0x9d,
+ 0x70, 0x69, 0xe0, 0x62, 0x77, 0x1c, 0x70, 0x54, 0x94, 0x52, 0xcb, 0xf9,
+ 0xf6, 0x39, 0x99, 0xf2, 0x96, 0x8d, 0xdf, 0x10, 0xbe, 0x9f, 0xd6, 0xe9,
+ 0xab, 0x75, 0x61, 0xd0, 0xcd, 0x9d, 0x25, 0x46, 0xcf, 0xe5, 0x0a, 0xd3,
+ 0x04, 0x8c, 0x9b, 0xe9, 0x7b, 0x8f, 0x1b, 0x29, 0x31, 0x42, 0x93, 0x78,
+ 0xd0, 0x7d, 0x96, 0x02, 0xe9, 0x32, 0x7a, 0x81, 0xb4, 0x74, 0xf5, 0x2a,
+ 0xb4, 0x74, 0xff, 0xdb, 0xf6, 0xcf, 0x57, 0xb4, 0x0c, 0xf9, 0xd3, 0xd9,
+ 0x67, 0x87, 0x9d, 0x0c, 0x8a, 0x9b, 0x47, 0xf4, 0x40, 0xec, 0x8d, 0x3f,
+ 0x0f, 0xbc, 0xab, 0x1e, 0x74, 0xff, 0xf5, 0xaf, 0x16, 0xe8, 0xa1, 0x6f,
+ 0x3a, 0x4b, 0x0e, 0x9f, 0xd7, 0xd3, 0xaa, 0x1a, 0xe4, 0xe8, 0x64, 0x5a,
+ 0xa1, 0x76, 0x29, 0xce, 0xce, 0x9e, 0x0e, 0x9f, 0xfe, 0x17, 0xf4, 0xae,
+ 0x52, 0xf6, 0xeb, 0xdc, 0xb9, 0xd3, 0xee, 0x9b, 0x6f, 0xbc, 0xe8, 0xe8,
+ 0x89, 0xba, 0x1f, 0xe1, 0x4e, 0x7e, 0xb1, 0xc7, 0xf5, 0x9f, 0xb0, 0xe9,
+ 0x9f, 0x61, 0xd3, 0xed, 0xd2, 0x3e, 0xe7, 0x4f, 0xff, 0x6d, 0xbc, 0x2f,
+ 0x43, 0x9d, 0xde, 0xed, 0xd9, 0x53, 0xfb, 0xba, 0xf8, 0x66, 0x01, 0xe2,
+ 0x04, 0x9d, 0xa4, 0xb0, 0xe8, 0x7a, 0x34, 0x79, 0x26, 0xfa, 0x92, 0x8f,
+ 0x66, 0x76, 0x79, 0xd3, 0xda, 0xb3, 0x04, 0xe9, 0xeb, 0x6f, 0x9a, 0x3a,
+ 0x2c, 0x3d, 0xca, 0x19, 0xd9, 0x0c, 0xfe, 0x1c, 0xe2, 0xf7, 0x6e, 0xce,
+ 0x9d, 0xc7, 0x1c, 0x1e, 0xaf, 0xa9, 0xd8, 0x3c, 0x96, 0xaf, 0xa2, 0xcd,
+ 0x64, 0x72, 0x89, 0x8e, 0xd7, 0xe7, 0xff, 0xd4, 0x29, 0xe5, 0x77, 0xd6,
+ 0xfd, 0xc7, 0xbd, 0x8e, 0x8b, 0x0f, 0xef, 0xc9, 0x2c, 0xfb, 0x04, 0x51,
+ 0x47, 0x47, 0x5b, 0x56, 0x86, 0xf3, 0x6a, 0x87, 0x42, 0x42, 0x6b, 0x23,
+ 0x42, 0x12, 0x59, 0xf2, 0x69, 0xb5, 0x72, 0xa7, 0x81, 0xb5, 0x72, 0xa6,
+ 0xe3, 0x82, 0xa1, 0xe7, 0xbd, 0x44, 0xdc, 0x10, 0x4d, 0x5c, 0x14, 0xb3,
+ 0x5f, 0x3f, 0xfe, 0xad, 0x30, 0x55, 0x0e, 0xb6, 0x8c, 0x36, 0x1d, 0x1d,
+ 0x9f, 0xb7, 0x04, 0xd3, 0xff, 0xf9, 0x9d, 0x20, 0xf7, 0xd3, 0x57, 0xa0,
+ 0xde, 0x0e, 0xae, 0x74, 0xfd, 0x6b, 0xf7, 0xeb, 0x7c, 0xe9, 0xff, 0x55,
+ 0x39, 0xfa, 0xf5, 0x4d, 0x73, 0xa1, 0xc3, 0xed, 0xf9, 0x7c, 0xe7, 0xe7,
+ 0xce, 0x9f, 0x3e, 0xb5, 0x5c, 0x95, 0x24, 0x70, 0xf0, 0xb4, 0x37, 0x3d,
+ 0xaf, 0x35, 0xb3, 0xa6, 0xed, 0x8e, 0x9b, 0xb6, 0x3a, 0x7d, 0xeb, 0xe8,
+ 0x56, 0x86, 0xb3, 0xb1, 0x68, 0x64, 0x46, 0x8a, 0x7c, 0xff, 0xda, 0xdd,
+ 0x2b, 0xc3, 0x77, 0x56, 0xe8, 0xe9, 0xfd, 0x68, 0x27, 0xfc, 0x37, 0x27,
+ 0x4f, 0x76, 0xac, 0x7d, 0xcf, 0xf3, 0x48, 0xf3, 0xba, 0xaa, 0xd3, 0xa7,
+ 0xbb, 0xfa, 0x7c, 0xe8, 0x63, 0xfb, 0xc3, 0xae, 0x07, 0xe7, 0xaf, 0xed,
+ 0xba, 0x3a, 0x77, 0x1c, 0x70, 0x54, 0xfa, 0xbc, 0x8f, 0xb7, 0x29, 0x65,
+ 0xfc, 0xfa, 0x97, 0xc7, 0x1c, 0x1d, 0x0c, 0x7c, 0x5a, 0x38, 0x9f, 0xfa,
+ 0x86, 0xae, 0x1b, 0x40, 0x61, 0x3a, 0x7b, 0x8c, 0x17, 0x9d, 0x3f, 0xda,
+ 0x6b, 0x7b, 0xcd, 0xed, 0x0e, 0x96, 0xce, 0x8a, 0x3c, 0x90, 0x39, 0x9d,
+ 0xc7, 0x1c, 0x15, 0x3f, 0x26, 0x79, 0xda, 0x68, 0xa5, 0x97, 0xf3, 0xea,
+ 0xee, 0xa9, 0xc3, 0xa5, 0x7e, 0x88, 0xa2, 0xf9, 0xf8, 0x9e, 0x4d, 0xeb,
+ 0xf9, 0x4d, 0x0e, 0xa3, 0x0c, 0x92, 0x6d, 0x3b, 0x81, 0x8e, 0x06, 0x19,
+ 0x77, 0xfd, 0xe4, 0x95, 0x0c, 0xff, 0x2c, 0xbf, 0x85, 0xae, 0xe3, 0x18,
+ 0xc2, 0xeb, 0xc2, 0x97, 0x51, 0xec, 0xcf, 0xcc, 0xaf, 0xff, 0x34, 0x74,
+ 0xff, 0xf2, 0x2a, 0xd7, 0xdf, 0xa5, 0x08, 0xd2, 0x76, 0x74, 0x6c, 0xff,
+ 0x34, 0x59, 0x25, 0xbb, 0xd0, 0x9f, 0x87, 0x77, 0x65, 0x3d, 0x6a, 0x41,
+ 0xeb, 0x42, 0xa6, 0x9c, 0xaa, 0xb2, 0x50, 0x2b, 0xe5, 0x55, 0xf3, 0x2d,
+ 0x2a, 0xab, 0x90, 0x1f, 0x31, 0xdb, 0x84, 0xad, 0xdb, 0x65, 0xa9, 0x24,
+ 0xad, 0xc7, 0x27, 0xd2, 0xbf, 0x3b, 0x78, 0xa9, 0x5e, 0x5b, 0xa4, 0x2f,
+ 0x65, 0x61, 0x17, 0xdc, 0xb9, 0x91, 0x9f, 0x5c, 0xbd, 0x6c, 0x25, 0xaa,
+ 0xd5, 0x43, 0xd8, 0xdf, 0x1d, 0x43, 0xd7, 0x88, 0x64, 0x75, 0x4b, 0x75,
+ 0xf1, 0x3e, 0xda, 0xed, 0x18, 0xbc, 0x2e, 0x14, 0x4f, 0x0f, 0xc5, 0x00,
+ 0xd4, 0xfe, 0x5d, 0x7c, 0x33, 0x00, 0xd1, 0x71, 0xcf, 0xe5, 0xd7, 0xc3,
+ 0x30, 0x0d, 0x17, 0x5c, 0xff, 0xcb, 0xc7, 0xae, 0xbe, 0x19, 0x80, 0x68,
+ 0x94, 0x61, 0xa1, 0x4b, 0xae, 0xf2, 0x8e, 0x4f, 0x3c, 0x9e, 0x01, 0xe2,
+ 0x43, 0xd3, 0xae, 0x7f, 0x98, 0xa2, 0xcb, 0xb9, 0xc6, 0x8f, 0x1d, 0x8f,
+ 0x27, 0xff, 0x2d, 0x58, 0xf5, 0xd7, 0xc3, 0x30, 0x0d, 0x12, 0xd4, 0xfb,
+ 0xe1, 0x98, 0x06, 0x88, 0xde, 0x7f, 0xd8, 0xf5, 0xd7, 0xc3, 0x30, 0x0d,
+ 0x12, 0xfc, 0x97, 0x47, 0xf0, 0xa3, 0x19, 0xfc, 0xba, 0xf8, 0x66, 0x01,
+ 0xa2, 0xab, 0x9f, 0xef, 0x34, 0x35, 0x6e, 0xb1, 0x47, 0x4d, 0xca, 0x1d,
+ 0x3f, 0x57, 0xc3, 0x30, 0x0d, 0x12, 0x04, 0x74, 0x3c, 0xc5, 0x8b, 0x4f,
+ 0xaf, 0x83, 0x96, 0x9d, 0x0f, 0x3c, 0xab, 0x49, 0x27, 0xff, 0x53, 0x9b,
+ 0xc5, 0x6b, 0x6d, 0xaf, 0x54, 0x74, 0x79, 0x4c, 0xf7, 0x21, 0x9f, 0xe0,
+ 0x8e, 0x7f, 0xe1, 0xab, 0x17, 0xd4, 0xc2, 0x35, 0xa3, 0xa1, 0x67, 0xfb,
+ 0xf3, 0x99, 0xfc, 0xba, 0xf8, 0x66, 0x01, 0xa2, 0xc8, 0x9f, 0xcb, 0xaf,
+ 0x86, 0x60, 0x1a, 0x2d, 0x79, 0xfc, 0xba, 0xf8, 0x66, 0x01, 0xa2, 0xe4,
+ 0x9f, 0x7c, 0x33, 0x00, 0xd1, 0x76, 0x4f, 0xfb, 0x1e, 0xba, 0xf8, 0x66,
+ 0x01, 0xa2, 0x8e, 0x92, 0xe8, 0xfe, 0x14, 0x63, 0x27, 0x9d, 0x3e, 0xf8,
+ 0x66, 0x01, 0xa2, 0x95, 0x9f, 0xff, 0xfe, 0xdb, 0x58, 0xdb, 0x47, 0x59,
+ 0xce, 0xd1, 0x61, 0xb4, 0x73, 0x6d, 0x65, 0x1d, 0x33, 0xd7, 0x48, 0xb0,
+ 0x70, 0xc6, 0x65, 0xaa, 0xd4, 0x77, 0xe4, 0x30, 0x22, 0xc5, 0xd8, 0x07,
+ 0xc3, 0x2e, 0xd2, 0x74, 0x8f, 0xd9, 0x44, 0x5d, 0x9e, 0x5c, 0xf3, 0x50,
+ 0xb4, 0x75, 0x18, 0xb4, 0xff, 0x3d, 0x75, 0xf0, 0xcc, 0x03, 0x44, 0x71,
+ 0x3f, 0xc8, 0xba, 0xf8, 0x66, 0x01, 0xa2, 0xb5, 0x92, 0xf1, 0x10, 0x7a,
+ 0x42, 0x9f, 0xfc, 0xb5, 0x63, 0xd7, 0x5f, 0x0c, 0xc0, 0x34, 0x4b, 0x73,
+ 0x55, 0xa7, 0x4f, 0xee, 0x69, 0x4a, 0x64, 0xb9, 0xd1, 0x69, 0xe4, 0x20,
+ 0xb4, 0xed, 0xf2, 0xf3, 0xa7, 0x3d, 0x40, 0x74, 0xff, 0xfd, 0xbc, 0xb7,
+ 0xbe, 0x77, 0x8f, 0xab, 0x8f, 0xb9, 0xe0, 0xe8, 0x34, 0x43, 0x73, 0xfe,
+ 0xc7, 0xae, 0xbe, 0x19, 0x80, 0x68, 0x98, 0x26, 0x0a, 0x3a, 0x6f, 0x7b,
+ 0x2a, 0x10, 0xd6, 0x7c, 0x52, 0x7f, 0x0d, 0x6b, 0x4d, 0xfb, 0x9d, 0x25,
+ 0xb2, 0x72, 0x96, 0x11, 0x72, 0x3b, 0x43, 0x60, 0xbe, 0xa1, 0x7d, 0x39,
+ 0xf8, 0x20, 0x9c, 0xaf, 0x7e, 0x54, 0xff, 0xb1, 0xeb, 0xaf, 0x86, 0x60,
+ 0x1a, 0x26, 0x39, 0x2d, 0x0f, 0x91, 0x43, 0xb3, 0xf3, 0x5f, 0xa6, 0xab,
+ 0x67, 0x4e, 0x61, 0xb0, 0xe9, 0xff, 0xff, 0xe7, 0xdf, 0x75, 0xef, 0x17,
+ 0xdd, 0x05, 0x5f, 0xa5, 0x5a, 0xfb, 0xa0, 0xa1, 0xd3, 0xc1, 0x98, 0x06,
+ 0x8a, 0xc6, 0x7f, 0xdd, 0x55, 0xa1, 0xaf, 0x58, 0x74, 0x74, 0x79, 0x4c,
+ 0xc8, 0x0b, 0xad, 0x1b, 0xfb, 0xfe, 0x8a, 0xe7, 0xff, 0x30, 0xeb, 0xcf,
+ 0xac, 0x34, 0x0d, 0xf3, 0xa7, 0xfb, 0x9d, 0xd5, 0xed, 0x7b, 0x6c, 0xe9,
+ 0xfe, 0x6b, 0x5e, 0xe3, 0xf3, 0xf6, 0x1d, 0x14, 0x7e, 0xa8, 0x75, 0x3f,
+ 0xea, 0xe7, 0xe9, 0xed, 0x9d, 0xdd, 0xe7, 0x4f, 0xff, 0xfc, 0x3e, 0xd9,
+ 0x41, 0xd0, 0x7d, 0x76, 0xe9, 0x56, 0xbe, 0xbd, 0x1e, 0xee, 0x74, 0xfe,
+ 0xeb, 0x76, 0x38, 0xfe, 0xb3, 0xf6, 0x1d, 0x3f, 0xfa, 0x9c, 0xde, 0x2b,
+ 0x5b, 0x6d, 0x7a, 0xa3, 0xa7, 0x6d, 0x17, 0x4a, 0x9d, 0x41, 0x37, 0x70,
+ 0xbd, 0x12, 0x0d, 0x21, 0x75, 0x3e, 0x78, 0x42, 0x9b, 0xc7, 0x67, 0x4d,
+ 0xeb, 0x87, 0x4f, 0xb0, 0x6c, 0xf6, 0xe7, 0x47, 0x67, 0xb2, 0x23, 0x37,
+ 0x18, 0x9f, 0x7b, 0x6d, 0x8d, 0xe4, 0xe9, 0xf2, 0xa8, 0x59, 0xe7, 0x4f,
+ 0x37, 0xf0, 0x4e, 0x9e, 0xbd, 0xdb, 0xb3, 0xa1, 0x8f, 0x9b, 0x64, 0xbc,
+ 0x0f, 0xcf, 0x99, 0xfd, 0xfa, 0xf3, 0xa7, 0x30, 0xbc, 0xe8, 0x70, 0xf0,
+ 0xf4, 0x53, 0x3b, 0x7e, 0x14, 0x74, 0xfc, 0xca, 0xa1, 0x4f, 0x27, 0x4a,
+ 0xe7, 0x42, 0x1b, 0xcc, 0x2c, 0x9b, 0xb6, 0x2a, 0x6e, 0x38, 0x2a, 0x10,
+ 0xd7, 0x70, 0x2d, 0x3f, 0xb1, 0xe3, 0x5a, 0xda, 0x14, 0xb3, 0x43, 0x3d,
+ 0xce, 0x5b, 0x73, 0xa7, 0x30, 0xb8, 0x74, 0xc2, 0xc7, 0x43, 0x86, 0xbf,
+ 0xe3, 0x73, 0xff, 0x79, 0x41, 0x0b, 0xb2, 0xb2, 0xdd, 0x1d, 0x3b, 0xba,
+ 0x76, 0x3a, 0x3c, 0x9f, 0x1f, 0xd1, 0x25, 0xe4, 0xe9, 0xbf, 0xe4, 0xe8,
+ 0x43, 0x55, 0xe0, 0x4a, 0x7f, 0xf9, 0x34, 0xcf, 0x4d, 0x6e, 0xad, 0xd7,
+ 0xac, 0x74, 0x32, 0x72, 0xd4, 0xa4, 0x90, 0x85, 0xda, 0x76, 0x11, 0x41,
+ 0xd2, 0x51, 0xd2, 0xde, 0x8b, 0xa7, 0x41, 0x53, 0xf7, 0x6d, 0xba, 0x75,
+ 0x87, 0x4f, 0xc9, 0xaa, 0xde, 0x79, 0x3a, 0x77, 0x1c, 0x70, 0x54, 0xff,
+ 0xd4, 0x1c, 0xb5, 0x9e, 0x2b, 0x79, 0x69, 0x4b, 0x2f, 0xe7, 0x93, 0xee,
+ 0xdc, 0x9d, 0x2f, 0x9d, 0x3e, 0x52, 0x6b, 0xbc, 0x3a, 0x2c, 0x3d, 0xce,
+ 0xb9, 0x2f, 0xa2, 0x13, 0xf8, 0x12, 0xe3, 0x4e, 0xb0, 0xe9, 0xab, 0x47,
+ 0x45, 0xa7, 0x8d, 0xb3, 0x19, 0xed, 0x0d, 0x3c, 0xe9, 0xff, 0xc9, 0x7d,
+ 0xd7, 0x23, 0x4e, 0x86, 0xae, 0x74, 0x7c, 0xfa, 0x74, 0x41, 0x25, 0xb2,
+ 0xf6, 0xb5, 0x85, 0xfc, 0xc2, 0x4a, 0x9c, 0x90, 0x8f, 0xeb, 0x4a, 0x6e,
+ 0xdc, 0x7a, 0xd8, 0xcd, 0xd9, 0x43, 0xb8, 0x5c, 0x29, 0x97, 0x85, 0x8e,
+ 0x9e, 0xfc, 0x42, 0x32, 0x7d, 0xf0, 0xcc, 0x03, 0x45, 0x6f, 0x3f, 0xec,
+ 0x7a, 0xeb, 0xe1, 0x98, 0x06, 0x89, 0xc2, 0x4b, 0xa3, 0xf8, 0x51, 0x8c,
+ 0xde, 0xec, 0xe9, 0xf7, 0xc3, 0x30, 0x0d, 0x16, 0x8c, 0xfc, 0xd8, 0x3e,
+ 0xf3, 0x47, 0x4c, 0x9e, 0x4e, 0x9f, 0xff, 0x58, 0xda, 0x6e, 0x7e, 0xdb,
+ 0xcb, 0x8d, 0x76, 0x74, 0xff, 0x9a, 0xdc, 0xeb, 0xec, 0x73, 0xaf, 0x61,
+ 0xd0, 0xc8, 0x9b, 0xda, 0xac, 0xa9, 0xc4, 0x6a, 0x5e, 0x16, 0x52, 0x5b,
+ 0xbc, 0x9b, 0xb5, 0x0b, 0xa8, 0xc7, 0x71, 0x80, 0x4f, 0x06, 0x60, 0x1a,
+ 0x2d, 0xa9, 0xfb, 0x6c, 0xa6, 0x4e, 0x4e, 0x95, 0x7c, 0xf5, 0xf4, 0x57,
+ 0x3f, 0xcb, 0xf3, 0xe7, 0x3f, 0xcf, 0xa2, 0x74, 0x2c, 0xf9, 0x7b, 0x27,
+ 0x9f, 0xcb, 0xaf, 0x86, 0x60, 0x1a, 0x2e, 0x59, 0xfc, 0xba, 0xf8, 0x66,
+ 0x01, 0xa2, 0xed, 0x86, 0x6c, 0xd6, 0x2c, 0x28, 0x7c, 0xa2, 0xfe, 0x61,
+ 0xbb, 0xe6, 0x5e, 0x72, 0x4f, 0xd6, 0xf5, 0xe3, 0x67, 0xdc, 0x73, 0xa3,
+ 0x18, 0x55, 0xc8, 0xf4, 0x79, 0x3f, 0x97, 0x5f, 0x0c, 0xc0, 0x34, 0x54,
+ 0xf3, 0x26, 0x8e, 0x9e, 0x0c, 0xc0, 0x34, 0x57, 0x33, 0xf9, 0x75, 0xf0,
+ 0xcc, 0x03, 0x45, 0x9d, 0x1f, 0x3e, 0x7d, 0x95, 0xcf, 0xff, 0x56, 0x9a,
+ 0xfd, 0x3d, 0xbe, 0x99, 0xc7, 0x10, 0xe9, 0xff, 0x6d, 0x3f, 0xce, 0xe9,
+ 0x07, 0xc9, 0xd3, 0xef, 0x86, 0x60, 0x1a, 0x24, 0x29, 0xfe, 0x4b, 0x6f,
+ 0xa1, 0x65, 0x5c, 0xe9, 0x9e, 0xba, 0x3e, 0x9e, 0xcc, 0x67, 0x9d, 0xed,
+ 0xb2, 0x8e, 0x9f, 0xd5, 0xbb, 0xde, 0xbf, 0x61, 0xd2, 0x5f, 0x2a, 0x88,
+ 0x29, 0xf1, 0x08, 0x9c, 0x53, 0xc8, 0x54, 0x5c, 0xbb, 0x44, 0xd3, 0xff,
+ 0x96, 0xac, 0x7a, 0xeb, 0xe1, 0x98, 0x06, 0x89, 0xf2, 0x01, 0x58, 0xff,
+ 0x5e, 0x52, 0xe6, 0xdc, 0x27, 0xdf, 0x0c, 0xc0, 0x34, 0x56, 0x53, 0xfe,
+ 0xc7, 0xae, 0xbe, 0x19, 0x80, 0x68, 0x9b, 0xa6, 0x45, 0xd1, 0xfc, 0x28,
+ 0xc6, 0x7d, 0xf0, 0xcc, 0x03, 0x44, 0xad, 0x3f, 0xde, 0x76, 0x9d, 0x3d,
+ 0x0a, 0xb9, 0xd3, 0xe5, 0xab, 0x1e, 0xba, 0x3e, 0xdc, 0x31, 0x9f, 0xf2,
+ 0x5f, 0xd5, 0x0a, 0x3a, 0xf7, 0x0e, 0x9f, 0xc2, 0xdf, 0xa7, 0x58, 0xa3,
+ 0xa1, 0xe7, 0xe4, 0x88, 0x13, 0xef, 0x86, 0x60, 0x1a, 0x25, 0xc9, 0xfe,
+ 0x4c, 0x7e, 0x85, 0x95, 0x73, 0xa7, 0x9d, 0x20, 0xb1, 0xd3, 0xe5, 0xab,
+ 0x1e, 0xb6, 0x45, 0x4d, 0x10, 0xec, 0xc7, 0x0d, 0xa7, 0xfe, 0x5e, 0x3d,
+ 0x75, 0xf0, 0xcc, 0x03, 0x44, 0x77, 0x3f, 0xda, 0xdd, 0x3d, 0x78, 0x37,
+ 0x3a, 0x7e, 0xeb, 0x05, 0x82, 0x84, 0xe9, 0xbd, 0xd9, 0xd3, 0xf3, 0xbe,
+ 0x35, 0xbc, 0xd1, 0xd3, 0xfa, 0xb8, 0xbb, 0x0e, 0xae, 0x74, 0xfb, 0xe1,
+ 0x98, 0x06, 0x8a, 0x86, 0x7b, 0x7a, 0xab, 0x0e, 0x9f, 0x55, 0x98, 0x2e,
+ 0x8e, 0x9f, 0xff, 0xff, 0xcc, 0xfe, 0x9a, 0xda, 0x35, 0xfa, 0x57, 0xa0,
+ 0xce, 0xba, 0x57, 0xff, 0x4e, 0xbd, 0xcd, 0x9d, 0x14, 0x8e, 0x11, 0x22,
+ 0xb9, 0x44, 0xff, 0xff, 0x7b, 0x9d, 0x74, 0xb3, 0x78, 0x9a, 0x6d, 0xa6,
+ 0xaf, 0x5c, 0x9d, 0x25, 0xbb, 0xea, 0x94, 0x5d, 0xe2, 0xee, 0xb0, 0x5e,
+ 0xc3, 0x0a, 0x32, 0xd4, 0x62, 0x5d, 0x45, 0xd3, 0xef, 0x86, 0x60, 0x1a,
+ 0x2a, 0x89, 0xff, 0x63, 0xd7, 0x5f, 0x0c, 0xc0, 0x34, 0x4d, 0x72, 0x5d,
+ 0x1f, 0xc2, 0x8c, 0x67, 0xf2, 0xeb, 0xe1, 0x98, 0x06, 0x8a, 0xb2, 0x7f,
+ 0xe5, 0xe3, 0xd7, 0x5f, 0x0c, 0xc0, 0x34, 0x48, 0x93, 0xef, 0x86, 0x60,
+ 0x1a, 0x2d, 0x29, 0xff, 0x63, 0xd7, 0x5f, 0x0c, 0xc0, 0x34, 0x4f, 0xb2,
+ 0x5d, 0x1f, 0xc2, 0x8c, 0x67, 0xff, 0x2d, 0x58, 0xf5, 0xd7, 0xc3, 0x30,
+ 0x0d, 0x14, 0x24, 0xfb, 0x69, 0x63, 0x7c, 0xe9, 0xf7, 0xc3, 0x30, 0x0d,
+ 0x14, 0x7c, 0xff, 0x85, 0x9c, 0x61, 0x67, 0x36, 0xc7, 0x4f, 0xff, 0xd5,
+ 0xce, 0xdb, 0xc2, 0xf4, 0x39, 0xdd, 0xee, 0xdd, 0x95, 0x3e, 0x5a, 0xb1,
+ 0xeb, 0x64, 0x79, 0x51, 0x3e, 0x8c, 0x7a, 0x8f, 0x21, 0x99, 0x0d, 0xf6,
+ 0x46, 0xb0, 0xf5, 0x7a, 0x4d, 0xf3, 0x2a, 0x20, 0x21, 0xf9, 0x69, 0x3b,
+ 0x87, 0x9b, 0x86, 0x2f, 0x64, 0xfa, 0x8d, 0x16, 0x7f, 0x2e, 0xbe, 0x19,
+ 0x80, 0x68, 0x88, 0xa7, 0xea, 0xf8, 0x66, 0x01, 0xa2, 0x2b, 0x9f, 0xee,
+ 0xba, 0xeb, 0xe1, 0x98, 0x06, 0x8a, 0xe2, 0x16, 0x7f, 0x98, 0x6d, 0x3d,
+ 0x5b, 0xcd, 0x1d, 0x3f, 0xa9, 0x3f, 0xdf, 0x7e, 0xdc, 0xe9, 0x3b, 0xe2,
+ 0x7a, 0xb7, 0x20, 0x9f, 0xff, 0xb5, 0x74, 0xde, 0x23, 0xd0, 0x75, 0xee,
+ 0xff, 0x47, 0x4f, 0xbe, 0x19, 0x80, 0x68, 0xa7, 0xa7, 0xea, 0xbf, 0x41,
+ 0xc7, 0x9d, 0x1d, 0x62, 0x38, 0xd8, 0xb2, 0x96, 0x44, 0xc6, 0x7f, 0xf6,
+ 0x3d, 0x7c, 0x8e, 0x71, 0x7b, 0xb7, 0x67, 0x42, 0xd1, 0x15, 0xc9, 0xfc,
+ 0xe5, 0xf3, 0x47, 0x4f, 0x99, 0xfd, 0xfa, 0xf3, 0xa7, 0x83, 0x30, 0x0d,
+ 0x15, 0x9c, 0x38, 0x7a, 0x9f, 0x29, 0x9f, 0xac, 0x53, 0x0b, 0xee, 0x74,
+ 0xe6, 0xb1, 0x0e, 0x9f, 0x6b, 0xbf, 0x02, 0xf3, 0xa7, 0x7b, 0x97, 0x3a,
+ 0x7d, 0x4e, 0x59, 0xef, 0x67, 0x49, 0x74, 0x8d, 0xcf, 0x91, 0xec, 0xb7,
+ 0x06, 0xc4, 0xab, 0xc0, 0xe4, 0xff, 0xcb, 0xc7, 0xae, 0xbe, 0x19, 0x80,
+ 0x68, 0x91, 0x67, 0xea, 0xf8, 0x66, 0x01, 0xa2, 0xc9, 0x9f, 0xfd, 0xab,
+ 0xf8, 0xba, 0xea, 0xc4, 0x17, 0xdc, 0xe8, 0x5a, 0x20, 0xa8, 0xda, 0x7f,
+ 0x2e, 0xbe, 0x19, 0x80, 0x68, 0xb6, 0x27, 0x55, 0xe8, 0xe9, 0xe0, 0xcc,
+ 0x03, 0x45, 0xb7, 0x3d, 0x7b, 0x33, 0xe7, 0x47, 0xcf, 0x37, 0x45, 0x72,
+ 0x5b, 0xd1, 0x13, 0x4c, 0xf3, 0xac, 0xda, 0x1d, 0x3f, 0xee, 0xb3, 0xac,
+ 0x77, 0x7a, 0xdd, 0x0b, 0x76, 0x74, 0xfc, 0xc2, 0xfe, 0x7d, 0x51, 0xd3,
+ 0xef, 0x86, 0x60, 0x1a, 0x2f, 0x09, 0xed, 0x75, 0x56, 0xce, 0x9f, 0xf9,
+ 0xbc, 0x2a, 0xd7, 0xea, 0x87, 0x57, 0x3a, 0x7d, 0x43, 0xdb, 0xb3, 0x1d,
+ 0x3e, 0x6f, 0x1e, 0xe5, 0xce, 0x9d, 0xa6, 0xec, 0xe9, 0x2f, 0xac, 0x4e,
+ 0x87, 0xad, 0x43, 0x96, 0x27, 0x51, 0x75, 0xa6, 0x3b, 0x24, 0xed, 0x18,
+ 0x4a, 0x74, 0x53, 0x39, 0x2a, 0xd3, 0xa7, 0xdf, 0x0c, 0xc0, 0x34, 0x5e,
+ 0x93, 0xfe, 0x1c, 0xd3, 0xdb, 0xce, 0x92, 0xc3, 0xa7, 0xd4, 0xad, 0xe7,
+ 0x27, 0x49, 0x7c, 0xa2, 0xca, 0x86, 0xfc, 0x18, 0xbb, 0x1f, 0xc3, 0x32,
+ 0x5c, 0xec, 0x85, 0xc5, 0x47, 0xc6, 0x04, 0x89, 0x1a, 0x67, 0xd7, 0x15,
+ 0x0c, 0xfe, 0xc8, 0x86, 0x18, 0xbe, 0xc7, 0x93, 0xc4, 0x68, 0xb3, 0x7b,
+ 0xb3, 0xa7, 0xab, 0x79, 0xa3, 0xa7, 0xf5, 0x27, 0xfb, 0xef, 0xdb, 0x9d,
+ 0x27, 0x7c, 0x4f, 0x56, 0xe4, 0x13, 0xe4, 0xd3, 0x5b, 0x61, 0xd3, 0xef,
+ 0x86, 0x60, 0x1a, 0x22, 0x39, 0xff, 0xed, 0xfb, 0x7b, 0xd2, 0x86, 0x9d,
+ 0x74, 0x67, 0x74, 0x74, 0xff, 0x9e, 0xd6, 0x7e, 0xb5, 0xa4, 0xd1, 0xd3,
+ 0xfd, 0x5f, 0xab, 0xd6, 0x0d, 0x87, 0x4f, 0xff, 0xf3, 0x6f, 0x13, 0x4d,
+ 0xb1, 0xad, 0x6d, 0x37, 0x49, 0xc1, 0xd3, 0x58, 0xa2, 0xa6, 0xe3, 0x82,
+ 0xa7, 0xfc, 0xb0, 0xda, 0x39, 0xb6, 0xb1, 0x7d, 0x9a, 0xfe, 0x05, 0xe7,
+ 0x9d, 0x36, 0x98, 0xe8, 0x79, 0xfd, 0x22, 0xc4, 0xfd, 0xd7, 0x1a, 0xde,
+ 0x68, 0xe9, 0xf9, 0xbc, 0xd0, 0xa7, 0x93, 0xa7, 0xea, 0xd3, 0xb6, 0xab,
+ 0x67, 0x45, 0x22, 0x30, 0x4b, 0xee, 0x5d, 0x3f, 0xff, 0x02, 0xff, 0x82,
+ 0x9a, 0x5f, 0xdb, 0x43, 0x9d, 0x9d, 0x0e, 0xf2, 0xbf, 0xce, 0xb1, 0xb1,
+ 0x8b, 0x28, 0xa0, 0x0c, 0x6d, 0x59, 0x43, 0xef, 0x9b, 0x64, 0x61, 0x7a,
+ 0x85, 0x6b, 0xa2, 0xe9, 0xf7, 0xc3, 0x30, 0x0d, 0x11, 0x74, 0xfb, 0x5d,
+ 0xf8, 0x17, 0x95, 0x25, 0xd1, 0xed, 0xe1, 0x8c, 0x2d, 0x32, 0xe7, 0xc6,
+ 0x11, 0x3f, 0xf2, 0xb1, 0xeb, 0xaf, 0x86, 0x60, 0x1a, 0x26, 0x69, 0xfb,
+ 0xad, 0x1d, 0xdb, 0xbf, 0x76, 0xd1, 0xd3, 0xad, 0x6b, 0x9d, 0x38, 0x11,
+ 0x47, 0x4d, 0xd5, 0xd6, 0xce, 0x9f, 0xb5, 0x56, 0x57, 0x6e, 0x1d, 0x1d,
+ 0x6c, 0xf3, 0x9c, 0x1f, 0x9f, 0x06, 0x6d, 0x1c, 0x3a, 0x7f, 0xfd, 0xdd,
+ 0xaf, 0xdf, 0xad, 0xf5, 0xed, 0x03, 0x3e, 0x74, 0xff, 0xce, 0xc9, 0xa4,
+ 0x04, 0xe7, 0x54, 0x07, 0x4f, 0xff, 0xf7, 0xb8, 0x20, 0x35, 0xce, 0xfd,
+ 0xe9, 0xb6, 0x7f, 0xda, 0xc3, 0xa1, 0x93, 0x04, 0xa5, 0x7d, 0xa2, 0x4f,
+ 0xff, 0xb9, 0x41, 0xb2, 0xae, 0x99, 0xb5, 0xf1, 0xc7, 0x05, 0x4f, 0xd6,
+ 0xbe, 0xfd, 0xfa, 0xe1, 0xd3, 0xc1, 0x98, 0x06, 0x8b, 0x3e, 0x7f, 0xc9,
+ 0xb6, 0x7a, 0x69, 0xb5, 0x73, 0xa7, 0xff, 0x93, 0xfb, 0xce, 0x94, 0xe8,
+ 0x6a, 0xf4, 0x27, 0x4e, 0xe3, 0x8e, 0x0a, 0x9f, 0xf6, 0x3e, 0xe3, 0x41,
+ 0xcd, 0x7c, 0xa5, 0x97, 0xf3, 0xfc, 0xdb, 0x4e, 0x47, 0x31, 0xc3, 0xa7,
+ 0xf9, 0x07, 0x9f, 0x1c, 0xfb, 0xab, 0x9d, 0x00, 0xa8, 0x79, 0xc5, 0x8f,
+ 0x99, 0x28, 0xaf, 0x67, 0x9d, 0xb7, 0x69, 0x2d, 0xd1, 0xbc, 0xff, 0x7f,
+ 0x38, 0xda, 0x37, 0xd8, 0xe9, 0xff, 0xff, 0xfa, 0xab, 0xbb, 0xd5, 0x0f,
+ 0x9f, 0x1f, 0x16, 0xad, 0xae, 0xe3, 0x56, 0x2a, 0x94, 0x74, 0xeb, 0xb5,
+ 0x87, 0x4e, 0xea, 0xad, 0x9d, 0x0f, 0x46, 0x1d, 0xe1, 0x13, 0xa1, 0xc9,
+ 0xdb, 0xf7, 0x83, 0xa7, 0x77, 0xe8, 0x1d, 0x3b, 0x55, 0xe0, 0xe8, 0xe4,
+ 0xf6, 0x2d, 0x1e, 0x41, 0xd9, 0xfb, 0xe8, 0xea, 0x86, 0xe7, 0x4f, 0xb6,
+ 0x2d, 0x5f, 0x32, 0x7f, 0xc9, 0xf7, 0xd7, 0xec, 0xf7, 0x39, 0x34, 0x41,
+ 0xab, 0x34, 0xb3, 0xec, 0x04, 0x53, 0x1d, 0x3f, 0x3f, 0x63, 0x96, 0xe8,
+ 0xe9, 0x50, 0x1e, 0x88, 0x92, 0x4f, 0xfd, 0x43, 0x6e, 0xab, 0xe9, 0x66,
+ 0x28, 0xe9, 0x90, 0x4e, 0x9f, 0xb3, 0x8d, 0x56, 0xf4, 0xc7, 0xaf, 0xe5,
+ 0x0e, 0x19, 0x3c, 0x27, 0xa9, 0x54, 0x2b, 0x85, 0xf2, 0x7e, 0xfd, 0x73,
+ 0x7d, 0xb1, 0xd3, 0xff, 0xfb, 0xd1, 0xcf, 0x3d, 0x3c, 0x0e, 0x6a, 0xe9,
+ 0x6e, 0xd3, 0x83, 0xa7, 0xfc, 0xaa, 0xd5, 0xfc, 0x5f, 0x1f, 0x47, 0x4f,
+ 0xd7, 0xbb, 0x7f, 0x4c, 0x72, 0xcd, 0xfc, 0xf6, 0xe9, 0x1d, 0x1d, 0x3f,
+ 0x5d, 0x3f, 0x5e, 0xfc, 0xe8, 0x44, 0x45, 0xec, 0xf3, 0x44, 0x53, 0x29,
+ 0xdf, 0x34, 0x5f, 0x93, 0xff, 0x3f, 0x5e, 0xbd, 0xea, 0xd6, 0x99, 0x47,
+ 0x4f, 0xfc, 0x94, 0x35, 0x57, 0xe8, 0xfb, 0xa8, 0xe8, 0xb5, 0x11, 0x37,
+ 0x46, 0x99, 0x1c, 0x3a, 0x76, 0x92, 0xc3, 0xa7, 0x0b, 0x01, 0xd1, 0xd0,
+ 0xf2, 0xd4, 0x2c, 0x23, 0x90, 0xc9, 0xbf, 0xf2, 0x5f, 0x50, 0xb1, 0xc6,
+ 0xf9, 0xff, 0xff, 0x9d, 0x9b, 0x68, 0xa5, 0xb8, 0xfc, 0xff, 0x8d, 0xa5,
+ 0xb7, 0x04, 0xb0, 0xe9, 0xfb, 0x3e, 0xdb, 0xf1, 0xc9, 0xd3, 0xdc, 0x65,
+ 0x5c, 0xe9, 0xfe, 0x7a, 0xb1, 0xfa, 0xbb, 0x79, 0x3a, 0x18, 0xf6, 0xf0,
+ 0x86, 0x7a, 0xae, 0x82, 0x74, 0x62, 0x32, 0x46, 0x11, 0x5e, 0x90, 0x4f,
+ 0x78, 0xf7, 0x2e, 0x74, 0xfc, 0xed, 0xaa, 0xc1, 0x03, 0xa7, 0xfa, 0xfd,
+ 0xa5, 0xb6, 0xbe, 0xb4, 0x74, 0x6c, 0xfa, 0x34, 0x5b, 0x0c, 0x8a, 0xea,
+ 0x84, 0x64, 0xce, 0x7a, 0x74, 0x94, 0x74, 0x5a, 0x6a, 0x1d, 0xc1, 0x89,
+ 0xfd, 0x99, 0x6b, 0xc5, 0xb9, 0x3a, 0x7f, 0xf0, 0xa3, 0x5c, 0x71, 0xfd,
+ 0x2f, 0x5f, 0x3a, 0x7f, 0xff, 0xdb, 0x4b, 0x75, 0x56, 0xeb, 0xff, 0x6d,
+ 0x77, 0xe0, 0x5f, 0xba, 0x3a, 0x7b, 0x9e, 0x70, 0x4e, 0x9f, 0xf6, 0x6c,
+ 0x13, 0x3a, 0x5f, 0x36, 0x74, 0x32, 0x6e, 0x1c, 0x93, 0xd1, 0x90, 0x24,
+ 0x23, 0x86, 0xc8, 0xa7, 0xfe, 0xa1, 0xb7, 0x55, 0xf4, 0xb3, 0x14, 0x74,
+ 0xfa, 0xb4, 0xf5, 0x6c, 0xe9, 0xf5, 0xb7, 0x16, 0x51, 0xd0, 0xc8, 0x91,
+ 0xba, 0x1f, 0xa4, 0xf3, 0x77, 0xb3, 0xa7, 0xeb, 0x1c, 0x7f, 0x59, 0xfb,
+ 0x0e, 0x9f, 0xde, 0x77, 0x5a, 0xda, 0x68, 0xe9, 0x93, 0xe7, 0x47, 0x5b,
+ 0x3f, 0xf4, 0x36, 0xd9, 0xa4, 0xff, 0xdc, 0xb7, 0x3f, 0x6d, 0x20, 0x27,
+ 0x27, 0x4f, 0xdb, 0xf6, 0xc7, 0x36, 0x87, 0x47, 0x27, 0xe9, 0xb4, 0x49,
+ 0x2f, 0xad, 0xb6, 0x41, 0x0e, 0xf1, 0xfb, 0xbb, 0x1c, 0x66, 0x8b, 0x0a,
+ 0x79, 0x8c, 0xaa, 0xa5, 0x26, 0xf9, 0x76, 0xb6, 0x1f, 0x49, 0x08, 0xd7,
+ 0x23, 0xf2, 0xfa, 0x02, 0x8b, 0x77, 0x2a, 0xc3, 0x10, 0x7b, 0x8d, 0x04,
+ 0x61, 0xc5, 0x78, 0xef, 0xb5, 0x0e, 0x6e, 0x0c, 0x3a, 0xa1, 0x2d, 0xe2,
+ 0x15, 0x10, 0xb6, 0xcf, 0x93, 0x75, 0x92, 0xac, 0xff, 0xe5, 0xab, 0x1e,
+ 0xba, 0xf8, 0x66, 0x01, 0xa2, 0x6c, 0x9f, 0xcb, 0xaf, 0x86, 0x60, 0x1a,
+ 0x2a, 0xd9, 0xfc, 0xf7, 0xfb, 0xa1, 0x67, 0x9d, 0x3d, 0x5b, 0xcd, 0x1d,
+ 0x27, 0x7e, 0x8f, 0x4c, 0x4c, 0xe7, 0xdf, 0x0c, 0xc0, 0x34, 0x56, 0x93,
+ 0xff, 0xc0, 0xdf, 0xae, 0xf1, 0x58, 0xf6, 0x40, 0x3a, 0x7f, 0xf9, 0xf7,
+ 0xa1, 0x65, 0x65, 0x6b, 0x4c, 0xa3, 0xa6, 0xd6, 0x99, 0x12, 0xf8, 0x97,
+ 0x3f, 0x99, 0xd7, 0x8d, 0x0b, 0x76, 0x74, 0xfd, 0x65, 0x6d, 0x29, 0x47,
+ 0x4f, 0xf5, 0x3b, 0x0b, 0x71, 0x6b, 0xee, 0x74, 0xfe, 0x7d, 0x6b, 0x07,
+ 0xbf, 0x4e, 0x92, 0xfa, 0xc4, 0xfc, 0x68, 0xad, 0x21, 0x91, 0xb2, 0xdc,
+ 0x36, 0x12, 0xcd, 0x1e, 0x4f, 0xe5, 0xd7, 0xc3, 0x30, 0x0d, 0x16, 0x04,
+ 0xfb, 0xe1, 0x98, 0x06, 0x89, 0xd6, 0x7f, 0xff, 0x6d, 0xac, 0xe6, 0x94,
+ 0xbb, 0xde, 0xb6, 0x97, 0xf6, 0xc3, 0xa7, 0xcb, 0x56, 0x3d, 0x74, 0x89,
+ 0x57, 0x0c, 0x67, 0xf3, 0xee, 0xbf, 0x3e, 0x59, 0x47, 0x4f, 0xbe, 0x19,
+ 0x80, 0x68, 0xb6, 0x67, 0xfd, 0xdb, 0x5d, 0x7b, 0x40, 0xcf, 0x9d, 0x25,
+ 0xd1, 0xf7, 0x61, 0x8c, 0xf0, 0x66, 0x01, 0xa2, 0xe6, 0x92, 0x8e, 0x8f,
+ 0x9b, 0xbe, 0x0a, 0xe6, 0x71, 0x47, 0x49, 0x74, 0x6e, 0x78, 0x22, 0x9f,
+ 0xcb, 0xaf, 0x86, 0x60, 0x1a, 0x2e, 0xf9, 0xe5, 0xf9, 0xe7, 0xb3, 0xa1,
+ 0x9b, 0xa5, 0xda, 0xad, 0x03, 0x80, 0xca, 0xd5, 0x34, 0x95, 0x01, 0xf7,
+ 0x15, 0x43, 0x47, 0x10, 0x3b, 0x85, 0x2d, 0xe1, 0x35, 0xa2, 0x7f, 0x07,
+ 0x93, 0xeb, 0xdd, 0x58, 0xf3, 0xa7, 0xfe, 0xb4, 0x3d, 0xcb, 0x75, 0x54,
+ 0x3e, 0x4e, 0x9c, 0x38, 0xb6, 0x3e, 0xdd, 0x13, 0xcf, 0xe1, 0xb2, 0x9d,
+ 0xb4, 0xde, 0x4e, 0x9f, 0x7c, 0x33, 0x00, 0xd1, 0x2b, 0xcf, 0xf8, 0x73,
+ 0x8e, 0x76, 0xd6, 0x57, 0x07, 0x4f, 0xff, 0xcf, 0xa4, 0xee, 0x94, 0x9a,
+ 0xbb, 0x2b, 0x2d, 0xd1, 0xd3, 0xde, 0xe7, 0xde, 0x74, 0xff, 0xfe, 0x4d,
+ 0x62, 0xb0, 0x7b, 0xdf, 0x18, 0x36, 0x02, 0x58, 0x74, 0x72, 0x88, 0x2c,
+ 0x22, 0x8e, 0x53, 0x3f, 0xa4, 0x0d, 0xc3, 0x72, 0x76, 0x3d, 0x6c, 0x9e,
+ 0xed, 0x1b, 0xde, 0x37, 0x09, 0xda, 0x6e, 0x4a, 0x9f, 0xfd, 0xbc, 0x4d,
+ 0x33, 0xd3, 0xf6, 0x7b, 0xd9, 0x53, 0xfb, 0x01, 0x7c, 0xfd, 0xdc, 0x5b,
+ 0x1f, 0x3d, 0xc7, 0x24, 0xb0, 0x56, 0x14, 0xa9, 0x41, 0xce, 0xa1, 0x5b,
+ 0x3f, 0xf9, 0x6a, 0xc7, 0xae, 0xbe, 0x19, 0x80, 0x68, 0x98, 0x67, 0xff,
+ 0x0b, 0x3a, 0x16, 0xb5, 0x7d, 0x6d, 0xdd, 0xdd, 0xe7, 0x4f, 0xfe, 0xfe,
+ 0x76, 0xbf, 0x3a, 0x7f, 0x0d, 0x77, 0x9d, 0x35, 0x2f, 0x94, 0x52, 0xf8,
+ 0x57, 0x9f, 0xf9, 0xdf, 0xab, 0x5f, 0xee, 0x68, 0x59, 0xe7, 0x4f, 0xe6,
+ 0xcb, 0x35, 0xe7, 0x3e, 0x74, 0xfb, 0x3e, 0xfc, 0x51, 0xd0, 0x27, 0xb5,
+ 0xe9, 0xa4, 0xfc, 0xa6, 0xa1, 0xd7, 0x51, 0xd2, 0xb9, 0xd3, 0xe6, 0xa1,
+ 0xd7, 0x51, 0xd3, 0xf6, 0xd3, 0x57, 0xcb, 0x7a, 0x1f, 0x33, 0x85, 0xca,
+ 0x10, 0x9f, 0xff, 0xf0, 0xd7, 0x0e, 0xda, 0xad, 0xf4, 0x1a, 0xb1, 0x28,
+ 0x6d, 0x7d, 0xce, 0x9f, 0xfe, 0x6d, 0x0e, 0x77, 0xba, 0x4e, 0x7d, 0xd5,
+ 0xce, 0x9f, 0x9d, 0x78, 0xd0, 0xb7, 0x67, 0x4f, 0xfe, 0x6d, 0x76, 0xcf,
+ 0xab, 0x75, 0x67, 0xbc, 0x1d, 0x0c, 0x7f, 0xe8, 0x63, 0x3f, 0x5d, 0x3c,
+ 0xab, 0x34, 0x74, 0xff, 0xff, 0xbf, 0x4e, 0x98, 0x75, 0xd3, 0xc0, 0xb6,
+ 0xf1, 0x34, 0xda, 0xb9, 0xd2, 0xab, 0x51, 0x39, 0xf2, 0xe9, 0xff, 0xf6,
+ 0xc6, 0xb5, 0xb4, 0xab, 0x75, 0x4e, 0x9a, 0xe7, 0x4e, 0x6e, 0xfc, 0x1d,
+ 0x14, 0x7e, 0x62, 0xab, 0x3d, 0x9e, 0x39, 0xa3, 0xa4, 0xbe, 0xb1, 0x71,
+ 0x6b, 0x98, 0x51, 0x84, 0x22, 0x1c, 0x55, 0xfb, 0x86, 0xe1, 0x9e, 0x30,
+ 0xbc, 0xd4, 0x27, 0x3d, 0x20, 0x9f, 0x7c, 0x33, 0x00, 0xd1, 0x57, 0x4f,
+ 0xf3, 0xd7, 0x5f, 0x0c, 0xc0, 0x34, 0x47, 0x92, 0x5d, 0x1f, 0x9e, 0x18,
+ 0xcf, 0xe5, 0xd7, 0xc3, 0x30, 0x0d, 0x16, 0x0c, 0xfe, 0x5d, 0x7c, 0x33,
+ 0x00, 0xd1, 0x65, 0x4f, 0xe5, 0xd7, 0xc3, 0x30, 0x0d, 0x16, 0x9c, 0xfe,
+ 0xab, 0xf4, 0xff, 0xfd, 0xd9, 0xd3, 0xc1, 0x98, 0x06, 0x8b, 0x72, 0x7f,
+ 0xe6, 0xaf, 0xd0, 0xf4, 0xdd, 0x5b, 0xc1, 0xd1, 0xf3, 0xf0, 0xb9, 0x5c,
+ 0xff, 0x30, 0xfa, 0xa6, 0xbe, 0x90, 0xe9, 0xfd, 0x99, 0x67, 0x2d, 0x5f,
+ 0x3a, 0x7f, 0xd8, 0xf5, 0xd7, 0xc3, 0x30, 0x0d, 0x14, 0x3c, 0xff, 0xca,
+ 0xce, 0x5b, 0x9d, 0xa0, 0xa2, 0x8e, 0x9f, 0xfb, 0xd7, 0xef, 0x3f, 0x6e,
+ 0x99, 0x2c, 0x3a, 0x7f, 0xde, 0xff, 0xbf, 0xe0, 0xea, 0xbb, 0x3a, 0x7e,
+ 0xbe, 0x5b, 0x7d, 0x21, 0xd3, 0xf0, 0xf5, 0x95, 0xf6, 0xb9, 0xd3, 0xff,
+ 0xf5, 0x73, 0xb6, 0xf0, 0xbd, 0x0e, 0x77, 0x7b, 0xb7, 0x65, 0x49, 0x6f,
+ 0x55, 0xf9, 0x50, 0xa6, 0x42, 0x27, 0x0d, 0xd4, 0x65, 0x88, 0xfd, 0xa1,
+ 0xdd, 0x1b, 0x48, 0x1e, 0x96, 0xf5, 0x18, 0x4f, 0xe5, 0xd7, 0xc3, 0x30,
+ 0x0d, 0x17, 0x9c, 0x33, 0x2e, 0x6d, 0xe8, 0xbc, 0xc3, 0xe2, 0xa7, 0x22,
+ 0xed, 0x8c, 0x67, 0xe4, 0xca, 0x3c, 0xd9, 0xe0, 0xcb, 0x38, 0x75, 0x0a,
+ 0x89, 0xfc, 0xba, 0xf8, 0x66, 0x01, 0xa2, 0x96, 0x9f, 0xcb, 0xaf, 0x86,
+ 0x60, 0x1a, 0x2c, 0x29, 0xfc, 0xba, 0xf8, 0x66, 0x01, 0xa2, 0xcb, 0x9e,
+ 0x5f, 0x9e, 0xb4, 0x77, 0x47, 0x4e, 0x5f, 0x85, 0x1d, 0x3c, 0x0b, 0x6b,
+ 0x81, 0xe7, 0xfa, 0x63, 0x3f, 0xf9, 0x6a, 0xc7, 0xae, 0xbe, 0x19, 0x80,
+ 0x68, 0xa3, 0x27, 0xf2, 0xd9, 0xd3, 0x7d, 0xbb, 0x3a, 0x1e, 0x9e, 0x17,
+ 0xcf, 0x14, 0x79, 0x90, 0x8b, 0xb9, 0xc6, 0x94, 0xe7, 0xfe, 0x5e, 0x3d,
+ 0x75, 0xf0, 0xcc, 0x03, 0x44, 0x73, 0x3f, 0xf9, 0x6a, 0xc7, 0xae, 0xbe,
+ 0x19, 0x80, 0x68, 0x9c, 0xa7, 0xf2, 0xeb, 0xe1, 0x98, 0x06, 0x8b, 0x32,
+ 0x7f, 0xbb, 0xfb, 0x6b, 0x79, 0x6b, 0xce, 0x9f, 0xd5, 0x7f, 0xfe, 0xad,
+ 0xb9, 0xd2, 0x5b, 0x1f, 0x6b, 0xce, 0xa7, 0xf2, 0xeb, 0xe1, 0x98, 0x06,
+ 0x8b, 0x76, 0x7f, 0xf2, 0xd5, 0x8f, 0x5d, 0x7c, 0x33, 0x00, 0xd1, 0x48,
+ 0x4f, 0xfc, 0xbc, 0x7a, 0xeb, 0xe1, 0x98, 0x06, 0x89, 0x4a, 0x2c, 0x54,
+ 0x98, 0xe2, 0x6a, 0x94, 0xfb, 0x85, 0x48, 0x93, 0xe8, 0xf1, 0xd9, 0x4e,
+ 0x7f, 0xd8, 0xf5, 0xd7, 0xc3, 0x30, 0x0d, 0x13, 0xb4, 0xff, 0xf9, 0x39,
+ 0xf5, 0x4c, 0xed, 0x9c, 0x8b, 0x0d, 0x01, 0xd2, 0x5a, 0x91, 0x3b, 0x88,
+ 0xf3, 0xff, 0x62, 0xb7, 0x41, 0x9b, 0x6f, 0x0f, 0x3a, 0x7f, 0xe1, 0xad,
+ 0xe5, 0x95, 0x71, 0xcb, 0x4e, 0x9b, 0xa9, 0x7c, 0xa2, 0x16, 0xe8, 0x70,
+ 0xa4, 0x70, 0x75, 0x42, 0xb6, 0x7d, 0xf0, 0xcc, 0x03, 0x44, 0x59, 0x3f,
+ 0xec, 0x7a, 0xeb, 0xe1, 0x98, 0x06, 0x89, 0x76, 0x7f, 0xfe, 0xae, 0x76,
+ 0xde, 0x17, 0xa1, 0xce, 0xef, 0x76, 0xec, 0xa9, 0x2e, 0x91, 0xac, 0xa3,
+ 0x1e, 0xa4, 0x79, 0xff, 0xcb, 0x56, 0x3d, 0x75, 0xf0, 0xcc, 0x03, 0x44,
+ 0xc5, 0x3e, 0xf8, 0x66, 0x01, 0xa2, 0xa9, 0x95, 0x1d, 0x14, 0x78, 0x1e,
+ 0x4c, 0x67, 0xff, 0xff, 0x7f, 0x37, 0x6b, 0xeb, 0x4b, 0xde, 0x5f, 0xe9,
+ 0xc6, 0xb6, 0x9f, 0x79, 0xd0, 0xb4, 0x4e, 0x61, 0x1c, 0xff, 0xe5, 0xab,
+ 0x1e, 0xba, 0xf8, 0x66, 0x01, 0xa2, 0x74, 0x9f, 0xc9, 0x9f, 0x67, 0xe3,
+ 0xa3, 0xa7, 0xce, 0x33, 0x8d, 0x73, 0xa7, 0xee, 0x29, 0x1d, 0x50, 0x9d,
+ 0x08, 0x7a, 0xb7, 0x28, 0x9c, 0x9b, 0x63, 0x96, 0x68, 0x67, 0xfe, 0xf6,
+ 0xfa, 0x6b, 0x57, 0xeb, 0x88, 0xa3, 0xa1, 0x47, 0xe5, 0xb2, 0xa9, 0xff,
+ 0x63, 0xd7, 0x5f, 0x0c, 0xc0, 0x34, 0x4e, 0xf3, 0xed, 0x7b, 0x8a, 0x42,
+ 0xa4, 0xbe, 0x53, 0xaa, 0xa8, 0xc6, 0x94, 0x45, 0x88, 0xf3, 0xff, 0x96,
+ 0xac, 0x7a, 0xeb, 0xe1, 0x98, 0x06, 0x8a, 0x16, 0x7f, 0xf2, 0xd5, 0x8f,
+ 0x5d, 0x7c, 0x33, 0x00, 0xd1, 0x49, 0x4f, 0xff, 0xea, 0xba, 0xfc, 0x53,
+ 0x9b, 0xc5, 0x6b, 0x6d, 0xaf, 0x54, 0x74, 0x58, 0xb9, 0xb2, 0xf3, 0x80,
+ 0x8c, 0xbf, 0xe4, 0x4a, 0x8f, 0xf7, 0xb4, 0x9f, 0x54, 0xfa, 0x94, 0xe7,
+ 0xf2, 0xeb, 0xe1, 0x98, 0x06, 0x88, 0x92, 0x7f, 0xf2, 0xd5, 0x8f, 0x5d,
+ 0x7c, 0x33, 0x00, 0xd1, 0x2f, 0x4f, 0xbf, 0xda, 0x92, 0xe7, 0x4e, 0xed,
+ 0xb4, 0x74, 0xff, 0xd8, 0xe5, 0xd9, 0xd6, 0x6d, 0xad, 0x70, 0xe8, 0x44,
+ 0x45, 0xb8, 0x51, 0xf1, 0xc9, 0xfe, 0x4c, 0x1f, 0x74, 0xe3, 0x79, 0x3a,
+ 0x7d, 0xf0, 0xcc, 0x03, 0x45, 0x2f, 0x3e, 0x1d, 0x59, 0x5c, 0x1d, 0x3f,
+ 0xdd, 0xdf, 0xed, 0x6b, 0xd1, 0x47, 0x4f, 0xf6, 0x59, 0xd2, 0xcf, 0x5c,
+ 0x6e, 0xb9, 0xd3, 0x53, 0xd8, 0xff, 0x3d, 0x3a, 0x99, 0xf4, 0x74, 0xe6,
+ 0xee, 0xe7, 0x47, 0x26, 0xc7, 0x81, 0x59, 0xff, 0x91, 0x59, 0xcf, 0x87,
+ 0x1e, 0xc3, 0x69, 0xd3, 0xd7, 0x4e, 0x34, 0x74, 0x6c, 0xfa, 0x74, 0x8f,
+ 0x3f, 0xd9, 0xbc, 0x71, 0x3e, 0xd6, 0x1d, 0x3e, 0x76, 0x45, 0x35, 0xce,
+ 0x9f, 0x63, 0xaa, 0xfd, 0xce, 0x93, 0x72, 0x7a, 0x2a, 0x29, 0x92, 0xd9,
+ 0x57, 0xe7, 0x26, 0x14, 0x75, 0x69, 0x8b, 0x90, 0xa4, 0xda, 0xf6, 0x42,
+ 0x32, 0xe4, 0x5a, 0x84, 0x4c, 0xfe, 0x5d, 0x7c, 0x33, 0x00, 0xd1, 0x4e,
+ 0x4f, 0xf9, 0x3f, 0x97, 0xdd, 0x50, 0x81, 0xd3, 0xfe, 0xad, 0xb7, 0xe9,
+ 0x7c, 0x71, 0xc1, 0x53, 0x27, 0x07, 0x4d, 0x62, 0xf9, 0x44, 0x87, 0x51,
+ 0xd3, 0xb2, 0x04, 0xfb, 0xe1, 0x98, 0x06, 0x8a, 0xf2, 0x7f, 0xfe, 0xae,
+ 0x76, 0xde, 0x17, 0xa1, 0xce, 0xef, 0x76, 0xec, 0xa9, 0x2e, 0x91, 0x1f,
+ 0xd4, 0x63, 0x3f, 0xf2, 0xf1, 0xeb, 0xaf, 0x86, 0x60, 0x1a, 0x24, 0x79,
+ 0xc9, 0xdb, 0x1d, 0x38, 0x29, 0x45, 0x2c, 0xbb, 0x9f, 0x7c, 0x33, 0x00,
+ 0xd1, 0x24, 0x4f, 0x2f, 0x1e, 0xb6, 0x3d, 0xaa, 0x29, 0x9f, 0xf9, 0x78,
+ 0xf5, 0xd7, 0xc3, 0x30, 0x0d, 0x12, 0x54, 0xfb, 0xe1, 0x98, 0x06, 0x8b,
+ 0xc6, 0x7d, 0x7b, 0xea, 0x80, 0xe9, 0xfe, 0x7a, 0xeb, 0xe1, 0x98, 0x06,
+ 0x89, 0x36, 0x4b, 0xa4, 0x4c, 0xfc, 0xc7, 0x09, 0xa1, 0x99, 0x11, 0x16,
+ 0x1e, 0x3e, 0x5e, 0xd7, 0x30, 0x95, 0x48, 0x66, 0x39, 0x0d, 0x35, 0x15,
+ 0xee, 0x18, 0x5a, 0x37, 0xf6, 0x1c, 0xd0, 0xd1, 0xe2, 0x46, 0xd9, 0x1d,
+ 0x93, 0xe5, 0x3d, 0x73, 0x28, 0xc2, 0xaf, 0x1d, 0xc3, 0xcc, 0xa5, 0xe0,
+ 0xb4, 0x9a, 0xf6, 0xd2, 0x04, 0x92, 0x79, 0x4b, 0xaf, 0x1d, 0xe3, 0x95,
+ 0x9d, 0x8f, 0xe9, 0x78, 0x4a, 0xc5, 0x35, 0x86, 0xe7, 0x8e, 0x32, 0xb4,
+ 0x76, 0xee, 0x5f, 0x73, 0xb9, 0x0b, 0x41, 0xa4, 0x84, 0x5e, 0x94, 0x5f,
+ 0xab, 0x40, 0x93, 0xed, 0x3f, 0x6d, 0xd4, 0xa7, 0x1e, 0x25, 0x54, 0x75,
+ 0x47, 0xdb, 0xe2, 0x77, 0x69, 0xda, 0x92, 0x1b, 0x00,
};
-static const unsigned kPreloadedHSTSBits = 117726;
+static const unsigned kPreloadedHSTSBits = 117858;
-static const unsigned kHSTSRootPosition = 117138;
+static const unsigned kHSTSRootPosition = 117270;
#endif // NET_HTTP_TRANSPORT_SECURITY_STATE_STATIC_H_
diff --git a/net/http/transport_security_state_static.json b/net/http/transport_security_state_static.json
index 3145671..d5dbad1 100644
--- a/net/http/transport_security_state_static.json
+++ b/net/http/transport_security_state_static.json
@@ -1774,7 +1774,8 @@
{ "name": "uonstaffhub.com", "include_subdomains": true, "mode": "force-https" },
{ "name": "whd-guide.de", "include_subdomains": true, "mode": "force-https" },
{ "name": "whocalld.com", "include_subdomains": true, "mode": "force-https" },
- { "name": "wootton95.com", "include_subdomains": true, "mode": "force-https" }
+ { "name": "wootton95.com", "include_subdomains": true, "mode": "force-https" },
+ { "name": "fassadenverkleidung24.de", "include_subdomains": true, "mode": "force-https" }
],
// |ReportUMAOnPinFailure| uses these to report which domain was associated
diff --git a/net/quic/quic_client_session.cc b/net/quic/quic_client_session.cc
index 8a41c6a..54c52ef 100644
--- a/net/quic/quic_client_session.cc
+++ b/net/quic/quic_client_session.cc
@@ -104,6 +104,8 @@
dict->SetString("host", server_id->host());
dict->SetInteger("port", server_id->port());
dict->SetBoolean("is_https", server_id->is_https());
+ dict->SetBoolean("privacy_mode",
+ server_id->privacy_mode() == PRIVACY_MODE_ENABLED);
dict->SetBoolean("require_confirmation", require_confirmation);
return dict;
}
diff --git a/net/spdy/spdy_headers_block_parser.cc b/net/spdy/spdy_headers_block_parser.cc
index 9686427..1ec0d0d 100644
--- a/net/spdy/spdy_headers_block_parser.cc
+++ b/net/spdy/spdy_headers_block_parser.cc
@@ -7,6 +7,12 @@
#include "base/sys_byteorder.h"
namespace net {
+namespace {
+
+// 0 is invalid according to both the SPDY 3.1 and HTTP/2 specifications.
+const SpdyStreamId kInvalidStreamId = 0;
+
+} // anonymous namespace
const size_t SpdyHeadersBlockParser::kMaximumFieldLength = 16 * 1024;
@@ -19,6 +25,7 @@
total_bytes_received_(0),
remaining_key_value_pairs_for_frame_(0),
handler_(handler),
+ stream_id_(kInvalidStreamId),
error_(OK),
spdy_version_(spdy_version) {
// The handler that we set must not be NULL.
@@ -34,15 +41,27 @@
if (error_ == NEED_MORE_DATA) {
error_ = OK;
}
- CHECK_EQ(error_, OK);
+ if (error_ != OK) {
+ LOG(DFATAL) << "Unexpected error: " << error_;
+ return false;
+ }
// If this is the first call with the current header block,
// save its stream id.
- if (state_ == READING_HEADER_BLOCK_LEN) {
+ if (state_ == READING_HEADER_BLOCK_LEN && stream_id_ == kInvalidStreamId) {
stream_id_ = stream_id;
}
- CHECK_EQ(stream_id_, stream_id);
-
+ if (stream_id != stream_id_) {
+ LOG(DFATAL) << "Unexpected stream id: " << stream_id << " (expected "
+ << stream_id_ << ")";
+ error_ = UNEXPECTED_STREAM_ID;
+ return false;
+ }
+ if (stream_id_ == kInvalidStreamId) {
+ LOG(DFATAL) << "Expected nonzero stream id, saw: " << stream_id_;
+ error_ = UNEXPECTED_STREAM_ID;
+ return false;
+ }
total_bytes_received_ += headers_data_length;
SpdyPinnableBufferPiece prefix, key, value;
@@ -81,7 +100,7 @@
if (!reader.ReadN(next_field_length_, &value)) {
error_ = NEED_MORE_DATA;
} else {
- handler_->OnHeader(stream_id, key, value);
+ handler_->OnHeader(key, value);
}
break;
case FINISHED_HEADER:
@@ -90,15 +109,14 @@
next_state = READING_KEY_LEN;
} else {
next_state = READING_HEADER_BLOCK_LEN;
- handler_->OnHeaderBlockEnd(stream_id, total_bytes_received_);
+ handler_->OnHeaderBlockEnd(total_bytes_received_);
+ stream_id_ = kInvalidStreamId;
// Expect to have consumed all buffer.
if (reader.Available() != 0) {
error_ = TOO_MUCH_DATA;
}
}
break;
- default:
- CHECK(false) << "Not reached.";
}
if (error_ == OK) {
@@ -130,7 +148,7 @@
error_ = HEADER_BLOCK_TOO_LARGE;
}
if (error_ == OK) {
- handler_->OnHeaderBlock(stream_id_, remaining_key_value_pairs_for_frame_);
+ handler_->OnHeaderBlock(remaining_key_value_pairs_for_frame_);
}
}
diff --git a/net/spdy/spdy_headers_block_parser.h b/net/spdy/spdy_headers_block_parser.h
index 3c0c8e3..a9dfaa6 100644
--- a/net/spdy/spdy_headers_block_parser.h
+++ b/net/spdy/spdy_headers_block_parser.h
@@ -22,18 +22,14 @@
// A callback method which notifies when the parser starts handling a new
// SPDY headers block, this method also notifies on the number of headers in
// the block.
- virtual void OnHeaderBlock(SpdyStreamId stream_id,
- uint32_t num_of_headers) = 0;
+ virtual void OnHeaderBlock(uint32_t num_of_headers) = 0;
// A callback method which notifies on a SPDY header key value pair.
- virtual void OnHeader(SpdyStreamId stream_id,
- base::StringPiece key,
- base::StringPiece value) = 0;
+ virtual void OnHeader(base::StringPiece key, base::StringPiece value) = 0;
// A callback method which notifies when the parser finishes handling a SPDY
// headers block. Also notifies on the total number of bytes in this block.
- virtual void OnHeaderBlockEnd(SpdyStreamId stream_id,
- size_t header_bytes_parsed) = 0;
+ virtual void OnHeaderBlockEnd(size_t header_bytes_parsed) = 0;
};
namespace test {
@@ -75,6 +71,8 @@
HEADER_BLOCK_TOO_LARGE,
// Set when a header key or value exceeds |kMaximumFieldLength|.
HEADER_FIELD_TOO_LARGE,
+ // Set when the parser is given an unexpected stream ID.
+ UNEXPECTED_STREAM_ID,
};
ParserError get_error() const { return error_; }
diff --git a/net/spdy/spdy_headers_block_parser_test.cc b/net/spdy/spdy_headers_block_parser_test.cc
index e2fdb31..8133888 100644
--- a/net/spdy/spdy_headers_block_parser_test.cc
+++ b/net/spdy/spdy_headers_block_parser_test.cc
@@ -9,6 +9,7 @@
#include "base/memory/scoped_ptr.h"
#include "base/strings/string_number_conversions.h"
#include "base/sys_byteorder.h"
+#include "net/test/gtest_util.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -22,12 +23,9 @@
// and call the callback methods when we should.
class MockSpdyHeadersHandler : public SpdyHeadersHandlerInterface {
public:
- MOCK_METHOD2(OnHeaderBlock, void(SpdyStreamId stream_id,
- uint32_t num_of_headers));
- MOCK_METHOD2(OnHeaderBlockEnd, void(SpdyStreamId stream_id, size_t bytes));
- MOCK_METHOD3(OnHeader, void(SpdyStreamId stream_id,
- StringPiece,
- StringPiece));
+ MOCK_METHOD1(OnHeaderBlock, void(uint32_t num_of_headers));
+ MOCK_METHOD1(OnHeaderBlockEnd, void(size_t bytes));
+ MOCK_METHOD2(OnHeader, void(StringPiece key, StringPiece value));
};
class SpdyHeadersBlockParserTest :
@@ -121,13 +119,13 @@
// handling a headers block.
string headers(CreateHeaders(1, false));
- EXPECT_CALL(handler_, OnHeaderBlock(1, 1)).Times(1);
+ EXPECT_CALL(handler_, OnHeaderBlock(1)).Times(1);
std::string expect_key = kBaseKey + IntToString(0);
std::string expect_value = kBaseValue + IntToString(0);
- EXPECT_CALL(handler_, OnHeader(1, StringPiece(expect_key),
+ EXPECT_CALL(handler_, OnHeader(StringPiece(expect_key),
StringPiece(expect_value))).Times(1);
- EXPECT_CALL(handler_, OnHeaderBlockEnd(1, headers.length())).Times(1);
+ EXPECT_CALL(handler_, OnHeaderBlockEnd(headers.length())).Times(1);
EXPECT_TRUE(parser_->
HandleControlFrameHeadersData(1, headers.c_str(), headers.length()));
@@ -139,13 +137,13 @@
// a single key-value pair when the key and value contain null charecters.
string headers(CreateHeaders(1, true));
- EXPECT_CALL(handler_, OnHeaderBlock(1, 1)).Times(1);
+ EXPECT_CALL(handler_, OnHeaderBlock(1)).Times(1);
std::string expect_key = kBaseKey + string("\0", 1) + IntToString(0);
std::string expect_value = kBaseValue + string("\0", 1) + IntToString(0);
- EXPECT_CALL(handler_, OnHeader(1, StringPiece(expect_key),
+ EXPECT_CALL(handler_, OnHeader(StringPiece(expect_key),
StringPiece(expect_value))).Times(1);
- EXPECT_CALL(handler_, OnHeaderBlockEnd(1, headers.length())).Times(1);
+ EXPECT_CALL(handler_, OnHeaderBlockEnd(headers.length())).Times(1);
EXPECT_TRUE(parser_->
HandleControlFrameHeadersData(1, headers.c_str(), headers.length()));
@@ -166,17 +164,16 @@
}
// For each block we expect to parse out the headers in order.
for (int i = 0; i < kNumHeaderBlocks; i++) {
- EXPECT_CALL(handler_, OnHeaderBlock(i, kNumHeadersInBlock)).Times(1);
+ EXPECT_CALL(handler_, OnHeaderBlock(kNumHeadersInBlock)).Times(1);
for (int j = 0; j < kNumHeadersInBlock; j++) {
EXPECT_CALL(handler_, OnHeader(
- i,
StringPiece(retained_arguments[2 * j]),
StringPiece(retained_arguments[2 * j + 1]))).Times(1);
}
- EXPECT_CALL(handler_, OnHeaderBlockEnd(i, headers.length())).Times(1);
+ EXPECT_CALL(handler_, OnHeaderBlockEnd(headers.length())).Times(1);
}
// Parse the header blocks, feeding the parser one byte at a time.
- for (int i = 0; i < kNumHeaderBlocks; i++) {
+ for (int i = 1; i <= kNumHeaderBlocks; i++) {
for (string::iterator it = headers.begin(); it != headers.end(); ++it) {
if ((it + 1) == headers.end()) {
// Last byte completes the block.
@@ -191,15 +188,15 @@
}
TEST_P(SpdyHeadersBlockParserTest, HandlesEmptyCallsTest) {
- EXPECT_CALL(handler_, OnHeaderBlock(1, 1)).Times(1);
+ EXPECT_CALL(handler_, OnHeaderBlock(1)).Times(1);
string headers(CreateHeaders(1, false));
string expect_key = kBaseKey + IntToString(0);
string expect_value = kBaseValue + IntToString(0);
- EXPECT_CALL(handler_, OnHeader(1, StringPiece(expect_key),
+ EXPECT_CALL(handler_, OnHeader(StringPiece(expect_key),
StringPiece(expect_value))).Times(1);
- EXPECT_CALL(handler_, OnHeaderBlockEnd(1, headers.length())).Times(1);
+ EXPECT_CALL(handler_, OnHeaderBlockEnd(headers.length())).Times(1);
// Send a header in pieces with intermediate empty calls.
for (string::iterator it = headers.begin(); it != headers.end(); ++it) {
@@ -228,7 +225,7 @@
parser_.reset(new SpdyHeadersBlockParser(spdy_version_, &handler_));
// Header block with one header, which has a too-long key.
{
- EXPECT_CALL(handler_, OnHeaderBlock(1, 1)).Times(1);
+ EXPECT_CALL(handler_, OnHeaderBlock(1)).Times(1);
string headers = EncodeLength(1) + EncodeLength(
SpdyHeadersBlockParser::kMaximumFieldLength + 1);
@@ -242,17 +239,39 @@
TEST_P(SpdyHeadersBlockParserTest, ExtraDataTest) {
string headers = CreateHeaders(1, false) + "foobar";
- EXPECT_CALL(handler_, OnHeaderBlock(1, 1)).Times(1);
- EXPECT_CALL(handler_, OnHeaderBlockEnd(1, headers.length())).Times(1);
+ EXPECT_CALL(handler_, OnHeaderBlock(1)).Times(1);
+ EXPECT_CALL(handler_, OnHeaderBlockEnd(headers.length())).Times(1);
string expect_key = kBaseKey + IntToString(0);
string expect_value = kBaseValue + IntToString(0);
- EXPECT_CALL(handler_, OnHeader(1, StringPiece(expect_key),
+ EXPECT_CALL(handler_, OnHeader(StringPiece(expect_key),
StringPiece(expect_value))).Times(1);
- EXPECT_FALSE(parser_->
- HandleControlFrameHeadersData(1, headers.c_str(), headers.length()));
+ EXPECT_FALSE(parser_->HandleControlFrameHeadersData(1, headers.c_str(),
+ headers.length()));
EXPECT_EQ(SpdyHeadersBlockParser::TOO_MUCH_DATA, parser_->get_error());
}
+TEST_P(SpdyHeadersBlockParserTest, WrongStreamIdTest) {
+ string headers(CreateHeaders(kNumHeadersInBlock, false));
+ EXPECT_FALSE(parser_->HandleControlFrameHeadersData(1, headers.data(), 1));
+ EXPECT_EQ(SpdyHeadersBlockParser::NEED_MORE_DATA, parser_->get_error());
+ bool result;
+ EXPECT_DFATAL(
+ result = parser_->HandleControlFrameHeadersData(2, headers.data() + 1, 1),
+ "Unexpected stream id: 2 \\(expected 1\\)");
+ EXPECT_FALSE(result);
+ EXPECT_EQ(SpdyHeadersBlockParser::UNEXPECTED_STREAM_ID, parser_->get_error());
+}
+
+TEST_P(SpdyHeadersBlockParserTest, InvalidStreamIdTest) {
+ string headers(CreateHeaders(kNumHeadersInBlock, false));
+ bool result;
+ EXPECT_DFATAL(
+ result = parser_->HandleControlFrameHeadersData(0, headers.data(), 1),
+ "Expected nonzero stream id, saw: 0");
+ EXPECT_FALSE(result);
+ EXPECT_EQ(SpdyHeadersBlockParser::UNEXPECTED_STREAM_ID, parser_->get_error());
+}
+
} // namespace net
diff --git a/net/tools/testserver/testserver.py b/net/tools/testserver/testserver.py
index 93de5ca..3098cc0 100755
--- a/net/tools/testserver/testserver.py
+++ b/net/tools/testserver/testserver.py
@@ -193,6 +193,8 @@
}[cert_type])
self.ssl_handshake_settings = tlslite.api.HandshakeSettings()
+ # Enable SSLv3 for testing purposes.
+ self.ssl_handshake_settings.minVersion = (3, 0)
if ssl_bulk_ciphers is not None:
self.ssl_handshake_settings.cipherNames = ssl_bulk_ciphers
if ssl_key_exchanges is not None:
@@ -674,7 +676,12 @@
if not self._ShouldHandleRequest("/echo"):
return False
- self.send_response(200)
+ _, _, _, _, query, _ = urlparse.urlparse(self.path)
+ query_params = cgi.parse_qs(query, True)
+ if 'status' in query_params:
+ self.send_response(int(query_params['status'][0]))
+ else:
+ self.send_response(200)
self.send_header('Content-Type', 'text/html')
self.end_headers()
self.wfile.write(self.ReadRequestBody())
diff --git a/net/url_request/test_url_fetcher_factory.cc b/net/url_request/test_url_fetcher_factory.cc
index 357dfeb..6dc9367 100644
--- a/net/url_request/test_url_fetcher_factory.cc
+++ b/net/url_request/test_url_fetcher_factory.cc
@@ -15,6 +15,7 @@
#include "net/base/host_port_pair.h"
#include "net/base/io_buffer.h"
#include "net/base/net_errors.h"
+#include "net/base/upload_data_stream.h"
#include "net/http/http_response_headers.h"
#include "net/url_request/url_fetcher_delegate.h"
#include "net/url_request/url_fetcher_impl.h"
@@ -73,6 +74,11 @@
upload_file_path_ = file_path;
}
+void TestURLFetcher::SetUploadStreamFactory(
+ const std::string& upload_content_type,
+ const CreateUploadStreamCallback& factory) {
+}
+
void TestURLFetcher::SetChunkedUpload(const std::string& upload_content_type) {
}
diff --git a/net/url_request/test_url_fetcher_factory.h b/net/url_request/test_url_fetcher_factory.h
index 078e8cb..5ceef51 100644
--- a/net/url_request/test_url_fetcher_factory.h
+++ b/net/url_request/test_url_fetcher_factory.h
@@ -95,6 +95,9 @@
uint64 range_offset,
uint64 range_length,
scoped_refptr<base::TaskRunner> file_task_runner) override;
+ void SetUploadStreamFactory(
+ const std::string& upload_content_type,
+ const CreateUploadStreamCallback& callback) override;
void SetChunkedUpload(const std::string& upload_content_type) override;
// Overriden to cache the chunks uploaded. Caller can read back the uploaded
// chunks with the upload_chunks() accessor.
diff --git a/net/url_request/url_fetcher.h b/net/url_request/url_fetcher.h
index 5dcaedd..e08bdaa 100644
--- a/net/url_request/url_fetcher.h
+++ b/net/url_request/url_fetcher.h
@@ -92,6 +92,11 @@
// base::SupportsUserData::Data object every time it's called.
typedef base::Callback<base::SupportsUserData::Data*()> CreateDataCallback;
+ // Used by SetUploadStreamFactory. The callback should assign a fresh upload
+ // data stream every time it's called.
+ typedef base::Callback<scoped_ptr<UploadDataStream>()>
+ CreateUploadStreamCallback;
+
virtual ~URLFetcher();
// |url| is the URL to send the request to.
@@ -149,6 +154,16 @@
uint64 range_length,
scoped_refptr<base::TaskRunner> file_task_runner) = 0;
+ // Sets data only needed by POSTs. All callers making POST requests should
+ // call one of the SetUpload* methods before the request is started.
+ // |upload_content_type| is the MIME type of the content, while |callback| is
+ // the callback to create the upload data stream (the Content-Length header
+ // value will be set to the length of this data). |callback| may be called
+ // mutliple times if the request is retried.
+ virtual void SetUploadStreamFactory(
+ const std::string& upload_content_type,
+ const CreateUploadStreamCallback& callback) = 0;
+
// Indicates that the POST data is sent via chunked transfer encoding.
// This may only be called before calling Start().
// Use AppendChunkToUpload() to give the data chunks after calling Start().
diff --git a/net/url_request/url_fetcher_core.cc b/net/url_request/url_fetcher_core.cc
index c9f028f..4007912 100644
--- a/net/url_request/url_fetcher_core.cc
+++ b/net/url_request/url_fetcher_core.cc
@@ -137,10 +137,8 @@
void URLFetcherCore::SetUploadData(const std::string& upload_content_type,
const std::string& upload_content) {
+ AssertHasNoUploadData();
DCHECK(!is_chunked_upload_);
- DCHECK(!upload_content_set_);
- DCHECK(upload_content_.empty());
- DCHECK(upload_file_path_.empty());
DCHECK(upload_content_type_.empty());
// Empty |upload_content_type| is allowed iff the |upload_content| is empty.
@@ -157,10 +155,8 @@
uint64 range_offset,
uint64 range_length,
scoped_refptr<base::TaskRunner> file_task_runner) {
+ AssertHasNoUploadData();
DCHECK(!is_chunked_upload_);
- DCHECK(!upload_content_set_);
- DCHECK(upload_content_.empty());
- DCHECK(upload_file_path_.empty());
DCHECK_EQ(upload_range_offset_, 0ULL);
DCHECK_EQ(upload_range_length_, 0ULL);
DCHECK(upload_content_type_.empty());
@@ -174,10 +170,23 @@
upload_content_set_ = true;
}
+void URLFetcherCore::SetUploadStreamFactory(
+ const std::string& upload_content_type,
+ const URLFetcher::CreateUploadStreamCallback& factory) {
+ AssertHasNoUploadData();
+ DCHECK(!is_chunked_upload_);
+ DCHECK(upload_content_type_.empty());
+
+ upload_content_type_ = upload_content_type;
+ upload_stream_factory_ = factory;
+ upload_content_set_ = true;
+}
+
void URLFetcherCore::SetChunkedUpload(const std::string& content_type) {
- DCHECK(is_chunked_upload_ ||
- (upload_content_type_.empty() &&
- upload_content_.empty()));
+ if (!is_chunked_upload_) {
+ AssertHasNoUploadData();
+ DCHECK(upload_content_type_.empty());
+ }
// Empty |content_type| is not allowed here, because it is impossible
// to ensure non-empty upload content as it is not yet supplied.
@@ -605,6 +614,10 @@
base::Time()));
request_->set_upload(
ElementsUploadDataStream::CreateWithReader(reader.Pass(), 0));
+ } else if (!upload_stream_factory_.is_null()) {
+ scoped_ptr<UploadDataStream> stream = upload_stream_factory_.Run();
+ DCHECK(stream);
+ request_->set_upload(stream.Pass());
}
current_upload_bytes_ = -1;
@@ -957,4 +970,11 @@
delegate_->OnURLFetchDownloadProgress(fetcher_, current, total);
}
+void URLFetcherCore::AssertHasNoUploadData() const {
+ DCHECK(!upload_content_set_);
+ DCHECK(upload_content_.empty());
+ DCHECK(upload_file_path_.empty());
+ DCHECK(upload_stream_factory_.is_null());
+}
+
} // namespace net
diff --git a/net/url_request/url_fetcher_core.h b/net/url_request/url_fetcher_core.h
index 6bf449f..193edb4 100644
--- a/net/url_request/url_fetcher_core.h
+++ b/net/url_request/url_fetcher_core.h
@@ -68,6 +68,9 @@
uint64 range_offset,
uint64 range_length,
scoped_refptr<base::TaskRunner> file_task_runner);
+ void SetUploadStreamFactory(
+ const std::string& upload_content_type,
+ const URLFetcher::CreateUploadStreamCallback& callback);
void SetChunkedUpload(const std::string& upload_content_type);
// Adds a block of data to be uploaded in a POST body. This can only be
// called after Start().
@@ -203,6 +206,9 @@
void InformDelegateDownloadProgressInDelegateThread(int64 current,
int64 total);
+ // Check if any upload data is set or not.
+ void AssertHasNoUploadData() const;
+
URLFetcher* fetcher_; // Corresponding fetcher object
GURL original_url_; // The URL we were asked to fetch
GURL url_; // The URL we eventually wound up at
@@ -239,6 +245,8 @@
// to be uploaded.
uint64 upload_range_length_; // The length of the part of file to be
// uploaded.
+ URLFetcher::CreateUploadStreamCallback
+ upload_stream_factory_; // Callback to create HTTP POST payload.
std::string upload_content_type_; // MIME type of POST payload
std::string referrer_; // HTTP Referer header value and policy
URLRequest::ReferrerPolicy referrer_policy_;
diff --git a/net/url_request/url_fetcher_impl.cc b/net/url_request/url_fetcher_impl.cc
index 179adfb..6358473 100644
--- a/net/url_request/url_fetcher_impl.cc
+++ b/net/url_request/url_fetcher_impl.cc
@@ -7,6 +7,7 @@
#include "base/bind.h"
#include "base/message_loop/message_loop_proxy.h"
#include "base/sequenced_task_runner.h"
+#include "net/base/upload_data_stream.h"
#include "net/url_request/url_fetcher_core.h"
#include "net/url_request/url_fetcher_factory.h"
#include "net/url_request/url_fetcher_response_writer.h"
@@ -43,6 +44,12 @@
file_task_runner);
}
+void URLFetcherImpl::SetUploadStreamFactory(
+ const std::string& upload_content_type,
+ const CreateUploadStreamCallback& callback) {
+ core_->SetUploadStreamFactory(upload_content_type, callback);
+}
+
void URLFetcherImpl::SetChunkedUpload(const std::string& content_type) {
core_->SetChunkedUpload(content_type);
}
diff --git a/net/url_request/url_fetcher_impl.h b/net/url_request/url_fetcher_impl.h
index f0a57af..4795629 100644
--- a/net/url_request/url_fetcher_impl.h
+++ b/net/url_request/url_fetcher_impl.h
@@ -45,6 +45,9 @@
uint64 range_offset,
uint64 range_length,
scoped_refptr<base::TaskRunner> file_task_runner) override;
+ void SetUploadStreamFactory(
+ const std::string& upload_content_type,
+ const CreateUploadStreamCallback& callback) override;
void SetChunkedUpload(const std::string& upload_content_type) override;
void AppendChunkToUpload(const std::string& data,
bool is_last_chunk) override;
diff --git a/net/url_request/url_fetcher_impl_unittest.cc b/net/url_request/url_fetcher_impl_unittest.cc
index fce7ace..faea357 100644
--- a/net/url_request/url_fetcher_impl_unittest.cc
+++ b/net/url_request/url_fetcher_impl_unittest.cc
@@ -17,7 +17,11 @@
#include "base/threading/thread.h"
#include "build/build_config.h"
#include "crypto/nss_util.h"
+#include "net/base/elements_upload_data_stream.h"
#include "net/base/network_change_notifier.h"
+#include "net/base/upload_bytes_element_reader.h"
+#include "net/base/upload_element_reader.h"
+#include "net/base/upload_file_element_reader.h"
#include "net/dns/mock_host_resolver.h"
#include "net/http/http_response_headers.h"
#include "net/test/spawned_test_server/spawned_test_server.h"
@@ -81,7 +85,7 @@
class URLFetcherTest : public testing::Test,
public URLFetcherDelegate {
public:
- URLFetcherTest() : fetcher_(NULL) {}
+ URLFetcherTest() : fetcher_(NULL), expected_status_code_(200) {}
static int GetNumFetcherCores() {
return URLFetcherImpl::GetNumFetcherCores();
@@ -135,6 +139,7 @@
URLFetcherImpl* fetcher_;
scoped_ptr<TestURLRequestContext> context_;
+ int expected_status_code_;
};
// A test fixture that uses a MockHostResolver, so that name resolutions can
@@ -166,7 +171,7 @@
void URLFetcherTest::OnURLFetchComplete(const URLFetcher* source) {
EXPECT_TRUE(source->GetStatus().is_success());
- EXPECT_EQ(200, source->GetResponseCode()); // HTTP OK
+ EXPECT_EQ(expected_status_code_, source->GetResponseCode()); // HTTP OK
std::string data;
EXPECT_TRUE(source->GetResponseAsString(&data));
@@ -259,6 +264,34 @@
uint64 range_length_;
};
+class URLFetcherSetUploadFactoryTest : public URLFetcherTest {
+ public:
+ URLFetcherSetUploadFactoryTest() : create_stream_count_(0) {}
+
+ // URLFetcherTest:
+ void CreateFetcher(const GURL& url) override;
+
+ // URLFetcherDelegate:
+ void OnURLFetchComplete(const URLFetcher* source) override;
+
+ // Callback passed to URLFetcher to create upload stream.
+ scoped_ptr<UploadDataStream> CreateUploadStream() {
+ ++create_stream_count_;
+ const std::string str("bobsyeruncle\n");
+ std::vector<char> buffer(str.begin(), str.end());
+ return ElementsUploadDataStream::CreateWithReader(
+ scoped_ptr<UploadElementReader>(
+ new UploadOwnedBytesElementReader(&buffer)),
+ 0);
+ }
+
+ size_t create_stream_count() const { return create_stream_count_; }
+
+ private:
+ // Count of calling CreateStream.
+ size_t create_stream_count_;
+};
+
// Version of URLFetcherTest that does a POST instead with empty upload body
class URLFetcherEmptyPostTest : public URLFetcherTest {
public:
@@ -571,6 +604,27 @@
URLFetcherTest::OnURLFetchComplete(source);
}
+void URLFetcherSetUploadFactoryTest::CreateFetcher(const GURL& url) {
+ fetcher_ = new URLFetcherImpl(url, URLFetcher::POST, this);
+ fetcher_->SetRequestContext(new ThrottlingTestURLRequestContextGetter(
+ io_message_loop_proxy().get(), request_context()));
+ fetcher_->SetUploadStreamFactory(
+ "text/plain",
+ base::Bind(&URLFetcherSetUploadFactoryTest::CreateUploadStream,
+ base::Unretained(this)));
+ fetcher_->SetAutomaticallyRetryOn5xx(true);
+ fetcher_->SetMaxRetriesOn5xx(1);
+ fetcher_->Start();
+}
+
+void URLFetcherSetUploadFactoryTest::OnURLFetchComplete(
+ const URLFetcher* source) {
+ std::string data;
+ EXPECT_TRUE(source->GetResponseAsString(&data));
+ EXPECT_EQ("bobsyeruncle\n", data);
+ URLFetcherTest::OnURLFetchComplete(source);
+}
+
void URLFetcherEmptyPostTest::CreateFetcher(const GURL& url) {
fetcher_ = new URLFetcherImpl(url, URLFetcher::POST, this);
fetcher_->SetRequestContext(new TestURLRequestContextGetter(
@@ -1085,6 +1139,28 @@
base::MessageLoop::current()->Run();
}
+TEST_F(URLFetcherSetUploadFactoryTest, Basic) {
+ SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTP,
+ SpawnedTestServer::kLocalhost,
+ base::FilePath(kDocRoot));
+ ASSERT_TRUE(test_server.Start());
+
+ CreateFetcher(test_server.GetURL("echo"));
+ base::MessageLoop::current()->Run();
+ ASSERT_EQ(1u, create_stream_count());
+}
+
+TEST_F(URLFetcherSetUploadFactoryTest, Retry) {
+ SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTP,
+ SpawnedTestServer::kLocalhost,
+ base::FilePath(kDocRoot));
+ ASSERT_TRUE(test_server.Start());
+ expected_status_code_ = 500;
+ CreateFetcher(test_server.GetURL("echo?status=500"));
+ base::MessageLoop::current()->Run();
+ ASSERT_EQ(2u, create_stream_count());
+}
+
TEST_F(URLFetcherEmptyPostTest, Basic) {
SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTP,
SpawnedTestServer::kLocalhost,
diff --git a/net/websockets/websocket_handshake_stream_create_helper_test.cc b/net/websockets/websocket_handshake_stream_create_helper_test.cc
index 512de24..8edbc66 100644
--- a/net/websockets/websocket_handshake_stream_create_helper_test.cc
+++ b/net/websockets/websocket_handshake_stream_create_helper_test.cc
@@ -78,6 +78,7 @@
protected:
scoped_ptr<WebSocketStream> CreateAndInitializeStream(
const std::string& socket_url,
+ const std::string& socket_host,
const std::string& socket_path,
const std::vector<std::string>& sub_protocols,
const std::string& origin,
@@ -89,8 +90,8 @@
scoped_ptr<ClientSocketHandle> socket_handle =
socket_handle_factory_.CreateClientSocketHandle(
- WebSocketStandardRequest(
- socket_path, origin, extra_request_headers),
+ WebSocketStandardRequest(socket_path, socket_host, origin,
+ extra_request_headers),
WebSocketStandardResponse(extra_response_headers));
scoped_ptr<WebSocketHandshakeStreamBase> handshake(
@@ -144,10 +145,9 @@
// Confirm that the basic case works as expected.
TEST_F(WebSocketHandshakeStreamCreateHelperTest, BasicStream) {
- scoped_ptr<WebSocketStream> stream =
- CreateAndInitializeStream("ws://localhost/", "/",
- std::vector<std::string>(), "http://localhost/",
- "", "");
+ scoped_ptr<WebSocketStream> stream = CreateAndInitializeStream(
+ "ws://localhost/", "localhost", "/", std::vector<std::string>(),
+ "http://localhost/", "", "");
EXPECT_EQ("", stream->GetExtensions());
EXPECT_EQ("", stream->GetSubProtocol());
}
@@ -157,13 +157,10 @@
std::vector<std::string> sub_protocols;
sub_protocols.push_back("chat");
sub_protocols.push_back("superchat");
- scoped_ptr<WebSocketStream> stream =
- CreateAndInitializeStream("ws://localhost/",
- "/",
- sub_protocols,
- "http://localhost/",
- "Sec-WebSocket-Protocol: chat, superchat\r\n",
- "Sec-WebSocket-Protocol: superchat\r\n");
+ scoped_ptr<WebSocketStream> stream = CreateAndInitializeStream(
+ "ws://localhost/", "localhost", "/", sub_protocols, "http://localhost/",
+ "Sec-WebSocket-Protocol: chat, superchat\r\n",
+ "Sec-WebSocket-Protocol: superchat\r\n");
EXPECT_EQ("superchat", stream->GetSubProtocol());
}
@@ -171,11 +168,8 @@
// websocket_stream_test.cc.
TEST_F(WebSocketHandshakeStreamCreateHelperTest, Extensions) {
scoped_ptr<WebSocketStream> stream = CreateAndInitializeStream(
- "ws://localhost/",
- "/",
- std::vector<std::string>(),
- "http://localhost/",
- "",
+ "ws://localhost/", "localhost", "/", std::vector<std::string>(),
+ "http://localhost/", "",
"Sec-WebSocket-Extensions: permessage-deflate\r\n");
EXPECT_EQ("permessage-deflate", stream->GetExtensions());
}
@@ -184,11 +178,8 @@
// websocket_stream_test.cc.
TEST_F(WebSocketHandshakeStreamCreateHelperTest, ExtensionParameters) {
scoped_ptr<WebSocketStream> stream = CreateAndInitializeStream(
- "ws://localhost/",
- "/",
- std::vector<std::string>(),
- "http://localhost/",
- "",
+ "ws://localhost/", "localhost", "/", std::vector<std::string>(),
+ "http://localhost/", "",
"Sec-WebSocket-Extensions: permessage-deflate;"
" client_max_window_bits=14; server_max_window_bits=14;"
" server_no_context_takeover; client_no_context_takeover\r\n");
diff --git a/net/websockets/websocket_stream_test.cc b/net/websockets/websocket_stream_test.cc
index 801e84e..03a593d 100644
--- a/net/websockets/websocket_stream_test.cc
+++ b/net/websockets/websocket_stream_test.cc
@@ -110,6 +110,7 @@
void CreateAndConnectCustomResponse(
const std::string& socket_url,
+ const std::string& socket_host,
const std::string& socket_path,
const std::vector<std::string>& sub_protocols,
const std::string& origin,
@@ -117,29 +118,27 @@
const std::string& response_body,
scoped_ptr<base::Timer> timer = scoped_ptr<base::Timer>()) {
url_request_context_host_.SetExpectations(
- WebSocketStandardRequest(socket_path, origin, extra_request_headers),
+ WebSocketStandardRequest(socket_path, socket_host, origin,
+ extra_request_headers),
response_body);
CreateAndConnectStream(socket_url, sub_protocols, origin, timer.Pass());
}
// |extra_request_headers| and |extra_response_headers| must end in "\r\n" or
// errors like "Unable to perform synchronous IO while stopped" will occur.
- void CreateAndConnectStandard(const std::string& socket_url,
- const std::string& socket_path,
- const std::vector<std::string>& sub_protocols,
- const std::string& origin,
- const std::string& extra_request_headers,
- const std::string& extra_response_headers,
- scoped_ptr<base::Timer> timer =
- scoped_ptr<base::Timer>()) {
+ void CreateAndConnectStandard(
+ const std::string& socket_url,
+ const std::string& socket_host,
+ const std::string& socket_path,
+ const std::vector<std::string>& sub_protocols,
+ const std::string& origin,
+ const std::string& extra_request_headers,
+ const std::string& extra_response_headers,
+ scoped_ptr<base::Timer> timer = scoped_ptr<base::Timer>()) {
CreateAndConnectCustomResponse(
- socket_url,
- socket_path,
- sub_protocols,
- origin,
+ socket_url, socket_host, socket_path, sub_protocols, origin,
extra_request_headers,
- WebSocketStandardResponse(extra_response_headers),
- timer.Pass());
+ WebSocketStandardResponse(extra_response_headers), timer.Pass());
}
void CreateAndConnectRawExpectations(
@@ -261,11 +260,8 @@
void CreateAndConnectWithExtensions(
const std::string& extensions_header_value) {
CreateAndConnectStandard(
- "ws://localhost/testing_path",
- "/testing_path",
- NoSubProtocols(),
- "http://localhost",
- "",
+ "ws://localhost/testing_path", "localhost", "/testing_path",
+ NoSubProtocols(), "http://localhost", "",
"Sec-WebSocket-Extensions: " + extensions_header_value + "\r\n");
RunUntilIdle();
}
@@ -280,7 +276,8 @@
scoped_ptr<DeterministicSocketData> BuildSocketData1(
const std::string& response) {
- request1_ = WebSocketStandardRequest("/", "http://localhost", "");
+ request1_ =
+ WebSocketStandardRequest("/", "localhost", "http://localhost", "");
writes1_[0] = MockWrite(SYNCHRONOUS, 0, request1_.c_str());
response1_ = response;
reads1_[0] = MockRead(SYNCHRONOUS, 1, response1_.c_str());
@@ -421,8 +418,8 @@
// Confirm that the basic case works as expected.
TEST_F(WebSocketStreamCreateTest, SimpleSuccess) {
- CreateAndConnectStandard(
- "ws://localhost/", "/", NoSubProtocols(), "http://localhost", "", "");
+ CreateAndConnectStandard("ws://localhost/", "localhost", "/",
+ NoSubProtocols(), "http://localhost", "", "");
EXPECT_FALSE(request_info_);
EXPECT_FALSE(response_info_);
RunUntilIdle();
@@ -443,13 +440,9 @@
"hoge: piyo\r\n"
"\r\n";
- CreateAndConnectCustomResponse(
- "ws://localhost/",
- "/",
- NoSubProtocols(),
- "http://localhost",
- "",
- kResponse);
+ CreateAndConnectCustomResponse("ws://localhost/", "localhost", "/",
+ NoSubProtocols(), "http://localhost", "",
+ kResponse);
EXPECT_FALSE(request_info_);
EXPECT_FALSE(response_info_);
RunUntilIdle();
@@ -501,20 +494,17 @@
// Confirm that the stream isn't established until the message loop runs.
TEST_F(WebSocketStreamCreateTest, NeedsToRunLoop) {
- CreateAndConnectStandard(
- "ws://localhost/", "/", NoSubProtocols(), "http://localhost", "", "");
+ CreateAndConnectStandard("ws://localhost/", "localhost", "/",
+ NoSubProtocols(), "http://localhost", "", "");
EXPECT_FALSE(has_failed());
EXPECT_FALSE(stream_);
}
// Check the path is used.
TEST_F(WebSocketStreamCreateTest, PathIsUsed) {
- CreateAndConnectStandard("ws://localhost/testing_path",
- "/testing_path",
- NoSubProtocols(),
- "http://localhost",
- "",
- "");
+ CreateAndConnectStandard("ws://localhost/testing_path", "localhost",
+ "/testing_path", NoSubProtocols(),
+ "http://localhost", "", "");
RunUntilIdle();
EXPECT_FALSE(has_failed());
EXPECT_TRUE(stream_);
@@ -522,12 +512,9 @@
// Check that the origin is used.
TEST_F(WebSocketStreamCreateTest, OriginIsUsed) {
- CreateAndConnectStandard("ws://localhost/testing_path",
- "/testing_path",
- NoSubProtocols(),
- "http://google.com",
- "",
- "");
+ CreateAndConnectStandard("ws://localhost/testing_path", "localhost",
+ "/testing_path", NoSubProtocols(),
+ "http://google.com", "", "");
RunUntilIdle();
EXPECT_FALSE(has_failed());
EXPECT_TRUE(stream_);
@@ -538,10 +525,8 @@
std::vector<std::string> sub_protocols;
sub_protocols.push_back("chatv11.chromium.org");
sub_protocols.push_back("chatv20.chromium.org");
- CreateAndConnectStandard("ws://localhost/testing_path",
- "/testing_path",
- sub_protocols,
- "http://google.com",
+ CreateAndConnectStandard("ws://localhost/testing_path", "localhost",
+ "/testing_path", sub_protocols, "http://google.com",
"Sec-WebSocket-Protocol: chatv11.chromium.org, "
"chatv20.chromium.org\r\n",
"Sec-WebSocket-Protocol: chatv20.chromium.org\r\n");
@@ -553,11 +538,9 @@
// Unsolicited sub-protocols are rejected.
TEST_F(WebSocketStreamCreateTest, UnsolicitedSubProtocol) {
- CreateAndConnectStandard("ws://localhost/testing_path",
- "/testing_path",
- NoSubProtocols(),
- "http://google.com",
- "",
+ CreateAndConnectStandard("ws://localhost/testing_path", "localhost",
+ "/testing_path", NoSubProtocols(),
+ "http://google.com", "",
"Sec-WebSocket-Protocol: chatv20.chromium.org\r\n");
RunUntilIdle();
EXPECT_FALSE(stream_);
@@ -572,12 +555,9 @@
TEST_F(WebSocketStreamCreateTest, UnacceptedSubProtocol) {
std::vector<std::string> sub_protocols;
sub_protocols.push_back("chat.example.com");
- CreateAndConnectStandard("ws://localhost/testing_path",
- "/testing_path",
- sub_protocols,
- "http://localhost",
- "Sec-WebSocket-Protocol: chat.example.com\r\n",
- "");
+ CreateAndConnectStandard("ws://localhost/testing_path", "localhost",
+ "/testing_path", sub_protocols, "http://localhost",
+ "Sec-WebSocket-Protocol: chat.example.com\r\n", "");
RunUntilIdle();
EXPECT_FALSE(stream_);
EXPECT_TRUE(has_failed());
@@ -592,10 +572,8 @@
std::vector<std::string> sub_protocols;
sub_protocols.push_back("chatv11.chromium.org");
sub_protocols.push_back("chatv20.chromium.org");
- CreateAndConnectStandard("ws://localhost/testing_path",
- "/testing_path",
- sub_protocols,
- "http://google.com",
+ CreateAndConnectStandard("ws://localhost/testing_path", "localhost",
+ "/testing_path", sub_protocols, "http://google.com",
"Sec-WebSocket-Protocol: chatv11.chromium.org, "
"chatv20.chromium.org\r\n",
"Sec-WebSocket-Protocol: chatv11.chromium.org, "
@@ -614,10 +592,8 @@
std::vector<std::string> sub_protocols;
sub_protocols.push_back("chatv11.chromium.org");
sub_protocols.push_back("chatv20.chromium.org");
- CreateAndConnectStandard("ws://localhost/testing_path",
- "/testing_path",
- sub_protocols,
- "http://google.com",
+ CreateAndConnectStandard("ws://localhost/testing_path", "localhost",
+ "/testing_path", sub_protocols, "http://google.com",
"Sec-WebSocket-Protocol: chatv11.chromium.org, "
"chatv20.chromium.org\r\n",
"Sec-WebSocket-Protocol: chatv21.chromium.org\r\n");
@@ -651,11 +627,8 @@
// permessage-deflate enabled.
TEST_F(WebSocketStreamCreateExtensionTest, PerMessageDeflateInflates) {
CreateAndConnectCustomResponse(
- "ws://localhost/testing_path",
- "/testing_path",
- NoSubProtocols(),
- "http://localhost",
- "",
+ "ws://localhost/testing_path", "localhost", "/testing_path",
+ NoSubProtocols(), "http://localhost", "",
WebSocketStandardResponse(
"Sec-WebSocket-Extensions: permessage-deflate\r\n") +
std::string(
@@ -837,12 +810,8 @@
// Additional Sec-WebSocket-Accept headers should be rejected.
TEST_F(WebSocketStreamCreateTest, DoubleAccept) {
CreateAndConnectStandard(
- "ws://localhost/",
- "/",
- NoSubProtocols(),
- "http://localhost",
- "",
- "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n");
+ "ws://localhost/", "localhost", "/", NoSubProtocols(), "http://localhost",
+ "", "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n");
RunUntilIdle();
EXPECT_FALSE(stream_);
EXPECT_TRUE(has_failed());
@@ -860,11 +829,8 @@
"Connection: Upgrade\r\n"
"Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n"
"\r\n";
- CreateAndConnectCustomResponse("ws://localhost/",
- "/",
- NoSubProtocols(),
- "http://localhost",
- "",
+ CreateAndConnectCustomResponse("ws://localhost/", "localhost", "/",
+ NoSubProtocols(), "http://localhost", "",
kInvalidStatusCodeResponse);
RunUntilIdle();
EXPECT_TRUE(has_failed());
@@ -883,11 +849,8 @@
"Location: ws://localhost/other\r\n"
"\r\n"
"<title>Moved</title><h1>Moved</h1>";
- CreateAndConnectCustomResponse("ws://localhost/",
- "/",
- NoSubProtocols(),
- "http://localhost",
- "",
+ CreateAndConnectCustomResponse("ws://localhost/", "localhost", "/",
+ NoSubProtocols(), "http://localhost", "",
kRedirectResponse);
RunUntilIdle();
EXPECT_TRUE(has_failed());
@@ -907,11 +870,8 @@
"Connection: Upgrade\r\n"
"Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n"
"\r\n";
- CreateAndConnectCustomResponse("ws://localhost/",
- "/",
- NoSubProtocols(),
- "http://localhost",
- "",
+ CreateAndConnectCustomResponse("ws://localhost/", "localhost", "/",
+ NoSubProtocols(), "http://localhost", "",
kMalformedResponse);
RunUntilIdle();
EXPECT_TRUE(has_failed());
@@ -926,11 +886,8 @@
"Connection: Upgrade\r\n"
"Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n"
"\r\n";
- CreateAndConnectCustomResponse("ws://localhost/",
- "/",
- NoSubProtocols(),
- "http://localhost",
- "",
+ CreateAndConnectCustomResponse("ws://localhost/", "localhost", "/",
+ NoSubProtocols(), "http://localhost", "",
kMissingUpgradeResponse);
RunUntilIdle();
EXPECT_TRUE(has_failed());
@@ -940,12 +897,9 @@
// There must only be one upgrade header.
TEST_F(WebSocketStreamCreateTest, DoubleUpgradeHeader) {
- CreateAndConnectStandard(
- "ws://localhost/",
- "/",
- NoSubProtocols(),
- "http://localhost",
- "", "Upgrade: HTTP/2.0\r\n");
+ CreateAndConnectStandard("ws://localhost/", "localhost", "/",
+ NoSubProtocols(), "http://localhost", "",
+ "Upgrade: HTTP/2.0\r\n");
RunUntilIdle();
EXPECT_TRUE(has_failed());
EXPECT_EQ("Error during WebSocket handshake: "
@@ -961,11 +915,8 @@
"Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n"
"Upgrade: hogefuga\r\n"
"\r\n";
- CreateAndConnectCustomResponse("ws://localhost/",
- "/",
- NoSubProtocols(),
- "http://localhost",
- "",
+ CreateAndConnectCustomResponse("ws://localhost/", "localhost", "/",
+ NoSubProtocols(), "http://localhost", "",
kMissingUpgradeResponse);
RunUntilIdle();
EXPECT_TRUE(has_failed());
@@ -981,11 +932,8 @@
"Upgrade: websocket\r\n"
"Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n"
"\r\n";
- CreateAndConnectCustomResponse("ws://localhost/",
- "/",
- NoSubProtocols(),
- "http://localhost",
- "",
+ CreateAndConnectCustomResponse("ws://localhost/", "localhost", "/",
+ NoSubProtocols(), "http://localhost", "",
kMissingConnectionResponse);
RunUntilIdle();
EXPECT_TRUE(has_failed());
@@ -1002,11 +950,8 @@
"Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n"
"Connection: hogefuga\r\n"
"\r\n";
- CreateAndConnectCustomResponse("ws://localhost/",
- "/",
- NoSubProtocols(),
- "http://localhost",
- "",
+ CreateAndConnectCustomResponse("ws://localhost/", "localhost", "/",
+ NoSubProtocols(), "http://localhost", "",
kMissingConnectionResponse);
RunUntilIdle();
EXPECT_TRUE(has_failed());
@@ -1023,11 +968,8 @@
"Connection: Upgrade, Keep-Alive\r\n"
"Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n"
"\r\n";
- CreateAndConnectCustomResponse("ws://localhost/",
- "/",
- NoSubProtocols(),
- "http://localhost",
- "",
+ CreateAndConnectCustomResponse("ws://localhost/", "localhost", "/",
+ NoSubProtocols(), "http://localhost", "",
kAdditionalConnectionTokenResponse);
RunUntilIdle();
EXPECT_FALSE(has_failed());
@@ -1041,11 +983,8 @@
"Upgrade: websocket\r\n"
"Connection: Upgrade\r\n"
"\r\n";
- CreateAndConnectCustomResponse("ws://localhost/",
- "/",
- NoSubProtocols(),
- "http://localhost",
- "",
+ CreateAndConnectCustomResponse("ws://localhost/", "localhost", "/",
+ NoSubProtocols(), "http://localhost", "",
kMissingAcceptResponse);
RunUntilIdle();
EXPECT_TRUE(has_failed());
@@ -1062,11 +1001,8 @@
"Connection: Upgrade\r\n"
"Sec-WebSocket-Accept: x/byyPZ2tOFvJCGkkugcKvqhhPk=\r\n"
"\r\n";
- CreateAndConnectCustomResponse("ws://localhost/",
- "/",
- NoSubProtocols(),
- "http://localhost",
- "",
+ CreateAndConnectCustomResponse("ws://localhost/", "localhost", "/",
+ NoSubProtocols(), "http://localhost", "",
kIncorrectAcceptResponse);
RunUntilIdle();
EXPECT_TRUE(has_failed());
@@ -1077,8 +1013,8 @@
// Cancellation works.
TEST_F(WebSocketStreamCreateTest, Cancellation) {
- CreateAndConnectStandard(
- "ws://localhost/", "/", NoSubProtocols(), "http://localhost", "", "");
+ CreateAndConnectStandard("ws://localhost/", "localhost", "/",
+ NoSubProtocols(), "http://localhost", "", "");
stream_request_.reset();
RunUntilIdle();
EXPECT_FALSE(has_failed());
@@ -1144,12 +1080,8 @@
scoped_ptr<MockWeakTimer> timer(new MockWeakTimer(false, false));
base::WeakPtr<MockWeakTimer> weak_timer = timer->AsWeakPtr();
- CreateAndConnectStandard("ws://localhost/",
- "/",
- NoSubProtocols(),
- "http://localhost",
- "",
- "",
+ CreateAndConnectStandard("ws://localhost/", "localhost", "/",
+ NoSubProtocols(), "http://localhost", "", "",
timer.Pass());
ASSERT_TRUE(weak_timer);
EXPECT_TRUE(weak_timer->IsRunning());
@@ -1223,7 +1155,8 @@
// Cancellation during read of the response headers works.
TEST_F(WebSocketStreamCreateTest, CancellationDuringRead) {
- std::string request = WebSocketStandardRequest("/", "http://localhost", "");
+ std::string request =
+ WebSocketStandardRequest("/", "localhost", "http://localhost", "");
MockWrite writes[] = {MockWrite(ASYNC, 0, request.c_str())};
MockRead reads[] = {
MockRead(ASYNC, 1, "HTTP/1.1 101 Switching Protocols\r\nUpgr"),
@@ -1255,8 +1188,9 @@
set_cookie_headers +=
base::StringPrintf("Set-Cookie: WK-websocket-test-flood-%d=1\r\n", i);
}
- CreateAndConnectStandard("ws://localhost/", "/", NoSubProtocols(),
- "http://localhost", "", set_cookie_headers);
+ CreateAndConnectStandard("ws://localhost/", "localhost", "/",
+ NoSubProtocols(), "http://localhost", "",
+ set_cookie_headers);
RunUntilIdle();
EXPECT_TRUE(has_failed());
EXPECT_FALSE(response_info_);
@@ -1266,7 +1200,8 @@
// log the console message "Connection closed before receiving a handshake
// response".
TEST_F(WebSocketStreamCreateTest, NoResponse) {
- std::string request = WebSocketStandardRequest("/", "http://localhost", "");
+ std::string request =
+ WebSocketStandardRequest("/", "localhost", "http://localhost", "");
MockWrite writes[] = {MockWrite(ASYNC, request.data(), request.size(), 0)};
MockRead reads[] = {MockRead(ASYNC, 0, 1)};
scoped_ptr<DeterministicSocketData> socket_data(
@@ -1314,8 +1249,8 @@
ssl_data.reset(new SSLSocketDataProvider(ASYNC, OK));
ssl_data_.push_back(ssl_data.release());
url_request_context_host_.AddRawExpectations(BuildNullSocketData());
- CreateAndConnectStandard(
- "wss://localhost/", "/", NoSubProtocols(), "http://localhost", "", "");
+ CreateAndConnectStandard("wss://localhost/", "localhost", "/",
+ NoSubProtocols(), "http://localhost", "", "");
RunUntilIdle();
ASSERT_TRUE(ssl_error_callbacks_);
ssl_error_callbacks_->ContinueSSLRequest();
@@ -1327,11 +1262,8 @@
// If the server requests authorisation, but we have no credentials, the
// connection should fail cleanly.
TEST_F(WebSocketStreamCreateBasicAuthTest, FailureNoCredentials) {
- CreateAndConnectCustomResponse("ws://localhost/",
- "/",
- NoSubProtocols(),
- "http://localhost",
- "",
+ CreateAndConnectCustomResponse("ws://localhost/", "localhost", "/",
+ NoSubProtocols(), "http://localhost", "",
kUnauthorizedResponse);
RunUntilIdle();
EXPECT_TRUE(has_failed());
@@ -1384,12 +1316,9 @@
{
StreamCreation creation;
- creation.CreateAndConnectStandard("ws://localhost/",
- "/",
+ creation.CreateAndConnectStandard("ws://localhost/", "localhost", "/",
creation.NoSubProtocols(),
- "http://localhost",
- "",
- "");
+ "http://localhost", "", "");
}
scoped_ptr<base::HistogramSamples> samples(GetSamples(name));
@@ -1408,12 +1337,9 @@
{
StreamCreation creation;
- creation.CreateAndConnectStandard("ws://localhost/",
- "/",
+ creation.CreateAndConnectStandard("ws://localhost/", "localhost", "/",
creation.NoSubProtocols(),
- "http://localhost",
- "",
- "");
+ "http://localhost", "", "");
creation.RunUntilIdle();
}
@@ -1439,12 +1365,9 @@
"Connection: Upgrade\r\n"
"Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n"
"\r\n";
- creation.CreateAndConnectCustomResponse("ws://localhost/",
- "/",
- creation.NoSubProtocols(),
- "http://localhost",
- "",
- kInvalidStatusCodeResponse);
+ creation.CreateAndConnectCustomResponse(
+ "ws://localhost/", "localhost", "/", creation.NoSubProtocols(),
+ "http://localhost", "", kInvalidStatusCodeResponse);
creation.RunUntilIdle();
}
diff --git a/net/websockets/websocket_test_util.cc b/net/websockets/websocket_test_util.cc
index 65613b5..6091c9e 100644
--- a/net/websockets/websocket_test_util.cc
+++ b/net/websockets/websocket_test_util.cc
@@ -33,6 +33,7 @@
}
std::string WebSocketStandardRequest(const std::string& path,
+ const std::string& host,
const std::string& origin,
const std::string& extra_headers) {
// Unrelated changes in net/http may change the order and default-values of
@@ -40,7 +41,7 @@
// string in that case.
return base::StringPrintf(
"GET %s HTTP/1.1\r\n"
- "Host: localhost\r\n"
+ "Host: %s\r\n"
"Connection: Upgrade\r\n"
"Pragma: no-cache\r\n"
"Cache-Control: no-cache\r\n"
@@ -53,9 +54,7 @@
"Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
"Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits\r\n"
"%s\r\n",
- path.c_str(),
- origin.c_str(),
- extra_headers.c_str());
+ path.c_str(), host.c_str(), origin.c_str(), extra_headers.c_str());
}
std::string WebSocketStandardResponse(const std::string& extra_headers) {
diff --git a/net/websockets/websocket_test_util.h b/net/websockets/websocket_test_util.h
index 803c9be..5c7db80 100644
--- a/net/websockets/websocket_test_util.h
+++ b/net/websockets/websocket_test_util.h
@@ -58,6 +58,7 @@
// "dGhlIHNhbXBsZSBub25jZQ==". Each header in |extra_headers| must be terminated
// with "\r\n".
extern std::string WebSocketStandardRequest(const std::string& path,
+ const std::string& host,
const std::string& origin,
const std::string& extra_headers);
diff --git a/sandbox/linux/services/credentials.cc b/sandbox/linux/services/credentials.cc
index 274ae28..291c2ca 100644
--- a/sandbox/linux/services/credentials.cc
+++ b/sandbox/linux/services/credentials.cc
@@ -19,7 +19,7 @@
#include "base/files/file_util.h"
#include "base/logging.h"
#include "base/posix/eintr_wrapper.h"
-#include "base/process/process.h"
+#include "base/process/launch.h"
#include "base/template_util.h"
#include "base/third_party/valgrind/valgrind.h"
#include "sandbox/linux/services/syscall_wrappers.h"
diff --git a/skia/config/SkUserConfig.h b/skia/config/SkUserConfig.h
index f86a1f7..358fb13 100644
--- a/skia/config/SkUserConfig.h
+++ b/skia/config/SkUserConfig.h
@@ -283,10 +283,6 @@
# define SK_SUPPORT_LEGACY_ADDRRECT
#endif
-#ifndef SK_IGNORE_GPU_LAYER_HOISTING
-# define SK_IGNORE_GPU_LAYER_HOISTING
-#endif
-
// If this goes well, we can have Skia respect DYNAMIC_ANNOTATIONS_ENABLED directly.
#if DYNAMIC_ANNOTATIONS_ENABLED
# define SK_DYNAMIC_ANNOTATIONS_ENABLED 1
diff --git a/sky/engine/bindings/core/v8/WindowProxy.cpp b/sky/engine/bindings/core/v8/WindowProxy.cpp
index 95d290c..626c184 100644
--- a/sky/engine/bindings/core/v8/WindowProxy.cpp
+++ b/sky/engine/bindings/core/v8/WindowProxy.cpp
@@ -109,11 +109,6 @@
m_document.clear();
- // Clear the document wrapper cache before turning on access checks on
- // the old LocalDOMWindow wrapper. This way, access to the document wrapper
- // will be protected by the security checks on the LocalDOMWindow wrapper.
- clearDocumentProperty();
-
v8::Handle<v8::Object> windowWrapper = V8Window::findInstanceInPrototypeChain(m_global.newLocal(m_isolate), m_isolate);
ASSERT(!windowWrapper.IsEmpty());
windowWrapper->TurnOnAccessCheck();
@@ -288,12 +283,6 @@
if (m_document.isEmpty())
updateDocumentWrapper(v8::Handle<v8::Object>::Cast(documentWrapper));
- // If instantiation of the document wrapper fails, clear the cache
- // and let the LocalDOMWindow accessor handle access to the document.
- if (documentWrapper.IsEmpty()) {
- clearDocumentProperty();
- return;
- }
ASSERT(documentWrapper->IsObject());
context->Global()->ForceSet(v8AtomicString(m_isolate, "document"), documentWrapper, static_cast<v8::PropertyAttribute>(v8::ReadOnly | v8::DontDelete));
@@ -303,15 +292,6 @@
V8HiddenValue::setHiddenValue(m_isolate, toInnerGlobalObject(context), V8HiddenValue::document(m_isolate), documentWrapper);
}
-void WindowProxy::clearDocumentProperty()
-{
- ASSERT(isContextInitialized());
- if (!m_world->isMainWorld())
- return;
- v8::HandleScope handleScope(m_isolate);
- m_scriptState->context()->Global()->ForceDelete(v8AtomicString(m_isolate, "document"));
-}
-
void WindowProxy::updateDocument()
{
ASSERT(m_world->isMainWorld());
diff --git a/sky/engine/bindings/core/v8/WindowProxy.h b/sky/engine/bindings/core/v8/WindowProxy.h
index 68e7123..f6a24fe 100644
--- a/sky/engine/bindings/core/v8/WindowProxy.h
+++ b/sky/engine/bindings/core/v8/WindowProxy.h
@@ -84,10 +84,8 @@
// The JavaScript wrapper for the document object is cached on the global
// object for fast access. UpdateDocumentProperty sets the wrapper
- // for the current document on the global object. ClearDocumentProperty
- // deletes the document wrapper from the global object.
+ // for the current document on the global object.
void updateDocumentProperty();
- void clearDocumentProperty();
void createContext();
bool installDOMWindow();
diff --git a/sky/engine/platform/fonts/skia/FontCustomPlatformDataSkia.cpp b/sky/engine/platform/fonts/skia/FontCustomPlatformDataSkia.cpp
index c675bc0..dd04343 100644
--- a/sky/engine/platform/fonts/skia/FontCustomPlatformDataSkia.cpp
+++ b/sky/engine/platform/fonts/skia/FontCustomPlatformDataSkia.cpp
@@ -69,8 +69,8 @@
return nullptr; // validation failed.
buffer = transcodeBuffer.get();
- RefPtr<SkMemoryStream> stream = adoptRef(new SkMemoryStream(buffer->getAsSkData().get()));
- RefPtr<SkTypeface> typeface = adoptRef(SkTypeface::CreateFromStream(stream.get()));
+ SkMemoryStream* stream = new SkMemoryStream(buffer->getAsSkData().get());
+ RefPtr<SkTypeface> typeface = adoptRef(SkTypeface::CreateFromStream(stream));
if (!typeface)
return nullptr;
diff --git a/sky/viewer/document_view.cc b/sky/viewer/document_view.cc
index 8125379..e710209 100644
--- a/sky/viewer/document_view.cc
+++ b/sky/viewer/document_view.cc
@@ -127,7 +127,9 @@
// assuming that we're focused.
web_view_->setFocus(true);
// Needed on android, as the window does not get the focus otherwise.
+#if defined(OS_ANDROID)
root_->SetFocus();
+#endif
root_->AddObserver(this);
}
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json
index 4da8bc0..e30787f 100644
--- a/testing/buildbot/chromium.fyi.json
+++ b/testing/buildbot/chromium.fyi.json
@@ -386,9 +386,337 @@
"sbox_validation_tests",
"ipc_tests",
"sync_unit_tests",
+ "skia_unit_tests",
"unit_tests",
"sql_unittests",
"ui_base_unittests",
+ "content_unittests",
+ "views_unittests",
+ "browser_tests",
+ {
+ "test": "content_browsertests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
+ "installer_util_unittests"
+ ]
+ },
+ "CrWinClang(dbg) tester": {
+ "gtest_tests": [
+ {
+ "test": "base_unittests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
+ "cacheinvalidation_unittests",
+ "chrome_elf_unittests",
+ "components_unittests",
+ "courgette_unittests",
+ "crypto_unittests",
+ "extensions_unittests",
+ "gcm_unit_tests",
+ "google_apis_unittests",
+ "gpu_unittests",
+ "url_unittests",
+ "jingle_unittests",
+ "content_unittests",
+ "device_unittests",
+ "media_unittests",
+ "net_unittests",
+ "ppapi_unittests",
+ "printing_unittests",
+ "remoting_unittests",
+ "sbox_unittests",
+ "sbox_integration_tests",
+ "sbox_validation_tests",
+ "ipc_tests",
+ "sync_unit_tests",
+ "skia_unit_tests",
+ "unit_tests",
+ "sql_unittests",
+ "ui_base_unittests",
+ "content_unittests",
+ "views_unittests",
+ "browser_tests",
+ {
+ "test": "content_browsertests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
+ "installer_util_unittests"
+ ]
+ },
+ "CrWinClang(shared) tester": {
+ "gtest_tests": [
+ {
+ "test": "base_unittests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
+ "cacheinvalidation_unittests",
+ "chrome_elf_unittests",
+ "components_unittests",
+ "courgette_unittests",
+ "crypto_unittests",
+ "extensions_unittests",
+ "gcm_unit_tests",
+ "google_apis_unittests",
+ "gpu_unittests",
+ "url_unittests",
+ "jingle_unittests",
+ "content_unittests",
+ "device_unittests",
+ "media_unittests",
+ "net_unittests",
+ "ppapi_unittests",
+ "printing_unittests",
+ "remoting_unittests",
+ "sbox_unittests",
+ "sbox_integration_tests",
+ "sbox_validation_tests",
+ "ipc_tests",
+ "sync_unit_tests",
+ "skia_unit_tests",
+ "unit_tests",
+ "sql_unittests",
+ "ui_base_unittests",
+ "content_unittests",
+ "views_unittests",
+ "browser_tests",
+ {
+ "test": "content_browsertests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
+ "installer_util_unittests"
+ ]
+ },
+ "CrWinClang64 tester": {
+ "gtest_tests": [
+ {
+ "test": "base_unittests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
+ "cacheinvalidation_unittests",
+ "chrome_elf_unittests",
+ "components_unittests",
+ "courgette_unittests",
+ "crypto_unittests",
+ "extensions_unittests",
+ "gcm_unit_tests",
+ "google_apis_unittests",
+ "gpu_unittests",
+ "url_unittests",
+ "jingle_unittests",
+ "content_unittests",
+ "device_unittests",
+ "media_unittests",
+ "net_unittests",
+ "ppapi_unittests",
+ "printing_unittests",
+ "remoting_unittests",
+ "sbox_unittests",
+ "sbox_integration_tests",
+ "sbox_validation_tests",
+ "ipc_tests",
+ "sync_unit_tests",
+ "skia_unit_tests",
+ "unit_tests",
+ "sql_unittests",
+ "ui_base_unittests",
+ "content_unittests",
+ "views_unittests",
+ "browser_tests",
+ {
+ "test": "content_browsertests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
+ "installer_util_unittests"
+ ]
+ },
+ "CrWinClang64(dbg) tester": {
+ "gtest_tests": [
+ {
+ "test": "base_unittests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
+ "cacheinvalidation_unittests",
+ "chrome_elf_unittests",
+ "components_unittests",
+ "courgette_unittests",
+ "crypto_unittests",
+ "extensions_unittests",
+ "gcm_unit_tests",
+ "google_apis_unittests",
+ "gpu_unittests",
+ "url_unittests",
+ "jingle_unittests",
+ "content_unittests",
+ "device_unittests",
+ "media_unittests",
+ "net_unittests",
+ "ppapi_unittests",
+ "printing_unittests",
+ "remoting_unittests",
+ "sbox_unittests",
+ "sbox_integration_tests",
+ "sbox_validation_tests",
+ "ipc_tests",
+ "sync_unit_tests",
+ "skia_unit_tests",
+ "unit_tests",
+ "sql_unittests",
+ "ui_base_unittests",
+ "content_unittests",
+ "views_unittests",
+ "browser_tests",
+ {
+ "test": "content_browsertests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
+ "installer_util_unittests"
+ ]
+ },
+ "CrWinClang64(dll) tester": {
+ "gtest_tests": [
+ {
+ "test": "base_unittests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
+ "cacheinvalidation_unittests",
+ "chrome_elf_unittests",
+ "components_unittests",
+ "courgette_unittests",
+ "crypto_unittests",
+ "extensions_unittests",
+ "gcm_unit_tests",
+ "google_apis_unittests",
+ "gpu_unittests",
+ "url_unittests",
+ "jingle_unittests",
+ "content_unittests",
+ "device_unittests",
+ "media_unittests",
+ "net_unittests",
+ "ppapi_unittests",
+ "printing_unittests",
+ "remoting_unittests",
+ "sbox_unittests",
+ "sbox_integration_tests",
+ "sbox_validation_tests",
+ "ipc_tests",
+ "sync_unit_tests",
+ "skia_unit_tests",
+ "unit_tests",
+ "sql_unittests",
+ "ui_base_unittests",
+ "content_unittests",
+ "views_unittests",
+ "browser_tests",
+ {
+ "test": "content_browsertests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
+ "installer_util_unittests"
+ ]
+ },
+ "CrWinClangLLD tester": {
+ "gtest_tests": [
+ {
+ "test": "base_unittests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
+ "cacheinvalidation_unittests",
+ "chrome_elf_unittests",
+ "components_unittests",
+ "courgette_unittests",
+ "crypto_unittests",
+ "extensions_unittests",
+ "gcm_unit_tests",
+ "google_apis_unittests",
+ "gpu_unittests",
+ "url_unittests",
+ "jingle_unittests",
+ "content_unittests",
+ "device_unittests",
+ "media_unittests",
+ "net_unittests",
+ "ppapi_unittests",
+ "printing_unittests",
+ "remoting_unittests",
+ "sbox_unittests",
+ "sbox_integration_tests",
+ "sbox_validation_tests",
+ "ipc_tests",
+ "sync_unit_tests",
+ "skia_unit_tests",
+ "unit_tests",
+ "sql_unittests",
+ "ui_base_unittests",
+ "content_unittests",
+ "views_unittests",
+ "browser_tests",
+ {
+ "test": "content_browsertests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
+ "installer_util_unittests"
+ ]
+ },
+ "CrWinClang64(asan) tester": {
+ "gtest_tests": [
+ {
+ "test": "base_unittests",
+ "swarming": {
+ "can_use_on_swarming_builders": true
+ }
+ },
+ "cacheinvalidation_unittests",
+ "chrome_elf_unittests",
+ "components_unittests",
+ "courgette_unittests",
+ "crypto_unittests",
+ "extensions_unittests",
+ "gcm_unit_tests",
+ "google_apis_unittests",
+ "gpu_unittests",
+ "url_unittests",
+ "jingle_unittests",
+ "content_unittests",
+ "device_unittests",
+ "media_unittests",
+ "net_unittests",
+ "ppapi_unittests",
+ "printing_unittests",
+ "remoting_unittests",
+ "ipc_tests",
+ "sync_unit_tests",
+ "skia_unit_tests",
+ "unit_tests",
+ "sql_unittests",
+ "ui_base_unittests",
+ "content_unittests",
"views_unittests",
"browser_tests",
{
diff --git a/testing/test.gni b/testing/test.gni
index 9362a78..3afb9f7 100644
--- a/testing/test.gni
+++ b/testing/test.gni
@@ -126,6 +126,9 @@
if (defined(invoker.apk_deps)) {
deps += invoker.apk_deps
}
+ if (defined(invoker.apk_asset_location)) {
+ asset_location = invoker.apk_asset_location
+ }
}
group(target_name) {
diff --git a/tools/valgrind/gtest_exclude/cc_unittests.gtest-drmemory_win32.txt b/tools/valgrind/gtest_exclude/cc_unittests.gtest-drmemory_win32.txt
index 2a84488..bdc0e84 100644
--- a/tools/valgrind/gtest_exclude/cc_unittests.gtest-drmemory_win32.txt
+++ b/tools/valgrind/gtest_exclude/cc_unittests.gtest-drmemory_win32.txt
@@ -26,6 +26,3 @@
PixelResourceTest/LayerTreeHostMasksPixelTest.MaskOfReplica/6
PixelResourceTest/LayerTreeHostMasksPixelTest.MaskOfReplicaOfClippedLayer/5
PixelResourceTest/LayerTreeHostMasksPixelTest.MaskOfReplicaOfClippedLayer/6
-
-# http://crbug.com/450216
-LayerTreeHostAnimationTestScrollOffsetAnimationRemoval.*_ImplSidePaint
diff --git a/ui/gl/gl_image_memory.cc b/ui/gl/gl_image_memory.cc
index 0a67e00..5e23d30 100644
--- a/ui/gl/gl_image_memory.cc
+++ b/ui/gl/gl_image_memory.cc
@@ -100,18 +100,26 @@
}
// static
-size_t GLImageMemory::BytesPerPixel(gfx::GpuMemoryBuffer::Format format) {
+bool GLImageMemory::StrideInBytes(size_t width,
+ gfx::GpuMemoryBuffer::Format format,
+ size_t* stride_in_bytes) {
+ base::CheckedNumeric<size_t> s = width;
switch (format) {
case gfx::GpuMemoryBuffer::RGBA_8888:
case gfx::GpuMemoryBuffer::BGRA_8888:
- return 4;
+ s *= 4;
+ if (!s.IsValid())
+ return false;
+
+ *stride_in_bytes = s.ValueOrDie();
+ return true;
case gfx::GpuMemoryBuffer::RGBX_8888:
NOTREACHED();
- return 0;
+ return false;
}
NOTREACHED();
- return 0;
+ return false;
}
bool GLImageMemory::Initialize(const unsigned char* memory,
diff --git a/ui/gl/gl_image_memory.h b/ui/gl/gl_image_memory.h
index fd659e7..a50a380 100644
--- a/ui/gl/gl_image_memory.h
+++ b/ui/gl/gl_image_memory.h
@@ -13,6 +13,7 @@
#include <EGL/eglext.h>
#endif
+#include "base/numerics/safe_math.h"
#include "ui/gfx/gpu_memory_buffer.h"
namespace gfx {
@@ -21,7 +22,9 @@
public:
GLImageMemory(const gfx::Size& size, unsigned internalformat);
- static size_t BytesPerPixel(gfx::GpuMemoryBuffer::Format format);
+ static bool StrideInBytes(size_t width,
+ gfx::GpuMemoryBuffer::Format format,
+ size_t* stride_in_bytes);
bool Initialize(const unsigned char* memory,
gfx::GpuMemoryBuffer::Format format);
diff --git a/ui/gl/gl_image_shared_memory.cc b/ui/gl/gl_image_shared_memory.cc
index 0bbf549..d9e31a7 100644
--- a/ui/gl/gl_image_shared_memory.cc
+++ b/ui/gl/gl_image_shared_memory.cc
@@ -17,8 +17,11 @@
size_t* size_in_bytes) {
if (size.IsEmpty())
return false;
- base::CheckedNumeric<size_t> s = GLImageMemory::BytesPerPixel(format);
- s *= size.width();
+
+ size_t stride_in_bytes = 0;
+ if (!GLImageMemory::StrideInBytes(size.width(), format, &stride_in_bytes))
+ return false;
+ base::CheckedNumeric<size_t> s = stride_in_bytes;
s *= size.height();
if (!s.IsValid())
return false;