diff options
122 files changed, 3011 insertions, 2107 deletions
diff --git a/cmake/core-files.txt b/cmake/core-files.txt index 0bfded8db8..a1e43d2357 100644 --- a/cmake/core-files.txt +++ b/cmake/core-files.txt @@ -97,6 +97,7 @@ src/mbgl/layout/clip_lines.cpp src/mbgl/layout/clip_lines.hpp src/mbgl/layout/merge_lines.cpp src/mbgl/layout/merge_lines.hpp +src/mbgl/layout/pattern_layout.hpp src/mbgl/layout/symbol_feature.hpp src/mbgl/layout/symbol_instance.cpp src/mbgl/layout/symbol_instance.hpp diff --git a/include/mbgl/util/indexed_tuple.hpp b/include/mbgl/util/indexed_tuple.hpp index cd8c0fecbb..d1a9e226b1 100644 --- a/include/mbgl/util/indexed_tuple.hpp +++ b/include/mbgl/util/indexed_tuple.hpp @@ -28,8 +28,6 @@ class IndexedTuple<TypeList<Is...>, TypeList<Ts...>> : public tuple_polyfill<Ts. public: static_assert(sizeof...(Is) == sizeof...(Ts), "IndexedTuple size mismatch"); - using tuple_polyfill<Ts...>::tuple; - template <class I> auto& get() { return get_polyfill<TypeIndex<I, Is...>::value>(*this); @@ -40,6 +38,9 @@ public: return get_polyfill<TypeIndex<I, Is...>::value>(*this); } + template <class... Us> + IndexedTuple(Us&&... other) : tuple_polyfill<Ts...>(std::forward<Us>(other)...) {} + template <class... Js, class... Us> IndexedTuple<TypeList<Is..., Js...>, TypeList<Ts..., Us...>> concat(const IndexedTuple<TypeList<Js...>, TypeList<Us...>>& other) const { diff --git a/mapbox-gl-js b/mapbox-gl-js -Subproject 754ec0bf51c3798d096aa38c3f009dcb58d3be7 +Subproject 53e622b475b7c9cb26b98d18e3fbd61d27b183a diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/FillExtrusionLayerTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/FillExtrusionLayerTest.java index 84b3e7bd68..ed509ccf4f 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/FillExtrusionLayerTest.java +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/FillExtrusionLayerTest.java @@ -266,6 +266,22 @@ public class FillExtrusionLayerTest extends BaseActivityTest { } @Test + public void testFillExtrusionPatternAsExpression() { + validateTestSetup(); + setupLayer(); + Timber.i("fill-extrusion-pattern-expression"); + invoke(mapboxMap, (uiController, mapboxMap) -> { + assertNotNull(layer); + + // Set and Get + Expression expression = string(Expression.get("undefined")); + layer.setProperties(fillExtrusionPattern(expression)); + assertEquals(layer.getFillExtrusionPattern().getExpression(), expression); + }); + } + + + @Test public void testFillExtrusionHeightTransition() { validateTestSetup(); setupLayer(); diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/FillLayerTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/FillLayerTest.java index 3e1cbf666d..0bcdae4113 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/FillLayerTest.java +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/FillLayerTest.java @@ -353,4 +353,20 @@ public class FillLayerTest extends BaseActivityTest { assertEquals((String) layer.getFillPattern().getValue(), (String) "pedestrian-polygon"); }); } + + @Test + public void testFillPatternAsExpression() { + validateTestSetup(); + setupLayer(); + Timber.i("fill-pattern-expression"); + invoke(mapboxMap, (uiController, mapboxMap) -> { + assertNotNull(layer); + + // Set and Get + Expression expression = string(Expression.get("undefined")); + layer.setProperties(fillPattern(expression)); + assertEquals(layer.getFillPattern().getExpression(), expression); + }); + } + } diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/LineLayerTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/LineLayerTest.java index e35f0edcc4..792dd84466 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/LineLayerTest.java +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/LineLayerTest.java @@ -545,4 +545,20 @@ public class LineLayerTest extends BaseActivityTest { assertEquals((String) layer.getLinePattern().getValue(), (String) "pedestrian-polygon"); }); } + + @Test + public void testLinePatternAsExpression() { + validateTestSetup(); + setupLayer(); + Timber.i("line-pattern-expression"); + invoke(mapboxMap, (uiController, mapboxMap) -> { + assertNotNull(layer); + + // Set and Get + Expression expression = string(Expression.get("undefined")); + layer.setProperties(linePattern(expression)); + assertEquals(layer.getLinePattern().getExpression(), expression); + }); + } + } diff --git a/platform/darwin/src/MGLFillExtrusionStyleLayer.h b/platform/darwin/src/MGLFillExtrusionStyleLayer.h index bca2a99f1e..99b3d3ffaf 100644 --- a/platform/darwin/src/MGLFillExtrusionStyleLayer.h +++ b/platform/darwin/src/MGLFillExtrusionStyleLayer.h @@ -222,11 +222,8 @@ MGL_EXPORT * Predefined functions, including mathematical and string operators * Conditional expressions * Variable assignments and references to assigned variables - * Step functions applied to the `$zoomLevel` variable - - This property does not support applying interpolation functions to the - `$zoomLevel` variable or applying interpolation or step functions to feature - attributes. + * Interpolation and step functions applied to the `$zoomLevel` variable and/or + feature attributes */ @property (nonatomic, null_resettable) NSExpression *fillExtrusionPattern; diff --git a/platform/darwin/src/MGLFillExtrusionStyleLayer.mm b/platform/darwin/src/MGLFillExtrusionStyleLayer.mm index 1b7896be9f..570b83b854 100644 --- a/platform/darwin/src/MGLFillExtrusionStyleLayer.mm +++ b/platform/darwin/src/MGLFillExtrusionStyleLayer.mm @@ -220,7 +220,7 @@ namespace mbgl { - (void)setFillExtrusionPattern:(NSExpression *)fillExtrusionPattern { MGLAssertStyleLayerIsValid(); - auto mbglValue = MGLStyleValueTransformer<std::string, NSString *>().toPropertyValue<mbgl::style::PropertyValue<std::string>>(fillExtrusionPattern, false); + auto mbglValue = MGLStyleValueTransformer<std::string, NSString *>().toPropertyValue<mbgl::style::PropertyValue<std::string>>(fillExtrusionPattern, true); self.rawLayer->setFillExtrusionPattern(mbglValue); } diff --git a/platform/darwin/src/MGLFillStyleLayer.h b/platform/darwin/src/MGLFillStyleLayer.h index af82482c62..eadf57222b 100644 --- a/platform/darwin/src/MGLFillStyleLayer.h +++ b/platform/darwin/src/MGLFillStyleLayer.h @@ -227,11 +227,8 @@ MGL_EXPORT * Predefined functions, including mathematical and string operators * Conditional expressions * Variable assignments and references to assigned variables - * Step functions applied to the `$zoomLevel` variable - - This property does not support applying interpolation functions to the - `$zoomLevel` variable or applying interpolation or step functions to feature - attributes. + * Interpolation and step functions applied to the `$zoomLevel` variable and/or + feature attributes */ @property (nonatomic, null_resettable) NSExpression *fillPattern; diff --git a/platform/darwin/src/MGLFillStyleLayer.mm b/platform/darwin/src/MGLFillStyleLayer.mm index 7c36f7989b..bb8c7fc1f2 100644 --- a/platform/darwin/src/MGLFillStyleLayer.mm +++ b/platform/darwin/src/MGLFillStyleLayer.mm @@ -209,7 +209,7 @@ namespace mbgl { - (void)setFillPattern:(NSExpression *)fillPattern { MGLAssertStyleLayerIsValid(); - auto mbglValue = MGLStyleValueTransformer<std::string, NSString *>().toPropertyValue<mbgl::style::PropertyValue<std::string>>(fillPattern, false); + auto mbglValue = MGLStyleValueTransformer<std::string, NSString *>().toPropertyValue<mbgl::style::PropertyValue<std::string>>(fillPattern, true); self.rawLayer->setFillPattern(mbglValue); } diff --git a/platform/darwin/src/MGLLineStyleLayer.h b/platform/darwin/src/MGLLineStyleLayer.h index a7ac7f1462..28bb286049 100644 --- a/platform/darwin/src/MGLLineStyleLayer.h +++ b/platform/darwin/src/MGLLineStyleLayer.h @@ -473,11 +473,8 @@ MGL_EXPORT * Predefined functions, including mathematical and string operators * Conditional expressions * Variable assignments and references to assigned variables - * Step functions applied to the `$zoomLevel` variable - - This property does not support applying interpolation functions to the - `$zoomLevel` variable or applying interpolation or step functions to feature - attributes. + * Interpolation and step functions applied to the `$zoomLevel` variable and/or + feature attributes */ @property (nonatomic, null_resettable) NSExpression *linePattern; diff --git a/platform/darwin/src/MGLLineStyleLayer.mm b/platform/darwin/src/MGLLineStyleLayer.mm index 5cf0762475..0f749f90af 100644 --- a/platform/darwin/src/MGLLineStyleLayer.mm +++ b/platform/darwin/src/MGLLineStyleLayer.mm @@ -396,7 +396,7 @@ namespace mbgl { - (void)setLinePattern:(NSExpression *)linePattern { MGLAssertStyleLayerIsValid(); - auto mbglValue = MGLStyleValueTransformer<std::string, NSString *>().toPropertyValue<mbgl::style::PropertyValue<std::string>>(linePattern, false); + auto mbglValue = MGLStyleValueTransformer<std::string, NSString *>().toPropertyValue<mbgl::style::PropertyValue<std::string>>(linePattern, true); self.rawLayer->setLinePattern(mbglValue); } diff --git a/platform/darwin/test/MGLFillExtrusionStyleLayerTests.mm b/platform/darwin/test/MGLFillExtrusionStyleLayerTests.mm index 54808f6b3c..eddf82eec8 100644 --- a/platform/darwin/test/MGLFillExtrusionStyleLayerTests.mm +++ b/platform/darwin/test/MGLFillExtrusionStyleLayerTests.mm @@ -372,12 +372,6 @@ @"Unsetting fillExtrusionPattern should return fill-extrusion-pattern to the default value."); XCTAssertEqualObjects(layer.fillExtrusionPattern, defaultExpression, @"fillExtrusionPattern should return the default value after being unset."); - - functionExpression = [NSExpression expressionForKeyPath:@"bogus"]; - XCTAssertThrowsSpecificNamed(layer.fillExtrusionPattern = functionExpression, NSException, NSInvalidArgumentException, @"MGLFillExtrusionLayer should raise an exception if a camera-data expression is applied to a property that does not support key paths to feature attributes."); - functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:(bogus, %@, %@)", constantExpression, @{@18: constantExpression}]; - functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: functionExpression}]; - XCTAssertThrowsSpecificNamed(layer.fillExtrusionPattern = functionExpression, NSException, NSInvalidArgumentException, @"MGLFillExtrusionLayer should raise an exception if a camera-data expression is applied to a property that does not support key paths to feature attributes."); // Transition property test layer.fillExtrusionPatternTransition = transitionTest; auto toptions = rawLayer->getFillExtrusionPatternTransition(); diff --git a/platform/darwin/test/MGLFillStyleLayerTests.mm b/platform/darwin/test/MGLFillStyleLayerTests.mm index 41ee820918..bae8779309 100644 --- a/platform/darwin/test/MGLFillStyleLayerTests.mm +++ b/platform/darwin/test/MGLFillStyleLayerTests.mm @@ -363,12 +363,6 @@ @"Unsetting fillPattern should return fill-pattern to the default value."); XCTAssertEqualObjects(layer.fillPattern, defaultExpression, @"fillPattern should return the default value after being unset."); - - functionExpression = [NSExpression expressionForKeyPath:@"bogus"]; - XCTAssertThrowsSpecificNamed(layer.fillPattern = functionExpression, NSException, NSInvalidArgumentException, @"MGLFillLayer should raise an exception if a camera-data expression is applied to a property that does not support key paths to feature attributes."); - functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:(bogus, %@, %@)", constantExpression, @{@18: constantExpression}]; - functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: functionExpression}]; - XCTAssertThrowsSpecificNamed(layer.fillPattern = functionExpression, NSException, NSInvalidArgumentException, @"MGLFillLayer should raise an exception if a camera-data expression is applied to a property that does not support key paths to feature attributes."); // Transition property test layer.fillPatternTransition = transitionTest; auto toptions = rawLayer->getFillPatternTransition(); diff --git a/platform/darwin/test/MGLLineStyleLayerTests.mm b/platform/darwin/test/MGLLineStyleLayerTests.mm index 4c0f91ba3b..7289debb94 100644 --- a/platform/darwin/test/MGLLineStyleLayerTests.mm +++ b/platform/darwin/test/MGLLineStyleLayerTests.mm @@ -689,12 +689,6 @@ @"Unsetting linePattern should return line-pattern to the default value."); XCTAssertEqualObjects(layer.linePattern, defaultExpression, @"linePattern should return the default value after being unset."); - - functionExpression = [NSExpression expressionForKeyPath:@"bogus"]; - XCTAssertThrowsSpecificNamed(layer.linePattern = functionExpression, NSException, NSInvalidArgumentException, @"MGLLineLayer should raise an exception if a camera-data expression is applied to a property that does not support key paths to feature attributes."); - functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:(bogus, %@, %@)", constantExpression, @{@18: constantExpression}]; - functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: functionExpression}]; - XCTAssertThrowsSpecificNamed(layer.linePattern = functionExpression, NSException, NSInvalidArgumentException, @"MGLLineLayer should raise an exception if a camera-data expression is applied to a property that does not support key paths to feature attributes."); // Transition property test layer.linePatternTransition = transitionTest; auto toptions = rawLayer->getLinePatternTransition(); diff --git a/platform/node/test/ignores.json b/platform/node/test/ignores.json index 0cbe550c0e..fcc9d88c88 100644 --- a/platform/node/test/ignores.json +++ b/platform/node/test/ignores.json @@ -17,6 +17,7 @@ "query-tests/fill-translate/multiple-layers": "https://github.com/mapbox/mapbox-gl-native/issues/12701", "query-tests/line-gap-width/feature-state": "skip - port https://github.com/mapbox/mapbox-gl-js/pull/6263 - needs issue", "query-tests/line-offset/feature-state": "skip - port https://github.com/mapbox/mapbox-gl-js/pull/6263 - needs issue", + "query-tests/line-offset/pattern-feature-state": "skip - port https://github.com/mapbox/mapbox-gl-js/pull/6263 - needs issue", "query-tests/line-width/feature-state": "skip - port https://github.com/mapbox/mapbox-gl-js/pull/6263 - needs issue", "query-tests/feature-state/default": "skip - port https://github.com/mapbox/mapbox-gl-js/pull/6263 - needs issue", "query-tests/regressions/mapbox-gl-js#6555": "skip - no querySourceFeatures in mbgl-node; needs issue", @@ -39,6 +40,7 @@ "render-tests/fill-extrusion-pattern/literal": "https://github.com/mapbox/mapbox-gl-js/issues/3327", "render-tests/fill-extrusion-pattern/missing": "https://github.com/mapbox/mapbox-gl-js/issues/3327", "render-tests/fill-extrusion-pattern/opacity": "https://github.com/mapbox/mapbox-gl-js/issues/3327", + "render-tests/fill-pattern/update-feature-state": "skip - port https://github.com/mapbox/mapbox-gl-js/pull/6263 - needs issue", "render-tests/geojson/inline-linestring-fill": "current behavior is arbitrary", "render-tests/geojson/inline-polygon-symbol": "behavior needs reconciliation with gl-js", "render-tests/icon-rotate/with-offset": "https://github.com/mapbox/mapbox-gl-native/issues/11872", @@ -98,5 +100,6 @@ "render-tests/combinations/symbol-translucent--fill-extrusion-translucent": "needs investigation", "render-tests/feature-state/composite-expression": "skip - port https://github.com/mapbox/mapbox-gl-js/pull/6263 - needs issue", "render-tests/feature-state/data-expression": "skip - port https://github.com/mapbox/mapbox-gl-js/pull/6263 - needs issue", + "render-tests/feature-state/set-paint-property": "skip - port https://github.com/mapbox/mapbox-gl-js/pull/6263 - needs issue", "render-tests/feature-state/vector-source": "skip - port https://github.com/mapbox/mapbox-gl-js/pull/6263 - needs issue" } diff --git a/scripts/generate-style-code.js b/scripts/generate-style-code.js index f85c6d8fd0..8b9b6ba5a2 100755 --- a/scripts/generate-style-code.js +++ b/scripts/generate-style-code.js @@ -56,21 +56,27 @@ global.evaluatedType = function (property) { function attributeUniformType(property, type) { const attributeNameExceptions = { - 'text-opacity': 'opacity', - 'icon-opacity': 'opacity', - 'text-color': 'fill_color', - 'icon-color': 'fill_color', - 'text-halo-color': 'halo_color', - 'icon-halo-color': 'halo_color', - 'text-halo-blur': 'halo_blur', - 'icon-halo-blur': 'halo_blur', - 'text-halo-width': 'halo_width', - 'icon-halo-width': 'halo_width', - 'line-gap-width': 'gapwidth' + 'text-opacity': ['opacity'], + 'icon-opacity': ['opacity'], + 'text-color': ['fill_color'], + 'icon-color': ['fill_color'], + 'text-halo-color': ['halo_color'], + 'icon-halo-color': ['halo_color'], + 'text-halo-blur': ['halo_blur'], + 'icon-halo-blur': ['halo_blur'], + 'text-halo-width': ['halo_width'], + 'icon-halo-width': ['halo_width'], + 'line-gap-width': ['gapwidth'], + 'line-pattern': ['pattern_to', 'pattern_from'], + 'fill-pattern': ['pattern_to', 'pattern_from'], + 'fill-extrusion-pattern': ['pattern_to', 'pattern_from'] } - const name = attributeNameExceptions[property.name] || - property.name.replace(type + '-', '').replace(/-/g, '_'); - return `attributes::a_${name}${name === 'offset' ? '<1>' : ''}, uniforms::u_${name}`; + const names = attributeNameExceptions[property.name] || + [ property.name.replace(type + '-', '').replace(/-/g, '_') ]; + + return names.map(name => { + return `attributes::a_${name}${name === 'offset' ? '<1>' : ''}, uniforms::u_${name}` + }).join(', '); } global.layoutPropertyType = function (property) { @@ -86,8 +92,9 @@ global.layoutPropertyType = function (property) { global.paintPropertyType = function (property, type) { switch (property['property-type']) { case 'data-driven': - case 'cross-faded-data-driven': return `DataDrivenPaintProperty<${evaluatedType(property)}, ${attributeUniformType(property, type)}>`; + case 'cross-faded-data-driven': + return `CrossFadedDataDrivenPaintProperty<${evaluatedType(property)}, ${attributeUniformType(property, type)}>`; case 'cross-faded': return `CrossFadedPaintProperty<${evaluatedType(property)}>`; default: diff --git a/src/mbgl/gl/uniform.cpp b/src/mbgl/gl/uniform.cpp index 2946980c19..3d8a8d53d9 100644 --- a/src/mbgl/gl/uniform.cpp +++ b/src/mbgl/gl/uniform.cpp @@ -79,6 +79,11 @@ void bindUniform<std::array<uint16_t, 2>>(UniformLocation location, const std::a bindUniform(location, util::convert<float>(t)); } +template <> +void bindUniform<std::array<uint16_t, 4>>(UniformLocation location, const std::array<uint16_t, 4>& t) { + bindUniform(location, util::convert<float>(t)); +} + // Add more as needed. #ifndef NDEBUG @@ -125,6 +130,12 @@ bool verifyUniform<std::array<float, 3>>(const ActiveUniform& uniform) { } template <> +bool verifyUniform<std::array<float, 4>>(const ActiveUniform& uniform) { + assert(uniform.size == 1 && uniform.type == UniformDataType::FloatVec4); + return true; +} + +template <> bool verifyUniform<std::array<double, 16>>(const ActiveUniform& uniform) { assert(uniform.size == 1 && uniform.type == UniformDataType::FloatMat4); return true; @@ -168,6 +179,14 @@ bool verifyUniform<std::array<uint16_t, 2>>(const ActiveUniform& uniform) { return true; } +template <> +bool verifyUniform<std::array<uint16_t, 4>>(const ActiveUniform& uniform) { + assert(uniform.size == 1 && + (uniform.type == UniformDataType::IntVec4 || + uniform.type == UniformDataType::FloatVec4)); + return true; +} + // Add more as needed. #endif diff --git a/src/mbgl/gl/uniform.hpp b/src/mbgl/gl/uniform.hpp index d8a167c382..f8eaf369a2 100644 --- a/src/mbgl/gl/uniform.hpp +++ b/src/mbgl/gl/uniform.hpp @@ -16,13 +16,6 @@ namespace gl { template <class T> void bindUniform(UniformLocation, const T&); -template <class Tag, class T> -class UniformValue { -public: - explicit UniformValue(T t_) : t(std::move(t_)) {} - T t; -}; - class ActiveUniform { public: std::size_t size; @@ -42,7 +35,8 @@ ActiveUniforms activeUniforms(ProgramID); template <class Tag, class T> class Uniform { public: - using Value = UniformValue<Tag, T>; + // TODO should maybe remove this altogether bc it is now redundant? + using Value = T; using Type = T; @@ -50,10 +44,10 @@ public: public: State(UniformLocation location_) : location(std::move(location_)) {} - void operator=(const Value& value) { - if (location >= 0 && (!current || *current != value.t)) { - current = value.t; - bindUniform(location, value.t); + void operator=(const Type& value) { + if (location >= 0 && (!current || *current != value)) { + current = value; + bindUniform(location, value); } } @@ -103,7 +97,7 @@ public: : false)... }); #endif - return State { { uniformLocation(id, Us::name()) }... }; + return State(uniformLocation(id, Us::name())...); } template <class Program> diff --git a/src/mbgl/layout/pattern_layout.hpp b/src/mbgl/layout/pattern_layout.hpp new file mode 100644 index 0000000000..9f4964ca6b --- /dev/null +++ b/src/mbgl/layout/pattern_layout.hpp @@ -0,0 +1,128 @@ +#pragma once +#include <mbgl/renderer/bucket_parameters.hpp> +#include <mbgl/geometry/feature_index.hpp> +#include <mbgl/renderer/render_layer.hpp> + +namespace mbgl { + +class PatternDependency { +public: + std::string min; + std::string mid; + std::string max; +}; + +using PatternLayerMap = std::unordered_map<std::string, PatternDependency>; + +class PatternFeature { +public: + const uint32_t i; + std::unique_ptr<GeometryTileFeature> feature; + PatternLayerMap patterns; +}; + +template <class B> +class PatternLayout { +public: + PatternLayout(const BucketParameters& parameters, + const std::vector<const RenderLayer*>& layers, + std::unique_ptr<GeometryTileLayer> sourceLayer_, + ImageDependencies& patternDependencies) + : bucketLeaderID(layers.at(0)->getID()), + sourceLayer(std::move(sourceLayer_)), + zoom(parameters.tileID.overscaledZ), + overscaling(parameters.tileID.overscaleFactor()), + hasPattern(false) { + + using PatternLayer = typename B::RenderLayerType; + const auto renderLayer = layers.at(0)->as<PatternLayer>(); + const typename PatternLayer::StyleLayerImpl& leader = renderLayer->impl(); + layout = leader.layout.evaluate(PropertyEvaluationParameters(zoom)); + sourceLayerID = leader.sourceLayer; + groupID = renderLayer->getID(); + + for (const auto& layer : layers) { + const typename B::PossiblyEvaluatedPaintProperties evaluatedProps = layer->as<PatternLayer>()->paintProperties(); + layerPaintProperties.emplace(layer->getID(), std::move(evaluatedProps)); + const auto patternProperty = evaluatedProps.template get<typename PatternLayer::PatternProperty>(); + const auto constantPattern = patternProperty.constantOr(Faded<std::basic_string<char> >{ "", ""}); + // determine if layer group has any layers that use *-pattern property and add + // constant pattern dependencies. + if (!patternProperty.isConstant()) { + hasPattern = true; + } else if (!constantPattern.to.empty()){ + hasPattern = true; + patternDependencies.emplace(constantPattern.to, ImageType::Pattern); + patternDependencies.emplace(constantPattern.from, ImageType::Pattern); + } + } + + const size_t featureCount = sourceLayer->featureCount(); + for (size_t i = 0; i < featureCount; ++i) { + auto feature = sourceLayer->getFeature(i); + if (!leader.filter(style::expression::EvaluationContext { this->zoom, feature.get() })) + continue; + + std::unordered_map<std::string, PatternDependency> patternDependencyMap; + if (hasPattern) { + for (const auto& layer : layers) { + const auto it = layerPaintProperties.find(layer->getID()); + if (it != layerPaintProperties.end()) { + const auto paint = it->second; + const auto patternProperty = paint.template get<typename PatternLayer::PatternProperty>(); + if (!patternProperty.isConstant()) { + // For layers with non-data-constant pattern properties, evaluate their expression and add + // the patterns to the dependency vector + const auto min = patternProperty.evaluate(*feature, zoom - 1, PatternLayer::PatternProperty::defaultValue()); + const auto mid = patternProperty.evaluate(*feature, zoom, PatternLayer::PatternProperty::defaultValue()); + const auto max = patternProperty.evaluate(*feature, zoom + 1, PatternLayer::PatternProperty::defaultValue()); + + patternDependencies.emplace(min.to, ImageType::Pattern); + patternDependencies.emplace(mid.to, ImageType::Pattern); + patternDependencies.emplace(max.to, ImageType::Pattern); + patternDependencyMap.emplace(layer->getID(), PatternDependency {min.to, mid.to, max.to}); + + } + } + } + } + features.push_back({static_cast<uint32_t>(i), std::move(feature), patternDependencyMap}); + } + }; + + bool pattern() { + return hasPattern; + } + + std::unique_ptr<B> createBucket(const ImagePositions& patternPositions, std::unique_ptr<FeatureIndex>& featureIndex) { + auto bucket = std::make_unique<B>(layout, layerPaintProperties, zoom, overscaling); + for (auto & patternFeature : features) { + const auto i = patternFeature.i; + std::unique_ptr<GeometryTileFeature> feature = std::move(patternFeature.feature); + PatternLayerMap patterns = patternFeature.patterns; + GeometryCollection geometries = feature->getGeometries(); + + bucket->addFeature(*feature, geometries, patternPositions, patterns); + featureIndex->insert(geometries, i, sourceLayerID, groupID); + } + return bucket; + }; + + std::map<std::string, typename B::PossiblyEvaluatedPaintProperties> layerPaintProperties; + const std::string bucketLeaderID; + + +private: + const std::unique_ptr<GeometryTileLayer> sourceLayer; + std::vector<PatternFeature> features; + typename B::PossiblyEvaluatedLayoutProperties layout; + + const float zoom; + const uint32_t overscaling; + std::string sourceLayerID; + std::string groupID; + bool hasPattern; +}; + +} // namespace mbgl + diff --git a/src/mbgl/layout/symbol_layout.cpp b/src/mbgl/layout/symbol_layout.cpp index ab718351ab..fd4dd2bedd 100644 --- a/src/mbgl/layout/symbol_layout.cpp +++ b/src/mbgl/layout/symbol_layout.cpp @@ -136,7 +136,7 @@ SymbolLayout::SymbolLayout(const BucketParameters& parameters, if (hasIcon) { ft.icon = layout.evaluate<IconImage>(zoom, ft); - imageDependencies.insert(*ft.icon); + imageDependencies.emplace(*ft.icon, ImageType::Icon); } if (ft.text || ft.icon) { @@ -455,15 +455,14 @@ std::unique_ptr<SymbolBucket> SymbolLayout::place(const bool showCollisionBoxes) symbolInstance.iconOffset, WritingModeType::None, symbolInstance.line, std::vector<float>()); symbolInstance.placedIconIndex = bucket->icon.placedSymbols.size() - 1; PlacedSymbol& iconSymbol = bucket->icon.placedSymbols.back(); - iconSymbol.vertexStartIndex = addSymbol( - bucket->icon, sizeData, *symbolInstance.iconQuad, + iconSymbol.vertexStartIndex = addSymbol(bucket->icon, sizeData, *symbolInstance.iconQuad, symbolInstance.anchor, iconSymbol); } } for (auto& pair : bucket->paintPropertyBinders) { - pair.second.first.populateVertexVectors(feature, bucket->icon.vertices.vertexSize()); - pair.second.second.populateVertexVectors(feature, bucket->text.vertices.vertexSize()); + pair.second.first.populateVertexVectors(feature, bucket->icon.vertices.vertexSize(), {}, {}); + pair.second.second.populateVertexVectors(feature, bucket->text.vertices.vertexSize(), {}, {}); } } diff --git a/src/mbgl/programs/attributes.hpp b/src/mbgl/programs/attributes.hpp index f1f1bdaa3f..ce3e7a7668 100644 --- a/src/mbgl/programs/attributes.hpp +++ b/src/mbgl/programs/attributes.hpp @@ -147,6 +147,16 @@ struct a_weight { using Type = gl::AttributeType<float, 1>; }; +struct a_pattern_to { + static auto name() { return "a_pattern_to"; } + using Type = gl::AttributeType<uint16_t, 4>; +}; + +struct a_pattern_from { + static auto name() { return "a_pattern_from"; } + using Type = gl::AttributeType<uint16_t, 4>; +}; + } // namespace attributes struct PositionOnlyLayoutAttributes : gl::Attributes< diff --git a/src/mbgl/programs/background_program.cpp b/src/mbgl/programs/background_program.cpp index 52a9638d6b..94d7aab2c8 100644 --- a/src/mbgl/programs/background_program.cpp +++ b/src/mbgl/programs/background_program.cpp @@ -16,7 +16,7 @@ BackgroundPatternUniforms::values(mat4 matrix, Size atlasSize, const ImagePosition& a, const ImagePosition& b, - const Faded<std::string>& fading, + const CrossfadeParameters& fading, const UnwrappedTileID& tileID, const TransformState& state) { @@ -25,22 +25,22 @@ BackgroundPatternUniforms::values(mat4 matrix, int32_t pixelY = tileSizeAtNearestZoom * tileID.canonical.y; return BackgroundPatternUniforms::Values { - uniforms::u_matrix::Value{ matrix }, - uniforms::u_opacity::Value{ opacity }, - uniforms::u_texsize::Value{ atlasSize }, - uniforms::u_pattern_tl_a::Value{ a.tl() }, - uniforms::u_pattern_br_a::Value{ a.br() }, - uniforms::u_pattern_tl_b::Value{ b.tl() }, - uniforms::u_pattern_br_b::Value{ b.br() }, - uniforms::u_pattern_size_a::Value{ a.displaySize() }, - uniforms::u_pattern_size_b::Value{ b.displaySize() }, - uniforms::u_scale_a::Value{ fading.fromScale }, - uniforms::u_scale_b::Value{ fading.toScale }, - uniforms::u_mix::Value{ fading.t }, - uniforms::u_image::Value{ 0 }, - uniforms::u_pixel_coord_upper::Value{ std::array<float, 2> {{ float(pixelX >> 16), float(pixelY >> 16) }} }, - uniforms::u_pixel_coord_lower::Value{ std::array<float, 2> {{ float(pixelX & 0xFFFF), float(pixelY & 0xFFFF) }} }, - uniforms::u_tile_units_to_pixels::Value{ 1.0f / tileID.pixelsToTileUnits(1.0f, state.getIntegerZoom()) }, + uniforms::u_matrix::Value( matrix ), + uniforms::u_opacity::Value( opacity ), + uniforms::u_texsize::Value( atlasSize ), + uniforms::u_pattern_tl_a::Value( a.tl() ), + uniforms::u_pattern_br_a::Value( a.br() ), + uniforms::u_pattern_tl_b::Value( b.tl() ), + uniforms::u_pattern_br_b::Value( b.br() ), + uniforms::u_pattern_size_a::Value( a.displaySize() ), + uniforms::u_pattern_size_b::Value( b.displaySize() ), + uniforms::u_scale_a::Value( fading.fromScale ), + uniforms::u_scale_b::Value( fading.toScale ), + uniforms::u_mix::Value( fading.t ), + uniforms::u_image::Value( 0 ), + uniforms::u_pixel_coord_upper::Value( std::array<float, 2> {{ float(pixelX >> 16), float(pixelY >> 16) }}), + uniforms::u_pixel_coord_lower::Value( std::array<float, 2> {{ float(pixelX & 0xFFFF), float(pixelY & 0xFFFF)}}), + uniforms::u_tile_units_to_pixels::Value( 1.0f / tileID.pixelsToTileUnits(1.0f, state.getIntegerZoom()) ), }; } diff --git a/src/mbgl/programs/background_program.hpp b/src/mbgl/programs/background_program.hpp index b76318938c..667db7792b 100644 --- a/src/mbgl/programs/background_program.hpp +++ b/src/mbgl/programs/background_program.hpp @@ -50,7 +50,7 @@ struct BackgroundPatternUniforms : gl::Uniforms< Size atlasSize, const ImagePosition&, const ImagePosition&, - const Faded<std::string>&, + const CrossfadeParameters&, const UnwrappedTileID&, const TransformState&); }; diff --git a/src/mbgl/programs/fill_extrusion_program.cpp b/src/mbgl/programs/fill_extrusion_program.cpp index aaf192a843..2bdd0604d7 100644 --- a/src/mbgl/programs/fill_extrusion_program.cpp +++ b/src/mbgl/programs/fill_extrusion_program.cpp @@ -36,47 +36,39 @@ FillExtrusionUniforms::values(mat4 matrix, const TransformState& state, const EvaluatedLight& light) { return FillExtrusionUniforms::Values{ - uniforms::u_matrix::Value{ matrix }, - uniforms::u_lightcolor::Value{ lightColor(light) }, - uniforms::u_lightpos::Value{ lightPosition(light, state) }, - uniforms::u_lightintensity::Value{ lightIntensity(light) } + uniforms::u_matrix::Value( matrix ), + uniforms::u_lightcolor::Value( lightColor(light) ), + uniforms::u_lightpos::Value( lightPosition(light, state) ), + uniforms::u_lightintensity::Value( lightIntensity(light) ) }; } FillExtrusionPatternUniforms::Values FillExtrusionPatternUniforms::values(mat4 matrix, Size atlasSize, - const ImagePosition& a, - const ImagePosition& b, - const Faded<std::string>& fading, + const CrossfadeParameters& crossfade, const UnwrappedTileID& tileID, const TransformState& state, const float heightFactor, + const float pixelRatio, const EvaluatedLight& light) { + const auto tileRatio = 1 / tileID.pixelsToTileUnits(1, state.getIntegerZoom()); int32_t tileSizeAtNearestZoom = util::tileSize * state.zoomScale(state.getIntegerZoom() - tileID.canonical.z); int32_t pixelX = tileSizeAtNearestZoom * (tileID.canonical.x + tileID.wrap * state.zoomScale(tileID.canonical.z)); int32_t pixelY = tileSizeAtNearestZoom * tileID.canonical.y; return FillExtrusionPatternUniforms::Values{ - uniforms::u_matrix::Value{ matrix }, - uniforms::u_pattern_tl_a::Value{ a.tl() }, - uniforms::u_pattern_br_a::Value{ a.br() }, - uniforms::u_pattern_tl_b::Value{ b.tl() }, - uniforms::u_pattern_br_b::Value{ b.br() }, - uniforms::u_pattern_size_a::Value{ a.displaySize() }, - uniforms::u_pattern_size_b::Value{ b.displaySize() }, - uniforms::u_scale_a::Value{ fading.fromScale }, - uniforms::u_scale_b::Value{ fading.toScale }, - uniforms::u_texsize::Value{ atlasSize }, - uniforms::u_mix::Value{ fading.t }, - uniforms::u_image::Value{ 0 }, - uniforms::u_pixel_coord_upper::Value{ std::array<float, 2>{{ float(pixelX >> 16), float(pixelY >> 16) }} }, - uniforms::u_pixel_coord_lower::Value{ std::array<float, 2>{{ float(pixelX & 0xFFFF), float(pixelY & 0xFFFF) }} }, - uniforms::u_tile_units_to_pixels::Value{ 1.0f / tileID.pixelsToTileUnits(1.0f, state.getIntegerZoom()) }, - uniforms::u_height_factor::Value{ heightFactor }, - uniforms::u_lightcolor::Value{ lightColor(light) }, - uniforms::u_lightpos::Value{ lightPosition(light, state) }, - uniforms::u_lightintensity::Value{ lightIntensity(light) }, + uniforms::u_matrix::Value( matrix ), + uniforms::u_scale::Value( {{pixelRatio, tileRatio, crossfade.fromScale, crossfade.toScale}} ), + uniforms::u_texsize::Value( atlasSize ), + uniforms::u_fade::Value( crossfade.t ), + uniforms::u_image::Value( 0 ), + uniforms::u_pixel_coord_upper::Value( std::array<float, 2>{{ float(pixelX >> 16), float(pixelY >> 16) }} ), + uniforms::u_pixel_coord_lower::Value( std::array<float, 2>{{ float(pixelX & 0xFFFF), float(pixelY & 0xFFFF) }} ), + uniforms::u_height_factor::Value( heightFactor ), + uniforms::u_lightcolor::Value( lightColor(light) ), + uniforms::u_lightpos::Value( lightPosition(light, state) ), + uniforms::u_lightintensity::Value( lightIntensity(light) ), }; } diff --git a/src/mbgl/programs/fill_extrusion_program.hpp b/src/mbgl/programs/fill_extrusion_program.hpp index c499e9ef2d..657238d4c0 100644 --- a/src/mbgl/programs/fill_extrusion_program.hpp +++ b/src/mbgl/programs/fill_extrusion_program.hpp @@ -46,20 +46,12 @@ struct FillExtrusionUniforms : gl::Uniforms< struct FillExtrusionPatternUniforms : gl::Uniforms< uniforms::u_matrix, - uniforms::u_pattern_tl_a, - uniforms::u_pattern_br_a, - uniforms::u_pattern_tl_b, - uniforms::u_pattern_br_b, - uniforms::u_pattern_size_a, - uniforms::u_pattern_size_b, - uniforms::u_scale_a, - uniforms::u_scale_b, + uniforms::u_scale, uniforms::u_texsize, - uniforms::u_mix, + uniforms::u_fade, uniforms::u_image, uniforms::u_pixel_coord_upper, uniforms::u_pixel_coord_lower, - uniforms::u_tile_units_to_pixels, uniforms::u_height_factor, uniforms::u_lightcolor, uniforms::u_lightpos, @@ -67,12 +59,11 @@ struct FillExtrusionPatternUniforms : gl::Uniforms< { static Values values(mat4, Size atlasSize, - const ImagePosition&, - const ImagePosition&, - const Faded<std::string>&, + const CrossfadeParameters&, const UnwrappedTileID&, const TransformState&, - const float, + const float heightFactor, + const float pixelRatio, const EvaluatedLight&); }; diff --git a/src/mbgl/programs/fill_program.cpp b/src/mbgl/programs/fill_program.cpp index 46dc830102..b072343e7a 100644 --- a/src/mbgl/programs/fill_program.cpp +++ b/src/mbgl/programs/fill_program.cpp @@ -14,33 +14,25 @@ FillPatternUniforms::Values FillPatternUniforms::values(mat4 matrix, Size framebufferSize, Size atlasSize, - const ImagePosition& a, - const ImagePosition& b, - const Faded<std::string>& fading, + const CrossfadeParameters& crossfade, const UnwrappedTileID& tileID, - const TransformState& state) + const TransformState& state, + const float pixelRatio) { + const auto tileRatio = 1 / tileID.pixelsToTileUnits(1, state.getIntegerZoom()); int32_t tileSizeAtNearestZoom = util::tileSize * state.zoomScale(state.getIntegerZoom() - tileID.canonical.z); int32_t pixelX = tileSizeAtNearestZoom * (tileID.canonical.x + tileID.wrap * state.zoomScale(tileID.canonical.z)); int32_t pixelY = tileSizeAtNearestZoom * tileID.canonical.y; return FillPatternUniforms::Values { - uniforms::u_matrix::Value{ matrix }, - uniforms::u_world::Value{ framebufferSize }, - uniforms::u_texsize::Value{ atlasSize }, - uniforms::u_pattern_tl_a::Value{ a.tl() }, - uniforms::u_pattern_br_a::Value{ a.br() }, - uniforms::u_pattern_tl_b::Value{ b.tl() }, - uniforms::u_pattern_br_b::Value{ b.br() }, - uniforms::u_pattern_size_a::Value{ a.displaySize() }, - uniforms::u_pattern_size_b::Value{ b.displaySize() }, - uniforms::u_scale_a::Value{ fading.fromScale }, - uniforms::u_scale_b::Value{ fading.toScale }, - uniforms::u_mix::Value{ fading.t }, - uniforms::u_image::Value{ 0 }, - uniforms::u_pixel_coord_upper::Value{ std::array<float, 2> {{ float(pixelX >> 16), float(pixelY >> 16) }} }, - uniforms::u_pixel_coord_lower::Value{ std::array<float, 2> {{ float(pixelX & 0xFFFF), float(pixelY & 0xFFFF) }} }, - uniforms::u_tile_units_to_pixels::Value{ 1.0f / tileID.pixelsToTileUnits(1.0f, state.getIntegerZoom()) }, + uniforms::u_matrix::Value( matrix ), + uniforms::u_world::Value( framebufferSize ), + uniforms::u_texsize::Value( atlasSize ), + uniforms::u_scale::Value({ {pixelRatio, tileRatio, crossfade.fromScale, crossfade.toScale} } ), + uniforms::u_fade::Value( crossfade.t ), + uniforms::u_image::Value( 0 ), + uniforms::u_pixel_coord_upper::Value( std::array<float, 2> {{ float(pixelX >> 16), float(pixelY >> 16) }}), + uniforms::u_pixel_coord_lower::Value( std::array<float, 2> {{ float(pixelX & 0xFFFF), float(pixelY & 0xFFFF) }} ) }; } diff --git a/src/mbgl/programs/fill_program.hpp b/src/mbgl/programs/fill_program.hpp index ac478250fc..9c623fee22 100644 --- a/src/mbgl/programs/fill_program.hpp +++ b/src/mbgl/programs/fill_program.hpp @@ -32,28 +32,19 @@ struct FillPatternUniforms : gl::Uniforms< uniforms::u_matrix, uniforms::u_world, uniforms::u_texsize, - uniforms::u_pattern_tl_a, - uniforms::u_pattern_br_a, - uniforms::u_pattern_tl_b, - uniforms::u_pattern_br_b, - uniforms::u_pattern_size_a, - uniforms::u_pattern_size_b, - uniforms::u_scale_a, - uniforms::u_scale_b, - uniforms::u_mix, + uniforms::u_scale, + uniforms::u_fade, uniforms::u_image, uniforms::u_pixel_coord_upper, - uniforms::u_pixel_coord_lower, - uniforms::u_tile_units_to_pixels> + uniforms::u_pixel_coord_lower> { static Values values(mat4 matrix, Size framebufferSize, Size atlasSize, - const ImagePosition&, - const ImagePosition&, - const Faded<std::string>&, + const CrossfadeParameters& crossfade, const UnwrappedTileID&, - const TransformState&); + const TransformState&, + const float pixelRatio); }; class FillProgram : public Program< diff --git a/src/mbgl/programs/line_program.cpp b/src/mbgl/programs/line_program.cpp index 0533a13c35..55362ad6fe 100644 --- a/src/mbgl/programs/line_program.cpp +++ b/src/mbgl/programs/line_program.cpp @@ -20,13 +20,13 @@ Values makeValues(const RenderLinePaintProperties::PossiblyEvaluated& properties Args&&... args) { return Values { - uniforms::u_matrix::Value{ + uniforms::u_matrix::Value( tile.translatedMatrix(properties.get<LineTranslate>(), properties.get<LineTranslateAnchor>(), state) - }, - uniforms::u_ratio::Value{ 1.0f / tile.id.pixelsToTileUnits(1.0, state.getZoom()) }, - uniforms::u_gl_units_to_pixels::Value{{{ 1.0f / pixelsToGLUnits[0], 1.0f / pixelsToGLUnits[1] }}}, + ), + uniforms::u_ratio::Value( 1.0f / tile.id.pixelsToTileUnits(1.0, state.getZoom()) ), + uniforms::u_gl_units_to_pixels::Value({ {1.0f / pixelsToGLUnits[0], 1.0f / pixelsToGLUnits[1]} }), std::forward<Args>(args)... }; } @@ -52,9 +52,10 @@ LineSDFProgram::uniformValues(const RenderLinePaintProperties::PossiblyEvaluated const std::array<float, 2>& pixelsToGLUnits, const LinePatternPos& posA, const LinePatternPos& posB, + const CrossfadeParameters& crossfade, float atlasWidth) { - const float widthA = posA.width * properties.get<LineDasharray>().fromScale; - const float widthB = posB.width * properties.get<LineDasharray>().toScale; + const float widthA = posA.width * crossfade.fromScale; + const float widthB = posB.width * crossfade.toScale; std::array<float, 2> scaleA {{ 1.0f / tile.id.pixelsToTileUnits(widthA, state.getIntegerZoom()), @@ -71,13 +72,13 @@ LineSDFProgram::uniformValues(const RenderLinePaintProperties::PossiblyEvaluated tile, state, pixelsToGLUnits, - uniforms::u_patternscale_a::Value{ scaleA }, - uniforms::u_patternscale_b::Value{ scaleB }, - uniforms::u_tex_y_a::Value{ posA.y }, - uniforms::u_tex_y_b::Value{ posB.y }, - uniforms::u_mix::Value{ properties.get<LineDasharray>().t }, - uniforms::u_sdfgamma::Value{ atlasWidth / (std::min(widthA, widthB) * 256.0f * pixelRatio) / 2.0f }, - uniforms::u_image::Value{ 0 } + uniforms::u_patternscale_a::Value( scaleA ), + uniforms::u_patternscale_b::Value( scaleB ), + uniforms::u_tex_y_a::Value( posA.y ), + uniforms::u_tex_y_b::Value( posB.y ), + uniforms::u_mix::Value( crossfade.t ), + uniforms::u_sdfgamma::Value( atlasWidth / (std::min(widthA, widthB) * 256.0f * pixelRatio) / 2.0f ), + uniforms::u_image::Value( 0 ) ); } @@ -87,32 +88,20 @@ LinePatternProgram::uniformValues(const RenderLinePaintProperties::PossiblyEvalu const TransformState& state, const std::array<float, 2>& pixelsToGLUnits, const Size atlasSize, - const ImagePosition& posA, - const ImagePosition& posB) { - std::array<float, 2> sizeA {{ - tile.id.pixelsToTileUnits(posA.displaySize()[0] * properties.get<LinePattern>().fromScale, state.getIntegerZoom()), - posA.displaySize()[1] - }}; - - std::array<float, 2> sizeB {{ - tile.id.pixelsToTileUnits(posB.displaySize()[0] * properties.get<LinePattern>().toScale, state.getIntegerZoom()), - posB.displaySize()[1] - }}; + const CrossfadeParameters& crossfade, + const float pixelRatio) { + + const auto tileRatio = 1 / tile.id.pixelsToTileUnits(1, state.getIntegerZoom()); return makeValues<LinePatternProgram::UniformValues>( properties, tile, state, pixelsToGLUnits, - uniforms::u_pattern_tl_a::Value{ posA.tl() }, - uniforms::u_pattern_br_a::Value{ posA.br() }, - uniforms::u_pattern_tl_b::Value{ posB.tl() }, - uniforms::u_pattern_br_b::Value{ posB.br() }, - uniforms::u_pattern_size_a::Value{ sizeA }, - uniforms::u_pattern_size_b::Value{ sizeB }, - uniforms::u_texsize::Value{ atlasSize }, - uniforms::u_fade::Value{ properties.get<LinePattern>().t }, - uniforms::u_image::Value{ 0 } + uniforms::u_scale::Value ({ {pixelRatio, tileRatio, crossfade.fromScale, crossfade.toScale} }), + uniforms::u_texsize::Value( atlasSize ), + uniforms::u_fade::Value( crossfade.t ), + uniforms::u_image::Value( 0 ) ); } diff --git a/src/mbgl/programs/line_program.hpp b/src/mbgl/programs/line_program.hpp index 632dbe92b9..9dde0939e7 100644 --- a/src/mbgl/programs/line_program.hpp +++ b/src/mbgl/programs/line_program.hpp @@ -9,7 +9,7 @@ #include <mbgl/shaders/line_sdf.hpp> #include <mbgl/util/geometry.hpp> #include <mbgl/renderer/layers/render_line_layer.hpp> - +#include <mbgl/renderer/cross_faded_property_evaluator.hpp> #include <cmath> namespace mbgl { @@ -24,7 +24,6 @@ MBGL_DEFINE_UNIFORM_SCALAR(float, u_ratio); MBGL_DEFINE_UNIFORM_SCALAR(float, u_tex_y_a); MBGL_DEFINE_UNIFORM_SCALAR(float, u_tex_y_b); MBGL_DEFINE_UNIFORM_SCALAR(float, u_sdfgamma); -MBGL_DEFINE_UNIFORM_SCALAR(float, u_fade); MBGL_DEFINE_UNIFORM_VECTOR(float, 2, u_patternscale_a); MBGL_DEFINE_UNIFORM_VECTOR(float, 2, u_patternscale_b); MBGL_DEFINE_UNIFORM_VECTOR(float, 2, u_gl_units_to_pixels); @@ -107,12 +106,7 @@ class LinePatternProgram : public Program< uniforms::u_matrix, uniforms::u_ratio, uniforms::u_gl_units_to_pixels, - uniforms::u_pattern_tl_a, - uniforms::u_pattern_br_a, - uniforms::u_pattern_tl_b, - uniforms::u_pattern_br_b, - uniforms::u_pattern_size_a, - uniforms::u_pattern_size_b, + uniforms::u_scale, uniforms::u_texsize, uniforms::u_fade, uniforms::u_image>, @@ -126,8 +120,8 @@ public: const TransformState&, const std::array<float, 2>& pixelsToGLUnits, Size atlasSize, - const ImagePosition& posA, - const ImagePosition& posB); + const CrossfadeParameters& crossfade, + const float pixelRatio); }; class LineSDFProgram : public Program< @@ -157,6 +151,7 @@ public: const std::array<float, 2>& pixelsToGLUnits, const LinePatternPos& posA, const LinePatternPos& posB, + const CrossfadeParameters& crossfade, float atlasWidth); }; diff --git a/src/mbgl/programs/symbol_program.cpp b/src/mbgl/programs/symbol_program.cpp index d73abd4fe1..0c195e4d37 100644 --- a/src/mbgl/programs/symbol_program.cpp +++ b/src/mbgl/programs/symbol_program.cpp @@ -77,25 +77,25 @@ Values makeValues(const bool isText, mat4 glCoordMatrix = getGlCoordMatrix(tile.matrix, pitchWithMap, rotateWithMap, state, pixelsToTileUnits); return Values { - uniforms::u_matrix::Value{ tile.translatedMatrix(values.translate, + uniforms::u_matrix::Value( tile.translatedMatrix(values.translate, values.translateAnchor, - state) }, - uniforms::u_label_plane_matrix::Value{labelPlaneMatrix}, - uniforms::u_gl_coord_matrix::Value{ tile.translateVtxMatrix(glCoordMatrix, + state) ), + uniforms::u_label_plane_matrix::Value(labelPlaneMatrix), + uniforms::u_gl_coord_matrix::Value( tile.translateVtxMatrix(glCoordMatrix, values.translate, values.translateAnchor, state, - true) }, - uniforms::u_extrude_scale::Value{ extrudeScale }, - uniforms::u_texsize::Value{ texsize }, - uniforms::u_texture::Value{ 0 }, - uniforms::u_fade_change::Value{ symbolFadeChange }, - uniforms::u_is_text::Value{ isText }, - uniforms::u_camera_to_center_distance::Value{ state.getCameraToCenterDistance() }, - uniforms::u_pitch::Value{ state.getPitch() }, - uniforms::u_pitch_with_map::Value{ pitchWithMap }, - uniforms::u_rotate_symbol::Value{ rotateInShader }, - uniforms::u_aspect_ratio::Value{ state.getSize().aspectRatio() }, + true) ), + uniforms::u_extrude_scale::Value( extrudeScale ), + uniforms::u_texsize::Value( texsize ), + uniforms::u_texture::Value( 0 ), + uniforms::u_fade_change::Value( symbolFadeChange ), + uniforms::u_is_text::Value( isText ), + uniforms::u_camera_to_center_distance::Value( state.getCameraToCenterDistance() ), + uniforms::u_pitch::Value( state.getPitch() ), + uniforms::u_pitch_with_map::Value( pitchWithMap ), + uniforms::u_rotate_symbol::Value( rotateInShader ), + uniforms::u_aspect_ratio::Value( state.getSize().aspectRatio() ), std::forward<Args>(args)... }; } @@ -147,8 +147,8 @@ typename SymbolSDFProgram<PaintProperties>::UniformValues SymbolSDFProgram<Paint tile, state, symbolFadeChange, - uniforms::u_gamma_scale::Value{ gammaScale }, - uniforms::u_is_halo::Value{ part == SymbolSDFPart::Halo } + uniforms::u_gamma_scale::Value( gammaScale ), + uniforms::u_is_halo::Value( part == SymbolSDFPart::Halo ) ); } diff --git a/src/mbgl/programs/symbol_program.hpp b/src/mbgl/programs/symbol_program.hpp index 27bcd7b427..6d22e812fa 100644 --- a/src/mbgl/programs/symbol_program.hpp +++ b/src/mbgl/programs/symbol_program.hpp @@ -125,10 +125,10 @@ public: UniformValues uniformValues(float currentZoom) const { const ZoomEvaluatedSize u = evaluateForZoom(currentZoom); return UniformValues { - uniforms::u_is_size_zoom_constant::Value{ u.isZoomConstant }, - uniforms::u_is_size_feature_constant::Value{ u.isFeatureConstant}, - uniforms::u_size_t::Value{ u.sizeT }, - uniforms::u_size::Value{ u.size } + uniforms::u_is_size_zoom_constant::Value( u.isZoomConstant ), + uniforms::u_is_size_feature_constant::Value( u.isFeatureConstant), + uniforms::u_size_t::Value( u.sizeT ), + uniforms::u_size::Value( u.size ) }; } }; diff --git a/src/mbgl/programs/uniforms.hpp b/src/mbgl/programs/uniforms.hpp index 071a27c808..ab68e43c87 100644 --- a/src/mbgl/programs/uniforms.hpp +++ b/src/mbgl/programs/uniforms.hpp @@ -36,6 +36,7 @@ MBGL_DEFINE_UNIFORM_SCALAR(Size, u_world); MBGL_DEFINE_UNIFORM_SCALAR(Size, u_texsize); MBGL_DEFINE_UNIFORM_SCALAR(bool, u_pitch_with_map); MBGL_DEFINE_UNIFORM_SCALAR(float, u_camera_to_center_distance); +MBGL_DEFINE_UNIFORM_SCALAR(float, u_fade); MBGL_DEFINE_UNIFORM_SCALAR(float, u_fade_change); MBGL_DEFINE_UNIFORM_SCALAR(float, u_weight); @@ -45,6 +46,9 @@ namespace heatmap { MBGL_DEFINE_UNIFORM_SCALAR(float, u_extrude_scale); } // namespace heatmap +MBGL_DEFINE_UNIFORM_VECTOR(uint16_t, 4, u_pattern_from); +MBGL_DEFINE_UNIFORM_VECTOR(uint16_t, 4, u_pattern_to); +MBGL_DEFINE_UNIFORM_VECTOR(float, 4, u_scale); MBGL_DEFINE_UNIFORM_VECTOR(uint16_t, 2, u_pattern_tl_a); MBGL_DEFINE_UNIFORM_VECTOR(uint16_t, 2, u_pattern_br_a); MBGL_DEFINE_UNIFORM_VECTOR(uint16_t, 2, u_pattern_tl_b); diff --git a/src/mbgl/renderer/bucket.hpp b/src/mbgl/renderer/bucket.hpp index f48593ae49..7ccab8672d 100644 --- a/src/mbgl/renderer/bucket.hpp +++ b/src/mbgl/renderer/bucket.hpp @@ -3,7 +3,8 @@ #include <mbgl/util/noncopyable.hpp> #include <mbgl/tile/geometry_tile_data.hpp> #include <mbgl/style/layer_type.hpp> - +#include <mbgl/style/image_impl.hpp> +#include <mbgl/renderer/image_atlas.hpp> #include <atomic> namespace mbgl { @@ -13,6 +14,8 @@ class Context; } // namespace gl class RenderLayer; +class PatternDependency; +using PatternLayerMap = std::unordered_map<std::string, PatternDependency>; class Bucket : private util::noncopyable { public: @@ -41,7 +44,12 @@ public: // Obtaining these is a costly operation, so we do it only once, and // pass-by-const-ref the geometries as a second parameter. virtual void addFeature(const GeometryTileFeature&, - const GeometryCollection&) {}; + const GeometryCollection&, + const ImagePositions&, + const PatternLayerMap&) {}; + + virtual void populateFeatureBuffers(const ImagePositions&) {}; + virtual void addPatternDependencies(const std::vector<const RenderLayer*>&, ImageDependencies&) {}; // As long as this bucket has a Prepare render pass, this function is getting called. Typically, // this only happens once when the bucket is being rendered for the first time. diff --git a/src/mbgl/renderer/buckets/circle_bucket.cpp b/src/mbgl/renderer/buckets/circle_bucket.cpp index d07c1f8dbe..820cf9f525 100644 --- a/src/mbgl/renderer/buckets/circle_bucket.cpp +++ b/src/mbgl/renderer/buckets/circle_bucket.cpp @@ -39,7 +39,9 @@ bool CircleBucket::hasData() const { } void CircleBucket::addFeature(const GeometryTileFeature& feature, - const GeometryCollection& geometry) { + const GeometryCollection& geometry, + const ImagePositions&, + const PatternLayerMap&) { constexpr const uint16_t vertexLength = 4; for (auto& circle : geometry) { @@ -87,7 +89,7 @@ void CircleBucket::addFeature(const GeometryTileFeature& feature, } for (auto& pair : paintPropertyBinders) { - pair.second.populateVertexVectors(feature, vertices.vertexSize()); + pair.second.populateVertexVectors(feature, vertices.vertexSize(), {}, {}); } } diff --git a/src/mbgl/renderer/buckets/circle_bucket.hpp b/src/mbgl/renderer/buckets/circle_bucket.hpp index 3c5f96fb15..db61a0c112 100644 --- a/src/mbgl/renderer/buckets/circle_bucket.hpp +++ b/src/mbgl/renderer/buckets/circle_bucket.hpp @@ -18,7 +18,10 @@ public: CircleBucket(const BucketParameters&, const std::vector<const RenderLayer*>&); void addFeature(const GeometryTileFeature&, - const GeometryCollection&) override; + const GeometryCollection&, + const ImagePositions&, + const PatternLayerMap&) override; + bool hasData() const override; void upload(gl::Context&) override; diff --git a/src/mbgl/renderer/buckets/fill_bucket.cpp b/src/mbgl/renderer/buckets/fill_bucket.cpp index 14be98c3af..3b1b7ec00f 100644 --- a/src/mbgl/renderer/buckets/fill_bucket.cpp +++ b/src/mbgl/renderer/buckets/fill_bucket.cpp @@ -27,20 +27,26 @@ using namespace style; struct GeometryTooLongException : std::exception {}; -FillBucket::FillBucket(const BucketParameters& parameters, const std::vector<const RenderLayer*>& layers) +FillBucket::FillBucket(const FillBucket::PossiblyEvaluatedLayoutProperties, + std::map<std::string, FillBucket::PossiblyEvaluatedPaintProperties> layerPaintProperties, + const float zoom, + const uint32_t) : Bucket(LayerType::Fill) { - for (const auto& layer : layers) { + + for (const auto& pair : layerPaintProperties) { paintPropertyBinders.emplace( std::piecewise_construct, - std::forward_as_tuple(layer->getID()), + std::forward_as_tuple(pair.first), std::forward_as_tuple( - layer->as<RenderFillLayer>()->evaluated, - parameters.tileID.overscaledZ)); + pair.second, + zoom)); } } void FillBucket::addFeature(const GeometryTileFeature& feature, - const GeometryCollection& geometry) { + const GeometryCollection& geometry, + const ImagePositions& patternPositions, + const PatternLayerMap& patternDependencies) { for (auto& polygon : classifyRings(geometry)) { // Optimize polygons with many interior rings for earcut tesselation. limitHoles(polygon, 500); @@ -105,7 +111,12 @@ void FillBucket::addFeature(const GeometryTileFeature& feature, } for (auto& pair : paintPropertyBinders) { - pair.second.populateVertexVectors(feature, vertices.vertexSize()); + const auto it = patternDependencies.find(pair.first); + if (it != patternDependencies.end()){ + pair.second.populateVertexVectors(feature, vertices.vertexSize(), patternPositions, it->second); + } else { + pair.second.populateVertexVectors(feature, vertices.vertexSize(), patternPositions, {}); + } } } diff --git a/src/mbgl/renderer/buckets/fill_bucket.hpp b/src/mbgl/renderer/buckets/fill_bucket.hpp index 20b65da39c..47e273d4d2 100644 --- a/src/mbgl/renderer/buckets/fill_bucket.hpp +++ b/src/mbgl/renderer/buckets/fill_bucket.hpp @@ -13,13 +13,26 @@ namespace mbgl { class BucketParameters; +class RenderFillLayer; class FillBucket : public Bucket { public: - FillBucket(const BucketParameters&, const std::vector<const RenderLayer*>&); + + // These aliases are used by the PatternLayout template + using RenderLayerType = RenderFillLayer; + using PossiblyEvaluatedPaintProperties = style::FillPaintProperties::PossiblyEvaluated; + using PossiblyEvaluatedLayoutProperties = style::Properties<>::PossiblyEvaluated; + + FillBucket(const PossiblyEvaluatedLayoutProperties layout, + std::map<std::string, PossiblyEvaluatedPaintProperties> layerPaintProperties, + const float zoom, + const uint32_t overscaling); void addFeature(const GeometryTileFeature&, - const GeometryCollection&) override; + const GeometryCollection&, + const mbgl::ImagePositions&, + const PatternLayerMap&) override; + bool hasData() const override; void upload(gl::Context&) override; diff --git a/src/mbgl/renderer/buckets/fill_extrusion_bucket.cpp b/src/mbgl/renderer/buckets/fill_extrusion_bucket.cpp index c6dba38db1..fe742828b8 100644 --- a/src/mbgl/renderer/buckets/fill_extrusion_bucket.cpp +++ b/src/mbgl/renderer/buckets/fill_extrusion_bucket.cpp @@ -34,19 +34,26 @@ using namespace style; struct GeometryTooLongException : std::exception {}; -FillExtrusionBucket::FillExtrusionBucket(const BucketParameters& parameters, const std::vector<const RenderLayer*>& layers) +FillExtrusionBucket::FillExtrusionBucket(const FillExtrusionBucket::PossiblyEvaluatedLayoutProperties, + std::map<std::string, FillExtrusionBucket::PossiblyEvaluatedPaintProperties> layerPaintProperties, + const float zoom, + const uint32_t) : Bucket(LayerType::FillExtrusion) { - for (const auto& layer : layers) { - paintPropertyBinders.emplace(std::piecewise_construct, - std::forward_as_tuple(layer->getID()), - std::forward_as_tuple( - layer->as<RenderFillExtrusionLayer>()->evaluated, - parameters.tileID.overscaledZ)); + + for (const auto& pair : layerPaintProperties) { + paintPropertyBinders.emplace( + std::piecewise_construct, + std::forward_as_tuple(pair.first), + std::forward_as_tuple( + pair.second, + zoom)); } } void FillExtrusionBucket::addFeature(const GeometryTileFeature& feature, - const GeometryCollection& geometry) { + const GeometryCollection& geometry, + const ImagePositions& patternPositions, + const PatternLayerMap& patternDependencies) { for (auto& polygon : classifyRings(geometry)) { // Optimize polygons with many interior rings for earcut tesselation. limitHoles(polygon, 500); @@ -143,7 +150,12 @@ void FillExtrusionBucket::addFeature(const GeometryTileFeature& feature, } for (auto& pair : paintPropertyBinders) { - pair.second.populateVertexVectors(feature, vertices.vertexSize()); + const auto it = patternDependencies.find(pair.first); + if (it != patternDependencies.end()){ + pair.second.populateVertexVectors(feature, vertices.vertexSize(), patternPositions, it->second); + } else { + pair.second.populateVertexVectors(feature, vertices.vertexSize(), patternPositions, {}); + } } } diff --git a/src/mbgl/renderer/buckets/fill_extrusion_bucket.hpp b/src/mbgl/renderer/buckets/fill_extrusion_bucket.hpp index ed98e01292..362a9f4c99 100644 --- a/src/mbgl/renderer/buckets/fill_extrusion_bucket.hpp +++ b/src/mbgl/renderer/buckets/fill_extrusion_bucket.hpp @@ -11,13 +11,26 @@ namespace mbgl { class BucketParameters; +class RenderFillExtrusionLayer; class FillExtrusionBucket : public Bucket { public: - FillExtrusionBucket(const BucketParameters&, const std::vector<const RenderLayer*>&); + + // These aliases are used by the PatternLayout template + using RenderLayerType = RenderFillExtrusionLayer; + using PossiblyEvaluatedPaintProperties = style::FillExtrusionPaintProperties::PossiblyEvaluated; + using PossiblyEvaluatedLayoutProperties = style::Properties<>::PossiblyEvaluated; + + FillExtrusionBucket(const PossiblyEvaluatedLayoutProperties, + std::map<std::string, PossiblyEvaluatedPaintProperties>, + const float, + const uint32_t); void addFeature(const GeometryTileFeature&, - const GeometryCollection&) override; + const GeometryCollection&, + const mbgl::ImagePositions&, + const PatternLayerMap&) override; + bool hasData() const override; void upload(gl::Context&) override; diff --git a/src/mbgl/renderer/buckets/heatmap_bucket.cpp b/src/mbgl/renderer/buckets/heatmap_bucket.cpp index eff0c60280..46d5f31599 100644 --- a/src/mbgl/renderer/buckets/heatmap_bucket.cpp +++ b/src/mbgl/renderer/buckets/heatmap_bucket.cpp @@ -39,7 +39,9 @@ bool HeatmapBucket::hasData() const { } void HeatmapBucket::addFeature(const GeometryTileFeature& feature, - const GeometryCollection& geometry) { + const GeometryCollection& geometry, + const ImagePositions&, + const PatternLayerMap&) { constexpr const uint16_t vertexLength = 4; for (auto& points : geometry) { @@ -87,7 +89,7 @@ void HeatmapBucket::addFeature(const GeometryTileFeature& feature, } for (auto& pair : paintPropertyBinders) { - pair.second.populateVertexVectors(feature, vertices.vertexSize()); + pair.second.populateVertexVectors(feature, vertices.vertexSize(), {}, {}); } } diff --git a/src/mbgl/renderer/buckets/heatmap_bucket.hpp b/src/mbgl/renderer/buckets/heatmap_bucket.hpp index 86b6f10296..b2d866d2a2 100644 --- a/src/mbgl/renderer/buckets/heatmap_bucket.hpp +++ b/src/mbgl/renderer/buckets/heatmap_bucket.hpp @@ -18,7 +18,9 @@ public: HeatmapBucket(const BucketParameters&, const std::vector<const RenderLayer*>&); void addFeature(const GeometryTileFeature&, - const GeometryCollection&) override; + const GeometryCollection&, + const ImagePositions&, + const PatternLayerMap&) override; bool hasData() const override; void upload(gl::Context&) override; diff --git a/src/mbgl/renderer/buckets/line_bucket.cpp b/src/mbgl/renderer/buckets/line_bucket.cpp index 80149edafe..2efb60c9ac 100644 --- a/src/mbgl/renderer/buckets/line_bucket.cpp +++ b/src/mbgl/renderer/buckets/line_bucket.cpp @@ -1,5 +1,4 @@ #include <mbgl/renderer/buckets/line_bucket.hpp> -#include <mbgl/renderer/layers/render_line_layer.hpp> #include <mbgl/renderer/bucket_parameters.hpp> #include <mbgl/style/layers/line_layer_impl.hpp> #include <mbgl/util/math.hpp> @@ -11,34 +10,45 @@ namespace mbgl { using namespace style; -LineBucket::LineBucket(const BucketParameters& parameters, - const std::vector<const RenderLayer*>& layers, - const style::LineLayoutProperties::Unevaluated& layout_) +LineBucket::LineBucket(const style::LineLayoutProperties::PossiblyEvaluated layout_, + std::map<std::string, RenderLinePaintProperties::PossiblyEvaluated> layerPaintProperties, + const float zoom_, + const uint32_t overscaling_) : Bucket(LayerType::Line), - layout(layout_.evaluate(PropertyEvaluationParameters(parameters.tileID.overscaledZ))), - overscaling(parameters.tileID.overscaleFactor()), - zoom(parameters.tileID.overscaledZ) { - for (const auto& layer : layers) { + layout(layout_), + zoom(zoom_), + overscaling(overscaling_) { + + for (const auto& pair : layerPaintProperties) { paintPropertyBinders.emplace( std::piecewise_construct, - std::forward_as_tuple(layer->getID()), + std::forward_as_tuple(pair.first), std::forward_as_tuple( - layer->as<RenderLineLayer>()->evaluated, - parameters.tileID.overscaledZ)); + pair.second, + zoom)); } } + void LineBucket::addFeature(const GeometryTileFeature& feature, - const GeometryCollection& geometryCollection) { + const GeometryCollection& geometryCollection, + const ImagePositions& patternPositions, + const PatternLayerMap& patternDependencies) { for (auto& line : geometryCollection) { addGeometry(line, feature); } for (auto& pair : paintPropertyBinders) { - pair.second.populateVertexVectors(feature, vertices.vertexSize()); + const auto it = patternDependencies.find(pair.first); + if (it != patternDependencies.end()){ + pair.second.populateVertexVectors(feature, vertices.vertexSize(), patternPositions, it->second); + } else { + pair.second.populateVertexVectors(feature, vertices.vertexSize(), patternPositions, {}); + } } } + /* * Sharp corners cause dashed lines to tilt because the distance along the line * is the same at both the inner and outer corners. To improve the appearance of @@ -130,7 +140,9 @@ void LineBucket::addGeometry(const GeometryCoordinates& coordinates, const Geome const float miterLimit = joinType == LineJoinType::Bevel ? 1.05f : float(layout.get<LineMiterLimit>()); - const double sharpCornerOffset = SHARP_CORNER_OFFSET * (float(util::EXTENT) / (util::tileSize * overscaling)); + const double sharpCornerOffset = overscaling == 0 ? + SHARP_CORNER_OFFSET * (float(util::EXTENT) / util::tileSize) : + SHARP_CORNER_OFFSET * (float(util::EXTENT) / (util::tileSize * overscaling)); const GeometryCoordinate firstCoordinate = coordinates[first]; const LineCapType beginCap = layout.get<LineCap>(); diff --git a/src/mbgl/renderer/buckets/line_bucket.hpp b/src/mbgl/renderer/buckets/line_bucket.hpp index 23d30ca416..6bd37076de 100644 --- a/src/mbgl/renderer/buckets/line_bucket.hpp +++ b/src/mbgl/renderer/buckets/line_bucket.hpp @@ -1,5 +1,4 @@ #pragma once - #include <mbgl/renderer/bucket.hpp> #include <mbgl/tile/geometry_tile_data.hpp> #include <mbgl/gl/vertex_buffer.hpp> @@ -7,6 +6,7 @@ #include <mbgl/programs/segment.hpp> #include <mbgl/programs/line_program.hpp> #include <mbgl/style/layers/line_layer_properties.hpp> +#include <mbgl/style/image_impl.hpp> #include <vector> @@ -17,19 +17,29 @@ class RenderLineLayer; class LineBucket : public Bucket { public: - LineBucket(const BucketParameters&, - const std::vector<const RenderLayer*>&, - const style::LineLayoutProperties::Unevaluated&); + + // These aliases are used by the PatternLayout template + using RenderLayerType = RenderLineLayer; + using PossiblyEvaluatedPaintProperties = RenderLinePaintProperties::PossiblyEvaluated; + using PossiblyEvaluatedLayoutProperties = style::LineLayoutProperties::PossiblyEvaluated; + + LineBucket(const PossiblyEvaluatedLayoutProperties layout, + std::map<std::string, PossiblyEvaluatedPaintProperties> layerPaintProperties, + const float zoom, + const uint32_t overscaling); void addFeature(const GeometryTileFeature&, - const GeometryCollection&) override; + const GeometryCollection&, + const mbgl::ImagePositions& patternPositions, + const PatternLayerMap&) override; + bool hasData() const override; void upload(gl::Context&) override; float getQueryRadius(const RenderLayer&) const override; - style::LineLayoutProperties::PossiblyEvaluated layout; + PossiblyEvaluatedLayoutProperties layout; gl::VertexVector<LineLayoutVertex> vertices; gl::IndexVector<gl::Triangles> triangles; @@ -63,8 +73,8 @@ private: std::ptrdiff_t e2; std::ptrdiff_t e3; - const uint32_t overscaling; const float zoom; + const uint32_t overscaling; float getLineWidth(const RenderLineLayer& layer) const; }; diff --git a/src/mbgl/renderer/cross_faded_property_evaluator.cpp b/src/mbgl/renderer/cross_faded_property_evaluator.cpp index 9a7af8636c..7be9c2bcf5 100644 --- a/src/mbgl/renderer/cross_faded_property_evaluator.cpp +++ b/src/mbgl/renderer/cross_faded_property_evaluator.cpp @@ -25,16 +25,9 @@ Faded<T> CrossFadedPropertyEvaluator<T>::operator()(const style::PropertyExpress template <typename T> Faded<T> CrossFadedPropertyEvaluator<T>::calculate(const T& min, const T& mid, const T& max) const { const float z = parameters.z; - const float fraction = z - std::floor(z); - const std::chrono::duration<float> d = parameters.defaultFadeDuration; - const float t = - d != std::chrono::duration<float>::zero() - ? std::min((parameters.now - parameters.zoomHistory.lastIntegerZoomTime) / d, 1.0f) - : 1.0f; - return z > parameters.zoomHistory.lastIntegerZoom - ? Faded<T> { min, mid, 2.0f, 1.0f, fraction + (1.0f - fraction) * t } - : Faded<T> { max, mid, 0.5f, 1.0f, 1 - (1 - t) * fraction }; + ? Faded<T> { min, mid } + : Faded<T> { max, mid }; } template class CrossFadedPropertyEvaluator<std::string>; diff --git a/src/mbgl/renderer/cross_faded_property_evaluator.hpp b/src/mbgl/renderer/cross_faded_property_evaluator.hpp index 1d17c5eb2f..e925b96fa3 100644 --- a/src/mbgl/renderer/cross_faded_property_evaluator.hpp +++ b/src/mbgl/renderer/cross_faded_property_evaluator.hpp @@ -11,9 +11,6 @@ class Faded { public: T from; T to; - float fromScale; - float toScale; - float t; }; template <typename T> diff --git a/src/mbgl/renderer/data_driven_property_evaluator.hpp b/src/mbgl/renderer/data_driven_property_evaluator.hpp index f9452cc572..d65ac36713 100644 --- a/src/mbgl/renderer/data_driven_property_evaluator.hpp +++ b/src/mbgl/renderer/data_driven_property_evaluator.hpp @@ -3,6 +3,7 @@ #include <mbgl/style/property_value.hpp> #include <mbgl/renderer/property_evaluation_parameters.hpp> #include <mbgl/renderer/possibly_evaluated_property_value.hpp> +#include <mbgl/renderer/cross_faded_property_evaluator.hpp> namespace mbgl { @@ -40,4 +41,43 @@ private: T defaultValue; }; +template <typename T> +class DataDrivenPropertyEvaluator<Faded<T>> { +public: + using ResultType = PossiblyEvaluatedPropertyValue<Faded<T>>; + + DataDrivenPropertyEvaluator(const PropertyEvaluationParameters& parameters_, T defaultValue_) + : parameters(parameters_), + defaultValue(std::move(defaultValue_)) {} + + ResultType operator()(const T& constant) const { + return ResultType(calculate(constant, constant, constant)); + } + + ResultType operator()(const style::Undefined& ) const { + return ResultType(calculate(defaultValue, defaultValue, defaultValue)); + } + + ResultType operator()(const style::PropertyExpression<T>& expression) const { + if (!expression.isFeatureConstant()) { + return ResultType(expression); + } else { + const T evaluated = expression.evaluate(floor(parameters.z)); + return ResultType(calculate(evaluated, evaluated, evaluated)); + } + } + + +private: + Faded<T> calculate(const T& min, const T& mid, const T& max) const { + const float z = parameters.z; + return z > parameters.zoomHistory.lastIntegerZoom + ? Faded<T> { min, mid } + : Faded<T> { max, mid }; + }; + + const PropertyEvaluationParameters& parameters; + T defaultValue; +}; + } // namespace mbgl diff --git a/src/mbgl/renderer/image_atlas.cpp b/src/mbgl/renderer/image_atlas.cpp index 8eee7c2095..b39c788ced 100644 --- a/src/mbgl/renderer/image_atlas.cpp +++ b/src/mbgl/renderer/image_atlas.cpp @@ -16,36 +16,56 @@ ImagePosition::ImagePosition(const mapbox::Bin& bin, const style::Image::Impl& i ) { } -ImageAtlas makeImageAtlas(const ImageMap& images) { +const mapbox::Bin& _packImage(mapbox::ShelfPack& pack, const style::Image::Impl& image, ImageAtlas& resultImage, ImageType imageType) { + const mapbox::Bin& bin = *pack.packOne(-1, + image.image.size.width + 2 * padding, + image.image.size.height + 2 * padding); + + resultImage.image.resize({ + static_cast<uint32_t>(pack.width()), + static_cast<uint32_t>(pack.height()) + }); + + PremultipliedImage::copy(image.image, + resultImage.image, + { 0, 0 }, + { + bin.x + padding, + bin.y + padding + }, + image.image.size); + uint32_t x = bin.x + padding, + y = bin.y + padding, + w = image.image.size.width, + h = image.image.size.height; + + if (imageType == ImageType::Pattern) { + // Add 1 pixel wrapped padding on each side of the image. + PremultipliedImage::copy(image.image, resultImage.image, { 0, h - 1 }, { x, y - 1 }, { w, 1 }); // T + PremultipliedImage::copy(image.image, resultImage.image, { 0, 0 }, { x, y + h }, { w, 1 }); // B + PremultipliedImage::copy(image.image, resultImage.image, { w - 1, 0 }, { x - 1, y }, { 1, h }); // L + PremultipliedImage::copy(image.image, resultImage.image, { 0, 0 }, { x + w, y }, { 1, h }); // R + } + return bin; +} + +ImageAtlas makeImageAtlas(const ImageMap& icons, const ImageMap& patterns) { ImageAtlas result; mapbox::ShelfPack::ShelfPackOptions options; options.autoResize = true; mapbox::ShelfPack pack(0, 0, options); - for (const auto& entry : images) { + for (const auto& entry : icons) { const style::Image::Impl& image = *entry.second; + const mapbox::Bin& bin = _packImage(pack, image, result, ImageType::Icon); + result.iconPositions.emplace(image.id, ImagePosition { bin, image }); + } - const mapbox::Bin& bin = *pack.packOne(-1, - image.image.size.width + 2 * padding, - image.image.size.height + 2 * padding); - - result.image.resize({ - static_cast<uint32_t>(pack.width()), - static_cast<uint32_t>(pack.height()) - }); - - PremultipliedImage::copy(image.image, - result.image, - { 0, 0 }, - { - bin.x + padding, - bin.y + padding - }, - image.image.size); - - result.positions.emplace(image.id, - ImagePosition { bin, image }); + for (const auto& entry : patterns) { + const style::Image::Impl& image = *entry.second; + const mapbox::Bin& bin = _packImage(pack, image, result, ImageType::Pattern); + result.patternPositions.emplace(image.id, ImagePosition { bin, image }); } pack.shrink(); diff --git a/src/mbgl/renderer/image_atlas.hpp b/src/mbgl/renderer/image_atlas.hpp index b3cc166eff..3af31a75f8 100644 --- a/src/mbgl/renderer/image_atlas.hpp +++ b/src/mbgl/renderer/image_atlas.hpp @@ -30,6 +30,12 @@ public: }}; } + std::array<uint16_t, 4> tlbr() const { + const auto _tl = tl(); + const auto _br = br(); + return {{ _tl[0], _tl[1], _br[0], _br[1] }}; + } + std::array<float, 2> displaySize() const { return {{ textureRect.w / pixelRatio, @@ -43,9 +49,10 @@ using ImagePositions = std::map<std::string, ImagePosition>; class ImageAtlas { public: PremultipliedImage image; - ImagePositions positions; + ImagePositions iconPositions; + ImagePositions patternPositions; }; -ImageAtlas makeImageAtlas(const ImageMap&); +ImageAtlas makeImageAtlas(const ImageMap&, const ImageMap&); } // namespace mbgl diff --git a/src/mbgl/renderer/image_manager.cpp b/src/mbgl/renderer/image_manager.cpp index 2ef6be0c4f..fc1f5bb167 100644 --- a/src/mbgl/renderer/image_manager.cpp +++ b/src/mbgl/renderer/image_manager.cpp @@ -67,7 +67,7 @@ void ImageManager::getImages(ImageRequestor& requestor, ImageRequestPair&& pair) bool hasAllDependencies = true; if (!isLoaded()) { for (const auto& dependency : pair.first) { - if (images.find(dependency) == images.end()) { + if (images.find(dependency.first) == images.end()) { hasAllDependencies = false; } } @@ -84,16 +84,17 @@ void ImageManager::removeRequestor(ImageRequestor& requestor) { } void ImageManager::notify(ImageRequestor& requestor, const ImageRequestPair& pair) const { - ImageMap response; + ImageMap iconMap; + ImageMap patternMap; for (const auto& dependency : pair.first) { - auto it = images.find(dependency); + auto it = images.find(dependency.first); if (it != images.end()) { - response.emplace(*it); + dependency.second == ImageType::Pattern ? patternMap.emplace(*it) : iconMap.emplace(*it); } } - requestor.onImagesAvailable(response, pair.second); + requestor.onImagesAvailable(iconMap, patternMap, pair.second); } void ImageManager::dumpDebugLogs() const { diff --git a/src/mbgl/renderer/image_manager.hpp b/src/mbgl/renderer/image_manager.hpp index f72ba9fb53..103491c58b 100644 --- a/src/mbgl/renderer/image_manager.hpp +++ b/src/mbgl/renderer/image_manager.hpp @@ -21,7 +21,7 @@ class Context; class ImageRequestor { public: virtual ~ImageRequestor() = default; - virtual void onImagesAvailable(ImageMap, uint64_t imageCorrelationID) = 0; + virtual void onImagesAvailable(ImageMap icons, ImageMap patterns, uint64_t imageCorrelationID) = 0; }; /* diff --git a/src/mbgl/renderer/layers/render_background_layer.cpp b/src/mbgl/renderer/layers/render_background_layer.cpp index 2dc5fe7339..ad85fe0cce 100644 --- a/src/mbgl/renderer/layers/render_background_layer.cpp +++ b/src/mbgl/renderer/layers/render_background_layer.cpp @@ -34,6 +34,7 @@ void RenderBackgroundLayer::transition(const TransitionParameters ¶meters) { void RenderBackgroundLayer::evaluate(const PropertyEvaluationParameters ¶meters) { evaluated = unevaluated.evaluate(parameters); + crossfade = parameters.getCrossfadeParameters(); passes = evaluated.get<style::BackgroundOpacity>() > 0 ? RenderPass::Translucent : RenderPass::None; @@ -43,6 +44,10 @@ bool RenderBackgroundLayer::hasTransition() const { return unevaluated.hasTransition(); } +bool RenderBackgroundLayer::hasCrossfade() const { + return crossfade.t != 1; +} + void RenderBackgroundLayer::render(PaintParameters& parameters, RenderSource*) { // Note that for bottommost layers without a pattern, the background color is drawn with // glClear rather than this method. @@ -97,7 +102,7 @@ void RenderBackgroundLayer::render(PaintParameters& parameters, RenderSource*) { parameters.imageManager.getPixelSize(), *imagePosA, *imagePosB, - evaluated.get<BackgroundPattern>(), + crossfade, tileID, parameters.state ) @@ -108,9 +113,9 @@ void RenderBackgroundLayer::render(PaintParameters& parameters, RenderSource*) { draw( parameters.programs.background, BackgroundProgram::UniformValues { - uniforms::u_matrix::Value{ parameters.matrixForTile(tileID) }, - uniforms::u_color::Value{ evaluated.get<BackgroundColor>() }, - uniforms::u_opacity::Value{ evaluated.get<BackgroundOpacity>() }, + uniforms::u_matrix::Value( parameters.matrixForTile(tileID) ), + uniforms::u_color::Value( evaluated.get<BackgroundColor>() ), + uniforms::u_opacity::Value( evaluated.get<BackgroundOpacity>() ), } ); } diff --git a/src/mbgl/renderer/layers/render_background_layer.hpp b/src/mbgl/renderer/layers/render_background_layer.hpp index a619670ee4..854c077a62 100644 --- a/src/mbgl/renderer/layers/render_background_layer.hpp +++ b/src/mbgl/renderer/layers/render_background_layer.hpp @@ -14,6 +14,7 @@ public: void transition(const TransitionParameters&) override; void evaluate(const PropertyEvaluationParameters&) override; bool hasTransition() const override; + bool hasCrossfade() const override; void render(PaintParameters&, RenderSource*) override; std::unique_ptr<Bucket> createBucket(const BucketParameters&, const std::vector<const RenderLayer*>&) const override; @@ -23,6 +24,8 @@ public: style::BackgroundPaintProperties::PossiblyEvaluated evaluated; const style::BackgroundLayer::Impl& impl() const; +private: + CrossfadeParameters crossfade; }; template <> diff --git a/src/mbgl/renderer/layers/render_circle_layer.cpp b/src/mbgl/renderer/layers/render_circle_layer.cpp index ce63ada770..af96e2e991 100644 --- a/src/mbgl/renderer/layers/render_circle_layer.cpp +++ b/src/mbgl/renderer/layers/render_circle_layer.cpp @@ -47,6 +47,10 @@ bool RenderCircleLayer::hasTransition() const { return unevaluated.hasTransition(); } +bool RenderCircleLayer::hasCrossfade() const { + return false; +} + void RenderCircleLayer::render(PaintParameters& parameters, RenderSource*) { if (parameters.pass == RenderPass::Opaque) { return; @@ -68,19 +72,19 @@ void RenderCircleLayer::render(PaintParameters& parameters, RenderSource*) { const auto allUniformValues = programInstance.computeAllUniformValues( CircleProgram::UniformValues { - uniforms::u_matrix::Value{ + uniforms::u_matrix::Value( tile.translatedMatrix(evaluated.get<CircleTranslate>(), evaluated.get<CircleTranslateAnchor>(), parameters.state) - }, - uniforms::u_scale_with_map::Value{ scaleWithMap }, - uniforms::u_extrude_scale::Value{ pitchWithMap + ), + uniforms::u_scale_with_map::Value( scaleWithMap ), + uniforms::u_extrude_scale::Value( pitchWithMap ? std::array<float, 2> {{ tile.id.pixelsToTileUnits(1, parameters.state.getZoom()), tile.id.pixelsToTileUnits(1, parameters.state.getZoom()) }} - : parameters.pixelsToGLUnits }, - uniforms::u_camera_to_center_distance::Value{ parameters.state.getCameraToCenterDistance() }, - uniforms::u_pitch_with_map::Value{ pitchWithMap } + : parameters.pixelsToGLUnits ), + uniforms::u_camera_to_center_distance::Value( parameters.state.getCameraToCenterDistance() ), + uniforms::u_pitch_with_map::Value( pitchWithMap ) }, paintPropertyBinders, evaluated, diff --git a/src/mbgl/renderer/layers/render_circle_layer.hpp b/src/mbgl/renderer/layers/render_circle_layer.hpp index c9eeae4652..53353fcdcb 100644 --- a/src/mbgl/renderer/layers/render_circle_layer.hpp +++ b/src/mbgl/renderer/layers/render_circle_layer.hpp @@ -14,6 +14,7 @@ public: void transition(const TransitionParameters&) override; void evaluate(const PropertyEvaluationParameters&) override; bool hasTransition() const override; + bool hasCrossfade() const override; void render(PaintParameters&, RenderSource*) override; bool queryIntersectsFeature( diff --git a/src/mbgl/renderer/layers/render_custom_layer.cpp b/src/mbgl/renderer/layers/render_custom_layer.cpp index be9f64d9eb..16c18447c5 100644 --- a/src/mbgl/renderer/layers/render_custom_layer.cpp +++ b/src/mbgl/renderer/layers/render_custom_layer.cpp @@ -38,6 +38,9 @@ void RenderCustomLayer::evaluate(const PropertyEvaluationParameters&) { bool RenderCustomLayer::hasTransition() const { return false; } +bool RenderCustomLayer::hasCrossfade() const { + return false; +} std::unique_ptr<Bucket> RenderCustomLayer::createBucket(const BucketParameters&, const std::vector<const RenderLayer*>&) const { assert(false); diff --git a/src/mbgl/renderer/layers/render_custom_layer.hpp b/src/mbgl/renderer/layers/render_custom_layer.hpp index 971d8d8f42..47d5bb3f40 100644 --- a/src/mbgl/renderer/layers/render_custom_layer.hpp +++ b/src/mbgl/renderer/layers/render_custom_layer.hpp @@ -13,6 +13,7 @@ public: void transition(const TransitionParameters&) final {} void evaluate(const PropertyEvaluationParameters&) override; bool hasTransition() const override; + bool hasCrossfade() const override; std::unique_ptr<Bucket> createBucket(const BucketParameters&, const std::vector<const RenderLayer*>&) const final; void render(PaintParameters&, RenderSource*) final; diff --git a/src/mbgl/renderer/layers/render_fill_extrusion_layer.cpp b/src/mbgl/renderer/layers/render_fill_extrusion_layer.cpp index 2f720284fc..08e9d609cd 100644 --- a/src/mbgl/renderer/layers/render_fill_extrusion_layer.cpp +++ b/src/mbgl/renderer/layers/render_fill_extrusion_layer.cpp @@ -12,6 +12,7 @@ #include <mbgl/geometry/feature_index.hpp> #include <mbgl/util/math.hpp> #include <mbgl/util/intersection_tests.hpp> +#include <mbgl/tile/geometry_tile.hpp> namespace mbgl { @@ -26,8 +27,18 @@ const style::FillExtrusionLayer::Impl& RenderFillExtrusionLayer::impl() const { return static_cast<const style::FillExtrusionLayer::Impl&>(*baseImpl); } -std::unique_ptr<Bucket> RenderFillExtrusionLayer::createBucket(const BucketParameters& parameters, const std::vector<const RenderLayer*>& layers) const { - return std::make_unique<FillExtrusionBucket>(parameters, layers); +std::unique_ptr<Bucket> RenderFillExtrusionLayer::createBucket(const BucketParameters&, const std::vector<const RenderLayer*>&) const { + assert(false); // Should be calling createLayout() instead. + return nullptr; +} + + +std::unique_ptr<PatternLayout<FillExtrusionBucket>> +RenderFillExtrusionLayer::createLayout(const BucketParameters& parameters, + const std::vector<const RenderLayer*>& group, + std::unique_ptr<GeometryTileLayer> layer, + ImageDependencies& imageDependencies) const { + return std::make_unique<PatternLayout<FillExtrusionBucket>>(parameters, group, std::move(layer), imageDependencies); } void RenderFillExtrusionLayer::transition(const TransitionParameters& parameters) { @@ -36,6 +47,7 @@ void RenderFillExtrusionLayer::transition(const TransitionParameters& parameters void RenderFillExtrusionLayer::evaluate(const PropertyEvaluationParameters& parameters) { evaluated = unevaluated.evaluate(parameters); + crossfade = parameters.getCrossfadeParameters(); passes = (evaluated.get<style::FillExtrusionOpacity>() > 0) ? (RenderPass::Translucent | RenderPass::Pass3D) @@ -46,6 +58,10 @@ bool RenderFillExtrusionLayer::hasTransition() const { return unevaluated.hasTransition(); } +bool RenderFillExtrusionLayer::hasCrossfade() const { + return crossfade.t != 1; +} + void RenderFillExtrusionLayer::render(PaintParameters& parameters, RenderSource*) { if (parameters.pass == RenderPass::Opaque) { return; @@ -68,8 +84,10 @@ void RenderFillExtrusionLayer::render(PaintParameters& parameters, RenderSource* parameters.context.setStencilMode(gl::StencilMode::disabled()); parameters.context.clear(Color{ 0.0f, 0.0f, 0.0f, 0.0f }, depthClearValue, {}); - auto draw = [&](auto& programInstance, const auto& tileBucket, auto&& uniformValues) { + auto draw = [&](auto& programInstance, const auto& tileBucket, auto&& uniformValues, + const optional<ImagePosition>& patternPositionA, const optional<ImagePosition>& patternPositionB) { const auto& paintPropertyBinders = tileBucket.paintPropertyBinders.at(getID()); + paintPropertyBinders.setPatternParameters(patternPositionA, patternPositionB, crossfade); const auto allUniformValues = programInstance.computeAllUniformValues( std::move(uniformValues), @@ -98,7 +116,7 @@ void RenderFillExtrusionLayer::render(PaintParameters& parameters, RenderSource* getID()); }; - if (evaluated.get<FillExtrusionPattern>().from.empty()) { + if (unevaluated.get<FillExtrusionPattern>().isUndefined()) { for (const RenderTile& tile : renderTiles) { auto bucket_ = tile.tile.getBucket<FillExtrusionBucket>(*baseImpl); if (!bucket_) { @@ -115,26 +133,22 @@ void RenderFillExtrusionLayer::render(PaintParameters& parameters, RenderSource* parameters.state), parameters.state, parameters.evaluatedLight - ) + ), + {}, {} ); } } else { - optional<ImagePosition> imagePosA = - parameters.imageManager.getPattern(evaluated.get<FillExtrusionPattern>().from); - optional<ImagePosition> imagePosB = - parameters.imageManager.getPattern(evaluated.get<FillExtrusionPattern>().to); - - if (!imagePosA || !imagePosB) { - return; - } - - parameters.imageManager.bind(parameters.context, 0); - for (const RenderTile& tile : renderTiles) { auto bucket_ = tile.tile.getBucket<FillExtrusionBucket>(*baseImpl); if (!bucket_) { continue; } + const auto fillPatternValue = evaluated.get<FillExtrusionPattern>().constantOr(mbgl::Faded<std::basic_string<char> >{"", ""}); + assert(dynamic_cast<GeometryTile*>(&tile.tile)); + GeometryTile& geometryTile = static_cast<GeometryTile&>(tile.tile); + optional<ImagePosition> patternPosA = geometryTile.getPattern(fillPatternValue.from); + optional<ImagePosition> patternPosB = geometryTile.getPattern(fillPatternValue.to); + parameters.context.bindTexture(*geometryTile.iconAtlasTexture, 0, gl::TextureFilter::Linear); FillExtrusionBucket& bucket = *bucket_; draw( @@ -144,11 +158,16 @@ void RenderFillExtrusionLayer::render(PaintParameters& parameters, RenderSource* tile.translatedClipMatrix(evaluated.get<FillExtrusionTranslate>(), evaluated.get<FillExtrusionTranslateAnchor>(), parameters.state), - parameters.imageManager.getPixelSize(), *imagePosA, *imagePosB, - evaluated.get<FillExtrusionPattern>(), tile.id, parameters.state, + geometryTile.iconAtlasTexture->size, + crossfade, + tile.id, + parameters.state, -std::pow(2, tile.id.canonical.z) / util::tileSize / 8.0f, + parameters.pixelRatio, parameters.evaluatedLight - ) + ), + patternPosA, + patternPosB ); } } @@ -168,9 +187,9 @@ void RenderFillExtrusionLayer::render(PaintParameters& parameters, RenderSource* const auto allUniformValues = programInstance.computeAllUniformValues( ExtrusionTextureProgram::UniformValues{ - uniforms::u_matrix::Value{ viewportMat }, uniforms::u_world::Value{ size }, - uniforms::u_image::Value{ 0 }, - uniforms::u_opacity::Value{ evaluated.get<FillExtrusionOpacity>() } + uniforms::u_matrix::Value( viewportMat ), uniforms::u_world::Value( size ), + uniforms::u_image::Value( 0 ), + uniforms::u_opacity::Value( evaluated.get<FillExtrusionOpacity>() ) }, paintAttributeData, properties, @@ -197,6 +216,17 @@ void RenderFillExtrusionLayer::render(PaintParameters& parameters, RenderSource* getID()); } } +style::FillExtrusionPaintProperties::PossiblyEvaluated RenderFillExtrusionLayer::paintProperties() const { + return FillExtrusionPaintProperties::PossiblyEvaluated { + evaluated.get<style::FillExtrusionOpacity>(), + evaluated.get<style::FillExtrusionColor>(), + evaluated.get<style::FillExtrusionTranslate>(), + evaluated.get<style::FillExtrusionTranslateAnchor>(), + evaluated.get<style::FillExtrusionPattern>(), + evaluated.get<style::FillExtrusionHeight>(), + evaluated.get<style::FillExtrusionBase>() + }; +} bool RenderFillExtrusionLayer::queryIntersectsFeature( const GeometryCoordinates& queryGeometry, diff --git a/src/mbgl/renderer/layers/render_fill_extrusion_layer.hpp b/src/mbgl/renderer/layers/render_fill_extrusion_layer.hpp index f7ba13c267..1a721d035b 100644 --- a/src/mbgl/renderer/layers/render_fill_extrusion_layer.hpp +++ b/src/mbgl/renderer/layers/render_fill_extrusion_layer.hpp @@ -8,15 +8,25 @@ namespace mbgl { +template <class B> +class PatternLayout; + +class FillExtrusionBucket; + class RenderFillExtrusionLayer: public RenderLayer { public: + using StyleLayerImpl = style::FillExtrusionLayer::Impl; + using PatternProperty = style::FillExtrusionPattern; + RenderFillExtrusionLayer(Immutable<style::FillExtrusionLayer::Impl>); ~RenderFillExtrusionLayer() final = default; void transition(const TransitionParameters&) override; void evaluate(const PropertyEvaluationParameters&) override; bool hasTransition() const override; + bool hasCrossfade() const override; void render(PaintParameters&, RenderSource*) override; + style::FillExtrusionPaintProperties::PossiblyEvaluated paintProperties() const; bool queryIntersectsFeature( const GeometryCoordinates&, @@ -28,6 +38,9 @@ public: std::unique_ptr<Bucket> createBucket(const BucketParameters&, const std::vector<const RenderLayer*>&) const override; + std::unique_ptr<PatternLayout<FillExtrusionBucket>> + createLayout(const BucketParameters&, const std::vector<const RenderLayer*>&, std::unique_ptr<GeometryTileLayer>, ImageDependencies&) const; + // Paint properties style::FillExtrusionPaintProperties::Unevaluated unevaluated; style::FillExtrusionPaintProperties::PossiblyEvaluated evaluated; @@ -35,6 +48,8 @@ public: const style::FillExtrusionLayer::Impl& impl() const; optional<OffscreenTexture> renderTexture; +private: + CrossfadeParameters crossfade; }; template <> diff --git a/src/mbgl/renderer/layers/render_fill_layer.cpp b/src/mbgl/renderer/layers/render_fill_layer.cpp index f03eb66c88..5d7ed02da8 100644 --- a/src/mbgl/renderer/layers/render_fill_layer.cpp +++ b/src/mbgl/renderer/layers/render_fill_layer.cpp @@ -10,6 +10,7 @@ #include <mbgl/geometry/feature_index.hpp> #include <mbgl/util/math.hpp> #include <mbgl/util/intersection_tests.hpp> +#include <mbgl/tile/geometry_tile.hpp> namespace mbgl { @@ -24,8 +25,17 @@ const style::FillLayer::Impl& RenderFillLayer::impl() const { return static_cast<const style::FillLayer::Impl&>(*baseImpl); } -std::unique_ptr<Bucket> RenderFillLayer::createBucket(const BucketParameters& parameters, const std::vector<const RenderLayer*>& layers) const { - return std::make_unique<FillBucket>(parameters, layers); +std::unique_ptr<Bucket> RenderFillLayer::createBucket(const BucketParameters&, const std::vector<const RenderLayer*>&) const { + assert(false); // Should be calling createLayout() instead. + return nullptr; +} + +std::unique_ptr<PatternLayout<FillBucket>> +RenderFillLayer::createLayout(const BucketParameters& parameters, + const std::vector<const RenderLayer*>& group, + std::unique_ptr<GeometryTileLayer> layer, + ImageDependencies& imageDependencies) const { + return std::make_unique<PatternLayout<FillBucket>>(parameters, group, std::move(layer), imageDependencies); } void RenderFillLayer::transition(const TransitionParameters& parameters) { @@ -34,6 +44,7 @@ void RenderFillLayer::transition(const TransitionParameters& parameters) { void RenderFillLayer::evaluate(const PropertyEvaluationParameters& parameters) { evaluated = unevaluated.evaluate(parameters); + crossfade = parameters.getCrossfadeParameters(); if (unevaluated.get<style::FillOutlineColor>().isUndefined()) { evaluated.get<style::FillOutlineColor>() = evaluated.get<style::FillColor>(); @@ -58,8 +69,12 @@ bool RenderFillLayer::hasTransition() const { return unevaluated.hasTransition(); } +bool RenderFillLayer::hasCrossfade() const { + return crossfade.t != 1; +} + void RenderFillLayer::render(PaintParameters& parameters, RenderSource*) { - if (evaluated.get<FillPattern>().from.empty()) { + if (unevaluated.get<FillPattern>().isUndefined()) { for (const RenderTile& tile : renderTiles) { auto bucket_ = tile.tile.getBucket<FillBucket>(*baseImpl); if (!bucket_) { @@ -78,12 +93,12 @@ void RenderFillLayer::render(PaintParameters& parameters, RenderSource*) { const auto allUniformValues = programInstance.computeAllUniformValues( FillProgram::UniformValues { - uniforms::u_matrix::Value{ + uniforms::u_matrix::Value( tile.translatedMatrix(evaluated.get<FillTranslate>(), evaluated.get<FillTranslateAnchor>(), parameters.state) - }, - uniforms::u_world::Value{ parameters.context.viewport.getCurrentValue().size }, + ), + uniforms::u_world::Value( parameters.context.viewport.getCurrentValue().size ), }, paintPropertyBinders, evaluated, @@ -138,17 +153,14 @@ void RenderFillLayer::render(PaintParameters& parameters, RenderSource*) { if (parameters.pass != RenderPass::Translucent) { return; } - - optional<ImagePosition> imagePosA = parameters.imageManager.getPattern(evaluated.get<FillPattern>().from); - optional<ImagePosition> imagePosB = parameters.imageManager.getPattern(evaluated.get<FillPattern>().to); - - if (!imagePosA || !imagePosB) { - return; - } - - parameters.imageManager.bind(parameters.context, 0); - + const auto fillPatternValue = evaluated.get<FillPattern>().constantOr(Faded<std::basic_string<char>>{"", ""}); for (const RenderTile& tile : renderTiles) { + assert(dynamic_cast<GeometryTile*>(&tile.tile)); + GeometryTile& geometryTile = static_cast<GeometryTile&>(tile.tile); + optional<ImagePosition> patternPosA = geometryTile.getPattern(fillPatternValue.from); + optional<ImagePosition> patternPosB = geometryTile.getPattern(fillPatternValue.to); + + parameters.context.bindTexture(*geometryTile.iconAtlasTexture, 0, gl::TextureFilter::Linear); auto bucket_ = tile.tile.getBucket<FillBucket>(*baseImpl); if (!bucket_) { continue; @@ -163,6 +175,7 @@ void RenderFillLayer::render(PaintParameters& parameters, RenderSource*) { auto& programInstance = program.get(evaluated); const auto& paintPropertyBinders = bucket.paintPropertyBinders.at(getID()); + paintPropertyBinders.setPatternParameters(patternPosA, patternPosB, crossfade); const auto allUniformValues = programInstance.computeAllUniformValues( FillPatternUniforms::values( @@ -170,12 +183,11 @@ void RenderFillLayer::render(PaintParameters& parameters, RenderSource*) { evaluated.get<FillTranslateAnchor>(), parameters.state), parameters.context.viewport.getCurrentValue().size, - parameters.imageManager.getPixelSize(), - *imagePosA, - *imagePosB, - evaluated.get<FillPattern>(), + geometryTile.iconAtlasTexture->size, + crossfade, tile.id, - parameters.state + parameters.state, + parameters.pixelRatio ), paintPropertyBinders, evaluated, @@ -220,6 +232,18 @@ void RenderFillLayer::render(PaintParameters& parameters, RenderSource*) { } } +style::FillPaintProperties::PossiblyEvaluated RenderFillLayer::paintProperties() const { + return FillPaintProperties::PossiblyEvaluated { + evaluated.get<style::FillAntialias>(), + evaluated.get<style::FillOpacity>(), + evaluated.get<style::FillColor>(), + evaluated.get<style::FillOutlineColor>(), + evaluated.get<style::FillTranslate>(), + evaluated.get<style::FillTranslateAnchor>(), + evaluated.get<style::FillPattern>() + }; +} + bool RenderFillLayer::queryIntersectsFeature( const GeometryCoordinates& queryGeometry, const GeometryTileFeature& feature, diff --git a/src/mbgl/renderer/layers/render_fill_layer.hpp b/src/mbgl/renderer/layers/render_fill_layer.hpp index bd195fb828..5a3c05387d 100644 --- a/src/mbgl/renderer/layers/render_fill_layer.hpp +++ b/src/mbgl/renderer/layers/render_fill_layer.hpp @@ -3,18 +3,26 @@ #include <mbgl/renderer/render_layer.hpp> #include <mbgl/style/layers/fill_layer_impl.hpp> #include <mbgl/style/layers/fill_layer_properties.hpp> +#include <mbgl/layout/pattern_layout.hpp> namespace mbgl { +class FillBucket; + class RenderFillLayer: public RenderLayer { public: + using StyleLayerImpl = style::FillLayer::Impl; + using PatternProperty = style::FillPattern; + RenderFillLayer(Immutable<style::FillLayer::Impl>); ~RenderFillLayer() final = default; void transition(const TransitionParameters&) override; void evaluate(const PropertyEvaluationParameters&) override; bool hasTransition() const override; + bool hasCrossfade() const override; void render(PaintParameters&, RenderSource*) override; + style::FillPaintProperties::PossiblyEvaluated paintProperties() const; bool queryIntersectsFeature( const GeometryCoordinates&, @@ -26,11 +34,17 @@ public: std::unique_ptr<Bucket> createBucket(const BucketParameters&, const std::vector<const RenderLayer*>&) const override; + std::unique_ptr<PatternLayout<FillBucket>> + createLayout(const BucketParameters&, const std::vector<const RenderLayer*>&, std::unique_ptr<GeometryTileLayer>, ImageDependencies&) const; + // Paint properties style::FillPaintProperties::Unevaluated unevaluated; style::FillPaintProperties::PossiblyEvaluated evaluated; const style::FillLayer::Impl& impl() const; +private: + CrossfadeParameters crossfade; + }; template <> diff --git a/src/mbgl/renderer/layers/render_heatmap_layer.cpp b/src/mbgl/renderer/layers/render_heatmap_layer.cpp index c9ca477cbb..8e24cf8f32 100644 --- a/src/mbgl/renderer/layers/render_heatmap_layer.cpp +++ b/src/mbgl/renderer/layers/render_heatmap_layer.cpp @@ -45,6 +45,10 @@ bool RenderHeatmapLayer::hasTransition() const { return unevaluated.hasTransition(); } +bool RenderHeatmapLayer::hasCrossfade() const { + return false; +} + void RenderHeatmapLayer::render(PaintParameters& parameters, RenderSource*) { if (parameters.pass == RenderPass::Opaque) { return; @@ -101,9 +105,9 @@ void RenderHeatmapLayer::render(PaintParameters& parameters, RenderSource*) { const auto allUniformValues = programInstance.computeAllUniformValues( HeatmapProgram::UniformValues { - uniforms::u_intensity::Value{ evaluated.get<style::HeatmapIntensity>() }, - uniforms::u_matrix::Value{ tile.matrix }, - uniforms::heatmap::u_extrude_scale::Value{ extrudeScale } + uniforms::u_intensity::Value( evaluated.get<style::HeatmapIntensity>() ), + uniforms::u_matrix::Value( tile.matrix ), + uniforms::heatmap::u_extrude_scale::Value( extrudeScale ) }, paintPropertyBinders, evaluated, @@ -147,10 +151,10 @@ void RenderHeatmapLayer::render(PaintParameters& parameters, RenderSource*) { const auto allUniformValues = programInstance.computeAllUniformValues( HeatmapTextureProgram::UniformValues{ - uniforms::u_matrix::Value{ viewportMat }, uniforms::u_world::Value{ size }, - uniforms::u_image::Value{ 0 }, - uniforms::u_color_ramp::Value{ 1 }, - uniforms::u_opacity::Value{ evaluated.get<HeatmapOpacity>() } + uniforms::u_matrix::Value( viewportMat ), uniforms::u_world::Value( size ), + uniforms::u_image::Value( 0 ), + uniforms::u_color_ramp::Value( 1 ), + uniforms::u_opacity::Value( evaluated.get<HeatmapOpacity>() ) }, paintAttributeData, properties, diff --git a/src/mbgl/renderer/layers/render_heatmap_layer.hpp b/src/mbgl/renderer/layers/render_heatmap_layer.hpp index 29fad7d8b8..6f8163ebf1 100644 --- a/src/mbgl/renderer/layers/render_heatmap_layer.hpp +++ b/src/mbgl/renderer/layers/render_heatmap_layer.hpp @@ -16,6 +16,7 @@ public: void transition(const TransitionParameters&) override; void evaluate(const PropertyEvaluationParameters&) override; bool hasTransition() const override; + bool hasCrossfade() const override; void render(PaintParameters&, RenderSource*) override; bool queryIntersectsFeature( diff --git a/src/mbgl/renderer/layers/render_hillshade_layer.cpp b/src/mbgl/renderer/layers/render_hillshade_layer.cpp index 8bcd3f1837..b96030f44d 100644 --- a/src/mbgl/renderer/layers/render_hillshade_layer.cpp +++ b/src/mbgl/renderer/layers/render_hillshade_layer.cpp @@ -56,6 +56,10 @@ bool RenderHillshadeLayer::hasTransition() const { return unevaluated.hasTransition(); } +bool RenderHillshadeLayer::hasCrossfade() const { + return false; +} + void RenderHillshadeLayer::render(PaintParameters& parameters, RenderSource* src) { if (parameters.pass != RenderPass::Translucent && parameters.pass != RenderPass::Pass3D) return; @@ -75,13 +79,13 @@ void RenderHillshadeLayer::render(PaintParameters& parameters, RenderSource* src const auto allUniformValues = programInstance.computeAllUniformValues( HillshadeProgram::UniformValues { - uniforms::u_matrix::Value{ matrix }, - uniforms::u_image::Value{ 0 }, - uniforms::u_highlight::Value{ evaluated.get<HillshadeHighlightColor>() }, - uniforms::u_shadow::Value{ evaluated.get<HillshadeShadowColor>() }, - uniforms::u_accent::Value{ evaluated.get<HillshadeAccentColor>() }, - uniforms::u_light::Value{ getLight(parameters) }, - uniforms::u_latrange::Value{ getLatRange(id) }, + uniforms::u_matrix::Value( matrix ), + uniforms::u_image::Value( 0 ), + uniforms::u_highlight::Value( evaluated.get<HillshadeHighlightColor>() ), + uniforms::u_shadow::Value( evaluated.get<HillshadeShadowColor>() ), + uniforms::u_accent::Value( evaluated.get<HillshadeAccentColor>() ), + uniforms::u_light::Value( getLight(parameters) ), + uniforms::u_latrange::Value( getLatRange(id) ), }, paintAttributeData, evaluated, @@ -137,11 +141,11 @@ void RenderHillshadeLayer::render(PaintParameters& parameters, RenderSource* src const auto allUniformValues = programInstance.computeAllUniformValues( HillshadePrepareProgram::UniformValues { - uniforms::u_matrix::Value { mat }, - uniforms::u_dimension::Value { {{uint16_t(tilesize * 2), uint16_t(tilesize * 2) }} }, - uniforms::u_zoom::Value{ float(tile.id.canonical.z) }, - uniforms::u_maxzoom::Value{ float(maxzoom) }, - uniforms::u_image::Value{ 0 } + uniforms::u_matrix::Value( mat ), + uniforms::u_dimension::Value( {{uint16_t(tilesize * 2), uint16_t(tilesize * 2)}} ), + uniforms::u_zoom::Value( float(tile.id.canonical.z) ), + uniforms::u_maxzoom::Value( float(maxzoom) ), + uniforms::u_image::Value( 0 ) }, paintAttributeData, properties, diff --git a/src/mbgl/renderer/layers/render_hillshade_layer.hpp b/src/mbgl/renderer/layers/render_hillshade_layer.hpp index 13093ee7ef..f88f1cd12f 100644 --- a/src/mbgl/renderer/layers/render_hillshade_layer.hpp +++ b/src/mbgl/renderer/layers/render_hillshade_layer.hpp @@ -15,6 +15,7 @@ public: void transition(const TransitionParameters&) override; void evaluate(const PropertyEvaluationParameters&) override; bool hasTransition() const override; + bool hasCrossfade() const override; void render(PaintParameters&, RenderSource* src) override; diff --git a/src/mbgl/renderer/layers/render_line_layer.cpp b/src/mbgl/renderer/layers/render_line_layer.cpp index f204c909e1..ff8a98c950 100644 --- a/src/mbgl/renderer/layers/render_line_layer.cpp +++ b/src/mbgl/renderer/layers/render_line_layer.cpp @@ -11,6 +11,7 @@ #include <mbgl/geometry/feature_index.hpp> #include <mbgl/util/math.hpp> #include <mbgl/util/intersection_tests.hpp> +#include <mbgl/tile/geometry_tile.hpp> namespace mbgl { @@ -26,8 +27,17 @@ const style::LineLayer::Impl& RenderLineLayer::impl() const { return static_cast<const style::LineLayer::Impl&>(*baseImpl); } -std::unique_ptr<Bucket> RenderLineLayer::createBucket(const BucketParameters& parameters, const std::vector<const RenderLayer*>& layers) const { - return std::make_unique<LineBucket>(parameters, layers, impl().layout); +std::unique_ptr<Bucket> RenderLineLayer::createBucket(const BucketParameters&, const std::vector<const RenderLayer*>&) const { + assert(false); // Should be calling createLayout() instead. + return nullptr; +} + +std::unique_ptr<PatternLayout<LineBucket>> +RenderLineLayer::createLayout(const BucketParameters& parameters, + const std::vector<const RenderLayer*>& group, + std::unique_ptr<GeometryTileLayer> layer, + ImageDependencies& imageDependencies) const { + return std::make_unique<PatternLayout<LineBucket>>(parameters, group, std::move(layer), imageDependencies); } void RenderLineLayer::transition(const TransitionParameters& parameters) { @@ -41,7 +51,9 @@ void RenderLineLayer::evaluate(const PropertyEvaluationParameters& parameters) { dashArrayParams.useIntegerZoom = true; evaluated = RenderLinePaintProperties::PossiblyEvaluated( - unevaluated.evaluate(parameters).concat(extra.evaluate(dashArrayParams))); + unevaluated.evaluate(parameters).concat(extra.evaluate(dashArrayParams))); + + crossfade = parameters.getCrossfadeParameters(); passes = (evaluated.get<style::LineOpacity>().constantOr(1.0) > 0 && evaluated.get<style::LineColor>().constantOr(Color::black()).a > 0 @@ -53,6 +65,10 @@ bool RenderLineLayer::hasTransition() const { return unevaluated.hasTransition(); } +bool RenderLineLayer::hasCrossfade() const { + return crossfade.t != 1; +} + void RenderLineLayer::render(PaintParameters& parameters, RenderSource*) { if (parameters.pass == RenderPass::Opaque) { return; @@ -65,11 +81,13 @@ void RenderLineLayer::render(PaintParameters& parameters, RenderSource*) { } LineBucket& bucket = *bucket_; - auto draw = [&] (auto& program, auto&& uniformValues) { + auto draw = [&] (auto& program, auto&& uniformValues, const optional<ImagePosition>& patternPositionA, const optional<ImagePosition>& patternPositionB) { auto& programInstance = program.get(evaluated); const auto& paintPropertyBinders = bucket.paintPropertyBinders.at(getID()); + paintPropertyBinders.setPatternParameters(patternPositionA, patternPositionB, crossfade); + const auto allUniformValues = programInstance.computeAllUniformValues( std::move(uniformValues), paintPropertyBinders, @@ -115,16 +133,18 @@ void RenderLineLayer::render(PaintParameters& parameters, RenderSource*) { parameters.pixelsToGLUnits, posA, posB, - parameters.lineAtlas.getSize().width)); - - } else if (!evaluated.get<LinePattern>().from.empty()) { - optional<ImagePosition> posA = parameters.imageManager.getPattern(evaluated.get<LinePattern>().from); - optional<ImagePosition> posB = parameters.imageManager.getPattern(evaluated.get<LinePattern>().to); + crossfade, + parameters.lineAtlas.getSize().width), {}, {}); - if (!posA || !posB) - return; + } else if (!unevaluated.get<LinePattern>().isUndefined()) { + const auto linePatternValue = evaluated.get<LinePattern>().constantOr(Faded<std::basic_string<char>>{ "", ""}); + assert(dynamic_cast<GeometryTile*>(&tile.tile)); + GeometryTile& geometryTile = static_cast<GeometryTile&>(tile.tile); + parameters.context.bindTexture(*geometryTile.iconAtlasTexture, 0, gl::TextureFilter::Linear); + const Size texsize = geometryTile.iconAtlasTexture->size; - parameters.imageManager.bind(parameters.context, 0); + optional<ImagePosition> posA = geometryTile.getPattern(linePatternValue.from); + optional<ImagePosition> posB = geometryTile.getPattern(linePatternValue.to); draw(parameters.programs.linePattern, LinePatternProgram::uniformValues( @@ -132,9 +152,11 @@ void RenderLineLayer::render(PaintParameters& parameters, RenderSource*) { tile, parameters.state, parameters.pixelsToGLUnits, - parameters.imageManager.getPixelSize(), + texsize, + crossfade, + parameters.pixelRatio), *posA, - *posB)); + *posB); } else if (!unevaluated.get<LineGradient>().getValue().isUndefined()) { if (!colorRampTexture) { colorRampTexture = parameters.context.createTexture(colorRamp); @@ -146,14 +168,14 @@ void RenderLineLayer::render(PaintParameters& parameters, RenderSource*) { evaluated, tile, parameters.state, - parameters.pixelsToGLUnits)); + parameters.pixelsToGLUnits), {}, {}); } else { draw(parameters.programs.line, LineProgram::uniformValues( evaluated, tile, parameters.state, - parameters.pixelsToGLUnits)); + parameters.pixelsToGLUnits), {}, {}); } } } @@ -240,6 +262,24 @@ void RenderLineLayer::updateColorRamp() { } } +RenderLinePaintProperties::PossiblyEvaluated RenderLineLayer::paintProperties() const { + return RenderLinePaintProperties::PossiblyEvaluated { + evaluated.get<style::LineOpacity>(), + evaluated.get<style::LineColor>(), + evaluated.get<style::LineTranslate>(), + evaluated.get<style::LineTranslateAnchor>(), + evaluated.get<style::LineWidth>(), + evaluated.get<style::LineGapWidth>(), + evaluated.get<style::LineOffset>(), + evaluated.get<style::LineBlur>(), + evaluated.get<style::LineDasharray>(), + evaluated.get<style::LinePattern>(), + evaluated.get<style::LineGradient>(), + evaluated.get<LineFloorwidth>() + + }; +} + float RenderLineLayer::getLineWidth(const GeometryTileFeature& feature, const float zoom) const { float lineWidth = evaluated.get<style::LineWidth>() .evaluate(feature, zoom, style::LineWidth::defaultValue()); diff --git a/src/mbgl/renderer/layers/render_line_layer.hpp b/src/mbgl/renderer/layers/render_line_layer.hpp index 1e0100548a..19ccccfb39 100644 --- a/src/mbgl/renderer/layers/render_line_layer.hpp +++ b/src/mbgl/renderer/layers/render_line_layer.hpp @@ -4,7 +4,8 @@ #include <mbgl/style/layers/line_layer_impl.hpp> #include <mbgl/style/layers/line_layer_properties.hpp> #include <mbgl/programs/uniforms.hpp> -#include <mbgl/util/image.hpp> +#include <mbgl/style/image_impl.hpp> +#include <mbgl/layout/pattern_layout.hpp> namespace mbgl { @@ -16,16 +17,24 @@ class RenderLinePaintProperties : public style::ConcatenateProperties< style::LinePaintProperties, style::Properties<LineFloorwidth>> {}; +class LineBucket; + class RenderLineLayer: public RenderLayer { public: + using StyleLayerImpl = style::LineLayer::Impl; + using PatternProperty = style::LinePattern; + RenderLineLayer(Immutable<style::LineLayer::Impl>); ~RenderLineLayer() final = default; void transition(const TransitionParameters&) override; void evaluate(const PropertyEvaluationParameters&) override; bool hasTransition() const override; + bool hasCrossfade() const override; void render(PaintParameters&, RenderSource*) override; + RenderLinePaintProperties::PossiblyEvaluated paintProperties() const; + bool queryIntersectsFeature( const GeometryCoordinates&, const GeometryTileFeature&, @@ -37,7 +46,10 @@ public: void updateColorRamp(); std::unique_ptr<Bucket> createBucket(const BucketParameters&, const std::vector<const RenderLayer*>&) const override; - + std::unique_ptr<PatternLayout<LineBucket>> createLayout(const BucketParameters&, + const std::vector<const RenderLayer*>&, + std::unique_ptr<GeometryTileLayer>, + ImageDependencies&) const; // Paint properties style::LinePaintProperties::Unevaluated unevaluated; RenderLinePaintProperties::PossiblyEvaluated evaluated; @@ -46,6 +58,7 @@ public: private: float getLineWidth(const GeometryTileFeature&, const float) const; + CrossfadeParameters crossfade; PremultipliedImage colorRamp; optional<gl::Texture> colorRampTexture; }; diff --git a/src/mbgl/renderer/layers/render_raster_layer.cpp b/src/mbgl/renderer/layers/render_raster_layer.cpp index e2524697b5..b8df71b7c1 100644 --- a/src/mbgl/renderer/layers/render_raster_layer.cpp +++ b/src/mbgl/renderer/layers/render_raster_layer.cpp @@ -41,6 +41,10 @@ bool RenderRasterLayer::hasTransition() const { return unevaluated.hasTransition(); } +bool RenderRasterLayer::hasCrossfade() const { + return false; +} + static float saturationFactor(float saturation) { if (saturation > 0) { return 1 - 1 / (1.001 - saturation); @@ -83,19 +87,19 @@ void RenderRasterLayer::render(PaintParameters& parameters, RenderSource* source const auto allUniformValues = programInstance.computeAllUniformValues( RasterProgram::UniformValues { - uniforms::u_matrix::Value{ matrix }, - uniforms::u_image0::Value{ 0 }, - uniforms::u_image1::Value{ 1 }, - uniforms::u_opacity::Value{ evaluated.get<RasterOpacity>() }, - uniforms::u_fade_t::Value{ 1 }, - uniforms::u_brightness_low::Value{ evaluated.get<RasterBrightnessMin>() }, - uniforms::u_brightness_high::Value{ evaluated.get<RasterBrightnessMax>() }, - uniforms::u_saturation_factor::Value{ saturationFactor(evaluated.get<RasterSaturation>()) }, - uniforms::u_contrast_factor::Value{ contrastFactor(evaluated.get<RasterContrast>()) }, - uniforms::u_spin_weights::Value{ spinWeights(evaluated.get<RasterHueRotate>()) }, - uniforms::u_buffer_scale::Value{ 1.0f }, - uniforms::u_scale_parent::Value{ 1.0f }, - uniforms::u_tl_parent::Value{ std::array<float, 2> {{ 0.0f, 0.0f }} }, + uniforms::u_matrix::Value( matrix ), + uniforms::u_image0::Value( 0 ), + uniforms::u_image1::Value( 1 ), + uniforms::u_opacity::Value( evaluated.get<RasterOpacity>() ), + uniforms::u_fade_t::Value( 1 ), + uniforms::u_brightness_low::Value( evaluated.get<RasterBrightnessMin>() ), + uniforms::u_brightness_high::Value( evaluated.get<RasterBrightnessMax>() ), + uniforms::u_saturation_factor::Value( saturationFactor(evaluated.get<RasterSaturation>()) ), + uniforms::u_contrast_factor::Value( contrastFactor(evaluated.get<RasterContrast>()) ), + uniforms::u_spin_weights::Value( spinWeights(evaluated.get<RasterHueRotate>()) ), + uniforms::u_buffer_scale::Value( 1.0f ), + uniforms::u_scale_parent::Value( 1.0f ), + uniforms::u_tl_parent::Value( std::array<float, 2> {{ 0.0f, 0.0f }} ), }, paintAttributeData, evaluated, diff --git a/src/mbgl/renderer/layers/render_raster_layer.hpp b/src/mbgl/renderer/layers/render_raster_layer.hpp index 87de316f7c..a8633c4d5e 100644 --- a/src/mbgl/renderer/layers/render_raster_layer.hpp +++ b/src/mbgl/renderer/layers/render_raster_layer.hpp @@ -14,6 +14,7 @@ public: void transition(const TransitionParameters&) override; void evaluate(const PropertyEvaluationParameters&) override; bool hasTransition() const override; + bool hasCrossfade() const override; void render(PaintParameters&, RenderSource*) override; diff --git a/src/mbgl/renderer/layers/render_symbol_layer.cpp b/src/mbgl/renderer/layers/render_symbol_layer.cpp index f9e4e7c043..cf65e29048 100644 --- a/src/mbgl/renderer/layers/render_symbol_layer.cpp +++ b/src/mbgl/renderer/layers/render_symbol_layer.cpp @@ -69,6 +69,10 @@ bool RenderSymbolLayer::hasTransition() const { return unevaluated.hasTransition(); } +bool RenderSymbolLayer::hasCrossfade() const { + return false; +} + void RenderSymbolLayer::render(PaintParameters& parameters, RenderSource*) { if (parameters.pass == RenderPass::Opaque) { return; @@ -251,9 +255,9 @@ void RenderSymbolLayer::render(PaintParameters& parameters, RenderSource*) { gl::StencilMode::disabled(), parameters.colorModeForRenderPass(), CollisionBoxProgram::UniformValues { - uniforms::u_matrix::Value{ tile.matrix }, - uniforms::u_extrude_scale::Value{ extrudeScale }, - uniforms::u_camera_to_center_distance::Value{ parameters.state.getCameraToCenterDistance() } + uniforms::u_matrix::Value( tile.matrix ), + uniforms::u_extrude_scale::Value( extrudeScale ), + uniforms::u_camera_to_center_distance::Value( parameters.state.getCameraToCenterDistance() ) }, *bucket.collisionBox.vertexBuffer, *bucket.collisionBox.dynamicVertexBuffer, @@ -285,10 +289,10 @@ void RenderSymbolLayer::render(PaintParameters& parameters, RenderSource*) { gl::StencilMode::disabled(), parameters.colorModeForRenderPass(), CollisionCircleProgram::UniformValues { - uniforms::u_matrix::Value{ tile.matrix }, - uniforms::u_extrude_scale::Value{ extrudeScale }, - uniforms::u_overscale_factor::Value{ float(tile.tile.id.overscaleFactor()) }, - uniforms::u_camera_to_center_distance::Value{ parameters.state.getCameraToCenterDistance() } + uniforms::u_matrix::Value( tile.matrix ), + uniforms::u_extrude_scale::Value( extrudeScale ), + uniforms::u_overscale_factor::Value( float(tile.tile.id.overscaleFactor()) ), + uniforms::u_camera_to_center_distance::Value( parameters.state.getCameraToCenterDistance() ) }, *bucket.collisionCircle.vertexBuffer, *bucket.collisionCircle.dynamicVertexBuffer, diff --git a/src/mbgl/renderer/layers/render_symbol_layer.hpp b/src/mbgl/renderer/layers/render_symbol_layer.hpp index 5b73b30294..efdcf0e932 100644 --- a/src/mbgl/renderer/layers/render_symbol_layer.hpp +++ b/src/mbgl/renderer/layers/render_symbol_layer.hpp @@ -64,6 +64,7 @@ public: void transition(const TransitionParameters&) override; void evaluate(const PropertyEvaluationParameters&) override; bool hasTransition() const override; + bool hasCrossfade() const override; void render(PaintParameters&, RenderSource*) override; style::IconPaintProperties::PossiblyEvaluated iconPaintProperties() const; diff --git a/src/mbgl/renderer/paint_property_binder.hpp b/src/mbgl/renderer/paint_property_binder.hpp index 29eb716785..dd204743b3 100644 --- a/src/mbgl/renderer/paint_property_binder.hpp +++ b/src/mbgl/renderer/paint_property_binder.hpp @@ -7,6 +7,11 @@ #include <mbgl/util/type_list.hpp> #include <mbgl/renderer/possibly_evaluated_property_value.hpp> #include <mbgl/renderer/paint_property_statistics.hpp> +#include <mbgl/renderer/cross_faded_property_evaluator.hpp> +#include <mbgl/util/variant.hpp> +#include <mbgl/renderer/image_atlas.hpp> +#include <mbgl/util/indexed_tuple.hpp> +#include <mbgl/layout/pattern_layout.hpp> #include <bitset> @@ -72,54 +77,92 @@ std::array<float, N*2> zoomInterpolatedAttributeValue(const std::array<float, N> Note that the shader source varies depending on whether we're using a uniform or attribute. Like GL JS, we dynamically compile shaders at runtime to accomodate this. */ -template <class T, class... As> + +template <class T, class UniformValueType, class PossiblyEvaluatedType, class... As> class PaintPropertyBinder { public: virtual ~PaintPropertyBinder() = default; - virtual void populateVertexVector(const GeometryTileFeature& feature, std::size_t length) = 0; + virtual void populateVertexVector(const GeometryTileFeature& feature, std::size_t length, const ImagePositions&, const optional<PatternDependency>&) = 0; virtual void upload(gl::Context& context) = 0; - virtual optional<gl::AttributeBinding> attributeBinding(const PossiblyEvaluatedPropertyValue<T>& currentValue) const = 0; - virtual float interpolationFactor(float currentZoom) const = 0; - virtual T uniformValue(const PossiblyEvaluatedPropertyValue<T>& currentValue) const = 0; + virtual void setPatternParameters(const optional<ImagePosition>&, const optional<ImagePosition>&, CrossfadeParameters&) = 0; + virtual std::tuple<ExpandToType<As, optional<gl::AttributeBinding>>...> attributeBinding(const PossiblyEvaluatedType& currentValue) const = 0; + virtual std::tuple<ExpandToType<As, float>...> interpolationFactor(float currentZoom) const = 0; + virtual std::tuple<ExpandToType<As, UniformValueType>...> uniformValue(const PossiblyEvaluatedType& currentValue) const = 0; - static std::unique_ptr<PaintPropertyBinder> create(const PossiblyEvaluatedPropertyValue<T>& value, float zoom, T defaultValue); + static std::unique_ptr<PaintPropertyBinder> create(const PossiblyEvaluatedType& value, float zoom, T defaultValue); PaintPropertyStatistics<T> statistics; }; template <class T, class A> -class ConstantPaintPropertyBinder : public PaintPropertyBinder<T, A> { +class ConstantPaintPropertyBinder : public PaintPropertyBinder<T, T, PossiblyEvaluatedPropertyValue<T>, A> { public: ConstantPaintPropertyBinder(T constant_) : constant(std::move(constant_)) { } - void populateVertexVector(const GeometryTileFeature&, std::size_t) override {} + void populateVertexVector(const GeometryTileFeature&, std::size_t, const ImagePositions&, const optional<PatternDependency>&) override {} void upload(gl::Context&) override {} + void setPatternParameters(const optional<ImagePosition>&, const optional<ImagePosition>&, CrossfadeParameters&) override {}; - optional<gl::AttributeBinding> attributeBinding(const PossiblyEvaluatedPropertyValue<T>&) const override { - return {}; + std::tuple<optional<gl::AttributeBinding>> attributeBinding(const PossiblyEvaluatedPropertyValue<T>&) const override { + return std::tuple<optional<gl::AttributeBinding>> {}; } - float interpolationFactor(float) const override { - return 0.0f; + std::tuple<float> interpolationFactor(float) const override { + return std::tuple<float> { 0.0f }; } - T uniformValue(const PossiblyEvaluatedPropertyValue<T>& currentValue) const override { - return currentValue.constantOr(constant); + std::tuple<T> uniformValue(const PossiblyEvaluatedPropertyValue<T>& currentValue) const override { + return std::tuple<T> { currentValue.constantOr(constant) }; } private: T constant; }; +template <class T, class... As> +class ConstantCrossFadedPaintPropertyBinder : public PaintPropertyBinder<T, std::array<uint16_t, 4>,PossiblyEvaluatedPropertyValue<Faded<T>>, As...> { +public: + ConstantCrossFadedPaintPropertyBinder(Faded<T> constant_) + : constant(std::move(constant_)), constantPatternPositions({}) { + } + + void populateVertexVector(const GeometryTileFeature&, std::size_t, const ImagePositions&, const optional<PatternDependency>&) override {} + void upload(gl::Context&) override {} + + void setPatternParameters(const optional<ImagePosition>& posA, const optional<ImagePosition>& posB, CrossfadeParameters&) override { + if (!posA && !posB) { + return; + } else { + constantPatternPositions = std::tuple<std::array<uint16_t, 4>, std::array<uint16_t, 4>> { posB->tlbr(), posA->tlbr() }; + } + } + + std::tuple<optional<gl::AttributeBinding>, optional<gl::AttributeBinding>> + attributeBinding(const PossiblyEvaluatedPropertyValue<Faded<T>>&) const override { + return std::tuple<optional<gl::AttributeBinding>, optional<gl::AttributeBinding>> {}; + } + + std::tuple<float, float> interpolationFactor(float) const override { + return std::tuple<float, float> { 0.0f, 0.0f }; + } + + std::tuple<std::array<uint16_t, 4>, std::array<uint16_t, 4>> uniformValue(const PossiblyEvaluatedPropertyValue<Faded<T>>&) const override { + return constantPatternPositions; + } + +private: + Faded<T> constant; + std::tuple<std::array<uint16_t, 4>, std::array<uint16_t, 4>> constantPatternPositions; +}; + template <class T, class A> -class SourceFunctionPaintPropertyBinder : public PaintPropertyBinder<T, A> { +class SourceFunctionPaintPropertyBinder : public PaintPropertyBinder<T, T, PossiblyEvaluatedPropertyValue<T>, A> { public: using BaseAttribute = A; - using BaseAttributeValue = typename BaseAttribute::Value; using BaseVertex = gl::detail::Vertex<BaseAttribute>; using AttributeType = ZoomInterpolatedAttributeType<A>; @@ -128,8 +171,8 @@ public: : expression(std::move(expression_)), defaultValue(std::move(defaultValue_)) { } - - void populateVertexVector(const GeometryTileFeature& feature, std::size_t length) override { + void setPatternParameters(const optional<ImagePosition>&, const optional<ImagePosition>&, CrossfadeParameters&) override {}; + void populateVertexVector(const GeometryTileFeature& feature, std::size_t length, const ImagePositions&, const optional<PatternDependency>&) override { auto evaluated = expression.evaluate(feature, defaultValue); this->statistics.add(evaluated); auto value = attributeValue(evaluated); @@ -142,21 +185,21 @@ public: vertexBuffer = context.createVertexBuffer(std::move(vertexVector)); } - optional<gl::AttributeBinding> attributeBinding(const PossiblyEvaluatedPropertyValue<T>& currentValue) const override { + std::tuple<optional<gl::AttributeBinding>> attributeBinding(const PossiblyEvaluatedPropertyValue<T>& currentValue) const override { if (currentValue.isConstant()) { return {}; } else { - return AttributeType::binding(*vertexBuffer, 0, BaseAttribute::Dimensions); + return std::tuple<optional<gl::AttributeBinding>> { AttributeType::binding(*vertexBuffer, 0, BaseAttribute::Dimensions) }; } } - float interpolationFactor(float) const override { - return 0.0f; + std::tuple<float> interpolationFactor(float) const override { + return std::tuple<float> { 0.0f }; } - T uniformValue(const PossiblyEvaluatedPropertyValue<T>& currentValue) const override { + std::tuple<T> uniformValue(const PossiblyEvaluatedPropertyValue<T>& currentValue) const override { if (currentValue.isConstant()) { - return *currentValue.constant(); + return std::tuple<T>{ *currentValue.constant() }; } else { // Uniform values for vertex attribute arrays are unused. return {}; @@ -171,7 +214,7 @@ private: }; template <class T, class A> -class CompositeFunctionPaintPropertyBinder : public PaintPropertyBinder<T, A> { +class CompositeFunctionPaintPropertyBinder : public PaintPropertyBinder<T, T, PossiblyEvaluatedPropertyValue<T>, A> { public: using AttributeType = ZoomInterpolatedAttributeType<A>; @@ -183,8 +226,8 @@ public: defaultValue(std::move(defaultValue_)), zoomRange({zoom, zoom + 1}) { } - - void populateVertexVector(const GeometryTileFeature& feature, std::size_t length) override { + void setPatternParameters(const optional<ImagePosition>&, const optional<ImagePosition>&, CrossfadeParameters&) override {}; + void populateVertexVector(const GeometryTileFeature& feature, std::size_t length, const ImagePositions&, const optional<PatternDependency>&) override { Range<T> range = expression.evaluate(zoomRange, feature, defaultValue); this->statistics.add(range.min); this->statistics.add(range.max); @@ -200,25 +243,25 @@ public: vertexBuffer = context.createVertexBuffer(std::move(vertexVector)); } - optional<gl::AttributeBinding> attributeBinding(const PossiblyEvaluatedPropertyValue<T>& currentValue) const override { + std::tuple<optional<gl::AttributeBinding>> attributeBinding(const PossiblyEvaluatedPropertyValue<T>& currentValue) const override { if (currentValue.isConstant()) { return {}; } else { - return AttributeType::binding(*vertexBuffer, 0); + return std::tuple<optional<gl::AttributeBinding>> { AttributeType::binding(*vertexBuffer, 0) }; } } - float interpolationFactor(float currentZoom) const override { + std::tuple<float> interpolationFactor(float currentZoom) const override { if (expression.useIntegerZoom) { - return expression.interpolationFactor(zoomRange, std::floor(currentZoom)); + return std::tuple<float> { expression.interpolationFactor(zoomRange, std::floor(currentZoom)) }; } else { - return expression.interpolationFactor(zoomRange, currentZoom); + return std::tuple<float> { expression.interpolationFactor(zoomRange, currentZoom) }; } } - T uniformValue(const PossiblyEvaluatedPropertyValue<T>& currentValue) const override { + std::tuple<T> uniformValue(const PossiblyEvaluatedPropertyValue<T>& currentValue) const override { if (currentValue.isConstant()) { - return *currentValue.constant(); + return std::tuple<T> { *currentValue.constant() }; } else { // Uniform values for vertex attribute arrays are unused. return {}; @@ -233,21 +276,131 @@ private: optional<gl::VertexBuffer<Vertex>> vertexBuffer; }; -template <class T, class... As> -std::unique_ptr<PaintPropertyBinder<T, As...>> -PaintPropertyBinder<T, As...>::create(const PossiblyEvaluatedPropertyValue<T>& value, float zoom, T defaultValue) { - return value.match( - [&] (const T& constant) -> std::unique_ptr<PaintPropertyBinder<T, As...>> { - return std::make_unique<ConstantPaintPropertyBinder<T, As...>>(constant); - }, - [&] (const style::PropertyExpression<T>& expression) -> std::unique_ptr<PaintPropertyBinder<T, As...>> { - if (expression.isZoomConstant()) { - return std::make_unique<SourceFunctionPaintPropertyBinder<T, As...>>(expression, defaultValue); - } else { - return std::make_unique<CompositeFunctionPaintPropertyBinder<T, As...>>(expression, zoom, defaultValue); +template <class T, class A1, class A2> +class CompositeCrossFadedPaintPropertyBinder : public PaintPropertyBinder<T, std::array<uint16_t, 4>, PossiblyEvaluatedPropertyValue<Faded<T>>, A1, A2> { +public: + using AttributeType = ZoomInterpolatedAttributeType<A1>; + using AttributeType2 = ZoomInterpolatedAttributeType<A2>; + + using BaseAttribute = A1; + using BaseAttributeValue = typename BaseAttribute::Value; + + using BaseAttribute2 = A2; + using BaseAttributeValue2 = typename BaseAttribute2::Value; + + using Vertex = gl::detail::Vertex<BaseAttribute>; + using Vertex2 = gl::detail::Vertex<BaseAttribute2>; + + CompositeCrossFadedPaintPropertyBinder(style::PropertyExpression<T> expression_, float zoom, T defaultValue_) + : expression(std::move(expression_)), + defaultValue(std::move(defaultValue_)), + zoomRange({zoom, zoom + 1}) { + } + + void setPatternParameters(const optional<ImagePosition>&, const optional<ImagePosition>&, CrossfadeParameters& crossfade_) override { + crossfade = crossfade_; + }; + + void populateVertexVector(const GeometryTileFeature&, std::size_t length, const ImagePositions& patternPositions, const optional<PatternDependency>& patternDependencies) override { + if (!patternDependencies) return; + if (!patternPositions.empty()) { + const auto min = patternPositions.find(patternDependencies->min); + const auto mid = patternPositions.find(patternDependencies->mid); + const auto max = patternPositions.find(patternDependencies->max); + + const auto end = patternPositions.end(); + if (min == end || mid == end || max == end) return; + + const ImagePosition imageMin = min->second; + const ImagePosition imageMid = mid->second; + const ImagePosition imageMax = max->second; + + for (std::size_t i = zoomInVertexVector.vertexSize(); i < length; ++i) { + patternToVertexVector.emplace_back(Vertex { imageMid.tlbr() }); + zoomInVertexVector.emplace_back(Vertex2 { imageMin.tlbr() }); + zoomOutVertexVector.emplace_back(Vertex2 { imageMax.tlbr() }); } } - ); + } + + void upload(gl::Context& context) override { + patternToVertexBuffer = context.createVertexBuffer(std::move(patternToVertexVector)); + zoomInVertexBuffer = context.createVertexBuffer(std::move(zoomInVertexVector)); + zoomOutVertexBuffer = context.createVertexBuffer(std::move(zoomOutVertexVector)); + } + + std::tuple<optional<gl::AttributeBinding>, optional<gl::AttributeBinding>> attributeBinding(const PossiblyEvaluatedPropertyValue<Faded<T>>& currentValue) const override { + if (currentValue.isConstant()) { + return {}; + } else { + return std::tuple<optional<gl::AttributeBinding>, optional<gl::AttributeBinding>> { + AttributeType::binding(*patternToVertexBuffer, 0, BaseAttribute::Dimensions), + AttributeType2::binding( + crossfade.fromScale == 2 ? *zoomInVertexBuffer : *zoomOutVertexBuffer, + 0, BaseAttribute2::Dimensions) }; + } + } + + std::tuple<float, float> interpolationFactor(float) const override { + return std::tuple<float, float> { 0.0f, 0.0f }; + } + + std::tuple<std::array<uint16_t, 4>, std::array<uint16_t, 4>> uniformValue(const PossiblyEvaluatedPropertyValue<Faded<T>>& ) const override { + // Uniform values for vertex attribute arrays are unused. + return {}; + } + +private: + style::PropertyExpression<T> expression; + T defaultValue; + Range<float> zoomRange; + gl::VertexVector<Vertex> patternToVertexVector; + gl::VertexVector<Vertex2> zoomInVertexVector; + gl::VertexVector<Vertex2> zoomOutVertexVector; + optional<gl::VertexBuffer<Vertex>> patternToVertexBuffer; + optional<gl::VertexBuffer<Vertex2>> zoomInVertexBuffer; + optional<gl::VertexBuffer<Vertex2>> zoomOutVertexBuffer; + CrossfadeParameters crossfade; +}; + +template <class T, class PossiblyEvaluatedType> +struct CreateBinder { + template <class A> + static std::unique_ptr<PaintPropertyBinder<T, T, PossiblyEvaluatedType, A>> create(const PossiblyEvaluatedType& value, float zoom, T defaultValue) { + return value.match( + [&] (const T& constant) -> std::unique_ptr<PaintPropertyBinder<T, T, PossiblyEvaluatedType, A>> { + return std::make_unique<ConstantPaintPropertyBinder<T, A>>(constant); + }, + [&] (const style::PropertyExpression<T>& expression) -> std::unique_ptr<PaintPropertyBinder<T, T, PossiblyEvaluatedType, A>> { + if (expression.isZoomConstant()) { + return std::make_unique<SourceFunctionPaintPropertyBinder<T, A>>(expression, defaultValue); + } else { + return std::make_unique<CompositeFunctionPaintPropertyBinder<T, A>>(expression, zoom, defaultValue); + } + } + ); + } +}; + +template <class T> +struct CreateBinder<T, PossiblyEvaluatedPropertyValue<Faded<T>>> { + template <class A1, class A2> + static std::unique_ptr<PaintPropertyBinder<T, std::array<uint16_t, 4>, PossiblyEvaluatedPropertyValue<Faded<T>>, A1, A2>> create(const PossiblyEvaluatedPropertyValue<Faded<T>>& value, float zoom, T defaultValue) { + return value.match( + [&] (const Faded<T>& constant) -> std::unique_ptr<PaintPropertyBinder<T, std::array<uint16_t, 4>, PossiblyEvaluatedPropertyValue<Faded<T>>, A1, A2>> { + return std::make_unique<ConstantCrossFadedPaintPropertyBinder<T, A1, A2>>(constant); + }, + [&] (const style::PropertyExpression<T>& expression) -> std::unique_ptr<PaintPropertyBinder<T, std::array<uint16_t, 4>, PossiblyEvaluatedPropertyValue<Faded<T>>, A1, A2>> { + return std::make_unique<CompositeCrossFadedPaintPropertyBinder<T, A1, A2>>(expression, zoom, defaultValue); + } + ); + } +}; + +template <class T, class UniformValueType, class PossiblyEvaluatedType, class... As> +std::unique_ptr<PaintPropertyBinder<T, UniformValueType, PossiblyEvaluatedType, As... >> +PaintPropertyBinder<T, UniformValueType, PossiblyEvaluatedType, As...>::create(const PossiblyEvaluatedType& value, float zoom, T defaultValue) { + return CreateBinder<T, PossiblyEvaluatedType>::template create<As...>(value, zoom, defaultValue); } template <class Attr> @@ -270,17 +423,18 @@ class PaintPropertyBinders; template <class... Ps> class PaintPropertyBinders<TypeList<Ps...>> { private: - template <class T, class... As> + template <class T, class PossiblyEvaluatedType, class... As> struct Detail; - template <class T, class... As> - struct Detail<T, TypeList<As...>> { - using Binder = PaintPropertyBinder<T, typename As::Type...>; + template <class T, class UniformValueType, class PossiblyEvaluatedType, class... As> + struct Detail<T, UniformValueType, PossiblyEvaluatedType, TypeList<As...>> { + using Binder = PaintPropertyBinder<T, UniformValueType, PossiblyEvaluatedType, typename As::Type...>; using ZoomInterpolatedAttributeList = TypeList<ZoomInterpolatedAttribute<As>...>; + using InterpolationUniformList = TypeList<InterpolationUniform<As>...>; }; template <class P> - using Property = Detail<typename P::Type, typename P::Attributes>; + using Property = Detail<typename P::Type, typename P::Uniform::Type, typename P::PossiblyEvaluatedType, typename P::Attributes>; public: template <class P> @@ -299,9 +453,15 @@ public: PaintPropertyBinders(PaintPropertyBinders&&) = default; PaintPropertyBinders(const PaintPropertyBinders&) = delete; - void populateVertexVectors(const GeometryTileFeature& feature, std::size_t length) { + void populateVertexVectors(const GeometryTileFeature& feature, std::size_t length, const ImagePositions& patternPositions, const optional<PatternDependency>& patternDependencies) { util::ignore({ - (binders.template get<Ps>()->populateVertexVector(feature, length), 0)... + (binders.template get<Ps>()->populateVertexVector(feature, length, patternPositions, patternDependencies), 0)... + }); + } + + void setPatternParameters(const optional<ImagePosition>& posA, const optional<ImagePosition>& posB, CrossfadeParameters& crossfade) const { + util::ignore({ + (binders.template get<Ps>()->setPatternParameters(posA, posB, crossfade), 0)... }); } @@ -313,31 +473,32 @@ public: template <class P> using ZoomInterpolatedAttributeList = typename Property<P>::ZoomInterpolatedAttributeList; + template <class P> + using InterpolationUniformList = typename Property<P>::InterpolationUniformList; using Attributes = typename TypeListConcat<ZoomInterpolatedAttributeList<Ps>...>::template ExpandInto<gl::Attributes>; using AttributeBindings = typename Attributes::Bindings; template <class EvaluatedProperties> AttributeBindings attributeBindings(const EvaluatedProperties& currentProperties) const { - return AttributeBindings { - binders.template get<Ps>()->attributeBinding(currentProperties.template get<Ps>())... - }; + return AttributeBindings { std::tuple_cat( + binders.template get<Ps>()->attributeBinding(currentProperties.template get<Ps>())... + ) }; } - using Uniforms = gl::Uniforms<InterpolationUniform<typename Ps::Attribute>..., typename Ps::Uniform...>; + using Uniforms = typename TypeListConcat<InterpolationUniformList<Ps>..., typename Ps::Uniforms...>::template ExpandInto<gl::Uniforms>; using UniformValues = typename Uniforms::Values; template <class EvaluatedProperties> - UniformValues uniformValues(float currentZoom, const EvaluatedProperties& currentProperties) const { + UniformValues uniformValues(float currentZoom, EvaluatedProperties& currentProperties) const { (void)currentZoom; // Workaround for https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56958 - return UniformValues { - typename InterpolationUniform<typename Ps::Attribute>::Value { - binders.template get<Ps>()->interpolationFactor(currentZoom) - }..., - typename Ps::Uniform::Value { - binders.template get<Ps>()->uniformValue(currentProperties.template get<Ps>()) - }... - }; + return UniformValues ( + std::tuple_cat( + // interpolation uniform values + binders.template get<Ps>()->interpolationFactor(currentZoom)..., + // uniform values + binders.template get<Ps>()->uniformValue(currentProperties.template get<Ps>())...) + ); } template <class P> @@ -345,7 +506,6 @@ public: return binders.template get<P>()->statistics; } - using Bitset = std::bitset<sizeof...(Ps)>; template <class EvaluatedProperties> @@ -358,13 +518,25 @@ public: return result; } + template <class> + struct UniformDefines; + + template <class... Us> + struct UniformDefines<TypeList<Us...>> { + static void appendDefines(std::vector<std::string>& defines) { + util::ignore({ + (defines.push_back(std::string("#define HAS_UNIFORM_") + Us::name()), 0)... + }); + } + }; + template <class EvaluatedProperties> static std::vector<std::string> defines(const EvaluatedProperties& currentProperties) { std::vector<std::string> result; util::ignore({ - (result.push_back(currentProperties.template get<Ps>().isConstant() - ? std::string("#define HAS_UNIFORM_") + Ps::Uniform::name() - : std::string()), 0)... + (currentProperties.template get<Ps>().isConstant() + ? UniformDefines<typename Ps::Uniforms>::appendDefines(result) + : (void) 0, 0)... }); return result; } diff --git a/src/mbgl/renderer/possibly_evaluated_property_value.hpp b/src/mbgl/renderer/possibly_evaluated_property_value.hpp index f2d265f2f7..353df2ab90 100644 --- a/src/mbgl/renderer/possibly_evaluated_property_value.hpp +++ b/src/mbgl/renderer/possibly_evaluated_property_value.hpp @@ -1,6 +1,7 @@ #pragma once #include <mbgl/style/property_expression.hpp> +#include <mbgl/renderer/cross_faded_property_evaluator.hpp> #include <mbgl/util/interpolate.hpp> #include <mbgl/util/variant.hpp> @@ -57,6 +58,61 @@ public: bool useIntegerZoom; }; +template <class T> +class PossiblyEvaluatedPropertyValue<Faded<T>> { +private: + using Value = variant< + Faded<T>, + style::PropertyExpression<T>>; + + Value value; + +public: + PossiblyEvaluatedPropertyValue() = default; + PossiblyEvaluatedPropertyValue(Value v, bool useIntegerZoom_ = false) + : value(std::move(v)), + useIntegerZoom(useIntegerZoom_) {} + + bool isConstant() const { + return value.template is<Faded<T>>(); + } + + optional<Faded<T>> constant() const { + return value.match( + [&] (const Faded<T>& t) { return optional<Faded<T>>(t); }, + [&] (const auto&) { return optional<Faded<T>>(); }); + } + + Faded<T> constantOr(const Faded<T>& t) const { + return constant().value_or(t); + } + + template <class... Ts> + auto match(Ts&&... ts) const { + return value.match(std::forward<Ts>(ts)...); + } + + template <class Feature> + Faded<T> evaluate(const Feature& feature, float zoom, T defaultValue) const { + return this->match( + [&] (const Faded<T>& constant_) { return constant_; }, + [&] (const style::PropertyExpression<T>& expression) { + if (!expression.isZoomConstant()) { + const T min = expression.evaluate(floor(zoom), feature, defaultValue); + const T max = expression.evaluate(floor(zoom) + 1, feature, defaultValue); + return Faded<T> {min, max}; + } else { + const T evaluated = expression.evaluate(feature, defaultValue); + return Faded<T> {evaluated, evaluated}; + } + } + ); + } + + bool useIntegerZoom; +}; + + namespace util { template <typename T> diff --git a/src/mbgl/renderer/property_evaluation_parameters.hpp b/src/mbgl/renderer/property_evaluation_parameters.hpp index da6a4a0892..0e1c317294 100644 --- a/src/mbgl/renderer/property_evaluation_parameters.hpp +++ b/src/mbgl/renderer/property_evaluation_parameters.hpp @@ -5,6 +5,13 @@ namespace mbgl { +class CrossfadeParameters { +public: + float fromScale; + float toScale; + float t; +}; + class PropertyEvaluationParameters { public: explicit PropertyEvaluationParameters(float z_) @@ -24,6 +31,18 @@ public: defaultFadeDuration(std::move(defaultFadeDuration_)), useIntegerZoom(useIntegerZoom_) {} + CrossfadeParameters getCrossfadeParameters() const { + const float fraction = z - std::floor(z); + const std::chrono::duration<float> d = defaultFadeDuration; + const float t = d != std::chrono::duration<float>::zero() + ? std::min((now - zoomHistory.lastIntegerZoomTime) / d, 1.0f) + : 1.0f; + + return z > zoomHistory.lastIntegerZoom + ? CrossfadeParameters { 2.0f, 1.0f, fraction + (1.0f - fraction) * t } + : CrossfadeParameters { 0.5f, 1.0f, 1 - (1 - t) * fraction }; + } + float z; TimePoint now; ZoomHistory zoomHistory; diff --git a/src/mbgl/renderer/render_layer.hpp b/src/mbgl/renderer/render_layer.hpp index 3e2f1d7525..9f327c63e5 100644 --- a/src/mbgl/renderer/render_layer.hpp +++ b/src/mbgl/renderer/render_layer.hpp @@ -40,6 +40,9 @@ public: // Returns true if any paint properties have active transitions. virtual bool hasTransition() const = 0; + // Returns true if the layer has a pattern property and is actively crossfading. + virtual bool hasCrossfade() const = 0; + // Check whether this layer is of the given subtype. template <class T> bool is() const; diff --git a/src/mbgl/renderer/render_tile.cpp b/src/mbgl/renderer/render_tile.cpp index 64790938ef..fcd8b77771 100644 --- a/src/mbgl/renderer/render_tile.cpp +++ b/src/mbgl/renderer/render_tile.cpp @@ -103,8 +103,8 @@ void RenderTile::finishRender(PaintParameters& parameters) { tile.debugBucket->segments, program.computeAllUniformValues( DebugProgram::UniformValues { - uniforms::u_matrix::Value{ matrix }, - uniforms::u_color::Value{ Color::white() } + uniforms::u_matrix::Value( matrix ), + uniforms::u_color::Value( Color::white() ) }, paintAttributeData, properties, @@ -124,8 +124,8 @@ void RenderTile::finishRender(PaintParameters& parameters) { tile.debugBucket->segments, program.computeAllUniformValues( DebugProgram::UniformValues { - uniforms::u_matrix::Value{ matrix }, - uniforms::u_color::Value{ Color::black() } + uniforms::u_matrix::Value( matrix ), + uniforms::u_color::Value( Color::black() ) }, paintAttributeData, properties, @@ -147,8 +147,8 @@ void RenderTile::finishRender(PaintParameters& parameters) { parameters.staticData.tileBorderSegments, program.computeAllUniformValues( DebugProgram::UniformValues { - uniforms::u_matrix::Value{ matrix }, - uniforms::u_color::Value{ Color::red() } + uniforms::u_matrix::Value( matrix ), + uniforms::u_color::Value( Color::red() ) }, paintAttributeData, properties, diff --git a/src/mbgl/renderer/renderer_impl.cpp b/src/mbgl/renderer/renderer_impl.cpp index bc39c40796..92d04063ca 100644 --- a/src/mbgl/renderer/renderer_impl.cpp +++ b/src/mbgl/renderer/renderer_impl.cpp @@ -14,6 +14,7 @@ #include <mbgl/renderer/layers/render_background_layer.hpp> #include <mbgl/renderer/layers/render_custom_layer.hpp> #include <mbgl/renderer/layers/render_fill_extrusion_layer.hpp> +#include <mbgl/renderer/layers/render_fill_layer.hpp> #include <mbgl/renderer/layers/render_heatmap_layer.hpp> #include <mbgl/renderer/layers/render_hillshade_layer.hpp> #include <mbgl/renderer/style_diff.hpp> @@ -195,7 +196,7 @@ void Renderer::Impl::render(const UpdateParameters& updateParameters) { } } - if (layerAdded || layerChanged || zoomChanged || layer.hasTransition()) { + if (layerAdded || layerChanged || zoomChanged || layer.hasTransition() || layer.hasCrossfade()) { layer.evaluate(evaluationParameters); } } @@ -512,7 +513,7 @@ void Renderer::Impl::render(const UpdateParameters& updateParameters) { parameters.staticData.tileTriangleSegments, program.computeAllUniformValues( ClippingMaskProgram::UniformValues { - uniforms::u_matrix::Value{ parameters.matrixForTile(clipID.first) }, + uniforms::u_matrix::Value( parameters.matrixForTile(clipID.first) ), }, paintAttributeData, properties, diff --git a/src/mbgl/renderer/sources/render_image_source.cpp b/src/mbgl/renderer/sources/render_image_source.cpp index 2ce046a7a0..d4577e787a 100644 --- a/src/mbgl/renderer/sources/render_image_source.cpp +++ b/src/mbgl/renderer/sources/render_image_source.cpp @@ -71,8 +71,8 @@ void RenderImageSource::finishRender(PaintParameters& parameters) { parameters.staticData.tileBorderSegments, programInstance.computeAllUniformValues( DebugProgram::UniformValues { - uniforms::u_matrix::Value{ matrix }, - uniforms::u_color::Value{ Color::red() } + uniforms::u_matrix::Value( matrix ), + uniforms::u_color::Value( Color::red() ) }, paintAttributeData, properties, diff --git a/src/mbgl/shaders/background.cpp b/src/mbgl/shaders/background.cpp index b0d176f07d..f03e58b577 100644 --- a/src/mbgl/shaders/background.cpp +++ b/src/mbgl/shaders/background.cpp @@ -7,8 +7,8 @@ namespace mbgl { namespace shaders { const char* background::name = "background"; -const char* background::vertexSource = source() + 2738; -const char* background::fragmentSource = source() + 2850; +const char* background::vertexSource = source() + 2739; +const char* background::fragmentSource = source() + 2851; } // namespace shaders } // namespace mbgl diff --git a/src/mbgl/shaders/background_pattern.cpp b/src/mbgl/shaders/background_pattern.cpp index f80a86a0d9..ded8dd57d0 100644 --- a/src/mbgl/shaders/background_pattern.cpp +++ b/src/mbgl/shaders/background_pattern.cpp @@ -7,8 +7,8 @@ namespace mbgl { namespace shaders { const char* background_pattern::name = "background_pattern"; -const char* background_pattern::vertexSource = source() + 3019; -const char* background_pattern::fragmentSource = source() + 3663; +const char* background_pattern::vertexSource = source() + 3020; +const char* background_pattern::fragmentSource = source() + 3664; } // namespace shaders } // namespace mbgl diff --git a/src/mbgl/shaders/circle.cpp b/src/mbgl/shaders/circle.cpp index 1ba1865504..e027975533 100644 --- a/src/mbgl/shaders/circle.cpp +++ b/src/mbgl/shaders/circle.cpp @@ -7,8 +7,8 @@ namespace mbgl { namespace shaders { const char* circle::name = "circle"; -const char* circle::vertexSource = source() + 4415; -const char* circle::fragmentSource = source() + 8663; +const char* circle::vertexSource = source() + 4416; +const char* circle::fragmentSource = source() + 8666; } // namespace shaders } // namespace mbgl diff --git a/src/mbgl/shaders/clipping_mask.cpp b/src/mbgl/shaders/clipping_mask.cpp index dff0e08ced..9a06ed0f85 100644 --- a/src/mbgl/shaders/clipping_mask.cpp +++ b/src/mbgl/shaders/clipping_mask.cpp @@ -7,8 +7,8 @@ namespace mbgl { namespace shaders { const char* clipping_mask::name = "clipping_mask"; -const char* clipping_mask::vertexSource = source() + 10630; -const char* clipping_mask::fragmentSource = source() + 10742; +const char* clipping_mask::vertexSource = source() + 10633; +const char* clipping_mask::fragmentSource = source() + 10745; } // namespace shaders } // namespace mbgl diff --git a/src/mbgl/shaders/collision_box.cpp b/src/mbgl/shaders/collision_box.cpp index e09881e87d..224918c7e8 100644 --- a/src/mbgl/shaders/collision_box.cpp +++ b/src/mbgl/shaders/collision_box.cpp @@ -7,8 +7,8 @@ namespace mbgl { namespace shaders { const char* collision_box::name = "collision_box"; -const char* collision_box::vertexSource = source() + 14425; -const char* collision_box::fragmentSource = source() + 15249; +const char* collision_box::vertexSource = source() + 14428; +const char* collision_box::fragmentSource = source() + 15252; } // namespace shaders } // namespace mbgl diff --git a/src/mbgl/shaders/collision_circle.cpp b/src/mbgl/shaders/collision_circle.cpp index 9188d728d8..bcbe569a09 100644 --- a/src/mbgl/shaders/collision_circle.cpp +++ b/src/mbgl/shaders/collision_circle.cpp @@ -7,8 +7,8 @@ namespace mbgl { namespace shaders { const char* collision_circle::name = "collision_circle"; -const char* collision_circle::vertexSource = source() + 15668; -const char* collision_circle::fragmentSource = source() + 16974; +const char* collision_circle::vertexSource = source() + 15671; +const char* collision_circle::fragmentSource = source() + 16977; } // namespace shaders } // namespace mbgl diff --git a/src/mbgl/shaders/debug.cpp b/src/mbgl/shaders/debug.cpp index 25f2cb2675..164387178d 100644 --- a/src/mbgl/shaders/debug.cpp +++ b/src/mbgl/shaders/debug.cpp @@ -7,8 +7,8 @@ namespace mbgl { namespace shaders { const char* debug::name = "debug"; -const char* debug::vertexSource = source() + 17916; -const char* debug::fragmentSource = source() + 18028; +const char* debug::vertexSource = source() + 17919; +const char* debug::fragmentSource = source() + 18031; } // namespace shaders } // namespace mbgl diff --git a/src/mbgl/shaders/extrusion_texture.cpp b/src/mbgl/shaders/extrusion_texture.cpp index a9de78da1f..9d5765eaf3 100644 --- a/src/mbgl/shaders/extrusion_texture.cpp +++ b/src/mbgl/shaders/extrusion_texture.cpp @@ -7,8 +7,8 @@ namespace mbgl { namespace shaders { const char* extrusion_texture::name = "extrusion_texture"; -const char* extrusion_texture::vertexSource = source() + 31747; -const char* extrusion_texture::fragmentSource = source() + 31963; +const char* extrusion_texture::vertexSource = source() + 36148; +const char* extrusion_texture::fragmentSource = source() + 36364; } // namespace shaders } // namespace mbgl diff --git a/src/mbgl/shaders/fill.cpp b/src/mbgl/shaders/fill.cpp index 146dbfb737..5d38c30e85 100644 --- a/src/mbgl/shaders/fill.cpp +++ b/src/mbgl/shaders/fill.cpp @@ -7,8 +7,8 @@ namespace mbgl { namespace shaders { const char* fill::name = "fill"; -const char* fill::vertexSource = source() + 18102; -const char* fill::fragmentSource = source() + 18807; +const char* fill::vertexSource = source() + 18105; +const char* fill::fragmentSource = source() + 18811; } // namespace shaders } // namespace mbgl diff --git a/src/mbgl/shaders/fill_extrusion.cpp b/src/mbgl/shaders/fill_extrusion.cpp index ece4635dc4..c9c1b1c487 100644 --- a/src/mbgl/shaders/fill_extrusion.cpp +++ b/src/mbgl/shaders/fill_extrusion.cpp @@ -7,8 +7,8 @@ namespace mbgl { namespace shaders { const char* fill_extrusion::name = "fill_extrusion"; -const char* fill_extrusion::vertexSource = source() + 24858; -const char* fill_extrusion::fragmentSource = source() + 27694; +const char* fill_extrusion::vertexSource = source() + 27816; +const char* fill_extrusion::fragmentSource = source() + 30653; } // namespace shaders } // namespace mbgl diff --git a/src/mbgl/shaders/fill_extrusion_pattern.cpp b/src/mbgl/shaders/fill_extrusion_pattern.cpp index 1d7a2d4428..53f41945fc 100644 --- a/src/mbgl/shaders/fill_extrusion_pattern.cpp +++ b/src/mbgl/shaders/fill_extrusion_pattern.cpp @@ -7,8 +7,8 @@ namespace mbgl { namespace shaders { const char* fill_extrusion_pattern::name = "fill_extrusion_pattern"; -const char* fill_extrusion_pattern::vertexSource = source() + 28334; -const char* fill_extrusion_pattern::fragmentSource = source() + 30619; +const char* fill_extrusion_pattern::vertexSource = source() + 31293; +const char* fill_extrusion_pattern::fragmentSource = source() + 34571; } // namespace shaders } // namespace mbgl diff --git a/src/mbgl/shaders/fill_outline.cpp b/src/mbgl/shaders/fill_outline.cpp index 873e49f8c2..bcb332d0cb 100644 --- a/src/mbgl/shaders/fill_outline.cpp +++ b/src/mbgl/shaders/fill_outline.cpp @@ -7,8 +7,8 @@ namespace mbgl { namespace shaders { const char* fill_outline::name = "fill_outline"; -const char* fill_outline::vertexSource = source() + 19276; -const char* fill_outline::fragmentSource = source() + 20180; +const char* fill_outline::vertexSource = source() + 19280; +const char* fill_outline::fragmentSource = source() + 20185; } // namespace shaders } // namespace mbgl diff --git a/src/mbgl/shaders/fill_outline_pattern.cpp b/src/mbgl/shaders/fill_outline_pattern.cpp index d1bcaa95bb..8ea5aee66b 100644 --- a/src/mbgl/shaders/fill_outline_pattern.cpp +++ b/src/mbgl/shaders/fill_outline_pattern.cpp @@ -7,8 +7,8 @@ namespace mbgl { namespace shaders { const char* fill_outline_pattern::name = "fill_outline_pattern"; -const char* fill_outline_pattern::vertexSource = source() + 20838; -const char* fill_outline_pattern::fragmentSource = source() + 21901; +const char* fill_outline_pattern::vertexSource = source() + 20843; +const char* fill_outline_pattern::fragmentSource = source() + 22928; } // namespace shaders } // namespace mbgl diff --git a/src/mbgl/shaders/fill_pattern.cpp b/src/mbgl/shaders/fill_pattern.cpp index 88b4fc92a2..27e43a54c4 100644 --- a/src/mbgl/shaders/fill_pattern.cpp +++ b/src/mbgl/shaders/fill_pattern.cpp @@ -7,8 +7,8 @@ namespace mbgl { namespace shaders { const char* fill_pattern::name = "fill_pattern"; -const char* fill_pattern::vertexSource = source() + 22998; -const char* fill_pattern::fragmentSource = source() + 23950; +const char* fill_pattern::vertexSource = source() + 24474; +const char* fill_pattern::fragmentSource = source() + 26459; } // namespace shaders } // namespace mbgl diff --git a/src/mbgl/shaders/heatmap.cpp b/src/mbgl/shaders/heatmap.cpp index c669e8e0af..32a45828d1 100644 --- a/src/mbgl/shaders/heatmap.cpp +++ b/src/mbgl/shaders/heatmap.cpp @@ -7,8 +7,8 @@ namespace mbgl { namespace shaders { const char* heatmap::name = "heatmap"; -const char* heatmap::vertexSource = source() + 10789; -const char* heatmap::fragmentSource = source() + 13245; +const char* heatmap::vertexSource = source() + 10792; +const char* heatmap::fragmentSource = source() + 13248; } // namespace shaders } // namespace mbgl diff --git a/src/mbgl/shaders/heatmap_texture.cpp b/src/mbgl/shaders/heatmap_texture.cpp index 8f5ec1f176..527caf4dca 100644 --- a/src/mbgl/shaders/heatmap_texture.cpp +++ b/src/mbgl/shaders/heatmap_texture.cpp @@ -7,8 +7,8 @@ namespace mbgl { namespace shaders { const char* heatmap_texture::name = "heatmap_texture"; -const char* heatmap_texture::vertexSource = source() + 13886; -const char* heatmap_texture::fragmentSource = source() + 14102; +const char* heatmap_texture::vertexSource = source() + 13889; +const char* heatmap_texture::fragmentSource = source() + 14105; } // namespace shaders } // namespace mbgl diff --git a/src/mbgl/shaders/hillshade.cpp b/src/mbgl/shaders/hillshade.cpp index ea81d7c10c..58db744b1f 100644 --- a/src/mbgl/shaders/hillshade.cpp +++ b/src/mbgl/shaders/hillshade.cpp @@ -7,8 +7,8 @@ namespace mbgl { namespace shaders { const char* hillshade::name = "hillshade"; -const char* hillshade::vertexSource = source() + 34909; -const char* hillshade::fragmentSource = source() + 35108; +const char* hillshade::vertexSource = source() + 39310; +const char* hillshade::fragmentSource = source() + 39509; } // namespace shaders } // namespace mbgl diff --git a/src/mbgl/shaders/hillshade_prepare.cpp b/src/mbgl/shaders/hillshade_prepare.cpp index fb610f01b2..2b039e5559 100644 --- a/src/mbgl/shaders/hillshade_prepare.cpp +++ b/src/mbgl/shaders/hillshade_prepare.cpp @@ -7,8 +7,8 @@ namespace mbgl { namespace shaders { const char* hillshade_prepare::name = "hillshade_prepare"; -const char* hillshade_prepare::vertexSource = source() + 32175; -const char* hillshade_prepare::fragmentSource = source() + 32389; +const char* hillshade_prepare::vertexSource = source() + 36576; +const char* hillshade_prepare::fragmentSource = source() + 36790; } // namespace shaders } // namespace mbgl diff --git a/src/mbgl/shaders/line.cpp b/src/mbgl/shaders/line.cpp index 1ba2a9f403..6ef2551b04 100644 --- a/src/mbgl/shaders/line.cpp +++ b/src/mbgl/shaders/line.cpp @@ -7,8 +7,8 @@ namespace mbgl { namespace shaders { const char* line::name = "line"; -const char* line::vertexSource = source() + 37744; -const char* line::fragmentSource = source() + 42206; +const char* line::vertexSource = source() + 42145; +const char* line::fragmentSource = source() + 46608; } // namespace shaders } // namespace mbgl diff --git a/src/mbgl/shaders/line_gradient.cpp b/src/mbgl/shaders/line_gradient.cpp index 9409086add..2b38e15e30 100644 --- a/src/mbgl/shaders/line_gradient.cpp +++ b/src/mbgl/shaders/line_gradient.cpp @@ -7,8 +7,8 @@ namespace mbgl { namespace shaders { const char* line_gradient::name = "line_gradient"; -const char* line_gradient::vertexSource = source() + 43378; -const char* line_gradient::fragmentSource = source() + 47687; +const char* line_gradient::vertexSource = source() + 47780; +const char* line_gradient::fragmentSource = source() + 52089; } // namespace shaders } // namespace mbgl diff --git a/src/mbgl/shaders/line_pattern.cpp b/src/mbgl/shaders/line_pattern.cpp index 777272ad6e..021cf7aa3d 100644 --- a/src/mbgl/shaders/line_pattern.cpp +++ b/src/mbgl/shaders/line_pattern.cpp @@ -7,8 +7,8 @@ namespace mbgl { namespace shaders { const char* line_pattern::name = "line_pattern"; -const char* line_pattern::vertexSource = source() + 48972; -const char* line_pattern::fragmentSource = source() + 53381; +const char* line_pattern::vertexSource = source() + 53374; +const char* line_pattern::fragmentSource = source() + 58450; } // namespace shaders } // namespace mbgl diff --git a/src/mbgl/shaders/line_sdf.cpp b/src/mbgl/shaders/line_sdf.cpp index e27923c758..18c35e1dae 100644 --- a/src/mbgl/shaders/line_sdf.cpp +++ b/src/mbgl/shaders/line_sdf.cpp @@ -7,8 +7,8 @@ namespace mbgl { namespace shaders { const char* line_sdf::name = "line_sdf"; -const char* line_sdf::vertexSource = source() + 55692; -const char* line_sdf::fragmentSource = source() + 61058; +const char* line_sdf::vertexSource = source() + 61749; +const char* line_sdf::fragmentSource = source() + 67116; } // namespace shaders } // namespace mbgl diff --git a/src/mbgl/shaders/preludes.cpp b/src/mbgl/shaders/preludes.cpp index f4b0349355..90bcef346f 100644 --- a/src/mbgl/shaders/preludes.cpp +++ b/src/mbgl/shaders/preludes.cpp @@ -7,7 +7,7 @@ namespace mbgl { namespace shaders { const char* vertexPrelude = source() + 0; -const char* fragmentPrelude = source() + 2557; +const char* fragmentPrelude = source() + 2558; } // namespace shaders } // namespace mbgl diff --git a/src/mbgl/shaders/raster.cpp b/src/mbgl/shaders/raster.cpp index 501890a405..e228bb24c2 100644 --- a/src/mbgl/shaders/raster.cpp +++ b/src/mbgl/shaders/raster.cpp @@ -7,8 +7,8 @@ namespace mbgl { namespace shaders { const char* raster::name = "raster"; -const char* raster::vertexSource = source() + 62984; -const char* raster::fragmentSource = source() + 63797; +const char* raster::vertexSource = source() + 69042; +const char* raster::fragmentSource = source() + 69855; } // namespace shaders } // namespace mbgl diff --git a/src/mbgl/shaders/source.cpp b/src/mbgl/shaders/source.cpp index c480176cb0..3a133eb31b 100644 --- a/src/mbgl/shaders/source.cpp +++ b/src/mbgl/shaders/source.cpp @@ -10,1486 +10,1551 @@ namespace shaders { const char* source() { static const uint8_t compressed[] = { - 0x78, 0xda, 0xed, 0x3d, 0x6b, 0x73, 0xdb, 0x46, - 0x92, 0xfb, 0xd9, 0xbf, 0x62, 0xb2, 0xa9, 0x5a, - 0x93, 0x32, 0x49, 0x91, 0x94, 0xe4, 0x97, 0x56, - 0x97, 0xf2, 0x26, 0x4e, 0xce, 0x77, 0xd9, 0xc4, - 0x15, 0x25, 0x9b, 0xad, 0x4b, 0x79, 0x59, 0x00, - 0x01, 0x92, 0x58, 0x83, 0x00, 0x03, 0x80, 0xa2, - 0xe4, 0x3b, 0xff, 0xf7, 0xeb, 0xc7, 0x3c, 0xf1, - 0x12, 0x25, 0x4b, 0xb2, 0xec, 0x70, 0x6b, 0x15, - 0x4b, 0xc0, 0xa0, 0xa7, 0x67, 0xa6, 0xa7, 0xa7, - 0x5f, 0xd3, 0xfd, 0x65, 0x34, 0x0b, 0xc2, 0x99, - 0xf8, 0xee, 0xfb, 0xc9, 0xcb, 0xd3, 0x07, 0xab, - 0x2c, 0x9c, 0x46, 0x79, 0x94, 0x26, 0x62, 0x11, - 0xcd, 0x17, 0x2b, 0x31, 0x8b, 0x53, 0xaf, 0x38, - 0x7e, 0xf0, 0x65, 0x18, 0xe7, 0xe1, 0x83, 0x07, - 0x5f, 0x46, 0x33, 0xf1, 0x05, 0x34, 0x8e, 0x92, - 0x30, 0xe8, 0xc4, 0xe9, 0x66, 0xd5, 0x7d, 0xf0, - 0x25, 0xff, 0x29, 0xf0, 0x2f, 0x68, 0x96, 0x04, - 0xd1, 0xac, 0xd4, 0x6e, 0x19, 0x06, 0xd1, 0x7a, - 0x69, 0x35, 0x95, 0x0f, 0xea, 0x5b, 0x53, 0xb7, - 0xa6, 0x2d, 0xfd, 0x69, 0x5a, 0xca, 0x7f, 0xf7, - 0xf7, 0xc5, 0x2f, 0xc9, 0xca, 0x9b, 0xbe, 0x15, - 0x9e, 0x58, 0x79, 0x51, 0x26, 0xd2, 0x99, 0x38, - 0xf3, 0xe2, 0x75, 0x98, 0x8b, 0x62, 0xe1, 0x15, - 0x62, 0xe1, 0x9d, 0x85, 0xc2, 0x0f, 0xc3, 0x44, - 0x60, 0xa3, 0x30, 0x10, 0x51, 0x52, 0xa4, 0xd0, - 0x36, 0x8f, 0x92, 0x79, 0x1c, 0xf2, 0xa0, 0x06, - 0x08, 0xe5, 0xe7, 0x45, 0xa8, 0x9a, 0xc8, 0xef, - 0xbd, 0x2c, 0x14, 0x5e, 0x9e, 0xaf, 0x01, 0x49, - 0x01, 0xdf, 0xf8, 0xa1, 0x78, 0xda, 0xf7, 0xa3, - 0x42, 0xac, 0x93, 0x3c, 0x9a, 0x27, 0x0c, 0x2a, - 0x9c, 0x87, 0x59, 0xde, 0x13, 0x5e, 0x12, 0x60, - 0x73, 0x84, 0x23, 0x61, 0xc4, 0xd1, 0xdb, 0x50, - 0xe4, 0xe9, 0x73, 0xf3, 0xe8, 0x1f, 0x08, 0x55, - 0x9c, 0x60, 0x97, 0x69, 0xd6, 0x89, 0x92, 0xd5, - 0xba, 0xf8, 0x6d, 0xf8, 0xa6, 0x2b, 0xf6, 0xc4, - 0xf8, 0xe8, 0xb1, 0x78, 0x24, 0xf8, 0xc9, 0xe8, - 0x4d, 0xef, 0xc1, 0x59, 0x38, 0x1d, 0x43, 0x2f, - 0xf8, 0xd9, 0x84, 0x10, 0xec, 0x4c, 0xd3, 0x24, - 0x2f, 0x18, 0x59, 0x1b, 0x5a, 0x57, 0xfc, 0xef, - 0x03, 0x01, 0xff, 0x03, 0x44, 0xe4, 0xe3, 0x57, - 0x49, 0xa1, 0xfa, 0x81, 0x87, 0x1d, 0xbb, 0xed, - 0xb1, 0x6e, 0x7a, 0x36, 0x84, 0xd7, 0xa5, 0xf6, - 0xfb, 0x88, 0x05, 0x37, 0xc9, 0xc2, 0x62, 0x9d, - 0x25, 0x02, 0xb1, 0xe8, 0x9c, 0x0d, 0x7b, 0xe5, - 0x96, 0x7d, 0xfc, 0x9e, 0x90, 0x06, 0x90, 0xef, - 0x1f, 0x38, 0xd8, 0xa6, 0xf0, 0xdf, 0xa8, 0xb8, - 0xa8, 0xc1, 0xf7, 0x47, 0x7e, 0x63, 0x63, 0x0c, - 0x3f, 0xf2, 0xa9, 0x83, 0xad, 0x6e, 0x09, 0x28, - 0x55, 0x11, 0xe2, 0xf9, 0x30, 0x9f, 0x62, 0xb3, - 0xd1, 0xf8, 0xc9, 0x00, 0xf0, 0x5c, 0xa6, 0x81, - 0x0b, 0xa2, 0x27, 0xc6, 0x83, 0x61, 0x97, 0xb1, - 0xc4, 0x15, 0x4e, 0xc5, 0x32, 0x4a, 0xa2, 0x65, - 0xf4, 0x2e, 0x04, 0xda, 0x08, 0x45, 0xb2, 0x5e, - 0xfa, 0x21, 0x11, 0x8c, 0x57, 0x14, 0x59, 0xe4, - 0xaf, 0x0b, 0x58, 0xf4, 0x24, 0x0c, 0x83, 0x30, - 0xe8, 0x89, 0x4d, 0x28, 0xc2, 0x64, 0x9a, 0x06, - 0x40, 0x02, 0xe2, 0xb0, 0x3f, 0x4d, 0x97, 0xab, - 0x34, 0x09, 0x93, 0x02, 0xe1, 0x4c, 0xd3, 0x38, - 0xcd, 0x14, 0x1d, 0x29, 0x9a, 0x23, 0xbc, 0x72, - 0xd1, 0x89, 0x06, 0xe1, 0x00, 0x1e, 0x23, 0xae, - 0x5d, 0xa0, 0x1e, 0x31, 0x4b, 0x63, 0xd8, 0x0f, - 0x39, 0xd1, 0xc1, 0x6f, 0x72, 0xed, 0x09, 0xc0, - 0x20, 0xa3, 0x49, 0x3c, 0x32, 0x04, 0xc0, 0x8f, - 0xe7, 0xfc, 0xb8, 0x87, 0x1f, 0x08, 0xe7, 0x03, - 0xbf, 0xf5, 0x03, 0xf1, 0x06, 0x57, 0xe2, 0x50, - 0x04, 0x21, 0x62, 0x3d, 0xa1, 0x77, 0x72, 0x1d, - 0x68, 0x85, 0x78, 0x34, 0xc1, 0xd7, 0xf8, 0x5c, - 0xad, 0x82, 0x99, 0xd8, 0xc3, 0x0e, 0x3d, 0xc0, - 0xff, 0x39, 0x84, 0x67, 0x7f, 0x45, 0xd4, 0x8a, - 0x74, 0x72, 0x04, 0xb3, 0xbd, 0x45, 0xf3, 0x91, - 0x69, 0x4e, 0xad, 0xf5, 0x42, 0x54, 0x36, 0x2c, - 0xfc, 0x8b, 0x64, 0x29, 0xb7, 0x5d, 0xc2, 0x3b, - 0x2b, 0x5b, 0xa5, 0xb1, 0x57, 0xe0, 0xe6, 0x2d, - 0x36, 0xb8, 0x7f, 0x61, 0xc9, 0x96, 0x83, 0x07, - 0x4c, 0x53, 0xb2, 0xd3, 0x65, 0x74, 0x3e, 0x21, - 0xaa, 0xb0, 0xc6, 0x69, 0x91, 0x7c, 0x4f, 0xd8, - 0x74, 0x58, 0x94, 0x46, 0x0d, 0x1f, 0xdb, 0xfb, - 0x03, 0x46, 0xd7, 0xb3, 0x3f, 0xc6, 0x9d, 0x08, - 0xdf, 0xdc, 0x04, 0xce, 0xb4, 0x2e, 0x2e, 0xca, - 0x87, 0x06, 0xe5, 0x43, 0xd9, 0x2b, 0x4d, 0x5a, - 0xde, 0x80, 0x33, 0xb5, 0x03, 0xea, 0xa5, 0x46, - 0xb0, 0x5d, 0x9c, 0x55, 0xa6, 0x29, 0xb0, 0x81, - 0x58, 0x63, 0x91, 0x0f, 0x60, 0x2d, 0x24, 0x03, - 0x60, 0x48, 0xde, 0xf9, 0x96, 0x90, 0xc6, 0x65, - 0x48, 0x07, 0x1a, 0x92, 0x35, 0x8f, 0x0a, 0xb3, - 0x9e, 0x86, 0x6c, 0xcf, 0x1d, 0xb2, 0xd6, 0x74, - 0x36, 0xcb, 0xc3, 0x02, 0x7a, 0x5b, 0x01, 0xe3, - 0xce, 0x05, 0x9e, 0x2a, 0xe9, 0x06, 0x5a, 0x27, - 0x17, 0x62, 0x15, 0x9d, 0xc3, 0x99, 0x42, 0xec, - 0xd6, 0x9a, 0x37, 0xb1, 0x49, 0xb3, 0x38, 0x10, - 0x69, 0x16, 0xcd, 0xa3, 0x84, 0x26, 0x18, 0x1f, - 0x86, 0xc1, 0x1c, 0x61, 0xd1, 0xef, 0x45, 0x14, - 0x87, 0xb4, 0xaf, 0x68, 0xdd, 0x65, 0x07, 0x27, - 0xcc, 0x06, 0x10, 0x24, 0x8c, 0x29, 0xcd, 0x60, - 0x2b, 0xe7, 0xb0, 0xe1, 0xbb, 0xd0, 0x0e, 0x9b, - 0xbe, 0x28, 0xe8, 0x1c, 0x11, 0xef, 0xd2, 0x74, - 0x29, 0xe2, 0xf0, 0x0c, 0x3b, 0x06, 0x58, 0xc8, - 0xe9, 0xf1, 0x07, 0xf8, 0x7c, 0x42, 0x8b, 0xcb, - 0x28, 0x5d, 0x19, 0x1d, 0x7d, 0x92, 0xcc, 0xe3, - 0x3c, 0x16, 0xf9, 0x2a, 0x9c, 0xc2, 0x48, 0xe3, - 0x0b, 0x31, 0x5f, 0x7b, 0x99, 0x07, 0xf4, 0x01, - 0xa4, 0x32, 0x7a, 0x2c, 0xe0, 0x10, 0xc9, 0xa9, - 0x17, 0x7d, 0xc2, 0xce, 0x60, 0x29, 0xac, 0x53, - 0x36, 0x1f, 0x88, 0x5f, 0x43, 0x62, 0x45, 0x30, - 0x9a, 0x0c, 0xb9, 0x95, 0x97, 0xd0, 0x71, 0x36, - 0x90, 0xc3, 0xa0, 0xc3, 0xca, 0x8c, 0x51, 0x44, - 0x39, 0x2c, 0x52, 0x9e, 0xd3, 0x99, 0x84, 0x5c, - 0xa7, 0xd8, 0xa4, 0xb2, 0x23, 0x49, 0xa1, 0x7c, - 0x0e, 0x99, 0x2f, 0x26, 0xeb, 0xd5, 0x2a, 0xcc, - 0xf4, 0x69, 0x64, 0xc3, 0x82, 0x2d, 0xfb, 0xaf, - 0xd1, 0xe3, 0x6e, 0xf9, 0x03, 0xe0, 0x62, 0xf4, - 0x41, 0x65, 0x7a, 0x55, 0xeb, 0xd2, 0x4a, 0x03, - 0x4a, 0x53, 0x2f, 0x9e, 0xae, 0x71, 0x3f, 0x30, - 0x5a, 0x22, 0x0f, 0xb3, 0x28, 0xa4, 0x91, 0xe7, - 0x45, 0xb8, 0x92, 0x07, 0x74, 0xbe, 0x48, 0xd7, - 0x30, 0xb1, 0x30, 0x17, 0xf0, 0xfa, 0x0c, 0xc7, - 0x8a, 0x83, 0x51, 0x33, 0xf3, 0x9c, 0x8f, 0x97, - 0x79, 0x58, 0x4c, 0x56, 0xc0, 0xa5, 0xc3, 0x2c, - 0x99, 0xac, 0xd2, 0xdc, 0xd9, 0xef, 0xe5, 0x41, - 0xa9, 0x1d, 0x54, 0x79, 0x4b, 0x23, 0x60, 0xc6, - 0xe5, 0xf0, 0x0b, 0x06, 0x8b, 0x54, 0x52, 0xda, - 0x7c, 0xb0, 0xa0, 0x93, 0x75, 0x02, 0x8b, 0x35, - 0x29, 0xd2, 0x09, 0x93, 0x84, 0x0b, 0x3c, 0xcd, - 0x71, 0x7f, 0xaa, 0x6d, 0x55, 0xa2, 0x41, 0xf5, - 0x53, 0x83, 0xa0, 0xdd, 0xa7, 0x64, 0xe7, 0x83, - 0x61, 0xc3, 0x63, 0xe0, 0xf3, 0xd5, 0x41, 0xb8, - 0x4d, 0x9d, 0xed, 0xd8, 0xa9, 0x43, 0x1b, 0x80, - 0x01, 0xb2, 0x00, 0x8a, 0x31, 0x44, 0xbe, 0x6c, - 0x43, 0xc0, 0x8d, 0xfa, 0xa7, 0x2f, 0xeb, 0x85, - 0x3f, 0x29, 0xa2, 0xdd, 0x4f, 0xf1, 0xef, 0x4f, - 0xfa, 0xe4, 0xe6, 0x05, 0xf0, 0x90, 0x3a, 0x8e, - 0x1f, 0x3c, 0x80, 0xe1, 0xc3, 0x96, 0x5a, 0x02, - 0x7f, 0x29, 0x80, 0xf3, 0x4e, 0xe0, 0x9f, 0x2c, - 0x3a, 0x87, 0xe7, 0x67, 0x69, 0x04, 0x5b, 0x0a, - 0x38, 0x77, 0x47, 0x31, 0xd6, 0x79, 0x3c, 0x79, - 0x9d, 0xe6, 0x51, 0x81, 0x43, 0x3d, 0xd1, 0x4d, - 0x61, 0xbe, 0x88, 0x49, 0x13, 0xbc, 0x9e, 0x80, - 0xb5, 0x19, 0x11, 0x37, 0xfb, 0x93, 0x02, 0xcc, - 0x2c, 0x9d, 0xb9, 0xe6, 0xb1, 0xee, 0x4e, 0x1e, - 0x4e, 0x4a, 0x0c, 0x6a, 0xea, 0xf0, 0xdb, 0xcc, - 0x9b, 0x2b, 0xf6, 0x2b, 0x61, 0x40, 0x87, 0xf6, - 0x67, 0x72, 0x2d, 0x7e, 0xfc, 0xc7, 0xcb, 0x9f, - 0xbe, 0xf9, 0xe9, 0xc5, 0xaf, 0x93, 0x57, 0x3f, - 0x9c, 0xbe, 0x7e, 0xf9, 0xf5, 0xcf, 0x3f, 0xfe, - 0x54, 0x07, 0x82, 0x30, 0x1d, 0x81, 0xa4, 0x73, - 0xac, 0xa6, 0xc5, 0x42, 0xb4, 0x34, 0x03, 0x16, - 0xfe, 0x20, 0xb4, 0x4d, 0x6c, 0x22, 0x98, 0x78, - 0xed, 0xaf, 0xfd, 0xea, 0xeb, 0x32, 0x65, 0xb7, - 0xb6, 0x20, 0xca, 0xad, 0xce, 0x55, 0x0e, 0x5c, - 0xc2, 0xe9, 0xdb, 0x7d, 0xe1, 0x57, 0x5f, 0xd4, - 0x11, 0x38, 0xcc, 0x59, 0x03, 0x29, 0x9c, 0x79, - 0xd9, 0x05, 0xc8, 0xfa, 0xfc, 0xf0, 0x0c, 0x1f, - 0x62, 0x67, 0x35, 0x4f, 0xfd, 0x0f, 0xa6, 0x0f, - 0x66, 0x04, 0xdc, 0x05, 0x34, 0x2e, 0x33, 0xad, - 0x9a, 0x09, 0xeb, 0xd5, 0xcd, 0x51, 0xcf, 0xcc, - 0x0a, 0x91, 0x85, 0xbb, 0x48, 0xbd, 0x86, 0x19, - 0xe8, 0xf1, 0x88, 0xd5, 0x29, 0xcf, 0x43, 0xba, - 0x11, 0x2c, 0xfc, 0x2a, 0x16, 0xfe, 0xe5, 0x58, - 0xb8, 0x9b, 0xc5, 0xa6, 0xa6, 0x22, 0x6e, 0x21, - 0x35, 0x3f, 0x6b, 0x79, 0x09, 0x5f, 0xfa, 0x6d, - 0x5f, 0x56, 0x5f, 0x16, 0xe1, 0x39, 0x33, 0xb8, - 0x32, 0x11, 0x2d, 0xed, 0xdd, 0x50, 0xdd, 0xb7, - 0xea, 0x4d, 0xee, 0x2d, 0x57, 0x71, 0x98, 0x8d, - 0xbf, 0x81, 0xb7, 0xd1, 0xd2, 0x9b, 0x87, 0x1f, - 0x4e, 0x51, 0xd4, 0x80, 0x60, 0xf1, 0x79, 0xcb, - 0xa7, 0x85, 0x84, 0x03, 0x84, 0x44, 0x1b, 0x59, - 0x37, 0x44, 0xb6, 0x7d, 0x42, 0x32, 0x96, 0x3b, - 0x81, 0xc0, 0xc1, 0xf5, 0xe8, 0x7a, 0xa5, 0xf9, - 0x73, 0xdf, 0x99, 0xae, 0x6c, 0x09, 0x90, 0xb8, - 0xce, 0x08, 0x40, 0x43, 0x3b, 0x38, 0x37, 0xc2, - 0xf1, 0x37, 0x1d, 0x39, 0xc2, 0x9e, 0xe0, 0x05, - 0xac, 0x43, 0x96, 0x28, 0xca, 0xa0, 0xeb, 0xd7, - 0xa1, 0x3b, 0xae, 0xc3, 0xd7, 0x6f, 0xc1, 0xd7, - 0x6f, 0xc2, 0x77, 0xe2, 0x57, 0x30, 0x1e, 0x37, - 0x62, 0x3c, 0x56, 0x28, 0x97, 0xb8, 0x23, 0xa2, - 0xc2, 0x83, 0xed, 0x49, 0x10, 0x3d, 0x5e, 0xfe, - 0xee, 0x5d, 0xf3, 0x5c, 0x3f, 0x4d, 0x63, 0xbd, - 0xa9, 0x36, 0x51, 0xb1, 0x80, 0x16, 0xab, 0xca, - 0xeb, 0x55, 0x54, 0x4c, 0x17, 0x35, 0xaf, 0x25, - 0x41, 0xc3, 0xd8, 0xb3, 0x35, 0xc8, 0xeb, 0x04, - 0xc5, 0xbc, 0xb5, 0x84, 0x47, 0x3c, 0x52, 0xbc, - 0x65, 0x98, 0x79, 0xb8, 0x2b, 0xa7, 0x21, 0x6a, - 0x25, 0x93, 0x20, 0xca, 0x0b, 0x2f, 0x99, 0x86, - 0xcd, 0x6c, 0x12, 0x87, 0x9f, 0xe0, 0xf8, 0xff, - 0xf3, 0xc5, 0xe9, 0xe4, 0x97, 0x1f, 0x5e, 0x7d, - 0xfb, 0xe3, 0x4f, 0x7f, 0x9f, 0xc8, 0xc3, 0x49, - 0xf7, 0x82, 0x47, 0xbb, 0xec, 0xc4, 0xe3, 0x57, - 0x13, 0x10, 0x09, 0x0c, 0x44, 0xc6, 0x82, 0x56, - 0xcb, 0x53, 0x67, 0xa3, 0xda, 0x17, 0xd6, 0x3b, - 0xf9, 0x86, 0x45, 0x09, 0x77, 0x04, 0xee, 0xb9, - 0xaa, 0x4e, 0xfb, 0x06, 0xe4, 0x32, 0x0f, 0xc4, - 0x87, 0xbc, 0x1e, 0x3b, 0x7e, 0xe7, 0xa2, 0xa7, - 0x44, 0x19, 0x39, 0x70, 0x6e, 0x62, 0x30, 0x74, - 0x24, 0x1d, 0xa1, 0xde, 0xba, 0x58, 0xba, 0x6d, - 0xd6, 0x13, 0xd3, 0xaa, 0x15, 0x53, 0x3f, 0x5e, - 0x37, 0xcc, 0x22, 0xbe, 0x71, 0xb1, 0xa4, 0xd7, - 0x12, 0x45, 0x7c, 0x6b, 0x10, 0xb4, 0x3e, 0xe4, - 0x17, 0x2e, 0x6e, 0xd6, 0xeb, 0xf5, 0x44, 0x35, - 0x68, 0x45, 0x4b, 0x12, 0x7f, 0x3d, 0x66, 0xf2, - 0x65, 0x33, 0x72, 0x7a, 0xeb, 0xd4, 0xe0, 0xa7, - 0xdf, 0xb5, 0xa0, 0x68, 0xb5, 0x69, 0xc5, 0x32, - 0x2f, 0xb2, 0xf4, 0x6d, 0xd8, 0x46, 0x8a, 0x76, - 0x8b, 0x16, 0x8a, 0xb4, 0x9b, 0xd5, 0x12, 0xa6, - 0xdb, 0xa0, 0x85, 0x3e, 0xcb, 0x0d, 0xb7, 0xc1, - 0x7f, 0x13, 0x05, 0xc5, 0xa2, 0x15, 0x7f, 0x6a, - 0xd1, 0x4a, 0xb2, 0x76, 0xc3, 0x26, 0xc2, 0x75, - 0xdb, 0xb4, 0x93, 0x6f, 0xb9, 0xed, 0x36, 0xe3, - 0x68, 0x25, 0x1a, 0xb7, 0x4d, 0x33, 0xed, 0xb8, - 0xed, 0x6a, 0x49, 0xa8, 0xdc, 0xa4, 0x85, 0x92, - 0xaa, 0x4d, 0xe5, 0x40, 0xac, 0x43, 0xf9, 0x00, - 0x0e, 0xe5, 0xc0, 0x2b, 0x3c, 0xe7, 0x4c, 0xc6, - 0xdf, 0xd4, 0xb9, 0xdc, 0xca, 0x01, 0x59, 0x69, - 0x94, 0x22, 0x7b, 0xc9, 0x92, 0x23, 0x59, 0x5d, - 0xcf, 0xf0, 0xc4, 0xae, 0xc2, 0x16, 0x3f, 0x2b, - 0x33, 0x3e, 0x23, 0xf4, 0x1b, 0x44, 0x5b, 0xfa, - 0x97, 0x4c, 0x8e, 0x34, 0x3c, 0xfa, 0xb5, 0x82, - 0xc1, 0xb8, 0xa3, 0x78, 0x59, 0xcf, 0x62, 0x7c, - 0x0e, 0x0e, 0x75, 0xac, 0x8d, 0xf0, 0x28, 0xf3, - 0xaf, 0x16, 0x44, 0x88, 0x87, 0xe1, 0x7b, 0xfc, - 0xa5, 0x16, 0x09, 0x7c, 0xd1, 0xd3, 0x3c, 0xcd, - 0x41, 0xa0, 0xc4, 0xba, 0xa8, 0x6f, 0x97, 0x45, - 0xb5, 0xf4, 0xac, 0x28, 0x0e, 0x9b, 0xa4, 0xda, - 0x62, 0x5c, 0xed, 0x3f, 0x55, 0x66, 0x5f, 0x8b, - 0x79, 0x35, 0x61, 0x61, 0xc1, 0xa9, 0xd2, 0x4d, - 0x0b, 0x2e, 0x0e, 0x33, 0xc2, 0x76, 0xf6, 0x83, - 0x5a, 0xe2, 0xb0, 0x1b, 0xf4, 0x2a, 0xcc, 0xaa, - 0x89, 0x54, 0xca, 0x60, 0x1b, 0x58, 0xce, 0xe5, - 0x98, 0x32, 0xdb, 0xb1, 0x30, 0xa5, 0x07, 0xb5, - 0xf3, 0x67, 0x37, 0xe8, 0x55, 0xd8, 0x52, 0x0b, - 0x41, 0x95, 0x21, 0x37, 0xf0, 0x95, 0xcb, 0x91, - 0xb5, 0x57, 0xda, 0x7d, 0xd4, 0x86, 0xb0, 0xb5, - 0xee, 0x65, 0xfe, 0xd3, 0xb4, 0xfc, 0x55, 0xe0, - 0xcd, 0x4c, 0x04, 0x3f, 0xdd, 0x07, 0x11, 0x35, - 0x91, 0x0e, 0x01, 0x32, 0xfc, 0xa1, 0x18, 0x46, - 0xf6, 0x11, 0x40, 0xa5, 0x80, 0x25, 0x22, 0x5b, - 0xd6, 0x26, 0x14, 0x79, 0xb2, 0x9e, 0xbe, 0x65, - 0xe7, 0x00, 0xb6, 0x23, 0xf1, 0x4a, 0xb6, 0x31, - 0x52, 0xb2, 0x14, 0xe2, 0x58, 0x8e, 0x1c, 0x93, - 0x95, 0x48, 0x6a, 0x92, 0xe8, 0xb0, 0x40, 0xcb, - 0xcf, 0x60, 0x28, 0xfa, 0x52, 0xb6, 0x56, 0xfd, - 0x2f, 0xd7, 0x71, 0x11, 0xad, 0xe2, 0x0b, 0x09, - 0xd3, 0xbf, 0x10, 0xc3, 0xc1, 0x11, 0x5a, 0x37, - 0x41, 0xae, 0xc3, 0x9e, 0x17, 0x5e, 0x20, 0xa2, - 0x02, 0x3f, 0x46, 0x6b, 0x1b, 0x88, 0xcf, 0x61, - 0x86, 0x6e, 0xab, 0x3c, 0x09, 0xbd, 0xb7, 0x0a, - 0x06, 0xbc, 0x30, 0x98, 0x23, 0x37, 0x34, 0x38, - 0x4d, 0xa3, 0x6c, 0x0a, 0x72, 0x29, 0x0b, 0x8c, - 0xda, 0x30, 0xc8, 0x7d, 0xed, 0x61, 0x57, 0xca, - 0x81, 0x34, 0x13, 0x9d, 0xb2, 0x94, 0xaa, 0x58, - 0xa8, 0x01, 0x96, 0x66, 0x09, 0x88, 0x9d, 0x2b, - 0xa3, 0x39, 0x3b, 0xe0, 0x8f, 0x75, 0x6b, 0x86, - 0xe6, 0x8a, 0xc4, 0x36, 0x34, 0xe6, 0xbb, 0x2e, - 0xb0, 0x47, 0x27, 0x7a, 0x02, 0xf7, 0x44, 0x47, - 0x32, 0xb3, 0x47, 0x0e, 0x11, 0xb2, 0x6c, 0x5f, - 0x92, 0x95, 0x15, 0xbc, 0xf7, 0x02, 0x29, 0xa2, - 0xd4, 0x09, 0x4c, 0xce, 0x6b, 0x1c, 0x13, 0x9e, - 0x16, 0xb8, 0x70, 0x8c, 0xaf, 0x40, 0x9c, 0xe8, - 0x6f, 0xc0, 0x4b, 0x84, 0xb3, 0x19, 0x2c, 0x64, - 0x74, 0x16, 0xc2, 0x22, 0x10, 0xcc, 0x1c, 0x27, - 0xdc, 0x6e, 0x52, 0x06, 0xf9, 0x73, 0x0a, 0xd8, - 0xaf, 0x71, 0xc8, 0xde, 0xb4, 0x60, 0xc2, 0x21, - 0x18, 0x64, 0xf0, 0xa5, 0x39, 0xec, 0x13, 0xa0, - 0xe7, 0xe2, 0x2c, 0x0a, 0x37, 0xab, 0x34, 0x2b, - 0xc8, 0xf3, 0x94, 0x85, 0xf4, 0x14, 0x3f, 0x28, - 0x43, 0xdc, 0x2c, 0xd2, 0x58, 0x63, 0xe7, 0x7b, - 0x68, 0xf2, 0x4d, 0xd9, 0x40, 0x4d, 0xe0, 0x08, - 0x2f, 0x1c, 0x83, 0xec, 0x07, 0x88, 0x12, 0x8d, - 0xcd, 0x38, 0xed, 0x99, 0x17, 0x83, 0x9e, 0x04, - 0x94, 0xe9, 0x80, 0x64, 0x07, 0x44, 0x96, 0xfe, - 0x1b, 0x5a, 0x87, 0x81, 0x59, 0xfe, 0xb2, 0xa5, - 0xc3, 0x59, 0x3f, 0x6d, 0xf1, 0xb8, 0xf9, 0x65, - 0xc2, 0xb6, 0x65, 0x74, 0x06, 0x1b, 0xd2, 0x10, - 0x1b, 0xb5, 0x1a, 0x0b, 0x91, 0xf7, 0x0f, 0xf4, - 0xaf, 0xed, 0x96, 0x9b, 0x12, 0xb6, 0xce, 0x88, - 0x2a, 0x04, 0x72, 0x09, 0xa8, 0xda, 0xa9, 0xb9, - 0x12, 0x89, 0x5b, 0x1d, 0x0c, 0xce, 0x2f, 0xae, - 0x3f, 0x75, 0xad, 0xaa, 0x5f, 0x2b, 0xfd, 0xdf, - 0x14, 0x06, 0x36, 0x9c, 0x8d, 0xbd, 0x2e, 0xd6, - 0xea, 0x90, 0xa3, 0x20, 0xca, 0xd1, 0x45, 0xe0, - 0xb1, 0x4b, 0x76, 0xbd, 0x64, 0xb1, 0x40, 0x21, - 0x2b, 0x5d, 0x03, 0xe8, 0x10, 0xc8, 0xd1, 0x9f, - 0xe1, 0x89, 0x99, 0xb7, 0x3e, 0xef, 0x7b, 0x49, - 0x11, 0x01, 0x79, 0x7b, 0xe8, 0xbc, 0xc7, 0x2d, - 0xa4, 0xa0, 0x99, 0x0d, 0x3b, 0x90, 0xfc, 0x90, - 0xa0, 0x11, 0xfc, 0xcc, 0x03, 0x5c, 0x94, 0x8f, - 0x86, 0x1b, 0x3d, 0xcc, 0xc9, 0x27, 0xa4, 0xbd, - 0x38, 0xe8, 0xb9, 0x43, 0x7f, 0x74, 0xae, 0xe1, - 0xa5, 0xe2, 0x6d, 0x18, 0xae, 0xe8, 0x25, 0x41, - 0x42, 0xa1, 0x29, 0x5d, 0xcf, 0x17, 0xb0, 0xf1, - 0x47, 0xab, 0xf3, 0x1e, 0xfb, 0x7b, 0x36, 0x29, - 0x39, 0x8d, 0xa2, 0xe4, 0x2c, 0xcc, 0x72, 0xe4, - 0x09, 0x59, 0x48, 0xce, 0x8e, 0x41, 0xf9, 0xb0, - 0xd1, 0x68, 0x4b, 0xd1, 0x07, 0xf8, 0x3a, 0x10, - 0xf4, 0x37, 0x2f, 0xff, 0xf1, 0xea, 0xeb, 0x97, - 0x93, 0xd7, 0xaf, 0xfe, 0xf9, 0xf2, 0xfb, 0xc9, - 0x4f, 0x2f, 0x7e, 0x7e, 0xf5, 0x23, 0x3c, 0x6c, - 0x98, 0x6a, 0x6d, 0x5b, 0x44, 0x9e, 0xcd, 0xc7, - 0xc6, 0x41, 0x47, 0x4e, 0xfd, 0x00, 0xf0, 0x51, - 0xbf, 0xe2, 0x19, 0x68, 0x77, 0xc6, 0x76, 0xb8, - 0x56, 0xc9, 0xf6, 0xf6, 0xf5, 0xf3, 0xbb, 0xd2, - 0xaf, 0x6f, 0x5d, 0x4d, 0xbe, 0x4b, 0x3d, 0xf7, - 0xe3, 0x68, 0xa7, 0x1f, 0x57, 0xa3, 0xfc, 0x48, - 0x4a, 0xa0, 0xad, 0x00, 0xb6, 0xe9, 0x7f, 0x57, - 0x51, 0xe4, 0x5a, 0xf5, 0xb8, 0x2b, 0x6b, 0x63, - 0x2d, 0xca, 0xd8, 0xf6, 0x8a, 0x55, 0xbb, 0x5e, - 0x75, 0x55, 0xd5, 0x68, 0x0b, 0xcd, 0xe8, 0xfa, - 0xda, 0xcc, 0x16, 0xca, 0xcc, 0x07, 0x29, 0x20, - 0x5b, 0xe9, 0x1f, 0x1f, 0xa0, 0x2d, 0x94, 0x85, - 0x7c, 0xa2, 0x39, 0x38, 0x56, 0xf9, 0x3c, 0x64, - 0x98, 0xea, 0xe0, 0x8c, 0xc3, 0x64, 0x4e, 0x48, - 0xf3, 0x2f, 0x8a, 0xab, 0x2b, 0x96, 0xdf, 0x72, - 0x8c, 0x48, 0xb0, 0xef, 0x6c, 0xa8, 0xba, 0x0d, - 0x08, 0x4f, 0xb2, 0x59, 0x7f, 0xe9, 0x9d, 0x77, - 0xa4, 0x6a, 0x5e, 0x3a, 0x1b, 0xac, 0x0f, 0xb5, - 0xc6, 0x04, 0x5f, 0xe4, 0xcb, 0x34, 0x2d, 0x16, - 0xe8, 0xa3, 0xef, 0x0c, 0xd1, 0x2f, 0x5d, 0x06, - 0xda, 0x2b, 0x23, 0xef, 0xa8, 0x2a, 0x0c, 0x4f, - 0xaa, 0xb7, 0x08, 0xcd, 0x5e, 0x9b, 0xbf, 0x82, - 0x26, 0x31, 0x1c, 0x89, 0xaf, 0xf0, 0x1f, 0xf1, - 0xdc, 0xee, 0x49, 0x8b, 0x0a, 0x95, 0xde, 0xf4, - 0x9b, 0xa1, 0x1d, 0x77, 0x54, 0x41, 0x41, 0xee, - 0xa3, 0xc6, 0x33, 0x54, 0xc5, 0x20, 0xd5, 0x99, - 0xf3, 0xcd, 0xe8, 0xf7, 0x8c, 0xc3, 0x00, 0x7e, - 0xd7, 0x9a, 0xa5, 0x43, 0xc0, 0x7b, 0xa2, 0xac, - 0x78, 0x1a, 0x65, 0xfe, 0x06, 0xdc, 0x08, 0x77, - 0xed, 0xd3, 0xbe, 0xd4, 0x47, 0x6d, 0x61, 0xd9, - 0x2c, 0x4d, 0x6c, 0x42, 0xd8, 0xee, 0x45, 0xbd, - 0x55, 0x90, 0xdf, 0x35, 0x58, 0x66, 0xc7, 0xba, - 0x41, 0xd9, 0x26, 0xcb, 0x9f, 0xab, 0x77, 0x75, - 0x07, 0x9e, 0xe2, 0xfd, 0xa6, 0xcd, 0x5d, 0x38, - 0x0c, 0xae, 0x28, 0xb2, 0x5c, 0xe2, 0x16, 0x52, - 0xdf, 0x35, 0x78, 0x76, 0x2a, 0x52, 0x44, 0xf9, - 0x05, 0x49, 0xaf, 0x39, 0xfb, 0xb0, 0xb6, 0xf3, - 0x81, 0xcb, 0x9e, 0x8e, 0x29, 0x38, 0xeb, 0xa5, - 0x52, 0x6a, 0xc5, 0x9f, 0x87, 0x7f, 0x46, 0x03, - 0x01, 0xca, 0xb6, 0x6f, 0x43, 0xd0, 0x8e, 0x62, - 0x11, 0x30, 0x60, 0xe5, 0x71, 0x43, 0xb9, 0xd8, - 0x0b, 0xfe, 0xbd, 0xce, 0x0b, 0xbb, 0x11, 0x89, - 0xd2, 0x45, 0x7a, 0xfc, 0x80, 0x04, 0x71, 0x90, - 0xb9, 0xc3, 0xe5, 0x2a, 0xca, 0x22, 0x18, 0x05, - 0x88, 0xc4, 0xd3, 0x45, 0x9a, 0x87, 0x89, 0x0a, - 0xb5, 0x54, 0xe1, 0x97, 0x18, 0xec, 0x55, 0x44, - 0x33, 0xd0, 0x89, 0x29, 0x12, 0x2c, 0x05, 0x01, - 0x3a, 0xf6, 0x56, 0x2b, 0x44, 0x91, 0x81, 0xe6, - 0x08, 0x0c, 0x75, 0xe4, 0xe2, 0x62, 0x85, 0x90, - 0xc4, 0x22, 0xf4, 0x0a, 0x54, 0xc1, 0xa7, 0xc0, - 0x16, 0x72, 0xd1, 0xa1, 0xb0, 0x5c, 0x6c, 0x3e, - 0x8d, 0x01, 0x9b, 0x30, 0x03, 0x2d, 0x38, 0x4f, - 0xd7, 0x19, 0xa8, 0x82, 0x0f, 0x38, 0x3e, 0xc7, - 0x26, 0x8f, 0xff, 0x79, 0xf9, 0xd3, 0x8f, 0x5a, - 0xea, 0xa6, 0x70, 0x44, 0x8c, 0x19, 0x7d, 0x3c, - 0x18, 0xf2, 0x04, 0x7c, 0xe7, 0xad, 0xf3, 0x3c, - 0xf2, 0x12, 0x35, 0x9e, 0x69, 0x0a, 0xba, 0x73, - 0x34, 0x8d, 0x40, 0x25, 0x78, 0x2e, 0x46, 0xd0, - 0x34, 0xff, 0x3d, 0x2b, 0x3a, 0x63, 0xd8, 0x3e, - 0xaf, 0x5f, 0x99, 0x70, 0x94, 0xef, 0x5e, 0xfc, - 0x72, 0x7a, 0x3a, 0xf9, 0xfa, 0xc7, 0x97, 0xdf, - 0x02, 0x5b, 0x3a, 0x78, 0xf6, 0xf4, 0xd9, 0xe1, - 0x78, 0xfc, 0x74, 0x78, 0x38, 0x1c, 0x1d, 0x1e, - 0x8c, 0x9f, 0x5c, 0xd1, 0xc4, 0x2c, 0xb7, 0x0e, - 0xb6, 0xe0, 0x5f, 0x6b, 0x8d, 0x5d, 0xfc, 0xaa, - 0x67, 0x6d, 0xa7, 0x1a, 0xdb, 0xa1, 0xbd, 0x65, - 0x68, 0xef, 0x97, 0x77, 0xc6, 0x76, 0x96, 0xe6, - 0x26, 0x09, 0xe5, 0xd6, 0xec, 0xce, 0xb7, 0x60, - 0x64, 0x5b, 0x27, 0xb4, 0x93, 0x82, 0xc9, 0xb5, - 0xac, 0x6d, 0xa4, 0xa0, 0x3e, 0x94, 0x9f, 0x3e, - 0x04, 0xa2, 0x58, 0xa2, 0xb5, 0x27, 0x81, 0x31, - 0x24, 0x73, 0xd2, 0x3e, 0xb3, 0x74, 0x29, 0x7e, - 0xeb, 0x8f, 0x7a, 0xa2, 0x4f, 0x81, 0xa2, 0xa9, - 0xf8, 0x0d, 0x7e, 0x1f, 0xbd, 0x19, 0x08, 0xf1, - 0x6b, 0xf8, 0x30, 0x8e, 0xc5, 0x5a, 0x4e, 0x01, - 0x5a, 0xdd, 0x0a, 0x7c, 0xbf, 0xca, 0xd2, 0x60, - 0x3d, 0xe5, 0x91, 0x01, 0xc1, 0x17, 0xd1, 0x94, - 0x63, 0xe1, 0x3c, 0x20, 0xb0, 0x35, 0x2a, 0x92, - 0xd0, 0xc3, 0x02, 0xe0, 0x7a, 0x4b, 0x65, 0x83, - 0x22, 0x6b, 0x8d, 0x98, 0x01, 0xe9, 0xc3, 0xe6, - 0x53, 0xc0, 0x36, 0xe1, 0x43, 0x8c, 0x54, 0x0c, - 0x02, 0x6a, 0x95, 0xb6, 0x6c, 0x57, 0x8d, 0x8a, - 0x17, 0xe7, 0x29, 0xc5, 0x07, 0x22, 0x26, 0x9e, - 0xd6, 0x72, 0x3d, 0x21, 0xf9, 0x02, 0x1c, 0x6f, - 0x29, 0xcf, 0x2d, 0x02, 0x03, 0x0c, 0xe6, 0x4b, - 0xd4, 0x87, 0xf3, 0x85, 0x87, 0x36, 0xc4, 0x29, - 0x6c, 0x8d, 0x20, 0x84, 0x4d, 0xb6, 0x44, 0xba, - 0xc7, 0x16, 0x5a, 0x4b, 0x4f, 0x67, 0x0a, 0x56, - 0xe8, 0x4d, 0x17, 0xe6, 0x4b, 0x9a, 0x9c, 0xca, - 0x08, 0x06, 0xaa, 0xf1, 0xdf, 0xc2, 0x19, 0x46, - 0x35, 0xc2, 0x42, 0x06, 0x29, 0x74, 0x4d, 0x26, - 0x2f, 0x0a, 0x76, 0x44, 0x73, 0x25, 0xd9, 0x11, - 0x30, 0xca, 0x7e, 0x25, 0xf2, 0xb5, 0xda, 0x88, - 0x68, 0x70, 0x33, 0x28, 0x2a, 0x38, 0x72, 0xd8, - 0x33, 0xe0, 0x34, 0xb9, 0x63, 0x9c, 0x03, 0x38, - 0xef, 0xc2, 0x2c, 0x15, 0x72, 0x44, 0x76, 0x94, - 0x26, 0x4e, 0xf2, 0xc0, 0x2c, 0x32, 0xda, 0xc7, - 0x72, 0x42, 0x60, 0x03, 0x72, 0x07, 0x29, 0xfe, - 0x49, 0xba, 0x11, 0xa7, 0xd0, 0xf7, 0x74, 0x41, - 0x1d, 0x9a, 0x79, 0xa7, 0x3d, 0xb5, 0x67, 0x73, - 0x5c, 0xf8, 0xcb, 0xe2, 0x03, 0x7b, 0x40, 0xb0, - 0xab, 0x4e, 0x7f, 0x38, 0x38, 0x82, 0x5f, 0x0f, - 0x06, 0xc3, 0x7f, 0x21, 0xcf, 0x38, 0xfd, 0xd7, - 0xb8, 0x2b, 0x4e, 0x4e, 0x88, 0x09, 0x29, 0x50, - 0xbf, 0x2e, 0x22, 0xb4, 0xd4, 0xa5, 0x31, 0x5a, - 0x37, 0x8a, 0xf4, 0xb9, 0x7a, 0x7e, 0x8a, 0xd2, - 0x12, 0x32, 0x9b, 0x3e, 0x52, 0xe4, 0x1e, 0x9c, - 0x4f, 0xf3, 0x0e, 0x31, 0x2f, 0x90, 0x69, 0x2e, - 0xed, 0xbe, 0xdb, 0xc5, 0xa8, 0xbe, 0x03, 0x19, - 0x6b, 0xcd, 0x1b, 0xae, 0x05, 0xa0, 0x84, 0xb7, - 0xef, 0xc0, 0xdb, 0x77, 0xe0, 0x31, 0x38, 0xb3, - 0x25, 0x5e, 0x23, 0x05, 0x11, 0xf5, 0xca, 0xe3, - 0x04, 0xb6, 0x03, 0x85, 0xff, 0xe0, 0xdc, 0x5a, - 0xcc, 0xe3, 0xcc, 0xda, 0x71, 0xa7, 0x88, 0x71, - 0x69, 0x23, 0x1a, 0x88, 0xa7, 0xb4, 0xd8, 0xfe, - 0x85, 0xe2, 0x0c, 0xca, 0x20, 0x83, 0xd1, 0xb9, - 0x7d, 0x36, 0x6e, 0x32, 0x3d, 0xe0, 0x51, 0x91, - 0x66, 0xf6, 0x2e, 0x82, 0x07, 0x6b, 0x2f, 0xd6, - 0xb6, 0x71, 0xdc, 0x3a, 0xca, 0x96, 0x57, 0x2f, - 0x82, 0x1b, 0x73, 0x96, 0xec, 0xac, 0xc6, 0x42, - 0x7c, 0x27, 0xa6, 0xf6, 0x43, 0x19, 0xd3, 0x43, - 0x52, 0x55, 0xd5, 0xca, 0x0e, 0x62, 0xab, 0xc4, - 0xca, 0x35, 0x25, 0x36, 0x0a, 0x75, 0x74, 0xc4, - 0x5f, 0x2a, 0x97, 0xdd, 0x98, 0x64, 0x55, 0xdf, - 0xcc, 0x12, 0x42, 0xda, 0x84, 0x8d, 0x5b, 0x3e, - 0x6b, 0xdb, 0x35, 0x79, 0xeb, 0x98, 0xdd, 0xf2, - 0xb0, 0x54, 0x6b, 0xf9, 0xdf, 0x2e, 0x7f, 0x0d, - 0xf3, 0x22, 0x5a, 0x7a, 0xb4, 0x12, 0x64, 0xfc, - 0xf7, 0x2a, 0xe3, 0xc2, 0x10, 0x67, 0x14, 0x8b, - 0x8e, 0xce, 0x8f, 0xac, 0xed, 0x88, 0xb1, 0x5e, - 0x86, 0x3d, 0xe8, 0xff, 0x06, 0x69, 0xd1, 0xd1, - 0xf3, 0xd4, 0x33, 0x53, 0xd6, 0xb5, 0x15, 0xbb, - 0x33, 0x10, 0x82, 0x4e, 0xb6, 0x66, 0x42, 0x41, - 0x83, 0x9e, 0x43, 0x34, 0x07, 0xa0, 0x28, 0x6e, - 0xcb, 0xfc, 0xa7, 0x7b, 0x87, 0x21, 0xa7, 0x14, - 0x47, 0x7f, 0xdc, 0x20, 0xa9, 0x56, 0x83, 0xe8, - 0xae, 0xab, 0xe0, 0xd0, 0x1c, 0x51, 0x5f, 0x35, - 0xe1, 0x99, 0x83, 0x73, 0xf8, 0xcc, 0xe3, 0xdf, - 0xac, 0x78, 0xc9, 0xc1, 0x85, 0x14, 0x13, 0xfb, - 0xf2, 0xe5, 0x85, 0x13, 0xc6, 0x58, 0x13, 0x0b, - 0x58, 0xf7, 0x8a, 0x75, 0x41, 0x38, 0xc6, 0x57, - 0x2d, 0x42, 0xfc, 0x96, 0x03, 0x95, 0x81, 0xe8, - 0xf5, 0x41, 0x6f, 0xf4, 0x59, 0x77, 0x90, 0x95, - 0x63, 0xe4, 0x4a, 0xad, 0x0d, 0x3e, 0x3d, 0x16, - 0x80, 0x40, 0x86, 0x44, 0x46, 0x23, 0xc9, 0xab, - 0xb4, 0xb2, 0x37, 0x13, 0x8d, 0x3c, 0xdc, 0x4a, - 0xa5, 0xad, 0x3c, 0x05, 0xa1, 0x62, 0x91, 0x66, - 0x0d, 0x2f, 0x35, 0x23, 0xa9, 0x02, 0x8b, 0xbd, - 0x69, 0x18, 0x1c, 0x5f, 0xaa, 0x69, 0xb5, 0x87, - 0xd0, 0x6d, 0x13, 0x3c, 0xa7, 0x96, 0x4d, 0xee, - 0x49, 0xdd, 0x73, 0xf9, 0x79, 0x92, 0x16, 0xbf, - 0xe4, 0x84, 0x52, 0x6d, 0xfc, 0xa7, 0xe5, 0x71, - 0x7b, 0x4d, 0x12, 0x52, 0x1d, 0x11, 0x9b, 0xc9, - 0x70, 0x9c, 0x53, 0x36, 0xeb, 0x32, 0xa8, 0xca, - 0xc6, 0x5a, 0x32, 0x3b, 0x29, 0xf5, 0xa0, 0x7c, - 0x31, 0xce, 0xd7, 0x69, 0x1c, 0x53, 0x8c, 0xff, - 0x64, 0x15, 0x66, 0x78, 0x57, 0x05, 0xa5, 0xa7, - 0x09, 0xfb, 0x4b, 0x80, 0x10, 0x62, 0xa0, 0x98, - 0x8e, 0x65, 0x7b, 0x39, 0x82, 0x93, 0x89, 0x99, - 0x57, 0xa7, 0x65, 0x92, 0x80, 0x87, 0x37, 0x62, - 0xd5, 0x75, 0x4d, 0x39, 0x24, 0x53, 0x64, 0xe1, - 0x19, 0x00, 0xc8, 0x49, 0x07, 0x44, 0x96, 0x19, - 0x80, 0x24, 0xe8, 0x65, 0xfd, 0x59, 0x14, 0xc6, - 0x81, 0xf0, 0xd3, 0x73, 0x96, 0xba, 0xc9, 0xb7, - 0x19, 0x06, 0xfb, 0xd8, 0x0a, 0x85, 0x03, 0x94, - 0x15, 0xa3, 0x38, 0xcc, 0x35, 0xbc, 0x43, 0x23, - 0xbc, 0x6f, 0x67, 0xfd, 0x30, 0x9c, 0xaf, 0xde, - 0xfb, 0xe5, 0x59, 0x02, 0xc3, 0x25, 0x5e, 0x2e, - 0xf8, 0xbb, 0x65, 0x2a, 0x0d, 0xdf, 0x21, 0x5a, - 0x61, 0xc6, 0x43, 0xbf, 0x1a, 0xde, 0x23, 0xc9, - 0xc5, 0x7e, 0xc7, 0xac, 0xe7, 0x83, 0x09, 0xce, - 0x36, 0x0d, 0xc6, 0xab, 0x05, 0xfa, 0x8e, 0x60, - 0x0d, 0x8d, 0xa4, 0xf3, 0x13, 0xf5, 0xaa, 0xd1, - 0xef, 0x01, 0x81, 0xc0, 0x90, 0x63, 0xcf, 0x0f, - 0xe3, 0x36, 0xbe, 0x2f, 0x27, 0x50, 0xcf, 0x22, - 0x4c, 0x01, 0x81, 0x37, 0x80, 0xff, 0xc6, 0x97, - 0x50, 0x93, 0xd4, 0x06, 0x4e, 0x70, 0xd1, 0x2d, - 0x97, 0x2f, 0xd2, 0x0d, 0xa0, 0xaf, 0x03, 0x0a, - 0xf4, 0xec, 0xfc, 0x07, 0xcb, 0x40, 0x8e, 0xeb, - 0xb5, 0x8e, 0xbb, 0x98, 0xbe, 0x99, 0x99, 0x19, - 0x04, 0x2c, 0x3f, 0x23, 0x43, 0x56, 0x93, 0x5b, - 0x01, 0xad, 0xb4, 0x3c, 0xa0, 0x32, 0xc0, 0xb3, - 0x40, 0x8d, 0x0d, 0x0e, 0x8b, 0x19, 0x28, 0x3d, - 0x28, 0xdc, 0xa5, 0xeb, 0xa2, 0x1e, 0x89, 0xbd, - 0x13, 0x31, 0x18, 0xa9, 0x7e, 0xde, 0xff, 0x71, - 0x59, 0x5b, 0xf9, 0x85, 0x52, 0xe9, 0x1b, 0x05, - 0xc0, 0xfa, 0xe7, 0x5a, 0xf6, 0xde, 0x71, 0xca, - 0x0f, 0xe0, 0x94, 0xec, 0xd8, 0xbe, 0x75, 0x5e, - 0x59, 0x99, 0x99, 0x15, 0x1b, 0x22, 0x26, 0x52, - 0x41, 0x43, 0xf1, 0x69, 0x7c, 0xcc, 0xca, 0x62, - 0xe0, 0x5a, 0x3a, 0xf2, 0x18, 0x45, 0x57, 0x56, - 0xce, 0x97, 0xde, 0xdb, 0x50, 0x64, 0x78, 0x05, - 0x13, 0x6d, 0x7c, 0x68, 0xf0, 0xef, 0x93, 0xc5, - 0x5f, 0x68, 0xb7, 0xd6, 0x55, 0x19, 0x72, 0x09, - 0x8f, 0x3b, 0xe2, 0xd0, 0xfc, 0x4e, 0x9b, 0xb5, - 0x3c, 0x3f, 0xef, 0x68, 0x34, 0x07, 0x17, 0x5d, - 0x9a, 0x88, 0x5f, 0xd1, 0xca, 0x91, 0x3c, 0x2c, - 0x64, 0x7c, 0x8e, 0x89, 0x42, 0xc8, 0xc9, 0xec, - 0xe2, 0xa7, 0xa0, 0x40, 0x68, 0x2d, 0xba, 0xd6, - 0xea, 0x85, 0xb6, 0xa1, 0xf0, 0x77, 0xd0, 0x76, - 0x71, 0x75, 0x41, 0xf4, 0x83, 0xc6, 0x38, 0x0d, - 0xd2, 0xf6, 0x23, 0x15, 0xef, 0x8a, 0xe6, 0x6d, - 0xcf, 0x97, 0x3b, 0x3b, 0xc7, 0x6e, 0x5b, 0x39, - 0x87, 0x27, 0x57, 0x0b, 0x27, 0xb9, 0x6c, 0x4a, - 0x2d, 0xb9, 0x59, 0x0b, 0xbf, 0x48, 0xb8, 0x14, - 0x06, 0xa3, 0xf0, 0xb8, 0x39, 0xa6, 0x73, 0x63, - 0x3c, 0xe7, 0x03, 0xce, 0x4a, 0x47, 0x02, 0xbf, - 0xfb, 0x93, 0x72, 0xfa, 0x51, 0x8f, 0xc8, 0xa9, - 0x3e, 0x1b, 0xc7, 0x4e, 0x07, 0xae, 0xb3, 0x93, - 0x97, 0xbf, 0xec, 0xf2, 0x2c, 0xad, 0x4b, 0x77, - 0x1b, 0x37, 0xa9, 0xd1, 0x92, 0x49, 0xe5, 0xad, - 0x82, 0xb7, 0x81, 0x94, 0xdc, 0xc3, 0xa3, 0x23, - 0xd2, 0xbb, 0x6b, 0x91, 0xda, 0xaf, 0x25, 0x54, - 0x03, 0x4a, 0x6f, 0x76, 0xbd, 0xef, 0x9b, 0xba, - 0xb7, 0x15, 0x7f, 0xb9, 0x69, 0x70, 0x1f, 0x91, - 0x31, 0x92, 0x79, 0x45, 0x83, 0x0b, 0xd3, 0x19, - 0x7f, 0x83, 0x5f, 0xb6, 0xef, 0xc6, 0xea, 0xd2, - 0x4a, 0xf7, 0xcb, 0xdd, 0x6c, 0xe1, 0xec, 0x94, - 0x0e, 0xf8, 0xf7, 0x1f, 0xef, 0x26, 0x6d, 0x5d, - 0x5c, 0xd1, 0xd6, 0xd7, 0x66, 0xaf, 0x83, 0xf9, - 0xa7, 0x78, 0xd3, 0xe9, 0xbe, 0x5d, 0xd4, 0xa9, - 0x37, 0xb9, 0xdd, 0xc3, 0xdb, 0x13, 0x77, 0x7e, - 0x75, 0xe0, 0x3a, 0x5b, 0xe1, 0x63, 0xc5, 0xe7, - 0xdd, 0x78, 0x5c, 0xdb, 0x5d, 0xc7, 0x54, 0x5d, - 0x27, 0x80, 0xa9, 0xcd, 0xe8, 0x75, 0x93, 0x97, - 0x41, 0xaf, 0xc6, 0x95, 0xea, 0x8d, 0xa4, 0xf5, - 0x66, 0xc2, 0xa6, 0xd5, 0x5c, 0x17, 0x71, 0x94, - 0xb4, 0xde, 0x93, 0x73, 0x9a, 0xb4, 0x30, 0x34, - 0xa7, 0x5d, 0x2d, 0x63, 0x2b, 0xb5, 0x68, 0x21, - 0xc5, 0x4a, 0xcb, 0xcf, 0x93, 0xd1, 0xb9, 0xb3, - 0x4f, 0xec, 0xc6, 0x7e, 0x52, 0xcb, 0xf8, 0x9c, - 0x16, 0xbd, 0xea, 0xfa, 0x34, 0x31, 0xc2, 0x0a, - 0xe4, 0xa6, 0x49, 0xfe, 0xa4, 0x19, 0xa3, 0x36, - 0xcb, 0x43, 0xcb, 0x4e, 0x49, 0x1f, 0xdc, 0x2f, - 0xe9, 0x77, 0x8f, 0x58, 0xb6, 0xde, 0x17, 0xec, - 0xe7, 0xd4, 0x1b, 0xa8, 0x99, 0xb9, 0xba, 0xeb, - 0xf5, 0x11, 0x28, 0xfc, 0xe6, 0x48, 0x74, 0x3b, - 0x57, 0x42, 0x03, 0x07, 0xad, 0x90, 0xed, 0x87, - 0xd0, 0xd9, 0x0d, 0x72, 0x68, 0x23, 0x38, 0xdb, - 0x32, 0x3f, 0x52, 0x43, 0xdf, 0xb0, 0xdf, 0x34, - 0x03, 0x15, 0xfd, 0xc2, 0x91, 0x97, 0x95, 0xe6, - 0xc6, 0x6e, 0x9c, 0x72, 0x24, 0x23, 0x29, 0x43, - 0x08, 0xb4, 0xde, 0xf9, 0xe1, 0x0e, 0x78, 0x4f, - 0x74, 0x18, 0x9a, 0x3e, 0x18, 0x3e, 0x82, 0x9f, - 0x6c, 0x97, 0xb0, 0xa5, 0x2d, 0xbd, 0xc6, 0x95, - 0xce, 0xc7, 0x4f, 0xf6, 0x68, 0xb9, 0xf7, 0xac, - 0x7a, 0x97, 0xf8, 0xc6, 0xc2, 0xe2, 0xa6, 0x0e, - 0xae, 0x7b, 0x9f, 0x3d, 0xe7, 0xc6, 0x92, 0xe4, - 0x5c, 0x67, 0x17, 0xdf, 0xb9, 0xce, 0x72, 0xed, - 0x93, 0x6c, 0x97, 0xef, 0xe7, 0x76, 0xf3, 0xfd, - 0x60, 0xa4, 0x70, 0x94, 0x04, 0xd6, 0xdd, 0xc1, - 0x54, 0x1d, 0xe4, 0xec, 0x5e, 0xa0, 0x33, 0xdc, - 0x64, 0xe7, 0xc4, 0x08, 0xb1, 0x3b, 0x12, 0x31, - 0xae, 0x9e, 0x90, 0xa8, 0x24, 0x70, 0xec, 0x52, - 0xc1, 0x7d, 0xb4, 0x54, 0x70, 0x3b, 0x29, 0x62, - 0x27, 0x45, 0xec, 0xd2, 0xe7, 0xdd, 0x8d, 0x00, - 0xb0, 0x3b, 0xec, 0x77, 0x87, 0xfd, 0xcd, 0x27, - 0xf7, 0xbb, 0xdb, 0x33, 0xf4, 0x00, 0x1e, 0x53, - 0x88, 0x43, 0x29, 0x27, 0xac, 0x62, 0xff, 0xfa, - 0x3d, 0x9d, 0x45, 0xb5, 0xf4, 0x4a, 0xaf, 0x2f, - 0xbf, 0xce, 0xe5, 0x3c, 0x45, 0x73, 0x6d, 0x02, - 0x90, 0xbc, 0x78, 0x12, 0x96, 0x2c, 0xc6, 0x87, - 0xb0, 0xc1, 0x94, 0x43, 0xad, 0xe9, 0xde, 0xbc, - 0x57, 0xbf, 0x77, 0x3c, 0x7a, 0xd3, 0x92, 0x97, - 0x0e, 0xde, 0xd6, 0xe7, 0xa5, 0xa3, 0x17, 0x6d, - 0x17, 0xee, 0x65, 0x83, 0x56, 0x1b, 0xd9, 0xa2, - 0xe5, 0x2e, 0xe1, 0xa2, 0xe6, 0x2e, 0xa1, 0x8d, - 0xda, 0xa2, 0x74, 0x95, 0xd0, 0xfa, 0x78, 0x51, - 0x1b, 0xef, 0xee, 0xa0, 0xb7, 0x28, 0x47, 0x80, - 0xdf, 0x6f, 0x6f, 0xe1, 0xd6, 0xa7, 0x3f, 0x2d, - 0x34, 0x25, 0xef, 0x82, 0x5f, 0xea, 0x93, 0x77, - 0xc1, 0x8b, 0x9e, 0x5e, 0xf8, 0xc6, 0xe4, 0x5d, - 0xf2, 0xf3, 0xd2, 0x3a, 0xb6, 0xf4, 0xbc, 0xb0, - 0xa2, 0xee, 0x9b, 0x2f, 0xb7, 0x2d, 0xf4, 0xe5, - 0xb6, 0x45, 0xdd, 0xe5, 0xb6, 0xca, 0x22, 0x12, - 0x0e, 0x8b, 0xed, 0xef, 0xb6, 0xdd, 0x89, 0x1f, - 0x52, 0xb1, 0xb3, 0x03, 0xc1, 0x3b, 0x92, 0xa2, - 0x70, 0xf4, 0xe6, 0x04, 0x35, 0xe2, 0x9d, 0xe4, - 0x62, 0x72, 0x16, 0xf1, 0x62, 0x36, 0xe9, 0x0c, - 0xf8, 0xb7, 0x0a, 0x5a, 0x53, 0xc3, 0xd3, 0x2f, - 0xf9, 0x89, 0x7b, 0xbb, 0x5a, 0xe5, 0x18, 0x67, - 0xe0, 0x98, 0x01, 0x64, 0x7c, 0xc5, 0xa0, 0xae, - 0x82, 0x82, 0x3d, 0x86, 0xe2, 0x2b, 0xd5, 0xe3, - 0x73, 0xc1, 0x14, 0x30, 0xea, 0xda, 0x11, 0x2f, - 0xa8, 0x2f, 0x9d, 0xc1, 0x06, 0xc3, 0xdb, 0x96, - 0xa4, 0x5c, 0x75, 0x30, 0x6d, 0x7f, 0xe0, 0x65, - 0x6f, 0xf7, 0xfd, 0x8c, 0xbe, 0x8b, 0xf8, 0x4e, - 0x50, 0xbe, 0xce, 0x66, 0x1e, 0xbc, 0xa7, 0x29, - 0xf9, 0xaa, 0x5b, 0xbe, 0x09, 0x7e, 0x26, 0x8b, - 0x92, 0x98, 0xd2, 0x17, 0xc3, 0xc1, 0x78, 0x34, - 0x76, 0xab, 0x58, 0x0c, 0x07, 0x4f, 0x46, 0x47, - 0x63, 0xfd, 0xc8, 0xa7, 0x47, 0xc3, 0x27, 0xe3, - 0xb1, 0x96, 0x0d, 0x1b, 0x62, 0x5c, 0xca, 0x11, - 0x6a, 0x98, 0xe8, 0x3f, 0x08, 0x64, 0xc8, 0x99, - 0xf0, 0x96, 0x3e, 0x5e, 0x30, 0x11, 0x92, 0xbd, - 0xce, 0x31, 0xec, 0x2a, 0x49, 0x4d, 0x9c, 0x15, - 0x97, 0x1e, 0x28, 0xd2, 0x82, 0x6e, 0xac, 0xfa, - 0x31, 0x90, 0x85, 0x39, 0x98, 0xe4, 0xc7, 0xb1, - 0x5c, 0x15, 0xd5, 0xf1, 0x01, 0x75, 0xaa, 0xff, - 0x6b, 0x0e, 0x4a, 0xc6, 0x10, 0xe3, 0xd5, 0xac, - 0x0f, 0x0d, 0x5a, 0x5f, 0xab, 0x94, 0xf8, 0xd0, - 0x30, 0xef, 0xc0, 0xc4, 0x15, 0x5e, 0xb7, 0x27, - 0x36, 0x54, 0x81, 0x80, 0xfe, 0x52, 0xf3, 0xe9, - 0x51, 0x79, 0x1a, 0x55, 0x80, 0x40, 0xcd, 0xae, - 0xa4, 0x2b, 0x8f, 0xd4, 0xdd, 0xd9, 0x6c, 0x0d, - 0x64, 0xc4, 0x98, 0x65, 0xde, 0x85, 0xa3, 0xd3, - 0x66, 0x18, 0x8d, 0x95, 0x26, 0x44, 0x83, 0x1c, - 0x9f, 0x88, 0xb7, 0x4c, 0xe4, 0xe7, 0x78, 0xfb, - 0xf5, 0xe0, 0xe9, 0x21, 0x4e, 0x9a, 0x39, 0x93, - 0xba, 0x0d, 0xd3, 0x48, 0xd7, 0x7d, 0x6d, 0x80, - 0xf2, 0x22, 0x9e, 0x9d, 0x7b, 0x07, 0x2f, 0x45, - 0x86, 0x56, 0xe5, 0x1d, 0x55, 0xce, 0x80, 0x60, - 0xef, 0xe3, 0x3d, 0x42, 0xba, 0x2e, 0x96, 0x8b, - 0xc4, 0xcb, 0x32, 0x94, 0x8e, 0xf5, 0xa5, 0x3a, - 0xbc, 0x3e, 0xc3, 0x95, 0x05, 0x78, 0x1c, 0xfa, - 0xf4, 0xd3, 0x97, 0x14, 0x61, 0xa8, 0xdc, 0x0a, - 0xdf, 0x87, 0x99, 0x24, 0x3b, 0xf8, 0xc0, 0xa1, - 0x38, 0x8e, 0x6e, 0x74, 0xc7, 0x8d, 0xc2, 0x41, - 0x87, 0x95, 0xf4, 0xf2, 0xd9, 0xda, 0xa5, 0x42, - 0x15, 0xea, 0xad, 0x45, 0xa1, 0x8f, 0xea, 0x9a, - 0xe2, 0x94, 0xf4, 0x6c, 0xe0, 0x25, 0x3a, 0x9b, - 0x63, 0xdc, 0x0e, 0x52, 0x98, 0x17, 0xa7, 0x30, - 0xce, 0x77, 0xc2, 0x3b, 0x8f, 0xb8, 0xcc, 0x01, - 0x06, 0x88, 0x49, 0x3c, 0x73, 0x1d, 0x6f, 0x25, - 0x37, 0xed, 0x85, 0xf8, 0x02, 0x03, 0xcc, 0x86, - 0x76, 0xbc, 0x95, 0x3d, 0x80, 0x3d, 0xb5, 0x72, - 0x9d, 0x02, 0xd0, 0x22, 0x16, 0x41, 0xb7, 0xbd, - 0x36, 0x9d, 0x85, 0xba, 0xbb, 0x37, 0x3a, 0x1a, - 0xaa, 0xe8, 0xae, 0x1e, 0x0d, 0x17, 0x76, 0x10, - 0xfe, 0xf9, 0xec, 0x69, 0x4f, 0x34, 0x0e, 0xdc, - 0xd0, 0xaa, 0x49, 0xc7, 0xf4, 0x22, 0xc7, 0x92, - 0x46, 0x68, 0x47, 0xf1, 0x62, 0x49, 0xc2, 0x3a, - 0xb7, 0x98, 0x9a, 0xe7, 0x47, 0xee, 0x46, 0x12, - 0x92, 0x5d, 0xba, 0x74, 0x68, 0x0d, 0x80, 0xab, - 0x22, 0x59, 0x6d, 0x6b, 0x16, 0xdd, 0x4f, 0xd7, - 0x58, 0x0d, 0x84, 0x2f, 0x95, 0xf3, 0x05, 0xd0, - 0xc5, 0x9a, 0x28, 0x29, 0xd6, 0xa7, 0x06, 0x7c, - 0xa1, 0xee, 0x7e, 0x5a, 0x94, 0x44, 0x43, 0x0a, - 0x4c, 0xf2, 0x35, 0xac, 0xd0, 0x13, 0x87, 0x78, - 0xfb, 0x14, 0xce, 0x55, 0xd1, 0x49, 0x57, 0x74, - 0x1b, 0x10, 0xa6, 0x8c, 0x47, 0x23, 0x83, 0x25, - 0xcb, 0xd8, 0x48, 0x8e, 0x32, 0xa0, 0x1d, 0xcb, - 0xb3, 0x6d, 0x38, 0x94, 0xb3, 0x18, 0x8e, 0x74, - 0x37, 0xc8, 0xd4, 0x74, 0xd3, 0xec, 0x1f, 0x94, - 0x66, 0x5b, 0xb6, 0x71, 0xe6, 0x5a, 0xf5, 0x34, - 0x2f, 0xf7, 0x34, 0x6f, 0xef, 0x69, 0xbe, 0x45, - 0x4f, 0xf3, 0xda, 0x9e, 0xfc, 0x72, 0x4f, 0x7e, - 0x7b, 0x4f, 0xfe, 0x16, 0x3d, 0xf9, 0xba, 0x27, - 0xcc, 0x1b, 0x51, 0x2f, 0x6a, 0xb6, 0x08, 0x20, - 0xb7, 0x2d, 0x30, 0xde, 0x90, 0xcc, 0x77, 0xeb, - 0xe1, 0x38, 0xdb, 0xaa, 0xa1, 0x5a, 0x6a, 0xdb, - 0x5e, 0x02, 0x6b, 0x15, 0xc0, 0xae, 0x26, 0x46, - 0x7d, 0x68, 0xdc, 0x4e, 0xad, 0x72, 0x65, 0x93, - 0xc9, 0xce, 0xae, 0x79, 0x35, 0xbb, 0x66, 0xb9, - 0x95, 0x14, 0x95, 0x75, 0x34, 0xf5, 0xbd, 0xd6, - 0x46, 0xaf, 0xe2, 0x05, 0x42, 0x76, 0xa2, 0xa4, - 0xb5, 0x6a, 0xcc, 0xb7, 0xc5, 0xc3, 0x76, 0x9a, - 0xed, 0xf5, 0xb9, 0xdc, 0x4e, 0x77, 0xac, 0x5c, - 0xf5, 0xbe, 0x44, 0x77, 0xb3, 0xa2, 0xd2, 0x83, - 0x79, 0x68, 0xdd, 0x20, 0xb2, 0x5b, 0x6e, 0x6e, - 0x5b, 0xc7, 0x33, 0x2d, 0xde, 0xa1, 0xbd, 0xac, - 0x5e, 0x8f, 0xbb, 0x8a, 0x2a, 0xf8, 0xce, 0x36, - 0xbf, 0x1b, 0xb3, 0xa4, 0xea, 0x17, 0xb3, 0x57, - 0xa0, 0x28, 0xf0, 0x97, 0xbf, 0x08, 0x2d, 0xb9, - 0x9e, 0x90, 0xe4, 0x6a, 0x3d, 0x7a, 0x47, 0xad, - 0x58, 0xab, 0xd0, 0xd2, 0xec, 0x57, 0x32, 0x7f, - 0x02, 0xe6, 0x07, 0xd1, 0x97, 0x5a, 0x8a, 0xd4, - 0x64, 0xc9, 0x7d, 0xce, 0x17, 0x92, 0xed, 0xd9, - 0x04, 0x74, 0x48, 0x30, 0x71, 0x78, 0x1b, 0xdf, - 0xa4, 0x31, 0x30, 0x50, 0xae, 0xfe, 0xd8, 0xee, - 0x82, 0xfb, 0xe0, 0x2c, 0x70, 0x02, 0x0e, 0xb4, - 0x7a, 0xdb, 0xa6, 0x1e, 0x5f, 0x51, 0x47, 0x3c, - 0x68, 0xd3, 0x11, 0xaf, 0xa5, 0x71, 0xf1, 0xed, - 0xb8, 0xab, 0x28, 0x59, 0xf7, 0x51, 0x65, 0x32, - 0xb3, 0x3d, 0xc8, 0xe6, 0x96, 0xa0, 0xdd, 0x2c, - 0x5e, 0x73, 0x67, 0x94, 0xb7, 0x75, 0x48, 0x23, - 0x95, 0xbf, 0x1e, 0x74, 0xeb, 0x04, 0x6d, 0xf5, - 0x7e, 0xa4, 0xea, 0x97, 0xfe, 0x31, 0xa3, 0x41, - 0x5c, 0x39, 0xe0, 0x73, 0x50, 0x2d, 0xee, 0xb7, - 0xe4, 0xbf, 0x73, 0x61, 0xdd, 0x81, 0x0b, 0x4b, - 0x96, 0x72, 0x3d, 0x97, 0x15, 0x55, 0x5b, 0xbd, - 0x58, 0x8d, 0x5e, 0x2f, 0xf5, 0xf1, 0x9e, 0xbb, - 0x43, 0x76, 0x49, 0x5c, 0x3e, 0x20, 0x89, 0xcb, - 0x75, 0x93, 0xb4, 0x94, 0xa6, 0xb5, 0x31, 0x53, - 0xcb, 0x8d, 0x67, 0x55, 0x69, 0xba, 0xe1, 0xb6, - 0x65, 0x4a, 0x02, 0x89, 0x68, 0x63, 0x70, 0xcc, - 0x07, 0xdf, 0xf2, 0x73, 0x02, 0x21, 0x9d, 0xfe, - 0x60, 0x47, 0x3d, 0x1d, 0x3d, 0x1b, 0x9b, 0xd0, - 0x47, 0xbc, 0x30, 0x3f, 0x3e, 0x6a, 0xab, 0x43, - 0x5a, 0x2a, 0x42, 0xcf, 0x0c, 0xab, 0x65, 0x55, - 0xeb, 0xc6, 0x53, 0xa2, 0xe2, 0x20, 0x5a, 0xe2, - 0x11, 0x9f, 0x26, 0x55, 0x1a, 0xc0, 0x8b, 0xf3, - 0x35, 0x07, 0x9d, 0x77, 0xce, 0x2f, 0x64, 0x19, - 0x6a, 0x90, 0xf7, 0x5e, 0xc6, 0xe1, 0x19, 0xc5, - 0x94, 0x75, 0x64, 0xe1, 0x0b, 0xaa, 0x89, 0x2b, - 0x19, 0x76, 0xe4, 0xe5, 0x6a, 0xde, 0xd0, 0xf6, - 0x9f, 0x62, 0xa6, 0xf8, 0x42, 0x55, 0xe2, 0x16, - 0xa1, 0xfa, 0x94, 0xcd, 0xe6, 0x74, 0x31, 0x1e, - 0xf3, 0xec, 0xe5, 0x86, 0x4d, 0xc8, 0x74, 0xef, - 0x35, 0x24, 0xc5, 0x0c, 0x93, 0x4b, 0x7f, 0x63, - 0x92, 0x36, 0xbb, 0x02, 0x2c, 0xa5, 0x05, 0xce, - 0x60, 0x4e, 0xe9, 0x97, 0xb9, 0x55, 0x49, 0x96, - 0x1e, 0xf8, 0xfa, 0x81, 0xfc, 0x17, 0x17, 0xe1, - 0x10, 0x81, 0xbc, 0x6f, 0xac, 0x57, 0x18, 0xae, - 0xf2, 0x28, 0xa6, 0x25, 0xe7, 0x34, 0x9a, 0xce, - 0xe4, 0xa9, 0x01, 0xfe, 0xbe, 0xc6, 0x02, 0xbf, - 0x81, 0xac, 0x9e, 0xac, 0xd3, 0xda, 0x3d, 0xea, - 0x9b, 0xff, 0x3d, 0x52, 0x0f, 0xff, 0x0f, 0xfe, - 0xd1, 0x3f, 0xe6, 0xa1, 0x07, 0x3f, 0x3e, 0xfc, - 0x4c, 0xed, 0x87, 0x35, 0x2d, 0xaf, 0x02, 0x33, - 0x80, 0x9f, 0x10, 0x7e, 0x66, 0x37, 0x08, 0x73, - 0x0e, 0x3f, 0x0b, 0xf8, 0x89, 0xae, 0x04, 0xd3, - 0x0e, 0x22, 0x64, 0x75, 0xc1, 0x22, 0x9f, 0x09, - 0x57, 0xe8, 0x25, 0x8d, 0xa8, 0x2f, 0xe7, 0x1b, - 0xb5, 0x3e, 0xfd, 0xfb, 0x05, 0x8b, 0xdf, 0x8e, - 0x14, 0xef, 0xb7, 0x82, 0x19, 0x5e, 0xf2, 0xf5, - 0xb4, 0xf5, 0xeb, 0x6d, 0x71, 0x08, 0xb6, 0x1e, - 0xca, 0xb0, 0xe6, 0xeb, 0xb0, 0xf6, 0xeb, 0x6a, - 0xbb, 0xd9, 0xb6, 0xb8, 0xd6, 0x75, 0x32, 0xdf, - 0x1a, 0xc5, 0xb6, 0x81, 0x2e, 0x2e, 0x9b, 0xec, - 0xb6, 0x8f, 0xa3, 0x6d, 0xf1, 0xaf, 0x02, 0x51, - 0xc4, 0x44, 0x5e, 0x42, 0xcc, 0x9a, 0x19, 0x9d, - 0x45, 0x32, 0x45, 0xea, 0x39, 0x39, 0x59, 0x2e, - 0x44, 0x1e, 0xa7, 0xab, 0x90, 0x32, 0x15, 0x3e, - 0x45, 0x8d, 0x07, 0x37, 0x20, 0x65, 0xa0, 0xd3, - 0x3e, 0x17, 0xfa, 0xd6, 0x3c, 0x07, 0x7e, 0xfc, - 0xd6, 0x93, 0xec, 0x66, 0x9f, 0x1e, 0x77, 0x45, - 0x64, 0xb6, 0x2c, 0x66, 0xa8, 0x58, 0x2f, 0x67, - 0xf0, 0x0d, 0xa7, 0xf9, 0xb4, 0x2a, 0xa0, 0xef, - 0x8b, 0x8e, 0xac, 0x29, 0x8d, 0x05, 0xc4, 0x51, - 0x2f, 0x85, 0x0e, 0x65, 0x7e, 0x5f, 0x6c, 0x88, - 0xa9, 0x46, 0xba, 0xa6, 0x5b, 0xcc, 0x74, 0x89, - 0x39, 0x81, 0x7f, 0x5f, 0x47, 0xc0, 0xe5, 0x42, - 0xca, 0xb1, 0xf9, 0x9c, 0x90, 0x3c, 0x1c, 0x0e, - 0x9f, 0x1c, 0x0d, 0x47, 0x8f, 0x07, 0x8f, 0x9f, - 0x1e, 0x1d, 0x3d, 0x79, 0x7a, 0x84, 0x90, 0x8f, - 0x46, 0x63, 0xa9, 0xb0, 0x91, 0x08, 0x84, 0xcc, - 0xb6, 0x5b, 0x02, 0x86, 0xe9, 0x48, 0x7d, 0x2c, - 0x91, 0x83, 0x69, 0x20, 0x03, 0x82, 0x26, 0xdb, - 0x8f, 0x9e, 0xc1, 0x11, 0xf2, 0x78, 0xf4, 0xec, - 0x19, 0x00, 0x1b, 0x3f, 0x21, 0x8d, 0x8a, 0x00, - 0x98, 0x0c, 0x9e, 0x3a, 0xc9, 0x27, 0x67, 0x25, - 0x21, 0x7f, 0x6f, 0x78, 0xee, 0xcd, 0xe7, 0x61, - 0x86, 0x2e, 0x59, 0x1c, 0xe4, 0x22, 0x8a, 0x63, - 0xe5, 0x66, 0x2a, 0x16, 0x58, 0xf3, 0xa3, 0x07, - 0xdd, 0x4d, 0x3d, 0x74, 0x71, 0xa5, 0x58, 0x29, - 0x7e, 0x13, 0x39, 0x89, 0x5d, 0x31, 0x39, 0x82, - 0x97, 0x61, 0xd2, 0xd1, 0x24, 0xc5, 0x44, 0x27, - 0x9e, 0x0f, 0x13, 0x02, 0xcb, 0x0d, 0x02, 0x37, - 0xa5, 0xb1, 0xcc, 0x07, 0xd8, 0x5f, 0x90, 0x52, - 0x6a, 0x64, 0x4a, 0x34, 0xaa, 0x93, 0x4b, 0x52, - 0xb2, 0x64, 0x1f, 0x33, 0x9b, 0x2e, 0x35, 0x44, - 0x27, 0xdd, 0xa5, 0x1c, 0x57, 0x87, 0xc7, 0x41, - 0x03, 0x92, 0x27, 0x10, 0x85, 0x0a, 0x77, 0xe5, - 0xaa, 0x92, 0xcf, 0x18, 0x66, 0xc5, 0xcb, 0xfc, - 0xa8, 0xc8, 0xd0, 0xfd, 0x45, 0xe7, 0x89, 0x02, - 0xf9, 0x9f, 0x92, 0x6a, 0x70, 0x04, 0xde, 0x09, - 0x68, 0x9c, 0x72, 0x22, 0x61, 0x39, 0xdf, 0xe6, - 0x18, 0x29, 0xad, 0x9c, 0x63, 0xe1, 0x39, 0x16, - 0x61, 0xa7, 0xc3, 0xd6, 0x0f, 0x01, 0xff, 0x81, - 0xc8, 0xc3, 0x50, 0x28, 0x30, 0x49, 0x34, 0x7d, - 0x1b, 0x05, 0xf1, 0x7a, 0xee, 0xe5, 0x8b, 0x87, - 0xd0, 0xdf, 0x26, 0x44, 0xbc, 0x85, 0x9f, 0x85, - 0xde, 0xdb, 0x20, 0xdd, 0x70, 0x0d, 0x7b, 0xaa, - 0x56, 0x1f, 0x25, 0xb3, 0x54, 0x93, 0x6c, 0x51, - 0xac, 0xf2, 0xe7, 0xfb, 0xfb, 0xf3, 0xa8, 0x58, - 0xac, 0xfd, 0xc1, 0x34, 0x5d, 0xee, 0x2f, 0xbd, - 0x95, 0x9f, 0x9e, 0xcb, 0x7f, 0xfa, 0xf3, 0xb8, - 0xff, 0x6f, 0xa0, 0xc0, 0x75, 0x1c, 0xef, 0x1f, - 0x8d, 0x9f, 0x3e, 0xfe, 0x32, 0x88, 0xf2, 0xe9, - 0x9a, 0x90, 0x98, 0x64, 0xa3, 0xc3, 0xa7, 0x87, - 0xa3, 0x67, 0x47, 0x47, 0x8f, 0x9d, 0x7c, 0x10, - 0x72, 0xb9, 0x94, 0x00, 0x42, 0x53, 0xf3, 0x57, - 0x12, 0x22, 0x30, 0xab, 0xfc, 0xa1, 0x78, 0x6e, - 0x1e, 0x1e, 0x0e, 0x8e, 0xe8, 0xe1, 0xc1, 0x11, - 0x3c, 0x85, 0x7f, 0x6c, 0xa5, 0x21, 0x80, 0xb3, - 0xea, 0x4c, 0xe5, 0x04, 0xd6, 0xd6, 0x84, 0xce, - 0x14, 0x76, 0xe4, 0x4c, 0xfe, 0x44, 0x5d, 0x98, - 0xf3, 0x8e, 0x87, 0xe7, 0xa6, 0xfc, 0x99, 0x5b, - 0x89, 0x79, 0x3a, 0x73, 0x78, 0xb0, 0x90, 0x3f, - 0xa6, 0xa9, 0x2f, 0x7f, 0xa6, 0x32, 0xe1, 0x3c, - 0x90, 0x35, 0x2f, 0x24, 0x9a, 0x1d, 0x1a, 0x96, - 0xd2, 0x19, 0xd4, 0x23, 0x49, 0xc8, 0x63, 0x43, - 0xc1, 0xf5, 0x6a, 0x00, 0x9b, 0x1c, 0x48, 0xee, - 0x32, 0xd6, 0x10, 0x1c, 0x15, 0x48, 0xc6, 0x46, - 0xaa, 0x3a, 0xea, 0x95, 0x5e, 0x5e, 0xd4, 0xbf, - 0x1c, 0xd9, 0xc9, 0xf5, 0xd9, 0x18, 0x33, 0xbc, - 0x8b, 0xf4, 0x90, 0xf7, 0x52, 0x5a, 0xad, 0x17, - 0x56, 0x2f, 0x53, 0x24, 0x6a, 0x91, 0x2a, 0xc9, - 0x9c, 0x31, 0x60, 0x80, 0xd1, 0x12, 0x15, 0x61, - 0x54, 0x06, 0x8a, 0x94, 0x0a, 0xcc, 0x23, 0x2b, - 0x4a, 0x37, 0x95, 0xc7, 0x3a, 0xb8, 0xa2, 0xf2, - 0xc6, 0x9b, 0x62, 0xa2, 0x1e, 0x5c, 0x30, 0x99, - 0x3c, 0xf5, 0xf5, 0x2b, 0x71, 0x30, 0x18, 0x1d, - 0x8e, 0x8e, 0x9e, 0x8d, 0x1f, 0x1f, 0x1d, 0x1c, - 0x3d, 0x7d, 0xf6, 0xe4, 0xd9, 0x41, 0x73, 0xb2, - 0x2d, 0x3a, 0x20, 0x5a, 0x74, 0x98, 0xba, 0x1d, - 0xd4, 0xe1, 0x03, 0x61, 0x90, 0xcd, 0x39, 0x97, - 0x76, 0xb7, 0x92, 0x4c, 0xfb, 0x57, 0xe7, 0xcc, - 0xa2, 0xb3, 0x0a, 0x19, 0x9f, 0xe7, 0xb2, 0x3b, - 0xa7, 0x9a, 0xd9, 0x14, 0x96, 0x2d, 0x51, 0x27, - 0x0f, 0xc1, 0x47, 0xa6, 0xb3, 0x5a, 0x65, 0xe9, - 0x39, 0xe6, 0x5e, 0xc5, 0xbc, 0x3b, 0x05, 0xe5, - 0x41, 0xb2, 0x6a, 0x36, 0xc1, 0xd8, 0xb1, 0xd8, - 0x1a, 0x73, 0xa2, 0x30, 0x9b, 0x7a, 0xc4, 0x44, - 0x39, 0xbb, 0x17, 0x65, 0xe1, 0x8d, 0x72, 0x78, - 0x42, 0x37, 0xaf, 0x88, 0xb5, 0x7d, 0x79, 0xf8, - 0x74, 0xf8, 0x84, 0x5a, 0x07, 0x61, 0xe1, 0x45, - 0x71, 0x6e, 0xa7, 0x8c, 0x41, 0xcc, 0xbe, 0x55, - 0x59, 0xad, 0x30, 0x58, 0x07, 0x83, 0x3c, 0xbc, - 0x24, 0xef, 0x74, 0xcc, 0x22, 0xfe, 0x36, 0x7c, - 0xc3, 0x86, 0x3b, 0xf5, 0xf7, 0xe8, 0x0d, 0x6e, - 0x67, 0x69, 0x02, 0x95, 0xea, 0x68, 0x97, 0xed, - 0x9d, 0x56, 0x13, 0x49, 0x6c, 0x3c, 0x31, 0x94, - 0x9c, 0xdb, 0x3a, 0x13, 0xec, 0xf9, 0xb1, 0x79, - 0xfa, 0xbb, 0xbe, 0x9c, 0x26, 0x98, 0x93, 0x11, - 0xf0, 0x07, 0x1b, 0x57, 0xfa, 0x00, 0xa8, 0xb6, - 0xf0, 0x92, 0x0e, 0xbe, 0xc3, 0x54, 0xcf, 0x7c, - 0x9f, 0x85, 0xd6, 0x08, 0x79, 0x90, 0x35, 0x1e, - 0xf7, 0x32, 0x0b, 0x25, 0x6e, 0x82, 0x8f, 0x15, - 0xe7, 0x60, 0x0b, 0x2b, 0xda, 0xee, 0x11, 0x9a, - 0x64, 0x19, 0x98, 0x5c, 0x86, 0xdf, 0x77, 0x81, - 0x93, 0x02, 0x49, 0xa9, 0x0b, 0x6b, 0xaa, 0x81, - 0xf6, 0x42, 0x8c, 0xa8, 0xae, 0x47, 0xbf, 0x52, - 0x0f, 0xc4, 0xa4, 0xab, 0x3d, 0x51, 0xc4, 0xae, - 0xd4, 0x76, 0x39, 0x0f, 0x41, 0x80, 0x80, 0x55, - 0x76, 0x30, 0x3a, 0x1c, 0x61, 0xed, 0x40, 0xc8, - 0x80, 0x6f, 0x60, 0xc5, 0x65, 0xee, 0xac, 0x79, - 0x9c, 0xfa, 0x5e, 0x2c, 0x03, 0x39, 0x52, 0x1f, - 0x97, 0xb6, 0x27, 0x0f, 0x34, 0x80, 0x90, 0x03, - 0x88, 0xfd, 0xb1, 0x13, 0xed, 0x81, 0x64, 0xf3, - 0x2e, 0x5a, 0xae, 0x8b, 0x85, 0x49, 0x17, 0xad, - 0x6b, 0xd4, 0xe9, 0x0e, 0x4a, 0xd4, 0x33, 0x0c, - 0xc2, 0x39, 0x16, 0xb4, 0x83, 0xf3, 0x70, 0x95, - 0x26, 0x2a, 0xd5, 0x7a, 0x02, 0xc4, 0xb3, 0xd8, - 0xa7, 0xda, 0x5f, 0xe9, 0x4a, 0xd1, 0xa6, 0x2a, - 0xdc, 0xa7, 0x4a, 0x27, 0xe4, 0xc5, 0x05, 0x90, - 0x34, 0xce, 0xaa, 0x1d, 0xc2, 0x84, 0x6f, 0xd2, - 0x2c, 0x9a, 0x53, 0x80, 0x8d, 0x4c, 0xac, 0xbe, - 0xf1, 0x72, 0xb1, 0xc9, 0xa2, 0x02, 0x26, 0x46, - 0xf6, 0x1f, 0xae, 0x0a, 0xd1, 0xe9, 0x83, 0x04, - 0x42, 0xe1, 0x76, 0x88, 0xe1, 0x37, 0xca, 0xa0, - 0x0c, 0xf4, 0xf4, 0x0c, 0x76, 0x96, 0x27, 0xa3, - 0xc3, 0xd4, 0x88, 0x06, 0xf6, 0x52, 0xf2, 0x43, - 0x6b, 0x82, 0x2f, 0x80, 0xf4, 0x5e, 0xbf, 0x72, - 0xf6, 0xa1, 0x2e, 0x2c, 0x28, 0xa9, 0x06, 0x0e, - 0xfd, 0x34, 0x09, 0xa9, 0xe4, 0x0a, 0x06, 0xbf, - 0xa9, 0x2d, 0xa8, 0x97, 0x0b, 0xc4, 0x30, 0xaa, - 0xb6, 0xe6, 0x81, 0xe0, 0xc5, 0xa1, 0x6b, 0xec, - 0x80, 0x59, 0x46, 0xb1, 0x87, 0x61, 0x35, 0x76, - 0x18, 0x98, 0x05, 0xcb, 0xbd, 0x6f, 0x25, 0x66, - 0xeb, 0x84, 0x47, 0x51, 0x99, 0xa4, 0xe7, 0x57, - 0x94, 0x14, 0x7c, 0x58, 0x7f, 0x78, 0x82, 0x45, - 0x1f, 0xf6, 0xf3, 0x6c, 0xba, 0x4f, 0x90, 0xfa, - 0x08, 0x69, 0xdf, 0xc8, 0x2f, 0xfb, 0xc4, 0xfb, - 0x68, 0x89, 0xf3, 0x7d, 0x83, 0x49, 0x38, 0xf8, - 0x77, 0xfe, 0xe5, 0xf7, 0xe3, 0xd1, 0x93, 0xfe, - 0xf7, 0xe3, 0xf1, 0xd3, 0x72, 0x70, 0x11, 0xf2, - 0x54, 0x58, 0x15, 0x43, 0xa8, 0x32, 0x98, 0x6d, - 0x0a, 0x12, 0x0e, 0xd6, 0x02, 0x41, 0xd1, 0x26, - 0x5d, 0x79, 0xa0, 0xe4, 0xda, 0x42, 0xa2, 0xbd, - 0x00, 0xd2, 0x40, 0x3b, 0x1a, 0x3c, 0x7d, 0x72, - 0x04, 0xeb, 0x65, 0x67, 0x68, 0x1e, 0x0d, 0x9e, - 0x1c, 0xd9, 0xdb, 0x0e, 0x0e, 0xff, 0x7f, 0xc8, - 0x90, 0x48, 0xce, 0x14, 0x88, 0xcb, 0x54, 0xe2, - 0x3e, 0xc1, 0xa9, 0xdc, 0xd7, 0x06, 0xd0, 0x17, - 0xdc, 0xfc, 0x2b, 0xe4, 0xb9, 0x20, 0x53, 0xb0, - 0xdf, 0x95, 0x16, 0x52, 0x31, 0x5d, 0x92, 0xcf, - 0xf5, 0x2b, 0xd5, 0x8d, 0x7a, 0x8b, 0xdc, 0x49, - 0x77, 0xfd, 0x9c, 0xbf, 0xb4, 0x6b, 0x1e, 0x84, - 0x82, 0xcf, 0x0f, 0x19, 0xd4, 0x01, 0x5b, 0x50, - 0xad, 0xba, 0x1b, 0x6b, 0x95, 0xe3, 0xc9, 0x22, - 0x37, 0x00, 0xd3, 0x11, 0x6c, 0x41, 0x45, 0x57, - 0x48, 0xdd, 0xed, 0x00, 0xf0, 0xf3, 0xf2, 0xf4, - 0x17, 0xa5, 0xce, 0x61, 0xdf, 0x92, 0x50, 0x0e, - 0xbd, 0x4c, 0x17, 0x14, 0x5f, 0x18, 0x52, 0xed, - 0x0f, 0xa0, 0xa0, 0xda, 0xbe, 0xa0, 0x3d, 0x37, - 0x00, 0x89, 0xd6, 0xd9, 0x15, 0x0c, 0x93, 0x79, - 0xb8, 0x35, 0xaf, 0x0e, 0x13, 0xd6, 0xfc, 0x97, - 0xd2, 0xf1, 0x59, 0xa8, 0xe0, 0xde, 0xb5, 0x07, - 0x44, 0xa7, 0x16, 0x09, 0x5e, 0x30, 0x9e, 0x12, - 0xa9, 0x94, 0x47, 0xa4, 0x5e, 0x47, 0x80, 0xd4, - 0x7f, 0xf0, 0xc2, 0x05, 0x29, 0xa5, 0x51, 0xc3, - 0x74, 0x7c, 0xec, 0x25, 0xc2, 0x1c, 0xf3, 0x5c, - 0xa9, 0x93, 0x27, 0x16, 0xfb, 0x60, 0xba, 0xb3, - 0xb4, 0x9e, 0x38, 0xac, 0x52, 0xe5, 0x5f, 0x09, - 0x9e, 0x64, 0x95, 0x21, 0x25, 0x85, 0x04, 0x68, - 0x12, 0x02, 0xd1, 0x2a, 0x9e, 0x37, 0xf9, 0x0a, - 0x74, 0x93, 0x44, 0xce, 0x07, 0xc7, 0x67, 0xd0, - 0xb8, 0x74, 0x20, 0xad, 0x3c, 0xaa, 0xf8, 0x29, - 0x5b, 0x28, 0xe5, 0xc8, 0xf7, 0xa4, 0x7c, 0x69, - 0x53, 0xf1, 0xb8, 0xd1, 0x9b, 0xc8, 0x73, 0xc4, - 0x69, 0xcd, 0xd0, 0xfe, 0xde, 0x91, 0xe7, 0xca, - 0x23, 0xc5, 0x95, 0x90, 0x30, 0x81, 0xbd, 0xb3, - 0xd0, 0xe9, 0x4a, 0x09, 0x1a, 0x37, 0x02, 0xa2, - 0x51, 0x63, 0x1b, 0x3d, 0x0b, 0x40, 0x3d, 0x5b, - 0xe6, 0xe9, 0x71, 0x43, 0xc4, 0x16, 0x08, 0xc9, - 0x59, 0xd3, 0xad, 0xb1, 0x2e, 0x09, 0xac, 0xce, - 0xac, 0xe8, 0x03, 0xdc, 0xc2, 0x67, 0xe0, 0xe1, - 0x31, 0x6e, 0x3d, 0xb8, 0x11, 0x91, 0xf8, 0xc1, - 0x03, 0xc9, 0x39, 0x4d, 0x45, 0x8d, 0x33, 0x3c, - 0x18, 0xe8, 0x38, 0xe3, 0x13, 0x2c, 0x91, 0xe5, - 0x2b, 0x30, 0xe7, 0x9e, 0xa4, 0x6d, 0x0a, 0xcc, - 0x2e, 0xe0, 0x80, 0x80, 0x33, 0xfb, 0x8c, 0x72, - 0x6b, 0x52, 0xf1, 0x0c, 0x90, 0xa6, 0x96, 0x40, - 0x02, 0x61, 0xe6, 0xdc, 0x84, 0xf5, 0x48, 0xd2, - 0x53, 0x45, 0x33, 0x07, 0x5a, 0x2c, 0x7c, 0xf1, - 0xc3, 0xcf, 0xaf, 0x5e, 0x7c, 0xff, 0xea, 0xc5, - 0xe9, 0xab, 0x1f, 0xbe, 0x6b, 0x2b, 0x48, 0x09, - 0x93, 0x47, 0x58, 0x72, 0xa1, 0x82, 0x11, 0xe8, - 0xd5, 0xf0, 0x8c, 0x2a, 0x5a, 0x3c, 0xc6, 0x5a, - 0x13, 0x12, 0x7f, 0xe0, 0x29, 0x54, 0xc4, 0x13, - 0xfa, 0x4f, 0x37, 0x80, 0xcb, 0x32, 0x2a, 0x28, - 0xa4, 0x77, 0xc9, 0x1a, 0x32, 0xca, 0x0a, 0x72, - 0x8b, 0x2f, 0x53, 0x8c, 0xd1, 0x1c, 0x98, 0x4c, - 0x97, 0x81, 0x8e, 0x6a, 0x8e, 0xa8, 0xea, 0x0f, - 0x8a, 0x68, 0xb4, 0xb7, 0x60, 0x40, 0xfe, 0x05, - 0x30, 0x80, 0x4e, 0x7f, 0x34, 0x7e, 0x3a, 0x18, - 0x40, 0xd7, 0xdd, 0x01, 0x15, 0x7f, 0xa1, 0x13, - 0x2c, 0x0b, 0xe7, 0x6b, 0x3c, 0x81, 0xf8, 0xdb, - 0x1c, 0xcb, 0x85, 0xc0, 0x68, 0x65, 0x26, 0xbd, - 0xc7, 0x07, 0xa0, 0xb4, 0xaf, 0x0b, 0x89, 0x1d, - 0xaa, 0xc8, 0x99, 0x14, 0xb4, 0xfe, 0x8c, 0x64, - 0x09, 0xe7, 0xd3, 0x9f, 0xf5, 0x87, 0xcc, 0xfb, - 0xbd, 0x33, 0xd4, 0xa3, 0xfd, 0x08, 0xd5, 0x30, - 0x05, 0xa5, 0x03, 0xac, 0x87, 0xc1, 0x62, 0xa0, - 0x7a, 0x94, 0xe8, 0x02, 0x47, 0x58, 0x84, 0xa8, - 0x4b, 0xeb, 0xa0, 0x66, 0x93, 0x71, 0xa2, 0x19, - 0x71, 0x1f, 0x61, 0xb5, 0xb3, 0xa3, 0xa7, 0x4f, - 0x0e, 0x86, 0xa3, 0xc7, 0x0f, 0xaa, 0xa1, 0x52, - 0xe8, 0xa3, 0x62, 0x3c, 0x6a, 0xe2, 0xa8, 0x64, - 0x9d, 0xc2, 0x4b, 0x1c, 0x32, 0xd5, 0xea, 0x53, - 0x94, 0x7e, 0xb3, 0xa4, 0x5c, 0x00, 0x31, 0x56, - 0x6f, 0xc9, 0x96, 0xd4, 0x15, 0x85, 0x48, 0xe9, - 0x31, 0x65, 0x18, 0x1c, 0x57, 0xa3, 0xb0, 0xe6, - 0xde, 0x72, 0xe9, 0xa9, 0x44, 0x9a, 0x75, 0xd5, - 0x25, 0xd0, 0x31, 0x95, 0x84, 0x79, 0x3a, 0xf3, - 0xb2, 0x4f, 0x34, 0xeb, 0x1e, 0x65, 0xa3, 0xad, - 0x8f, 0x21, 0xa3, 0x0a, 0xf7, 0x8d, 0x31, 0x64, - 0x54, 0x7f, 0xf1, 0xd6, 0xcb, 0x91, 0xde, 0x97, - 0x2b, 0xc8, 0xf5, 0x58, 0xce, 0xbd, 0x15, 0x57, - 0x6b, 0xac, 0x45, 0x53, 0xbd, 0x6d, 0xad, 0xb7, - 0xa6, 0x1a, 0x5d, 0x56, 0x71, 0xcd, 0x6e, 0xd7, - 0x3e, 0x73, 0xb3, 0x59, 0x1e, 0x36, 0x44, 0xdf, - 0xf1, 0xbb, 0x96, 0x79, 0xa3, 0xf7, 0xed, 0x53, - 0xa3, 0x9b, 0xb4, 0x62, 0xd1, 0x32, 0x2d, 0x97, - 0xcf, 0xc9, 0x56, 0x13, 0x52, 0x9e, 0x8d, 0x4f, - 0x26, 0x5d, 0xa3, 0xce, 0xff, 0xac, 0x6a, 0x99, - 0x56, 0x43, 0x0d, 0xb9, 0x90, 0xa5, 0xdc, 0x81, - 0x8d, 0xa1, 0x86, 0xed, 0xa5, 0x50, 0xef, 0xc3, - 0xf5, 0xf8, 0x16, 0x5c, 0xf4, 0xd6, 0xa9, 0x96, - 0x50, 0x53, 0xaf, 0x6a, 0x71, 0x53, 0x2f, 0x7b, - 0xce, 0x06, 0x6b, 0x29, 0xc8, 0x66, 0x43, 0xab, - 0xd9, 0x45, 0x6d, 0xd3, 0xc5, 0x3b, 0xa9, 0x3c, - 0x60, 0x7a, 0x5a, 0x3f, 0x6f, 0xf4, 0xaa, 0x67, - 0x6d, 0xb4, 0xc6, 0x59, 0xd3, 0x40, 0x2a, 0x1b, - 0xaa, 0xad, 0x86, 0x5e, 0xc3, 0x84, 0x35, 0xcf, - 0x96, 0x9e, 0xaa, 0xcb, 0xe7, 0xc9, 0x4c, 0x52, - 0x79, 0x67, 0x69, 0x63, 0x98, 0xe7, 0xa4, 0xde, - 0x96, 0xf5, 0x5e, 0x51, 0xc4, 0x05, 0xd9, 0x65, - 0xe8, 0x18, 0x5c, 0x4c, 0xfc, 0xb2, 0x8c, 0x55, - 0x91, 0xcd, 0xdf, 0xf5, 0x28, 0x33, 0x3b, 0x8b, - 0xc5, 0x56, 0x54, 0x9f, 0x3c, 0x43, 0x51, 0x58, - 0x57, 0xd5, 0xa2, 0xb8, 0x3d, 0x7b, 0x6d, 0x51, - 0x2e, 0x95, 0x4f, 0x30, 0xcf, 0xf9, 0xe3, 0x43, - 0x5d, 0xd3, 0xae, 0x1a, 0xd2, 0x69, 0x4b, 0x1c, - 0x54, 0x8e, 0x56, 0x29, 0x19, 0xe7, 0x28, 0xa5, - 0x8d, 0x30, 0xd4, 0x2e, 0x22, 0x83, 0x09, 0x56, - 0x3b, 0x07, 0xcd, 0x67, 0xea, 0xad, 0x40, 0x72, - 0xae, 0xfa, 0x3d, 0x2e, 0x74, 0x73, 0x14, 0xe3, - 0xa4, 0xf8, 0x46, 0xb5, 0xde, 0x50, 0x10, 0xe3, - 0x8b, 0x3f, 0x7d, 0x09, 0x4e, 0x3d, 0x47, 0x1f, - 0x81, 0x33, 0xb5, 0x84, 0x97, 0x15, 0x6c, 0x6b, - 0xa1, 0xf6, 0x6e, 0x63, 0xf2, 0xae, 0xcb, 0xf7, - 0x4a, 0x3a, 0xb1, 0xec, 0x0d, 0xb9, 0xd4, 0x71, - 0x90, 0x05, 0x92, 0x99, 0x21, 0xa7, 0xfc, 0xd4, - 0x28, 0xb0, 0xf9, 0x21, 0xda, 0x0a, 0xe3, 0x88, - 0x05, 0x49, 0x44, 0xf2, 0xbf, 0x4e, 0x09, 0xab, - 0x84, 0xef, 0x33, 0x52, 0x89, 0x41, 0x54, 0x91, - 0x73, 0x5d, 0x0b, 0x6e, 0x09, 0xa2, 0x37, 0xd9, - 0x69, 0x96, 0xa6, 0xb0, 0xa0, 0x34, 0xd4, 0xa0, - 0x45, 0x08, 0xd4, 0x8a, 0x0c, 0xf7, 0x32, 0x29, - 0x84, 0xd1, 0x12, 0x60, 0xe3, 0x76, 0xe6, 0xaf, - 0xad, 0x6d, 0xa4, 0x7f, 0xdd, 0xe7, 0x15, 0xb0, - 0x9c, 0x87, 0x5e, 0x3c, 0x53, 0xad, 0x2a, 0x4d, - 0x34, 0xcd, 0xa3, 0xe1, 0x0c, 0xaf, 0xae, 0x4b, - 0xc2, 0x77, 0x0c, 0x68, 0xdc, 0x42, 0xf7, 0xf0, - 0x48, 0x74, 0xf4, 0xef, 0xca, 0xfa, 0xe6, 0x48, - 0xf5, 0xcf, 0x2b, 0x3e, 0x48, 0x50, 0x1f, 0x2a, - 0x40, 0x0c, 0x5e, 0x7b, 0x35, 0x00, 0xc7, 0x64, - 0xce, 0x1b, 0x31, 0x99, 0x75, 0xac, 0x31, 0x28, - 0x2b, 0x21, 0xd7, 0xf1, 0xb5, 0xfb, 0xed, 0x96, - 0xeb, 0xbb, 0xd5, 0x26, 0xb5, 0x27, 0x97, 0x11, - 0xea, 0x27, 0xf6, 0x9d, 0x46, 0x68, 0x99, 0xa0, - 0xc8, 0xed, 0x5f, 0x18, 0xed, 0xc7, 0x6c, 0x6c, - 0x00, 0x48, 0x26, 0x87, 0x28, 0x27, 0xff, 0x5d, - 0x78, 0x3e, 0xa8, 0xd2, 0x93, 0xcc, 0xe6, 0x23, - 0x07, 0xba, 0xe7, 0x64, 0xc1, 0x2f, 0x15, 0x79, - 0x33, 0x57, 0x31, 0x49, 0x81, 0xe6, 0x15, 0xd8, - 0x20, 0x06, 0x41, 0xe6, 0x6d, 0xd8, 0xe6, 0x15, - 0x73, 0xc9, 0x43, 0x8f, 0xaf, 0xb9, 0x4a, 0xa2, - 0x40, 0x3b, 0xb6, 0xb4, 0x7d, 0x70, 0x15, 0x3a, - 0x6a, 0x36, 0xb0, 0x8d, 0xdd, 0xa9, 0x76, 0xee, - 0x91, 0xf5, 0x88, 0x81, 0xd9, 0x45, 0x2c, 0xe5, - 0xa6, 0x28, 0xd2, 0x8d, 0x97, 0x05, 0xb9, 0xad, - 0x0d, 0x91, 0xe6, 0x02, 0xfb, 0xaf, 0x00, 0xcc, - 0x2c, 0x3f, 0x23, 0x21, 0xc6, 0xb5, 0x1f, 0x15, - 0x7a, 0xbc, 0x47, 0x81, 0x13, 0x29, 0x68, 0x1d, - 0x97, 0xb7, 0xc0, 0x0e, 0x84, 0xee, 0x46, 0x5d, - 0x59, 0xb7, 0x0e, 0xfa, 0x88, 0xf4, 0x1d, 0x3c, - 0x35, 0x2b, 0x12, 0x27, 0x09, 0x00, 0x95, 0xae, - 0x84, 0x76, 0xbb, 0x09, 0xab, 0x1d, 0xd4, 0xf0, - 0xc3, 0xb5, 0x36, 0x5b, 0x59, 0x3d, 0x1e, 0xd7, - 0x34, 0x2c, 0x4c, 0x2c, 0x96, 0x9f, 0x77, 0xd6, - 0xdd, 0xe3, 0xea, 0x8a, 0xf1, 0xc4, 0x63, 0xdc, - 0x9c, 0x5c, 0x82, 0x9a, 0x45, 0x43, 0x0f, 0xb3, - 0x8a, 0x00, 0x46, 0x03, 0x56, 0x41, 0x45, 0xac, - 0xfa, 0xeb, 0x9e, 0x80, 0xff, 0x17, 0x4e, 0x60, - 0x9d, 0x2e, 0xe6, 0x61, 0xf1, 0xe3, 0xb2, 0xdf, - 0x87, 0x88, 0x64, 0x5f, 0x29, 0x4b, 0x26, 0x48, - 0xba, 0x5a, 0x0c, 0xa8, 0xe6, 0x63, 0x76, 0xda, - 0x2b, 0xac, 0xcb, 0x50, 0xe4, 0x4e, 0xa9, 0x60, - 0x61, 0xc8, 0x4e, 0xdb, 0xc3, 0x04, 0xde, 0xa4, - 0x5e, 0xae, 0xa5, 0xa6, 0x6f, 0x95, 0x50, 0x20, - 0x93, 0x32, 0x16, 0x05, 0x8d, 0xf2, 0x05, 0xea, - 0xfc, 0x19, 0xe6, 0xaf, 0x0f, 0xb1, 0xa8, 0x87, - 0x43, 0x28, 0x8d, 0x49, 0xf2, 0x27, 0x68, 0x67, - 0x83, 0x1d, 0x60, 0x97, 0x65, 0x30, 0x19, 0xae, - 0xac, 0xec, 0x97, 0x8d, 0x1f, 0xd7, 0x7f, 0x59, - 0x19, 0x54, 0x5d, 0x42, 0xbb, 0xbd, 0x5a, 0x6d, - 0x53, 0xbb, 0xd7, 0x2c, 0xad, 0x11, 0x00, 0x6f, - 0x81, 0xf7, 0xfe, 0x65, 0xf8, 0xe9, 0x93, 0x92, - 0x15, 0x55, 0xe5, 0xd1, 0x65, 0x0e, 0xd0, 0x63, - 0xb6, 0xf9, 0x71, 0xd3, 0x6c, 0x93, 0x50, 0x7b, - 0xeb, 0xda, 0xe0, 0x6d, 0xe5, 0x93, 0x2d, 0xeb, - 0xff, 0x0d, 0xd6, 0x82, 0x5a, 0xb3, 0xc0, 0x9d, - 0x27, 0x04, 0xd7, 0xfa, 0xc3, 0xf6, 0xba, 0xc0, - 0x0d, 0x26, 0xff, 0xa9, 0x1c, 0x2a, 0x56, 0xa1, - 0x5c, 0xe3, 0xc7, 0x34, 0xd5, 0x71, 0xe9, 0x74, - 0xa1, 0x8a, 0x3d, 0xb8, 0x47, 0x06, 0x2d, 0x49, - 0xe9, 0x78, 0xb6, 0xbb, 0x14, 0xee, 0xcb, 0x0b, - 0x32, 0xc8, 0x9b, 0x4e, 0x32, 0x8f, 0x1c, 0x30, - 0x6c, 0xef, 0xe3, 0x52, 0x1d, 0xec, 0x38, 0x1c, - 0x70, 0x29, 0x0f, 0x0c, 0xc6, 0x89, 0x88, 0xc5, - 0xd3, 0x91, 0x32, 0x93, 0x37, 0xaa, 0x13, 0xdb, - 0x91, 0xa3, 0x10, 0x43, 0x43, 0x17, 0x95, 0x28, - 0x4e, 0x14, 0x73, 0xa6, 0x37, 0x1d, 0x8d, 0x44, - 0xd1, 0x45, 0xf6, 0x64, 0x03, 0x52, 0x35, 0x41, - 0x00, 0x92, 0x69, 0x96, 0xdb, 0xf9, 0x20, 0x70, - 0x19, 0x70, 0x9b, 0x76, 0x68, 0x61, 0x1e, 0x35, - 0x1a, 0x1f, 0x79, 0xb4, 0x0e, 0x3d, 0x55, 0x73, - 0xf0, 0xb1, 0xb5, 0x77, 0x09, 0x04, 0x46, 0x53, - 0xd6, 0xb7, 0x71, 0x83, 0xbf, 0xa8, 0x2f, 0xbc, - 0x4c, 0xa1, 0x31, 0x81, 0x87, 0xc4, 0x01, 0xa1, - 0x4b, 0x7a, 0x59, 0xcd, 0x7a, 0xd0, 0x90, 0x1b, - 0xfe, 0x76, 0x72, 0x01, 0x2b, 0x03, 0xaa, 0xd1, - 0xf7, 0xa7, 0x18, 0x25, 0x4a, 0x5b, 0x0a, 0xf8, - 0xed, 0x1c, 0x1d, 0x5a, 0x32, 0xad, 0x80, 0x94, - 0x46, 0xb0, 0x26, 0x0c, 0x59, 0xbc, 0xa9, 0xe6, - 0x34, 0xa0, 0x3e, 0xfe, 0xd7, 0xe8, 0xc8, 0xd4, - 0x4a, 0xfd, 0xfb, 0x8b, 0x7f, 0x4e, 0xbe, 0x7f, - 0xf5, 0xc3, 0xcb, 0xc9, 0x37, 0xaf, 0x4e, 0x7f, - 0x7e, 0xf1, 0xc3, 0xd7, 0x2f, 0xc5, 0xc1, 0xf8, - 0xc9, 0xe3, 0x27, 0xd2, 0x8a, 0xbb, 0xb3, 0x35, - 0xef, 0x6c, 0xcd, 0x9f, 0xaf, 0xad, 0x59, 0x6d, - 0x98, 0xe3, 0x9d, 0x45, 0x77, 0x67, 0xd1, 0xdd, - 0x59, 0x74, 0x77, 0x16, 0xd5, 0x9d, 0x45, 0x75, - 0x67, 0x51, 0xad, 0xb5, 0xa8, 0x6a, 0xd1, 0xea, - 0xca, 0x46, 0x55, 0x78, 0x5f, 0x11, 0xb1, 0x76, - 0x86, 0xd6, 0x9d, 0xa1, 0x75, 0x67, 0x68, 0xdd, - 0x19, 0x5a, 0x77, 0x86, 0xd6, 0x9d, 0xa1, 0x75, - 0x67, 0x68, 0xc5, 0xb0, 0xb6, 0xcf, 0xc2, 0x10, - 0x7a, 0x85, 0x84, 0x16, 0x1f, 0x62, 0x24, 0xdd, - 0x4a, 0x9f, 0xdd, 0x3a, 0x6f, 0xc4, 0xce, 0x00, - 0xba, 0x33, 0x80, 0x7e, 0xa0, 0x01, 0x14, 0x30, - 0xff, 0x16, 0x06, 0xa5, 0xb3, 0x9a, 0x52, 0x08, - 0x42, 0xaf, 0x2c, 0x39, 0xcb, 0x3c, 0xb5, 0xc4, - 0x93, 0xa5, 0x85, 0x92, 0x78, 0x26, 0x4c, 0x7e, - 0xc6, 0x13, 0xd8, 0x73, 0x2e, 0x35, 0xba, 0xf6, - 0xca, 0x9e, 0xbe, 0x15, 0xa1, 0xbb, 0xc9, 0x60, - 0x20, 0x64, 0xdd, 0xb4, 0x8c, 0x72, 0xf2, 0x1e, - 0xd2, 0xa0, 0x5a, 0x5f, 0xbb, 0xee, 0x86, 0x12, - 0xb2, 0x23, 0x17, 0x4b, 0x4e, 0xf4, 0xf3, 0x51, - 0x2c, 0xbb, 0x3b, 0x3b, 0xe6, 0x8d, 0xd8, 0x31, - 0xcb, 0xb7, 0x56, 0x34, 0x47, 0xf1, 0xc3, 0x19, - 0x46, 0xb9, 0x73, 0x65, 0x7b, 0x14, 0xdc, 0xa4, - 0xd4, 0xe8, 0xaf, 0x67, 0x33, 0x38, 0xb4, 0x74, - 0x14, 0x3e, 0x8c, 0x1e, 0xaf, 0x0c, 0xd3, 0x14, - 0x21, 0x34, 0xa2, 0x54, 0x05, 0x85, 0x53, 0x15, - 0xd3, 0xa3, 0x3c, 0x9c, 0xe3, 0x2c, 0xe7, 0x03, - 0xf1, 0x4b, 0x2e, 0xaf, 0x1f, 0xe9, 0xb4, 0x0c, - 0xeb, 0xa4, 0x8a, 0x80, 0x31, 0x6f, 0x3b, 0xba, - 0xe0, 0xe4, 0xf4, 0xeb, 0x17, 0xdf, 0xbf, 0xd4, - 0xa6, 0xec, 0x4f, 0xc0, 0xe0, 0xfe, 0x59, 0x59, - 0x8a, 0xad, 0x90, 0xe3, 0x76, 0xcf, 0xe4, 0xce, - 0x40, 0x7c, 0xf3, 0x06, 0xe2, 0xfb, 0x61, 0x8c, - 0xbd, 0x8f, 0x66, 0xea, 0x9d, 0x81, 0xf8, 0x9e, - 0x1b, 0x88, 0xef, 0x9d, 0xf5, 0xf5, 0x13, 0xb0, - 0x58, 0x7f, 0x76, 0x06, 0x62, 0xfb, 0x8b, 0xeb, - 0xc6, 0xdd, 0xd6, 0x08, 0x03, 0x3b, 0xf3, 0xf0, - 0xce, 0x3c, 0xbc, 0x33, 0x0f, 0xef, 0xcc, 0xc3, - 0x3b, 0xf3, 0xf0, 0xce, 0x3c, 0xfc, 0x07, 0x30, - 0x0f, 0xdb, 0x27, 0xa7, 0x67, 0x2b, 0x64, 0x5b, - 0x5a, 0x8f, 0x6f, 0xb6, 0x7e, 0xc3, 0x7d, 0xca, - 0x93, 0x8c, 0x6a, 0xfe, 0xd5, 0x12, 0x25, 0x7f, - 0x0c, 0xed, 0xf7, 0x13, 0x8a, 0x54, 0xde, 0x19, - 0xc5, 0x77, 0x46, 0xf1, 0x3b, 0x32, 0x8a, 0x73, - 0x07, 0xe7, 0x54, 0x6a, 0x80, 0x13, 0x4c, 0x1b, - 0x3e, 0xb7, 0x5f, 0x61, 0x53, 0x98, 0xc7, 0xb1, - 0x9c, 0x22, 0xe3, 0xdc, 0x4a, 0x4e, 0xdd, 0xf2, - 0xad, 0x6f, 0xbe, 0x55, 0x53, 0xa6, 0x56, 0x7a, - 0x40, 0xf2, 0xbe, 0x31, 0x0b, 0x47, 0x01, 0xc9, - 0x0b, 0x8a, 0x8e, 0xc8, 0xe6, 0x8e, 0xd2, 0x86, - 0x7c, 0xcf, 0x25, 0xb6, 0xd0, 0xc0, 0x08, 0x00, - 0xd5, 0x43, 0x2a, 0x42, 0x40, 0x0f, 0xad, 0xb4, - 0x88, 0x34, 0x5f, 0x25, 0x51, 0x4f, 0xc9, 0x6e, - 0x2c, 0xc5, 0xab, 0x42, 0x74, 0x43, 0x92, 0x0f, - 0x51, 0xfe, 0x64, 0xd2, 0x65, 0xcc, 0x55, 0x4e, - 0xf1, 0x55, 0xbc, 0xce, 0xe1, 0x19, 0x9b, 0x64, - 0x31, 0xe3, 0x5d, 0xd7, 0xca, 0xce, 0x15, 0x26, - 0xf9, 0x5a, 0xe6, 0xaf, 0x4c, 0x93, 0x87, 0x85, - 0x64, 0x7f, 0xd4, 0x8d, 0xca, 0x0c, 0x16, 0x84, - 0x58, 0x86, 0x8c, 0x72, 0xc5, 0xe4, 0x17, 0x4b, - 0x3f, 0x8d, 0x55, 0x36, 0xb0, 0x7c, 0x05, 0x42, - 0x3f, 0xea, 0x01, 0x61, 0x58, 0x68, 0x01, 0x0f, - 0x25, 0x1f, 0xcc, 0x7c, 0x18, 0x04, 0xac, 0x6c, - 0xe4, 0x8b, 0x68, 0x56, 0xe8, 0x62, 0x60, 0x94, - 0x89, 0x48, 0x61, 0x8f, 0x12, 0x1a, 0x34, 0x72, - 0x47, 0x31, 0x22, 0x85, 0xc2, 0x4d, 0x54, 0x94, - 0xce, 0x6c, 0x8a, 0x97, 0x4e, 0x06, 0x4e, 0xb6, - 0x8b, 0x19, 0x99, 0xec, 0xc3, 0xfe, 0x82, 0x68, - 0x81, 0xeb, 0x19, 0x74, 0xac, 0x25, 0x52, 0x29, - 0x48, 0x0c, 0x75, 0x49, 0x6a, 0xea, 0x54, 0xa8, - 0x04, 0xf3, 0x33, 0x99, 0x24, 0xc8, 0xdd, 0x3a, - 0x42, 0x72, 0x4b, 0xcf, 0x5f, 0x10, 0x0d, 0x7d, - 0x40, 0x9f, 0xfe, 0xe5, 0x7d, 0xfa, 0xba, 0x4f, - 0xa5, 0xb1, 0x32, 0xd1, 0x7f, 0x40, 0x8a, 0x77, - 0x3a, 0xea, 0xcf, 0x31, 0x7b, 0x3c, 0x4c, 0x5a, - 0xb7, 0x0c, 0xdd, 0xff, 0xc0, 0x84, 0xec, 0x12, - 0xba, 0x8f, 0xd0, 0xfd, 0xae, 0x23, 0x85, 0xda, - 0xb9, 0x64, 0xea, 0xd3, 0xb2, 0x4f, 0xb0, 0xfe, - 0x62, 0xc3, 0x2b, 0xac, 0x76, 0xc6, 0xa7, 0xf6, - 0x25, 0x1e, 0xa4, 0x92, 0x03, 0x69, 0xe7, 0x3f, - 0xda, 0xf9, 0x8f, 0x76, 0xfe, 0xa3, 0xdb, 0xf7, - 0x1f, 0x49, 0x96, 0xd0, 0x58, 0x5e, 0x0d, 0xb6, - 0xf5, 0xe4, 0xa2, 0x59, 0xb4, 0x6f, 0xae, 0xbe, - 0x46, 0xdf, 0xf9, 0xb7, 0xe9, 0xaf, 0x92, 0x8f, - 0xb1, 0x27, 0xaf, 0xf6, 0xa9, 0x7f, 0x4d, 0x11, - 0x7e, 0x97, 0x50, 0x67, 0x77, 0xfd, 0x62, 0x77, - 0xfd, 0xe2, 0xea, 0xde, 0x35, 0xb5, 0x78, 0x35, - 0x5e, 0x88, 0xab, 0xba, 0xde, 0xea, 0x91, 0xa4, - 0xc3, 0xbc, 0x05, 0x53, 0xf3, 0xbe, 0x79, 0xca, - 0x4c, 0x9b, 0x5a, 0x6a, 0xb3, 0x5f, 0xb7, 0xcc, - 0xaa, 0xdb, 0x6c, 0x97, 0x22, 0x68, 0x77, 0xa1, - 0xe5, 0x8f, 0x76, 0xa1, 0xe5, 0x76, 0x3d, 0x94, - 0x2d, 0x28, 0x58, 0x4c, 0x40, 0x2a, 0x75, 0xf2, - 0xcf, 0x5a, 0x64, 0xcc, 0xeb, 0x5e, 0x89, 0x41, - 0x34, 0x4d, 0x8c, 0x0b, 0xb0, 0x7e, 0xa7, 0xef, - 0xfc, 0xa7, 0x3b, 0xff, 0xe9, 0xce, 0x7f, 0xfa, - 0x49, 0xf8, 0x4f, 0x77, 0xee, 0xd3, 0x9d, 0xfb, - 0x74, 0xe7, 0x3e, 0xfd, 0x63, 0xb9, 0x4f, 0xc9, - 0x24, 0xa0, 0xdc, 0xa3, 0xf6, 0x39, 0xba, 0x57, - 0xb1, 0x78, 0x50, 0x9d, 0x17, 0x5b, 0x48, 0xb0, - 0xa8, 0xab, 0xd2, 0xf6, 0x82, 0xca, 0x50, 0x48, - 0x93, 0x88, 0x1e, 0x08, 0x99, 0x1a, 0xb6, 0xea, - 0xcd, 0xbf, 0x42, 0x6f, 0xbe, 0xd3, 0x9b, 0xdf, - 0xbd, 0xc2, 0xd5, 0xa1, 0x2b, 0xd4, 0x69, 0xcc, - 0x83, 0x19, 0xad, 0x43, 0x53, 0x41, 0xda, 0x7b, - 0x69, 0x99, 0xd9, 0xe5, 0x99, 0xda, 0x46, 0x97, - 0xbf, 0x4b, 0x6d, 0xfc, 0x4e, 0x14, 0xe9, 0xcf, - 0x30, 0xe5, 0x55, 0x33, 0xb4, 0x4b, 0x03, 0x43, - 0x9b, 0x34, 0xa6, 0x4b, 0x15, 0xa6, 0x6b, 0xa8, - 0x3a, 0x3b, 0xf7, 0xfb, 0xe7, 0xe3, 0x7e, 0x07, - 0x8e, 0x8f, 0xed, 0x26, 0x5e, 0x53, 0x89, 0x2a, - 0xe2, 0xda, 0xdd, 0x81, 0x77, 0x5c, 0xf3, 0x91, - 0xdf, 0xf6, 0x91, 0x5f, 0xff, 0x91, 0x74, 0x1d, - 0xea, 0x7e, 0x7b, 0x06, 0x9a, 0x29, 0xd1, 0x8c, - 0x5f, 0x49, 0x0f, 0xe0, 0x89, 0xc8, 0x97, 0x29, - 0x48, 0x9e, 0x79, 0x11, 0xae, 0xa8, 0xd4, 0x7d, - 0xdf, 0x3a, 0xa7, 0x4a, 0xc7, 0x27, 0x7b, 0x71, - 0x1b, 0x5f, 0xcb, 0x8e, 0x3e, 0xca, 0xdd, 0xb5, - 0xed, 0x8a, 0x40, 0x17, 0xf1, 0x84, 0xcb, 0x8b, - 0xd4, 0x1c, 0xcd, 0x24, 0x06, 0x34, 0xbd, 0x65, - 0x17, 0x9b, 0x3e, 0x2f, 0x6f, 0xa8, 0x00, 0xdc, - 0xb0, 0xae, 0x00, 0xdb, 0xe8, 0x46, 0xca, 0xc2, - 0xc9, 0x0a, 0x55, 0x59, 0x28, 0x8b, 0x21, 0xbd, - 0x4a, 0x8a, 0xd1, 0x63, 0x52, 0xa7, 0x55, 0x84, - 0x80, 0xae, 0x28, 0x65, 0x42, 0x05, 0x48, 0xd3, - 0x9a, 0xa3, 0xf0, 0xb7, 0x86, 0xdd, 0x9d, 0x60, - 0x29, 0x49, 0x61, 0xca, 0x19, 0xcf, 0x52, 0xad, - 0xc4, 0xcc, 0x32, 0x6f, 0xca, 0xd5, 0x60, 0xec, - 0xaf, 0x07, 0xd8, 0x25, 0xd6, 0x6c, 0xc4, 0xda, - 0x73, 0x14, 0xde, 0xa0, 0x95, 0xd0, 0x6a, 0x58, - 0x42, 0xae, 0xcc, 0x03, 0x3c, 0xb5, 0xba, 0xf2, - 0x94, 0x53, 0x17, 0x32, 0x8a, 0x2f, 0xe8, 0xac, - 0x51, 0xd5, 0x3a, 0x01, 0x26, 0x16, 0x4c, 0x0a, - 0x33, 0xf4, 0xc3, 0x06, 0xe1, 0xef, 0x6b, 0x64, - 0x56, 0x06, 0x43, 0x62, 0x20, 0xb0, 0x80, 0x58, - 0xe1, 0x4b, 0xd5, 0x39, 0xa2, 0x22, 0x41, 0xcc, - 0xaf, 0xc8, 0xb5, 0x4b, 0x8a, 0xa4, 0xb7, 0x0c, - 0xa5, 0xab, 0x53, 0x56, 0xa7, 0x7a, 0xf9, 0xcf, - 0x9f, 0x5f, 0xfe, 0xf0, 0x33, 0x7a, 0x4e, 0xcd, - 0x94, 0xe1, 0x64, 0xa5, 0x6b, 0x59, 0x30, 0x94, - 0xb1, 0x24, 0x63, 0x8e, 0x35, 0x86, 0x9e, 0x55, - 0x40, 0x07, 0x56, 0x64, 0x21, 0x2b, 0x4a, 0x02, - 0x4d, 0xd2, 0xa2, 0x4a, 0x06, 0x89, 0xbe, 0xe0, - 0x34, 0xc9, 0x61, 0x6b, 0x98, 0xc2, 0x36, 0xb4, - 0xfc, 0x54, 0x89, 0xae, 0xb1, 0xcc, 0x74, 0x9f, - 0x6e, 0x82, 0x92, 0xa2, 0x63, 0x93, 0x9f, 0xe8, - 0x72, 0x49, 0x1a, 0xab, 0xfc, 0x1f, 0x16, 0x9d, - 0xef, 0x48, 0x90, 0x7b, 0x25, 0x5a, 0xe6, 0x5a, - 0x6e, 0x16, 0xe1, 0x5b, 0x9b, 0xc5, 0x8e, 0xf2, - 0x9b, 0x14, 0x2d, 0x65, 0xc5, 0x1b, 0x45, 0xdc, - 0x61, 0xcb, 0xbb, 0xd1, 0xf1, 0x55, 0x48, 0xbe, - 0xb2, 0xe3, 0x32, 0x8c, 0xcf, 0x01, 0xd9, 0x3e, - 0x9f, 0xc4, 0x76, 0x39, 0xc1, 0x9a, 0xf7, 0x48, - 0x21, 0x35, 0x10, 0x72, 0x0f, 0x26, 0x95, 0xac, - 0x53, 0x13, 0x3e, 0xb9, 0xaa, 0x40, 0x60, 0x59, - 0x80, 0xcc, 0x80, 0x37, 0x96, 0x1b, 0x00, 0x6e, - 0x07, 0x08, 0x62, 0x15, 0x25, 0x93, 0x0d, 0x45, - 0x0a, 0x55, 0xaf, 0xb4, 0xab, 0xb5, 0xcf, 0x42, - 0x2f, 0x20, 0x1b, 0xca, 0x34, 0x4b, 0xf3, 0xbc, - 0x3f, 0xd3, 0xa5, 0x97, 0x72, 0x73, 0x44, 0xe3, - 0x47, 0xd4, 0x86, 0x57, 0x81, 0x6b, 0xce, 0x96, - 0x82, 0x3e, 0x86, 0x75, 0xdc, 0x7e, 0x28, 0xcb, - 0x18, 0x3a, 0x55, 0x87, 0xa8, 0xf9, 0xa8, 0xae, - 0xf9, 0x48, 0x36, 0x57, 0x6c, 0x20, 0x9a, 0x89, - 0x0e, 0x03, 0x1f, 0x78, 0x6c, 0x59, 0x52, 0x0c, - 0x45, 0xbb, 0x43, 0x86, 0x83, 0x6c, 0xee, 0x2b, - 0xfe, 0xcc, 0x7f, 0xec, 0xab, 0x3f, 0xe4, 0x01, - 0xf3, 0xde, 0x85, 0x35, 0x6a, 0x84, 0x35, 0xb2, - 0x61, 0x8d, 0x6c, 0x58, 0x23, 0x17, 0x56, 0x25, - 0xd4, 0x85, 0x3b, 0xec, 0xc9, 0xc6, 0x3d, 0x4d, - 0x94, 0x72, 0x1c, 0xb2, 0xa2, 0x11, 0x1e, 0x57, - 0x16, 0x59, 0x4a, 0x48, 0x07, 0xc2, 0xea, 0x15, - 0x3b, 0x35, 0x22, 0x0d, 0x2e, 0x20, 0x17, 0x1a, - 0x9f, 0x4b, 0x9d, 0xf1, 0xc0, 0xaa, 0x3c, 0x9a, - 0x16, 0x1d, 0x78, 0xde, 0x2b, 0x2d, 0x34, 0x28, - 0xd7, 0xef, 0xac, 0xa2, 0xa9, 0x4d, 0xad, 0xde, - 0x9d, 0x5f, 0x6c, 0xd1, 0xea, 0xe2, 0xdd, 0x79, - 0xd7, 0x32, 0xcb, 0x19, 0x9a, 0xb4, 0x85, 0x10, - 0xac, 0x84, 0x35, 0x47, 0xb5, 0xbc, 0x23, 0x87, - 0x80, 0xc5, 0x58, 0xe9, 0xb7, 0xb9, 0xfe, 0xcd, - 0x47, 0x4e, 0x70, 0xa0, 0xeb, 0xa6, 0xc3, 0x70, - 0x1e, 0x61, 0x89, 0x7a, 0xf9, 0x69, 0x1f, 0x9f, - 0x70, 0x31, 0xac, 0x1a, 0xb2, 0xd7, 0x16, 0x10, - 0x49, 0xee, 0xd6, 0x8c, 0x20, 0xd2, 0x8a, 0xd3, - 0xec, 0x55, 0x77, 0x84, 0x62, 0x35, 0x0a, 0x82, - 0xd9, 0x75, 0x66, 0xf2, 0xb9, 0xce, 0x15, 0x7a, - 0x00, 0xd4, 0x0c, 0x97, 0x77, 0x6f, 0x4f, 0x5c, - 0xfe, 0xa4, 0x7b, 0x6c, 0x43, 0x84, 0x07, 0x8d, - 0x00, 0xb1, 0xb7, 0x9e, 0xd8, 0xe6, 0x51, 0x83, - 0x24, 0x42, 0x47, 0x26, 0x87, 0x6f, 0x29, 0xcc, - 0x7b, 0xa6, 0xcf, 0x9e, 0x9a, 0x4a, 0x49, 0x73, - 0x3d, 0xf5, 0xcb, 0xcd, 0x08, 0x2a, 0x78, 0x12, - 0x14, 0x72, 0xe1, 0x5f, 0xbf, 0x82, 0x56, 0x95, - 0x52, 0xa7, 0xc7, 0x0d, 0x01, 0x2a, 0xca, 0x32, - 0xdd, 0x10, 0xa0, 0xe2, 0x3c, 0x3e, 0xc0, 0x6f, - 0xb4, 0xd5, 0xa8, 0x24, 0x9d, 0x68, 0xff, 0x2d, - 0xee, 0x30, 0x13, 0x00, 0xa6, 0x78, 0x9f, 0x9f, - 0xa6, 0x31, 0xf2, 0xf0, 0x9c, 0x83, 0xeb, 0xb0, - 0x9c, 0xef, 0x84, 0xb0, 0xf6, 0x6c, 0xc9, 0xa8, - 0xd4, 0x6a, 0x16, 0x7a, 0x74, 0x84, 0x55, 0x1b, - 0xda, 0x49, 0x42, 0xd6, 0xdc, 0xb8, 0x38, 0x46, - 0x5a, 0x52, 0x1e, 0x03, 0xab, 0xda, 0xa1, 0x0e, - 0x77, 0xa4, 0x92, 0xc3, 0x79, 0x91, 0xae, 0x72, - 0x3e, 0xd4, 0xa9, 0x00, 0x38, 0x1e, 0xe1, 0x1c, - 0x28, 0x99, 0x63, 0x68, 0xa5, 0xaa, 0xd0, 0xd8, - 0xd2, 0x93, 0xe9, 0xc7, 0x81, 0x42, 0x25, 0xf3, - 0xa8, 0x0b, 0x64, 0xc9, 0x12, 0x75, 0xa1, 0x50, - 0x6f, 0x80, 0x37, 0x05, 0xa1, 0x21, 0xf3, 0xd0, - 0xb2, 0x86, 0x85, 0xd7, 0xe0, 0x34, 0x56, 0x5a, - 0x59, 0xd3, 0x50, 0x57, 0x51, 0x31, 0x5d, 0x54, - 0x26, 0x8c, 0xed, 0xcb, 0x13, 0x0e, 0x16, 0x6d, - 0xfa, 0x94, 0x4b, 0xd1, 0x95, 0x63, 0x88, 0x9c, - 0xe3, 0x9a, 0x2b, 0x0c, 0x1e, 0x7f, 0x32, 0x11, - 0x22, 0x97, 0x85, 0x4f, 0xf1, 0xe3, 0xd8, 0xf3, - 0x43, 0x10, 0x55, 0x62, 0x2f, 0x09, 0x9b, 0x9a, - 0xc0, 0x26, 0x23, 0x09, 0xcc, 0x94, 0x63, 0xae, - 0x92, 0x24, 0x9e, 0x8b, 0x95, 0x99, 0xa7, 0xf5, - 0x60, 0x2b, 0xe6, 0xd2, 0x5b, 0x55, 0xeb, 0x1c, - 0xeb, 0x4b, 0x10, 0x35, 0x26, 0xb4, 0xaa, 0x01, - 0xad, 0xb4, 0x79, 0xb6, 0x0e, 0x46, 0xb8, 0x73, - 0x97, 0xbc, 0xed, 0x3d, 0xb5, 0x7d, 0x91, 0xcc, - 0x4e, 0xc8, 0x17, 0x69, 0xb5, 0xd0, 0xee, 0x30, - 0xa7, 0x11, 0x7a, 0x05, 0xed, 0x56, 0x30, 0x23, - 0xb6, 0x07, 0xd6, 0x81, 0x40, 0x9b, 0x4c, 0xbf, - 0xd4, 0x5f, 0xda, 0x04, 0x2e, 0x03, 0x0f, 0x27, - 0x40, 0xc1, 0x64, 0x8d, 0xee, 0x97, 0x98, 0xd5, - 0x6f, 0xe3, 0x37, 0xae, 0x12, 0x4d, 0xcb, 0xa2, - 0x64, 0x90, 0x2f, 0x1a, 0x78, 0x93, 0xf8, 0xcb, - 0x5f, 0xc4, 0x17, 0xcd, 0x1c, 0xc9, 0x16, 0x56, - 0x24, 0x8e, 0x78, 0x06, 0x30, 0xc2, 0xbf, 0x0d, - 0xdf, 0xf4, 0x24, 0xee, 0xbf, 0x8d, 0xde, 0xf4, - 0x34, 0xa3, 0xa2, 0x98, 0xe3, 0xa3, 0xc7, 0xea, - 0xd8, 0x7d, 0x2f, 0x70, 0xfa, 0x09, 0x8b, 0x1b, - 0x43, 0x42, 0x23, 0xd0, 0xd8, 0x55, 0xdb, 0x80, - 0xaf, 0xd4, 0x95, 0x64, 0x8a, 0x36, 0xfc, 0xf6, - 0x36, 0x75, 0xee, 0x9d, 0xd7, 0x14, 0xc0, 0xbf, - 0x8d, 0x0e, 0x6a, 0x2f, 0xb9, 0xe1, 0x9e, 0xc0, - 0x32, 0x17, 0xa9, 0xe1, 0x9e, 0x00, 0xc9, 0x05, - 0x3d, 0xd8, 0x68, 0x0d, 0xf6, 0x34, 0xa4, 0xc0, - 0x78, 0x0a, 0x52, 0x45, 0x75, 0x91, 0x99, 0x26, - 0x9a, 0x1f, 0x06, 0xec, 0x86, 0xac, 0x74, 0xa3, - 0xa0, 0x32, 0xeb, 0x24, 0x2c, 0xdd, 0x6d, 0x2f, - 0xbe, 0x32, 0x12, 0x6b, 0x23, 0x4a, 0xfb, 0x6d, - 0xec, 0x5e, 0x3c, 0xd7, 0x10, 0xda, 0x5a, 0xed, - 0x37, 0xc3, 0xaf, 0xce, 0x8e, 0xe5, 0x55, 0xd1, - 0x98, 0xb3, 0x49, 0x4a, 0xf7, 0x85, 0xff, 0x63, - 0xfb, 0x0b, 0xfb, 0xff, 0xdc, 0x91, 0xf6, 0x4a, - 0xed, 0x60, 0x15, 0x60, 0xfe, 0x5e, 0x67, 0xe1, - 0x19, 0xcd, 0x1d, 0x86, 0xe1, 0xe2, 0xb2, 0x06, - 0x22, 0x09, 0xbd, 0xac, 0x3f, 0x8b, 0xc2, 0x58, - 0xdd, 0x57, 0xc8, 0xd9, 0x72, 0x88, 0x4e, 0xae, - 0x60, 0x1f, 0xdb, 0x21, 0x89, 0xe1, 0xc1, 0xac, - 0x35, 0x14, 0xf5, 0xbf, 0x43, 0x63, 0xdb, 0x22, - 0x5a, 0x01, 0x59, 0xbc, 0x82, 0xb7, 0xb3, 0x6d, - 0x67, 0x20, 0x4b, 0x9e, 0x4a, 0x87, 0x93, 0x66, - 0xcb, 0xe2, 0x2b, 0xfe, 0x1a, 0x88, 0xfd, 0x90, - 0x1c, 0xd8, 0x92, 0xe7, 0x56, 0x78, 0x04, 0xaf, - 0x35, 0x1d, 0x97, 0x6c, 0xf4, 0x18, 0xaa, 0xad, - 0xc1, 0xdb, 0xcf, 0x39, 0x48, 0x6d, 0x62, 0xdf, - 0x9a, 0x70, 0x34, 0x6d, 0x33, 0x97, 0x7b, 0xbd, - 0x15, 0x85, 0xc3, 0x02, 0x10, 0x87, 0x06, 0x1d, - 0x65, 0xd8, 0xd5, 0xe4, 0x6e, 0xc3, 0x03, 0x26, - 0x58, 0x25, 0x6a, 0x72, 0xd8, 0xd5, 0x13, 0xba, - 0xfe, 0xcc, 0xd7, 0xae, 0xd8, 0xd7, 0x35, 0x1f, - 0xd7, 0xbe, 0xd9, 0x58, 0x5d, 0x57, 0x67, 0x8c, - 0xea, 0xa1, 0x77, 0xd0, 0xb5, 0xd5, 0x17, 0x78, - 0x2f, 0x83, 0x08, 0xdb, 0x96, 0x2d, 0x7a, 0x02, - 0x7d, 0x64, 0xf8, 0x52, 0x59, 0x05, 0xdf, 0x57, - 0x57, 0x82, 0xb8, 0xf4, 0x04, 0x6b, 0xdb, 0x9f, - 0x70, 0xf5, 0x5a, 0x87, 0x7b, 0x3f, 0x2a, 0xf7, - 0x5b, 0xb3, 0xf9, 0x19, 0xc2, 0x94, 0x0e, 0x1f, - 0xaa, 0x69, 0xbc, 0x15, 0x04, 0xf4, 0x36, 0x0b, - 0xf5, 0x4c, 0x2d, 0xc5, 0x09, 0x3b, 0xa1, 0x35, - 0xc4, 0x9e, 0x8a, 0xdb, 0xd0, 0x58, 0xf6, 0xaa, - 0xbf, 0x42, 0xbb, 0x06, 0x57, 0x35, 0x1f, 0x88, - 0x75, 0x72, 0x87, 0xb5, 0xe8, 0x76, 0x6b, 0x58, - 0x8b, 0xba, 0xca, 0xbc, 0x8e, 0x6d, 0xae, 0x24, - 0xa1, 0x68, 0xff, 0x75, 0x09, 0x8e, 0x4d, 0x10, - 0xf4, 0x68, 0x03, 0x53, 0x51, 0x1e, 0x2f, 0xda, - 0x4b, 0xd5, 0xa1, 0x0c, 0xfa, 0x1f, 0x97, 0xb0, - 0xd7, 0x1b, 0xab, 0x5b, 0x35, 0x3b, 0x9f, 0xe9, - 0xc3, 0x19, 0xff, 0xdd, 0xb7, 0xe5, 0x1a, 0x4d, - 0x68, 0xb6, 0xec, 0x62, 0x84, 0x0f, 0xf9, 0xa0, - 0xe3, 0x2a, 0x06, 0x8e, 0xc7, 0xda, 0x92, 0x3c, - 0xe1, 0x3b, 0xbb, 0x19, 0x9c, 0x9a, 0x64, 0x13, - 0xc0, 0x4a, 0xdf, 0x8e, 0x84, 0x0a, 0x3b, 0xbc, - 0x5f, 0x12, 0x59, 0x19, 0xcd, 0x12, 0x12, 0x4b, - 0xef, 0xbc, 0x43, 0x63, 0x41, 0x23, 0xfc, 0x08, - 0x7f, 0x71, 0xc0, 0xc3, 0xf1, 0xf8, 0xc8, 0xee, - 0xbe, 0xeb, 0xde, 0xbc, 0xb5, 0x8d, 0x4f, 0xd2, - 0x28, 0x72, 0xfc, 0xd1, 0xea, 0xcf, 0x5c, 0x5f, - 0x5e, 0xbc, 0xc1, 0x3b, 0x9c, 0xb6, 0xbc, 0x2f, - 0x9d, 0x1c, 0xea, 0xa3, 0xbd, 0x0a, 0x3a, 0x35, - 0xca, 0xab, 0x6d, 0x5a, 0x92, 0xbf, 0x4b, 0xcf, - 0x43, 0x57, 0x5d, 0x1f, 0xfa, 0xcc, 0xf5, 0x61, - 0x69, 0x30, 0xe1, 0x03, 0x74, 0xa6, 0x24, 0x5b, - 0x5c, 0x57, 0x8a, 0x5f, 0x0b, 0xd4, 0x4d, 0xbf, - 0xe2, 0x62, 0x45, 0xde, 0x2d, 0x80, 0x0f, 0xe7, - 0xa1, 0x2e, 0xad, 0xae, 0x34, 0x4f, 0x34, 0x09, - 0xff, 0x2f, 0xce, 0x60, 0x2f, 0x02, 0x70, 0xef, - 0xfb, 0x08, 0x85, 0x2e, 0xbd, 0x60, 0xc6, 0x42, - 0x25, 0xac, 0xe5, 0x4a, 0xfa, 0x44, 0xf5, 0x14, - 0x8e, 0x76, 0xcf, 0x8f, 0xc3, 0x40, 0xb7, 0xca, - 0xd3, 0x75, 0x36, 0x35, 0x0a, 0x2f, 0x34, 0xde, - 0x80, 0xaa, 0x1c, 0x25, 0x88, 0x42, 0x7c, 0x01, - 0xff, 0x51, 0xd6, 0x6c, 0xbc, 0x28, 0xc9, 0x07, - 0xdc, 0x73, 0x42, 0x8d, 0x9f, 0x02, 0x6e, 0x65, - 0x04, 0x44, 0x88, 0xaf, 0xe8, 0xda, 0x22, 0xf9, - 0x04, 0xf0, 0x06, 0xe2, 0x3a, 0x23, 0xd3, 0xa4, - 0x94, 0x23, 0x2d, 0x14, 0xcb, 0x0a, 0x77, 0xfe, - 0x1c, 0xdf, 0xfd, 0x46, 0x24, 0x42, 0xd0, 0x3a, - 0x74, 0x6f, 0xf3, 0x7f, 0x40, 0x70, 0x38, 0x05, - 0x95, 0xbd, 0xa7, 0x40, 0x74, 0x7b, 0xd8, 0x4e, - 0x58, 0xed, 0xe8, 0x2a, 0x67, 0xb5, 0x9d, 0x78, - 0xb3, 0x33, 0x3e, 0x28, 0xe3, 0x43, 0xa3, 0xfb, - 0x3f, 0x8a, 0xe3, 0xb6, 0xab, 0x32, 0xe6, 0x7d, - 0xcb, 0x7d, 0x19, 0xd3, 0xa8, 0xf6, 0xd2, 0x8c, - 0xfd, 0xba, 0x25, 0xb6, 0xc3, 0x6d, 0xd6, 0x1a, - 0xb4, 0xb0, 0xf0, 0xe2, 0xb4, 0x0d, 0x6b, 0xf3, - 0xbe, 0x05, 0x6b, 0xd3, 0xa8, 0x16, 0x6b, 0xfb, - 0x75, 0x0b, 0xd6, 0x6e, 0xb3, 0xcf, 0xe0, 0x76, - 0x0d, 0x0d, 0xa8, 0xe5, 0x7a, 0x86, 0x79, 0xdf, - 0x8c, 0xab, 0x69, 0x53, 0x8b, 0xae, 0xfd, 0xba, - 0x05, 0x63, 0xb7, 0xd9, 0xe5, 0x48, 0x37, 0x5f, - 0xaa, 0xd2, 0xaf, 0x2f, 0x41, 0xb9, 0xf1, 0x7a, - 0x95, 0xf5, 0xf6, 0x32, 0x84, 0x4b, 0x31, 0x44, - 0xf7, 0xcf, 0x40, 0x75, 0x47, 0x66, 0xc5, 0x2b, - 0x9b, 0x39, 0xeb, 0xed, 0x90, 0xdb, 0x5a, 0xd3, - 0xf0, 0x74, 0x76, 0xbd, 0x80, 0x07, 0xf2, 0xe9, - 0xe8, 0x2a, 0x76, 0x34, 0x8b, 0x1f, 0x92, 0x7c, - 0xaa, 0xff, 0xac, 0xbd, 0xde, 0x63, 0x5e, 0xf7, - 0x4a, 0xbc, 0xb2, 0xe9, 0xa2, 0x8f, 0x0b, 0xb0, - 0x96, 0xe7, 0xb5, 0x60, 0x67, 0xf1, 0x3d, 0x82, - 0xab, 0xff, 0xac, 0xc5, 0xce, 0xbc, 0xee, 0x95, - 0x78, 0x62, 0x13, 0x76, 0x2e, 0xc0, 0x5a, 0xde, - 0xf6, 0x89, 0x5c, 0x0b, 0xb2, 0xb8, 0x98, 0x9e, - 0xa9, 0xe6, 0xfb, 0x25, 0xe6, 0x75, 0xaf, 0xc4, - 0xe1, 0x9a, 0xf0, 0x72, 0x01, 0xd6, 0xb2, 0xaa, - 0xcb, 0xb0, 0xd3, 0xf1, 0x6a, 0xfa, 0xaf, 0x66, - 0xdc, 0xd4, 0x4d, 0x2e, 0x8b, 0x91, 0xb5, 0x62, - 0xa6, 0xe3, 0xde, 0xea, 0x58, 0xd2, 0x27, 0x6a, - 0xb9, 0x2d, 0x1b, 0x6e, 0x77, 0x96, 0xdb, 0x3f, - 0x9c, 0xe5, 0xf6, 0x95, 0xcc, 0xef, 0x82, 0xa7, - 0x25, 0x0a, 0xbd, 0xd2, 0xc0, 0x28, 0xf0, 0x70, - 0x93, 0x01, 0x11, 0x20, 0xff, 0xc7, 0xde, 0x45, - 0xba, 0xa6, 0x1b, 0x1e, 0x41, 0xaa, 0x42, 0x18, - 0xb9, 0x5d, 0x0e, 0x9b, 0xcb, 0x64, 0x63, 0xe7, - 0x04, 0x02, 0x4b, 0xef, 0x6d, 0x98, 0x33, 0x48, - 0x1d, 0x3c, 0xa4, 0x71, 0x51, 0xb9, 0x02, 0xb2, - 0x30, 0xe6, 0x7b, 0x46, 0x20, 0xdb, 0x63, 0x34, - 0xff, 0x2a, 0xcd, 0x0a, 0x86, 0x66, 0x5f, 0x13, - 0x99, 0xa6, 0x6b, 0x3c, 0xdb, 0xbc, 0x69, 0x81, - 0x01, 0x19, 0x32, 0x1d, 0x0d, 0x46, 0xe4, 0xcf, - 0x66, 0x30, 0x1c, 0xbc, 0x3d, 0xb2, 0x5c, 0xc7, - 0x45, 0xb4, 0x8a, 0xe9, 0x88, 0x92, 0x77, 0x62, - 0xec, 0xe0, 0x78, 0x3a, 0x42, 0x07, 0x0d, 0xa3, - 0xc5, 0x54, 0x31, 0xf5, 0x03, 0xa6, 0x4c, 0x32, - 0x7a, 0xd8, 0x49, 0x09, 0xc3, 0xab, 0x8c, 0x37, - 0xf6, 0xb2, 0x79, 0x69, 0xb8, 0xf8, 0x5e, 0x92, - 0x12, 0xe8, 0x2a, 0x74, 0x47, 0xc5, 0x0a, 0xc6, - 0x5c, 0x0e, 0xb6, 0x1b, 0x78, 0x10, 0x9d, 0x45, - 0xc1, 0xe5, 0xa3, 0xfe, 0x63, 0x18, 0xdd, 0xb7, - 0x31, 0xb8, 0xdf, 0xbc, 0xb1, 0xfd, 0x13, 0x32, - 0xb4, 0x33, 0x4b, 0x91, 0x34, 0x4a, 0xb4, 0xfe, - 0x50, 0x01, 0xea, 0x7b, 0x71, 0x34, 0x4f, 0xf0, - 0xb4, 0x78, 0x8e, 0xc4, 0xff, 0x90, 0x22, 0xeb, - 0x60, 0x45, 0xa2, 0x77, 0x80, 0xad, 0x17, 0x73, - 0x6b, 0x20, 0x55, 0x1c, 0x16, 0x91, 0x2f, 0x86, - 0xd9, 0xd1, 0xed, 0x15, 0xbb, 0x83, 0x9f, 0x53, - 0x90, 0xc4, 0xe6, 0xa8, 0x21, 0xe3, 0x96, 0x21, - 0x5a, 0xe5, 0xb3, 0x07, 0x27, 0x52, 0x71, 0x1f, - 0xb9, 0x7d, 0x68, 0x7b, 0x65, 0xde, 0x06, 0x53, - 0x87, 0x2c, 0x70, 0x57, 0x59, 0xbd, 0xa9, 0x50, - 0x64, 0xec, 0xc5, 0x86, 0x2f, 0xbf, 0x94, 0xa0, - 0x44, 0x54, 0xf0, 0x15, 0xca, 0x65, 0xe8, 0x51, - 0xea, 0x27, 0xc0, 0xa6, 0xb1, 0xbf, 0xc1, 0xce, - 0x89, 0xb0, 0x73, 0x22, 0x7c, 0x76, 0x4e, 0x04, - 0xc3, 0x55, 0xdc, 0x1b, 0x63, 0xce, 0x65, 0x33, - 0x5b, 0xa6, 0xfc, 0x24, 0xdc, 0x0d, 0xea, 0x22, - 0xaf, 0x36, 0xf6, 0x05, 0x37, 0xe0, 0x7f, 0x90, - 0x8e, 0x0c, 0x52, 0x68, 0xd5, 0x05, 0x31, 0xbc, - 0x1b, 0x7b, 0x4e, 0xe9, 0xb9, 0x4c, 0x4e, 0x32, - 0x56, 0x6e, 0x55, 0x2c, 0x9b, 0x35, 0xad, 0x3d, - 0xc1, 0xe9, 0xc0, 0x1a, 0xf1, 0x62, 0x27, 0x87, - 0xca, 0x71, 0x74, 0xfa, 0xcd, 0xb7, 0x93, 0xd7, - 0xff, 0x14, 0x4f, 0xad, 0xf4, 0x51, 0x2f, 0xbf, - 0xf9, 0xee, 0xe5, 0xe4, 0xbb, 0x17, 0x7f, 0xff, - 0xfb, 0x0b, 0x98, 0x8c, 0xd1, 0xf0, 0x68, 0xbf, - 0x7a, 0xff, 0xa1, 0xce, 0xfc, 0x80, 0xca, 0xc6, - 0xf1, 0x16, 0x96, 0xc6, 0xbb, 0xb6, 0x11, 0xde, - 0xa9, 0x75, 0xef, 0xee, 0xcc, 0x73, 0x77, 0x6c, - 0x59, 0xbb, 0x15, 0xb3, 0x58, 0xad, 0x87, 0xad, - 0xde, 0x84, 0xe4, 0xdc, 0xb5, 0x69, 0xb2, 0x7d, - 0xdd, 0x84, 0x59, 0xe8, 0x52, 0xab, 0xd0, 0xf5, - 0xec, 0x39, 0x97, 0x9b, 0x73, 0xae, 0x65, 0x88, - 0xb9, 0xed, 0x3b, 0x6c, 0x25, 0x4b, 0xca, 0xf5, - 0x6c, 0x20, 0x97, 0x99, 0x40, 0xae, 0x67, 0xbf, - 0xe0, 0x33, 0x42, 0x2e, 0xb2, 0x36, 0x3b, 0xd4, - 0x1d, 0x33, 0x72, 0xc9, 0x07, 0xe7, 0x65, 0x33, - 0x82, 0xf5, 0xee, 0xa2, 0x72, 0x46, 0x98, 0x19, - 0x93, 0x6d, 0xca, 0x11, 0x64, 0x57, 0x96, 0x90, - 0x95, 0xc5, 0xd9, 0x44, 0xa9, 0xdb, 0x14, 0x53, - 0x96, 0x4d, 0xf8, 0x36, 0xd4, 0x89, 0xcd, 0x8e, - 0xf7, 0x45, 0xc7, 0x74, 0xba, 0xe7, 0xee, 0x0a, - 0x79, 0x30, 0xd8, 0xd7, 0x1f, 0xd7, 0xb3, 0x19, - 0x46, 0x63, 0x93, 0x19, 0x01, 0x64, 0x29, 0xce, - 0x2d, 0xe2, 0x98, 0x15, 0xb4, 0xe9, 0x02, 0x67, - 0xba, 0x12, 0x79, 0x0f, 0x1f, 0xdb, 0xb4, 0xa7, - 0xde, 0x29, 0xc4, 0x3a, 0x66, 0xb1, 0xf6, 0xe0, - 0xa0, 0x1f, 0x3d, 0x03, 0xd8, 0xf2, 0x38, 0x79, - 0x64, 0x61, 0xdd, 0xdd, 0x06, 0x6d, 0xca, 0x64, - 0x24, 0xf1, 0x65, 0x6c, 0x2d, 0xfa, 0xda, 0xb7, - 0xe4, 0x0a, 0xdd, 0x87, 0x23, 0x15, 0x5a, 0xa3, - 0x96, 0xf7, 0xd5, 0x6a, 0x5d, 0xcd, 0xe8, 0x68, - 0x56, 0x77, 0x06, 0x2a, 0x53, 0x3d, 0x91, 0xf5, - 0xd9, 0x4e, 0xe4, 0x00, 0xf7, 0x44, 0xe5, 0x7e, - 0x9f, 0x23, 0x3a, 0x4a, 0x07, 0xb8, 0x75, 0xd3, - 0x8d, 0x06, 0xd0, 0x77, 0xa0, 0xf5, 0x78, 0x54, - 0x8f, 0x4a, 0x0f, 0xaf, 0x71, 0xa5, 0x0d, 0xa5, - 0x2b, 0xf7, 0x14, 0xbf, 0x01, 0x47, 0xf9, 0xff, - 0x03, 0xf5, 0xc1, 0x10, 0x7e + 0x78, 0xda, 0xed, 0x7d, 0x6b, 0x73, 0x1b, 0x37, + 0xb2, 0xe8, 0x7e, 0xd6, 0xaf, 0x40, 0x36, 0x55, + 0x6b, 0x52, 0x1e, 0x52, 0x24, 0x25, 0xf9, 0xa5, + 0xf5, 0x49, 0xf9, 0x24, 0x4a, 0x8e, 0xee, 0xcd, + 0x26, 0xae, 0xc8, 0x49, 0xb6, 0xd6, 0xe5, 0x65, + 0xcd, 0x90, 0x43, 0x72, 0xd6, 0xc3, 0x19, 0x66, + 0x66, 0x28, 0x8a, 0x3e, 0x37, 0xff, 0xfd, 0x76, + 0x37, 0xde, 0x98, 0x07, 0x29, 0x59, 0x2f, 0xdb, + 0xdc, 0x5a, 0xc5, 0xd2, 0x00, 0x68, 0x34, 0x80, + 0x46, 0xa3, 0xbb, 0xd1, 0xe8, 0xfe, 0x3a, 0x9a, + 0x8c, 0xc3, 0x09, 0xfb, 0xe1, 0xc7, 0xe1, 0xe9, + 0xf9, 0xde, 0x22, 0x0b, 0x47, 0x51, 0x1e, 0xa5, + 0x09, 0x9b, 0x45, 0xd3, 0xd9, 0x82, 0x4d, 0xe2, + 0xd4, 0x2f, 0x4e, 0xf6, 0xbe, 0x0e, 0xe3, 0x3c, + 0xdc, 0xdb, 0xfb, 0x3a, 0x9a, 0xb0, 0xaf, 0xa0, + 0x72, 0x94, 0x84, 0xe3, 0x56, 0x9c, 0xae, 0x16, + 0xed, 0xbd, 0xaf, 0xf9, 0x9f, 0x0c, 0xff, 0x82, + 0x6a, 0xc9, 0x38, 0x9a, 0x38, 0xf5, 0xe6, 0xe1, + 0x38, 0x5a, 0xce, 0x8d, 0xaa, 0xe2, 0x43, 0x75, + 0x6d, 0xea, 0x56, 0xd7, 0xa5, 0x3f, 0x75, 0x4d, + 0xf1, 0xef, 0xc1, 0x01, 0xfb, 0x35, 0x59, 0xf8, + 0xa3, 0xf7, 0xcc, 0x67, 0x0b, 0x3f, 0xca, 0x58, + 0x3a, 0x61, 0x17, 0x7e, 0xbc, 0x0c, 0x73, 0x56, + 0xcc, 0xfc, 0x82, 0xcd, 0xfc, 0x8b, 0x90, 0x05, + 0x61, 0x98, 0x30, 0xac, 0x14, 0x8e, 0x59, 0x94, + 0x14, 0x29, 0xd4, 0xcd, 0xa3, 0x64, 0x1a, 0x87, + 0x7c, 0x50, 0x5d, 0x84, 0xf2, 0x66, 0x16, 0xca, + 0x2a, 0xa2, 0xbd, 0x9f, 0x85, 0xcc, 0xcf, 0xf3, + 0x25, 0x20, 0xc9, 0xa0, 0x4d, 0x10, 0xb2, 0x67, + 0x9d, 0x20, 0x2a, 0xd8, 0x32, 0xc9, 0xa3, 0x69, + 0xc2, 0x41, 0x85, 0xd3, 0x30, 0xcb, 0x3d, 0xe6, + 0x27, 0x63, 0xac, 0x8e, 0x70, 0x04, 0x8c, 0x38, + 0x7a, 0x1f, 0xb2, 0x3c, 0x7d, 0xa1, 0x3f, 0xfd, + 0x86, 0x50, 0xd9, 0x4b, 0xec, 0x32, 0xcd, 0x5a, + 0x51, 0xb2, 0x58, 0x16, 0x6f, 0x7b, 0xef, 0xda, + 0x6c, 0x9f, 0x0d, 0x8e, 0x9f, 0xb0, 0xc7, 0x8c, + 0x7f, 0xe9, 0xbf, 0xf3, 0xf6, 0x2e, 0xc2, 0xd1, + 0x00, 0x7a, 0xc1, 0x66, 0x43, 0x42, 0xb0, 0x35, + 0x4a, 0x93, 0xbc, 0xe0, 0xc8, 0x9a, 0xd0, 0xda, + 0xec, 0x7f, 0xf7, 0x18, 0xfc, 0x0f, 0x10, 0x11, + 0x9f, 0xcf, 0x92, 0x42, 0xf6, 0x03, 0x1f, 0x5b, + 0x66, 0xdd, 0x13, 0x55, 0xf5, 0xa2, 0x07, 0xc5, + 0x4e, 0xfd, 0x03, 0xc4, 0x82, 0x57, 0xc9, 0xc2, + 0x62, 0x99, 0x25, 0x0c, 0xb1, 0x68, 0x5d, 0xf4, + 0x3c, 0xb7, 0x66, 0x07, 0xdb, 0x13, 0xd2, 0x00, + 0xf2, 0xcf, 0x3d, 0x0b, 0xdb, 0x14, 0xfe, 0x1b, + 0x15, 0xeb, 0x0a, 0x7c, 0x7f, 0xe6, 0x25, 0x26, + 0xc6, 0xf0, 0x23, 0xbe, 0x5a, 0xd8, 0xaa, 0x9a, + 0x80, 0x52, 0x19, 0x21, 0x3e, 0x1f, 0xba, 0x29, + 0x56, 0xeb, 0x0f, 0x9e, 0x76, 0x01, 0xcf, 0x79, + 0x3a, 0xb6, 0x41, 0x78, 0x6c, 0xd0, 0xed, 0xb5, + 0x39, 0x96, 0xb8, 0xc2, 0x29, 0x9b, 0x47, 0x49, + 0x34, 0x8f, 0x3e, 0x84, 0x40, 0x1b, 0x21, 0x4b, + 0x96, 0xf3, 0x20, 0x24, 0x82, 0xf1, 0x8b, 0x22, + 0x8b, 0x82, 0x65, 0x01, 0x8b, 0x9e, 0x84, 0xe1, + 0x38, 0x1c, 0x7b, 0x6c, 0x15, 0xb2, 0x30, 0x19, + 0xa5, 0x63, 0x20, 0x01, 0x76, 0xd4, 0x19, 0xa5, + 0xf3, 0x45, 0x9a, 0x84, 0x49, 0x81, 0x70, 0x46, + 0x69, 0x9c, 0x66, 0x92, 0x8e, 0x24, 0xcd, 0x11, + 0x5e, 0x39, 0x6b, 0x45, 0xdd, 0xb0, 0x0b, 0x9f, + 0x11, 0xd7, 0x36, 0x50, 0x0f, 0x9b, 0xa4, 0x31, + 0xec, 0x87, 0x9c, 0xe8, 0xe0, 0xad, 0x58, 0x7b, + 0x02, 0xd0, 0xcd, 0x68, 0x12, 0x8f, 0x35, 0x01, + 0xf0, 0xcf, 0x53, 0xfe, 0xd9, 0xc3, 0x06, 0xcc, + 0x6a, 0x10, 0x34, 0x36, 0x60, 0xef, 0x70, 0x25, + 0x8e, 0xd8, 0x38, 0x44, 0xac, 0x87, 0x54, 0x26, + 0xd6, 0x81, 0x56, 0x88, 0x8f, 0x66, 0xfc, 0x2d, + 0x7e, 0x97, 0xab, 0xa0, 0x27, 0xf6, 0xa8, 0x45, + 0x1f, 0xf0, 0x7f, 0x16, 0xe1, 0x99, 0xad, 0x88, + 0x5a, 0x91, 0x4e, 0x8e, 0x61, 0xb6, 0xb7, 0xa8, + 0xde, 0xd7, 0xd5, 0xa9, 0xb6, 0x5a, 0x88, 0xd2, + 0x86, 0x85, 0x7f, 0x91, 0x2c, 0xc5, 0xb6, 0x4b, + 0xf8, 0xce, 0xca, 0x16, 0x69, 0xec, 0x17, 0xb8, + 0x79, 0x8b, 0x15, 0xee, 0x5f, 0x58, 0xb2, 0x79, + 0x77, 0x8f, 0xd3, 0x94, 0xe8, 0x74, 0x1e, 0x5d, + 0x0e, 0x89, 0x2a, 0x8c, 0x71, 0x1a, 0x24, 0xef, + 0x31, 0x93, 0x0e, 0x0b, 0x67, 0xd4, 0xd0, 0xd8, + 0xdc, 0x1f, 0x30, 0x3a, 0xcf, 0x6c, 0x8c, 0x3b, + 0x11, 0xda, 0xdc, 0x04, 0xce, 0xb4, 0x2e, 0x06, + 0xca, 0xce, 0xda, 0x1c, 0x89, 0x6e, 0x69, 0xd6, + 0xf2, 0x1a, 0xa4, 0xa9, 0x1e, 0x90, 0x2f, 0x55, + 0x82, 0xfd, 0x62, 0x2d, 0x33, 0xcd, 0x81, 0x09, + 0xc4, 0x18, 0x8c, 0xf8, 0x00, 0x8b, 0x21, 0x38, + 0x00, 0x87, 0xe4, 0x5f, 0x6e, 0x09, 0x69, 0xe0, + 0x42, 0x3a, 0x54, 0x90, 0x8c, 0x89, 0x94, 0x98, + 0x79, 0x0a, 0xb2, 0x39, 0x79, 0xc8, 0x5b, 0xd3, + 0xc9, 0x24, 0x0f, 0x0b, 0xe8, 0x6d, 0x01, 0x9c, + 0x3b, 0x67, 0x78, 0xac, 0xa4, 0x2b, 0xa8, 0x9d, + 0xac, 0xd9, 0x22, 0xba, 0x84, 0x43, 0x85, 0xf8, + 0xad, 0x31, 0x71, 0x6c, 0x95, 0x66, 0xf1, 0x98, + 0xa5, 0x59, 0x34, 0x8d, 0x12, 0x9a, 0x61, 0xfc, + 0x18, 0x8e, 0xa7, 0x08, 0x8b, 0x7e, 0x2f, 0xa2, + 0x38, 0xa4, 0x8d, 0x45, 0x0b, 0x2f, 0x3a, 0x78, + 0xc9, 0xf9, 0x00, 0x82, 0x84, 0x31, 0xa5, 0x19, + 0xec, 0xe5, 0x1c, 0x76, 0x7c, 0x1b, 0xea, 0x61, + 0xd5, 0x57, 0x05, 0x1d, 0x24, 0xec, 0x43, 0x9a, + 0xce, 0x59, 0x1c, 0x5e, 0x60, 0xc7, 0x00, 0x0b, + 0x59, 0x3d, 0xfe, 0x00, 0xa3, 0x4f, 0x68, 0x75, + 0x39, 0x4a, 0x57, 0x46, 0x47, 0x1d, 0x25, 0xd3, + 0x38, 0x8f, 0x59, 0xbe, 0x08, 0x47, 0x30, 0xd2, + 0x78, 0xcd, 0xa6, 0x4b, 0x3f, 0xf3, 0x81, 0x40, + 0x80, 0x56, 0xfa, 0x4f, 0x18, 0x9c, 0x22, 0x39, + 0xf5, 0xa2, 0x8e, 0xd8, 0x09, 0x2c, 0x85, 0x71, + 0xcc, 0xe6, 0x5d, 0xf6, 0x7b, 0x48, 0xbc, 0x08, + 0x46, 0x93, 0x21, 0xbb, 0xf2, 0x13, 0x3a, 0xcf, + 0xba, 0x62, 0x18, 0x74, 0x5a, 0xe9, 0x31, 0xb2, + 0x28, 0x87, 0x45, 0xca, 0x73, 0x3a, 0x94, 0x90, + 0xed, 0x14, 0xab, 0x54, 0x74, 0x24, 0x48, 0x94, + 0x1f, 0x44, 0xba, 0xc5, 0x70, 0xb9, 0x58, 0x84, + 0x99, 0x3a, 0x8e, 0x4c, 0x58, 0xb0, 0x67, 0xff, + 0xdd, 0x7f, 0xd2, 0x76, 0x1b, 0x00, 0x1b, 0xa3, + 0x06, 0xa5, 0xe9, 0x95, 0xb5, 0x9d, 0x95, 0x06, + 0x94, 0x46, 0x7e, 0x3c, 0x5a, 0xe2, 0x86, 0xe0, + 0x68, 0xb1, 0x3c, 0xcc, 0xa2, 0x90, 0x46, 0x9e, + 0x17, 0xe1, 0x42, 0x9c, 0xd0, 0xf9, 0x2c, 0x5d, + 0xc2, 0xc4, 0xc2, 0x5c, 0x40, 0xf1, 0x05, 0x8e, + 0x15, 0x07, 0x23, 0x67, 0xe6, 0x05, 0x3f, 0x5f, + 0xa6, 0x61, 0x31, 0x5c, 0x00, 0x9b, 0x0e, 0xb3, + 0x64, 0xb8, 0x48, 0x73, 0x6b, 0xc3, 0xbb, 0x83, + 0x92, 0x3b, 0xa8, 0x54, 0x4a, 0x23, 0xe0, 0x9c, + 0xcb, 0x62, 0x18, 0x1c, 0x2c, 0x52, 0x89, 0xb3, + 0xf9, 0x60, 0x41, 0x87, 0xcb, 0x04, 0x16, 0x6b, + 0x58, 0xa4, 0x43, 0x4e, 0x12, 0x36, 0xf0, 0x34, + 0xc7, 0xfd, 0x29, 0xb7, 0x95, 0x43, 0x83, 0xf2, + 0xa7, 0x02, 0x41, 0xb3, 0x4f, 0xc1, 0xcf, 0xbb, + 0xbd, 0x9a, 0xcf, 0xc0, 0xe8, 0xcb, 0x83, 0xb0, + 0xab, 0x5a, 0xdb, 0xb1, 0x55, 0x85, 0x36, 0x00, + 0x03, 0x64, 0x01, 0x14, 0xc7, 0x10, 0x19, 0xb3, + 0x09, 0x01, 0x37, 0xea, 0x5f, 0xbe, 0xae, 0x96, + 0xfe, 0x84, 0x8c, 0xf6, 0x30, 0xe5, 0xbf, 0xbf, + 0xa8, 0xa3, 0x9b, 0x2f, 0x80, 0x8f, 0xd4, 0x71, + 0xb2, 0xb7, 0x07, 0xc3, 0x87, 0x2d, 0x35, 0x07, + 0xfe, 0x52, 0x00, 0xeb, 0x1d, 0xc2, 0x3f, 0x59, + 0x74, 0x09, 0xdf, 0x2f, 0xd2, 0x08, 0xb6, 0x14, + 0xb0, 0xee, 0x96, 0x64, 0xac, 0xd3, 0x78, 0xf8, + 0x3a, 0xcd, 0xa3, 0x02, 0x87, 0xfa, 0x52, 0x55, + 0x85, 0xf9, 0xa2, 0x53, 0x91, 0xe0, 0x79, 0x0c, + 0xd6, 0xa6, 0x4f, 0xdc, 0xec, 0x2f, 0x12, 0x30, + 0xe7, 0xe9, 0x9c, 0x6b, 0x9e, 0xa8, 0xee, 0xc4, + 0xe9, 0x24, 0xe5, 0xa0, 0xba, 0x0e, 0xbf, 0xcf, + 0xfc, 0xa9, 0x64, 0xbf, 0x02, 0x06, 0x74, 0x68, + 0x36, 0x13, 0x6b, 0xf1, 0xf3, 0x6f, 0xa7, 0xbf, + 0x7c, 0xf7, 0xcb, 0xab, 0xdf, 0x87, 0x67, 0x3f, + 0x9d, 0xbf, 0x3e, 0xfd, 0xf6, 0xcd, 0xcf, 0xbf, + 0x54, 0x81, 0x20, 0x4c, 0xfb, 0x20, 0xea, 0x9c, + 0xc8, 0x69, 0x31, 0x10, 0x75, 0x66, 0xc0, 0xc0, + 0x1f, 0xa4, 0xb6, 0xa1, 0x49, 0x04, 0x43, 0xbf, + 0xb9, 0x38, 0x28, 0x17, 0xbb, 0x94, 0xdd, 0x58, + 0x83, 0x28, 0xb7, 0x3c, 0x57, 0x39, 0x70, 0x09, + 0xab, 0x6f, 0xbb, 0x20, 0x28, 0x17, 0x54, 0x11, + 0x38, 0xcc, 0x59, 0x0d, 0x29, 0x5c, 0xf8, 0xd9, + 0x1a, 0x84, 0x7d, 0xfe, 0xf1, 0x02, 0x3f, 0x62, + 0x67, 0x15, 0x5f, 0x83, 0x8f, 0xa6, 0x0f, 0xce, + 0x08, 0x78, 0x17, 0x50, 0xd9, 0x65, 0x5a, 0x15, + 0x13, 0xe6, 0x55, 0xcd, 0x91, 0xa7, 0x67, 0x85, + 0xc8, 0xc2, 0x5e, 0x24, 0xaf, 0x66, 0x06, 0x3c, + 0x3e, 0x62, 0x79, 0xca, 0xf3, 0x21, 0xdd, 0x08, + 0x16, 0x41, 0x19, 0x8b, 0x60, 0x33, 0x16, 0xf6, + 0x66, 0x31, 0xa9, 0xa9, 0x88, 0x1b, 0x48, 0x2d, + 0xc8, 0x1a, 0x0a, 0xa1, 0x65, 0xd0, 0xd4, 0xb2, + 0x5c, 0x58, 0x84, 0x97, 0x9c, 0xc1, 0xb9, 0x44, + 0x34, 0x37, 0x77, 0x43, 0x79, 0xdf, 0xca, 0x92, + 0xdc, 0x9f, 0x2f, 0xe2, 0x30, 0x1b, 0x7c, 0x07, + 0xa5, 0xd1, 0xdc, 0x9f, 0x86, 0x1f, 0x4f, 0x51, + 0x54, 0x81, 0x60, 0xf1, 0xf3, 0x96, 0x9f, 0x16, + 0x02, 0x0e, 0x10, 0x12, 0x6d, 0x64, 0x55, 0x11, + 0xd9, 0xf6, 0x4b, 0x92, 0xb1, 0xec, 0x09, 0x04, + 0x0e, 0xae, 0x46, 0xe7, 0x39, 0xf3, 0x67, 0x97, + 0xe9, 0xae, 0x4c, 0x09, 0x90, 0xb8, 0x4e, 0x1f, + 0x40, 0x43, 0x3d, 0x38, 0x37, 0xc2, 0xc1, 0x77, + 0x2d, 0x31, 0x42, 0x8f, 0xf1, 0x05, 0xac, 0x42, + 0x96, 0x28, 0x4a, 0xa3, 0x1b, 0x54, 0xa1, 0x3b, + 0xa8, 0xc2, 0x37, 0x68, 0xc0, 0x37, 0xa8, 0xc3, + 0x77, 0x18, 0x94, 0x30, 0x1e, 0xd4, 0x62, 0x3c, + 0x90, 0x28, 0x3b, 0xdc, 0x11, 0x51, 0xe1, 0x83, + 0xf5, 0x04, 0x08, 0x8f, 0x2f, 0x7f, 0xfb, 0xae, + 0x79, 0x6e, 0x90, 0xa6, 0xb1, 0xda, 0x54, 0xab, + 0xa8, 0x98, 0x41, 0x8d, 0x45, 0xa9, 0x78, 0x11, + 0x15, 0xa3, 0x59, 0x45, 0xb1, 0x20, 0x68, 0x18, + 0x7b, 0xb6, 0x04, 0x79, 0x9d, 0xa0, 0xe8, 0x52, + 0x43, 0x78, 0xc4, 0x23, 0xc5, 0x9f, 0x87, 0x99, + 0x8f, 0xbb, 0x72, 0x14, 0xa2, 0x5a, 0x32, 0x1c, + 0x47, 0x79, 0xe1, 0x27, 0xa3, 0xb0, 0x9e, 0x4d, + 0xe2, 0xf0, 0x13, 0x1c, 0xff, 0xff, 0xbc, 0x3a, + 0x1f, 0xfe, 0xfa, 0xd3, 0xd9, 0xf7, 0x3f, 0xff, + 0xf2, 0x8f, 0xa1, 0x38, 0x9c, 0x54, 0x2f, 0x78, + 0xb4, 0x8b, 0x4e, 0x7c, 0x5e, 0x34, 0x04, 0x91, + 0x40, 0x43, 0xe4, 0x58, 0xd0, 0x6a, 0xf9, 0xf2, + 0x6c, 0x94, 0xfb, 0xc2, 0x28, 0x13, 0x25, 0x5c, + 0x94, 0xb0, 0x47, 0x60, 0x9f, 0xab, 0xf2, 0xb4, + 0xaf, 0x41, 0x2e, 0xf3, 0x41, 0x7c, 0xc8, 0xab, + 0xb1, 0xe3, 0x65, 0x36, 0x7a, 0x52, 0x94, 0x11, + 0x03, 0xe7, 0x55, 0x34, 0x86, 0x96, 0xa4, 0xc3, + 0x64, 0xa9, 0x8d, 0xa5, 0x5d, 0x67, 0x39, 0xd4, + 0xb5, 0x1a, 0x31, 0x0d, 0xe2, 0x65, 0xcd, 0x2c, + 0x62, 0x89, 0x8d, 0x25, 0x15, 0x0b, 0x14, 0xb1, + 0x54, 0x23, 0x68, 0x34, 0xe4, 0x05, 0x36, 0x6e, + 0x46, 0xf1, 0x72, 0x28, 0x2b, 0x34, 0xa2, 0x25, + 0x88, 0xbf, 0x1a, 0x33, 0x51, 0x58, 0x8f, 0x9c, + 0xda, 0x3a, 0x15, 0xf8, 0xa9, 0xb2, 0x06, 0x14, + 0x8d, 0x3a, 0x8d, 0x58, 0xe6, 0x45, 0x96, 0xbe, + 0x0f, 0x9b, 0x48, 0xd1, 0xac, 0xd1, 0x40, 0x91, + 0x66, 0xb5, 0x4a, 0xc2, 0xb4, 0x2b, 0x34, 0xd0, + 0xa7, 0x5b, 0x71, 0x1b, 0xfc, 0x57, 0xd1, 0xb8, + 0x98, 0x35, 0xe2, 0x4f, 0x35, 0x1a, 0x49, 0xd6, + 0xac, 0x58, 0x47, 0xb8, 0x76, 0x9d, 0x66, 0xf2, + 0x75, 0xeb, 0x6e, 0x33, 0x8e, 0x46, 0xa2, 0xb1, + 0xeb, 0xd4, 0xd3, 0x8e, 0x5d, 0xaf, 0x92, 0x84, + 0xdc, 0x2a, 0x0d, 0x94, 0x54, 0xae, 0x2a, 0x06, + 0x62, 0x1c, 0xca, 0x87, 0x70, 0x28, 0x8f, 0xfd, + 0xc2, 0xb7, 0xce, 0x64, 0xfc, 0x4d, 0x9e, 0xcb, + 0x8d, 0x1c, 0x90, 0x2b, 0x8d, 0x42, 0x64, 0x77, + 0x4d, 0x39, 0x82, 0xd7, 0x79, 0x9a, 0x29, 0xb6, + 0x25, 0xba, 0xd8, 0xce, 0xe5, 0x7c, 0x5a, 0xea, + 0xd7, 0x98, 0x36, 0x20, 0x20, 0xb8, 0x1c, 0xa9, + 0x78, 0xf4, 0xab, 0x8d, 0x02, 0x99, 0x6c, 0x24, + 0x33, 0xf3, 0x0c, 0xce, 0x67, 0xe1, 0x50, 0xc5, + 0xdb, 0x08, 0x0f, 0x97, 0x81, 0x35, 0x20, 0x42, + 0x4c, 0x0c, 0xcb, 0xf1, 0x97, 0x4a, 0x24, 0xb0, + 0xc0, 0x53, 0x4c, 0xcd, 0x42, 0xc0, 0xe1, 0x5d, + 0xd4, 0xb7, 0xcd, 0xa3, 0x1a, 0x7a, 0x96, 0x24, + 0x87, 0x55, 0x52, 0x65, 0x33, 0x2e, 0xf7, 0x9f, + 0x4a, 0xc3, 0xaf, 0xc1, 0xbd, 0xea, 0xb0, 0x30, + 0xe0, 0x94, 0x09, 0xa7, 0x01, 0x17, 0x8b, 0x1b, + 0x61, 0x3d, 0xf3, 0x43, 0x35, 0x75, 0x98, 0x35, + 0xbc, 0x12, 0xbb, 0xaa, 0xa3, 0x15, 0x17, 0x6e, + 0x0d, 0xd3, 0xd9, 0x8c, 0x2a, 0x67, 0x3c, 0x06, + 0xaa, 0xf4, 0xa1, 0x72, 0x02, 0xcd, 0x0a, 0x5e, + 0x89, 0x31, 0x35, 0x50, 0x94, 0x0b, 0xb9, 0x86, + 0xb3, 0x6c, 0x46, 0xd6, 0x5c, 0x6a, 0xfb, 0x53, + 0x13, 0xc2, 0xc6, 0xc2, 0xbb, 0x1c, 0xa8, 0x6e, + 0xfd, 0xcb, 0xc0, 0xeb, 0xd9, 0x08, 0x36, 0x3d, + 0x00, 0x21, 0x35, 0x11, 0x77, 0x02, 0x64, 0xfa, + 0x43, 0x41, 0x8c, 0x2c, 0x24, 0x80, 0x4a, 0x01, + 0x4b, 0x44, 0xd6, 0xac, 0x55, 0xc8, 0xf2, 0x64, + 0x39, 0x7a, 0xcf, 0xef, 0x07, 0xb0, 0x1e, 0x09, + 0x58, 0xa2, 0x8e, 0x96, 0x93, 0x85, 0x18, 0xc7, + 0x25, 0xc9, 0x01, 0xd9, 0x89, 0x84, 0x2e, 0x89, + 0x77, 0x16, 0x68, 0xfb, 0xe9, 0xf6, 0x58, 0x47, + 0x48, 0xd7, 0xb2, 0xff, 0xf9, 0x32, 0x2e, 0xa2, + 0x45, 0xbc, 0x16, 0x30, 0x83, 0x35, 0xeb, 0x75, + 0x8f, 0xd1, 0xbe, 0x09, 0x92, 0x1d, 0xf6, 0x3c, + 0xf3, 0xc7, 0x2c, 0x2a, 0xb0, 0x31, 0xda, 0xdb, + 0x40, 0x80, 0x0e, 0x33, 0xbc, 0xb9, 0xca, 0x93, + 0xd0, 0x7f, 0x2f, 0x61, 0x40, 0x81, 0xc6, 0x1c, + 0xf9, 0xa1, 0xc6, 0x69, 0x14, 0x65, 0x23, 0x90, + 0x4c, 0xb9, 0xc8, 0xa8, 0x4c, 0x83, 0xbc, 0xaf, + 0x7d, 0xec, 0x4a, 0xde, 0x21, 0x4d, 0x58, 0xcb, + 0x95, 0x53, 0x25, 0x13, 0xd5, 0xc0, 0xd2, 0x2c, + 0x01, 0xc1, 0x73, 0xa1, 0x75, 0x67, 0x0b, 0xfc, + 0x89, 0xaa, 0xcd, 0xa1, 0xd9, 0x42, 0xb1, 0x09, + 0x8d, 0x73, 0x5e, 0x1b, 0xd8, 0xe3, 0x97, 0x6a, + 0x02, 0xf7, 0x59, 0x4b, 0x70, 0xb3, 0xc7, 0x16, + 0x11, 0x72, 0xe9, 0xde, 0x91, 0x96, 0x25, 0xbc, + 0x3f, 0x19, 0x52, 0x84, 0xd3, 0x09, 0x4c, 0xce, + 0x6b, 0x1c, 0x13, 0x9e, 0x17, 0xb8, 0x70, 0x1c, + 0x5f, 0x86, 0x38, 0xd1, 0xdf, 0x80, 0x17, 0x0b, + 0x27, 0x13, 0x58, 0xc8, 0xe8, 0x22, 0x84, 0x45, + 0x20, 0x98, 0x39, 0x4e, 0xb8, 0x59, 0xc5, 0x05, + 0xf9, 0x26, 0x05, 0xec, 0x97, 0x38, 0x64, 0x7f, + 0x54, 0x70, 0xc2, 0x21, 0x18, 0x64, 0xf2, 0xa5, + 0x39, 0xec, 0x10, 0xa0, 0x17, 0xec, 0x22, 0x0a, + 0x57, 0x8b, 0x34, 0x2b, 0xe8, 0xf2, 0x29, 0x0b, + 0xe9, 0x2b, 0x36, 0x70, 0x21, 0xae, 0x66, 0x69, + 0xac, 0xb0, 0x0b, 0x7c, 0x34, 0xfa, 0xa6, 0xdc, + 0x44, 0x4d, 0xe0, 0x08, 0x2f, 0x1c, 0x83, 0xe8, + 0x07, 0x88, 0x12, 0xcd, 0xcd, 0x38, 0xed, 0x99, + 0x1f, 0x83, 0xa6, 0x04, 0x94, 0x69, 0x81, 0xe4, + 0x57, 0x10, 0x59, 0xfa, 0x1f, 0xa8, 0x1d, 0x8e, + 0xf5, 0xf2, 0xbb, 0xb6, 0x0e, 0x6b, 0xfd, 0x94, + 0xcd, 0xe3, 0xe6, 0x97, 0x09, 0xeb, 0xba, 0xe8, + 0x74, 0x57, 0xa4, 0x23, 0xd6, 0xea, 0x35, 0x06, + 0x22, 0x7f, 0xee, 0xa9, 0x5f, 0x9b, 0x6d, 0x37, + 0x0e, 0xb6, 0xd6, 0x88, 0x4a, 0x04, 0xb2, 0x01, + 0x54, 0xe5, 0xd4, 0x5c, 0x89, 0xc4, 0x8d, 0x0e, + 0xba, 0x97, 0xeb, 0xeb, 0x4f, 0x5d, 0xa3, 0xf2, + 0xd7, 0x48, 0xff, 0x37, 0x85, 0x81, 0x09, 0x67, + 0x65, 0xae, 0x8b, 0xb1, 0x3a, 0x74, 0x55, 0x10, + 0xe5, 0x78, 0x49, 0xe0, 0xf3, 0x5b, 0xd9, 0xe5, + 0x9c, 0xcb, 0x05, 0x12, 0x59, 0x71, 0x39, 0x80, + 0x57, 0x02, 0x39, 0xde, 0x68, 0xf8, 0x6c, 0xe2, + 0x2f, 0x2f, 0x3b, 0x7e, 0x52, 0x44, 0x40, 0xde, + 0x3e, 0xde, 0xdf, 0xe3, 0x16, 0x92, 0xd0, 0xf4, + 0x86, 0xed, 0x0a, 0x7e, 0x48, 0xd0, 0x08, 0x7e, + 0xe6, 0x03, 0x2e, 0xf2, 0x96, 0x86, 0x57, 0x7a, + 0x94, 0xd3, 0xad, 0x90, 0xba, 0xc7, 0xc1, 0xcb, + 0x3b, 0xbc, 0x92, 0xce, 0x15, 0xbc, 0x94, 0xbd, + 0x0f, 0xc3, 0x05, 0x15, 0x12, 0x24, 0x94, 0x9a, + 0xd2, 0xe5, 0x74, 0x06, 0x1b, 0xbf, 0xbf, 0xb8, + 0xf4, 0xf8, 0x8d, 0xcf, 0x2a, 0xa5, 0x6b, 0xa3, + 0x28, 0xb9, 0x08, 0xb3, 0x1c, 0x79, 0x42, 0x16, + 0xd2, 0x75, 0x47, 0xd7, 0x3d, 0x6c, 0x14, 0xda, + 0x42, 0xf6, 0x01, 0xbe, 0x0e, 0x04, 0xfd, 0xdd, + 0xe9, 0x6f, 0x67, 0xdf, 0x9e, 0x0e, 0x5f, 0x9f, + 0xfd, 0xf3, 0xf4, 0xc7, 0xe1, 0x2f, 0xaf, 0xde, + 0x9c, 0xfd, 0x0c, 0x1f, 0x6b, 0xa6, 0x5a, 0x59, + 0x17, 0x91, 0x67, 0xf3, 0x63, 0xe3, 0xb0, 0x25, + 0xa6, 0xbe, 0x0b, 0xf8, 0xc8, 0x5f, 0xf1, 0x0c, + 0x34, 0x3b, 0xe3, 0x96, 0xb8, 0x46, 0xd9, 0xf6, + 0xf6, 0x35, 0xf4, 0xbb, 0xd2, 0xb0, 0x6f, 0x5d, + 0x51, 0xbe, 0x4b, 0x4d, 0xf7, 0x7e, 0xf4, 0xd3, + 0xfb, 0xd5, 0x29, 0xef, 0x49, 0x0d, 0x34, 0x55, + 0xc0, 0x26, 0x0d, 0xf0, 0x2a, 0x9a, 0x5c, 0xa3, + 0x22, 0x77, 0x65, 0x75, 0xac, 0x41, 0x1b, 0xdb, + 0x5e, 0xb3, 0x6a, 0x56, 0xac, 0xae, 0xaa, 0x1b, + 0x6d, 0xa1, 0x1a, 0x5d, 0x5f, 0x9b, 0xd9, 0x42, + 0x99, 0xf9, 0x28, 0x05, 0x64, 0x2b, 0xfd, 0xe3, + 0x23, 0xb4, 0x05, 0x57, 0xc8, 0x27, 0x9a, 0x83, + 0x63, 0x95, 0x9f, 0x87, 0x1c, 0xa6, 0x3c, 0x38, + 0xe3, 0x30, 0x99, 0x12, 0xd2, 0xfc, 0x17, 0xc9, + 0xd5, 0x25, 0xcb, 0x6f, 0x38, 0x46, 0x04, 0xd8, + 0x0f, 0x26, 0x54, 0x55, 0x07, 0x84, 0x27, 0x51, + 0xad, 0x33, 0xf7, 0x2f, 0x5b, 0x42, 0x37, 0x77, + 0xce, 0x06, 0xa3, 0xa1, 0xd2, 0x98, 0xa0, 0x45, + 0x3e, 0x4f, 0xd3, 0x62, 0x86, 0xb7, 0xf4, 0xad, + 0x1e, 0xde, 0x4c, 0xbb, 0x40, 0x3d, 0x17, 0x79, + 0x4b, 0x55, 0xe1, 0xf0, 0x84, 0x7a, 0x8b, 0xd0, + 0xcc, 0xb5, 0xf9, 0x3b, 0x68, 0x12, 0xbd, 0x3e, + 0xfb, 0x06, 0xff, 0x61, 0x2f, 0xcc, 0x9e, 0x94, + 0xa8, 0x50, 0xea, 0x4d, 0x95, 0xf4, 0x4c, 0xd7, + 0xa3, 0x12, 0x0a, 0x62, 0x1f, 0xd5, 0x9e, 0xa1, + 0xd2, 0x0d, 0xa9, 0xca, 0xa0, 0xaf, 0x47, 0xbf, + 0xaf, 0xaf, 0x0c, 0xe0, 0x77, 0xa5, 0x59, 0x5a, + 0x04, 0xbc, 0xcf, 0x5c, 0xc5, 0x53, 0x2b, 0xf3, + 0x37, 0x70, 0x91, 0x70, 0xd7, 0xb7, 0xda, 0x1b, + 0x6f, 0xa9, 0x0d, 0x2c, 0xeb, 0xa5, 0x89, 0x55, + 0x08, 0xdb, 0xbd, 0xa8, 0xb6, 0x0b, 0xf2, 0xb2, + 0x1a, 0xdb, 0xec, 0x40, 0x55, 0x70, 0xad, 0xb2, + 0xbc, 0xb9, 0x2c, 0xab, 0x3a, 0xf0, 0x24, 0xef, + 0xd7, 0x75, 0xee, 0xe2, 0xca, 0xe0, 0x8a, 0x22, + 0xcb, 0x86, 0x8b, 0x21, 0xd9, 0xae, 0xe6, 0x6e, + 0xa7, 0x24, 0x45, 0xb8, 0x05, 0x24, 0xbd, 0xe6, + 0xfc, 0x16, 0x6b, 0xbb, 0x5b, 0x70, 0xd1, 0xd3, + 0x09, 0xb9, 0x67, 0x9d, 0x4a, 0xa5, 0x96, 0xfd, + 0xb5, 0xf7, 0x57, 0x34, 0x10, 0xa0, 0x6c, 0xfb, + 0x3e, 0x04, 0xed, 0x28, 0x66, 0x63, 0x0e, 0x58, + 0xde, 0xb9, 0xa1, 0x5c, 0xec, 0x8f, 0xff, 0xb3, + 0xcc, 0x0b, 0xb3, 0x12, 0x89, 0xd2, 0x45, 0x7a, + 0xb2, 0x47, 0x82, 0x38, 0xc8, 0xdc, 0xe1, 0x7c, + 0x11, 0x65, 0x11, 0x8c, 0x02, 0x44, 0xe2, 0xd1, + 0x2c, 0xcd, 0xc3, 0x44, 0x7a, 0x5b, 0x4a, 0x0f, + 0x4c, 0x74, 0xf7, 0x2a, 0xa2, 0x09, 0xe8, 0xc4, + 0xe4, 0x0b, 0x96, 0x82, 0x00, 0x1d, 0xfb, 0x8b, + 0x05, 0xa2, 0xc8, 0x81, 0xe6, 0x08, 0x0c, 0x75, + 0xe4, 0x62, 0xbd, 0x40, 0x48, 0x6c, 0x16, 0xfa, + 0x05, 0xaa, 0xe0, 0x23, 0x60, 0x0b, 0x39, 0x6b, + 0x91, 0x67, 0x2e, 0x56, 0x1f, 0xc5, 0x80, 0x4d, + 0x98, 0x81, 0x16, 0x9c, 0xa7, 0xcb, 0x0c, 0x54, + 0xc1, 0x3d, 0xee, 0xa1, 0x63, 0x92, 0xc7, 0xbf, + 0x4e, 0x7f, 0xf9, 0x59, 0x49, 0xdd, 0xe4, 0x91, + 0x88, 0x6e, 0xa3, 0x4f, 0xba, 0x3d, 0x3e, 0x01, + 0x3f, 0xf8, 0xcb, 0x3c, 0x8f, 0xfc, 0x44, 0x8e, + 0x67, 0x94, 0x82, 0xee, 0x1c, 0x8d, 0x22, 0x50, + 0x09, 0x5e, 0xb0, 0x3e, 0x54, 0xcd, 0xff, 0xc8, + 0x8a, 0xd6, 0x00, 0xb6, 0xcf, 0xeb, 0x33, 0xed, + 0x90, 0xf2, 0xc3, 0xab, 0x5f, 0xcf, 0xcf, 0x87, + 0xdf, 0xfe, 0x7c, 0xfa, 0x3d, 0xb0, 0xa5, 0xc3, + 0xe7, 0xcf, 0x9e, 0x1f, 0x0d, 0x06, 0xcf, 0x7a, + 0x47, 0xbd, 0xfe, 0xd1, 0xe1, 0xe0, 0xe9, 0x15, + 0x8d, 0xcc, 0x62, 0xeb, 0x60, 0x0d, 0xfe, 0x6b, + 0xa5, 0xb1, 0x8b, 0x17, 0x79, 0xc6, 0x76, 0xaa, + 0xb0, 0x1d, 0x9a, 0x5b, 0x86, 0xf6, 0xbe, 0xbb, + 0x33, 0xb6, 0x33, 0x35, 0xd7, 0x49, 0x28, 0xb7, + 0x66, 0x78, 0xbe, 0x05, 0x23, 0xdb, 0x32, 0xa1, + 0x9d, 0x34, 0x1e, 0x5e, 0xcb, 0xda, 0x46, 0x0a, + 0xea, 0x23, 0xd1, 0xf4, 0x11, 0x10, 0xc5, 0x1c, + 0xad, 0x3d, 0x09, 0x8c, 0x21, 0x99, 0x92, 0xf6, + 0x99, 0xa5, 0x73, 0xf6, 0xb6, 0xd3, 0xf7, 0x58, + 0x87, 0x7c, 0x45, 0x53, 0xf6, 0x16, 0x7e, 0xef, + 0xbf, 0xeb, 0x32, 0xf6, 0x7b, 0xf8, 0x28, 0x8e, + 0xd9, 0x52, 0x4c, 0x01, 0x5a, 0xdd, 0x0a, 0x2c, + 0x5f, 0x64, 0xe9, 0x78, 0x39, 0xe2, 0x23, 0x03, + 0x82, 0x2f, 0xa2, 0x11, 0xf7, 0x86, 0xf3, 0x81, + 0xc0, 0x96, 0xa8, 0x48, 0x42, 0x0f, 0x33, 0x80, + 0xeb, 0xcf, 0xa5, 0x0d, 0x8a, 0xac, 0x35, 0x6c, + 0x02, 0xa4, 0x0f, 0x9b, 0x4f, 0x02, 0x5b, 0x85, + 0x8f, 0xd0, 0x57, 0x71, 0x3c, 0xa6, 0x5a, 0x69, + 0xc3, 0x76, 0x55, 0xa8, 0xf8, 0x71, 0x9e, 0x92, + 0x87, 0x20, 0x62, 0xe2, 0x2b, 0x2d, 0xd7, 0x67, + 0x82, 0x2f, 0xc0, 0xf1, 0x96, 0xf2, 0xb9, 0x45, + 0x60, 0x80, 0xc1, 0x74, 0x8e, 0xfa, 0x70, 0x3e, + 0xf3, 0xd1, 0x86, 0x38, 0x82, 0xad, 0x31, 0x0e, + 0x61, 0x93, 0xcd, 0x91, 0xee, 0xb1, 0x86, 0xd2, + 0xd2, 0xd3, 0x89, 0x84, 0x15, 0xfa, 0xa3, 0x99, + 0x6e, 0x49, 0x93, 0x53, 0x1a, 0x41, 0x57, 0x56, + 0xfe, 0xef, 0x70, 0x82, 0x7e, 0x8d, 0xb0, 0x90, + 0xe3, 0x14, 0xba, 0x26, 0x93, 0x17, 0xb9, 0x3b, + 0xa2, 0xb9, 0x92, 0xec, 0x08, 0xe8, 0x68, 0xbf, + 0x60, 0xf9, 0x52, 0x6e, 0x44, 0x34, 0xb8, 0x69, + 0x14, 0x25, 0x1c, 0x31, 0xec, 0x09, 0x70, 0x9a, + 0xdc, 0x32, 0xce, 0x01, 0x9c, 0x0f, 0x61, 0x96, + 0x32, 0x31, 0x22, 0xd3, 0x4f, 0x13, 0x27, 0xb9, + 0xab, 0x17, 0x19, 0xed, 0x63, 0x39, 0x21, 0xb0, + 0x02, 0xb9, 0x83, 0x14, 0xff, 0x24, 0x5d, 0xb1, + 0x73, 0xe8, 0x7b, 0x34, 0xa3, 0x0e, 0xf5, 0xbc, + 0xd3, 0x9e, 0xda, 0x37, 0x39, 0x2e, 0xfc, 0x65, + 0xf0, 0x81, 0x7d, 0x20, 0xd8, 0x45, 0xab, 0xd3, + 0xeb, 0x1e, 0xc3, 0xaf, 0x87, 0xdd, 0xde, 0xbf, + 0x91, 0x67, 0x9c, 0xff, 0x7b, 0xd0, 0x66, 0x2f, + 0x5f, 0x12, 0x13, 0x92, 0xa0, 0x7e, 0x9f, 0x45, + 0x68, 0xa9, 0x4b, 0x63, 0xb4, 0x6e, 0x14, 0xe9, + 0x0b, 0xf9, 0xfd, 0x1c, 0xa5, 0x25, 0x64, 0x36, + 0x1d, 0xa4, 0xc8, 0x7d, 0x38, 0x9f, 0xa6, 0x2d, + 0x62, 0x5e, 0x20, 0xd3, 0x6c, 0xec, 0xbe, 0xdd, + 0x46, 0xbf, 0xbe, 0x43, 0xe1, 0x6e, 0xcd, 0x37, + 0x5c, 0x03, 0x40, 0x01, 0xef, 0xc0, 0x82, 0x77, + 0x60, 0xc1, 0xe3, 0xe0, 0xf4, 0x96, 0x78, 0x8d, + 0x14, 0x44, 0xd4, 0x2b, 0x8e, 0x13, 0xd8, 0x0e, + 0xe4, 0x00, 0x84, 0x73, 0x6b, 0x30, 0x8f, 0x0b, + 0x63, 0xc7, 0x9d, 0x23, 0xc6, 0xce, 0x46, 0xd4, + 0x10, 0xcf, 0x69, 0xb1, 0x83, 0xb5, 0xe4, 0x0c, + 0xd2, 0x20, 0x83, 0xfe, 0xb9, 0x1d, 0x6e, 0xdc, + 0xe4, 0xf4, 0x80, 0x47, 0x45, 0x9a, 0x99, 0xbb, + 0x08, 0x3e, 0x2c, 0xfd, 0x58, 0xd9, 0xc6, 0x71, + 0xeb, 0x48, 0x5b, 0x5e, 0xb5, 0x08, 0xae, 0xcd, + 0x59, 0xa2, 0xb3, 0x0a, 0x0b, 0xf1, 0x9d, 0x98, + 0xda, 0x8f, 0x84, 0x57, 0x0f, 0x49, 0x55, 0x65, + 0x2b, 0x3b, 0x88, 0xad, 0x02, 0x2b, 0xdb, 0x94, + 0x58, 0x2b, 0xd4, 0xd1, 0x11, 0xbf, 0x51, 0x2e, + 0xbb, 0x31, 0xc9, 0xaa, 0xba, 0x9a, 0x21, 0x84, + 0x34, 0x09, 0x1b, 0xb7, 0x7c, 0xd6, 0x36, 0x6b, + 0xf2, 0xc6, 0x31, 0xbb, 0xe5, 0x61, 0x29, 0xd7, + 0xf2, 0xff, 0xda, 0xfc, 0x35, 0xcc, 0x8b, 0x68, + 0xee, 0xd3, 0x4a, 0x90, 0xf1, 0xdf, 0x2f, 0x8d, + 0x0b, 0x9d, 0x9c, 0x51, 0x2c, 0x3a, 0xbe, 0x3c, + 0x36, 0xb6, 0x23, 0x7a, 0x7b, 0x69, 0xf6, 0xa0, + 0xfe, 0x3b, 0x4e, 0x8b, 0x96, 0x9a, 0x27, 0x4f, + 0x4f, 0x59, 0xdb, 0x54, 0xec, 0x2e, 0x40, 0x08, + 0x7a, 0xb9, 0x35, 0x13, 0x1a, 0xd7, 0xe8, 0x39, + 0x44, 0x73, 0x00, 0x8a, 0x3c, 0xb7, 0xf4, 0x7f, + 0xda, 0x77, 0xe8, 0x74, 0x4a, 0x9e, 0xf4, 0x27, + 0x35, 0x92, 0x6a, 0xd9, 0x8d, 0xee, 0xba, 0x0a, + 0x0e, 0xcd, 0x11, 0xf5, 0x55, 0xe1, 0xa0, 0xd9, + 0xbd, 0x84, 0x66, 0x3e, 0xff, 0xcd, 0xf0, 0x98, + 0xec, 0xae, 0x85, 0x98, 0xd8, 0x11, 0x85, 0x6b, + 0xcb, 0x91, 0xb1, 0xc2, 0x1b, 0xb0, 0xaa, 0x88, + 0xeb, 0x82, 0x70, 0x8c, 0x2f, 0x1a, 0x84, 0xf8, + 0x2d, 0x07, 0x2a, 0x5c, 0xd1, 0xab, 0xdd, 0xde, + 0xa8, 0x59, 0xbb, 0x9b, 0xb9, 0x5e, 0x72, 0x4e, + 0x6d, 0x8d, 0x8f, 0xc7, 0x05, 0x20, 0x90, 0x21, + 0x91, 0xd1, 0x08, 0xf2, 0x72, 0x56, 0xf6, 0x66, + 0xfc, 0x91, 0x7b, 0x5b, 0xa9, 0xb4, 0xa5, 0xaf, + 0x20, 0x54, 0xcc, 0xd2, 0xac, 0xa6, 0x50, 0x31, + 0x92, 0x32, 0xb0, 0xd8, 0x1f, 0x85, 0xe3, 0x93, + 0x8d, 0x9a, 0x56, 0xb3, 0x13, 0xdd, 0x36, 0xee, + 0x73, 0x72, 0xd9, 0xc4, 0x9e, 0x54, 0x3d, 0xbb, + 0xdf, 0x93, 0xb4, 0xf8, 0x35, 0x27, 0x94, 0x2a, + 0x3d, 0x40, 0x8d, 0x1b, 0xb7, 0xd7, 0x24, 0x21, + 0x55, 0x11, 0xb1, 0x9e, 0x0c, 0xeb, 0x72, 0xca, + 0x64, 0x5d, 0x1a, 0x55, 0x51, 0x59, 0x49, 0x66, + 0x2f, 0x9d, 0x1e, 0xe4, 0x5d, 0x8c, 0xd5, 0x3a, + 0x8d, 0x63, 0xf2, 0xf2, 0x1f, 0x2e, 0xc2, 0x0c, + 0x5f, 0xab, 0xa0, 0xf4, 0x34, 0xe4, 0xf7, 0x25, + 0x40, 0x08, 0x31, 0x50, 0x4c, 0xcb, 0xb0, 0xbd, + 0x1c, 0xc3, 0xc9, 0xc4, 0x99, 0x57, 0xab, 0x61, + 0x92, 0x80, 0x87, 0xd7, 0x62, 0xd5, 0xb6, 0x4d, + 0x39, 0x24, 0x53, 0x64, 0xe1, 0x05, 0x00, 0xc8, + 0x49, 0x07, 0x44, 0x96, 0x39, 0x06, 0x49, 0xd0, + 0xcf, 0x3a, 0x93, 0x28, 0x8c, 0xc7, 0x2c, 0x48, + 0x2f, 0xb9, 0xd4, 0x4d, 0x77, 0x9b, 0xe1, 0xf8, + 0x00, 0x6b, 0xa1, 0x70, 0x80, 0xb2, 0x62, 0x14, + 0x87, 0xb9, 0x82, 0x77, 0xa4, 0x85, 0xf7, 0xed, + 0xac, 0x1f, 0x9a, 0xf3, 0x55, 0xdf, 0x7e, 0xf9, + 0x86, 0xc0, 0xb0, 0xe1, 0x96, 0x0b, 0xfe, 0x6e, + 0x98, 0x4a, 0xcd, 0x77, 0x88, 0x56, 0x38, 0xe3, + 0xa1, 0x5f, 0x35, 0xef, 0x11, 0xe4, 0x62, 0x96, + 0x71, 0xd6, 0xf3, 0xd1, 0x04, 0x67, 0x9a, 0x06, + 0xe3, 0xc5, 0x0c, 0xef, 0x8e, 0x60, 0x0d, 0xb5, + 0xa4, 0xf3, 0x0b, 0xf5, 0xaa, 0xd0, 0xf7, 0x80, + 0x40, 0x60, 0xc8, 0xb1, 0x1f, 0x84, 0x71, 0x13, + 0xdf, 0x17, 0x13, 0xa8, 0x66, 0x11, 0xa6, 0x80, + 0xc0, 0x6b, 0xc0, 0xff, 0xcd, 0xdf, 0xa1, 0x26, + 0xa9, 0x09, 0x9c, 0xe0, 0xe2, 0xb5, 0x5c, 0x3e, + 0x4b, 0x57, 0x80, 0xbe, 0x72, 0x28, 0x50, 0xb3, + 0xf3, 0x5f, 0x5c, 0x06, 0xb2, 0xae, 0x5e, 0xab, + 0xb8, 0x8b, 0xee, 0x9b, 0x33, 0x33, 0x8d, 0x80, + 0x71, 0xcf, 0xc8, 0x21, 0xcb, 0xc9, 0x2d, 0x81, + 0x96, 0x5a, 0x1e, 0x50, 0x19, 0xe0, 0x59, 0xa0, + 0xc6, 0x06, 0x87, 0xc5, 0x04, 0x94, 0x1e, 0x14, + 0xee, 0xd2, 0x65, 0x51, 0x8d, 0xc4, 0xfe, 0x4b, + 0xd6, 0xed, 0xcb, 0x7e, 0xfe, 0xfc, 0x72, 0x59, + 0x9b, 0x5b, 0x20, 0x55, 0xfa, 0x5a, 0x01, 0xb0, + 0xfa, 0xbb, 0x92, 0xbd, 0x77, 0x9c, 0xf2, 0x23, + 0x38, 0x25, 0xbf, 0xd8, 0xbe, 0x75, 0x5e, 0x59, + 0x9a, 0x99, 0x05, 0x37, 0x44, 0x0c, 0x85, 0x82, + 0x86, 0xe2, 0xd3, 0xe0, 0x84, 0x2b, 0x8b, 0x63, + 0xdb, 0xd2, 0x91, 0xc7, 0x28, 0xba, 0x72, 0xe5, + 0x7c, 0xee, 0xbf, 0x0f, 0x59, 0x86, 0x8f, 0x30, + 0xd1, 0xc6, 0x87, 0x06, 0xff, 0x0e, 0x59, 0xfc, + 0x99, 0xba, 0xd6, 0xba, 0x2a, 0x43, 0x76, 0xf0, + 0xb8, 0x23, 0x0e, 0xcd, 0xcb, 0x94, 0x59, 0xcb, + 0x0f, 0xf2, 0x96, 0x42, 0xb3, 0xbb, 0x6e, 0xd3, + 0x44, 0xfc, 0x8e, 0x56, 0x8e, 0xe4, 0x51, 0x21, + 0xfc, 0x73, 0xb4, 0x17, 0x42, 0x4e, 0x66, 0x97, + 0x20, 0x05, 0x05, 0x42, 0x69, 0xd1, 0x95, 0x56, + 0x2f, 0xb4, 0x0d, 0x85, 0x7f, 0x80, 0xb6, 0x8b, + 0xab, 0x0b, 0xa2, 0x1f, 0x54, 0xc6, 0x69, 0x10, + 0xb6, 0x1f, 0xa1, 0x78, 0x97, 0x34, 0x6f, 0x73, + 0xbe, 0xec, 0xd9, 0x39, 0xb1, 0xeb, 0x8a, 0x39, + 0x7c, 0x79, 0x35, 0x77, 0x92, 0x4d, 0x53, 0x6a, + 0xc8, 0xcd, 0x4a, 0xf8, 0x45, 0xc2, 0x25, 0x37, + 0x18, 0x89, 0xc7, 0xcd, 0x31, 0x9d, 0x1b, 0xe3, + 0x39, 0x1f, 0x71, 0x56, 0x5a, 0x12, 0xf8, 0xdd, + 0x9f, 0x94, 0xa3, 0x7b, 0x3d, 0x22, 0x47, 0xea, + 0x6c, 0x1c, 0x58, 0x1d, 0xd8, 0x97, 0x9d, 0x7c, + 0xf9, 0xdd, 0x2b, 0x4f, 0x67, 0x5d, 0xda, 0xdb, + 0x5c, 0x93, 0x6a, 0x2d, 0x99, 0x54, 0xde, 0x32, + 0x78, 0x13, 0x88, 0x73, 0x3d, 0xdc, 0x3f, 0x26, + 0xbd, 0xbb, 0x12, 0xa9, 0x83, 0x4a, 0x42, 0xd5, + 0xa0, 0xd4, 0x66, 0x57, 0xfb, 0xbe, 0xae, 0x7b, + 0x53, 0xf1, 0x17, 0x9b, 0x06, 0xf7, 0x11, 0x19, + 0x23, 0x39, 0xaf, 0xa8, 0xb9, 0xc2, 0xb4, 0xc6, + 0x5f, 0x73, 0x2f, 0xdb, 0xb1, 0x7d, 0x75, 0x69, + 0xa5, 0x3b, 0x6e, 0x37, 0x5b, 0x5c, 0x76, 0x8a, + 0x0b, 0xf8, 0x3f, 0xef, 0xef, 0x2d, 0x6d, 0x95, + 0x5f, 0xd1, 0xd6, 0x0f, 0x67, 0xaf, 0x83, 0xf9, + 0xa7, 0xf8, 0xd6, 0xe9, 0xa1, 0x3d, 0xd5, 0xa9, + 0x36, 0xb9, 0x3d, 0xc4, 0xf7, 0x13, 0x77, 0xfe, + 0x78, 0xe0, 0x3a, 0x7b, 0xe1, 0xbe, 0x1c, 0xf4, + 0x6e, 0xdc, 0xb1, 0xed, 0xae, 0x9d, 0xaa, 0xae, + 0xe3, 0xc1, 0xd4, 0x64, 0xf5, 0xba, 0xc9, 0xf7, + 0xa0, 0x57, 0x63, 0x4b, 0xd5, 0x56, 0xd2, 0x6a, + 0x3b, 0x61, 0xdd, 0x6a, 0x2e, 0x8b, 0x38, 0x4a, + 0x1a, 0x9f, 0xca, 0x59, 0x55, 0x1a, 0x38, 0x9a, + 0x55, 0xaf, 0x92, 0xb3, 0x39, 0x35, 0x1a, 0x48, + 0xb1, 0x54, 0xf3, 0xf3, 0xe4, 0x74, 0xf6, 0xec, + 0x13, 0xbb, 0x31, 0xbf, 0x54, 0x73, 0x3e, 0xab, + 0x8a, 0x57, 0x5e, 0xa0, 0x3a, 0x4e, 0x58, 0x02, + 0x5d, 0x37, 0xcb, 0x9f, 0x34, 0x67, 0x54, 0x86, + 0x79, 0xa8, 0xd9, 0x72, 0x34, 0xc2, 0x03, 0x47, + 0xc3, 0x7b, 0xcc, 0xa5, 0xeb, 0x03, 0xc6, 0x6f, + 0x3a, 0xd5, 0x0e, 0xaa, 0xe7, 0xae, 0xf6, 0x82, + 0xdd, 0x03, 0x89, 0xdf, 0x1c, 0x8d, 0x6e, 0x77, + 0x99, 0x50, 0xc3, 0x42, 0x4b, 0x74, 0xfb, 0x31, + 0x74, 0x76, 0x83, 0x2c, 0x5a, 0x8b, 0xce, 0xa6, + 0xd4, 0x8f, 0xd4, 0xd0, 0xd1, 0xfc, 0x37, 0xcd, + 0x40, 0x49, 0x5f, 0x5b, 0x12, 0xb3, 0xd4, 0xdd, + 0xf8, 0x45, 0x8e, 0xeb, 0xcb, 0x48, 0xea, 0x10, + 0x02, 0xad, 0xbe, 0xfe, 0xb0, 0x07, 0xbc, 0xcf, + 0x5a, 0x1c, 0x9a, 0x3a, 0x19, 0xee, 0xe1, 0xa6, + 0xec, 0x26, 0xc3, 0xae, 0x48, 0x07, 0x71, 0xa1, + 0xfe, 0xde, 0x40, 0xd0, 0x94, 0x2b, 0x1d, 0x50, + 0x9f, 0xc4, 0x83, 0x73, 0x19, 0x9b, 0x02, 0x9d, + 0x58, 0xaa, 0x51, 0x35, 0x6b, 0x54, 0xe3, 0x7b, + 0xe4, 0xd4, 0x72, 0x90, 0x16, 0x71, 0xdf, 0xcc, + 0xf2, 0x0a, 0xc4, 0xc5, 0x62, 0xb9, 0xf5, 0xb6, + 0x42, 0xbe, 0x48, 0x9b, 0x51, 0x07, 0x0d, 0x71, + 0x23, 0xe2, 0xe8, 0xd3, 0x57, 0x8f, 0x36, 0x96, + 0x6e, 0x46, 0x9a, 0xd7, 0xba, 0xf2, 0x59, 0xfa, + 0x80, 0x5e, 0xfc, 0x5a, 0xe4, 0x80, 0xf5, 0xcc, + 0x0f, 0xdc, 0x1e, 0x58, 0xb1, 0x90, 0xa6, 0xf3, + 0x5b, 0x69, 0xb5, 0x09, 0x87, 0xea, 0x65, 0xdd, + 0x02, 0x11, 0x58, 0x5a, 0x13, 0x8d, 0x22, 0xb5, + 0x90, 0xd0, 0xcb, 0x52, 0x8b, 0x02, 0xb5, 0xa8, + 0x59, 0x22, 0x1d, 0xca, 0xc5, 0x8c, 0x36, 0xf3, + 0xd2, 0x42, 0x5f, 0x39, 0xb2, 0x5b, 0x15, 0x29, + 0xf4, 0x8c, 0x53, 0xf1, 0xc3, 0xea, 0xa4, 0x12, + 0x62, 0x60, 0x54, 0x2c, 0xd2, 0x5a, 0x78, 0x4e, + 0x35, 0x84, 0x66, 0xf0, 0x79, 0x62, 0x73, 0xbf, + 0x08, 0x1b, 0xbc, 0xe0, 0x69, 0xd2, 0x60, 0xab, + 0x43, 0xb8, 0xb9, 0x15, 0x2c, 0x1f, 0x7c, 0x44, + 0xf2, 0x5c, 0x59, 0x3f, 0x79, 0x05, 0xcb, 0x9d, + 0xbe, 0x48, 0xdd, 0xe2, 0xd5, 0xc9, 0xde, 0x35, + 0x23, 0x43, 0xe1, 0xe0, 0xe0, 0xe0, 0x59, 0xc4, + 0xfe, 0x5a, 0x04, 0x73, 0x92, 0x1e, 0x89, 0x2d, + 0x73, 0x0e, 0xbb, 0x97, 0x70, 0x6a, 0x99, 0xb3, + 0xdf, 0xbd, 0xa4, 0x80, 0x6d, 0x6a, 0xb4, 0x1e, + 0xb3, 0xeb, 0xaf, 0xdd, 0xfa, 0x6b, 0xbb, 0xbe, + 0x19, 0xa0, 0xc7, 0xea, 0x3f, 0xa8, 0xea, 0x3f, + 0x70, 0xfb, 0x0f, 0x9a, 0xfb, 0x0f, 0xdc, 0xfe, + 0x83, 0x8a, 0xfe, 0x6f, 0x2c, 0x34, 0x96, 0x5e, + 0xb0, 0x7d, 0x67, 0x2e, 0x3d, 0xbd, 0xda, 0x37, + 0x1f, 0x0b, 0x4b, 0x92, 0x81, 0xd3, 0x69, 0x50, + 0xd9, 0xe9, 0x8d, 0x89, 0xad, 0x9b, 0x82, 0x59, + 0x35, 0xf8, 0xa3, 0xc8, 0x33, 0x0f, 0x2d, 0xb5, + 0x77, 0x70, 0xa0, 0xdf, 0xe5, 0x89, 0x7c, 0xf7, + 0x07, 0xe9, 0x1d, 0x9c, 0x81, 0xb7, 0xfd, 0x36, + 0xab, 0x74, 0x88, 0x7d, 0xcc, 0xd9, 0xb4, 0xf1, + 0x68, 0xfa, 0x3c, 0x4f, 0x9d, 0xeb, 0x46, 0x6e, + 0xab, 0x8f, 0xdb, 0xf6, 0xf0, 0xa2, 0xb6, 0xd5, + 0xc7, 0x6c, 0xbb, 0xbd, 0x88, 0x6d, 0xf8, 0xd2, + 0x23, 0x4a, 0xc6, 0xc6, 0xdb, 0xef, 0x54, 0xaa, + 0x61, 0xfc, 0x7a, 0x98, 0x34, 0x30, 0x1d, 0x60, + 0x19, 0x3d, 0x7c, 0xef, 0x48, 0x41, 0xbc, 0x42, + 0x48, 0x39, 0xe4, 0xb4, 0xea, 0x8a, 0xed, 0x86, + 0x2d, 0x89, 0x5b, 0x46, 0xf3, 0x7c, 0x58, 0x8a, + 0xe1, 0x4e, 0x09, 0xdc, 0x29, 0x81, 0x3b, 0x25, + 0x70, 0xa7, 0x04, 0x3e, 0x04, 0x25, 0xf0, 0x5f, + 0x69, 0x3a, 0xbf, 0x2d, 0x45, 0xf0, 0x4b, 0xd6, + 0xeb, 0xee, 0x2d, 0x44, 0xf2, 0x26, 0x3d, 0x50, + 0x2d, 0xf8, 0x5d, 0xeb, 0x82, 0x15, 0x1d, 0x97, + 0x43, 0x21, 0xd7, 0x86, 0x25, 0x16, 0xea, 0xda, + 0x8d, 0x85, 0x1f, 0xde, 0xa9, 0x6d, 0x3b, 0xb5, + 0x6d, 0xa7, 0xb6, 0xed, 0xd4, 0xb6, 0x7b, 0x0b, + 0xb4, 0x2d, 0xb5, 0xa2, 0xbb, 0xd5, 0x86, 0x0e, + 0xe1, 0x33, 0x79, 0x1b, 0x3b, 0x09, 0x1a, 0xe4, + 0x2e, 0x57, 0xe5, 0xa4, 0xd5, 0x54, 0xf2, 0x38, + 0x2a, 0xde, 0x1c, 0x59, 0xc1, 0xfa, 0x8a, 0x62, + 0x73, 0x02, 0x90, 0xfc, 0x78, 0x18, 0x3a, 0xbe, + 0x1b, 0x47, 0xc0, 0x94, 0xa5, 0x6f, 0x5b, 0x5d, + 0x08, 0x2b, 0xbf, 0x9a, 0xdf, 0xfa, 0x54, 0xd2, + 0x10, 0x24, 0x1a, 0x4a, 0xab, 0x83, 0x44, 0x53, + 0x41, 0x53, 0xec, 0x2b, 0x51, 0xa1, 0x91, 0xa1, + 0xce, 0x1a, 0xc2, 0x7a, 0xcc, 0x2a, 0xc2, 0x7a, + 0x98, 0xa8, 0xcd, 0x9c, 0xa8, 0x1e, 0x46, 0xe3, + 0x59, 0xe5, 0xd3, 0x53, 0x0b, 0xbd, 0x99, 0xfb, + 0x18, 0xf3, 0x61, 0x3b, 0xee, 0x6d, 0xad, 0xd7, + 0xd0, 0x42, 0x53, 0x20, 0x5d, 0xf8, 0xa5, 0x3a, + 0x90, 0x2e, 0x14, 0x78, 0x6a, 0xe1, 0x6b, 0x03, + 0xe9, 0x8a, 0xe6, 0xce, 0x3a, 0x36, 0xf4, 0x3c, + 0x33, 0x1e, 0xc0, 0xd6, 0xc7, 0x99, 0x98, 0xa9, + 0x38, 0x13, 0xb3, 0xaa, 0x38, 0x13, 0xa5, 0x45, + 0x24, 0x1c, 0x66, 0xdb, 0x87, 0x99, 0xb8, 0x1b, + 0x97, 0x40, 0xc9, 0xd0, 0x0e, 0x19, 0xdf, 0x92, + 0xa4, 0x1f, 0xa9, 0xdd, 0x09, 0xa7, 0xc8, 0x07, + 0xc1, 0xc7, 0xc4, 0x34, 0x62, 0x90, 0x24, 0xb2, + 0xff, 0xe0, 0xdf, 0xf2, 0x01, 0x89, 0x1c, 0x9f, + 0x2a, 0xe4, 0x5f, 0xec, 0x48, 0x47, 0x32, 0xe3, + 0x0f, 0x07, 0x8e, 0xd1, 0xf8, 0x06, 0x57, 0x7c, + 0x60, 0x51, 0x90, 0xe3, 0x75, 0x8f, 0x7d, 0x23, + 0x7b, 0x7c, 0xc1, 0x38, 0x09, 0xf4, 0xdb, 0xa6, + 0xf7, 0x39, 0xda, 0xbe, 0x2e, 0x60, 0x87, 0x61, + 0xe4, 0x13, 0x32, 0x94, 0xb5, 0x30, 0x89, 0xd6, + 0xd8, 0xcf, 0xde, 0x1f, 0x04, 0x19, 0xb5, 0x8b, + 0xf8, 0xfb, 0xfc, 0x7c, 0x99, 0x4d, 0x7c, 0x28, + 0xa7, 0x29, 0xf9, 0xa6, 0xed, 0x46, 0x65, 0xba, + 0x10, 0x39, 0x02, 0x75, 0x26, 0xba, 0x5e, 0x77, + 0xd0, 0x1f, 0xd8, 0x49, 0xe5, 0x7a, 0xdd, 0xa7, + 0xfd, 0xe3, 0x81, 0xfa, 0x14, 0xd0, 0xa7, 0xde, + 0xd3, 0xc1, 0x40, 0x49, 0xf1, 0x35, 0xfe, 0xe6, + 0xee, 0x6b, 0x11, 0x4c, 0xbb, 0x35, 0x1e, 0x8b, + 0xe7, 0x1f, 0xcc, 0x9f, 0x07, 0xf8, 0xd8, 0x9b, + 0x09, 0xfe, 0x3a, 0xc5, 0x27, 0x10, 0x49, 0xaa, + 0xdf, 0x3c, 0xf0, 0x44, 0x60, 0x45, 0x5a, 0x50, + 0xf4, 0x98, 0x20, 0x06, 0xba, 0xd0, 0x47, 0x93, + 0x68, 0x1c, 0x8b, 0x55, 0x91, 0x1d, 0x1f, 0x52, + 0xa7, 0xea, 0xbf, 0xfa, 0x98, 0xe4, 0x18, 0xe2, + 0xdb, 0x11, 0xa3, 0xa1, 0x46, 0xeb, 0x5b, 0x99, + 0xa0, 0x0a, 0x2a, 0xe6, 0x2d, 0x98, 0xb8, 0xc2, + 0x6f, 0x7b, 0x6c, 0x45, 0xf9, 0xc0, 0xe8, 0x2f, + 0x39, 0x9f, 0x3e, 0x65, 0x8b, 0x94, 0xe9, 0xc0, + 0xe4, 0xec, 0x0a, 0xba, 0xf2, 0xc9, 0x74, 0x39, + 0x99, 0x2c, 0x81, 0x8c, 0x38, 0x66, 0x99, 0xbf, + 0xb6, 0xec, 0x93, 0x19, 0xbe, 0x8c, 0x48, 0x13, + 0xa2, 0x41, 0xfe, 0x56, 0x08, 0x5f, 0x7c, 0x8b, + 0xe6, 0x18, 0x89, 0xe6, 0xf0, 0xd9, 0x11, 0x4e, + 0x9a, 0x3e, 0x94, 0xda, 0x35, 0xd3, 0x48, 0xa1, + 0x77, 0x4c, 0x80, 0x22, 0x28, 0x86, 0x19, 0x07, + 0x13, 0x03, 0x94, 0x84, 0x46, 0x22, 0x4c, 0x99, + 0x5c, 0x8c, 0x60, 0x1f, 0x60, 0x4c, 0x0f, 0x0a, + 0xdd, 0x90, 0xb3, 0xc4, 0xcf, 0x32, 0x54, 0x69, + 0x54, 0x80, 0x0b, 0x7c, 0xca, 0xce, 0xf3, 0x7c, + 0xf1, 0x71, 0xa8, 0xe3, 0x4f, 0x05, 0x0c, 0x81, + 0xa1, 0xf2, 0x5a, 0x58, 0x1e, 0x66, 0x82, 0xec, + 0xa0, 0x81, 0x45, 0x71, 0xfc, 0xa5, 0x91, 0x3d, + 0x6e, 0x14, 0x0f, 0x5a, 0xdc, 0xe0, 0xea, 0x1e, + 0xae, 0x6d, 0x4a, 0x1b, 0x27, 0x4b, 0x0d, 0x0a, + 0x7d, 0x5c, 0x55, 0x15, 0xa7, 0xc4, 0x33, 0x81, + 0x3b, 0x74, 0x36, 0x45, 0x1f, 0x7a, 0xa4, 0x30, + 0x3f, 0x4e, 0x61, 0x9c, 0x1f, 0x98, 0x7f, 0x19, + 0xf1, 0xa4, 0x63, 0xf8, 0x58, 0x43, 0xe0, 0x99, + 0xab, 0xb7, 0x0f, 0x62, 0xd3, 0xae, 0xd9, 0x57, + 0xf8, 0xd8, 0xa3, 0x67, 0xbe, 0x7d, 0x30, 0x07, + 0xb0, 0x2f, 0x57, 0xae, 0x55, 0x00, 0x5a, 0xc4, + 0x22, 0x28, 0xf2, 0xc2, 0xaa, 0x35, 0x93, 0x71, + 0x34, 0xfa, 0xc7, 0x3d, 0xf9, 0xd2, 0xc2, 0xa3, + 0xe1, 0xc2, 0x0e, 0xc2, 0x3f, 0x9f, 0x3f, 0xf3, + 0x58, 0xed, 0xc0, 0x35, 0xad, 0xea, 0xd0, 0xa8, + 0xaf, 0x72, 0xcc, 0x30, 0x8a, 0x36, 0x71, 0x3f, + 0x16, 0x24, 0xac, 0xe2, 0xfc, 0xca, 0x79, 0x7e, + 0x6c, 0x6f, 0x24, 0x26, 0xd8, 0xa5, 0x4d, 0x87, + 0xc6, 0x00, 0x78, 0x92, 0x52, 0xa3, 0x6e, 0xc5, + 0xa2, 0x07, 0xe9, 0x12, 0x73, 0xf3, 0xf1, 0x00, + 0x4f, 0x3c, 0x18, 0xcb, 0x6c, 0x49, 0x94, 0x14, + 0xab, 0x63, 0x03, 0x5a, 0xc8, 0x38, 0x2c, 0x06, + 0x25, 0xd1, 0x90, 0xc6, 0x3a, 0x10, 0x32, 0x26, + 0xcc, 0x8c, 0x43, 0x8c, 0x04, 0x03, 0x07, 0x2b, + 0x6b, 0xa5, 0x0b, 0x8a, 0xcc, 0x01, 0x53, 0xc6, + 0x47, 0x23, 0x1e, 0x2e, 0xb9, 0xd8, 0x08, 0x8e, + 0xd2, 0xa5, 0x1d, 0xcb, 0x67, 0x5b, 0x73, 0x28, + 0x6b, 0x31, 0x2c, 0xf1, 0xae, 0x9b, 0xc9, 0xe9, + 0xa6, 0xd9, 0x3f, 0x74, 0x66, 0x5b, 0xd4, 0xb1, + 0xe6, 0x5a, 0xf6, 0x34, 0x75, 0x7b, 0x9a, 0x36, + 0xf7, 0x34, 0xdd, 0xa2, 0xa7, 0x69, 0x65, 0x4f, + 0x81, 0xdb, 0x53, 0xd0, 0xdc, 0x53, 0xb0, 0x45, + 0x4f, 0x81, 0xea, 0x09, 0x63, 0xb8, 0x55, 0xcb, + 0x9a, 0x0d, 0x12, 0xc8, 0x6d, 0x4b, 0x8c, 0x37, + 0x24, 0xf4, 0xdd, 0xba, 0x67, 0xfc, 0xb6, 0x9a, + 0xbd, 0x12, 0xdb, 0xb6, 0x17, 0xc1, 0x1a, 0x25, + 0xb0, 0xab, 0xc9, 0x51, 0x1f, 0xeb, 0x42, 0x5f, + 0xa9, 0x5d, 0x99, 0x64, 0xf2, 0xf0, 0xaf, 0xa8, + 0x6c, 0x12, 0x51, 0x4f, 0xb3, 0x6a, 0x6e, 0xb0, + 0x1e, 0xb4, 0x3a, 0x78, 0x15, 0x27, 0x0c, 0xdc, + 0xce, 0x52, 0x5a, 0xda, 0x69, 0x8f, 0x37, 0xcd, + 0x48, 0x76, 0xf7, 0x7c, 0xf7, 0x7e, 0xcf, 0xf7, + 0xa5, 0xeb, 0xc3, 0xbb, 0xbb, 0xc5, 0x9d, 0x83, + 0x69, 0xf5, 0xbd, 0x62, 0x93, 0xed, 0xc2, 0x78, + 0x21, 0x3d, 0x9e, 0x86, 0x46, 0x34, 0x0b, 0xb3, + 0xe6, 0xee, 0x8e, 0xf2, 0xb6, 0x8d, 0x3c, 0xba, + 0xc6, 0x07, 0x34, 0x99, 0x57, 0x1b, 0x72, 0xae, + 0x62, 0x0b, 0xfa, 0xe0, 0xba, 0x0c, 0xf3, 0x1b, + 0x09, 0xd9, 0x2f, 0x86, 0x92, 0x44, 0x5d, 0xe0, + 0x6f, 0x7f, 0x63, 0x4a, 0x75, 0x7d, 0x49, 0xaa, + 0xab, 0xf1, 0xe9, 0x03, 0xd5, 0xe2, 0x66, 0x05, + 0xa5, 0xce, 0x7e, 0x23, 0x82, 0x19, 0x62, 0xb0, + 0x4e, 0x15, 0x61, 0xa2, 0x48, 0x75, 0xca, 0x9a, + 0x17, 0x7c, 0x41, 0x4c, 0x72, 0x02, 0x74, 0x48, + 0x33, 0xb1, 0x44, 0x2e, 0x1e, 0xd6, 0x42, 0xc3, + 0x40, 0xc5, 0xfa, 0xce, 0x3d, 0x7c, 0xef, 0xc1, + 0xbf, 0xd7, 0xf2, 0xee, 0x55, 0xf6, 0xab, 0x26, + 0xfb, 0xd7, 0x15, 0x8d, 0x40, 0x87, 0x4d, 0x46, + 0xa0, 0x6b, 0x99, 0x54, 0x78, 0x28, 0x9a, 0xab, + 0x58, 0x51, 0x1e, 0xa2, 0x4d, 0x44, 0xcf, 0x76, + 0x37, 0x9b, 0x1a, 0x9a, 0x74, 0xbd, 0xfe, 0xcc, + 0x3b, 0xa3, 0x24, 0x29, 0x3d, 0x1a, 0xa9, 0xf8, + 0xf5, 0xb0, 0x5d, 0xa5, 0x49, 0xcb, 0x72, 0xec, + 0xf8, 0x5e, 0xef, 0xeb, 0xaf, 0x27, 0xf5, 0x7f, + 0xd2, 0x8a, 0xfc, 0x97, 0xe8, 0x23, 0xf0, 0xd0, + 0x2c, 0x09, 0x3b, 0x2f, 0x83, 0x9d, 0x97, 0xc1, + 0x43, 0xf5, 0x32, 0xa0, 0xca, 0xd0, 0x79, 0x38, + 0xde, 0xc2, 0xd1, 0xa0, 0xd6, 0x33, 0x41, 0xb6, + 0xde, 0xb7, 0xb9, 0xea, 0x2e, 0xe4, 0xed, 0x47, + 0x84, 0xbc, 0xbd, 0x6e, 0x48, 0x5b, 0x67, 0x5a, + 0x6b, 0xe3, 0xda, 0xde, 0x78, 0x0c, 0xda, 0xba, + 0x78, 0x40, 0x5b, 0x06, 0x70, 0x14, 0x88, 0xd6, + 0x7a, 0xc2, 0x7f, 0x74, 0x4c, 0x24, 0xeb, 0xd9, + 0x98, 0xd5, 0x1f, 0x6c, 0xa9, 0x67, 0xfd, 0xe7, + 0x03, 0xfd, 0x50, 0x0c, 0xc3, 0x0b, 0x0e, 0x8e, + 0x69, 0xa5, 0xc4, 0xbc, 0xfc, 0xf0, 0xe3, 0xf0, + 0xf4, 0x7c, 0x6f, 0x01, 0x02, 0x11, 0x05, 0x10, + 0x33, 0x63, 0xf4, 0x69, 0x56, 0xda, 0xb0, 0xaa, + 0x55, 0xe3, 0x71, 0xa8, 0x78, 0x1c, 0xcd, 0x51, + 0x46, 0x4b, 0x93, 0x32, 0x0d, 0x60, 0x98, 0xc1, + 0xf2, 0x57, 0x10, 0x41, 0x79, 0xc1, 0x1e, 0xff, + 0x02, 0xf2, 0xf9, 0x69, 0x1c, 0x5e, 0xd0, 0x0b, + 0x8e, 0x96, 0x48, 0x13, 0x0a, 0x8c, 0xc1, 0x93, + 0x47, 0x60, 0xe4, 0xe7, 0x72, 0xde, 0xf0, 0x76, + 0x36, 0xc5, 0xbc, 0x7a, 0xa0, 0xde, 0x52, 0x3e, + 0x88, 0x31, 0x0b, 0x65, 0x53, 0x7e, 0xb1, 0x49, + 0x61, 0x04, 0x31, 0x2b, 0x41, 0xae, 0xf9, 0x84, + 0x48, 0x8e, 0x57, 0x41, 0x52, 0x9c, 0x5b, 0x62, + 0xc0, 0x76, 0x4c, 0xff, 0xc1, 0xe7, 0x3a, 0x0b, + 0xa1, 0x56, 0xc2, 0x5a, 0x94, 0x44, 0x29, 0x83, + 0x39, 0xa5, 0x5f, 0xa6, 0x54, 0xe9, 0x09, 0x4d, + 0x32, 0x7d, 0x08, 0xd4, 0x07, 0xf1, 0x2f, 0x2e, + 0xc2, 0x11, 0x02, 0xf9, 0xb3, 0x26, 0x66, 0xe5, + 0x80, 0x85, 0x8b, 0x3c, 0x8a, 0x69, 0xc9, 0x79, + 0xd2, 0x11, 0x6b, 0xf2, 0xe4, 0x00, 0xff, 0x58, + 0x86, 0x59, 0x04, 0x03, 0x23, 0x7d, 0x24, 0x57, + 0x49, 0x00, 0x1e, 0x77, 0xf4, 0xff, 0x1e, 0xcb, + 0x8f, 0xff, 0x0f, 0xfe, 0x51, 0x3f, 0xfa, 0xa3, + 0x0f, 0x3f, 0x01, 0xfc, 0x8c, 0xcc, 0x8f, 0x15, + 0x35, 0xaf, 0x02, 0x73, 0x0c, 0x3f, 0x21, 0xfc, + 0x4c, 0x6e, 0x10, 0xe6, 0x14, 0x7e, 0x66, 0xf0, + 0x13, 0x5d, 0x09, 0xa6, 0xf9, 0x64, 0x87, 0xab, + 0x77, 0x06, 0xf9, 0xd0, 0xbe, 0x78, 0xcc, 0x55, + 0xd6, 0x8e, 0x98, 0x6f, 0x54, 0xcb, 0xd5, 0xef, + 0x6b, 0xae, 0x3f, 0x59, 0x6a, 0x58, 0xd0, 0x08, + 0xa6, 0xb7, 0xa1, 0xf5, 0xa8, 0xb1, 0xf5, 0xb6, + 0x38, 0x8c, 0xb7, 0x1e, 0x4a, 0xaf, 0xa2, 0x75, + 0x58, 0xd9, 0xba, 0x5c, 0x6f, 0xb2, 0x2d, 0xae, + 0x55, 0x9d, 0x4c, 0xb7, 0x46, 0xb1, 0x69, 0xa0, + 0xb3, 0x4d, 0x93, 0xdd, 0xd4, 0x38, 0xda, 0x16, + 0xff, 0x32, 0x10, 0x49, 0x4c, 0xe4, 0xc7, 0x81, + 0x39, 0x46, 0xa2, 0x8b, 0x48, 0x24, 0x94, 0xb9, + 0xa4, 0x6b, 0xf0, 0x35, 0xcb, 0xe3, 0x74, 0x11, + 0x52, 0x5e, 0x87, 0x67, 0xa8, 0xb2, 0xe2, 0x06, + 0xa4, 0x78, 0xfd, 0xea, 0x56, 0x9c, 0xda, 0xea, + 0xef, 0xc0, 0x8f, 0xdf, 0xfb, 0x82, 0xdd, 0x1c, + 0xd0, 0xe7, 0x36, 0x8b, 0xf4, 0x96, 0xc5, 0x78, + 0x9e, 0xcb, 0xf9, 0x04, 0xda, 0xf0, 0xa4, 0x28, + 0xd4, 0x17, 0x1d, 0xc4, 0x98, 0xb9, 0x83, 0xef, + 0x6f, 0xb6, 0xc0, 0x1c, 0x11, 0x11, 0x19, 0x19, + 0x44, 0x36, 0x24, 0xac, 0x88, 0x81, 0x59, 0xdb, + 0xba, 0x5b, 0xcc, 0x0b, 0x82, 0x19, 0x94, 0xfe, + 0x58, 0x46, 0xc0, 0xe5, 0x42, 0xca, 0x48, 0xf2, + 0x82, 0x90, 0x3c, 0xea, 0xf5, 0x9e, 0x1e, 0xf7, + 0xfa, 0x4f, 0xba, 0x4f, 0x9e, 0x1d, 0x1f, 0x3f, + 0x7d, 0x76, 0x8c, 0x90, 0x8f, 0xfb, 0x03, 0xa1, + 0x71, 0x93, 0x0c, 0x84, 0xcc, 0xb6, 0xed, 0x00, + 0xc3, 0xe4, 0x2d, 0x01, 0x26, 0x14, 0xc6, 0xa4, + 0x19, 0x63, 0x82, 0x26, 0xea, 0xf7, 0x9f, 0xc3, + 0x11, 0xf2, 0xa4, 0xff, 0xfc, 0x39, 0x00, 0x1b, + 0x3c, 0x25, 0x95, 0x98, 0x00, 0xe8, 0x7c, 0x27, + 0x2a, 0x25, 0x0a, 0x8f, 0xe1, 0x4a, 0x1e, 0x39, + 0xe1, 0xa5, 0x3f, 0x9d, 0x86, 0x19, 0x3a, 0xcd, + 0xe0, 0x20, 0x67, 0x51, 0x1c, 0x4b, 0x47, 0x80, + 0x62, 0x86, 0x19, 0x52, 0x3d, 0xe8, 0x6e, 0xe4, + 0xa3, 0x13, 0x42, 0x0a, 0x15, 0xb2, 0x55, 0x64, + 0xa5, 0xc1, 0xc1, 0x50, 0x92, 0x7e, 0x86, 0x29, + 0x5a, 0x92, 0x14, 0xc3, 0xc2, 0xfa, 0x01, 0x4c, + 0x08, 0x2c, 0x37, 0xa8, 0x30, 0x94, 0xf4, 0x23, + 0xef, 0x62, 0x7f, 0xe3, 0x94, 0x12, 0x49, 0x51, + 0x5a, 0x16, 0x95, 0x8a, 0x83, 0x52, 0x4b, 0x05, + 0x98, 0x07, 0x66, 0xae, 0x20, 0x5a, 0xc9, 0x41, + 0xc4, 0xb8, 0x5a, 0x7c, 0x1c, 0x34, 0x20, 0x71, + 0x02, 0xd1, 0xbb, 0xbc, 0xb6, 0x58, 0x55, 0xf2, + 0xea, 0x81, 0x59, 0xf1, 0xb3, 0x20, 0x2a, 0x32, + 0x74, 0x50, 0xa0, 0xf3, 0x44, 0x82, 0xfc, 0x1f, + 0x41, 0x35, 0x38, 0x02, 0xff, 0x65, 0xaf, 0x7b, + 0x28, 0x26, 0x12, 0x96, 0xf3, 0x7d, 0x8e, 0xef, + 0x12, 0xa5, 0xfb, 0x42, 0x78, 0x09, 0xa7, 0x6d, + 0x4e, 0x87, 0x6d, 0x10, 0x02, 0xfe, 0x5d, 0x96, + 0x87, 0x21, 0x93, 0x60, 0x92, 0x68, 0xf4, 0x3e, + 0x1a, 0xc7, 0xcb, 0xa9, 0x9f, 0xcf, 0x1e, 0x41, + 0x7f, 0xab, 0x10, 0xf1, 0x66, 0x41, 0x16, 0xfa, + 0xef, 0xc7, 0xe9, 0x2a, 0x21, 0xb7, 0x9c, 0x79, + 0x4a, 0xe9, 0x63, 0x27, 0xa9, 0x22, 0xd9, 0xa2, + 0x58, 0xe4, 0x2f, 0x0e, 0x0e, 0xa6, 0x51, 0x31, + 0x5b, 0x06, 0xdd, 0x51, 0x3a, 0x3f, 0x98, 0xfb, + 0x8b, 0x20, 0xbd, 0x14, 0xff, 0x74, 0xa6, 0x71, + 0xe7, 0x3f, 0x40, 0x81, 0xcb, 0x38, 0x3e, 0x38, + 0x1e, 0x3c, 0x7b, 0xf2, 0xf5, 0x38, 0xca, 0x47, + 0x4b, 0x42, 0x62, 0x98, 0xf5, 0x8f, 0x9e, 0x1d, + 0xf5, 0x9f, 0x1f, 0x1f, 0x3f, 0xb1, 0xa2, 0x67, + 0x8a, 0xe5, 0x92, 0x02, 0x08, 0x4d, 0xcd, 0xdf, + 0x49, 0x88, 0xc0, 0x1c, 0x7c, 0x47, 0xec, 0x85, + 0xfe, 0x78, 0xd4, 0x3d, 0xa6, 0x8f, 0x87, 0xc7, + 0xf0, 0x15, 0xfe, 0xb1, 0x8c, 0xc7, 0x70, 0x56, + 0x5d, 0x48, 0x9b, 0xad, 0x32, 0x07, 0xb5, 0x46, + 0xb0, 0x23, 0x27, 0xe2, 0x27, 0x6a, 0xc3, 0x9c, + 0xb7, 0x7c, 0x3c, 0x37, 0xc5, 0xcf, 0xd4, 0x08, + 0x63, 0xdc, 0x9a, 0xc2, 0x87, 0x99, 0xf8, 0xd1, + 0x55, 0x03, 0xf1, 0x33, 0x12, 0xe9, 0xf9, 0x80, + 0xac, 0xf9, 0x42, 0xa2, 0xdd, 0xa8, 0x66, 0x29, + 0xad, 0x41, 0x3d, 0x16, 0x84, 0x3c, 0xd0, 0x14, + 0x5c, 0xad, 0x06, 0x70, 0x9b, 0x11, 0xc9, 0x5d, + 0xda, 0x9c, 0x85, 0xa3, 0x02, 0xc9, 0x58, 0x4b, + 0x55, 0xc7, 0x9e, 0x53, 0xb8, 0xae, 0x2e, 0xec, + 0x9b, 0xa9, 0x08, 0xb9, 0x35, 0xad, 0x77, 0x17, + 0xc9, 0x34, 0x1e, 0xa4, 0xb4, 0x5a, 0x2d, 0xac, + 0x6e, 0x52, 0x24, 0x2a, 0x91, 0x72, 0x64, 0xce, + 0x18, 0x30, 0x40, 0x7f, 0xb6, 0x92, 0x30, 0x2a, + 0x5c, 0xf9, 0xdc, 0xcb, 0x7f, 0x60, 0x45, 0xe9, + 0xaa, 0xf4, 0x59, 0xb9, 0xbf, 0x95, 0x4a, 0xfc, + 0x11, 0x86, 0x35, 0xc6, 0x05, 0x13, 0xa9, 0x66, + 0x5e, 0x9f, 0xb1, 0xc3, 0x6e, 0xff, 0xa8, 0x7f, + 0xfc, 0x7c, 0xf0, 0xe4, 0xf8, 0xf0, 0xf8, 0xd9, + 0xf3, 0xa7, 0xcf, 0x0f, 0xeb, 0x43, 0x93, 0xd3, + 0x01, 0xd1, 0xa0, 0xc3, 0x54, 0xed, 0xa0, 0x16, + 0x3f, 0x10, 0xba, 0xd9, 0x94, 0x67, 0x1e, 0x6b, + 0x97, 0x52, 0x8f, 0xfd, 0x6e, 0x9d, 0x59, 0x74, + 0x56, 0x21, 0xe3, 0xf3, 0x6d, 0x76, 0x67, 0xe5, + 0x7e, 0x1f, 0xc1, 0xb2, 0x25, 0xf2, 0xe4, 0x21, + 0xf8, 0xc8, 0x74, 0x16, 0x8b, 0x2c, 0xbd, 0xc4, + 0x4c, 0x35, 0x18, 0xa5, 0xb8, 0xa0, 0xa8, 0xd1, + 0x46, 0x86, 0x6b, 0x18, 0x3b, 0xa6, 0xa6, 0xe7, + 0x9c, 0x28, 0xcc, 0x46, 0x3e, 0x31, 0x51, 0x1e, + 0x0b, 0x9d, 0x72, 0x16, 0x45, 0x39, 0x7c, 0xa1, + 0x38, 0x15, 0xc4, 0xda, 0xbe, 0x3e, 0x7a, 0xd6, + 0x7b, 0x4a, 0xb5, 0xc7, 0x61, 0xe1, 0x47, 0x71, + 0x6e, 0x06, 0xd8, 0x45, 0xcc, 0xbe, 0x97, 0x31, + 0xc0, 0xd1, 0x9d, 0x12, 0xdd, 0xf0, 0xfc, 0x24, + 0x6f, 0xb5, 0xf4, 0x22, 0xbe, 0xed, 0xbd, 0xe3, + 0x96, 0x57, 0xf9, 0x77, 0xff, 0x1d, 0x6e, 0x67, + 0x61, 0xc3, 0x16, 0xea, 0x68, 0x9b, 0x1b, 0xac, + 0x8d, 0x2a, 0x82, 0xd8, 0xf8, 0xc4, 0x50, 0x2a, + 0x33, 0xe3, 0x4c, 0x30, 0xe7, 0xc7, 0xe4, 0xe9, + 0x1f, 0x3a, 0x62, 0x9a, 0x60, 0x4e, 0xfa, 0xc0, + 0x1f, 0x4c, 0x5c, 0xa9, 0x01, 0x50, 0x6d, 0xe1, + 0x27, 0x2d, 0x2c, 0xc3, 0xc4, 0x58, 0xfc, 0xf5, + 0x38, 0xad, 0x11, 0xf2, 0x20, 0x63, 0x3c, 0xf6, + 0xd3, 0x71, 0x0a, 0x73, 0x0d, 0x8d, 0x25, 0xe7, + 0xe0, 0x26, 0x72, 0xbc, 0x5c, 0x41, 0x68, 0x82, + 0x65, 0x60, 0x28, 0x5e, 0x5e, 0xde, 0x06, 0x4e, + 0x0a, 0x24, 0x25, 0xc3, 0x7b, 0xc8, 0x0a, 0xea, + 0x9a, 0xa8, 0x4f, 0x59, 0x50, 0x3b, 0xa5, 0xec, + 0xa9, 0x3a, 0xb9, 0xcf, 0x4b, 0x49, 0xec, 0x52, + 0x6d, 0x17, 0xf3, 0x30, 0x1e, 0x23, 0x60, 0x19, + 0x4b, 0x9d, 0x0e, 0x47, 0x58, 0x3b, 0x10, 0x32, + 0xa0, 0x0d, 0xac, 0xb8, 0x88, 0x34, 0x3e, 0x8d, + 0xd3, 0xc0, 0x8f, 0x85, 0xab, 0x5d, 0x1a, 0xe0, + 0xd2, 0x7a, 0xe2, 0x40, 0x03, 0x08, 0x39, 0x80, + 0x38, 0x18, 0x58, 0xfe, 0x78, 0x48, 0x36, 0x1f, + 0xa2, 0xf9, 0xb2, 0x98, 0xe9, 0xe4, 0x5a, 0x32, + 0xaf, 0x96, 0xee, 0xc0, 0xa1, 0x9e, 0xde, 0x38, + 0x9c, 0xc2, 0xa2, 0x67, 0x70, 0x1e, 0x2e, 0xd2, + 0x44, 0x26, 0xa6, 0x4b, 0x80, 0x78, 0x66, 0x07, + 0x94, 0x29, 0x3d, 0x5d, 0x48, 0xda, 0xbc, 0x88, + 0xc2, 0xd5, 0x02, 0x0a, 0x64, 0xa2, 0xc9, 0xbc, + 0x58, 0x03, 0x49, 0xe3, 0xac, 0x9a, 0x4e, 0xa6, + 0x58, 0x92, 0x66, 0xd1, 0x94, 0x5c, 0x20, 0x45, + 0x1a, 0xba, 0x95, 0x9f, 0xb3, 0x55, 0x16, 0x15, + 0x30, 0x31, 0xa2, 0xff, 0x70, 0x51, 0xb0, 0x56, + 0x07, 0x24, 0x10, 0x72, 0x88, 0x46, 0x0c, 0xbf, + 0x93, 0x37, 0x02, 0x40, 0x4f, 0xcf, 0x61, 0x67, + 0xf9, 0xc2, 0x7f, 0x57, 0x8e, 0xa8, 0x6b, 0x2e, + 0x25, 0xff, 0x68, 0x4c, 0xf0, 0x1a, 0x48, 0xef, + 0xf5, 0x99, 0xb5, 0x0f, 0xf9, 0x8e, 0xd3, 0x64, + 0x06, 0x87, 0x7e, 0x9a, 0x84, 0x94, 0xa0, 0x16, + 0xdd, 0x93, 0xe5, 0x16, 0x54, 0xcb, 0x05, 0x62, + 0x18, 0xe5, 0xa6, 0xf7, 0x41, 0xf0, 0xe2, 0xce, + 0xc5, 0xfc, 0x86, 0x6c, 0x1e, 0xc5, 0x3e, 0x3a, + 0x3e, 0x9a, 0x8e, 0xba, 0x06, 0x2c, 0x3b, 0xba, + 0x01, 0x9b, 0x2c, 0x13, 0x3e, 0x8a, 0xd2, 0x24, + 0xbd, 0xb8, 0xa2, 0xa4, 0x10, 0xc0, 0xfa, 0xc3, + 0x17, 0x4c, 0x91, 0x79, 0x90, 0x67, 0xa3, 0x03, + 0x82, 0xd4, 0x41, 0x48, 0x07, 0x5a, 0x7e, 0x39, + 0x20, 0xde, 0x47, 0x4b, 0x9c, 0x1f, 0x68, 0x4c, + 0xc2, 0xee, 0x7f, 0xf2, 0xaf, 0x7f, 0x1c, 0xf4, + 0x9f, 0x76, 0x7e, 0x1c, 0x0c, 0x9e, 0xb9, 0xee, + 0x9f, 0xc8, 0x53, 0x61, 0x55, 0x34, 0xa1, 0x0a, + 0x77, 0xe3, 0x11, 0x48, 0x38, 0x98, 0x39, 0x15, + 0x45, 0x9b, 0x74, 0xe1, 0x83, 0x92, 0x6b, 0x0a, + 0x89, 0xe6, 0x02, 0x08, 0x93, 0x77, 0xbf, 0xfb, + 0xec, 0xe9, 0x31, 0xac, 0x97, 0x99, 0xcf, 0xaa, + 0xdf, 0x7d, 0x7a, 0x6c, 0x6e, 0x3b, 0x38, 0xfc, + 0x7f, 0x13, 0x4e, 0xeb, 0x3c, 0xaf, 0x02, 0x2e, + 0x93, 0xc3, 0x7d, 0xc6, 0xe7, 0x62, 0x5f, 0x6b, + 0x40, 0x5f, 0xf1, 0xea, 0xdf, 0x20, 0xcf, 0x05, + 0x99, 0x82, 0xbb, 0x91, 0xd0, 0x42, 0x4a, 0xa6, + 0x4b, 0xf2, 0xb9, 0x2a, 0x92, 0xdd, 0xc8, 0x52, + 0xe4, 0x4e, 0xaa, 0xeb, 0x17, 0xbc, 0xa5, 0x99, + 0x21, 0x32, 0x64, 0xfc, 0xfc, 0x10, 0x6e, 0x77, + 0xb0, 0x05, 0xe5, 0xaa, 0xdb, 0xde, 0xb0, 0x39, + 0x9e, 0x2c, 0x62, 0x03, 0x70, 0x3a, 0x82, 0x2d, + 0x28, 0xe9, 0x0a, 0xa9, 0xbb, 0x19, 0x00, 0x36, + 0x77, 0xa7, 0xbf, 0x70, 0x3a, 0x87, 0x7d, 0x4b, + 0x42, 0x39, 0xf4, 0x32, 0x9a, 0x91, 0x07, 0x78, + 0x48, 0x99, 0x52, 0x81, 0x82, 0x2a, 0xfb, 0x82, + 0xfa, 0xbc, 0x02, 0x48, 0xb4, 0xd6, 0xae, 0xe0, + 0x30, 0x39, 0x0f, 0x37, 0xe6, 0xd5, 0x62, 0xc2, + 0x8a, 0xff, 0x52, 0xf2, 0x02, 0x03, 0x15, 0xdc, + 0xbb, 0xe6, 0x80, 0xe8, 0xd4, 0x22, 0xc1, 0x0b, + 0xc6, 0xe3, 0x90, 0x8a, 0x3b, 0x22, 0x59, 0x1c, + 0x01, 0x52, 0xff, 0xc5, 0x17, 0x6e, 0x9c, 0x52, + 0xd0, 0x79, 0x4c, 0x5e, 0xc0, 0xaf, 0xf9, 0x30, + 0x23, 0x1f, 0xa5, 0x79, 0x14, 0x13, 0x8b, 0x7d, + 0x70, 0xba, 0x33, 0xb4, 0x1e, 0x4c, 0x1f, 0xe9, + 0x52, 0xe5, 0xdf, 0x09, 0x9e, 0x60, 0x95, 0x21, + 0xa5, 0xd0, 0x00, 0x68, 0x02, 0x02, 0xd1, 0x2a, + 0x9e, 0x37, 0xf9, 0x02, 0x74, 0x93, 0x44, 0xcc, + 0x07, 0xf7, 0x8f, 0xa2, 0x71, 0xa9, 0xa7, 0x0e, + 0xe2, 0xa8, 0xe2, 0x5f, 0xb9, 0x85, 0x52, 0x8c, + 0x7c, 0x5f, 0xc8, 0x97, 0x26, 0x15, 0x0f, 0x6a, + 0xaf, 0x83, 0xf9, 0x1c, 0xf1, 0x20, 0xf0, 0x68, + 0x7c, 0x6f, 0x89, 0x73, 0xe5, 0xb1, 0xe4, 0x4a, + 0x48, 0x98, 0xc0, 0xde, 0xb9, 0xd0, 0x69, 0x4b, + 0x09, 0x0a, 0x37, 0x02, 0xa2, 0x50, 0x43, 0xb3, + 0xb8, 0x14, 0x80, 0x3c, 0x53, 0xe6, 0xf1, 0x78, + 0x45, 0xc4, 0x16, 0x08, 0xc9, 0x5a, 0xd3, 0xad, + 0xb1, 0x76, 0x04, 0x56, 0x6b, 0x56, 0xd4, 0x01, + 0x6e, 0xe0, 0xd3, 0xf5, 0xf1, 0x18, 0x37, 0x3e, + 0xdc, 0x88, 0x48, 0xbc, 0xb7, 0x27, 0x38, 0xa7, + 0xce, 0x3f, 0x7a, 0x81, 0x07, 0x03, 0x1d, 0x67, + 0xfc, 0x04, 0x4b, 0x44, 0xb2, 0x4f, 0xbc, 0x0e, + 0x10, 0xb4, 0x4d, 0x4f, 0x67, 0x0a, 0x38, 0x20, + 0xe0, 0xcc, 0xbe, 0xa0, 0x4c, 0x24, 0x94, 0x6a, + 0x14, 0xa4, 0xa9, 0x39, 0x90, 0x00, 0xb4, 0x37, + 0xe3, 0xce, 0xf8, 0x24, 0xe9, 0x51, 0x2e, 0x12, + 0xe2, 0x56, 0x52, 0x2c, 0x7c, 0xf5, 0xd3, 0x9b, + 0xb3, 0x57, 0x3f, 0x9e, 0xbd, 0x3a, 0x3f, 0xfb, + 0xe9, 0x07, 0x61, 0xd3, 0xfb, 0xee, 0xf4, 0xb7, + 0xb3, 0x6f, 0x4f, 0x87, 0xaf, 0xcf, 0xfe, 0x79, + 0xfa, 0xe3, 0xf0, 0x97, 0x57, 0x6f, 0xce, 0x7e, + 0xe6, 0xc7, 0x3c, 0x61, 0xc9, 0xd3, 0x3a, 0xf6, + 0x41, 0xaf, 0x86, 0x6f, 0x94, 0xff, 0xf3, 0x09, + 0x66, 0xe6, 0x14, 0xf8, 0x03, 0x4f, 0x81, 0x55, + 0x9e, 0x43, 0x3f, 0xe8, 0x7f, 0x00, 0x92, 0x65, + 0x54, 0xd0, 0xa3, 0x8b, 0x39, 0xd7, 0x90, 0x51, + 0x56, 0x10, 0x5b, 0x7c, 0x9e, 0xa2, 0x17, 0x7d, + 0x57, 0xe7, 0x05, 0x19, 0xab, 0x77, 0x27, 0x11, + 0xe5, 0x48, 0x46, 0x11, 0x8d, 0xf6, 0x16, 0x0c, + 0x28, 0x58, 0x03, 0x03, 0x68, 0x75, 0xfa, 0x83, + 0x67, 0xdd, 0x2e, 0x74, 0xdd, 0xee, 0x52, 0xaa, + 0x5c, 0x3a, 0xc1, 0xb2, 0x70, 0xba, 0xc4, 0x13, + 0x88, 0xb7, 0xcd, 0x31, 0xb9, 0x2a, 0x8c, 0x56, + 0xe4, 0x1d, 0x78, 0x72, 0x08, 0x4a, 0xfb, 0xb2, + 0x10, 0xd8, 0xa1, 0x8a, 0x9c, 0x09, 0x41, 0xeb, + 0xaf, 0x48, 0x96, 0x70, 0x3e, 0xfd, 0x55, 0x35, + 0xe4, 0xbc, 0xdf, 0xbf, 0x40, 0x3d, 0x3a, 0x88, + 0x50, 0x0d, 0x93, 0x50, 0x5a, 0xc0, 0x7a, 0x38, + 0x58, 0x7c, 0x4a, 0x14, 0x25, 0x2a, 0x1d, 0x34, + 0xa6, 0x6c, 0x6e, 0xd3, 0x3a, 0xc8, 0xd9, 0xe4, + 0x38, 0xd1, 0x8c, 0xd8, 0x9f, 0x30, 0x37, 0xfc, + 0xf1, 0xb3, 0xa7, 0x87, 0xbd, 0xfe, 0x93, 0xbd, + 0xb2, 0x33, 0x2d, 0x5e, 0x50, 0x71, 0x3c, 0x2a, + 0x3c, 0x6d, 0xd1, 0x56, 0xbb, 0x39, 0xba, 0x76, + 0x39, 0x57, 0x37, 0x25, 0x2b, 0x71, 0x94, 0x0b, + 0x20, 0x46, 0xca, 0xc8, 0x82, 0x8e, 0x93, 0xdc, + 0x7a, 0x53, 0xd6, 0xa1, 0x24, 0x22, 0xce, 0x67, + 0xca, 0xc7, 0x30, 0x28, 0xe7, 0x29, 0x99, 0xfa, + 0xf3, 0xb9, 0x2f, 0x9d, 0x93, 0xab, 0x72, 0x71, + 0xe2, 0xc5, 0x54, 0x12, 0xe6, 0xe9, 0xc4, 0xcf, + 0x3e, 0xd1, 0x1c, 0x05, 0x94, 0xbb, 0xa7, 0xda, + 0x05, 0x19, 0x4a, 0x1a, 0x5c, 0x90, 0xa1, 0xb4, + 0xda, 0x05, 0x99, 0x0a, 0x9a, 0xbc, 0x18, 0x44, + 0x85, 0x4f, 0x2a, 0xa0, 0x78, 0x35, 0x96, 0x53, + 0x7f, 0x41, 0xa4, 0x53, 0x8d, 0xa6, 0x2c, 0x6d, + 0xcc, 0x4e, 0x2f, 0x2b, 0x6d, 0xca, 0x4f, 0x6f, + 0xd6, 0x6b, 0x9e, 0xb9, 0xc9, 0x24, 0x0f, 0x6b, + 0x9c, 0xb7, 0x79, 0x59, 0xc3, 0xbc, 0x51, 0x79, + 0xf3, 0xd4, 0xa8, 0x2a, 0x8d, 0x58, 0x34, 0x4c, + 0xcb, 0xe6, 0x39, 0xd9, 0x6a, 0x42, 0xdc, 0xd9, + 0xf8, 0x74, 0x92, 0x5b, 0xa8, 0x74, 0x59, 0xf8, + 0x4b, 0xb5, 0xeb, 0x34, 0x14, 0x78, 0x6a, 0x0b, + 0xd6, 0xba, 0x4e, 0x8b, 0xe6, 0xce, 0x8e, 0xfa, + 0x44, 0x82, 0x33, 0xa9, 0xbd, 0x53, 0xce, 0x38, + 0x2f, 0x8b, 0x2a, 0x71, 0x93, 0x85, 0x9e, 0xb5, + 0xc3, 0x1a, 0xf2, 0xd7, 0x9b, 0xd0, 0x2a, 0xb6, + 0x51, 0xd3, 0x74, 0xf1, 0xad, 0xe4, 0x0e, 0x98, + 0xbe, 0x56, 0xcf, 0x1b, 0x15, 0x79, 0xc6, 0x4e, + 0xab, 0x9d, 0x35, 0x05, 0xa4, 0xb4, 0xa3, 0x1a, + 0x10, 0xaa, 0x9b, 0xb0, 0xfa, 0xd9, 0x52, 0x53, + 0xb5, 0x79, 0x9e, 0xf4, 0x24, 0xb9, 0x5b, 0x4b, + 0x59, 0xc3, 0x7c, 0x2b, 0x53, 0x19, 0x5d, 0xb4, + 0x5e, 0xa2, 0x33, 0x2f, 0x0a, 0x2f, 0x3d, 0xcb, + 0xe2, 0x32, 0x54, 0x6e, 0x7e, 0xc2, 0x53, 0x45, + 0x54, 0xff, 0xe0, 0x51, 0x22, 0x3b, 0x2e, 0x17, + 0x1b, 0x7e, 0x99, 0xe2, 0x10, 0x45, 0x69, 0x5d, + 0x26, 0xd7, 0xe6, 0xf5, 0xf9, 0xb5, 0x2d, 0x0a, + 0xa6, 0xe2, 0x0b, 0xa6, 0x85, 0x7b, 0x72, 0xc4, + 0x73, 0x72, 0x0d, 0x34, 0x0c, 0xed, 0xa0, 0x63, + 0x8a, 0x1c, 0xe4, 0x11, 0x24, 0xb5, 0x8c, 0x4b, + 0x14, 0xd3, 0xfa, 0xe8, 0x2c, 0x19, 0x91, 0xc5, + 0x84, 0x65, 0xf8, 0x76, 0x12, 0x24, 0x9d, 0x05, + 0x88, 0xce, 0xe5, 0x8b, 0x8f, 0xb5, 0xaa, 0x8e, + 0x72, 0x9c, 0x90, 0xdf, 0x16, 0x98, 0x6c, 0x10, + 0x25, 0x31, 0xfe, 0x36, 0xb3, 0x23, 0xc0, 0xc9, + 0xef, 0x78, 0x49, 0xe0, 0xfa, 0x4b, 0x0d, 0x4c, + 0x7f, 0x70, 0x03, 0x35, 0xe5, 0xd3, 0x34, 0x54, + 0xe5, 0x52, 0x3c, 0x31, 0x0c, 0x0e, 0xb9, 0x50, + 0x72, 0x90, 0x07, 0x92, 0x9d, 0x21, 0xa7, 0x74, + 0x5e, 0x28, 0xb1, 0x05, 0x21, 0x1a, 0x0b, 0xe3, + 0x88, 0x4b, 0x92, 0x88, 0xe4, 0xff, 0x39, 0x27, + 0xac, 0x12, 0xfe, 0xe4, 0x1c, 0x6f, 0xe0, 0x49, + 0x5f, 0xcf, 0xbb, 0x2a, 0x45, 0x3a, 0xc8, 0xde, + 0x64, 0xa8, 0x99, 0xa3, 0xb6, 0x95, 0x6a, 0xfd, + 0x32, 0x23, 0x93, 0x10, 0xe8, 0x15, 0x19, 0xee, + 0x65, 0xd2, 0x08, 0xa3, 0x39, 0xc0, 0xc6, 0xed, + 0xcc, 0x5b, 0x1b, 0xdb, 0x48, 0xfd, 0x7a, 0xc0, + 0x57, 0xc0, 0xb8, 0x3d, 0xf4, 0xe3, 0x89, 0xac, + 0x55, 0xaa, 0xa2, 0x68, 0x1e, 0x2d, 0x67, 0x18, + 0x5e, 0x44, 0x10, 0xbe, 0x65, 0x41, 0xe3, 0x35, + 0x54, 0x0f, 0x8f, 0x59, 0x4b, 0xfd, 0x2e, 0xcd, + 0x6f, 0x96, 0x58, 0xff, 0xa2, 0x74, 0x09, 0x09, + 0xfa, 0x43, 0x09, 0x88, 0xc6, 0x6b, 0xbf, 0x02, + 0xe0, 0x80, 0xec, 0x79, 0x7d, 0x4e, 0x66, 0x2d, + 0x63, 0x0c, 0xd2, 0x4c, 0xd8, 0xa3, 0x0a, 0x66, + 0xbf, 0x86, 0xe1, 0xf7, 0x5c, 0x59, 0x9b, 0x4a, + 0x39, 0x00, 0xe9, 0xce, 0x08, 0x15, 0x14, 0xf3, + 0xd9, 0x39, 0xd4, 0x4c, 0x50, 0xe6, 0x0e, 0xd6, + 0x5a, 0xfd, 0xd1, 0x1b, 0x1b, 0x00, 0x92, 0xcd, + 0x01, 0x68, 0x0f, 0x2f, 0xf0, 0xc2, 0xcb, 0x6e, + 0x99, 0x9e, 0x44, 0xf0, 0x4c, 0x31, 0xd0, 0x7d, + 0x2b, 0x69, 0xa0, 0x7c, 0x49, 0x57, 0x7a, 0x2d, + 0x4f, 0x1a, 0x34, 0x5f, 0x81, 0x15, 0x62, 0x30, + 0xce, 0xfc, 0x15, 0x37, 0x7a, 0x11, 0x06, 0x5c, + 0x9b, 0xcf, 0xa5, 0x59, 0x91, 0xde, 0x5d, 0x0b, + 0xe3, 0x87, 0x3f, 0x2a, 0x96, 0x64, 0x8e, 0x4c, + 0xc2, 0xae, 0x69, 0xed, 0x4e, 0xd5, 0xed, 0x1e, + 0x99, 0x8f, 0x38, 0x30, 0x31, 0x72, 0x02, 0x27, + 0x36, 0x45, 0x91, 0xae, 0xfc, 0x6c, 0x9c, 0x9b, + 0xea, 0x10, 0xa9, 0x2e, 0xb0, 0xff, 0x0a, 0xc0, + 0xcc, 0xb8, 0x68, 0x24, 0xc4, 0x56, 0xe1, 0x23, + 0xd0, 0x64, 0x24, 0x7a, 0x7c, 0x8f, 0x02, 0x27, + 0x92, 0xd0, 0x5a, 0x36, 0x6f, 0x81, 0x1d, 0x08, + 0xdd, 0xf5, 0xdb, 0xa8, 0x26, 0x8f, 0x68, 0x94, + 0x91, 0x7a, 0x26, 0x2d, 0x67, 0x45, 0xe0, 0x24, + 0x00, 0xa0, 0xd6, 0x95, 0xd0, 0x6e, 0xd7, 0x8e, + 0xd1, 0xdd, 0x0a, 0x7e, 0xb8, 0x54, 0x76, 0x2b, + 0xa3, 0xc7, 0x93, 0x8a, 0x8a, 0x85, 0x76, 0xc6, + 0x0a, 0xf2, 0xd6, 0xb2, 0x7d, 0x52, 0x5e, 0x31, + 0x3e, 0xf1, 0xe8, 0x39, 0x27, 0x96, 0xa0, 0x62, + 0xd1, 0xf0, 0x8a, 0x59, 0xfa, 0x70, 0xa3, 0x05, + 0xab, 0xa0, 0x9c, 0xdf, 0x9d, 0xa5, 0xc7, 0xe0, + 0xff, 0x85, 0xe5, 0x5a, 0xa7, 0x72, 0x9f, 0x1a, + 0xfc, 0xd8, 0xbd, 0xf8, 0x21, 0x22, 0x39, 0x90, + 0xda, 0x92, 0x76, 0x73, 0xdf, 0x2a, 0x00, 0x1c, + 0xbf, 0xb5, 0x97, 0x58, 0xbb, 0x50, 0xc4, 0x4e, + 0x29, 0x61, 0xa1, 0xc9, 0x4e, 0x19, 0xc4, 0x18, + 0x06, 0xbb, 0x98, 0x2f, 0x85, 0xaa, 0x6f, 0x64, + 0x9c, 0x24, 0x9b, 0x32, 0xcb, 0xff, 0x58, 0x46, + 0xf9, 0x0c, 0x95, 0xfe, 0x0c, 0xd3, 0xfd, 0x85, + 0x98, 0x03, 0xd5, 0x22, 0x94, 0xda, 0x9c, 0x82, + 0x43, 0x34, 0xb4, 0xc1, 0x0e, 0x30, 0xb3, 0x58, + 0xea, 0x80, 0xb2, 0x46, 0xaa, 0x90, 0xda, 0xc6, + 0xd5, 0x2d, 0x4b, 0x83, 0xaa, 0x8a, 0xff, 0xbd, + 0x5f, 0xa9, 0x6e, 0xaa, 0xfb, 0x35, 0x43, 0x6d, + 0x04, 0xc0, 0x5b, 0xe0, 0x7d, 0xb0, 0x09, 0x3f, + 0x75, 0x52, 0x72, 0x4d, 0x55, 0x5e, 0xe9, 0x72, + 0x0e, 0xe0, 0x71, 0xb6, 0x79, 0xbf, 0x49, 0xc9, + 0x48, 0xa8, 0xbd, 0x75, 0x75, 0xf0, 0xb6, 0x92, + 0xef, 0xb8, 0x06, 0x80, 0x1a, 0x73, 0x41, 0xa5, + 0x5d, 0xe0, 0xce, 0xd3, 0xa7, 0x29, 0xfd, 0x61, + 0x7b, 0x5d, 0xe0, 0x06, 0x13, 0xfc, 0x94, 0x0e, + 0x15, 0x6d, 0xd7, 0x33, 0x2e, 0x32, 0xe9, 0x45, + 0x90, 0x3e, 0xdf, 0x28, 0xc1, 0x31, 0xee, 0x91, + 0x6e, 0x43, 0x0c, 0x68, 0x3e, 0xdb, 0x6d, 0xf2, + 0xf7, 0xe5, 0x0b, 0xd2, 0xcd, 0xeb, 0x4e, 0x32, + 0x9f, 0x6e, 0x60, 0xb8, 0xc1, 0x8f, 0x67, 0x36, + 0xe5, 0x37, 0x87, 0x5d, 0x9e, 0xf9, 0x14, 0xbd, + 0x71, 0x22, 0x62, 0xf1, 0x74, 0xa4, 0x4c, 0x44, + 0xd0, 0x8b, 0xc4, 0xbc, 0xc9, 0x91, 0x88, 0xa1, + 0xa5, 0x0b, 0x71, 0xf7, 0x13, 0xc9, 0x9c, 0xa9, + 0xa4, 0xa5, 0x90, 0x28, 0xda, 0xc8, 0x9e, 0x4c, + 0x40, 0x32, 0x85, 0x2a, 0x40, 0xd2, 0xd5, 0x72, + 0x33, 0x64, 0x0f, 0x2e, 0x03, 0x6e, 0xd3, 0x16, + 0x2d, 0xcc, 0xe3, 0x5a, 0xeb, 0x23, 0x1f, 0xad, + 0x45, 0x4f, 0xe5, 0x90, 0xd7, 0xdc, 0xdc, 0x3b, + 0x07, 0x02, 0xa3, 0x29, 0xeb, 0x98, 0xb8, 0xc1, + 0x5f, 0xd4, 0x17, 0x3e, 0x87, 0x51, 0x98, 0xc0, + 0x47, 0xe2, 0x80, 0xd0, 0x25, 0x15, 0x96, 0x03, + 0xd3, 0xd4, 0x64, 0xd2, 0xbb, 0x9d, 0xc4, 0x49, + 0xd2, 0x82, 0xaa, 0x15, 0xfe, 0x11, 0xba, 0x89, + 0xd2, 0x96, 0x02, 0x7e, 0x3b, 0xc5, 0x1b, 0x2d, + 0x11, 0xf9, 0x45, 0x48, 0x23, 0x98, 0x42, 0x97, + 0x4c, 0xde, 0x28, 0x8f, 0xbc, 0x05, 0xd4, 0x07, + 0xff, 0xee, 0x1f, 0xb7, 0x95, 0xdd, 0xf1, 0x1f, + 0xaf, 0xfe, 0x39, 0xfc, 0xf1, 0xec, 0xa7, 0xd3, + 0xe1, 0x77, 0x67, 0xe7, 0x6f, 0x5e, 0xfd, 0xf4, + 0xed, 0x29, 0x3b, 0x1c, 0x3c, 0x7d, 0xf2, 0x54, + 0x98, 0x71, 0x77, 0xc6, 0xe6, 0x9d, 0xb1, 0xf9, + 0xf3, 0x35, 0x36, 0xcb, 0x0d, 0x73, 0xb2, 0x33, + 0xe9, 0xee, 0x4c, 0xba, 0x3b, 0x93, 0xee, 0xce, + 0xa2, 0xba, 0xb3, 0xa8, 0xee, 0x2c, 0xaa, 0x95, + 0x16, 0x55, 0x25, 0x5a, 0x5d, 0xd9, 0xa8, 0x0a, + 0xe5, 0x25, 0x11, 0x6b, 0x67, 0x68, 0xdd, 0x19, + 0x5a, 0x77, 0x86, 0xd6, 0x9d, 0xa1, 0x75, 0x67, + 0x68, 0xdd, 0x19, 0x5a, 0x77, 0x86, 0x56, 0xf4, + 0x6b, 0xfb, 0x2c, 0x0c, 0xa1, 0x57, 0x88, 0x82, + 0xf2, 0x31, 0x46, 0xd2, 0xad, 0xf4, 0xd9, 0xad, + 0x43, 0x71, 0xec, 0x0c, 0xa0, 0x3b, 0x03, 0xe8, + 0x47, 0x1a, 0x40, 0x01, 0xf3, 0xef, 0x61, 0x50, + 0x2a, 0xf0, 0x34, 0xb9, 0x20, 0x78, 0xae, 0xe4, + 0x2c, 0x42, 0x89, 0x13, 0x4f, 0x16, 0x16, 0x4a, + 0xe2, 0x99, 0x30, 0xf9, 0x19, 0x9f, 0x40, 0xcf, + 0x7a, 0xd5, 0x68, 0xdb, 0x2b, 0x3d, 0xf5, 0x2c, + 0x42, 0x75, 0x93, 0xc1, 0x40, 0xc8, 0xba, 0x69, + 0x18, 0xe5, 0xc4, 0x43, 0xa4, 0xae, 0x13, 0x67, + 0xa3, 0xe6, 0x89, 0x12, 0xb2, 0x23, 0x1b, 0x4b, + 0x1e, 0xaa, 0xe9, 0x5e, 0x2c, 0xbb, 0x3b, 0x3b, + 0xe6, 0x8d, 0xd8, 0x31, 0xdd, 0x67, 0x2b, 0x8a, + 0xa3, 0x04, 0xe1, 0x04, 0xdd, 0xdc, 0xd1, 0x97, + 0x1e, 0xb7, 0xaf, 0x7a, 0xc6, 0x1a, 0x2c, 0x27, + 0x13, 0x38, 0xb4, 0x94, 0x1b, 0x3e, 0x8c, 0x1e, + 0xdf, 0x0c, 0xd3, 0x14, 0x21, 0x34, 0xa2, 0x54, + 0x09, 0x85, 0x47, 0x93, 0xa7, 0x4f, 0x79, 0x38, + 0xc5, 0x59, 0xce, 0xbb, 0xec, 0xd7, 0x5c, 0xbc, + 0x3f, 0x52, 0x71, 0x19, 0x96, 0x49, 0x19, 0x01, + 0x6d, 0xde, 0xb6, 0x74, 0xc1, 0xe1, 0xf9, 0xb7, + 0xaf, 0x7e, 0x3c, 0x55, 0xa6, 0xec, 0x4f, 0xc0, + 0xe0, 0x7e, 0x1b, 0x96, 0xe2, 0x06, 0x53, 0xf0, + 0x06, 0x63, 0xf2, 0x47, 0x5a, 0x8a, 0x0d, 0x9f, + 0xe3, 0xe6, 0x9b, 0xc9, 0x9d, 0x81, 0xf8, 0xe6, + 0x0d, 0xc4, 0x0f, 0xc3, 0x18, 0xfb, 0x10, 0xcd, + 0xd4, 0x77, 0x6f, 0x20, 0xde, 0x45, 0x87, 0x7e, + 0xa8, 0xd1, 0xa1, 0x77, 0x06, 0xf9, 0x87, 0x68, + 0xed, 0xfe, 0x04, 0x6e, 0x08, 0xee, 0xc7, 0x20, + 0xbf, 0x0b, 0xf4, 0x7d, 0xeb, 0x17, 0x13, 0x66, + 0x8b, 0xeb, 0xfa, 0x7b, 0x57, 0x08, 0xa1, 0xea, + 0x85, 0xeb, 0xc6, 0xd8, 0xde, 0xbb, 0x9b, 0x8b, + 0xdd, 0xcd, 0xc5, 0xee, 0xe6, 0x62, 0x77, 0x73, + 0xb1, 0xbb, 0xb9, 0xd8, 0xdd, 0x5c, 0x7c, 0xce, + 0x37, 0x17, 0xe6, 0xe1, 0xea, 0x9b, 0xb6, 0x82, + 0x2d, 0x2f, 0x36, 0xae, 0x16, 0x46, 0xdd, 0x55, + 0xd5, 0x6a, 0x12, 0x3a, 0x6d, 0x71, 0xbd, 0x70, + 0xc7, 0x46, 0x90, 0xcf, 0x29, 0x86, 0xf9, 0xe7, + 0xe1, 0x92, 0xbf, 0xe5, 0xed, 0xcf, 0x27, 0x10, + 0xf8, 0xfc, 0x21, 0x5e, 0x5b, 0x7d, 0x56, 0xe9, + 0x7b, 0xfe, 0x95, 0xa6, 0xf3, 0x5b, 0x4c, 0xe1, + 0xf3, 0x65, 0xa7, 0xdd, 0xb1, 0x16, 0xcc, 0x9e, + 0x00, 0x7b, 0x5a, 0xba, 0x28, 0x0c, 0xe8, 0x99, + 0x3e, 0xb0, 0x97, 0xc6, 0x73, 0x26, 0xb1, 0xbb, + 0x6e, 0x9f, 0xd4, 0xc0, 0x0f, 0x2a, 0xe1, 0x07, + 0x04, 0x5f, 0x2e, 0x54, 0x33, 0xf4, 0x80, 0xa0, + 0xef, 0xee, 0x67, 0x3f, 0x9b, 0xfb, 0x59, 0xde, + 0xc1, 0x25, 0x91, 0x1e, 0xcf, 0x74, 0xa0, 0xe5, + 0x9a, 0x03, 0x87, 0x3a, 0x31, 0xa2, 0xb0, 0x1b, + 0xac, 0xe9, 0xd2, 0xc8, 0x91, 0x50, 0xdb, 0x32, + 0xd0, 0x2d, 0xe5, 0x74, 0xc9, 0x55, 0xee, 0x92, + 0x6e, 0xaf, 0x6f, 0x27, 0xa3, 0x31, 0xe9, 0x06, + 0x92, 0x86, 0xe8, 0xea, 0x17, 0x35, 0x0b, 0x51, + 0xce, 0x93, 0xf1, 0xe2, 0x3d, 0x17, 0x00, 0x94, + 0x1f, 0x29, 0x79, 0x11, 0x7d, 0x34, 0xc2, 0xf3, + 0xd2, 0x5c, 0x39, 0x6a, 0x9d, 0xd4, 0xd3, 0xb8, + 0xc6, 0x2e, 0x53, 0x56, 0xf7, 0x48, 0x17, 0x44, + 0x5d, 0x93, 0x93, 0x2d, 0xc7, 0x5c, 0x66, 0x0b, + 0x59, 0xc4, 0xcb, 0x1c, 0xbe, 0xf1, 0x9b, 0x41, + 0x8c, 0xbc, 0xda, 0x36, 0xa2, 0x44, 0x86, 0x49, + 0xbe, 0x14, 0x71, 0x94, 0xd3, 0xe4, 0x51, 0x21, + 0xc4, 0x2f, 0xea, 0x46, 0x46, 0xa8, 0x1c, 0x87, + 0x98, 0xb0, 0x98, 0x62, 0x96, 0xe5, 0xeb, 0x79, + 0x90, 0xc6, 0x32, 0x2a, 0x65, 0xbe, 0x00, 0x05, + 0x1f, 0x75, 0xfe, 0x30, 0x2c, 0x94, 0x32, 0x87, + 0x5a, 0x0e, 0x46, 0xe0, 0x1d, 0x8f, 0xb9, 0x61, + 0x21, 0x9f, 0x45, 0x93, 0x42, 0xa5, 0x0d, 0xa6, + 0x88, 0x78, 0x12, 0x7b, 0xd4, 0xc6, 0xa0, 0x92, + 0x3d, 0x8a, 0x3e, 0x19, 0x0f, 0xec, 0x80, 0x79, + 0xe9, 0xc4, 0xa4, 0x76, 0x71, 0xd7, 0xcd, 0x83, + 0xbe, 0x63, 0x64, 0x40, 0x53, 0xb0, 0x5f, 0x13, + 0x1d, 0xf0, 0xc4, 0x48, 0x2d, 0x63, 0x89, 0x64, + 0x28, 0x2c, 0x4d, 0x59, 0x82, 0x92, 0x5a, 0x0e, + 0x85, 0x60, 0x94, 0x40, 0x1d, 0x8a, 0xbf, 0x5d, + 0x26, 0xa1, 0xb5, 0x45, 0x3d, 0x6b, 0xa2, 0x9e, + 0x6b, 0xf7, 0x17, 0x6c, 0xea, 0x2f, 0x70, 0x98, + 0xa1, 0x48, 0xc0, 0x75, 0xdd, 0xdc, 0x22, 0xc4, + 0x3b, 0x2f, 0x31, 0x65, 0x09, 0x4c, 0x54, 0xdb, + 0x85, 0x1c, 0x7c, 0x44, 0x26, 0x10, 0x01, 0x39, + 0x40, 0xc8, 0x41, 0xdb, 0xd2, 0x30, 0xcd, 0x18, + 0x66, 0xd5, 0xf9, 0x40, 0x86, 0x98, 0x99, 0xbd, + 0xa6, 0x08, 0xf3, 0x20, 0x37, 0x26, 0x00, 0x91, + 0x8e, 0x0b, 0x8e, 0xdf, 0xc2, 0xce, 0x6d, 0x61, + 0xe7, 0xb6, 0xb0, 0x73, 0x5b, 0xb8, 0xfd, 0x07, + 0x6e, 0x82, 0x25, 0xd0, 0xdc, 0x62, 0xee, 0x33, + 0x57, 0xfb, 0x87, 0x6d, 0x3d, 0x5c, 0x9b, 0x05, + 0x55, 0xed, 0x82, 0xba, 0x76, 0xc1, 0x6d, 0x3e, + 0xa8, 0x13, 0x9f, 0xb1, 0x27, 0xbf, 0xf2, 0x6b, + 0x70, 0x4d, 0x93, 0xc1, 0x2e, 0x90, 0xdb, 0xee, + 0xd5, 0xdf, 0xee, 0xd5, 0xdf, 0xd5, 0x9d, 0x3a, + 0xe4, 0xe2, 0x55, 0x5c, 0xc6, 0xde, 0x8c, 0xc7, + 0x07, 0x1d, 0xe6, 0x0d, 0x98, 0xea, 0xf2, 0xfa, + 0x29, 0xd3, 0x75, 0x2a, 0xa9, 0xcd, 0x2c, 0x6e, + 0x98, 0x55, 0xbb, 0xda, 0x2e, 0x34, 0xdd, 0xee, + 0x21, 0xe5, 0x17, 0xf7, 0x90, 0xf2, 0xde, 0x3c, + 0x35, 0x0c, 0x2e, 0x20, 0x34, 0x39, 0xf1, 0x67, + 0x25, 0x32, 0xba, 0xd8, 0x73, 0x38, 0x44, 0xdd, + 0xc4, 0xd8, 0x00, 0xab, 0xb7, 0xfa, 0x27, 0xe8, + 0x3f, 0xb1, 0x73, 0x8e, 0xd8, 0x39, 0x47, 0x7c, + 0x89, 0xce, 0x11, 0x3b, 0xdf, 0x88, 0x9d, 0x6f, + 0xc4, 0xce, 0x37, 0xe2, 0xcb, 0xf2, 0x8d, 0x20, + 0x9b, 0x80, 0xbc, 0x6c, 0x32, 0xcf, 0xd1, 0xfd, + 0x92, 0xc9, 0x83, 0x12, 0x8c, 0x99, 0x42, 0x82, + 0x41, 0x5d, 0xa5, 0xba, 0x6b, 0xca, 0x7f, 0x24, + 0x6c, 0x22, 0x6a, 0x20, 0x64, 0x6b, 0xd8, 0xaa, + 0xb7, 0xe0, 0x0a, 0xbd, 0x05, 0x56, 0x6f, 0x41, + 0xfb, 0x0a, 0x4f, 0x56, 0xaf, 0x90, 0x20, 0x38, + 0x1f, 0x4f, 0x68, 0x1d, 0x2a, 0x12, 0xc4, 0x52, + 0x46, 0xb3, 0x07, 0x69, 0x9a, 0xd9, 0xc5, 0x37, + 0xdc, 0x46, 0x99, 0xbf, 0x4b, 0x75, 0xfc, 0x4e, + 0x34, 0xe9, 0xcf, 0x30, 0xd4, 0x62, 0x3d, 0xb4, + 0x8d, 0x0e, 0xf2, 0x75, 0x1a, 0xd3, 0x46, 0x85, + 0xe9, 0x1a, 0xaa, 0xce, 0xee, 0xae, 0xfd, 0xf3, + 0xb9, 0x6b, 0x07, 0x8e, 0x8f, 0xf5, 0x86, 0x7e, + 0x5d, 0x6e, 0x44, 0xe2, 0xda, 0xed, 0xae, 0x7f, + 0x52, 0xd1, 0x28, 0x68, 0x6a, 0x14, 0x54, 0x37, + 0x12, 0x77, 0x87, 0xaa, 0x5f, 0x4f, 0x43, 0xf3, + 0xf8, 0x39, 0x23, 0x4e, 0x52, 0x71, 0x05, 0xf8, + 0x92, 0xe5, 0xf3, 0x14, 0x24, 0xcf, 0xbc, 0x08, + 0x17, 0x2d, 0x14, 0x2d, 0x3b, 0xc6, 0x39, 0xe5, + 0x1c, 0x9f, 0xfc, 0xea, 0xb6, 0xb6, 0x58, 0x74, + 0x74, 0x2f, 0x6f, 0xa6, 0xb7, 0x7b, 0x55, 0x5a, + 0xc4, 0x43, 0x9e, 0xd7, 0xaa, 0xe2, 0x68, 0x26, + 0x31, 0xa0, 0xae, 0x94, 0xdf, 0xb1, 0xa9, 0xf3, + 0xf2, 0x86, 0x32, 0x8f, 0xf6, 0xaa, 0x32, 0x7f, + 0xf6, 0x6f, 0x24, 0x1f, 0xa9, 0x48, 0x8d, 0x98, + 0x85, 0x22, 0x0b, 0xdf, 0x59, 0x52, 0xf4, 0x9f, + 0x90, 0x3a, 0x2d, 0x5d, 0x02, 0x54, 0x2a, 0x43, + 0xed, 0x1b, 0x40, 0x9a, 0xd6, 0x14, 0x85, 0xbf, + 0x25, 0xec, 0xee, 0x04, 0x73, 0x18, 0x83, 0x40, + 0x1d, 0x8e, 0x22, 0x52, 0x1f, 0x27, 0xa9, 0x52, + 0x62, 0x26, 0x99, 0x3f, 0xe2, 0x69, 0xc8, 0xcc, + 0xd6, 0x5d, 0xec, 0x12, 0x93, 0x05, 0x63, 0xd2, + 0x53, 0xf2, 0x67, 0x50, 0x4a, 0x68, 0xd9, 0x0f, + 0x21, 0x97, 0xe6, 0x01, 0x3e, 0xb5, 0x2a, 0xe5, + 0xa1, 0x95, 0x90, 0x38, 0x8a, 0xd7, 0x74, 0xd6, + 0xc8, 0x34, 0xd1, 0x00, 0x13, 0x33, 0xf5, 0x85, + 0x19, 0x5e, 0xc4, 0x8e, 0xc3, 0x3f, 0x96, 0xc8, + 0xac, 0x34, 0x86, 0xc4, 0x40, 0x60, 0x01, 0x31, + 0xb5, 0xa4, 0x4c, 0xb0, 0x47, 0xd9, 0xe9, 0x38, + 0xbf, 0xa2, 0xbb, 0x5d, 0x52, 0x24, 0xfd, 0x79, + 0x28, 0xee, 0x3a, 0x45, 0x5a, 0xc4, 0xd3, 0x7f, + 0xbe, 0x39, 0xfd, 0xe9, 0x0d, 0x5e, 0x9d, 0xea, + 0x29, 0xc3, 0xc9, 0x4a, 0x97, 0x22, 0x53, 0x35, + 0xc7, 0x92, 0x8c, 0x39, 0xc6, 0x18, 0x3c, 0x23, + 0x73, 0x1b, 0xac, 0xc8, 0x4c, 0xa4, 0x32, 0x06, + 0x9a, 0xa4, 0x45, 0x15, 0x0c, 0x12, 0x2f, 0x83, + 0xd3, 0x24, 0x87, 0xad, 0xa1, 0x33, 0xaa, 0xd1, + 0xf2, 0x53, 0x0a, 0xd4, 0x56, 0x75, 0xca, 0x58, + 0x34, 0x51, 0x61, 0x04, 0x02, 0x52, 0x74, 0x4c, + 0xf2, 0x63, 0x6d, 0x9e, 0x0b, 0xcd, 0xc8, 0x3b, + 0xdb, 0x47, 0x40, 0x02, 0xe4, 0xbe, 0x43, 0xcb, + 0x3c, 0x89, 0xa8, 0x41, 0xf8, 0xc6, 0x66, 0x31, + 0x9d, 0x8e, 0x87, 0x15, 0x54, 0xaf, 0x0e, 0xd0, + 0x5a, 0x11, 0xb7, 0xd7, 0x50, 0xd6, 0x3f, 0xb9, + 0x0a, 0xc9, 0x97, 0x76, 0x5c, 0x86, 0x0e, 0x39, + 0x20, 0xdb, 0xe7, 0xc3, 0xd8, 0xcc, 0x63, 0x5b, + 0x51, 0x8e, 0x14, 0x52, 0x01, 0x21, 0xf7, 0x61, + 0x52, 0xc9, 0x3a, 0x35, 0xe4, 0x27, 0x57, 0x19, + 0x08, 0x2c, 0x0b, 0x90, 0x19, 0xf0, 0x46, 0xb7, + 0x02, 0xe0, 0x76, 0x88, 0x20, 0x16, 0x51, 0x32, + 0x5c, 0x91, 0x6b, 0x50, 0x39, 0x94, 0x8a, 0x5c, + 0xfb, 0x2c, 0xf4, 0xc7, 0x64, 0x43, 0x19, 0x65, + 0x69, 0x9e, 0x77, 0x26, 0x2a, 0xe7, 0x5f, 0xae, + 0x8f, 0x68, 0x6c, 0x44, 0x75, 0xf8, 0x2a, 0xf0, + 0x64, 0xe7, 0x8e, 0xd7, 0x47, 0xaf, 0x8a, 0xdb, + 0xf7, 0x44, 0xfe, 0x5c, 0x2b, 0xdd, 0x1d, 0x55, + 0xef, 0x57, 0x55, 0xef, 0x8b, 0xea, 0x92, 0x0d, + 0x44, 0x13, 0xd6, 0xe2, 0xc0, 0xbb, 0x3e, 0xb7, + 0x2c, 0x49, 0x86, 0xa2, 0xee, 0x43, 0x7a, 0xdd, + 0x6c, 0x1a, 0x48, 0xfe, 0xcc, 0xff, 0x38, 0x90, + 0x7f, 0x88, 0x03, 0xe6, 0x4f, 0x1b, 0x56, 0xbf, + 0x16, 0x56, 0xdf, 0x84, 0xd5, 0x37, 0x61, 0xf5, + 0x6d, 0x58, 0x25, 0x5f, 0x17, 0xde, 0xa1, 0x27, + 0x2a, 0x7b, 0x8a, 0x28, 0xc5, 0x38, 0x44, 0x2a, + 0x3d, 0x3c, 0xae, 0x0c, 0xb2, 0x14, 0x90, 0x0e, + 0x99, 0xd1, 0x2b, 0x76, 0xaa, 0x45, 0x1a, 0x5c, + 0x40, 0xfa, 0x9d, 0xd7, 0xc0, 0xca, 0x46, 0xca, + 0xeb, 0xb4, 0x68, 0xc1, 0x77, 0xcf, 0x59, 0x68, + 0x50, 0xae, 0x3f, 0x18, 0xd9, 0xba, 0xeb, 0x6a, + 0x7d, 0xb8, 0x5c, 0x6f, 0x51, 0x6b, 0xfd, 0xe1, + 0xb2, 0x6d, 0x98, 0xe5, 0x34, 0x4d, 0x9a, 0x42, + 0x08, 0xa6, 0x60, 0x9c, 0xa2, 0x5a, 0xde, 0x12, + 0x43, 0xc0, 0x2c, 0xe0, 0xf4, 0xdb, 0x54, 0xfd, + 0x16, 0x20, 0x27, 0x38, 0x94, 0x56, 0x4b, 0x1c, + 0xce, 0x63, 0xa8, 0x2f, 0x9b, 0x76, 0xf0, 0x0b, + 0xcf, 0xc2, 0x58, 0x41, 0xf6, 0xca, 0x02, 0x22, + 0xc8, 0xdd, 0x98, 0x11, 0x44, 0x5a, 0x72, 0x9a, + 0xfd, 0xf2, 0x8e, 0x90, 0xac, 0x46, 0x42, 0xd0, + 0xbb, 0x4e, 0x4f, 0x3e, 0x4f, 0xb0, 0x88, 0x37, + 0x00, 0x72, 0x86, 0xdd, 0xdd, 0xeb, 0xb1, 0xcd, + 0x5f, 0xda, 0x27, 0x26, 0x44, 0xf8, 0x50, 0x0b, + 0x10, 0x7b, 0xf3, 0xd8, 0x36, 0x9f, 0x6a, 0x24, + 0x11, 0x3a, 0x32, 0x79, 0x92, 0x48, 0x89, 0xb9, + 0xa7, 0xfb, 0xf4, 0xe4, 0x54, 0x0a, 0x9a, 0xf3, + 0xe4, 0x2f, 0x37, 0x23, 0xa8, 0xe0, 0x49, 0x50, + 0x88, 0x85, 0x7f, 0x7d, 0x06, 0xb5, 0x4a, 0x39, + 0xb6, 0x4f, 0x6a, 0x3c, 0x54, 0xa4, 0x65, 0xba, + 0xc6, 0x43, 0xc5, 0xfa, 0x7c, 0x88, 0x6d, 0x94, + 0xd5, 0xc8, 0x91, 0x4e, 0xd4, 0x05, 0x2e, 0xee, + 0x30, 0xed, 0x01, 0x26, 0x79, 0x5f, 0x90, 0xa6, + 0x31, 0xf2, 0xf0, 0x9c, 0x7b, 0xd5, 0x61, 0x1e, + 0xf9, 0x21, 0x61, 0xed, 0x9b, 0x92, 0x91, 0x53, + 0x6b, 0x12, 0xfa, 0x74, 0x84, 0x95, 0x2b, 0x9a, + 0xc1, 0xa9, 0x96, 0xbc, 0x72, 0x71, 0x82, 0xb4, + 0x24, 0x6f, 0x0c, 0x8c, 0x34, 0xbb, 0xca, 0xbf, + 0x91, 0x72, 0xdd, 0xe7, 0x45, 0xba, 0xc8, 0xf9, + 0xa1, 0x8e, 0xcd, 0xe8, 0x08, 0xe7, 0x9e, 0x91, + 0x39, 0xfa, 0x52, 0xca, 0xd4, 0xc0, 0x0d, 0x3d, + 0xe9, 0x7e, 0x2c, 0x28, 0x94, 0xab, 0x95, 0xba, + 0x40, 0x96, 0x2c, 0x50, 0x67, 0x12, 0xf5, 0x1a, + 0x78, 0x23, 0x10, 0x1a, 0x32, 0x1f, 0x2d, 0x6b, + 0x98, 0xf1, 0x13, 0x4e, 0x63, 0xa9, 0x95, 0xd5, + 0x0d, 0x75, 0x11, 0x15, 0xa3, 0x59, 0x69, 0xc2, + 0xb8, 0x7d, 0x79, 0xc8, 0xbd, 0x43, 0xeb, 0x9a, + 0xf2, 0x1c, 0xa8, 0xae, 0x13, 0x91, 0x75, 0x5c, + 0xf3, 0xd4, 0xb6, 0x27, 0x9f, 0x8c, 0x8b, 0xc8, + 0x26, 0xff, 0x29, 0xfe, 0x39, 0xf6, 0x83, 0x10, + 0x44, 0x95, 0xd8, 0x4f, 0xc2, 0xba, 0x2a, 0xb0, + 0xc9, 0x48, 0x02, 0x53, 0xe5, 0x15, 0x24, 0x89, + 0xe7, 0x62, 0x69, 0xe6, 0x69, 0x3d, 0xb8, 0x15, + 0x73, 0xee, 0x2f, 0x8c, 0x76, 0xee, 0x9b, 0xac, + 0x0a, 0x13, 0x5a, 0xd9, 0x80, 0xe6, 0x6c, 0x9e, + 0xad, 0xbd, 0x11, 0xee, 0xfc, 0x4a, 0xde, 0xbc, + 0x3d, 0x35, 0xef, 0x22, 0x39, 0x3b, 0xb1, 0x1f, + 0x94, 0xc8, 0x7b, 0x6c, 0xb7, 0xd2, 0x07, 0xeb, + 0x19, 0x07, 0x09, 0xac, 0xe6, 0x0d, 0xac, 0x05, + 0x81, 0x36, 0x99, 0x2a, 0x54, 0x2d, 0x4d, 0x02, + 0x17, 0x9e, 0x87, 0x43, 0xa0, 0x60, 0xb2, 0x46, + 0x77, 0x1c, 0x66, 0xf5, 0x76, 0xf0, 0xce, 0x56, + 0xa2, 0x69, 0x59, 0xa4, 0x0c, 0xf2, 0x55, 0x0d, + 0x6f, 0x62, 0x7f, 0xfb, 0x1b, 0xfb, 0xaa, 0x9e, + 0x23, 0x99, 0xc2, 0x8a, 0xc0, 0x11, 0xcf, 0x00, + 0x8e, 0xf0, 0xdb, 0xde, 0x3b, 0x4f, 0xe0, 0xfe, + 0xb6, 0xff, 0xce, 0x53, 0x8c, 0x8a, 0x5c, 0x8d, + 0x8f, 0x9f, 0xc8, 0x63, 0xf7, 0x4f, 0x86, 0xd3, + 0x4f, 0x58, 0xdc, 0x18, 0x12, 0x0a, 0x81, 0xda, + 0xae, 0x9a, 0x06, 0x7c, 0xa5, 0xae, 0x04, 0x53, + 0x34, 0xe1, 0x37, 0xd7, 0xa9, 0xba, 0xde, 0x79, + 0x4d, 0x1e, 0xfb, 0xdb, 0xe8, 0xa0, 0xe6, 0x92, + 0x6b, 0xee, 0x09, 0x2c, 0x73, 0x96, 0x6a, 0xee, + 0x89, 0xef, 0x96, 0x2c, 0xd0, 0xdd, 0x95, 0xd2, + 0x60, 0xcf, 0x43, 0xf2, 0x84, 0x27, 0x2f, 0x55, + 0x54, 0x17, 0x39, 0xd3, 0x44, 0xf3, 0x43, 0x97, + 0x5f, 0x43, 0x96, 0xba, 0x91, 0x50, 0x39, 0xeb, + 0xe4, 0xef, 0xc9, 0xac, 0x6d, 0xcf, 0xbe, 0xd1, + 0x12, 0x6b, 0x2d, 0x4a, 0x07, 0x4d, 0xec, 0x9e, + 0xbd, 0x50, 0x10, 0x9a, 0x6a, 0x1d, 0xd4, 0xc3, + 0x2f, 0xcf, 0x8e, 0x71, 0xab, 0xa2, 0x30, 0xe7, + 0x26, 0x29, 0xd5, 0x17, 0xfe, 0x8f, 0xdb, 0x5f, + 0xf8, 0xfd, 0x9f, 0x3d, 0x52, 0xcf, 0xa9, 0x07, + 0xab, 0x00, 0xf3, 0xf7, 0x3a, 0x0b, 0x2f, 0x68, + 0xee, 0xd0, 0x0f, 0x17, 0x97, 0x75, 0xcc, 0x92, + 0xd0, 0xcf, 0x3a, 0x93, 0x28, 0x8c, 0xe5, 0x03, + 0x85, 0x9c, 0x5b, 0x0e, 0xf1, 0x92, 0x6b, 0x7c, + 0x80, 0xf5, 0x90, 0xc4, 0xf0, 0x60, 0x56, 0x1a, + 0x8a, 0xfc, 0xdf, 0x91, 0xb6, 0x6d, 0x11, 0xad, + 0x80, 0x2c, 0x5e, 0xc2, 0xdb, 0xda, 0xb6, 0x13, + 0x90, 0x25, 0xf5, 0x7b, 0x30, 0xc1, 0x96, 0xd9, + 0x37, 0xbc, 0x35, 0x10, 0xfb, 0x11, 0x5d, 0x60, + 0x0b, 0x9e, 0x5b, 0xe2, 0x11, 0x7c, 0xad, 0xe9, + 0xb8, 0xe4, 0x46, 0x8f, 0x9e, 0xdc, 0x1a, 0x7c, + 0xfb, 0x59, 0x07, 0xa9, 0x49, 0xec, 0x5b, 0x13, + 0x8e, 0xa2, 0x6d, 0xce, 0xe5, 0x5e, 0x6f, 0x45, + 0xe1, 0xb0, 0x00, 0xc4, 0xa1, 0x41, 0x47, 0xe9, + 0xb5, 0x15, 0xb9, 0x9b, 0xf0, 0x80, 0x09, 0x96, + 0x89, 0x9a, 0x2e, 0xec, 0xaa, 0x09, 0x5d, 0x35, + 0x0b, 0xd4, 0x55, 0xec, 0xeb, 0x8a, 0xc6, 0x95, + 0x25, 0x2b, 0xa3, 0xeb, 0xf2, 0x8c, 0x01, 0x03, + 0x4e, 0x5a, 0x2d, 0xfe, 0x46, 0x4d, 0x3c, 0x8c, + 0xb3, 0x65, 0x0b, 0x8f, 0xf1, 0x07, 0x6f, 0xf8, + 0xca, 0xce, 0xda, 0xf2, 0xe6, 0x4a, 0x10, 0x97, + 0x06, 0xae, 0x80, 0x10, 0x29, 0x6d, 0xba, 0xc5, + 0xbd, 0x1f, 0xbb, 0xfd, 0x56, 0x6c, 0x7e, 0x0e, + 0x61, 0x44, 0x87, 0x0f, 0xfc, 0x77, 0x4b, 0x08, + 0x78, 0xdb, 0xcc, 0xe4, 0x37, 0xb9, 0x14, 0x2f, + 0xf9, 0x25, 0xb4, 0x82, 0xe8, 0x49, 0xbf, 0x0d, + 0x85, 0xa5, 0x57, 0xfe, 0x15, 0xea, 0xd5, 0x5c, + 0x55, 0xf3, 0x03, 0xb1, 0x4a, 0xee, 0x30, 0x16, + 0xdd, 0xac, 0x0d, 0x6b, 0x51, 0x95, 0x12, 0xde, + 0xb2, 0xcd, 0x39, 0x12, 0x8a, 0xba, 0xbf, 0x76, + 0xe0, 0x98, 0x04, 0x41, 0x9f, 0x56, 0x30, 0x15, + 0xee, 0x78, 0xd1, 0x5e, 0x2a, 0x0f, 0x65, 0xd0, + 0xff, 0x06, 0x34, 0x56, 0xb5, 0xb1, 0xda, 0x65, + 0xb3, 0xf3, 0x85, 0x3a, 0x9c, 0xf1, 0xdf, 0x03, + 0x53, 0xae, 0x51, 0x84, 0x66, 0xca, 0x2e, 0x5a, + 0xf8, 0x10, 0x1f, 0x5a, 0xb6, 0x62, 0x60, 0xdd, + 0x58, 0x1b, 0x92, 0x27, 0xb4, 0x33, 0xab, 0xc1, + 0xa9, 0x49, 0x36, 0x81, 0x63, 0xd8, 0xdf, 0x96, + 0x84, 0x0a, 0x3b, 0xbc, 0xe3, 0x88, 0xac, 0x1c, + 0x4d, 0x07, 0x89, 0xb9, 0x7f, 0xd9, 0xa2, 0xb1, + 0xa0, 0x11, 0xbe, 0x8f, 0xbf, 0x58, 0xe0, 0xe1, + 0x78, 0x7c, 0x6c, 0x76, 0xdf, 0xb6, 0x9f, 0xd5, + 0x9b, 0xc6, 0x27, 0x61, 0x14, 0x39, 0xb9, 0xb7, + 0xbc, 0x67, 0xd7, 0x97, 0x17, 0x6f, 0xf0, 0x65, + 0xb2, 0x29, 0xef, 0x8b, 0x4b, 0x0e, 0xd9, 0x68, + 0xbf, 0x84, 0x4e, 0x85, 0xf2, 0x6a, 0x9a, 0x96, + 0xc4, 0xef, 0xe2, 0xe6, 0xa1, 0x2d, 0xdf, 0x0f, + 0x7d, 0xe6, 0xfa, 0xb0, 0x30, 0x98, 0xf0, 0x03, + 0x74, 0x22, 0x25, 0x5b, 0x5c, 0x57, 0xf2, 0x5f, + 0x1b, 0xcb, 0xa7, 0x7d, 0xc5, 0x7a, 0x41, 0xb7, + 0x5b, 0x00, 0x1f, 0xce, 0x43, 0x98, 0x5f, 0xb2, + 0x2c, 0xef, 0x49, 0xcd, 0x13, 0x4d, 0xc2, 0xff, + 0x8b, 0x33, 0xe8, 0x45, 0x00, 0xee, 0xcf, 0x0e, + 0x42, 0xa1, 0x57, 0x2f, 0x18, 0x29, 0x57, 0x0a, + 0x6b, 0xb9, 0x94, 0x3e, 0x51, 0x3d, 0x85, 0xa3, + 0xdd, 0x0f, 0xe2, 0x70, 0xac, 0x6a, 0xe5, 0xe9, + 0x32, 0x1b, 0x69, 0x85, 0x17, 0x2a, 0xaf, 0x40, + 0x55, 0x8e, 0x12, 0x44, 0x21, 0x5e, 0xc3, 0x7f, + 0xa4, 0x35, 0x1b, 0x5f, 0x46, 0xf2, 0x03, 0xee, + 0x05, 0xa1, 0xc6, 0xbf, 0x02, 0x6e, 0x2e, 0x02, + 0x2c, 0xc4, 0x22, 0x7a, 0xa7, 0x48, 0x77, 0x02, + 0xf8, 0xe4, 0x70, 0x99, 0x91, 0x69, 0x52, 0xc8, + 0x91, 0x06, 0x8a, 0xae, 0xc2, 0x9d, 0xbf, 0xc0, + 0xb2, 0xb7, 0x44, 0x22, 0x04, 0xad, 0x45, 0x0f, + 0x35, 0xf1, 0x15, 0xf1, 0x39, 0xa8, 0xec, 0x9e, + 0x04, 0xd1, 0xf6, 0xb0, 0x1e, 0x33, 0xea, 0xd1, + 0xdb, 0xcd, 0x72, 0x3d, 0xf6, 0x6e, 0x67, 0x7c, + 0x90, 0xc6, 0x87, 0xda, 0xeb, 0xff, 0x28, 0x8e, + 0x9b, 0xde, 0xca, 0xe8, 0xf2, 0x86, 0x07, 0x33, + 0xba, 0x52, 0xe5, 0xab, 0x19, 0xb3, 0xb8, 0xc1, + 0xb7, 0xc3, 0xae, 0xd6, 0xe8, 0xb4, 0x30, 0xf3, + 0xe3, 0xb4, 0x09, 0x6b, 0x5d, 0xde, 0x80, 0xb5, + 0xae, 0x54, 0x89, 0xb5, 0x59, 0xdc, 0x80, 0xb5, + 0x5d, 0xed, 0x33, 0x78, 0x5e, 0x43, 0x03, 0x6a, + 0x78, 0x9f, 0xa1, 0xcb, 0xeb, 0x71, 0xd5, 0x75, + 0x2a, 0xd1, 0x35, 0x8b, 0x1b, 0x30, 0xb6, 0xab, + 0x6d, 0x46, 0xba, 0xfe, 0x55, 0x95, 0x2a, 0xde, + 0x80, 0x72, 0xed, 0xfb, 0x2a, 0xa3, 0x74, 0x13, + 0xc2, 0x8e, 0x0f, 0xd1, 0xc3, 0x33, 0x50, 0xdd, + 0x91, 0x59, 0xf1, 0xca, 0x66, 0xce, 0x6a, 0x3b, + 0xe4, 0xb6, 0xd6, 0x34, 0x3c, 0x9d, 0xed, 0x5b, + 0xc0, 0x43, 0xf1, 0xb5, 0x7f, 0x15, 0x3b, 0x9a, + 0xc1, 0x0f, 0x49, 0x3e, 0x55, 0x7f, 0x56, 0xbf, + 0xef, 0xd1, 0xe5, 0x9e, 0xc3, 0x2c, 0xeb, 0x5e, + 0xfa, 0xd8, 0x10, 0x2b, 0x99, 0x5e, 0x03, 0x7a, + 0x06, 0xe3, 0x23, 0xb8, 0xea, 0xcf, 0x6a, 0xf4, + 0x74, 0xb9, 0xe7, 0x70, 0xc5, 0x3a, 0xf4, 0x6c, + 0x88, 0x95, 0xdc, 0xed, 0x13, 0x79, 0x18, 0x64, + 0xf0, 0x31, 0x35, 0x55, 0xf5, 0x2f, 0x4c, 0x74, + 0xb1, 0xe7, 0xf0, 0xb8, 0x3a, 0xbc, 0x6c, 0x80, + 0x95, 0xcc, 0x6a, 0x13, 0x76, 0xca, 0x63, 0x4d, + 0xfd, 0x55, 0x8f, 0x9b, 0x7c, 0xcb, 0x65, 0xb0, + 0xb2, 0x46, 0xcc, 0x94, 0xe7, 0x5b, 0x15, 0x53, + 0xfa, 0x44, 0x6d, 0xb7, 0xae, 0xe9, 0x76, 0x67, + 0xbb, 0xfd, 0xe2, 0x6c, 0xb7, 0x67, 0x22, 0xa4, + 0x0b, 0x9e, 0x97, 0x28, 0xf6, 0x0a, 0x13, 0x23, + 0xc3, 0xe3, 0x4d, 0xb8, 0x44, 0x80, 0x06, 0x10, + 0xfb, 0xeb, 0x74, 0x49, 0x6f, 0x3c, 0xc6, 0xa9, + 0x74, 0x62, 0xe4, 0xf5, 0x72, 0xd8, 0x5c, 0x3a, + 0x0f, 0x08, 0x8f, 0x21, 0x30, 0xf7, 0xdf, 0x87, + 0x39, 0x07, 0xa9, 0xdc, 0x87, 0x14, 0x2e, 0x32, + 0x5c, 0x40, 0x16, 0xc6, 0xfc, 0xa5, 0x11, 0x48, + 0xf7, 0xe8, 0xcf, 0xbf, 0x48, 0xb3, 0x82, 0x43, + 0x33, 0x1f, 0x8a, 0x8c, 0xd2, 0x25, 0x9e, 0x6e, + 0xfe, 0xa8, 0x40, 0x97, 0x0c, 0x11, 0x81, 0x06, + 0x7d, 0xf2, 0x27, 0x13, 0x18, 0x0e, 0xbe, 0x1f, + 0x99, 0x2f, 0xe3, 0x22, 0x5a, 0xc4, 0x74, 0x48, + 0x89, 0x57, 0x31, 0xa6, 0x7b, 0x3c, 0x1d, 0xa2, + 0xdd, 0x9a, 0xd1, 0x62, 0x74, 0x98, 0xea, 0x01, + 0x53, 0xf0, 0x18, 0x35, 0xec, 0xc4, 0xc1, 0xf0, + 0x2a, 0xe3, 0x8d, 0xfd, 0x6c, 0xea, 0x0c, 0x17, + 0xcb, 0x05, 0x29, 0x81, 0xb6, 0x42, 0xaf, 0x54, + 0x0c, 0x77, 0xcc, 0x79, 0x77, 0xbb, 0x81, 0x8f, + 0xa3, 0x8b, 0x68, 0xbc, 0x79, 0xd4, 0x5f, 0x86, + 0xd9, 0x7d, 0x1b, 0x93, 0xfb, 0xcd, 0x9b, 0xdb, + 0x3f, 0x21, 0x53, 0x3b, 0x67, 0x29, 0x82, 0x46, + 0x89, 0xd6, 0x1f, 0x49, 0x40, 0x1d, 0x3f, 0x8e, + 0xa6, 0x09, 0x9e, 0x16, 0x2f, 0x90, 0xf8, 0x1f, + 0x91, 0x6f, 0x1d, 0xac, 0x48, 0xf4, 0x01, 0xb0, + 0xf5, 0x63, 0x5e, 0x1b, 0x48, 0x15, 0x87, 0x45, + 0xe4, 0x8b, 0x8e, 0x76, 0xf4, 0x7e, 0xc5, 0xec, + 0xe0, 0x4d, 0x0a, 0xa2, 0xd8, 0x14, 0x75, 0x64, + 0xdc, 0x32, 0x44, 0xab, 0xfc, 0xec, 0xc1, 0x89, + 0x94, 0xdc, 0x47, 0x6c, 0x1f, 0xda, 0x5e, 0x99, + 0xbf, 0xc2, 0xe8, 0x21, 0x33, 0xdc, 0x55, 0x46, + 0x6f, 0xd2, 0x19, 0x19, 0x7b, 0x31, 0xe1, 0x8b, + 0x96, 0x02, 0x14, 0x8b, 0x0a, 0xfe, 0x88, 0x72, + 0x1e, 0xfa, 0x14, 0xed, 0x09, 0xb0, 0xa9, 0xed, + 0xaf, 0xbb, 0xbb, 0x46, 0xd8, 0x5d, 0x23, 0x7c, + 0x76, 0xd7, 0x08, 0x9a, 0xab, 0xd8, 0x6f, 0xc6, + 0xac, 0xe7, 0x66, 0xa6, 0x4c, 0xf9, 0x49, 0x5c, + 0x38, 0xc8, 0xa7, 0xbc, 0xca, 0xdc, 0x37, 0xbe, + 0x81, 0x1b, 0x08, 0x71, 0x95, 0x41, 0x2a, 0xad, + 0x7c, 0x22, 0x86, 0xaf, 0x63, 0x2f, 0x29, 0x42, + 0x97, 0x0e, 0x47, 0xc6, 0xd5, 0x5b, 0xe9, 0xcd, + 0x66, 0x4c, 0xab, 0xc7, 0x78, 0x44, 0xb0, 0x5a, + 0xbc, 0xf8, 0x35, 0x87, 0x0c, 0x73, 0x74, 0xfe, + 0xdd, 0xf7, 0xc3, 0xd7, 0xff, 0x64, 0xcf, 0x8c, + 0x08, 0x52, 0xa7, 0xdf, 0xfd, 0x70, 0x3a, 0xfc, + 0xe1, 0xd5, 0x3f, 0xfe, 0xf1, 0x0a, 0x26, 0xa3, + 0xdf, 0x3b, 0x3e, 0x28, 0xbf, 0x80, 0xa8, 0x32, + 0x40, 0xa0, 0xb2, 0x71, 0xb2, 0x85, 0xad, 0xf1, + 0xae, 0xad, 0x84, 0x77, 0x6a, 0xdf, 0xbb, 0x3b, + 0x03, 0xdd, 0x1d, 0xdb, 0xd6, 0x6e, 0xc5, 0x30, + 0x56, 0x79, 0xc7, 0x56, 0x6d, 0x44, 0xb2, 0x5e, + 0xdb, 0xd4, 0x59, 0xbf, 0x6e, 0xc2, 0x30, 0xb4, + 0xd1, 0x2e, 0x74, 0x3d, 0x83, 0xce, 0x66, 0x7b, + 0xce, 0xb5, 0x0c, 0x31, 0xb7, 0xfd, 0x8a, 0xcd, + 0xb1, 0xa4, 0x5c, 0xcf, 0x06, 0xb2, 0xc9, 0x04, + 0x72, 0x3d, 0xfb, 0x05, 0x3f, 0x23, 0xc4, 0x22, + 0x2b, 0xb3, 0x43, 0xd5, 0x31, 0x23, 0x96, 0xdc, + 0x0e, 0x4f, 0x2c, 0x14, 0x5c, 0x59, 0xb6, 0x2e, + 0x9d, 0x11, 0x7a, 0xc6, 0x44, 0x1d, 0xd7, 0x87, + 0xec, 0xca, 0x12, 0xb2, 0x8e, 0x0f, 0x2e, 0x17, + 0xd7, 0xa4, 0x18, 0x57, 0x36, 0xe1, 0xef, 0xa1, + 0x5e, 0x9a, 0xec, 0xf8, 0x80, 0xb5, 0x74, 0xa7, + 0xfb, 0xf6, 0xae, 0x10, 0x07, 0x83, 0xf9, 0x00, + 0x72, 0x39, 0x99, 0xa0, 0x3f, 0x36, 0x99, 0x11, + 0x40, 0x96, 0xe2, 0xd1, 0x45, 0x2c, 0xb3, 0x82, + 0x32, 0x5d, 0xe0, 0x4c, 0x97, 0x7c, 0xef, 0xa1, + 0xb1, 0x49, 0x7b, 0xb2, 0x4c, 0x22, 0xd6, 0xd2, + 0x8b, 0xb5, 0x0f, 0x07, 0x7d, 0xff, 0x39, 0xc0, + 0x16, 0xc7, 0xc9, 0x63, 0x03, 0xeb, 0xf6, 0x36, + 0x68, 0x53, 0x2c, 0x23, 0x81, 0x2f, 0xc7, 0xd6, + 0xa0, 0xaf, 0x03, 0x43, 0xae, 0x50, 0x7d, 0x58, + 0x52, 0xa1, 0x31, 0x6a, 0xf1, 0x62, 0xad, 0xf2, + 0xb2, 0x19, 0xaf, 0x9a, 0xe5, 0xab, 0x81, 0xd2, + 0x54, 0x0f, 0x45, 0x66, 0xd0, 0x97, 0x62, 0x80, + 0xfb, 0xac, 0xf4, 0xc2, 0xcf, 0x12, 0x1d, 0xc5, + 0x15, 0xb8, 0xf1, 0xd6, 0x8d, 0x06, 0xd0, 0xb1, + 0xa0, 0x79, 0x7c, 0x54, 0x8f, 0x9d, 0x8f, 0xd7, + 0x78, 0xd4, 0x86, 0xd2, 0x95, 0x7d, 0x8a, 0xdf, + 0xc0, 0x55, 0xf9, 0xff, 0x07, 0x06, 0x46, 0x05, + 0x63 }; static std::string decompressed = util::decompress(std::string(reinterpret_cast<const char*>(compressed), sizeof(compressed))); return decompressed.c_str(); diff --git a/src/mbgl/shaders/symbol_icon.cpp b/src/mbgl/shaders/symbol_icon.cpp index 388a3fa5f0..e44b955948 100644 --- a/src/mbgl/shaders/symbol_icon.cpp +++ b/src/mbgl/shaders/symbol_icon.cpp @@ -7,8 +7,8 @@ namespace mbgl { namespace shaders { const char* symbol_icon::name = "symbol_icon"; -const char* symbol_icon::vertexSource = source() + 65201; -const char* symbol_icon::fragmentSource = source() + 68607; +const char* symbol_icon::vertexSource = source() + 71259; +const char* symbol_icon::fragmentSource = source() + 74665; } // namespace shaders } // namespace mbgl diff --git a/src/mbgl/shaders/symbol_sdf.cpp b/src/mbgl/shaders/symbol_sdf.cpp index 676fd7a2fc..e52d2d39f7 100644 --- a/src/mbgl/shaders/symbol_sdf.cpp +++ b/src/mbgl/shaders/symbol_sdf.cpp @@ -7,8 +7,8 @@ namespace mbgl { namespace shaders { const char* symbol_sdf::name = "symbol_sdf"; -const char* symbol_sdf::vertexSource = source() + 69057; -const char* symbol_sdf::fragmentSource = source() + 74980; +const char* symbol_sdf::vertexSource = source() + 75115; +const char* symbol_sdf::fragmentSource = source() + 81040; } // namespace shaders } // namespace mbgl diff --git a/src/mbgl/style/image_impl.hpp b/src/mbgl/style/image_impl.hpp index e439e42695..54b5e6487b 100644 --- a/src/mbgl/style/image_impl.hpp +++ b/src/mbgl/style/image_impl.hpp @@ -26,8 +26,13 @@ public: } // namespace style +enum class ImageType : bool { + Icon, + Pattern +}; + using ImageMap = std::unordered_map<std::string, Immutable<style::Image::Impl>>; -using ImageDependencies = std::set<std::string>; +using ImageDependencies = std::unordered_map<std::string, ImageType>; using ImageRequestPair = std::pair<ImageDependencies, uint64_t>; } // namespace mbgl diff --git a/src/mbgl/style/layers/fill_extrusion_layer.cpp b/src/mbgl/style/layers/fill_extrusion_layer.cpp index 74cdb9abe6..9301f8dd00 100644 --- a/src/mbgl/style/layers/fill_extrusion_layer.cpp +++ b/src/mbgl/style/layers/fill_extrusion_layer.cpp @@ -443,7 +443,7 @@ optional<Error> FillExtrusionLayer::setPaintProperty(const std::string& name, co if (property == Property::FillExtrusionPattern) { Error error; - optional<PropertyValue<std::string>> typedValue = convert<PropertyValue<std::string>>(value, error, false, false); + optional<PropertyValue<std::string>> typedValue = convert<PropertyValue<std::string>>(value, error, true, false); if (!typedValue) { return error; } diff --git a/src/mbgl/style/layers/fill_extrusion_layer_impl.hpp b/src/mbgl/style/layers/fill_extrusion_layer_impl.hpp index 9abc6fc4b3..9a9a52dea4 100644 --- a/src/mbgl/style/layers/fill_extrusion_layer_impl.hpp +++ b/src/mbgl/style/layers/fill_extrusion_layer_impl.hpp @@ -14,6 +14,7 @@ public: bool hasLayoutDifference(const Layer::Impl&) const override; void stringifyLayout(rapidjson::Writer<rapidjson::StringBuffer>&) const override; + Properties<>::Unevaluated layout; FillExtrusionPaintProperties::Transitionable paint; }; diff --git a/src/mbgl/style/layers/fill_extrusion_layer_properties.hpp b/src/mbgl/style/layers/fill_extrusion_layer_properties.hpp index 19be59a2fe..47d8cd3a1c 100644 --- a/src/mbgl/style/layers/fill_extrusion_layer_properties.hpp +++ b/src/mbgl/style/layers/fill_extrusion_layer_properties.hpp @@ -28,7 +28,7 @@ struct FillExtrusionTranslateAnchor : PaintProperty<TranslateAnchorType> { static TranslateAnchorType defaultValue() { return TranslateAnchorType::Map; } }; -struct FillExtrusionPattern : CrossFadedPaintProperty<std::string> { +struct FillExtrusionPattern : CrossFadedDataDrivenPaintProperty<std::string, attributes::a_pattern_to, uniforms::u_pattern_to, attributes::a_pattern_from, uniforms::u_pattern_from> { static std::string defaultValue() { return ""; } }; diff --git a/src/mbgl/style/layers/fill_layer.cpp b/src/mbgl/style/layers/fill_layer.cpp index bdfc000736..69b3a16004 100644 --- a/src/mbgl/style/layers/fill_layer.cpp +++ b/src/mbgl/style/layers/fill_layer.cpp @@ -462,7 +462,7 @@ optional<Error> FillLayer::setPaintProperty(const std::string& name, const Conve if (property == Property::FillPattern) { Error error; - optional<PropertyValue<std::string>> typedValue = convert<PropertyValue<std::string>>(value, error, false, false); + optional<PropertyValue<std::string>> typedValue = convert<PropertyValue<std::string>>(value, error, true, false); if (!typedValue) { return error; } diff --git a/src/mbgl/style/layers/fill_layer_impl.hpp b/src/mbgl/style/layers/fill_layer_impl.hpp index 2673cd7443..22573e0d5d 100644 --- a/src/mbgl/style/layers/fill_layer_impl.hpp +++ b/src/mbgl/style/layers/fill_layer_impl.hpp @@ -14,6 +14,7 @@ public: bool hasLayoutDifference(const Layer::Impl&) const override; void stringifyLayout(rapidjson::Writer<rapidjson::StringBuffer>&) const override; + Properties<>::Unevaluated layout; FillPaintProperties::Transitionable paint; }; diff --git a/src/mbgl/style/layers/fill_layer_properties.hpp b/src/mbgl/style/layers/fill_layer_properties.hpp index cb01194515..a20089ff2e 100644 --- a/src/mbgl/style/layers/fill_layer_properties.hpp +++ b/src/mbgl/style/layers/fill_layer_properties.hpp @@ -36,7 +36,7 @@ struct FillTranslateAnchor : PaintProperty<TranslateAnchorType> { static TranslateAnchorType defaultValue() { return TranslateAnchorType::Map; } }; -struct FillPattern : CrossFadedPaintProperty<std::string> { +struct FillPattern : CrossFadedDataDrivenPaintProperty<std::string, attributes::a_pattern_to, uniforms::u_pattern_to, attributes::a_pattern_from, uniforms::u_pattern_from> { static std::string defaultValue() { return ""; } }; diff --git a/src/mbgl/style/layers/line_layer.cpp b/src/mbgl/style/layers/line_layer.cpp index 1ddc690cc7..f5354e2bdb 100644 --- a/src/mbgl/style/layers/line_layer.cpp +++ b/src/mbgl/style/layers/line_layer.cpp @@ -698,7 +698,7 @@ optional<Error> LineLayer::setPaintProperty(const std::string& name, const Conve if (property == Property::LinePattern) { Error error; - optional<PropertyValue<std::string>> typedValue = convert<PropertyValue<std::string>>(value, error, false, false); + optional<PropertyValue<std::string>> typedValue = convert<PropertyValue<std::string>>(value, error, true, false); if (!typedValue) { return error; } diff --git a/src/mbgl/style/layers/line_layer_properties.hpp b/src/mbgl/style/layers/line_layer_properties.hpp index 5fd349d38b..6f85eadafb 100644 --- a/src/mbgl/style/layers/line_layer_properties.hpp +++ b/src/mbgl/style/layers/line_layer_properties.hpp @@ -68,7 +68,7 @@ struct LineDasharray : CrossFadedPaintProperty<std::vector<float>> { static std::vector<float> defaultValue() { return { }; } }; -struct LinePattern : CrossFadedPaintProperty<std::string> { +struct LinePattern : CrossFadedDataDrivenPaintProperty<std::string, attributes::a_pattern_to, uniforms::u_pattern_to, attributes::a_pattern_from, uniforms::u_pattern_from> { static std::string defaultValue() { return ""; } }; diff --git a/src/mbgl/style/paint_property.hpp b/src/mbgl/style/paint_property.hpp index 1afc1e5734..58de3354fb 100644 --- a/src/mbgl/style/paint_property.hpp +++ b/src/mbgl/style/paint_property.hpp @@ -36,6 +36,23 @@ public: using Attribute = A; using Attributes = TypeList<A>; using Uniform = U; + using Uniforms = TypeList<U>; +}; + +template <class T, class A1, class U1, class A2, class U2> +class CrossFadedDataDrivenPaintProperty { +public: + using TransitionableType = Transitionable<PropertyValue<T>>; + using UnevaluatedType = Transitioning<PropertyValue<T>>; + using EvaluatorType = DataDrivenPropertyEvaluator<Faded<T>>; + using PossiblyEvaluatedType = PossiblyEvaluatedPropertyValue<Faded<T>>; + using Type = T; + static constexpr bool IsDataDriven = true; + + using Attribute = A1; + using Attributes = TypeList<A1, A2>; + using Uniforms = TypeList<U1, U2>; + using Uniform = U1; }; template <class T> diff --git a/src/mbgl/tile/geometry_tile.cpp b/src/mbgl/tile/geometry_tile.cpp index 90d4d07895..9743cd3f7d 100644 --- a/src/mbgl/tile/geometry_tile.cpp +++ b/src/mbgl/tile/geometry_tile.cpp @@ -137,8 +137,8 @@ void GeometryTile::onLayout(LayoutResult result, const uint64_t resultCorrelatio if (result.glyphAtlasImage) { glyphAtlasImage = std::move(*result.glyphAtlasImage); } - if (result.iconAtlasImage) { - iconAtlasImage = std::move(*result.iconAtlasImage); + if (result.iconAtlas.image.valid()) { + iconAtlas = std::move(result.iconAtlas); } observer->onTileChanged(*this); @@ -160,14 +160,22 @@ void GeometryTile::getGlyphs(GlyphDependencies glyphDependencies) { glyphManager.getGlyphs(*this, std::move(glyphDependencies)); } -void GeometryTile::onImagesAvailable(ImageMap images, uint64_t imageCorrelationID) { - worker.self().invoke(&GeometryTileWorker::onImagesAvailable, std::move(images), imageCorrelationID); +void GeometryTile::onImagesAvailable(ImageMap images, ImageMap patterns, uint64_t imageCorrelationID) { + worker.self().invoke(&GeometryTileWorker::onImagesAvailable, std::move(images), std::move(patterns), imageCorrelationID); } void GeometryTile::getImages(ImageRequestPair pair) { imageManager.getImages(*this, std::move(pair)); } +const optional<ImagePosition> GeometryTile::getPattern(const std::string& pattern) { + auto it = iconAtlas.patternPositions.find(pattern); + if (it != iconAtlas.patternPositions.end()) { + return it->second; + } + return {}; +} + void GeometryTile::upload(gl::Context& context) { auto uploadFn = [&] (Bucket& bucket) { if (bucket.needsUpload()) { @@ -184,9 +192,9 @@ void GeometryTile::upload(gl::Context& context) { glyphAtlasImage = {}; } - if (iconAtlasImage) { - iconAtlasTexture = context.createTexture(*iconAtlasImage, 0); - iconAtlasImage = {}; + if (iconAtlas.image.valid()) { + iconAtlasTexture = context.createTexture(iconAtlas.image, 0); + iconAtlas.image = {}; } } diff --git a/src/mbgl/tile/geometry_tile.hpp b/src/mbgl/tile/geometry_tile.hpp index af122474c2..3d0ca03a82 100644 --- a/src/mbgl/tile/geometry_tile.hpp +++ b/src/mbgl/tile/geometry_tile.hpp @@ -37,7 +37,7 @@ public: void setShowCollisionBoxes(const bool showCollisionBoxes) override; void onGlyphsAvailable(GlyphMap) override; - void onImagesAvailable(ImageMap, uint64_t imageCorrelationID) override; + void onImagesAvailable(ImageMap, ImageMap, uint64_t imageCorrelationID) override; void getGlyphs(GlyphDependencies); void getImages(ImageRequestPair); @@ -69,26 +69,26 @@ public: std::unordered_map<std::string, std::shared_ptr<Bucket>> buckets; std::unique_ptr<FeatureIndex> featureIndex; optional<AlphaImage> glyphAtlasImage; - optional<PremultipliedImage> iconAtlasImage; + ImageAtlas iconAtlas; LayoutResult(std::unordered_map<std::string, std::shared_ptr<Bucket>> buckets_, std::unique_ptr<FeatureIndex> featureIndex_, optional<AlphaImage> glyphAtlasImage_, - optional<PremultipliedImage> iconAtlasImage_) + ImageAtlas iconAtlas_) : buckets(std::move(buckets_)), featureIndex(std::move(featureIndex_)), glyphAtlasImage(std::move(glyphAtlasImage_)), - iconAtlasImage(std::move(iconAtlasImage_)) {} + iconAtlas(std::move(iconAtlas_)) {} }; void onLayout(LayoutResult, uint64_t correlationID); void onError(std::exception_ptr, uint64_t correlationID); - + bool holdForFade() const override; void markRenderedIdeal() override; void markRenderedPreviously() override; void performedFadePlacement() override; - + const optional<ImagePosition> getPattern(const std::string& pattern); const std::shared_ptr<FeatureIndex> getFeatureIndex() const { return latestFeatureIndex; } protected: @@ -117,7 +117,7 @@ private: std::shared_ptr<FeatureIndex> latestFeatureIndex; optional<AlphaImage> glyphAtlasImage; - optional<PremultipliedImage> iconAtlasImage; + ImageAtlas iconAtlas; const MapMode mode; diff --git a/src/mbgl/tile/geometry_tile_worker.cpp b/src/mbgl/tile/geometry_tile_worker.cpp index 31f4b89801..973f9af737 100644 --- a/src/mbgl/tile/geometry_tile_worker.cpp +++ b/src/mbgl/tile/geometry_tile_worker.cpp @@ -2,10 +2,14 @@ #include <mbgl/tile/geometry_tile_data.hpp> #include <mbgl/tile/geometry_tile.hpp> #include <mbgl/layout/symbol_layout.hpp> +#include <mbgl/layout/pattern_layout.hpp> #include <mbgl/renderer/bucket_parameters.hpp> #include <mbgl/renderer/group_by_layout.hpp> #include <mbgl/style/filter.hpp> #include <mbgl/style/layers/symbol_layer_impl.hpp> +#include <mbgl/renderer/layers/render_fill_layer.hpp> +#include <mbgl/renderer/layers/render_fill_extrusion_layer.hpp> +#include <mbgl/renderer/layers/render_line_layer.hpp> #include <mbgl/renderer/layers/render_symbol_layer.hpp> #include <mbgl/renderer/buckets/symbol_bucket.hpp> #include <mbgl/util/logging.hpp> @@ -195,11 +199,15 @@ void GeometryTileWorker::symbolDependenciesChanged() { assert(hasPendingParseResult()); performSymbolLayout(); coalesce(); + } else if (patternNeedsLayout) { + performSymbolLayout(); + coalesce(); } + break; case Coalescing: - if (symbolLayoutsNeedPreparation) { + if (symbolLayoutsNeedPreparation || patternNeedsLayout) { state = NeedsSymbolLayout; } break; @@ -267,11 +275,12 @@ void GeometryTileWorker::onGlyphsAvailable(GlyphMap newGlyphMap) { symbolDependenciesChanged(); } -void GeometryTileWorker::onImagesAvailable(ImageMap newImageMap, uint64_t imageCorrelationID_) { +void GeometryTileWorker::onImagesAvailable(ImageMap newIconMap, ImageMap newPatternMap, uint64_t imageCorrelationID_) { if (imageCorrelationID != imageCorrelationID_) { return; // Ignore outdated image request replies. } - imageMap = std::move(newImageMap); + imageMap = std::move(newIconMap); + patternMap = std::move(newPatternMap); pendingImageDependencies.clear(); symbolDependenciesChanged(); } @@ -292,6 +301,7 @@ void GeometryTileWorker::requestNewGlyphs(const GlyphDependencies& glyphDependen void GeometryTileWorker::requestNewImages(const ImageDependencies& imageDependencies) { pendingImageDependencies = imageDependencies; + if (!pendingImageDependencies.empty()) { parent.invoke(&GeometryTile::getImages, std::make_pair(pendingImageDependencies, ++imageCorrelationID)); } @@ -315,6 +325,24 @@ static std::vector<std::unique_ptr<RenderLayer>> toRenderLayers(const std::vecto return renderLayers; } +// Helper function that takes a PatternLayout and either adds it to patternLayouts to await the +// availability of the imageDependencies or, if the layergroup does not use a *-pattern property, +// creates the Bucket and adds it to GeometryTileWorker::buckets. +template <typename B> +void GeometryTileWorker::checkPatternLayout(std::unique_ptr<PatternLayout<B>> layout) { + if (layout->pattern()) { + patternLayouts.push_back(std::move(layout)); + patternNeedsLayout = true; + } else { + std::shared_ptr<B> bucket = layout->createBucket({}, featureIndex); + if (bucket->hasData()) { + for (const auto& pair : layout->layerPaintProperties) { + buckets.emplace(pair.first, bucket); + } + } + } +} + void GeometryTileWorker::parse() { if (!data || !layers) { return; @@ -329,6 +357,7 @@ void GeometryTileWorker::parse() { } std::unordered_map<std::string, std::unique_ptr<SymbolLayout>> symbolLayoutMap; + buckets.clear(); featureIndex = std::make_unique<FeatureIndex>(*data ? (*data)->clone() : nullptr); BucketParameters parameters { id, mode, pixelRatio }; @@ -362,12 +391,27 @@ void GeometryTileWorker::parse() { } featureIndex->setBucketLayerIDs(leader.getID(), layerIDs); - if (leader.is<RenderSymbolLayer>()) { auto layout = leader.as<RenderSymbolLayer>()->createLayout( parameters, group, std::move(geometryLayer), glyphDependencies, imageDependencies); symbolLayoutMap.emplace(leader.getID(), std::move(layout)); symbolLayoutsNeedPreparation = true; + } else if (leader.is<RenderLineLayer>()) { + // Layers that support pattern properties have an extra step at layout time to figure out what images + // are needed to render the layer. They use the intermediate PatternLayout data structure to accomplish this, + // and either immediately create a bucket if no pattern properties are used, or the PatternLayout is stored until + // the images are available to add the features to the buckets. + std::unique_ptr<PatternLayout<LineBucket>> layout = leader.as<RenderLineLayer>()->createLayout( + parameters, group, std::move(geometryLayer), imageDependencies); + checkPatternLayout(std::move(layout)); + } else if (leader.is<RenderFillLayer>()) { + std::unique_ptr<PatternLayout<FillBucket>> layout = leader.as<RenderFillLayer>()->createLayout( + parameters, group, std::move(geometryLayer), imageDependencies); + checkPatternLayout(std::move(layout)); + } else if (leader.is<RenderFillExtrusionLayer>()) { + std::unique_ptr<PatternLayout<FillExtrusionBucket>> layout = leader.as<RenderFillExtrusionLayer>()->createLayout( + parameters, group, std::move(geometryLayer), imageDependencies); + checkPatternLayout(std::move(layout)); } else { const Filter& filter = leader.baseImpl->filter; const std::string& sourceLayerID = leader.baseImpl->sourceLayer; @@ -380,17 +424,17 @@ void GeometryTileWorker::parse() { continue; GeometryCollection geometries = feature->getGeometries(); - bucket->addFeature(*feature, geometries); + bucket->addFeature(*feature, geometries, {}, PatternLayerMap ()); featureIndex->insert(geometries, i, sourceLayerID, leader.getID()); } if (!bucket->hasData()) { continue; } - for (const auto& layer : group) { buckets.emplace(layer->getID(), bucket); } + } } @@ -433,14 +477,13 @@ void GeometryTileWorker::performSymbolLayout() { MBGL_TIMING_START(watch) optional<AlphaImage> glyphAtlasImage; - optional<PremultipliedImage> iconAtlasImage; + ImageAtlas iconAtlas; if (symbolLayoutsNeedPreparation) { GlyphAtlas glyphAtlas = makeGlyphAtlas(glyphMap); - ImageAtlas imageAtlas = makeImageAtlas(imageMap); + iconAtlas = makeImageAtlas(imageMap, patternMap); glyphAtlasImage = std::move(glyphAtlas.image); - iconAtlasImage = std::move(imageAtlas.image); for (auto& symbolLayout : symbolLayouts) { if (obsolete) { @@ -448,12 +491,45 @@ void GeometryTileWorker::performSymbolLayout() { } symbolLayout->prepare(glyphMap, glyphAtlas.positions, - imageMap, imageAtlas.positions); + imageMap, iconAtlas.iconPositions); } symbolLayoutsNeedPreparation = false; } + if (!iconAtlas.image.valid()) { + iconAtlas = makeImageAtlas(imageMap, patternMap); + } + + for (auto& value : patternLayouts) { + if (obsolete) { + return; + } + + value.match( + [&] (const std::unique_ptr<PatternLayout<LineBucket>>& linePatternLayout) { + std::shared_ptr<LineBucket> bucket = linePatternLayout->createBucket(iconAtlas.patternPositions, featureIndex); + for (const auto& pair : linePatternLayout->layerPaintProperties) { + buckets.emplace(pair.first, bucket); + } + }, + [&] (const std::unique_ptr<PatternLayout<FillBucket>>& fillPatternLayout) { + std::shared_ptr<FillBucket> bucket = fillPatternLayout->createBucket(iconAtlas.patternPositions, featureIndex); + for (const auto& pair : fillPatternLayout->layerPaintProperties) { + buckets.emplace(pair.first, bucket); + } + }, + [&] (const std::unique_ptr<PatternLayout<FillExtrusionBucket>>& fillExtrusionLayout) { + std::shared_ptr<FillExtrusionBucket> bucket = fillExtrusionLayout->createBucket(iconAtlas.patternPositions, featureIndex); + for (const auto& pair : fillExtrusionLayout->layerPaintProperties) { + buckets.emplace(pair.first, bucket); + } + } + ); + } + patternNeedsLayout = false; + patternLayouts.clear(); + for (auto& symbolLayout : symbolLayouts) { if (obsolete) { return; @@ -483,8 +559,7 @@ void GeometryTileWorker::performSymbolLayout() { std::move(buckets), std::move(featureIndex), std::move(glyphAtlasImage), - std::move(iconAtlasImage) + std::move(iconAtlas) }, correlationID); } - } // namespace mbgl diff --git a/src/mbgl/tile/geometry_tile_worker.hpp b/src/mbgl/tile/geometry_tile_worker.hpp index b5417c8114..616d1a3625 100644 --- a/src/mbgl/tile/geometry_tile_worker.hpp +++ b/src/mbgl/tile/geometry_tile_worker.hpp @@ -10,6 +10,9 @@ #include <mbgl/style/layer_impl.hpp> #include <mbgl/geometry/feature_index.hpp> #include <mbgl/renderer/bucket.hpp> +#include <mbgl/renderer/buckets/fill_bucket.hpp> +#include <mbgl/renderer/buckets/fill_extrusion_bucket.hpp> +#include <mbgl/renderer/buckets/line_bucket.hpp> #include <atomic> #include <memory> @@ -20,6 +23,9 @@ class GeometryTile; class GeometryTileData; class SymbolLayout; +template <class B> +class PatternLayout; + namespace style { class Layer; } // namespace style @@ -41,7 +47,7 @@ public: void setShowCollisionBoxes(bool showCollisionBoxes_, uint64_t correlationID_); void onGlyphsAvailable(GlyphMap glyphs); - void onImagesAvailable(ImageMap images, uint64_t imageCorrelationID); + void onImagesAvailable(ImageMap icons, ImageMap patterns, uint64_t imageCorrelationID); private: void coalesced(); @@ -57,6 +63,9 @@ private: bool hasPendingSymbolDependencies() const; bool hasPendingParseResult() const; + template <typename B> + void checkPatternLayout(std::unique_ptr<PatternLayout<B>> layout); + ActorRef<GeometryTileWorker> self; ActorRef<GeometryTile> parent; @@ -85,11 +94,21 @@ private: optional<std::unique_ptr<const GeometryTileData>> data; bool symbolLayoutsNeedPreparation = false; + bool patternNeedsLayout = false; + std::vector<std::unique_ptr<SymbolLayout>> symbolLayouts; + + using LinePatternLayout = PatternLayout<LineBucket>; + using FillPatternLayout = PatternLayout<FillBucket>; + using FillExtrusionPatternLayout = PatternLayout<FillExtrusionBucket>; + + std::vector<variant<std::unique_ptr<LinePatternLayout>, std::unique_ptr<FillPatternLayout>, std::unique_ptr<FillExtrusionPatternLayout>>> patternLayouts; + GlyphDependencies pendingGlyphDependencies; ImageDependencies pendingImageDependencies; GlyphMap glyphMap; ImageMap imageMap; + ImageMap patternMap; bool showCollisionBoxes; bool firstLoad = true; diff --git a/test/gl/bucket.test.cpp b/test/gl/bucket.test.cpp index 9b28b2e01a..04e6447ad8 100644 --- a/test/gl/bucket.test.cpp +++ b/test/gl/bucket.test.cpp @@ -52,7 +52,7 @@ TEST(Buckets, CircleBucket) { ASSERT_FALSE(bucket.needsUpload()); GeometryCollection point { { { 0, 0 } } }; - bucket.addFeature(StubGeometryTileFeature { {}, FeatureType::Point, point, properties }, point); + bucket.addFeature(StubGeometryTileFeature { {}, FeatureType::Point, point, properties }, point, {}, PatternLayerMap()); ASSERT_TRUE(bucket.hasData()); ASSERT_TRUE(bucket.needsUpload()); @@ -64,14 +64,15 @@ TEST(Buckets, CircleBucket) { TEST(Buckets, FillBucket) { HeadlessBackend backend({ 512, 256 }); BackendScope scope { backend }; + style::Properties<>::PossiblyEvaluated layout; gl::Context context; - FillBucket bucket { { {0, 0, 0}, MapMode::Static, 1.0 }, {} }; + FillBucket bucket { layout, {}, 5.0f, 1}; ASSERT_FALSE(bucket.hasData()); ASSERT_FALSE(bucket.needsUpload()); GeometryCollection polygon { { { 0, 0 }, { 0, 1 }, { 1, 1 } } }; - bucket.addFeature(StubGeometryTileFeature { {}, FeatureType::Polygon, polygon, properties }, polygon); + bucket.addFeature(StubGeometryTileFeature { {}, FeatureType::Polygon, polygon, properties }, polygon, {}, PatternLayerMap()); ASSERT_TRUE(bucket.hasData()); ASSERT_TRUE(bucket.needsUpload()); @@ -82,19 +83,20 @@ TEST(Buckets, FillBucket) { TEST(Buckets, LineBucket) { HeadlessBackend backend({ 512, 256 }); BackendScope scope { backend }; + style::LineLayoutProperties::PossiblyEvaluated layout; gl::Context context; - LineBucket bucket { { {0, 0, 0}, MapMode::Static, 1.0 }, {}, {} }; + LineBucket bucket { layout, {}, 10.0f, 1 }; ASSERT_FALSE(bucket.hasData()); ASSERT_FALSE(bucket.needsUpload()); // Ignore invalid feature type. GeometryCollection point { { { 0, 0 } } }; - bucket.addFeature(StubGeometryTileFeature { {}, FeatureType::Point, point, properties }, point); + bucket.addFeature(StubGeometryTileFeature { {}, FeatureType::Point, point, properties }, point, {}, PatternLayerMap()); ASSERT_FALSE(bucket.hasData()); GeometryCollection line { { { 0, 0 }, { 1, 1 } } }; - bucket.addFeature(StubGeometryTileFeature { {}, FeatureType::LineString, line, properties }, line); + bucket.addFeature(StubGeometryTileFeature { {}, FeatureType::LineString, line, properties }, line, {}, PatternLayerMap()); ASSERT_TRUE(bucket.hasData()); ASSERT_TRUE(bucket.needsUpload()); @@ -123,7 +125,7 @@ TEST(Buckets, SymbolBucket) { // SymbolBucket::addFeature() is a no-op. GeometryCollection point { { { 0, 0 } } }; - bucket.addFeature(StubGeometryTileFeature { {}, FeatureType::Point, point, properties }, point); + bucket.addFeature(StubGeometryTileFeature { {}, FeatureType::Point, point, properties }, point, {}, PatternLayerMap()); ASSERT_FALSE(bucket.hasData()); ASSERT_FALSE(bucket.needsUpload()); diff --git a/test/programs/symbol_program.test.cpp b/test/programs/symbol_program.test.cpp index b2467d5998..4d30e5dc3d 100644 --- a/test/programs/symbol_program.test.cpp +++ b/test/programs/symbol_program.test.cpp @@ -9,9 +9,9 @@ using namespace mbgl::style::expression::dsl; TEST(SymbolProgram, SymbolSizeBinder) { auto binder = SymbolSizeBinder::create(5.0f, 12.0f, 0.0f); auto uniformValues = binder->uniformValues(5.5f); - EXPECT_EQ(uniformValues.get<uniforms::u_is_size_zoom_constant>().t, true); - EXPECT_EQ(uniformValues.get<uniforms::u_is_size_feature_constant>().t, true); - EXPECT_EQ(uniformValues.get<uniforms::u_size>().t, 12.0f); + EXPECT_EQ(uniformValues.get<uniforms::u_is_size_zoom_constant>(), true); + EXPECT_EQ(uniformValues.get<uniforms::u_is_size_feature_constant>(), true); + EXPECT_EQ(uniformValues.get<uniforms::u_size>(), 12.0f); binder = SymbolSizeBinder::create(1.0f, style::PropertyExpression<float>( interpolate( @@ -20,9 +20,9 @@ TEST(SymbolProgram, SymbolSizeBinder) { 0., literal(8.), 10., literal(18.))), 0.0f); uniformValues = binder->uniformValues(1.5f); - EXPECT_EQ(uniformValues.get<uniforms::u_is_size_zoom_constant>().t, false); - EXPECT_EQ(uniformValues.get<uniforms::u_is_size_feature_constant>().t, true); - EXPECT_EQ(uniformValues.get<uniforms::u_size>().t, 9.5f); + EXPECT_EQ(uniformValues.get<uniforms::u_is_size_zoom_constant>(), false); + EXPECT_EQ(uniformValues.get<uniforms::u_is_size_feature_constant>(), true); + EXPECT_EQ(uniformValues.get<uniforms::u_size>(), 9.5f); binder = SymbolSizeBinder::create(0.0f, style::PropertyExpression<float>( interpolate( @@ -31,9 +31,9 @@ TEST(SymbolProgram, SymbolSizeBinder) { 1., literal(8.), 11., literal(18.))), 0.0f); uniformValues = binder->uniformValues(0.5f); - EXPECT_EQ(uniformValues.get<uniforms::u_is_size_zoom_constant>().t, false); - EXPECT_EQ(uniformValues.get<uniforms::u_is_size_feature_constant>().t, true); - EXPECT_EQ(uniformValues.get<uniforms::u_size>().t, 8.0f); + EXPECT_EQ(uniformValues.get<uniforms::u_is_size_zoom_constant>(), false); + EXPECT_EQ(uniformValues.get<uniforms::u_is_size_feature_constant>(), true); + EXPECT_EQ(uniformValues.get<uniforms::u_size>(), 8.0f); binder = SymbolSizeBinder::create(12.0f, style::PropertyExpression<float>( interpolate( @@ -42,9 +42,9 @@ TEST(SymbolProgram, SymbolSizeBinder) { 1., literal(8.), 11., literal(18.))), 0.0f); uniformValues = binder->uniformValues(12.5f); - EXPECT_EQ(uniformValues.get<uniforms::u_is_size_zoom_constant>().t, false); - EXPECT_EQ(uniformValues.get<uniforms::u_is_size_feature_constant>().t, true); - EXPECT_EQ(uniformValues.get<uniforms::u_size>().t, 18.0f); + EXPECT_EQ(uniformValues.get<uniforms::u_is_size_zoom_constant>(), false); + EXPECT_EQ(uniformValues.get<uniforms::u_is_size_feature_constant>(), true); + EXPECT_EQ(uniformValues.get<uniforms::u_size>(), 18.0f); binder = SymbolSizeBinder::create(0.0f, style::PropertyExpression<float>( interpolate( @@ -53,8 +53,8 @@ TEST(SymbolProgram, SymbolSizeBinder) { 1., literal(8.), 11., literal(18.))), 0.0f); uniformValues = binder->uniformValues(12.5f); - EXPECT_EQ(uniformValues.get<uniforms::u_is_size_zoom_constant>().t, true); - EXPECT_EQ(uniformValues.get<uniforms::u_is_size_feature_constant>().t, false); + EXPECT_EQ(uniformValues.get<uniforms::u_is_size_zoom_constant>(), true); + EXPECT_EQ(uniformValues.get<uniforms::u_is_size_feature_constant>(), false); binder = SymbolSizeBinder::create(5.0f, style::PropertyExpression<float>( interpolate( @@ -63,7 +63,7 @@ TEST(SymbolProgram, SymbolSizeBinder) { 1., interpolate(linear(), number(get("x")), 0., literal(8.), 100., literal(18.)), 11., interpolate(linear(), number(get("x")), 0., literal(12.), 100., literal(24.9)))), 0.0f); uniformValues = binder->uniformValues(5.5f); - EXPECT_EQ(uniformValues.get<uniforms::u_is_size_zoom_constant>().t, false); - EXPECT_EQ(uniformValues.get<uniforms::u_is_size_feature_constant>().t, false); - EXPECT_EQ(uniformValues.get<uniforms::u_size_t>().t, 0.45f); + EXPECT_EQ(uniformValues.get<uniforms::u_is_size_zoom_constant>(), false); + EXPECT_EQ(uniformValues.get<uniforms::u_is_size_feature_constant>(), false); + EXPECT_EQ(uniformValues.get<uniforms::u_size_t>(), 0.45f); } diff --git a/test/renderer/image_manager.test.cpp b/test/renderer/image_manager.test.cpp index ebe1bcd72f..4a838d0f9c 100644 --- a/test/renderer/image_manager.test.cpp +++ b/test/renderer/image_manager.test.cpp @@ -108,11 +108,11 @@ TEST(ImageManager, RemoveReleasesBinPackRect) { class StubImageRequestor : public ImageRequestor { public: - void onImagesAvailable(ImageMap images, uint64_t imageCorrelationID_) final { - if (imagesAvailable && imageCorrelationID == imageCorrelationID_) imagesAvailable(images); + void onImagesAvailable(ImageMap icons, ImageMap patterns, uint64_t imageCorrelationID_) final { + if (imagesAvailable && imageCorrelationID == imageCorrelationID_) imagesAvailable(icons, patterns); } - std::function<void (ImageMap)> imagesAvailable; + std::function<void (ImageMap, ImageMap)> imagesAvailable; uint64_t imageCorrelationID = 0; }; @@ -121,12 +121,14 @@ TEST(ImageManager, NotifiesRequestorWhenSpriteIsLoaded) { StubImageRequestor requestor; bool notified = false; - requestor.imagesAvailable = [&] (ImageMap) { + requestor.imagesAvailable = [&] (ImageMap, ImageMap) { notified = true; }; uint64_t imageCorrelationID = 0; - imageManager.getImages(requestor, std::make_pair(std::set<std::string> {"one"}, imageCorrelationID)); + ImageDependencies dependencies; + dependencies.emplace("one", ImageType::Icon); + imageManager.getImages(requestor, std::make_pair(dependencies, imageCorrelationID)); ASSERT_FALSE(notified); imageManager.setLoaded(true); @@ -138,13 +140,15 @@ TEST(ImageManager, NotifiesRequestorImmediatelyIfDependenciesAreSatisfied) { StubImageRequestor requestor; bool notified = false; - requestor.imagesAvailable = [&] (ImageMap) { + requestor.imagesAvailable = [&] (ImageMap, ImageMap) { notified = true; }; uint64_t imageCorrelationID = 0; + ImageDependencies dependencies; + dependencies.emplace("one", ImageType::Icon); imageManager.addImage(makeMutable<style::Image::Impl>("one", PremultipliedImage({ 16, 16 }), 2)); - imageManager.getImages(requestor, std::make_pair(std::set<std::string> {"one"}, imageCorrelationID)); + imageManager.getImages(requestor, std::make_pair(dependencies, imageCorrelationID)); ASSERT_TRUE(notified); } |