From fbbf8cf16bda19d766b25565a9735a10817e4ac8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20B=C3=BCchele?= Date: Fri, 13 Apr 2018 08:38:06 -0700 Subject: [PATCH] =?UTF-8?q?Initial=20commit=20=F0=9F=8E=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fbshipit-source-id: b6fc29740c6875d2e78953b8a7123890a67930f2 Co-authored-by: Sebastian McKenzie Co-authored-by: John Knox Co-authored-by: Emil Sjölander Co-authored-by: Pritesh Nandgaonkar --- .eslintignore | 8 + .eslintrc.js | 30 + .flowconfig | 24 + .gitignore | 6 + .gitmodules | 3 + .sonarhandles | 1 + .travis.yml | 56 + .vscode/launch.json | 12 + .yarnrc | 1 + CODE_OF_CONDUCT.md | 3 + CONTRIBUTING.md | 55 + LICENSE | 21 + README.md | 54 + android/AndroidManifest.xml | 4 + android/CMakeLists.txt | 63 + android/android/AndroidSonarClient.java | 83 + android/android/EventBase.java | 32 + android/android/SonarClientImpl.java | 57 + android/android/SonarConnectionImpl.java | 52 + android/android/SonarResponderImpl.java | 53 + android/android/SonarThread.java | 44 + android/android/sonar.cpp | 305 + android/android/utils/SonarUtils.java | 54 + android/build.gradle | 172 + android/core/ErrorReportingRunnable.java | 34 + android/core/SonarArray.java | 164 + android/core/SonarClient.java | 20 + android/core/SonarConnection.java | 37 + android/core/SonarDynamic.java | 124 + android/core/SonarObject.java | 221 + android/core/SonarPlugin.java | 37 + android/core/SonarReceiver.java | 25 + android/core/SonarResponder.java | 28 + android/core/SonarValue.java | 12 + .../plugins/common/BufferingSonarPlugin.java | 75 + .../common/MainThreadSonarReceiver.java | 40 + android/plugins/common/RingBuffer.java | 31 + .../plugins/console/ConsoleSonarPlugin.java | 35 + .../console/JavascriptEnvironment.java | 58 + .../plugins/console/JavascriptSession.java | 169 + .../console/iface/ConsoleCommandReceiver.java | 88 + .../iface/NullScriptingEnvironment.java | 43 + .../console/iface/ScriptingEnvironment.java | 17 + .../console/iface/ScriptingSession.java | 20 + .../plugins/inspector/ApplicationWrapper.java | 128 + android/plugins/inspector/BoundsDrawable.java | 175 + .../plugins/inspector/DescriptorMapping.java | 89 + android/plugins/inspector/HiddenNode.java | 12 + .../plugins/inspector/HighlightedOverlay.java | 69 + .../inspector/InspectorSonarPlugin.java | 418 ++ android/plugins/inspector/InspectorValue.java | 79 + android/plugins/inspector/Named.java | 27 + android/plugins/inspector/NodeDescriptor.java | 143 + android/plugins/inspector/ObjectTracker.java | 45 + .../plugins/inspector/SearchResultNode.java | 51 + .../SelfRegisteringNodeDescriptor.java | 14 + android/plugins/inspector/Touch.java | 31 + .../descriptors/ActivityDescriptor.java | 129 + .../descriptors/ApplicationDescriptor.java | 161 + .../descriptors/DialogDescriptor.java | 81 + .../descriptors/DialogFragmentDescriptor.java | 90 + .../descriptors/DrawableDescriptor.java | 146 + .../descriptors/FragmentDescriptor.java | 124 + .../descriptors/ObjectDescriptor.java | 85 + .../SupportDialogFragmentDescriptor.java | 90 + .../SupportFragmentDescriptor.java | 106 + .../descriptors/TextViewDescriptor.java | 132 + .../inspector/descriptors/ViewDescriptor.java | 708 +++ .../descriptors/ViewGroupDescriptor.java | 273 + .../descriptors/WindowDescriptor.java | 81 + .../utils/AccessibilityEvaluationUtil.java | 383 ++ .../utils/AccessibilityRoleUtil.java | 120 + .../descriptors/utils/AccessibilityUtil.java | 357 ++ .../utils/AndroidRootResolver.java | 102 + .../descriptors/utils/EnumMapping.java | 51 + .../utils/ViewAccessibilityHelper.java | 48 + .../litho-sonar/DebugComponentDescriptor.java | 696 +++ .../litho-sonar/LithoSonarDescriptors.java | 15 + .../litho-sonar/LithoViewDescriptor.java | 111 + .../litho-sonar/PropWithDescription.java | 8 + android/plugins/network/NetworkReporter.java | 69 + .../network/NetworkResponseFormatter.java | 22 + .../plugins/network/NetworkSonarPlugin.java | 122 + .../network/SonarOkhttpInterceptor.java | 106 + .../SharedPreferencesSonarPlugin.java | 114 + android/sample/AndroidManifest.xml | 29 + android/sample/build.gradle | 63 + android/sample/debug.keystore | Bin 0 -> 2253 bytes android/sample/debug.keystore.properties | 3 + .../sample/res/drawable-hdpi/ic_launcher.png | Bin 0 -> 2843 bytes .../sample/res/drawable-mdpi/ic_launcher.png | Bin 0 -> 1642 bytes .../sample/res/drawable-xhdpi/ic_launcher.png | Bin 0 -> 3433 bytes .../res/drawable-xxhdpi/ic_launcher.png | Bin 0 -> 5827 bytes .../res/drawable-xxxhdpi/ic_launcher.png | Bin 0 -> 7987 bytes android/sample/res/values/strings.xml | 5 + android/sample/res/values/styles.xml | 7 + .../facebook/sonar/sample/MainActivity.java | 22 + .../sonar/sample/RootComponentSpec.java | 105 + .../sonar/sample/SonarSampleApplication.java | 50 + android/testing/SonarConnectionMock.java | 56 + android/testing/SonarResponderMock.java | 39 + .../console/ConsoleSonarPluginTest.java | 49 + .../console/JavascriptSessionTest.java | 109 + .../inspector/ApplicationWrapperTest.java | 90 + .../inspector/DescriptorMappingTest.java | 129 + .../inspector/InspectorSonarPluginTest.java | 424 ++ .../descriptors/ViewGroupDescriptorTest.java | 63 + .../DoubleConversion/ApplicationManifest.xml | 4 + .../DoubleConversion/CMakeLists.txt | 12 + .../third-party/DoubleConversion/build.gradle | 34 + .../third-party/Folly/ApplicationManifest.xml | 4 + android/third-party/Folly/CMakeLists.txt | 81 + android/third-party/Folly/build.gradle | 39 + .../third-party/glog/ApplicationManifest.xml | 4 + android/third-party/glog/CMakeLists.txt | 45 + android/third-party/glog/build.gradle | 34 + android/third-party/glog/config.h | 179 + android/third-party/glog/logging.cc | 2088 +++++++ build.gradle | 68 + docs/assets/initial.png | Bin 0 -> 210671 bytes docs/assets/layout.png | Bin 0 -> 536975 bytes docs/assets/logs.png | Bin 0 -> 305272 bytes docs/assets/network.png | Bin 0 -> 630757 bytes docs/communitcating.md | 46 + docs/create-plugin.md | 140 + docs/create-table-plugin.md | 86 + docs/error-handling.md | 32 + docs/getting-started.md | 82 + docs/jssetup.md | 58 + docs/layout-plugin.md | 54 + docs/logs-plugin.md | 18 + docs/network-plugin.md | 32 + docs/send-data.md | 50 + docs/stetho.md | 11 + docs/styling-components.md | 75 + docs/testing.md | 96 + docs/ui-components.md | 254 + docs/unterstanding-sonar.md | 13 + flow-typed/electron-menu.js | 78 + flow-typed/npm/JSONStream_vx.x.x.js | 192 + flow-typed/npm/adbkit-fb_vx.x.x.js | 507 ++ flow-typed/npm/adbkit-logcat-fb_vx.x.x.js | 80 + flow-typed/npm/babel-cli_vx.x.x.js | 108 + flow-typed/npm/babel-code-frame_vx.x.x.js | 32 + flow-typed/npm/babel-core_vx.x.x.js | 171 + flow-typed/npm/babel-eslint_vx.x.x.js | 80 + flow-typed/npm/babel-generator_vx.x.x.js | 151 + ...lugin-transform-class-properties_vx.x.x.js | 32 + ...n-transform-es2015-destructuring_vx.x.x.js | 32 + ...ransform-es2015-modules-commonjs_vx.x.x.js | 32 + ...lugin-transform-flow-strip-types_vx.x.x.js | 32 + ...gin-transform-object-rest-spread_vx.x.x.js | 32 + flow-typed/npm/babel-preset-react_vx.x.x.js | 32 + flow-typed/npm/babel-register_vx.x.x.js | 46 + flow-typed/npm/babel-traverse_vx.x.x.js | 200 + flow-typed/npm/babylon_vx.x.x.js | 46 + flow-typed/npm/chalk_v1.x.x.js | 114 + flow-typed/npm/codemirror_vx.x.x.js | 1761 ++++++ flow-typed/npm/dashify_vx.x.x.js | 33 + flow-typed/npm/deep-equal_vx.x.x.js | 59 + flow-typed/npm/detect-port_vx.x.x.js | 38 + flow-typed/npm/electron-builder_vx.x.x.js | 347 ++ .../npm/electron-devtools-installer_vx.x.x.js | 67 + flow-typed/npm/electron_vx.x.x.js | 59 + .../npm/eslint-config-react-app_vx.x.x.js | 33 + .../npm/eslint-plugin-flowtype_vx.x.x.js | 340 ++ flow-typed/npm/eslint-plugin-import_vx.x.x.js | 340 ++ flow-typed/npm/eslint-plugin-jest_vx.x.x.js | 67 + .../npm/eslint-plugin-jsx-a11y_vx.x.x.js | 1411 +++++ .../npm/eslint-plugin-prettier_vx.x.x.js | 32 + .../npm/eslint-plugin-prettify_vx.x.x.js | 45 + flow-typed/npm/eslint-plugin-react_vx.x.x.js | 500 ++ flow-typed/npm/eslint_vx.x.x.js | 2293 +++++++ flow-typed/npm/express_v4.x.x.js | 207 + flow-typed/npm/flow-bin_v0.x.x.js | 6 + flow-typed/npm/fs-extra_vx.x.x.js | 235 + flow-typed/npm/graphiql_vx.x.x.js | 277 + flow-typed/npm/graphql_vx.x.x.js | 633 ++ flow-typed/npm/invariant_v2.x.x.js | 6 + flow-typed/npm/jest_v21.x.x.js | 584 ++ flow-typed/npm/lodash_v4.x.x.js | 4207 +++++++++++++ flow-typed/npm/openssl-wrapper_vx.x.x.js | 46 + flow-typed/npm/polished_vx.x.x.js | 585 ++ flow-typed/npm/prettier_vx.x.x.js | 87 + flow-typed/npm/prop-types_v15.x.x.js | 34 + flow-typed/npm/react-color_vx.x.x.js | 704 +++ flow-typed/npm/react-devtools-core_vx.x.x.js | 52 + flow-typed/npm/react-redux_v5.x.x.js | 157 + flow-typed/npm/react-test-renderer_vx.x.x.js | 66 + flow-typed/npm/react-virtualized_vx.x.x.js | 1376 +++++ flow-typed/npm/redux_v3.x.x.js | 59 + flow-typed/npm/rsocket.js | 8 + .../npm/string-natural-compare_vx.x.x.js | 32 + flow-typed/npm/vis_vx.x.x.js | 1305 ++++ flow-typed/npm/websocket_vx.x.x.js | 164 + flow-typed/npm/ws_vx.x.x.js | 108 + flow-typed/npm/yargs_vx.x.x.js | 101 + flow-typed/react.js | 8 + gradle.properties | 7 + gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 54413 bytes gradle/wrapper/gradle-wrapper.properties | 5 + gradlew | 172 + .../CKComponent+Sonar.h | 21 + .../CKComponent+Sonar.mm | 166 + .../CKFlexboxComponent+Sonar.h | 14 + .../CKFlexboxComponent+Sonar.mm | 80 + .../CKInsetComponent+Sonar.h | 14 + .../CKInsetComponent+Sonar.mm | 27 + .../SKComponentHostingViewDescriptor.h | 14 + .../SKComponentHostingViewDescriptor.mm | 48 + .../SKComponentLayoutDescriptor.h | 14 + .../SKComponentLayoutDescriptor.mm | 178 + .../SKComponentLayoutWrapper.h | 29 + .../SKComponentLayoutWrapper.mm | 81 + .../SKComponentRootViewDescriptor.h | 14 + .../SKComponentRootViewDescriptor.mm | 52 + .../SonarKitLayoutComponentKitSupport.h | 16 + .../SonarKitLayoutComponentKitSupport.mm | 37 + .../SonarKitLayoutComponentKitSupport/Utils.h | 12 + .../Utils.mm | 32 + .../SonarKitLayoutPlugin/SKDescriptorMapper.h | 22 + .../SKDescriptorMapper.mm | 64 + .../SonarKitLayoutPlugin/SKHighlightOverlay.h | 18 + .../SonarKitLayoutPlugin/SKHighlightOverlay.m | 54 + .../SonarKitLayoutPlugin/SKInvalidation.h | 26 + .../SonarKitLayoutPlugin/SKInvalidation.m | 57 + .../SonarKitLayoutPlugin/SKNamed.h | 17 + .../SonarKitLayoutPlugin/SKNamed.mm | 33 + .../SonarKitLayoutPlugin/SKNodeDescriptor.h | 115 + .../SonarKitLayoutPlugin/SKNodeDescriptor.mm | 83 + .../SonarKitLayoutPlugin/SKObject.h | 52 + .../SonarKitLayoutPlugin/SKObject.mm | 117 + .../SonarKitLayoutPlugin/SKSearchResultNode.h | 25 + .../SonarKitLayoutPlugin/SKSearchResultNode.m | 50 + .../SonarKitLayoutPlugin/SKTapListener.h | 22 + .../SonarKitLayoutPlugin/SKTapListenerImpl.h | 12 + .../SonarKitLayoutPlugin/SKTapListenerImpl.m | 91 + .../SonarKitLayoutPlugin/SKTouch.h | 28 + .../SonarKitLayoutPlugin/SKTouch.m | 62 + .../SonarKitLayoutPlugin.h | 31 + .../SonarKitLayoutPlugin.mm | 414 ++ .../UICollectionView+SKInvalidation.h | 17 + .../UICollectionView+SKInvalidation.mm | 35 + .../UIColor+SKSonarValueCoder.h | 17 + .../UIColor+SKSonarValueCoder.mm | 68 + .../UIView+SKInvalidation.h | 15 + .../UIView+SKInvalidation.mm | 58 + .../descriptors/SKApplicationDescriptor.h | 14 + .../descriptors/SKApplicationDescriptor.m | 66 + .../descriptors/SKButtonDescriptor.h | 16 + .../descriptors/SKButtonDescriptor.mm | 93 + .../descriptors/SKScrollViewDescriptor.h | 14 + .../descriptors/SKScrollViewDescriptor.m | 86 + .../descriptors/SKViewControllerDescriptor.h | 14 + .../descriptors/SKViewControllerDescriptor.m | 50 + .../descriptors/SKViewDescriptor.h | 18 + .../descriptors/SKViewDescriptor.mm | 575 ++ .../utils/SKHiddenWindow.h | 11 + .../utils/SKHiddenWindow.m | 16 + .../SonarKitLayoutPlugin/utils/SKObjectHash.h | 19 + .../SonarKitLayoutPlugin/utils/SKSwizzle.h | 10 + .../SonarKitLayoutPlugin/utils/SKSwizzle.mm | 32 + .../utils/SKYogaKitHelper.h | 31 + .../SKTapListenerMock.h | 14 + .../SKTapListenerMock.m | 45 + .../SonarKitLayoutPluginTests.m | 250 + .../SonarKitLayoutPluginTests/TestNode.h | 21 + .../SonarKitLayoutPluginTests/TestNode.m | 26 + .../TestNodeDescriptor.h | 13 + .../TestNodeDescriptor.m | 50 + .../FLEXNetworkLib/FLEXNetworkObserver.h | 27 + .../FLEXNetworkLib/FLEXNetworkObserver.mm | 1088 ++++ .../FLEXNetworkLib/FLEXNetworkRecorder.h | 70 + .../FLEXNetworkLib/FLEXNetworkRecorder.mm | 235 + .../FLEXNetworkLib/FLEXNetworkTransaction.h | 45 + .../FLEXNetworkLib/FLEXNetworkTransaction.m | 74 + .../FLEXNetworkLib/FLEXUtility.h | 34 + .../FLEXNetworkLib/FLEXUtility.mm | 117 + .../SKIOSNetworkPlugin/SKIOSNetworkAdapter.h | 19 + .../SKIOSNetworkPlugin/SKIOSNetworkAdapter.mm | 31 + .../SonarKitNetworkPlugin/SKBufferingPlugin.h | 26 + .../SKBufferingPlugin.mm | 83 + .../SonarKitNetworkPlugin/SKDispatchQueue.h | 39 + .../SonarKitNetworkPlugin/SKNetworkReporter.h | 57 + .../SonarKitNetworkPlugin.h | 26 + .../SonarKitNetworkPlugin.mm | 101 + iOS/Podfile | 20 + iOS/Sample/AppDelegate.h | 11 + iOS/Sample/AppDelegate.mm | 53 + .../AppIcon.appiconset/Contents.json | 62 + .../AppIcon.appiconset/icon_20pt@2x.png | Bin 0 -> 2220 bytes .../AppIcon.appiconset/icon_20pt@3x.png | Bin 0 -> 3993 bytes .../AppIcon.appiconset/icon_29pt@2x.png | Bin 0 -> 3796 bytes .../AppIcon.appiconset/icon_29pt@3x.png | Bin 0 -> 6740 bytes .../AppIcon.appiconset/icon_40pt@2x.png | Bin 0 -> 5971 bytes .../AppIcon.appiconset/icon_40pt@3x.png | Bin 0 -> 11074 bytes .../AppIcon.appiconset/icon_60pt@2x.png | Bin 0 -> 11074 bytes .../AppIcon.appiconset/icon_60pt@3x.png | Bin 0 -> 19384 bytes .../AppIcon.appiconset/icon_83.5@2x.png | Bin 0 -> 17580 bytes iOS/Sample/Icons.xcassets/Contents.json | 6 + .../sonarpattern.imageset/Contents.json | 21 + .../sonarpattern.imageset/sonarpattern.png | Bin 0 -> 107589 bytes iOS/Sample/Info.plist | 43 + iOS/Sample/MainStoryBoard.storyboard | 165 + iOS/Sample/MainViewController.h | 12 + iOS/Sample/MainViewController.m | 38 + iOS/Sample/NetworkViewController.h | 13 + iOS/Sample/NetworkViewController.m | 84 + iOS/Sample/Podfile | 31 + iOS/Sample/Podfile.lock | 128 + iOS/Sample/RootViewController.h | 12 + iOS/Sample/RootViewController.mm | 99 + iOS/Sample/Sample.xcodeproj/project.pbxproj | 480 ++ iOS/Sample/main.m | 16 + iOS/SonarKit.podspec | 99 + iOS/SonarKit.xcodeproj/project.pbxproj | 668 ++ .../CppBridge/SonarCppBridgingConnection.h | 18 + .../CppBridge/SonarCppBridgingConnection.mm | 45 + .../CppBridge/SonarCppBridgingResponder.h | 18 + .../CppBridge/SonarCppBridgingResponder.mm | 35 + .../CppBridge/SonarCppWrapperPlugin.h | 48 + iOS/SonarKit/FBDefines/FBMacros.h | 16 + iOS/SonarKit/SKMacros.h | 27 + iOS/SonarKit/SonarClient.h | 52 + iOS/SonarKit/SonarClient.mm | 117 + iOS/SonarKit/SonarConnection.h | 31 + iOS/SonarKit/SonarPlugin.h | 39 + iOS/SonarKit/SonarResponder.h | 25 + iOS/SonarKit/SonarUtil.m | 18 + .../PortForwarding/SKPortForwardingCommon.h | 21 + .../PortForwarding/SKPortForwardingServer.h | 18 + .../PortForwarding/SKPortForwardingServer.m | 190 + iOS/SonarKitTestUtils/BlockBasedSonarPlugin.h | 21 + iOS/SonarKitTestUtils/BlockBasedSonarPlugin.m | 46 + iOS/SonarKitTestUtils/SonarClient+Testing.h | 21 + iOS/SonarKitTestUtils/SonarConnectionMock.h | 18 + iOS/SonarKitTestUtils/SonarConnectionMock.m | 47 + iOS/SonarKitTestUtils/SonarResponderMock.h | 17 + iOS/SonarKitTestUtils/SonarResponderMock.m | 31 + iOS/SonarKitTests/SonarCppBridgingTests.mm | 41 + iOS/scripts/ios-configure-glog.sh | 41 + iOS/third-party-podspecs/ComponentKit.podspec | 21 + .../DoubleConversion.podspec | 18 + iOS/third-party-podspecs/EasyWSClient.podspec | 17 + iOS/third-party-podspecs/Folly.podspec | 95 + iOS/third-party-podspecs/glog.podspec | 41 + libs/easywsclient/AndroidManifest.xml | 4 + libs/easywsclient/CMakeLists.txt | 13 + libs/easywsclient/build.gradle | 34 + libs/easywsclient/easywsclient.cpp | 529 ++ libs/easywsclient/easywsclient.hpp | 72 + libs/fbjni/build.gradle | 33 + libs/fbjni/src/main/AndroidManifest.xml | 14 + libs/fbjni/src/main/cpp/CMakeLists.txt | 33 + libs/fbjni/src/main/cpp/assert.cpp | 39 + .../src/main/cpp/include/jni/Countable.h | 34 + .../main/cpp/include/jni/GlobalReference.h | 89 + .../src/main/cpp/include/jni/LocalReference.h | 35 + .../src/main/cpp/include/jni/LocalString.h | 92 + .../src/main/cpp/include/jni/Registration.h | 25 + .../src/main/cpp/include/jni/WeakReference.h | 53 + .../src/main/cpp/include/jni/jni_helpers.h | 137 + libs/fbjni/src/main/cpp/jni/ByteBuffer.cpp | 75 + libs/fbjni/src/main/cpp/jni/Countable.cpp | 67 + libs/fbjni/src/main/cpp/jni/Environment.cpp | 130 + libs/fbjni/src/main/cpp/jni/Exceptions.cpp | 283 + libs/fbjni/src/main/cpp/jni/Hybrid.cpp | 63 + libs/fbjni/src/main/cpp/jni/JThrowable.cpp | 23 + libs/fbjni/src/main/cpp/jni/LocalString.cpp | 310 + libs/fbjni/src/main/cpp/jni/OnLoad.cpp | 20 + libs/fbjni/src/main/cpp/jni/References.cpp | 39 + libs/fbjni/src/main/cpp/jni/WeakReference.cpp | 41 + libs/fbjni/src/main/cpp/jni/fbjni.cpp | 194 + libs/fbjni/src/main/cpp/jni/jni_helpers.cpp | 195 + libs/fbjni/src/main/cpp/log.cpp | 98 + libs/fbjni/src/main/cpp/lyra/lyra.cpp | 125 + libs/fbjni/src/main/cpp/onload.cpp | 29 + .../main/java/com/facebook/jni/Countable.java | 34 + .../java/com/facebook/jni/CppException.java | 18 + .../facebook/jni/CppSystemErrorException.java | 25 + .../java/com/facebook/jni/HybridData.java | 46 + .../java/com/facebook/jni/IteratorHelper.java | 50 + .../com/facebook/jni/MapIteratorHelper.java | 49 + .../java/com/facebook/jni/NativeRunnable.java | 23 + .../com/facebook/jni/ThreadScopeSupport.java | 22 + .../com/facebook/jni/UnknownCppException.java | 23 + .../src/main/java/com/facebook/jni/fbjni.pro | 11 + libs/folly | 1 + libs/jni-hack/README.md | 1 + libs/jni-hack/jni.h | 14 + libs/jni-hack/real/jni.h | 1132 ++++ local.properties | 12 + package.json | 86 + scripts/build-release.js | 205 + scripts/eslint.sh | 30 + scripts/flow.sh | 31 + scripts/install-dependencies.sh | 29 + scripts/metro-transform.js | 63 + scripts/public-build.json | 20 + scripts/public-build.sh | 46 + scripts/setup-env.sh | 15 + scripts/start-dev-server.js | 176 + scripts/yarn-install.js | 48 + settings.gradle | 29 + src/App.js | 363 ++ src/MenuBar.js | 361 ++ src/PluginContainer.js | 128 + src/chrome/AutoUpdateVersion.js | 103 + src/chrome/BugReporterDialog.js | 239 + src/chrome/DevicesButton.js | 291 + src/chrome/DevicesList.js | 142 + src/chrome/ErrorBar.js | 28 + src/chrome/MainSidebar.js | 305 + src/chrome/PluginManager.js | 404 ++ src/chrome/Popover.js | 196 + src/chrome/SonarTitleBar.js | 157 + src/chrome/Version.js | 92 + src/chrome/WelcomeScreen.js | 177 + src/createTablePlugin.js | 206 + src/device-plugins/cpu/index.js | 323 + src/device-plugins/index.js | 22 + src/device-plugins/logs/LogTable.js | 562 ++ src/device-plugins/logs/LogWatcher.js | 216 + src/device-plugins/logs/index.js | 8 + src/device-plugins/screen/index.js | 282 + src/devices/AndroidDevice.js | 95 + src/devices/BaseDevice.js | 78 + src/devices/IOSDevice.js | 162 + src/devices/OculusDevice.js | 142 + src/dispatcher/androidDevice.js | 97 + src/dispatcher/application.js | 25 + src/dispatcher/iOSDevice.js | 99 + src/dispatcher/index.js | 14 + src/fb-stubs/BugReporter.js | 15 + src/fb-stubs/ErrorReporter.js | 21 + src/fb-stubs/GK.js | 16 + src/fb-stubs/Logger.js | 40 + src/fb-stubs/ScribeLogger.js | 18 + src/fb-stubs/config.js | 11 + src/fb-stubs/constants.js | 19 + src/index.js | 21 + src/init.js | 48 + src/plugin.js | 241 + src/plugins/index.js | 72 + src/plugins/layout/index.js | 576 ++ src/plugins/layout/package.json | 9 + src/plugins/layout/yarn.lock | 7 + src/plugins/network/RequestDetails.js | 539 ++ src/plugins/network/index.js | 411 ++ src/plugins/network/package.json | 10 + src/plugins/network/yarn.lock | 11 + src/reducers.js | 184 + src/reducers/application.js | 88 + src/reducers/devices.js | 39 + src/reducers/index.js | 29 + src/server.js | 520 ++ src/ui/components/Block.js | 12 + src/ui/components/Box.js | 15 + src/ui/components/Button.js | 363 ++ src/ui/components/ButtonGroup.js | 45 + src/ui/components/ButtonNavigationGroup.js | 28 + src/ui/components/Checkbox.js | 36 + src/ui/components/ClickableList.js | 12 + src/ui/components/ClickableListItem.js | 33 + src/ui/components/CodeBlock.js | 12 + src/ui/components/ContextMenu.js | 56 + src/ui/components/ContextMenuProvider.js | 50 + src/ui/components/Dropdown.js | 35 + src/ui/components/ErrorBlock.js | 38 + src/ui/components/ErrorBoundary.js | 80 + src/ui/components/File.js | 82 + src/ui/components/FileList.js | 173 + src/ui/components/FlexBox.js | 18 + src/ui/components/FlexCenter.js | 14 + src/ui/components/FlexColumn.js | 12 + src/ui/components/FlexRow.js | 12 + src/ui/components/FocusableBox.js | 72 + src/ui/components/Glyph.js | 107 + src/ui/components/Heading.js | 57 + src/ui/components/HorizontalRule.js | 14 + src/ui/components/InlineContextMenu.js | 14 + src/ui/components/Input.js | 41 + src/ui/components/Interactive.js | 696 +++ src/ui/components/Label.js | 13 + src/ui/components/Link.js | 39 + src/ui/components/LoadingIndicator.js | 42 + src/ui/components/ModalOverlay.js | 49 + src/ui/components/Orderable.js | 428 ++ src/ui/components/Panel.js | 179 + src/ui/components/PathBreadcrumbs.js | 53 + src/ui/components/Popover.js | 89 + src/ui/components/ResizeSensor.js | 52 + src/ui/components/Select.js | 29 + src/ui/components/Sidebar.js | 178 + src/ui/components/SidebarLabel.js | 15 + src/ui/components/Tab.js | 37 + src/ui/components/Tabs.js | 271 + src/ui/components/Text.js | 159 + src/ui/components/TextParagraph.js | 21 + src/ui/components/Textarea.js | 22 + src/ui/components/ToggleSwitch.js | 61 + src/ui/components/Toolbar.js | 49 + src/ui/components/Tooltip.js | 75 + src/ui/components/TooltipProvider.js | 92 + src/ui/components/View.js | 22 + src/ui/components/ViewWithSize.js | 44 + src/ui/components/VirtualList.js | 146 + src/ui/components/colors.js | 273 + src/ui/components/console.js | 213 + .../data-inspector/DataDescription.js | 521 ++ .../data-inspector/DataInspector.js | 616 ++ .../components/data-inspector/DataPreview.js | 109 + .../data-inspector/ManagedDataInspector.js | 105 + src/ui/components/data-inspector/utils.js | 12 + src/ui/components/desktop-toolbar.js | 132 + .../elements-inspector/ElementsInspector.js | 83 + .../components/elements-inspector/elements.js | 595 ++ .../components/elements-inspector/sidebar.js | 134 + src/ui/components/filter/FilterRow.js | 88 + src/ui/components/filter/types.js | 24 + src/ui/components/intro/intro.js | 107 + src/ui/components/searchable/FilterToken.js | 251 + src/ui/components/searchable/Searchable.js | 392 ++ .../components/searchable/SearchableTable.js | 107 + src/ui/components/table/ManagedTable.js | 231 + src/ui/components/table/Table.js | 606 ++ src/ui/components/table/TableBody.js | 559 ++ src/ui/components/table/TableHead.js | 305 + src/ui/components/table/types.js | 86 + src/ui/components/table/utils.js | 31 + src/ui/index.js | 162 + src/ui/styled/__tests__/gc.node.js | 145 + src/ui/styled/__tests__/hash.node.js | 14 + src/ui/styled/__tests__/index.node.js | 387 ++ src/ui/styled/__tests__/rules.node.js | 76 + src/ui/styled/__tests__/sheet.node.js | 74 + src/ui/styled/gc.js | 114 + src/ui/styled/hash.js | 74 + src/ui/styled/index.js | 440 ++ src/ui/styled/rules.js | 180 + src/ui/styled/sheet.js | 92 + src/ui/styled/types.js | 1280 ++++ src/ui/virtualized/DynamicList.js | 392 ++ src/ui/virtualized/FixedList.js | 47 + src/ui/virtualized/index.js | 9 + src/ui/virtualized/types.js | 19 + src/utils/CertificateProvider.js | 387 ++ src/utils/InteractionTracker.js | 40 + src/utils/LRUCache.js | 172 + src/utils/LowPassFilter.js | 51 + src/utils/assignDeep.js | 38 + src/utils/createPaste.js | 70 + src/utils/dynamicPluginLoading.js | 47 + src/utils/geometry.js | 43 + src/utils/icons.js | 117 + src/utils/index.js | 9 + src/utils/info.js | 49 + src/utils/openssl-wrapper-with-promises.js | 18 + src/utils/performance.js | 24 + src/utils/snap.js | 159 + src/utils/textContent.js | 46 + .../CocoaAsyncSocketMac | Bin 0 -> 399592 bytes .../Resources/Info.plist | 44 + .../Versions/A/CocoaAsyncSocketMac | Bin 0 -> 399592 bytes .../Versions/A/Resources/Info.plist | 44 + .../FBPortForwarding-Mac | Bin 0 -> 60056 bytes .../Resources/Info.plist | 46 + .../Versions/A/FBPortForwarding-Mac | Bin 0 -> 60056 bytes .../Versions/A/Resources/Info.plist | 46 + .../Resources/Info.plist | 46 + .../Versions/A/Resources/Info.plist | 46 + .../Versions/A/peertalkMac | Bin 0 -> 109264 bytes .../peertalkMac.framework/peertalkMac | Bin 0 -> 109264 bytes .../Contents/Info.plist | 50 + .../Contents/MacOS/PortForwardingMacApp | Bin 0 -> 29612 bytes .../PortForwardingMacApp.app/Contents/PkgInfo | 1 + static/anchor.svg | 16 + static/compilePlugins.js | 184 + static/graphiql/graphiql.css | 1739 ++++++ static/icon.icns | Bin 0 -> 1730122 bytes static/icon.ico | Bin 0 -> 161097 bytes static/icon.png | Bin 0 -> 61071 bytes static/icons/android.svg | 9 + static/icons/componentkit-logo.png | Bin 0 -> 4436 bytes static/icons/componentscript-logo.png | Bin 0 -> 7062 bytes static/icons/ios.svg | 9 + static/icons/litho-logo.png | Bin 0 -> 812 bytes static/icons/oculus.png | Bin 0 -> 1818 bytes static/icons/sidebar_bottom.svg | 7 + static/icons/sidebar_left.svg | 7 + static/icons/sidebar_right.svg | 7 + static/index.dev.html | 110 + static/index.html | 18 + static/index.js | 156 + static/package.json | 17 + static/pattern.gif | Bin 0 -> 4822 bytes static/serviceWorker.js | 35 + static/style.css | 158 + static/transforms/dynamic-requires.js | 31 + static/transforms/electron-requires.js | 87 + static/transforms/fb-stubs.js | 45 + static/transforms/import-react.js | 51 + static/transforms/index.js | 64 + static/transforms/sonar-requires.js | 64 + static/uiperf/screenshot.png | Bin 0 -> 33585 bytes static/vis/vis.min.css | 1 + static/yarn.lock | 3115 ++++++++++ website/.gitignore | 11 + website/blog/2016-03-11-blog-post.md | 18 + website/blog/2017-04-10-blog-post-two.md | 18 + website/blog/2017-09-25-testing-rss.md | 11 + website/blog/2017-09-26-adding-rss.md | 10 + website/blog/2017-10-24-new-version-1.0.0.md | 8 + website/core/Footer.js | 82 + website/i18n/en.json | 46 + website/package.json | 14 + website/pages/docs/en/index.js | 22 + website/pages/en/index.js | 110 + website/sidebars.json | 19 + website/siteConfig.js | 40 + website/static/css/custom.css | 324 + website/static/img/SonarKit.png | Bin 0 -> 16245 bytes website/static/img/SonarKit@2x.png | Bin 0 -> 31104 bytes website/static/img/docusaurus.svg | 1 + website/static/img/favicon.png | Bin 0 -> 984 bytes website/static/img/favicon/favicon.ico | Bin 0 -> 9662 bytes website/static/img/icon.png | Bin 0 -> 57812 bytes website/static/img/inspector.png | Bin 0 -> 69926 bytes website/static/img/inspector@2x.png | Bin 0 -> 214228 bytes website/static/img/mascot.png | Bin 0 -> 45563 bytes website/static/img/oss_logo.png | Bin 0 -> 4370 bytes website/static/img/plugins.png | Bin 0 -> 107839 bytes website/static/img/plugins@2x.png | Bin 0 -> 304895 bytes website/static/img/splash.png | Bin 0 -> 132257 bytes website/static/img/splash@2x.png | Bin 0 -> 308796 bytes website/yarn.lock | 1765 ++++++ xplat/AndroidManifest.xml | 4 + xplat/CMakeLists.txt | 60 + xplat/Sonar/CertificateUtils.cpp | 223 + xplat/Sonar/CertificateUtils.h | 20 + xplat/Sonar/SonarClient.cpp | 204 + xplat/Sonar/SonarClient.h | 87 + xplat/Sonar/SonarConnection.h | 54 + xplat/Sonar/SonarConnectionImpl.h | 61 + xplat/Sonar/SonarInitConfig.h | 40 + xplat/Sonar/SonarKitCPP.podspec | 33 + xplat/Sonar/SonarPlugin.h | 42 + xplat/Sonar/SonarResponder.h | 36 + xplat/Sonar/SonarResponderImpl.h | 41 + xplat/Sonar/SonarWebSocket.h | 63 + xplat/Sonar/SonarWebSocketImpl.cpp | 301 + xplat/Sonar/SonarWebSocketImpl.h | 67 + xplat/SonarTestLib/SonarConnectionMock.h | 34 + xplat/SonarTestLib/SonarPluginMock.h | 62 + xplat/SonarTestLib/SonarResponderMock.h | 43 + xplat/SonarTestLib/SonarWebSocketMock.h | 55 + xplat/SonarTests/SonarClientTests.cpp | 292 + xplat/build.gradle | 37 + yarn.lock | 5364 +++++++++++++++++ 659 files changed, 87130 insertions(+) create mode 100644 .eslintignore create mode 100644 .eslintrc.js create mode 100644 .flowconfig create mode 100644 .gitignore create mode 100644 .gitmodules create mode 100644 .sonarhandles create mode 100644 .travis.yml create mode 100644 .vscode/launch.json create mode 100644 .yarnrc create mode 100644 CODE_OF_CONDUCT.md create mode 100644 CONTRIBUTING.md create mode 100644 LICENSE create mode 100644 README.md create mode 100644 android/AndroidManifest.xml create mode 100644 android/CMakeLists.txt create mode 100644 android/android/AndroidSonarClient.java create mode 100644 android/android/EventBase.java create mode 100644 android/android/SonarClientImpl.java create mode 100644 android/android/SonarConnectionImpl.java create mode 100644 android/android/SonarResponderImpl.java create mode 100644 android/android/SonarThread.java create mode 100644 android/android/sonar.cpp create mode 100644 android/android/utils/SonarUtils.java create mode 100644 android/build.gradle create mode 100644 android/core/ErrorReportingRunnable.java create mode 100644 android/core/SonarArray.java create mode 100644 android/core/SonarClient.java create mode 100644 android/core/SonarConnection.java create mode 100644 android/core/SonarDynamic.java create mode 100644 android/core/SonarObject.java create mode 100644 android/core/SonarPlugin.java create mode 100644 android/core/SonarReceiver.java create mode 100644 android/core/SonarResponder.java create mode 100644 android/core/SonarValue.java create mode 100644 android/plugins/common/BufferingSonarPlugin.java create mode 100644 android/plugins/common/MainThreadSonarReceiver.java create mode 100644 android/plugins/common/RingBuffer.java create mode 100644 android/plugins/console/ConsoleSonarPlugin.java create mode 100644 android/plugins/console/JavascriptEnvironment.java create mode 100644 android/plugins/console/JavascriptSession.java create mode 100644 android/plugins/console/iface/ConsoleCommandReceiver.java create mode 100644 android/plugins/console/iface/NullScriptingEnvironment.java create mode 100644 android/plugins/console/iface/ScriptingEnvironment.java create mode 100644 android/plugins/console/iface/ScriptingSession.java create mode 100644 android/plugins/inspector/ApplicationWrapper.java create mode 100644 android/plugins/inspector/BoundsDrawable.java create mode 100644 android/plugins/inspector/DescriptorMapping.java create mode 100644 android/plugins/inspector/HiddenNode.java create mode 100644 android/plugins/inspector/HighlightedOverlay.java create mode 100644 android/plugins/inspector/InspectorSonarPlugin.java create mode 100644 android/plugins/inspector/InspectorValue.java create mode 100644 android/plugins/inspector/Named.java create mode 100644 android/plugins/inspector/NodeDescriptor.java create mode 100644 android/plugins/inspector/ObjectTracker.java create mode 100644 android/plugins/inspector/SearchResultNode.java create mode 100644 android/plugins/inspector/SelfRegisteringNodeDescriptor.java create mode 100644 android/plugins/inspector/Touch.java create mode 100644 android/plugins/inspector/descriptors/ActivityDescriptor.java create mode 100644 android/plugins/inspector/descriptors/ApplicationDescriptor.java create mode 100644 android/plugins/inspector/descriptors/DialogDescriptor.java create mode 100644 android/plugins/inspector/descriptors/DialogFragmentDescriptor.java create mode 100644 android/plugins/inspector/descriptors/DrawableDescriptor.java create mode 100644 android/plugins/inspector/descriptors/FragmentDescriptor.java create mode 100644 android/plugins/inspector/descriptors/ObjectDescriptor.java create mode 100644 android/plugins/inspector/descriptors/SupportDialogFragmentDescriptor.java create mode 100644 android/plugins/inspector/descriptors/SupportFragmentDescriptor.java create mode 100644 android/plugins/inspector/descriptors/TextViewDescriptor.java create mode 100644 android/plugins/inspector/descriptors/ViewDescriptor.java create mode 100644 android/plugins/inspector/descriptors/ViewGroupDescriptor.java create mode 100644 android/plugins/inspector/descriptors/WindowDescriptor.java create mode 100644 android/plugins/inspector/descriptors/utils/AccessibilityEvaluationUtil.java create mode 100644 android/plugins/inspector/descriptors/utils/AccessibilityRoleUtil.java create mode 100644 android/plugins/inspector/descriptors/utils/AccessibilityUtil.java create mode 100644 android/plugins/inspector/descriptors/utils/AndroidRootResolver.java create mode 100644 android/plugins/inspector/descriptors/utils/EnumMapping.java create mode 100644 android/plugins/inspector/descriptors/utils/ViewAccessibilityHelper.java create mode 100644 android/plugins/inspector/litho-sonar/DebugComponentDescriptor.java create mode 100644 android/plugins/inspector/litho-sonar/LithoSonarDescriptors.java create mode 100644 android/plugins/inspector/litho-sonar/LithoViewDescriptor.java create mode 100644 android/plugins/inspector/litho-sonar/PropWithDescription.java create mode 100644 android/plugins/network/NetworkReporter.java create mode 100644 android/plugins/network/NetworkResponseFormatter.java create mode 100644 android/plugins/network/NetworkSonarPlugin.java create mode 100644 android/plugins/network/SonarOkhttpInterceptor.java create mode 100644 android/plugins/sharedpreferences/SharedPreferencesSonarPlugin.java create mode 100644 android/sample/AndroidManifest.xml create mode 100644 android/sample/build.gradle create mode 100644 android/sample/debug.keystore create mode 100644 android/sample/debug.keystore.properties create mode 100644 android/sample/res/drawable-hdpi/ic_launcher.png create mode 100644 android/sample/res/drawable-mdpi/ic_launcher.png create mode 100644 android/sample/res/drawable-xhdpi/ic_launcher.png create mode 100644 android/sample/res/drawable-xxhdpi/ic_launcher.png create mode 100644 android/sample/res/drawable-xxxhdpi/ic_launcher.png create mode 100644 android/sample/res/values/strings.xml create mode 100644 android/sample/res/values/styles.xml create mode 100644 android/sample/src/sonar/com/facebook/sonar/sample/MainActivity.java create mode 100644 android/sample/src/sonar/com/facebook/sonar/sample/RootComponentSpec.java create mode 100644 android/sample/src/sonar/com/facebook/sonar/sample/SonarSampleApplication.java create mode 100644 android/testing/SonarConnectionMock.java create mode 100644 android/testing/SonarResponderMock.java create mode 100644 android/tests/plugins/console/ConsoleSonarPluginTest.java create mode 100644 android/tests/plugins/console/JavascriptSessionTest.java create mode 100644 android/tests/plugins/inspector/ApplicationWrapperTest.java create mode 100644 android/tests/plugins/inspector/DescriptorMappingTest.java create mode 100644 android/tests/plugins/inspector/InspectorSonarPluginTest.java create mode 100644 android/tests/plugins/inspector/descriptors/ViewGroupDescriptorTest.java create mode 100644 android/third-party/DoubleConversion/ApplicationManifest.xml create mode 100644 android/third-party/DoubleConversion/CMakeLists.txt create mode 100644 android/third-party/DoubleConversion/build.gradle create mode 100644 android/third-party/Folly/ApplicationManifest.xml create mode 100644 android/third-party/Folly/CMakeLists.txt create mode 100644 android/third-party/Folly/build.gradle create mode 100644 android/third-party/glog/ApplicationManifest.xml create mode 100644 android/third-party/glog/CMakeLists.txt create mode 100644 android/third-party/glog/build.gradle create mode 100644 android/third-party/glog/config.h create mode 100644 android/third-party/glog/logging.cc create mode 100644 build.gradle create mode 100644 docs/assets/initial.png create mode 100644 docs/assets/layout.png create mode 100644 docs/assets/logs.png create mode 100644 docs/assets/network.png create mode 100644 docs/communitcating.md create mode 100644 docs/create-plugin.md create mode 100644 docs/create-table-plugin.md create mode 100644 docs/error-handling.md create mode 100644 docs/getting-started.md create mode 100644 docs/jssetup.md create mode 100644 docs/layout-plugin.md create mode 100644 docs/logs-plugin.md create mode 100644 docs/network-plugin.md create mode 100644 docs/send-data.md create mode 100644 docs/stetho.md create mode 100644 docs/styling-components.md create mode 100644 docs/testing.md create mode 100644 docs/ui-components.md create mode 100644 docs/unterstanding-sonar.md create mode 100644 flow-typed/electron-menu.js create mode 100644 flow-typed/npm/JSONStream_vx.x.x.js create mode 100644 flow-typed/npm/adbkit-fb_vx.x.x.js create mode 100644 flow-typed/npm/adbkit-logcat-fb_vx.x.x.js create mode 100644 flow-typed/npm/babel-cli_vx.x.x.js create mode 100644 flow-typed/npm/babel-code-frame_vx.x.x.js create mode 100644 flow-typed/npm/babel-core_vx.x.x.js create mode 100644 flow-typed/npm/babel-eslint_vx.x.x.js create mode 100644 flow-typed/npm/babel-generator_vx.x.x.js create mode 100644 flow-typed/npm/babel-plugin-transform-class-properties_vx.x.x.js create mode 100644 flow-typed/npm/babel-plugin-transform-es2015-destructuring_vx.x.x.js create mode 100644 flow-typed/npm/babel-plugin-transform-es2015-modules-commonjs_vx.x.x.js create mode 100644 flow-typed/npm/babel-plugin-transform-flow-strip-types_vx.x.x.js create mode 100644 flow-typed/npm/babel-plugin-transform-object-rest-spread_vx.x.x.js create mode 100644 flow-typed/npm/babel-preset-react_vx.x.x.js create mode 100644 flow-typed/npm/babel-register_vx.x.x.js create mode 100644 flow-typed/npm/babel-traverse_vx.x.x.js create mode 100644 flow-typed/npm/babylon_vx.x.x.js create mode 100644 flow-typed/npm/chalk_v1.x.x.js create mode 100644 flow-typed/npm/codemirror_vx.x.x.js create mode 100644 flow-typed/npm/dashify_vx.x.x.js create mode 100644 flow-typed/npm/deep-equal_vx.x.x.js create mode 100644 flow-typed/npm/detect-port_vx.x.x.js create mode 100644 flow-typed/npm/electron-builder_vx.x.x.js create mode 100644 flow-typed/npm/electron-devtools-installer_vx.x.x.js create mode 100644 flow-typed/npm/electron_vx.x.x.js create mode 100644 flow-typed/npm/eslint-config-react-app_vx.x.x.js create mode 100644 flow-typed/npm/eslint-plugin-flowtype_vx.x.x.js create mode 100644 flow-typed/npm/eslint-plugin-import_vx.x.x.js create mode 100644 flow-typed/npm/eslint-plugin-jest_vx.x.x.js create mode 100644 flow-typed/npm/eslint-plugin-jsx-a11y_vx.x.x.js create mode 100644 flow-typed/npm/eslint-plugin-prettier_vx.x.x.js create mode 100644 flow-typed/npm/eslint-plugin-prettify_vx.x.x.js create mode 100644 flow-typed/npm/eslint-plugin-react_vx.x.x.js create mode 100644 flow-typed/npm/eslint_vx.x.x.js create mode 100644 flow-typed/npm/express_v4.x.x.js create mode 100644 flow-typed/npm/flow-bin_v0.x.x.js create mode 100644 flow-typed/npm/fs-extra_vx.x.x.js create mode 100644 flow-typed/npm/graphiql_vx.x.x.js create mode 100644 flow-typed/npm/graphql_vx.x.x.js create mode 100644 flow-typed/npm/invariant_v2.x.x.js create mode 100644 flow-typed/npm/jest_v21.x.x.js create mode 100644 flow-typed/npm/lodash_v4.x.x.js create mode 100644 flow-typed/npm/openssl-wrapper_vx.x.x.js create mode 100644 flow-typed/npm/polished_vx.x.x.js create mode 100644 flow-typed/npm/prettier_vx.x.x.js create mode 100644 flow-typed/npm/prop-types_v15.x.x.js create mode 100644 flow-typed/npm/react-color_vx.x.x.js create mode 100644 flow-typed/npm/react-devtools-core_vx.x.x.js create mode 100644 flow-typed/npm/react-redux_v5.x.x.js create mode 100644 flow-typed/npm/react-test-renderer_vx.x.x.js create mode 100644 flow-typed/npm/react-virtualized_vx.x.x.js create mode 100644 flow-typed/npm/redux_v3.x.x.js create mode 100644 flow-typed/npm/rsocket.js create mode 100644 flow-typed/npm/string-natural-compare_vx.x.x.js create mode 100644 flow-typed/npm/vis_vx.x.x.js create mode 100644 flow-typed/npm/websocket_vx.x.x.js create mode 100644 flow-typed/npm/ws_vx.x.x.js create mode 100644 flow-typed/npm/yargs_vx.x.x.js create mode 100644 flow-typed/react.js create mode 100644 gradle.properties create mode 100644 gradle/wrapper/gradle-wrapper.jar create mode 100644 gradle/wrapper/gradle-wrapper.properties create mode 100755 gradlew create mode 100644 iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutComponentKitSupport/CKComponent+Sonar.h create mode 100644 iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutComponentKitSupport/CKComponent+Sonar.mm create mode 100644 iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutComponentKitSupport/CKFlexboxComponent+Sonar.h create mode 100644 iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutComponentKitSupport/CKFlexboxComponent+Sonar.mm create mode 100644 iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutComponentKitSupport/CKInsetComponent+Sonar.h create mode 100644 iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutComponentKitSupport/CKInsetComponent+Sonar.mm create mode 100644 iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutComponentKitSupport/SKComponentHostingViewDescriptor.h create mode 100644 iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutComponentKitSupport/SKComponentHostingViewDescriptor.mm create mode 100644 iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutComponentKitSupport/SKComponentLayoutDescriptor.h create mode 100644 iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutComponentKitSupport/SKComponentLayoutDescriptor.mm create mode 100644 iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutComponentKitSupport/SKComponentLayoutWrapper.h create mode 100644 iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutComponentKitSupport/SKComponentLayoutWrapper.mm create mode 100644 iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutComponentKitSupport/SKComponentRootViewDescriptor.h create mode 100644 iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutComponentKitSupport/SKComponentRootViewDescriptor.mm create mode 100644 iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutComponentKitSupport/SonarKitLayoutComponentKitSupport.h create mode 100644 iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutComponentKitSupport/SonarKitLayoutComponentKitSupport.mm create mode 100644 iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutComponentKitSupport/Utils.h create mode 100644 iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutComponentKitSupport/Utils.mm create mode 100644 iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/SKDescriptorMapper.h create mode 100644 iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/SKDescriptorMapper.mm create mode 100644 iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/SKHighlightOverlay.h create mode 100644 iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/SKHighlightOverlay.m create mode 100644 iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/SKInvalidation.h create mode 100644 iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/SKInvalidation.m create mode 100644 iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/SKNamed.h create mode 100644 iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/SKNamed.mm create mode 100644 iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/SKNodeDescriptor.h create mode 100644 iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/SKNodeDescriptor.mm create mode 100644 iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/SKObject.h create mode 100644 iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/SKObject.mm create mode 100644 iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/SKSearchResultNode.h create mode 100644 iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/SKSearchResultNode.m create mode 100644 iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/SKTapListener.h create mode 100644 iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/SKTapListenerImpl.h create mode 100644 iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/SKTapListenerImpl.m create mode 100644 iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/SKTouch.h create mode 100644 iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/SKTouch.m create mode 100644 iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/SonarKitLayoutPlugin.h create mode 100644 iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/SonarKitLayoutPlugin.mm create mode 100644 iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/UICollectionView+SKInvalidation.h create mode 100644 iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/UICollectionView+SKInvalidation.mm create mode 100644 iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/UIColor+SKSonarValueCoder.h create mode 100644 iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/UIColor+SKSonarValueCoder.mm create mode 100644 iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/UIView+SKInvalidation.h create mode 100644 iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/UIView+SKInvalidation.mm create mode 100644 iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/descriptors/SKApplicationDescriptor.h create mode 100644 iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/descriptors/SKApplicationDescriptor.m create mode 100644 iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/descriptors/SKButtonDescriptor.h create mode 100644 iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/descriptors/SKButtonDescriptor.mm create mode 100644 iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/descriptors/SKScrollViewDescriptor.h create mode 100644 iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/descriptors/SKScrollViewDescriptor.m create mode 100644 iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/descriptors/SKViewControllerDescriptor.h create mode 100644 iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/descriptors/SKViewControllerDescriptor.m create mode 100644 iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/descriptors/SKViewDescriptor.h create mode 100644 iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/descriptors/SKViewDescriptor.mm create mode 100644 iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/utils/SKHiddenWindow.h create mode 100644 iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/utils/SKHiddenWindow.m create mode 100644 iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/utils/SKObjectHash.h create mode 100644 iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/utils/SKSwizzle.h create mode 100644 iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/utils/SKSwizzle.mm create mode 100644 iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/utils/SKYogaKitHelper.h create mode 100644 iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPluginTests/SKTapListenerMock.h create mode 100644 iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPluginTests/SKTapListenerMock.m create mode 100644 iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPluginTests/SonarKitLayoutPluginTests.m create mode 100644 iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPluginTests/TestNode.h create mode 100644 iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPluginTests/TestNode.m create mode 100644 iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPluginTests/TestNodeDescriptor.h create mode 100644 iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPluginTests/TestNodeDescriptor.m create mode 100755 iOS/Plugins/SonarKitNetworkPlugin/SKIOSNetworkPlugin/FLEXNetworkLib/FLEXNetworkObserver.h create mode 100755 iOS/Plugins/SonarKitNetworkPlugin/SKIOSNetworkPlugin/FLEXNetworkLib/FLEXNetworkObserver.mm create mode 100755 iOS/Plugins/SonarKitNetworkPlugin/SKIOSNetworkPlugin/FLEXNetworkLib/FLEXNetworkRecorder.h create mode 100755 iOS/Plugins/SonarKitNetworkPlugin/SKIOSNetworkPlugin/FLEXNetworkLib/FLEXNetworkRecorder.mm create mode 100755 iOS/Plugins/SonarKitNetworkPlugin/SKIOSNetworkPlugin/FLEXNetworkLib/FLEXNetworkTransaction.h create mode 100755 iOS/Plugins/SonarKitNetworkPlugin/SKIOSNetworkPlugin/FLEXNetworkLib/FLEXNetworkTransaction.m create mode 100755 iOS/Plugins/SonarKitNetworkPlugin/SKIOSNetworkPlugin/FLEXNetworkLib/FLEXUtility.h create mode 100755 iOS/Plugins/SonarKitNetworkPlugin/SKIOSNetworkPlugin/FLEXNetworkLib/FLEXUtility.mm create mode 100644 iOS/Plugins/SonarKitNetworkPlugin/SKIOSNetworkPlugin/SKIOSNetworkAdapter.h create mode 100644 iOS/Plugins/SonarKitNetworkPlugin/SKIOSNetworkPlugin/SKIOSNetworkAdapter.mm create mode 100644 iOS/Plugins/SonarKitNetworkPlugin/SonarKitNetworkPlugin/SKBufferingPlugin.h create mode 100644 iOS/Plugins/SonarKitNetworkPlugin/SonarKitNetworkPlugin/SKBufferingPlugin.mm create mode 100644 iOS/Plugins/SonarKitNetworkPlugin/SonarKitNetworkPlugin/SKDispatchQueue.h create mode 100644 iOS/Plugins/SonarKitNetworkPlugin/SonarKitNetworkPlugin/SKNetworkReporter.h create mode 100644 iOS/Plugins/SonarKitNetworkPlugin/SonarKitNetworkPlugin/SonarKitNetworkPlugin.h create mode 100644 iOS/Plugins/SonarKitNetworkPlugin/SonarKitNetworkPlugin/SonarKitNetworkPlugin.mm create mode 100644 iOS/Podfile create mode 100644 iOS/Sample/AppDelegate.h create mode 100644 iOS/Sample/AppDelegate.mm create mode 100644 iOS/Sample/Icons.xcassets/AppIcon.appiconset/Contents.json create mode 100644 iOS/Sample/Icons.xcassets/AppIcon.appiconset/icon_20pt@2x.png create mode 100644 iOS/Sample/Icons.xcassets/AppIcon.appiconset/icon_20pt@3x.png create mode 100644 iOS/Sample/Icons.xcassets/AppIcon.appiconset/icon_29pt@2x.png create mode 100644 iOS/Sample/Icons.xcassets/AppIcon.appiconset/icon_29pt@3x.png create mode 100644 iOS/Sample/Icons.xcassets/AppIcon.appiconset/icon_40pt@2x.png create mode 100644 iOS/Sample/Icons.xcassets/AppIcon.appiconset/icon_40pt@3x.png create mode 100644 iOS/Sample/Icons.xcassets/AppIcon.appiconset/icon_60pt@2x.png create mode 100644 iOS/Sample/Icons.xcassets/AppIcon.appiconset/icon_60pt@3x.png create mode 100644 iOS/Sample/Icons.xcassets/AppIcon.appiconset/icon_83.5@2x.png create mode 100644 iOS/Sample/Icons.xcassets/Contents.json create mode 100644 iOS/Sample/Icons.xcassets/sonarpattern.imageset/Contents.json create mode 100644 iOS/Sample/Icons.xcassets/sonarpattern.imageset/sonarpattern.png create mode 100644 iOS/Sample/Info.plist create mode 100644 iOS/Sample/MainStoryBoard.storyboard create mode 100644 iOS/Sample/MainViewController.h create mode 100644 iOS/Sample/MainViewController.m create mode 100644 iOS/Sample/NetworkViewController.h create mode 100644 iOS/Sample/NetworkViewController.m create mode 100644 iOS/Sample/Podfile create mode 100644 iOS/Sample/Podfile.lock create mode 100644 iOS/Sample/RootViewController.h create mode 100644 iOS/Sample/RootViewController.mm create mode 100644 iOS/Sample/Sample.xcodeproj/project.pbxproj create mode 100644 iOS/Sample/main.m create mode 100644 iOS/SonarKit.podspec create mode 100644 iOS/SonarKit.xcodeproj/project.pbxproj create mode 100644 iOS/SonarKit/CppBridge/SonarCppBridgingConnection.h create mode 100644 iOS/SonarKit/CppBridge/SonarCppBridgingConnection.mm create mode 100644 iOS/SonarKit/CppBridge/SonarCppBridgingResponder.h create mode 100644 iOS/SonarKit/CppBridge/SonarCppBridgingResponder.mm create mode 100644 iOS/SonarKit/CppBridge/SonarCppWrapperPlugin.h create mode 100644 iOS/SonarKit/FBDefines/FBMacros.h create mode 100644 iOS/SonarKit/SKMacros.h create mode 100644 iOS/SonarKit/SonarClient.h create mode 100644 iOS/SonarKit/SonarClient.mm create mode 100644 iOS/SonarKit/SonarConnection.h create mode 100644 iOS/SonarKit/SonarPlugin.h create mode 100644 iOS/SonarKit/SonarResponder.h create mode 100644 iOS/SonarKit/SonarUtil.m create mode 100644 iOS/SonarKit/Utilities/PortForwarding/SKPortForwardingCommon.h create mode 100644 iOS/SonarKit/Utilities/PortForwarding/SKPortForwardingServer.h create mode 100644 iOS/SonarKit/Utilities/PortForwarding/SKPortForwardingServer.m create mode 100644 iOS/SonarKitTestUtils/BlockBasedSonarPlugin.h create mode 100644 iOS/SonarKitTestUtils/BlockBasedSonarPlugin.m create mode 100644 iOS/SonarKitTestUtils/SonarClient+Testing.h create mode 100644 iOS/SonarKitTestUtils/SonarConnectionMock.h create mode 100644 iOS/SonarKitTestUtils/SonarConnectionMock.m create mode 100644 iOS/SonarKitTestUtils/SonarResponderMock.h create mode 100644 iOS/SonarKitTestUtils/SonarResponderMock.m create mode 100644 iOS/SonarKitTests/SonarCppBridgingTests.mm create mode 100644 iOS/scripts/ios-configure-glog.sh create mode 100644 iOS/third-party-podspecs/ComponentKit.podspec create mode 100755 iOS/third-party-podspecs/DoubleConversion.podspec create mode 100644 iOS/third-party-podspecs/EasyWSClient.podspec create mode 100755 iOS/third-party-podspecs/Folly.podspec create mode 100755 iOS/third-party-podspecs/glog.podspec create mode 100644 libs/easywsclient/AndroidManifest.xml create mode 100644 libs/easywsclient/CMakeLists.txt create mode 100644 libs/easywsclient/build.gradle create mode 100644 libs/easywsclient/easywsclient.cpp create mode 100644 libs/easywsclient/easywsclient.hpp create mode 100644 libs/fbjni/build.gradle create mode 100644 libs/fbjni/src/main/AndroidManifest.xml create mode 100644 libs/fbjni/src/main/cpp/CMakeLists.txt create mode 100644 libs/fbjni/src/main/cpp/assert.cpp create mode 100644 libs/fbjni/src/main/cpp/include/jni/Countable.h create mode 100644 libs/fbjni/src/main/cpp/include/jni/GlobalReference.h create mode 100644 libs/fbjni/src/main/cpp/include/jni/LocalReference.h create mode 100644 libs/fbjni/src/main/cpp/include/jni/LocalString.h create mode 100644 libs/fbjni/src/main/cpp/include/jni/Registration.h create mode 100644 libs/fbjni/src/main/cpp/include/jni/WeakReference.h create mode 100644 libs/fbjni/src/main/cpp/include/jni/jni_helpers.h create mode 100644 libs/fbjni/src/main/cpp/jni/ByteBuffer.cpp create mode 100644 libs/fbjni/src/main/cpp/jni/Countable.cpp create mode 100644 libs/fbjni/src/main/cpp/jni/Environment.cpp create mode 100644 libs/fbjni/src/main/cpp/jni/Exceptions.cpp create mode 100644 libs/fbjni/src/main/cpp/jni/Hybrid.cpp create mode 100644 libs/fbjni/src/main/cpp/jni/JThrowable.cpp create mode 100644 libs/fbjni/src/main/cpp/jni/LocalString.cpp create mode 100644 libs/fbjni/src/main/cpp/jni/OnLoad.cpp create mode 100644 libs/fbjni/src/main/cpp/jni/References.cpp create mode 100644 libs/fbjni/src/main/cpp/jni/WeakReference.cpp create mode 100644 libs/fbjni/src/main/cpp/jni/fbjni.cpp create mode 100644 libs/fbjni/src/main/cpp/jni/jni_helpers.cpp create mode 100644 libs/fbjni/src/main/cpp/log.cpp create mode 100644 libs/fbjni/src/main/cpp/lyra/lyra.cpp create mode 100644 libs/fbjni/src/main/cpp/onload.cpp create mode 100644 libs/fbjni/src/main/java/com/facebook/jni/Countable.java create mode 100644 libs/fbjni/src/main/java/com/facebook/jni/CppException.java create mode 100644 libs/fbjni/src/main/java/com/facebook/jni/CppSystemErrorException.java create mode 100644 libs/fbjni/src/main/java/com/facebook/jni/HybridData.java create mode 100644 libs/fbjni/src/main/java/com/facebook/jni/IteratorHelper.java create mode 100644 libs/fbjni/src/main/java/com/facebook/jni/MapIteratorHelper.java create mode 100644 libs/fbjni/src/main/java/com/facebook/jni/NativeRunnable.java create mode 100644 libs/fbjni/src/main/java/com/facebook/jni/ThreadScopeSupport.java create mode 100644 libs/fbjni/src/main/java/com/facebook/jni/UnknownCppException.java create mode 100644 libs/fbjni/src/main/java/com/facebook/jni/fbjni.pro create mode 160000 libs/folly create mode 100644 libs/jni-hack/README.md create mode 100644 libs/jni-hack/jni.h create mode 100644 libs/jni-hack/real/jni.h create mode 100644 local.properties create mode 100644 package.json create mode 100755 scripts/build-release.js create mode 100755 scripts/eslint.sh create mode 100755 scripts/flow.sh create mode 100755 scripts/install-dependencies.sh create mode 100644 scripts/metro-transform.js create mode 100644 scripts/public-build.json create mode 100755 scripts/public-build.sh create mode 100755 scripts/setup-env.sh create mode 100644 scripts/start-dev-server.js create mode 100644 scripts/yarn-install.js create mode 100644 settings.gradle create mode 100644 src/App.js create mode 100644 src/MenuBar.js create mode 100644 src/PluginContainer.js create mode 100644 src/chrome/AutoUpdateVersion.js create mode 100644 src/chrome/BugReporterDialog.js create mode 100644 src/chrome/DevicesButton.js create mode 100644 src/chrome/DevicesList.js create mode 100644 src/chrome/ErrorBar.js create mode 100644 src/chrome/MainSidebar.js create mode 100644 src/chrome/PluginManager.js create mode 100644 src/chrome/Popover.js create mode 100644 src/chrome/SonarTitleBar.js create mode 100644 src/chrome/Version.js create mode 100644 src/chrome/WelcomeScreen.js create mode 100644 src/createTablePlugin.js create mode 100644 src/device-plugins/cpu/index.js create mode 100644 src/device-plugins/index.js create mode 100644 src/device-plugins/logs/LogTable.js create mode 100644 src/device-plugins/logs/LogWatcher.js create mode 100644 src/device-plugins/logs/index.js create mode 100644 src/device-plugins/screen/index.js create mode 100644 src/devices/AndroidDevice.js create mode 100644 src/devices/BaseDevice.js create mode 100644 src/devices/IOSDevice.js create mode 100644 src/devices/OculusDevice.js create mode 100644 src/dispatcher/androidDevice.js create mode 100644 src/dispatcher/application.js create mode 100644 src/dispatcher/iOSDevice.js create mode 100644 src/dispatcher/index.js create mode 100644 src/fb-stubs/BugReporter.js create mode 100644 src/fb-stubs/ErrorReporter.js create mode 100644 src/fb-stubs/GK.js create mode 100644 src/fb-stubs/Logger.js create mode 100644 src/fb-stubs/ScribeLogger.js create mode 100644 src/fb-stubs/config.js create mode 100644 src/fb-stubs/constants.js create mode 100644 src/index.js create mode 100644 src/init.js create mode 100644 src/plugin.js create mode 100644 src/plugins/index.js create mode 100644 src/plugins/layout/index.js create mode 100644 src/plugins/layout/package.json create mode 100644 src/plugins/layout/yarn.lock create mode 100644 src/plugins/network/RequestDetails.js create mode 100644 src/plugins/network/index.js create mode 100644 src/plugins/network/package.json create mode 100644 src/plugins/network/yarn.lock create mode 100644 src/reducers.js create mode 100644 src/reducers/application.js create mode 100644 src/reducers/devices.js create mode 100644 src/reducers/index.js create mode 100644 src/server.js create mode 100644 src/ui/components/Block.js create mode 100644 src/ui/components/Box.js create mode 100644 src/ui/components/Button.js create mode 100644 src/ui/components/ButtonGroup.js create mode 100644 src/ui/components/ButtonNavigationGroup.js create mode 100644 src/ui/components/Checkbox.js create mode 100644 src/ui/components/ClickableList.js create mode 100644 src/ui/components/ClickableListItem.js create mode 100644 src/ui/components/CodeBlock.js create mode 100644 src/ui/components/ContextMenu.js create mode 100644 src/ui/components/ContextMenuProvider.js create mode 100644 src/ui/components/Dropdown.js create mode 100644 src/ui/components/ErrorBlock.js create mode 100644 src/ui/components/ErrorBoundary.js create mode 100644 src/ui/components/File.js create mode 100644 src/ui/components/FileList.js create mode 100644 src/ui/components/FlexBox.js create mode 100644 src/ui/components/FlexCenter.js create mode 100644 src/ui/components/FlexColumn.js create mode 100644 src/ui/components/FlexRow.js create mode 100644 src/ui/components/FocusableBox.js create mode 100644 src/ui/components/Glyph.js create mode 100644 src/ui/components/Heading.js create mode 100644 src/ui/components/HorizontalRule.js create mode 100644 src/ui/components/InlineContextMenu.js create mode 100644 src/ui/components/Input.js create mode 100644 src/ui/components/Interactive.js create mode 100644 src/ui/components/Label.js create mode 100644 src/ui/components/Link.js create mode 100644 src/ui/components/LoadingIndicator.js create mode 100644 src/ui/components/ModalOverlay.js create mode 100644 src/ui/components/Orderable.js create mode 100644 src/ui/components/Panel.js create mode 100644 src/ui/components/PathBreadcrumbs.js create mode 100644 src/ui/components/Popover.js create mode 100644 src/ui/components/ResizeSensor.js create mode 100644 src/ui/components/Select.js create mode 100644 src/ui/components/Sidebar.js create mode 100644 src/ui/components/SidebarLabel.js create mode 100644 src/ui/components/Tab.js create mode 100644 src/ui/components/Tabs.js create mode 100644 src/ui/components/Text.js create mode 100644 src/ui/components/TextParagraph.js create mode 100644 src/ui/components/Textarea.js create mode 100644 src/ui/components/ToggleSwitch.js create mode 100644 src/ui/components/Toolbar.js create mode 100644 src/ui/components/Tooltip.js create mode 100644 src/ui/components/TooltipProvider.js create mode 100644 src/ui/components/View.js create mode 100644 src/ui/components/ViewWithSize.js create mode 100644 src/ui/components/VirtualList.js create mode 100644 src/ui/components/colors.js create mode 100644 src/ui/components/console.js create mode 100644 src/ui/components/data-inspector/DataDescription.js create mode 100644 src/ui/components/data-inspector/DataInspector.js create mode 100755 src/ui/components/data-inspector/DataPreview.js create mode 100644 src/ui/components/data-inspector/ManagedDataInspector.js create mode 100644 src/ui/components/data-inspector/utils.js create mode 100644 src/ui/components/desktop-toolbar.js create mode 100644 src/ui/components/elements-inspector/ElementsInspector.js create mode 100644 src/ui/components/elements-inspector/elements.js create mode 100644 src/ui/components/elements-inspector/sidebar.js create mode 100644 src/ui/components/filter/FilterRow.js create mode 100644 src/ui/components/filter/types.js create mode 100644 src/ui/components/intro/intro.js create mode 100644 src/ui/components/searchable/FilterToken.js create mode 100644 src/ui/components/searchable/Searchable.js create mode 100644 src/ui/components/searchable/SearchableTable.js create mode 100644 src/ui/components/table/ManagedTable.js create mode 100644 src/ui/components/table/Table.js create mode 100644 src/ui/components/table/TableBody.js create mode 100644 src/ui/components/table/TableHead.js create mode 100644 src/ui/components/table/types.js create mode 100644 src/ui/components/table/utils.js create mode 100644 src/ui/index.js create mode 100644 src/ui/styled/__tests__/gc.node.js create mode 100644 src/ui/styled/__tests__/hash.node.js create mode 100644 src/ui/styled/__tests__/index.node.js create mode 100644 src/ui/styled/__tests__/rules.node.js create mode 100644 src/ui/styled/__tests__/sheet.node.js create mode 100644 src/ui/styled/gc.js create mode 100644 src/ui/styled/hash.js create mode 100644 src/ui/styled/index.js create mode 100644 src/ui/styled/rules.js create mode 100644 src/ui/styled/sheet.js create mode 100644 src/ui/styled/types.js create mode 100644 src/ui/virtualized/DynamicList.js create mode 100644 src/ui/virtualized/FixedList.js create mode 100644 src/ui/virtualized/index.js create mode 100644 src/ui/virtualized/types.js create mode 100644 src/utils/CertificateProvider.js create mode 100644 src/utils/InteractionTracker.js create mode 100644 src/utils/LRUCache.js create mode 100644 src/utils/LowPassFilter.js create mode 100644 src/utils/assignDeep.js create mode 100644 src/utils/createPaste.js create mode 100644 src/utils/dynamicPluginLoading.js create mode 100644 src/utils/geometry.js create mode 100644 src/utils/icons.js create mode 100644 src/utils/index.js create mode 100644 src/utils/info.js create mode 100644 src/utils/openssl-wrapper-with-promises.js create mode 100644 src/utils/performance.js create mode 100644 src/utils/snap.js create mode 100644 src/utils/textContent.js create mode 100755 static/PortForwardingMacApp.app/Contents/Frameworks/CocoaAsyncSocketMac.framework/CocoaAsyncSocketMac create mode 100644 static/PortForwardingMacApp.app/Contents/Frameworks/CocoaAsyncSocketMac.framework/Resources/Info.plist create mode 100755 static/PortForwardingMacApp.app/Contents/Frameworks/CocoaAsyncSocketMac.framework/Versions/A/CocoaAsyncSocketMac create mode 100644 static/PortForwardingMacApp.app/Contents/Frameworks/CocoaAsyncSocketMac.framework/Versions/A/Resources/Info.plist create mode 100755 static/PortForwardingMacApp.app/Contents/Frameworks/FBPortForwarding-Mac.framework/FBPortForwarding-Mac create mode 100644 static/PortForwardingMacApp.app/Contents/Frameworks/FBPortForwarding-Mac.framework/Resources/Info.plist create mode 100755 static/PortForwardingMacApp.app/Contents/Frameworks/FBPortForwarding-Mac.framework/Versions/A/FBPortForwarding-Mac create mode 100644 static/PortForwardingMacApp.app/Contents/Frameworks/FBPortForwarding-Mac.framework/Versions/A/Resources/Info.plist create mode 100644 static/PortForwardingMacApp.app/Contents/Frameworks/peertalkMac.framework/Resources/Info.plist create mode 100644 static/PortForwardingMacApp.app/Contents/Frameworks/peertalkMac.framework/Versions/A/Resources/Info.plist create mode 100755 static/PortForwardingMacApp.app/Contents/Frameworks/peertalkMac.framework/Versions/A/peertalkMac create mode 100755 static/PortForwardingMacApp.app/Contents/Frameworks/peertalkMac.framework/peertalkMac create mode 100644 static/PortForwardingMacApp.app/Contents/Info.plist create mode 100755 static/PortForwardingMacApp.app/Contents/MacOS/PortForwardingMacApp create mode 100644 static/PortForwardingMacApp.app/Contents/PkgInfo create mode 100644 static/anchor.svg create mode 100644 static/compilePlugins.js create mode 100644 static/graphiql/graphiql.css create mode 100644 static/icon.icns create mode 100644 static/icon.ico create mode 100644 static/icon.png create mode 100644 static/icons/android.svg create mode 100644 static/icons/componentkit-logo.png create mode 100755 static/icons/componentscript-logo.png create mode 100644 static/icons/ios.svg create mode 100644 static/icons/litho-logo.png create mode 100644 static/icons/oculus.png create mode 100644 static/icons/sidebar_bottom.svg create mode 100644 static/icons/sidebar_left.svg create mode 100644 static/icons/sidebar_right.svg create mode 100644 static/index.dev.html create mode 100644 static/index.html create mode 100644 static/index.js create mode 100644 static/package.json create mode 100644 static/pattern.gif create mode 100644 static/serviceWorker.js create mode 100644 static/style.css create mode 100644 static/transforms/dynamic-requires.js create mode 100644 static/transforms/electron-requires.js create mode 100644 static/transforms/fb-stubs.js create mode 100644 static/transforms/import-react.js create mode 100644 static/transforms/index.js create mode 100644 static/transforms/sonar-requires.js create mode 100644 static/uiperf/screenshot.png create mode 100644 static/vis/vis.min.css create mode 100644 static/yarn.lock create mode 100644 website/.gitignore create mode 100755 website/blog/2016-03-11-blog-post.md create mode 100644 website/blog/2017-04-10-blog-post-two.md create mode 100644 website/blog/2017-09-25-testing-rss.md create mode 100644 website/blog/2017-09-26-adding-rss.md create mode 100644 website/blog/2017-10-24-new-version-1.0.0.md create mode 100644 website/core/Footer.js create mode 100644 website/i18n/en.json create mode 100644 website/package.json create mode 100644 website/pages/docs/en/index.js create mode 100755 website/pages/en/index.js create mode 100644 website/sidebars.json create mode 100644 website/siteConfig.js create mode 100644 website/static/css/custom.css create mode 100644 website/static/img/SonarKit.png create mode 100644 website/static/img/SonarKit@2x.png create mode 100644 website/static/img/docusaurus.svg create mode 100644 website/static/img/favicon.png create mode 100644 website/static/img/favicon/favicon.ico create mode 100644 website/static/img/icon.png create mode 100644 website/static/img/inspector.png create mode 100644 website/static/img/inspector@2x.png create mode 100644 website/static/img/mascot.png create mode 100644 website/static/img/oss_logo.png create mode 100644 website/static/img/plugins.png create mode 100644 website/static/img/plugins@2x.png create mode 100644 website/static/img/splash.png create mode 100644 website/static/img/splash@2x.png create mode 100644 website/yarn.lock create mode 100644 xplat/AndroidManifest.xml create mode 100644 xplat/CMakeLists.txt create mode 100644 xplat/Sonar/CertificateUtils.cpp create mode 100644 xplat/Sonar/CertificateUtils.h create mode 100644 xplat/Sonar/SonarClient.cpp create mode 100644 xplat/Sonar/SonarClient.h create mode 100644 xplat/Sonar/SonarConnection.h create mode 100644 xplat/Sonar/SonarConnectionImpl.h create mode 100644 xplat/Sonar/SonarInitConfig.h create mode 100644 xplat/Sonar/SonarKitCPP.podspec create mode 100644 xplat/Sonar/SonarPlugin.h create mode 100644 xplat/Sonar/SonarResponder.h create mode 100644 xplat/Sonar/SonarResponderImpl.h create mode 100644 xplat/Sonar/SonarWebSocket.h create mode 100644 xplat/Sonar/SonarWebSocketImpl.cpp create mode 100644 xplat/Sonar/SonarWebSocketImpl.h create mode 100644 xplat/SonarTestLib/SonarConnectionMock.h create mode 100644 xplat/SonarTestLib/SonarPluginMock.h create mode 100644 xplat/SonarTestLib/SonarResponderMock.h create mode 100644 xplat/SonarTestLib/SonarWebSocketMock.h create mode 100644 xplat/SonarTests/SonarClientTests.cpp create mode 100644 xplat/build.gradle create mode 100644 yarn.lock diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 000000000..71caa58fe --- /dev/null +++ b/.eslintignore @@ -0,0 +1,8 @@ +src/fb/plugins/relaydevtools/relay-devtools/* +latest +resources +templates +node_modules +flow-typed +lib +!.eslintrc.js diff --git a/.eslintrc.js b/.eslintrc.js new file mode 100644 index 000000000..841ea8d90 --- /dev/null +++ b/.eslintrc.js @@ -0,0 +1,30 @@ +/** + * Copyright 2018-present Facebook. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * @format + */ + +const fbjs = require('eslint-config-fbjs'); + +// enforces copyright header and @format directive to be present in every file +const pattern = /^\*\n \* Copyright 2018-present Facebook\.\n \* This source code is licensed under the MIT license found in the\n \* LICENSE file in the root directory of this source tree\.\n \* @format\n./; + +module.exports = { + extends: 'fbjs', + plugins: [...fbjs.plugins, 'header', 'prettier'], + rules: { + // disable rules from eslint-config-fbjs + 'react/react-in-jsx-scope': 0, // not needed with our metro implementation + 'no-new': 0, // new keyword needed e.g. new Notification + 'no-catch-shadow': 0, // only relevant for IE8 and below + 'no-bitwise': 0, // bitwise operations needed in some places + 'consistent-return': 0, + 'max-len': 0, // let's take prettier take care of this + indent: 0, // let's take prettier take care of this + + // additional rules for this project + 'header/header': [2, 'block', {pattern}], + 'prettier/prettier': [2, 'fb', '@format'], + }, +}; diff --git a/.flowconfig b/.flowconfig new file mode 100644 index 000000000..a065c3782 --- /dev/null +++ b/.flowconfig @@ -0,0 +1,24 @@ +[ignore] +.*/scripts/.* +.*/coverage/.* +.*/node_modules/.* +.*/build/.* +.*/dist/.* +.*/static/.* +/src/fb/plugins/relaydevtools/relay-devtools/DevtoolsUI.js$ +.*/website/.* + +[libs] +lib +flow-typed + +[options] +esproposal.export_star_as=enable +module.use_strict=true +emoji=true +all=true +include_warnings=true +module.name_mapper='sonar' -> '/src/index.js' + +[version] +0.69.0 diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..660a55ca5 --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +node_modules +dist +website/build +*.xcworkspace +**/Pods/ +**/xcuserdata/ diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 000000000..849454e73 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "libs/folly"] + path = libs/folly + url = https://github.com/facebook/folly.git diff --git a/.sonarhandles b/.sonarhandles new file mode 100644 index 000000000..b2518ae20 --- /dev/null +++ b/.sonarhandles @@ -0,0 +1 @@ +{"osx": "GICWmAAS05ZnyDsCAAAAAABHIak5bnw7AAAg", "linux": "GICWmACHSiVuyDsCAAAAAABVAX1Bbnw7AAAg", "windows": "GICWmAAn5YB0yDsCAAAAAAAMdghhbnw7AAAg"} diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 000000000..91a50b339 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,56 @@ +os: osx +osx_image: xcode9.3 + +matrix: + include: + - language: node_js + node_js: + - "8" + + install: + - yarn + - cd website + - yarn + - cd .. + + script: + - yarn lint + - yarn build macOnly build-number=$TRAVIS_BUILD_NUMBER + - cd website + - yarn build + - cd .. + + before_deploy: + - export SONAR_VERSION="v$(plutil -p $TRAVIS_BUILD_DIR/dist/mac/Sonar.app/Contents/Info.plist | awk '/CFBundleShortVersionString/ {print substr($3, 2, length($3)-2)}')" + + deploy: + - provider: pages + skip-cleanup: true + github-token: $GITHUB_TOKEN + fqdn: fbsonar.com + local-dir: website/build/sonar + keep-history: true + on: + branch: master + - provider: releases + api_key: $GITHUB_TOKEN + file: dist/Sonar.zip + name: $SONAR_VERSION + draft: true + skip_cleanup: true + on: + branch: master + + - language: objective-c + + before_install: + - pod repo update + + install: + - cd iOS/Sample + - pod install + - cd ../../ + + script: + - cd iOS/Sample + - xcodebuild clean build -workspace Sample.xcworkspace -scheme Pods-Sample \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 000000000..3e2f26fa9 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,12 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "name": "Attach to Running Renderer", + "type": "chrome", + "request": "attach", + "port": 9222, + "webRoot": "${workspaceRoot}" + } + ] +} diff --git a/.yarnrc b/.yarnrc new file mode 100644 index 000000000..6a904ab64 --- /dev/null +++ b/.yarnrc @@ -0,0 +1 @@ +--install.mutex network diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 000000000..0a45f9bd5 --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,3 @@ +# Code of Conduct + +Facebook has adopted a Code of Conduct that we expect project participants to adhere to. Please [read the full text](https://code.facebook.com/codeofconduct) so that you can understand what actions will and will not be tolerated. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 000000000..45b5f7a72 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,55 @@ +# Contributing to Sonar + +We want to make contributing to this project as easy and transparent as +possible. + +## Our Development Process + +Changes from Facebook employees are synced to the GitHub repo automatically. +PRs from the community are imported into our internal source control and then +pushed to GitHub. + +For changes affecting both, native code and JavaScript, make sure to only create +a single PR containing both parts of the code. + +Although the Sonar desktop app is only released for macOS right now, it is +possible to create Windows and Linux builds of the app. Please keep this in mind +when dealing with platform-specific code. + +## Pull Requests + +We actively welcome your pull requests. + +1. Fork the repo and create your branch from `master`. +2. If you've added code that should be tested, add tests. +3. If you've changed APIs, update the documentation. +4. Ensure the test suite passes. +5. Make sure your code lints. +6. If you haven't already, complete the Contributor License Agreement ("CLA"). + +## Contributor License Agreement ("CLA") + +In order to accept your pull request, we need you to submit a CLA. You only need +to do this once to work on any of Facebook's open source projects. + +Complete your CLA here: + +## Issues + +We use GitHub issues to track public bugs. Please ensure your description is +clear and has sufficient instructions to be able to reproduce the issue. + +Facebook has a [bounty program](https://www.facebook.com/whitehat/) for the safe +disclosure of security bugs. In those cases, please go through the process +outlined on that page and do not file a public issue. + +## Coding Style + +We are using Prettier to format our source code. The styles are enforced via +eslint. Make sure everything is well formatted before creating a PR. Therefore, +run `yarn lint` and `yarn fix` to apply formatting fixes. + +## License + +By contributing to Sonar, you agree that your contributions will be licensed +under the LICENSE file in the root directory of this source tree. diff --git a/LICENSE b/LICENSE new file mode 100644 index 000000000..86642be60 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2004-present, Facebook, Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 000000000..326dec991 --- /dev/null +++ b/README.md @@ -0,0 +1,54 @@ +Sonar is a desktop app and client API for real time debugging of mobile apps. Sonar enables developers to quickly build plugins which expose runtime information from Android and iOS apps in a easy to use desktop interface. + +# Why should I build tools on top of Sonar? + +Sonar provides you with everything you need to quickly get your tools into people hands. Sonar provides a simple API for communicating with both Android and iOS devices, reconnecting if connection is lost as well as managing multiple connections. With Sonar's built in set of components it is easy to make good looking, easy to use, and powerful developer tools. + +# In this repo + +This repository includes all parts of Sonar. This includes: + +* Sonar's desktop app built using Electron (`/src`) +* native Sonar SDKs for iOS +* native Sonar SDKs for Android +* Plugins: + * Logs (`/src/device-plugins/logs`) + * Layout inspector (`/src/plugins/layout`) + * Network inspector (`/src/plugins/network`) +* website and documentation (`/website` / `/docs`) + +# Getting started + +## Requirements + +* macOS (while Sonar is buildable using other systems as well, only macOS is officially supported) +* node >= 8 +* yarn >= 1.5 +* iOS developer tools (for developing iOS plugins) +* Android SDK and adb + +## Starting the desktop app + +``` +git clone https://github.com/facebook/Sonar.git +cd Sonar +yarn +yarn start +``` + +## Building the desktop app + +``` +yarn build [macOnly] [build-number=$buildNumber] +``` + +A binary for macOS is created in `dist/mac`. `macOnly` and `build-number` are optional params. + +## Documentation + +Find the full documentation for this project at [fbsonar.com](https://fbsonar.com/). + +## Contributing and license + +See the CONTRIBUTING file for how to help out. +Sonar is MIT licensed, as found in the LICENSE file. diff --git a/android/AndroidManifest.xml b/android/AndroidManifest.xml new file mode 100644 index 000000000..af9aaeea8 --- /dev/null +++ b/android/AndroidManifest.xml @@ -0,0 +1,4 @@ + + + diff --git a/android/CMakeLists.txt b/android/CMakeLists.txt new file mode 100644 index 000000000..496069fe9 --- /dev/null +++ b/android/CMakeLists.txt @@ -0,0 +1,63 @@ +cmake_minimum_required (VERSION 3.6.0) +project(sonar CXX C) +set(CMAKE_VERBOSE_MAKEFILE on) + +set(PACKAGE_NAME "sonar") + +add_compile_options(-DFOLLY_NO_CONFIG + -DSONAR_JNI_EXTERNAL=1 + -DFB_SONARKIT_ENABLED=1 + -DFOLLY_HAVE_MEMRCHR + -DFOLLY_MOBILE=1 + -DFOLLY_USE_LIBCPP=1 + -DFOLLY_HAVE_LIBJEMALLOC=0 + -DFOLLY_HAVE_PREADV=0 + -frtti + -fexceptions + -std=c++14 + -Wno-error + -Wno-unused-local-typedefs + -Wno-unused-variable + -Wno-sign-compare + -Wno-comment + -Wno-return-type + -Wno-tautological-constant-compare + ) + +file(GLOB SOURCES android/sonar.cpp) +add_library(${PACKAGE_NAME} SHARED ${SOURCES}) +target_include_directories(${PACKAGE_NAME} PUBLIC "./") + +set(libjnihack_DIR ${CMAKE_SOURCE_DIR}/../libs/jni-hack/) +set(libfbjni_DIR ${CMAKE_SOURCE_DIR}/../libs/fbjni/src/main/cpp/include/) +set(libsonar_DIR ${CMAKE_SOURCE_DIR}/../xplat/) +set(third_party_ndk build/third-party-ndk) +set(libfolly_DIR ${third_party_ndk}/folly/) +set(glog_DIR ${third_party_ndk}/glog) +set(BOOST_DIR ${third_party_ndk}/boost/boost_1_63_0/) + + +set(build_DIR ${CMAKE_SOURCE_DIR}/build) + +set(fbjni_build_DIR ${build_DIR}/fbjni/${ANDROID_ABI}) +set(libsonar_build_DIR ${build_DIR}/libsonar/${ANDROID_ABI}) +set(libfolly_build_DIR ${build_DIR}/libfolly/${ANDROID_ABI}) + +file(MAKE_DIRECTORY ${build_DIR}) + +add_subdirectory(${libsonar_DIR} ${libsonar_build_DIR}) +add_subdirectory(${libfbjni_DIR}/../ ${fbjni_build_DIR}) + +target_include_directories(${PACKAGE_NAME} PRIVATE + ${libjnihack_DIR} + ${libfbjni_DIR} + ${libsonar_DIR} + ${libfolly_DIR} + ${glog_DIR} + ${glog_DIR}/../ + ${glog_DIR}/glog-0.3.5/src/ + ${BOOST_DIR} + ${BOOST_DIR}/../ + ) + +target_link_libraries(${PACKAGE_NAME} fb sonarcpp) diff --git a/android/android/AndroidSonarClient.java b/android/android/AndroidSonarClient.java new file mode 100644 index 000000000..963799c9d --- /dev/null +++ b/android/android/AndroidSonarClient.java @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +package com.facebook.sonar.android; + +import android.content.Context; +import android.net.wifi.WifiInfo; +import android.net.wifi.WifiManager; +import android.os.Build; +import com.facebook.sonar.core.SonarClient; + +public final class AndroidSonarClient { + private static boolean sIsInitialized = false; + private static SonarThread sSonarThread; + + public static synchronized SonarClient getInstance(Context context) { + if (!sIsInitialized) { + sSonarThread = new SonarThread(); + sSonarThread.start(); + + final Context app = context.getApplicationContext(); + SonarClientImpl.init( + sSonarThread.getEventBase(), + getServerHost(app), + "Android", + getFriendlyDeviceName(), + getId(), + getRunningAppName(app), + getPackageName(app), + context.getFilesDir().getAbsolutePath()); + sIsInitialized = true; + } + return SonarClientImpl.getInstance(); + } + + static boolean isRunningOnGenymotion() { + return Build.FINGERPRINT.contains("vbox"); + } + + static boolean isRunningOnStockEmulator() { + return Build.FINGERPRINT.contains("generic") && !Build.FINGERPRINT.contains("vbox"); + } + + static String getId() { + return Build.SERIAL; + } + + static String getFriendlyDeviceName() { + if (isRunningOnGenymotion()) { + // Genymotion already has a friendly name by default + return Build.MODEL; + } else { + return Build.MODEL + " - " + Build.VERSION.RELEASE + " - API " + Build.VERSION.SDK_INT; + } + } + + static String getServerHost(Context context) { + if (isRunningOnStockEmulator()) { + return "10.0.2.2"; + } else if (isRunningOnGenymotion()) { + // This is hand-wavy but works on but ipv4 and ipv6 genymotion + final WifiManager wifi = (WifiManager) context.getSystemService(Context.WIFI_SERVICE); + final WifiInfo info = wifi.getConnectionInfo(); + final int ip = info.getIpAddress(); + return String.format("%d.%d.%d.2", (ip & 0xff), (ip >> 8 & 0xff), (ip >> 16 & 0xff)); + } else { + // Running on physical device. Sonar desktop will run `adb reverse tcp:8088 tcp:8088` + return "localhost"; + } + } + + static String getRunningAppName(Context context) { + return context.getApplicationInfo().loadLabel(context.getPackageManager()).toString(); + } + + static String getPackageName(Context context) { + return context.getPackageName(); + } +} diff --git a/android/android/EventBase.java b/android/android/EventBase.java new file mode 100644 index 000000000..db90b35f2 --- /dev/null +++ b/android/android/EventBase.java @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2004-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +package com.facebook.sonar.android; + +import com.facebook.jni.HybridClassBase; +import com.facebook.proguard.annotations.DoNotStrip; +import com.facebook.soloader.SoLoader; +import com.facebook.sonar.BuildConfig; + +@DoNotStrip +class EventBase extends HybridClassBase { + static { + if (BuildConfig.IS_INTERNAL_BUILD) { + SoLoader.loadLibrary("sonar"); + } + } + + EventBase() { + initHybrid(); + } + + @DoNotStrip + native void loopForever(); + + @DoNotStrip + private native void initHybrid(); +} diff --git a/android/android/SonarClientImpl.java b/android/android/SonarClientImpl.java new file mode 100644 index 000000000..eae290a4d --- /dev/null +++ b/android/android/SonarClientImpl.java @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +package com.facebook.sonar.android; + +import com.facebook.jni.HybridData; +import com.facebook.proguard.annotations.DoNotStrip; +import com.facebook.soloader.SoLoader; +import com.facebook.sonar.BuildConfig; +import com.facebook.sonar.core.SonarClient; +import com.facebook.sonar.core.SonarPlugin; + +@DoNotStrip +class SonarClientImpl implements SonarClient { + static { + if (BuildConfig.IS_INTERNAL_BUILD) { + SoLoader.loadLibrary("sonar"); + } + } + + private final HybridData mHybridData; + + private SonarClientImpl(HybridData hd) { + mHybridData = hd; + } + + public static native void init( + EventBase eventBase, + String host, + String os, + String device, + String deviceId, + String app, + String appId, + String privateAppDirectory); + + public static native SonarClientImpl getInstance(); + + @Override + public native void addPlugin(SonarPlugin plugin); + + @Override + public native T getPlugin(String id); + + @Override + public native void removePlugin(SonarPlugin plugin); + + @Override + public native void start(); + + @Override + public native void stop(); +} diff --git a/android/android/SonarConnectionImpl.java b/android/android/SonarConnectionImpl.java new file mode 100644 index 000000000..7b4b49984 --- /dev/null +++ b/android/android/SonarConnectionImpl.java @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +package com.facebook.sonar.android; + +import com.facebook.jni.HybridData; +import com.facebook.proguard.annotations.DoNotStrip; +import com.facebook.soloader.SoLoader; +import com.facebook.sonar.BuildConfig; +import com.facebook.sonar.core.SonarArray; +import com.facebook.sonar.core.SonarConnection; +import com.facebook.sonar.core.SonarObject; +import com.facebook.sonar.core.SonarReceiver; + +@DoNotStrip +class SonarConnectionImpl implements SonarConnection { + static { + if (BuildConfig.IS_INTERNAL_BUILD) { + SoLoader.loadLibrary("sonar"); + } + } + + private final HybridData mHybridData; + + private SonarConnectionImpl(HybridData hd) { + mHybridData = hd; + } + + @Override + public void send(String method, SonarObject params) { + sendObject(method, params); + } + + @Override + public void send(String method, SonarArray params) { + sendArray(method, params); + } + + public native void sendObject(String method, SonarObject params); + + public native void sendArray(String method, SonarArray params); + + @Override + public native void reportError(Throwable throwable); + + @Override + public native void receive(String method, SonarReceiver receiver); +} diff --git a/android/android/SonarResponderImpl.java b/android/android/SonarResponderImpl.java new file mode 100644 index 000000000..e9902fd66 --- /dev/null +++ b/android/android/SonarResponderImpl.java @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +package com.facebook.sonar.android; + +import com.facebook.jni.HybridData; +import com.facebook.proguard.annotations.DoNotStrip; +import com.facebook.soloader.SoLoader; +import com.facebook.sonar.BuildConfig; +import com.facebook.sonar.core.SonarArray; +import com.facebook.sonar.core.SonarObject; +import com.facebook.sonar.core.SonarResponder; + +@DoNotStrip +class SonarResponderImpl implements SonarResponder { + static { + if (BuildConfig.IS_INTERNAL_BUILD) { + SoLoader.loadLibrary("sonar"); + } + } + + private final HybridData mHybridData; + + private SonarResponderImpl(HybridData hd) { + mHybridData = hd; + } + + @Override + public void success(SonarObject params) { + successObject(params); + } + + @Override + public void success(SonarArray params) { + successArray(params); + } + + @Override + public void success() { + successObject(new SonarObject.Builder().build()); + } + + public native void successObject(SonarObject response); + + public native void successArray(SonarArray response); + + @Override + public native void error(SonarObject response); +} diff --git a/android/android/SonarThread.java b/android/android/SonarThread.java new file mode 100644 index 000000000..608fb5a62 --- /dev/null +++ b/android/android/SonarThread.java @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2004-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +package com.facebook.sonar.android; + +import android.os.Process; +import javax.annotation.Nullable; + +class SonarThread extends Thread { + private @Nullable EventBase mEventBase; + + SonarThread() { + super("SonarEventBaseThread"); + } + + @Override + public void run() { + Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); + synchronized (this) { + try { + mEventBase = new EventBase(); + } finally { + notifyAll(); + } + } + + mEventBase.loopForever(); + } + + synchronized EventBase getEventBase() { + while (mEventBase == null) { + try { + wait(); + } catch (InterruptedException e) { + // ignore + } + } + return mEventBase; + } +} diff --git a/android/android/sonar.cpp b/android/android/sonar.cpp new file mode 100644 index 000000000..f7a279e57 --- /dev/null +++ b/android/android/sonar.cpp @@ -0,0 +1,305 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ + +#include + +#include + +#include +#include +#include + +#include +#include +#include +#include + +using namespace facebook; +using namespace facebook::sonar; + +namespace { + +class JEventBase : public jni::HybridClass { + public: + constexpr static auto kJavaDescriptor = "Lcom/facebook/sonar/android/EventBase;"; + + static void registerNatives() { + registerHybrid({ + makeNativeMethod("initHybrid", JEventBase::initHybrid), + makeNativeMethod("loopForever", JEventBase::loopForever), + }); + } + + folly::EventBase* eventBase() { + return &eventBase_; + } + + private: + friend HybridBase; + + JEventBase() {} + + void loopForever() { + folly::EventBaseManager::get()->setEventBase(&eventBase_, false); + eventBase_.loopForever(); + } + + static void initHybrid(jni::alias_ref o) { + return setCxxInstance(o); + } + + folly::EventBase eventBase_; +}; + +class JSonarObject : public jni::JavaClass { + public: + constexpr static auto kJavaDescriptor = "Lcom/facebook/sonar/core/SonarObject;"; + + static jni::local_ref create(const folly::dynamic& json) { + return newInstance(folly::toJson(json)); + } + + std::string toJsonString() { + static const auto method = javaClassStatic()->getMethod("toJsonString"); + return method(self())->toStdString(); + } +}; + +class JSonarArray : public jni::JavaClass { + public: + constexpr static auto kJavaDescriptor = "Lcom/facebook/sonar/core/SonarArray;"; + + static jni::local_ref create(const folly::dynamic& json) { + return newInstance(folly::toJson(json)); + } + + std::string toJsonString() { + static const auto method = javaClassStatic()->getMethod("toJsonString"); + return method(self())->toStdString(); + } +}; + +class JSonarResponder : public jni::JavaClass { + public: + constexpr static auto kJavaDescriptor = "Lcom/facebook/sonar/core/SonarResponder;"; +}; + +class JSonarResponderImpl : public jni::HybridClass { + public: + constexpr static auto kJavaDescriptor = "Lcom/facebook/sonar/android/SonarResponderImpl;"; + + static void registerNatives() { + registerHybrid({ + makeNativeMethod("successObject", JSonarResponderImpl::successObject), + makeNativeMethod("successArray", JSonarResponderImpl::successArray), + makeNativeMethod("error", JSonarResponderImpl::error), + }); + } + + void successObject(jni::alias_ref json) { + _responder->success(json ? folly::parseJson(json->toJsonString()) : folly::dynamic::object()); + } + + void successArray(jni::alias_ref json) { + _responder->success(json ? folly::parseJson(json->toJsonString()) : folly::dynamic::object()); + } + + void error(jni::alias_ref json) { + _responder->error(json ? folly::parseJson(json->toJsonString()) : folly::dynamic::object()); + } + + private: + friend HybridBase; + std::shared_ptr _responder; + + JSonarResponderImpl(std::shared_ptr responder): _responder(std::move(responder)) {} +}; + +class JSonarReceiver : public jni::JavaClass { + public: + constexpr static auto kJavaDescriptor = "Lcom/facebook/sonar/core/SonarReceiver;"; + + void receive(const folly::dynamic params, std::shared_ptr responder) const { + static const auto method = javaClassStatic()->getMethod, jni::alias_ref)>("onReceive"); + method(self(), JSonarObject::create(std::move(params)), JSonarResponderImpl::newObjectCxxArgs(responder)); + } +}; + +class JSonarConnection : public jni::JavaClass { + public: + constexpr static auto kJavaDescriptor = "Lcom/facebook/sonar/core/SonarConnection;"; +}; + +class JSonarConnectionImpl : public jni::HybridClass { + public: + constexpr static auto kJavaDescriptor = "Lcom/facebook/sonar/android/SonarConnectionImpl;"; + + static void registerNatives() { + registerHybrid({ + makeNativeMethod("sendObject", JSonarConnectionImpl::sendObject), + makeNativeMethod("sendArray", JSonarConnectionImpl::sendArray), + makeNativeMethod("reportError", JSonarConnectionImpl::reportError), + makeNativeMethod("receive", JSonarConnectionImpl::receive), + }); + } + + void sendObject(const std::string method, jni::alias_ref json) { + _connection->send(std::move(method), json ? folly::parseJson(json->toJsonString()) : folly::dynamic::object()); + } + + void sendArray(const std::string method, jni::alias_ref json) { + _connection->send(std::move(method), json ? folly::parseJson(json->toJsonString()) : folly::dynamic::object()); + } + + void reportError(jni::alias_ref throwable) { + _connection->error(throwable->toString(), throwable->getStackTrace()->toString()); + } + + void receive(const std::string method, jni::alias_ref receiver) { + auto global = make_global(receiver); + _connection->receive(std::move(method), [global] (const folly::dynamic& params, std::unique_ptr responder) { + global->receive(params, std::move(responder)); + }); + } + + private: + friend HybridBase; + std::shared_ptr _connection; + + JSonarConnectionImpl(std::shared_ptr connection): _connection(std::move(connection)) {} +}; + +class JSonarPlugin : public jni::JavaClass { + public: + constexpr static auto kJavaDescriptor = "Lcom/facebook/sonar/core/SonarPlugin;"; + + std::string identifier() const { + static const auto method = javaClassStatic()->getMethod("getId"); + return method(self())->toStdString(); + } + + void didConnect(std::shared_ptr conn) { + static const auto method = javaClassStatic()->getMethod)>("onConnect"); + method(self(), JSonarConnectionImpl::newObjectCxxArgs(conn)); + } + + void didDisconnect() { + static const auto method = javaClassStatic()->getMethod("onDisconnect"); + method(self()); + } +}; + +class JSonarPluginWrapper : public SonarPlugin { + public: + jni::global_ref jplugin; + + virtual std::string identifier() const override { + return jplugin->identifier(); + } + + virtual void didConnect(std::shared_ptr conn) override { + jplugin->didConnect(conn); + } + + virtual void didDisconnect() override { + jplugin->didDisconnect(); + } + + JSonarPluginWrapper(jni::global_ref plugin): jplugin(plugin) {} +}; + +class JSonarClient : public jni::HybridClass { + public: + constexpr static auto kJavaDescriptor = "Lcom/facebook/sonar/android/SonarClientImpl;"; + + static void registerNatives() { + registerHybrid({ + makeNativeMethod("init", JSonarClient::init), + makeNativeMethod("getInstance", JSonarClient::getInstance), + makeNativeMethod("start", JSonarClient::start), + makeNativeMethod("stop", JSonarClient::stop), + makeNativeMethod("addPlugin", JSonarClient::addPlugin), + makeNativeMethod("removePlugin", JSonarClient::removePlugin), + makeNativeMethod("getPlugin", JSonarClient::getPlugin), + }); + } + + static jni::alias_ref getInstance(jni::alias_ref) { + static auto client = make_global(newObjectCxxArgs()); + return client; + } + + void start() { + SonarClient::instance()->start(); + } + + void stop() { + SonarClient::instance()->stop(); + } + + void addPlugin(jni::alias_ref plugin) { + auto wrapper = std::make_shared(make_global(plugin)); + SonarClient::instance()->addPlugin(wrapper); + } + + void removePlugin(jni::alias_ref plugin) { + auto client = SonarClient::instance(); + client->removePlugin(client->getPlugin(plugin->identifier())); + } + + jni::alias_ref getPlugin(const std::string& identifier) { + auto plugin = SonarClient::instance()->getPlugin(identifier); + if (plugin) { + auto wrapper = std::static_pointer_cast(plugin); + return wrapper->jplugin; + } else { + return nullptr; + } + } + + static void init( + jni::alias_ref, + JEventBase* jEventBase, + const std::string host, + const std::string os, + const std::string device, + const std::string deviceId, + const std::string app, + const std::string appId, + const std::string privateAppDirectory) { + + SonarClient::init({ + { + std::move(host), + std::move(os), + std::move(device), + std::move(deviceId), + std::move(app), + std::move(appId), + std::move(privateAppDirectory) + }, + jEventBase->eventBase(), + }); + } + + private: + friend HybridBase; + + JSonarClient() {} +}; + +} // namespace + +jint JNI_OnLoad(JavaVM* vm, void*) { + return jni::initialize(vm, [] { + JSonarClient::registerNatives(); + JSonarConnectionImpl::registerNatives(); + JSonarResponderImpl::registerNatives(); + JEventBase::registerNatives(); + }); +} diff --git a/android/android/utils/SonarUtils.java b/android/android/utils/SonarUtils.java new file mode 100644 index 000000000..6150c273c --- /dev/null +++ b/android/android/utils/SonarUtils.java @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +package com.facebook.sonar.android.utils; + +import android.app.ActivityManager; +import android.content.Context; +import com.facebook.sonar.BuildConfig; +import java.util.List; + +public final class SonarUtils { + + private SonarUtils() {} + + public static boolean shouldEnableSonar(Context context) { + return BuildConfig.IS_INTERNAL_BUILD && !isEndToEndTest() && isMainProcess(context); + } + + private static boolean isEndToEndTest() { + final String value = System.getenv("BUDDY_SONAR_DISABLED"); + if (value == null || value.length() == 0) { + return false; + } + + try { + return Boolean.parseBoolean(value); + } catch (NumberFormatException e) { + return false; + } + } + + private static boolean isMainProcess(Context context) { + final int pid = android.os.Process.myPid(); + final ActivityManager manager = + (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); + final List infoList = manager.getRunningAppProcesses(); + + String processName = null; + if (infoList != null) { + for (ActivityManager.RunningAppProcessInfo info : infoList) { + if (info.pid == pid) { + processName = info.processName; + break; + } + } + } + + return context.getPackageName().equals(processName); + } +} diff --git a/android/build.gradle b/android/build.gradle new file mode 100644 index 000000000..92f11a0f5 --- /dev/null +++ b/android/build.gradle @@ -0,0 +1,172 @@ +apply plugin: 'com.android.library' + +apply plugin: 'de.undercouch.download' + +import de.undercouch.gradle.tasks.download.Download +import org.apache.tools.ant.taskdefs.condition.Os +import org.apache.tools.ant.filters.ReplaceTokens + +def downloadsDir = new File("$buildDir/downloads") +def thirdPartyNdkDir = new File("$buildDir/third-party-ndk") + +task createNativeDepsDirectories { + downloadsDir.mkdirs() + thirdPartyNdkDir.mkdirs() +} + +task downloadGlog(dependsOn: createNativeDepsDirectories, type: Download) { + src 'https://github.com/google/glog/archive/v0.3.5.tar.gz' + onlyIfNewer true + overwrite false + dest new File(downloadsDir, 'glog-0.3.5.tar.gz') +} + +task prepareGlog(dependsOn: [downloadGlog], type: Copy) { + from tarTree(downloadGlog.dest) + from './third-party/glog/' + include 'glog-0.3.5/src/**/*', 'Android.mk', 'config.h', 'build.gradle', 'CMakeLists.txt', 'ApplicationManifest.xml' + includeEmptyDirs = false + filesMatching('**/*.h.in') { + filter(ReplaceTokens, tokens: [ + ac_cv_have_unistd_h: '1', + ac_cv_have_stdint_h: '1', + ac_cv_have_systypes_h: '1', + ac_cv_have_inttypes_h: '1', + ac_cv_have_libgflags: '0', + ac_google_start_namespace: 'namespace google {', + ac_cv_have_uint16_t: '1', + ac_cv_have_u_int16_t: '1', + ac_cv_have___uint16: '0', + ac_google_end_namespace: '}', + ac_cv_have___builtin_expect: '1', + ac_google_namespace: 'google', + ac_cv___attribute___noinline: '__attribute__ ((noinline))', + ac_cv___attribute___noreturn: '__attribute__ ((noreturn))', + ac_cv___attribute___printf_4_5: '__attribute__((__format__ (__printf__, 4, 5)))' + ]) + it.path = (it.name - '.in') + } + into "$thirdPartyNdkDir/glog" +} + +task finalizeGlog(dependsOn: [prepareGlog], type: Copy) { + from './third-party/glog/' + include 'logging.cc' + includeEmptyDirs = false + into "$thirdPartyNdkDir/glog/glog-0.3.5/src/" +} + +task downloadDoubleConversion(dependsOn: createNativeDepsDirectories, type: Download) { + src 'https://github.com/google/double-conversion/archive/v3.0.0.tar.gz' + onlyIfNewer true + overwrite false + dest new File(downloadsDir, 'double-conversion-3.0.0.tar.gz') +} + +task prepareDoubleConversion(dependsOn: [downloadDoubleConversion], type: Copy) { + from tarTree(downloadDoubleConversion.dest) + from './third-party/DoubleConversion/' + include 'double-conversion-3.0.0/**/*', 'build.gradle', 'CMakeLists.txt', 'ApplicationManifest.xml' + includeEmptyDirs = false + into "$thirdPartyNdkDir/double-conversion" +} + +task downloadBoost(dependsOn: createNativeDepsDirectories, type: Download) { + src 'https://github.com/react-native-community/boost-for-react-native/releases/download/v1.63.0-0/boost_1_63_0.tar.gz' + onlyIfNewer true + overwrite false + dest new File(downloadsDir, 'boost_1_63_0.tar.gz') +} + +task prepareBoost(dependsOn: [downloadBoost], type: Copy) { + from tarTree(resources.gzip(downloadBoost.dest)) + include 'boost_1_63_0/boost/**/*.hpp', 'boost/boost/**/*.hpp' + includeEmptyDirs = false + into "$thirdPartyNdkDir/boost" + doLast { + file("$thirdPartyNdkDir/boost/boost").renameTo("$thirdPartyNdkDir/boost/boost_1_63_0") + } +} + +task downloadFolly(dependsOn: createNativeDepsDirectories, type: Download) { + src 'https://github.com/facebook/folly/archive/v2018.05.21.00.tar.gz' + onlyIfNewer true + overwrite false + dest new File(downloadsDir, 'folly-2018.05.21.00.tar.gz'); +} + +task prepareFolly(dependsOn: [downloadFolly], type: Copy) { + from tarTree(downloadFolly.dest) + from './third-party/folly/' + include 'folly-2018.05.21.00/folly/**/*', 'build.gradle', 'CMakeLists.txt', 'ApplicationManifest.xml' + eachFile {fname -> fname.path = (fname.path - "folly-2018.05.21.00/")} + includeEmptyDirs = false + into "$thirdPartyNdkDir/folly" +} + +task prepareAllLibs() { + dependsOn finalizeGlog + dependsOn prepareDoubleConversion + dependsOn prepareBoost + dependsOn prepareFolly +} + +android { + compileSdkVersion rootProject.compileSdkVersion + buildToolsVersion rootProject.buildToolsVersion + + defaultConfig { + minSdkVersion rootProject.minSdkVersion + targetSdkVersion rootProject.targetSdkVersion + buildConfigField "boolean", "IS_INTERNAL_BUILD", 'true' + ndk { + abiFilters 'x86', 'x86_64', 'armeabi-v7a', 'arm64-v8a' + } + + externalNativeBuild { + cmake { + arguments '-DANDROID_TOOLCHAIN=clang' + } + } + } + lintOptions { + abortOnError false + } + sourceSets { + main { + manifest.srcFile './AndroidManifest.xml' + java { + srcDir 'android' + srcDir 'core' + srcDir 'plugins' + } + res { + srcDir 'res' + } + } + } + externalNativeBuild { + cmake { + path './CMakeLists.txt' + } + } + + dependencies { + implementation project(':fbjni') + implementation deps.soloader + compileOnly deps.lithoAnnotations + implementation 'org.glassfish:javax.annotation:10.0-b28' + implementation deps.guava + implementation deps.jsr305 + implementation deps.supportAppCompat + implementation deps.stetho + implementation deps.okhttp3 + implementation 'com.facebook.litho:litho-core:0.15.0' + implementation 'com.facebook.litho:litho-widget:0.15.0' + implementation fileTree(dir: 'plugins/console/dependencies', include: ['*.jar']) + } +} + +project.afterEvaluate { + preBuild.dependsOn prepareAllLibs +} diff --git a/android/core/ErrorReportingRunnable.java b/android/core/ErrorReportingRunnable.java new file mode 100644 index 000000000..0fc3e246a --- /dev/null +++ b/android/core/ErrorReportingRunnable.java @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +package com.facebook.sonar.core; + +public abstract class ErrorReportingRunnable implements Runnable { + + private final SonarConnection mConnection; + + public ErrorReportingRunnable(SonarConnection connection) { + mConnection = connection; + } + + @Override + public final void run() { + try { + runOrThrow(); + } catch (Exception e) { + if (mConnection != null) { + mConnection.reportError(e); + } + } finally { + doFinally(); + } + } + + protected void doFinally() {} + + protected abstract void runOrThrow() throws Exception; +} diff --git a/android/core/SonarArray.java b/android/core/SonarArray.java new file mode 100644 index 000000000..12b0973a2 --- /dev/null +++ b/android/core/SonarArray.java @@ -0,0 +1,164 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +package com.facebook.sonar.core; + +import java.util.ArrayList; +import java.util.List; +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +public class SonarArray { + final JSONArray mJson; + + SonarArray(JSONArray json) { + mJson = (json != null ? json : new JSONArray()); + } + + SonarArray(String json) { + try { + mJson = new JSONArray(json); + } catch (JSONException e) { + throw new RuntimeException(e); + } + } + + public SonarDynamic getDynamic(int index) { + return new SonarDynamic(mJson.opt(index)); + } + + public String getString(int index) { + return mJson.optString(index); + } + + public int getInt(int index) { + return mJson.optInt(index); + } + + public long getLong(int index) { + return mJson.optLong(index); + } + + public float getFloat(int index) { + return (float) mJson.optDouble(index); + } + + public double getDouble(int index) { + return mJson.optDouble(index); + } + + public boolean getBoolean(int index) { + return mJson.optBoolean(index); + } + + public SonarObject getObject(int index) { + final Object o = mJson.opt(index); + return new SonarObject((JSONObject) o); + } + + public SonarArray getArray(int index) { + final Object o = mJson.opt(index); + return new SonarArray((JSONArray) o); + } + + public int length() { + return mJson.length(); + } + + public List toStringList() { + final int length = length(); + final List list = new ArrayList<>(length); + for (int i = 0; i < length; i++) { + list.add(getString(i)); + } + return list; + } + + public String toJsonString() { + return toString(); + } + + @Override + public String toString() { + return mJson.toString(); + } + + @Override + public boolean equals(Object o) { + return mJson.toString().equals(o.toString()); + } + + @Override + public int hashCode() { + return mJson.hashCode(); + } + + public static class Builder { + private final JSONArray mJson; + + public Builder() { + mJson = new JSONArray(); + } + + public Builder put(String s) { + mJson.put(s); + return this; + } + + public Builder put(Integer i) { + mJson.put(i); + return this; + } + + public Builder put(Long l) { + mJson.put(l); + return this; + } + + public Builder put(Float f) { + mJson.put(Float.isNaN(f) ? null : f); + return this; + } + + public Builder put(Double d) { + mJson.put(Double.isNaN(d) ? null : d); + return this; + } + + public Builder put(Boolean b) { + mJson.put(b); + return this; + } + + public Builder put(SonarValue v) { + return put(v.toSonarObject()); + } + + public Builder put(SonarArray a) { + mJson.put(a == null ? null : a.mJson); + return this; + } + + public Builder put(SonarArray.Builder b) { + return put(b.build()); + } + + public Builder put(SonarObject o) { + mJson.put(o == null ? null : o.mJson); + return this; + } + + public Builder put(SonarObject.Builder b) { + return put(b.build()); + } + + public SonarArray build() { + return new SonarArray(mJson); + } + } +} diff --git a/android/core/SonarClient.java b/android/core/SonarClient.java new file mode 100644 index 000000000..8c91c3599 --- /dev/null +++ b/android/core/SonarClient.java @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +package com.facebook.sonar.core; + +public interface SonarClient { + void addPlugin(SonarPlugin plugin); + + T getPlugin(String id); + + void removePlugin(SonarPlugin plugin); + + void start(); + + void stop(); +} diff --git a/android/core/SonarConnection.java b/android/core/SonarConnection.java new file mode 100644 index 000000000..bd9ce9dd8 --- /dev/null +++ b/android/core/SonarConnection.java @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +package com.facebook.sonar.core; + +/** + * A connection between a SonarPlugin and the desktop Sonar application. Register request handlers + * to respond to calls made by the desktop application or directly send messages to the desktop + * application. + */ +public interface SonarConnection { + + /** + * Call a remote method on the Sonar desktop application, passing an optional JSON object as a + * parameter. + */ + void send(String method, SonarObject params); + + /** + * Call a remote method on the Sonar desktop application, passing an optional JSON array as a + * parameter. + */ + void send(String method, SonarArray params); + + /** Report client error */ + void reportError(Throwable throwable); + + /** + * Register a receiver for a remote method call issued by the Sonar desktop application. The + * SonarReceiver is passed a responder to respond back to the desktop application. + */ + void receive(String method, SonarReceiver receiver); +} diff --git a/android/core/SonarDynamic.java b/android/core/SonarDynamic.java new file mode 100644 index 000000000..ffda260ee --- /dev/null +++ b/android/core/SonarDynamic.java @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +package com.facebook.sonar.core; + +import javax.annotation.Nullable; +import org.json.JSONArray; +import org.json.JSONObject; + +public class SonarDynamic { + private final Object mObject; + + public SonarDynamic(Object object) { + mObject = object; + } + + public @Nullable String asString() { + if (mObject == null) { + return null; + } + return mObject.toString(); + } + + public int asInt() { + if (mObject == null) { + return 0; + } + if (mObject instanceof Integer) { + return (Integer) mObject; + } + if (mObject instanceof Long) { + return ((Long) mObject).intValue(); + } + if (mObject instanceof Float) { + return ((Float) mObject).intValue(); + } + if (mObject instanceof Double) { + return ((Double) mObject).intValue(); + } + return 0; + } + + public long asLong() { + if (mObject == null) { + return 0; + } + if (mObject instanceof Integer) { + return (Integer) mObject; + } + if (mObject instanceof Long) { + return (Long) mObject; + } + if (mObject instanceof Float) { + return ((Float) mObject).longValue(); + } + if (mObject instanceof Double) { + return ((Double) mObject).longValue(); + } + return 0; + } + + public float asFloat() { + if (mObject == null) { + return 0; + } + if (mObject instanceof Integer) { + return (Integer) mObject; + } + if (mObject instanceof Long) { + return (Long) mObject; + } + if (mObject instanceof Float) { + return (Float) mObject; + } + if (mObject instanceof Double) { + return ((Double) mObject).floatValue(); + } + return 0; + } + + public double asDouble() { + if (mObject == null) { + return 0; + } + if (mObject instanceof Integer) { + return (Integer) mObject; + } + if (mObject instanceof Long) { + return (Long) mObject; + } + if (mObject instanceof Float) { + return (Float) mObject; + } + if (mObject instanceof Double) { + return (Double) mObject; + } + return 0; + } + + public boolean asBoolean() { + if (mObject == null) { + return false; + } + return (Boolean) mObject; + } + + public SonarObject asObject() { + if (mObject instanceof JSONObject) { + return new SonarObject((JSONObject) mObject); + } + return (SonarObject) mObject; + } + + public SonarArray asArray() { + if (mObject instanceof JSONArray) { + return new SonarArray((JSONArray) mObject); + } + return (SonarArray) mObject; + } +} diff --git a/android/core/SonarObject.java b/android/core/SonarObject.java new file mode 100644 index 000000000..4c0081735 --- /dev/null +++ b/android/core/SonarObject.java @@ -0,0 +1,221 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +package com.facebook.sonar.core; + +import java.util.Arrays; +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +public class SonarObject { + final JSONObject mJson; + + public SonarObject(JSONObject json) { + mJson = (json != null ? json : new JSONObject()); + } + + public SonarObject(String json) { + try { + mJson = new JSONObject(json); + } catch (JSONException e) { + throw new RuntimeException(e); + } + } + + public SonarDynamic getDynamic(String name) { + return new SonarDynamic(mJson.opt(name)); + } + + public String getString(String name) { + if (mJson.isNull(name)) { + return null; + } + return mJson.optString(name); + } + + public int getInt(String name) { + return mJson.optInt(name); + } + + public long getLong(String name) { + return mJson.optLong(name); + } + + public float getFloat(String name) { + return (float) mJson.optDouble(name); + } + + public double getDouble(String name) { + return mJson.optDouble(name); + } + + public boolean getBoolean(String name) { + return mJson.optBoolean(name); + } + + public SonarObject getObject(String name) { + final Object o = mJson.opt(name); + return new SonarObject((JSONObject) o); + } + + public SonarArray getArray(String name) { + final Object o = mJson.opt(name); + return new SonarArray((JSONArray) o); + } + + public boolean contains(String name) { + return mJson.has(name); + } + + public String toJsonString() { + return toString(); + } + + @Override + public String toString() { + return mJson.toString(); + } + + @Override + public boolean equals(Object o) { + return mJson.toString().equals(o.toString()); + } + + @Override + public int hashCode() { + return mJson.hashCode(); + } + + public static class Builder { + private final JSONObject mJson; + + public Builder() { + mJson = new JSONObject(); + } + + public Builder put(String name, Object obj) { + if (obj == null) { + return put(name, (String) null); + } else if (obj instanceof Integer) { + return put(name, (Integer) obj); + } else if (obj instanceof Long) { + return put(name, (Long) obj); + } else if (obj instanceof Float) { + return put(name, (Float) obj); + } else if (obj instanceof Double) { + return put(name, (Double) obj); + } else if (obj instanceof String) { + return put(name, (String) obj); + } else if (obj instanceof Boolean) { + return put(name, (Boolean) obj); + } else if (obj instanceof Object[]) { + return put(name, Arrays.deepToString((Object[]) obj)); + } else if (obj instanceof SonarObject) { + return put(name, (SonarObject) obj); + } else if (obj instanceof SonarObject.Builder) { + return put(name, (SonarObject.Builder) obj); + } else if (obj instanceof SonarArray) { + return put(name, (SonarArray) obj); + } else if (obj instanceof SonarArray.Builder) { + return put(name, (SonarArray.Builder) obj); + } else if (obj instanceof SonarValue) { + return put(name, ((SonarValue) obj).toSonarObject()); + } else { + return put(name, obj.toString()); + } + } + + public Builder put(String name, String s) { + try { + mJson.put(name, s); + } catch (JSONException e) { + throw new RuntimeException(e); + } + return this; + } + + public Builder put(String name, Integer i) { + try { + mJson.put(name, i); + } catch (JSONException e) { + throw new RuntimeException(e); + } + return this; + } + + public Builder put(String name, Long l) { + try { + mJson.put(name, l); + } catch (JSONException e) { + throw new RuntimeException(e); + } + return this; + } + + public Builder put(String name, Float f) { + try { + mJson.put(name, Float.isNaN(f) ? null : f); + } catch (JSONException e) { + throw new RuntimeException(e); + } + return this; + } + + public Builder put(String name, Double d) { + try { + mJson.put(name, Double.isNaN(d) ? null : d); + } catch (JSONException e) { + throw new RuntimeException(e); + } + return this; + } + + public Builder put(String name, Boolean b) { + try { + mJson.put(name, b); + } catch (JSONException e) { + throw new RuntimeException(e); + } + return this; + } + + public Builder put(String name, SonarValue v) { + return put(name, v.toSonarObject()); + } + + public Builder put(String name, SonarArray a) { + try { + mJson.put(name, a == null ? null : a.mJson); + } catch (JSONException e) { + throw new RuntimeException(e); + } + return this; + } + + public Builder put(String name, SonarArray.Builder b) { + return put(name, b.build()); + } + + public Builder put(String name, SonarObject o) { + try { + mJson.put(name, o == null ? null : o.mJson); + } catch (JSONException e) { + throw new RuntimeException(e); + } + return this; + } + + public Builder put(String name, SonarObject.Builder b) { + return put(name, b.build()); + } + + public SonarObject build() { + return new SonarObject(mJson); + } + } +} diff --git a/android/core/SonarPlugin.java b/android/core/SonarPlugin.java new file mode 100644 index 000000000..f524f2037 --- /dev/null +++ b/android/core/SonarPlugin.java @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +package com.facebook.sonar.core; + +/** + * A SonarPlugin is an object which exposes an API to the Desktop Sonar application. When a + * connection is established the plugin is given a SonarConnection on which it can register request + * handlers and send messages. When the SonarConnection is invalid onDisconnect is called. onConnect + * may be called again on the same plugin object if Sonar re-connects, this will provide a new + * SonarConnection, do not attempt to re-use the previous connection. + */ +public interface SonarPlugin { + + /** + * @return The id of this plugin. This is the namespace which Sonar desktop plugins will call + * methods on to route them to your plugin. This should match the id specified in your React + * plugin. + */ + String getId(); + + /** + * Called when a connection has been established. The connection passed to this method is valid + * until {@link SonarPlugin#onDisconnect()} is called. + */ + void onConnect(SonarConnection connection) throws Exception; + + /** + * Called when the connection passed to {@link SonarPlugin#onConnect(SonarConnection)} is no + * longer valid. Do not try to use the connection in or after this method has been called. + */ + void onDisconnect() throws Exception; +} diff --git a/android/core/SonarReceiver.java b/android/core/SonarReceiver.java new file mode 100644 index 000000000..08d1c7384 --- /dev/null +++ b/android/core/SonarReceiver.java @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +package com.facebook.sonar.core; + +/** + * A receiver of a remote method call issued by the Sonar desktop application. If the given + * responder is present it means the Sonar desktop application is expecting a response. + */ +public interface SonarReceiver { + + /** + * Reciver for a request sent from the Sonar desktop client. + * + * @param params Optional set of parameters sent with the request. + * @param responder Optional responder for request. Some requests don't warrant a response + * through. In this case the request should be made from the desktop using send() instead of + * call(). + */ + void onReceive(SonarObject params, SonarResponder responder) throws Exception; +} diff --git a/android/core/SonarResponder.java b/android/core/SonarResponder.java new file mode 100644 index 000000000..3af6d4b2a --- /dev/null +++ b/android/core/SonarResponder.java @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +package com.facebook.sonar.core; + +/** + * SonarResponder is used to asyncronously response to a messaged recieved from the Sonar desktop + * app. The Sonar Responder will automatically wrap the response in an approriate object depending + * on if it is an error or not. + */ +public interface SonarResponder { + + /** Deliver a successful response to the Sonar desktop app. */ + void success(SonarObject response); + + /** Deliver a successful response to the Sonar desktop app. */ + void success(SonarArray response); + + /** Deliver a successful response to the Sonar desktop app. */ + void success(); + + /** Inform the Sonar desktop app of an error in handling the request. */ + void error(SonarObject response); +} diff --git a/android/core/SonarValue.java b/android/core/SonarValue.java new file mode 100644 index 000000000..07126d00b --- /dev/null +++ b/android/core/SonarValue.java @@ -0,0 +1,12 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +package com.facebook.sonar.core; + +public interface SonarValue { + SonarObject toSonarObject(); +} diff --git a/android/plugins/common/BufferingSonarPlugin.java b/android/plugins/common/BufferingSonarPlugin.java new file mode 100644 index 000000000..3881bddc8 --- /dev/null +++ b/android/plugins/common/BufferingSonarPlugin.java @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +package com.facebook.sonar.plugins.common; + +import com.facebook.sonar.core.SonarConnection; +import com.facebook.sonar.core.SonarObject; +import com.facebook.sonar.core.SonarPlugin; +import javax.annotation.Nullable; + +/** + * Sonar plugin that keeps events in a buffer until a connection is available. + * + *

In order to send data to the {@link SonarConnection}, use {@link #send(String, SonarObject)} + * instead of {@link SonarConnection#send(String, SonarObject)}. + */ +public abstract class BufferingSonarPlugin implements SonarPlugin { + + private static final int BUFFER_SIZE = 500; + + private @Nullable RingBuffer mEventQueue; + private @Nullable SonarConnection mConnection; + + @Override + public synchronized void onConnect(SonarConnection connection) { + mConnection = connection; + + sendBufferedEvents(); + } + + @Override + public synchronized void onDisconnect() { + mConnection = null; + } + + public synchronized SonarConnection getConnection() { + return mConnection; + } + + public synchronized boolean isConnected() { + return mConnection != null; + } + + public synchronized void send(String method, SonarObject sonarObject) { + if (mEventQueue == null) { + mEventQueue = new RingBuffer<>(BUFFER_SIZE); + } + mEventQueue.enqueue(new CachedSonarEvent(method, sonarObject)); + if (mConnection != null) { + mConnection.send(method, sonarObject); + } + } + + private synchronized void sendBufferedEvents() { + if (mEventQueue != null && mConnection != null) { + for (CachedSonarEvent cachedSonarEvent : mEventQueue.asList()) { + mConnection.send(cachedSonarEvent.method, cachedSonarEvent.sonarObject); + } + } + } + + private static class CachedSonarEvent { + final String method; + final SonarObject sonarObject; + + private CachedSonarEvent(String method, SonarObject sonarObject) { + this.method = method; + this.sonarObject = sonarObject; + } + } +} diff --git a/android/plugins/common/MainThreadSonarReceiver.java b/android/plugins/common/MainThreadSonarReceiver.java new file mode 100644 index 000000000..d793af421 --- /dev/null +++ b/android/plugins/common/MainThreadSonarReceiver.java @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +package com.facebook.sonar.plugins.common; + +import android.os.Handler; +import android.os.Looper; +import com.facebook.sonar.core.ErrorReportingRunnable; +import com.facebook.sonar.core.SonarConnection; +import com.facebook.sonar.core.SonarObject; +import com.facebook.sonar.core.SonarReceiver; +import com.facebook.sonar.core.SonarResponder; + +public abstract class MainThreadSonarReceiver implements SonarReceiver { + + public MainThreadSonarReceiver(SonarConnection connection) { + this.mConnection = connection; + } + + private final SonarConnection mConnection; + private final Handler mHandler = new Handler(Looper.getMainLooper()); + + @Override + public final void onReceive(final SonarObject params, final SonarResponder responder) { + mHandler.post( + new ErrorReportingRunnable(mConnection) { + @Override + public void runOrThrow() throws Exception { + onReceiveOnMainThread(params, responder); + } + }); + } + + public abstract void onReceiveOnMainThread(SonarObject params, SonarResponder responder) + throws Exception; +} diff --git a/android/plugins/common/RingBuffer.java b/android/plugins/common/RingBuffer.java new file mode 100644 index 000000000..872082683 --- /dev/null +++ b/android/plugins/common/RingBuffer.java @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +package com.facebook.sonar.plugins.common; + +import java.util.LinkedList; +import java.util.List; + +final class RingBuffer { + final int mBufferSize; + final List mBuffer = new LinkedList<>(); + + RingBuffer(int bufferSize) { + mBufferSize = bufferSize; + } + + void enqueue(T item) { + if (mBuffer.size() >= mBufferSize) { + mBuffer.remove(0); + } + mBuffer.add(item); + } + + List asList() { + return mBuffer; + } +} diff --git a/android/plugins/console/ConsoleSonarPlugin.java b/android/plugins/console/ConsoleSonarPlugin.java new file mode 100644 index 000000000..53b818799 --- /dev/null +++ b/android/plugins/console/ConsoleSonarPlugin.java @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +package com.facebook.sonar.plugins.console; + +import com.facebook.sonar.core.SonarConnection; +import com.facebook.sonar.core.SonarPlugin; +import com.facebook.sonar.plugins.console.iface.ConsoleCommandReceiver; + +public class ConsoleSonarPlugin implements SonarPlugin { + + private final JavascriptEnvironment mJavascriptEnvironment; + private JavascriptSession mJavascriptSession; + + public ConsoleSonarPlugin(JavascriptEnvironment jsEnvironment) { + this.mJavascriptEnvironment = jsEnvironment; + } + + @Override + public String getId() { + return "Console"; + } + + @Override + public void onConnect(SonarConnection connection) throws Exception { + ConsoleCommandReceiver.listenForCommands(connection, mJavascriptEnvironment); + } + + public void onDisconnect() throws Exception { + } +} diff --git a/android/plugins/console/JavascriptEnvironment.java b/android/plugins/console/JavascriptEnvironment.java new file mode 100644 index 000000000..7aa0177c9 --- /dev/null +++ b/android/plugins/console/JavascriptEnvironment.java @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +package com.facebook.sonar.plugins.console; + +import com.facebook.sonar.plugins.console.iface.ScriptingEnvironment; +import java.util.HashMap; +import java.util.Map; +import org.mozilla.javascript.Context; +import org.mozilla.javascript.ContextFactory; + +public class JavascriptEnvironment implements ScriptingEnvironment { + + private final Map mBoundVariables; + private final ContextFactory mContextFactory; + + public JavascriptEnvironment() { + mBoundVariables = new HashMap<>(); + mContextFactory = + new ContextFactory() { + @Override + public boolean hasFeature(Context cx, int featureIndex) { + return featureIndex == Context.FEATURE_ENHANCED_JAVA_ACCESS; + } + }; + } + + @Override + public JavascriptSession startSession() { + return new JavascriptSession(mContextFactory, mBoundVariables); + } + + /** + * Method for other plugins to register objects to a name, so that they can be accessed in all + * console sessions. + * + * @param name The variable name to bind the object to. + * @param object The reference to bind. + */ + @Override + public void registerGlobalObject(String name, Object object) { + if (mBoundVariables.containsKey(name)) { + throw new IllegalStateException( + String.format( + "Variable %s is already reserved for %s", name, mBoundVariables.get(name))); + } + mBoundVariables.put(name, object); + } + + @Override + public boolean isEnabled() { + return true; + } +} diff --git a/android/plugins/console/JavascriptSession.java b/android/plugins/console/JavascriptSession.java new file mode 100644 index 000000000..d5a46372e --- /dev/null +++ b/android/plugins/console/JavascriptSession.java @@ -0,0 +1,169 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +package com.facebook.sonar.plugins.console; + +import com.facebook.sonar.plugins.console.iface.ScriptingSession; +import java.io.Closeable; +import java.util.Map; +import java.util.concurrent.atomic.AtomicInteger; +import org.json.JSONException; +import org.json.JSONObject; +import org.json.JSONTokener; +import org.mozilla.javascript.Context; +import org.mozilla.javascript.ContextFactory; +import org.mozilla.javascript.Function; +import org.mozilla.javascript.NativeJSON; +import org.mozilla.javascript.NativeJavaMethod; +import org.mozilla.javascript.NativeJavaObject; +import org.mozilla.javascript.Scriptable; +import org.mozilla.javascript.ScriptableObject; +import org.mozilla.javascript.Undefined; + +public class JavascriptSession implements Closeable, ScriptingSession { + + private static final String TYPE = "type"; + private static final String VALUE = "value"; + public static final String JSON = "json"; + private final Context mContext; + private final ContextFactory mContextFactory; + private final Scriptable mScope; + private final AtomicInteger lineNumber = new AtomicInteger(0); + + JavascriptSession(ContextFactory contextFactory, Map globals) { + mContextFactory = contextFactory; + mContext = contextFactory.enterContext(); + + // Interpreted mode, or it will produce Dalvik incompatible bytecode. + mContext.setOptimizationLevel(-1); + mScope = mContext.initStandardObjects(); + + for (Map.Entry entry : globals.entrySet()) { + final Object value = entry.getValue(); + + if (value instanceof Number || value instanceof String) { + ScriptableObject.putConstProperty(mScope, entry.getKey(), entry.getValue()); + } else { + // Calling java methods in the VM produces objects wrapped in NativeJava*. + // So passing in wrapped objects keeps them consistent. + ScriptableObject.putConstProperty( + mScope, + entry.getKey(), + new NativeJavaObject(mScope, entry.getValue(), entry.getValue().getClass())); + } + } + } + + @Override + public JSONObject evaluateCommand(String userScript) throws JSONException { + return evaluateCommand(userScript, mScope); + } + + @Override + public JSONObject evaluateCommand(String userScript, Object context) throws JSONException { + Scriptable scope = new NativeJavaObject(mScope, context, context.getClass()); + return evaluateCommand(userScript, scope); + } + + private JSONObject evaluateCommand(String command, Scriptable scope) throws JSONException { + try { + // This may be called by any thread, and contexts have to be entered in the current thread + // before being used, so enter/exit every time. + mContextFactory.enterContext(); + return toJson( + mContext.evaluateString( + scope, command, "sonar-console", lineNumber.incrementAndGet(), null)); + } finally { + Context.exit(); + } + } + + private JSONObject toJson(Object result) throws JSONException { + + if (result instanceof String) { + return new JSONObject().put(TYPE, JSON).put(VALUE, result); + } + + if (result instanceof Class) { + return new JSONObject().put(TYPE, "class").put(VALUE, ((Class) result).getName()); + } + + if (result instanceof NativeJavaObject + && ((NativeJavaObject) result).unwrap() instanceof String) { + return new JSONObject().put(TYPE, JSON).put(VALUE, ((NativeJavaObject) result).unwrap()); + } + + if (result instanceof NativeJavaObject + && ((NativeJavaObject) result).unwrap() instanceof Class) { + return new JSONObject() + .put(TYPE, "class") + .put(VALUE, ((NativeJavaObject) result).unwrap().toString()); + } + + if (result instanceof NativeJavaObject) { + final JSONObject o = new JSONObject(); + o.put("toString", ((NativeJavaObject) result).unwrap().toString()); + for (Object id : ((NativeJavaObject) result).getIds()) { + if (id instanceof String) { + final String name = (String) id; + final Object value = ((NativeJavaObject) result).get(name, (NativeJavaObject) result); + if (value != null && value instanceof NativeJavaMethod) { + continue; + } + final String valueString = value == null ? null : safeUnwrap(value).toString(); + o.put(name, valueString); + } + } + return new JSONObject().put(TYPE, "javaObject").put(VALUE, o); + } + + if (result instanceof NativeJavaMethod) { + final JSONObject o = new JSONObject(); + o.put(TYPE, "method"); + o.put("name", ((NativeJavaMethod) result).getFunctionName()); + return o; + } + + if (result == null || result instanceof Undefined) { + return new JSONObject().put(TYPE, "null"); + } + + if (result instanceof Function) { + final JSONObject o = new JSONObject(); + o.put(TYPE, "function"); + o.put(VALUE, Context.toString(result)); + return o; + } + + if (result instanceof ScriptableObject) { + return new JSONObject() + .put(TYPE, JSON) + .put( + VALUE, + new JSONTokener(NativeJSON.stringify(mContext, mScope, result, null, null).toString()) + .nextValue()); + } + + if (result instanceof Number) { + return new JSONObject().put(TYPE, JSON).put(VALUE, result); + } + + return new JSONObject().put(TYPE, "unknown").put(VALUE, result.toString()); + } + + @Override + public void close() { + Context.exit(); + } + + private static Object safeUnwrap(Object o) { + if (o instanceof NativeJavaObject) { + return ((NativeJavaObject) o).unwrap(); + } + return o; + } +} diff --git a/android/plugins/console/iface/ConsoleCommandReceiver.java b/android/plugins/console/iface/ConsoleCommandReceiver.java new file mode 100644 index 000000000..1d28d81b6 --- /dev/null +++ b/android/plugins/console/iface/ConsoleCommandReceiver.java @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +package com.facebook.sonar.plugins.console.iface; + +import android.support.annotation.Nullable; +import com.facebook.sonar.core.SonarConnection; +import com.facebook.sonar.core.SonarObject; +import com.facebook.sonar.core.SonarReceiver; +import com.facebook.sonar.core.SonarResponder; +import com.facebook.sonar.plugins.common.MainThreadSonarReceiver; +import org.json.JSONObject; + +/** + * Convenience class for adding console execution to a Sonar Plugin. Calling {@link + * ConsoleCommandReceiver#listenForCommands(SonarConnection, ScriptingEnvironment, ContextProvider)} + * will add the necessary listeners for responding to command execution calls. + */ +public class ConsoleCommandReceiver { + + /** + * Incoming command execution calls may reference a context ID that means something to your + * plugin. Implement {@link ContextProvider} to provide a mapping from context ID to java object. + * This will allow your sonar plugin to control the execution context of the command. + */ + public interface ContextProvider { + @Nullable + Object getObjectForId(String id); + } + + public static void listenForCommands( + final SonarConnection connection, + final ScriptingEnvironment scriptingEnvironment, + final ContextProvider contextProvider) { + + final ScriptingSession session = scriptingEnvironment.startSession(); + final SonarReceiver executeCommandReceiver = + new MainThreadSonarReceiver(connection) { + @Override + public void onReceiveOnMainThread(SonarObject params, SonarResponder responder) + throws Exception { + final String command = params.getString("command"); + final String contextObjectId = params.getString("context"); + final Object contextObject = contextProvider.getObjectForId(contextObjectId); + try { + JSONObject o = + contextObject == null + ? session.evaluateCommand(command) + : session.evaluateCommand(command, contextObject); + responder.success(new SonarObject(o)); + } catch (Exception e) { + responder.error(new SonarObject.Builder().put("message", e.getMessage()).build()); + } + } + }; + final SonarReceiver isEnabledReceiver = + new SonarReceiver() { + @Override + public void onReceive(SonarObject params, SonarResponder responder) throws Exception { + responder.success( + new SonarObject.Builder() + .put("isEnabled", scriptingEnvironment.isEnabled()) + .build()); + } + }; + + connection.receive("executeCommand", executeCommandReceiver); + connection.receive("isConsoleEnabled", isEnabledReceiver); + } + + public static void listenForCommands( + SonarConnection connection, ScriptingEnvironment scriptingEnvironment) { + listenForCommands(connection, scriptingEnvironment, nullContextProvider); + } + + private static final ContextProvider nullContextProvider = + new ContextProvider() { + @Override + @Nullable + public Object getObjectForId(String id) { + return null; + } + }; +} diff --git a/android/plugins/console/iface/NullScriptingEnvironment.java b/android/plugins/console/iface/NullScriptingEnvironment.java new file mode 100644 index 000000000..940893e22 --- /dev/null +++ b/android/plugins/console/iface/NullScriptingEnvironment.java @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +package com.facebook.sonar.plugins.console.iface; + +import org.json.JSONException; +import org.json.JSONObject; + +public class NullScriptingEnvironment implements ScriptingEnvironment { + + @Override + public ScriptingSession startSession() { + return new NoOpScriptingSession(); + } + + @Override + public void registerGlobalObject(String name, Object object) {} + + static class NoOpScriptingSession implements ScriptingSession { + + @Override + public JSONObject evaluateCommand(String userScript) throws JSONException { + throw new UnsupportedOperationException("Console plugin not enabled in this app"); + } + + @Override + public JSONObject evaluateCommand(String userScript, Object context) throws JSONException { + return evaluateCommand(userScript); + } + + @Override + public void close() {} + } + + @Override + public boolean isEnabled() { + return false; + } +} diff --git a/android/plugins/console/iface/ScriptingEnvironment.java b/android/plugins/console/iface/ScriptingEnvironment.java new file mode 100644 index 000000000..3f5c8c17f --- /dev/null +++ b/android/plugins/console/iface/ScriptingEnvironment.java @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +package com.facebook.sonar.plugins.console.iface; + +public interface ScriptingEnvironment { + + ScriptingSession startSession(); + + void registerGlobalObject(String name, Object object); + + boolean isEnabled(); +} diff --git a/android/plugins/console/iface/ScriptingSession.java b/android/plugins/console/iface/ScriptingSession.java new file mode 100644 index 000000000..89b37d165 --- /dev/null +++ b/android/plugins/console/iface/ScriptingSession.java @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +package com.facebook.sonar.plugins.console.iface; + +import org.json.JSONException; +import org.json.JSONObject; + +public interface ScriptingSession { + + JSONObject evaluateCommand(String userScript) throws JSONException; + + JSONObject evaluateCommand(String userScript, Object context) throws JSONException; + + void close(); +} diff --git a/android/plugins/inspector/ApplicationWrapper.java b/android/plugins/inspector/ApplicationWrapper.java new file mode 100644 index 000000000..c3137d736 --- /dev/null +++ b/android/plugins/inspector/ApplicationWrapper.java @@ -0,0 +1,128 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ + +package com.facebook.sonar.plugins.inspector; + +import android.app.Activity; +import android.app.Application; +import android.os.Bundle; +import android.os.Handler; +import android.os.Looper; +import android.view.View; +import com.facebook.sonar.plugins.inspector.descriptors.utils.AndroidRootResolver; +import com.facebook.sonar.plugins.inspector.descriptors.utils.AndroidRootResolver.Root; +import java.lang.ref.WeakReference; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; + +public class ApplicationWrapper implements Application.ActivityLifecycleCallbacks { + + public interface ActivityStackChangedListener { + void onActivityStackChanged(List stack); + } + + private final Application mApplication; + private final AndroidRootResolver mAndroidRootsResolver; + private final List> mActivities; + private final Handler mHandler; + private ActivityStackChangedListener mListener; + + public ApplicationWrapper(Application application) { + mApplication = application; + mAndroidRootsResolver = new AndroidRootResolver(); + mApplication.registerActivityLifecycleCallbacks(this); + mActivities = new ArrayList<>(); + mHandler = new Handler(Looper.getMainLooper()); + } + + @Override + public void onActivityCreated(Activity activity, Bundle savedInstanceState) { + mActivities.add(new WeakReference<>(activity)); + notifyListener(); + } + + @Override + public void onActivityStarted(Activity activity) {} + + @Override + public void onActivityResumed(Activity activity) {} + + @Override + public void onActivityPaused(Activity activity) { + if (activity.isFinishing()) { + final Iterator> activityIterator = mActivities.iterator(); + + while (activityIterator.hasNext()) { + if (activityIterator.next().get() == activity) { + activityIterator.remove(); + } + } + + notifyListener(); + } + } + + @Override + public void onActivityStopped(Activity activity) {} + + @Override + public void onActivitySaveInstanceState(Activity activity, Bundle outState) {} + + @Override + public void onActivityDestroyed(Activity activity) {} + + private void notifyListener() { + if (mListener != null) { + mListener.onActivityStackChanged(getActivityStack()); + } + } + + public void setListener(ActivityStackChangedListener listener) { + mListener = listener; + } + + public Application getApplication() { + return mApplication; + } + + public List getActivityStack() { + final List activities = new ArrayList<>(mActivities.size()); + final Iterator> activityIterator = mActivities.iterator(); + + while (activityIterator.hasNext()) { + final Activity activity = activityIterator.next().get(); + if (activity == null) { + activityIterator.remove(); + } else { + activities.add(activity); + } + } + + return activities; + } + + public List getViewRoots() { + final List roots = mAndroidRootsResolver.listActiveRoots(); + if (roots == null) { + return Collections.EMPTY_LIST; + } + + final List viewRoots = new ArrayList<>(roots.size()); + for (Root root : roots) { + viewRoots.add(root.view); + } + + return viewRoots; + } + + public void postDelayed(Runnable r, long delayMillis) { + mHandler.postDelayed(r, delayMillis); + } +} diff --git a/android/plugins/inspector/BoundsDrawable.java b/android/plugins/inspector/BoundsDrawable.java new file mode 100644 index 000000000..01c2ebd8b --- /dev/null +++ b/android/plugins/inspector/BoundsDrawable.java @@ -0,0 +1,175 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ + +package com.facebook.sonar.plugins.inspector; + +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.ColorFilter; +import android.graphics.Paint; +import android.graphics.PixelFormat; +import android.graphics.Rect; +import android.graphics.Region; +import android.graphics.drawable.Drawable; +import android.text.TextPaint; +import javax.annotation.Nullable; + +public class BoundsDrawable extends Drawable { + public static final int COLOR_HIGHLIGHT_CONTENT = 0x888875c5; + public static final int COLOR_HIGHLIGHT_PADDING = 0x889dd185; + public static final int COLOR_HIGHLIGHT_MARGIN = 0x88f7b77b; + private static @Nullable BoundsDrawable sInstance; + + private final TextPaint mTextPaint; + private final Paint mMarginPaint; + private final Paint mPaddingPaint; + private final Paint mContentPaint; + private final Rect mWorkRect; + private final Rect mMarginBounds; + private final Rect mPaddingBounds; + private final Rect mContentBounds; + + private final int mStrokeWidth; + private final float mAscentOffset; + private final float mDensity; + + public static BoundsDrawable getInstance( + float density, Rect marginBounds, Rect paddingBounds, Rect contentBounds) { + final BoundsDrawable drawable = getInstance(density); + drawable.setBounds(marginBounds, paddingBounds, contentBounds); + return drawable; + } + + public static BoundsDrawable getInstance(float density) { + if (sInstance == null) { + sInstance = new BoundsDrawable(density); + } + return sInstance; + } + + private BoundsDrawable(float density) { + mWorkRect = new Rect(); + mMarginBounds = new Rect(); + mPaddingBounds = new Rect(); + mContentBounds = new Rect(); + + mDensity = density; + + mTextPaint = new TextPaint(); + mTextPaint.setAntiAlias(true); + mTextPaint.setTextAlign(Paint.Align.CENTER); + mTextPaint.setTextSize(dpToPx(8f)); + mAscentOffset = -mTextPaint.ascent() / 2f; + mStrokeWidth = dpToPx(2f); + + mPaddingPaint = new Paint(); + mPaddingPaint.setStyle(Paint.Style.FILL); + mPaddingPaint.setColor(COLOR_HIGHLIGHT_PADDING); + + mContentPaint = new Paint(); + mContentPaint.setStyle(Paint.Style.FILL); + mContentPaint.setColor(COLOR_HIGHLIGHT_CONTENT); + + mMarginPaint = new Paint(); + mMarginPaint.setStyle(Paint.Style.FILL); + mMarginPaint.setColor(COLOR_HIGHLIGHT_MARGIN); + } + + public void setBounds(Rect marginBounds, Rect paddingBounds, Rect contentBounds) { + mMarginBounds.set(marginBounds); + mPaddingBounds.set(paddingBounds); + mContentBounds.set(contentBounds); + setBounds(marginBounds); + } + + @Override + public void draw(Canvas canvas) { + canvas.drawRect(mContentBounds, mContentPaint); + + int saveCount = canvas.save(); + canvas.clipRect(mContentBounds, Region.Op.DIFFERENCE); + canvas.drawRect(mPaddingBounds, mPaddingPaint); + canvas.restoreToCount(saveCount); + + saveCount = canvas.save(); + canvas.clipRect(mPaddingBounds, Region.Op.DIFFERENCE); + canvas.drawRect(mMarginBounds, mMarginPaint); + canvas.restoreToCount(saveCount); + + drawBoundsDimensions(canvas, mContentBounds); + + // Disabled for now since Sonar doesn't support options too well at this point in time. + // Once options are supported, we should re-enable the calls below + // drawCardinalDimensionsBetween(canvas, mContentBounds, mPaddingBounds); + // drawCardinalDimensionsBetween(canvas, mPaddingBounds, mMarginBounds); + } + + @Override + public void setAlpha(int alpha) { + // No-op + } + + @Override + public void setColorFilter(ColorFilter colorFilter) { + // No-op + } + + @Override + public int getOpacity() { + return PixelFormat.TRANSLUCENT; + } + + private void drawCardinalDimensionsBetween(Canvas canvas, Rect inner, Rect outer) { + mWorkRect.set(inner); + mWorkRect.left = outer.left; + mWorkRect.right = inner.left; + drawBoundsDimension(canvas, mWorkRect, mWorkRect.width()); + mWorkRect.left = inner.right; + mWorkRect.right = outer.right; + drawBoundsDimension(canvas, mWorkRect, mWorkRect.width()); + mWorkRect.set(outer); + mWorkRect.bottom = inner.top; + drawBoundsDimension(canvas, mWorkRect, mWorkRect.height()); + mWorkRect.bottom = outer.bottom; + mWorkRect.top = inner.bottom; + drawBoundsDimension(canvas, mWorkRect, mWorkRect.height()); + } + + private void drawBoundsDimension(Canvas canvas, Rect bounds, int value) { + if (value <= 0) { + return; + } + int saveCount = canvas.save(); + canvas.translate(bounds.centerX(), bounds.centerY()); + drawOutlinedText(canvas, value + "px"); + canvas.restoreToCount(saveCount); + } + + private void drawBoundsDimensions(Canvas canvas, Rect bounds) { + int saveCount = canvas.save(); + canvas.translate(bounds.centerX(), bounds.centerY()); + drawOutlinedText(canvas, bounds.width() + "px \u00D7 " + bounds.height() + "px"); + canvas.restoreToCount(saveCount); + } + + private void drawOutlinedText(Canvas canvas, String text) { + mTextPaint.setColor(Color.BLACK); + mTextPaint.setStrokeWidth(mStrokeWidth); + mTextPaint.setStyle(Paint.Style.STROKE); + canvas.drawText(text, 0f, mAscentOffset, mTextPaint); + + mTextPaint.setColor(Color.WHITE); + mTextPaint.setStrokeWidth(0f); + mTextPaint.setStyle(Paint.Style.FILL); + canvas.drawText(text, 0f, mAscentOffset, mTextPaint); + } + + private int dpToPx(float dp) { + return (int) (dp * mDensity); + } +} diff --git a/android/plugins/inspector/DescriptorMapping.java b/android/plugins/inspector/DescriptorMapping.java new file mode 100644 index 000000000..cdf906570 --- /dev/null +++ b/android/plugins/inspector/DescriptorMapping.java @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ + +package com.facebook.sonar.plugins.inspector; + +import android.app.Activity; +import android.app.Dialog; +import android.graphics.drawable.Drawable; +import android.view.View; +import android.view.ViewGroup; +import android.view.Window; +import android.widget.TextView; +import com.facebook.sonar.core.SonarConnection; +import com.facebook.sonar.plugins.inspector.descriptors.ActivityDescriptor; +import com.facebook.sonar.plugins.inspector.descriptors.ApplicationDescriptor; +import com.facebook.sonar.plugins.inspector.descriptors.DialogDescriptor; +import com.facebook.sonar.plugins.inspector.descriptors.DialogFragmentDescriptor; +import com.facebook.sonar.plugins.inspector.descriptors.DrawableDescriptor; +import com.facebook.sonar.plugins.inspector.descriptors.FragmentDescriptor; +import com.facebook.sonar.plugins.inspector.descriptors.ObjectDescriptor; +import com.facebook.sonar.plugins.inspector.descriptors.SupportDialogFragmentDescriptor; +import com.facebook.sonar.plugins.inspector.descriptors.SupportFragmentDescriptor; +import com.facebook.sonar.plugins.inspector.descriptors.TextViewDescriptor; +import com.facebook.sonar.plugins.inspector.descriptors.ViewDescriptor; +import com.facebook.sonar.plugins.inspector.descriptors.ViewGroupDescriptor; +import com.facebook.sonar.plugins.inspector.descriptors.WindowDescriptor; +import java.util.HashMap; +import java.util.Map; + +/** + * A mapping from classes to the object use to describe instances of a class. When looking for a + * descriptor to describe an object this classs will traverse the object's class hierarchy until it + * finds a matching descriptor instance. + */ +public class DescriptorMapping { + private Map, NodeDescriptor> mMapping = new HashMap<>(); + + /** + * @return A DescriptorMapping initialized with default descriptors for java and Android classes. + */ + public static DescriptorMapping withDefaults() { + final DescriptorMapping mapping = new DescriptorMapping(); + mapping.register(Object.class, new ObjectDescriptor()); + mapping.register(ApplicationWrapper.class, new ApplicationDescriptor()); + mapping.register(Activity.class, new ActivityDescriptor()); + mapping.register(Window.class, new WindowDescriptor()); + mapping.register(ViewGroup.class, new ViewGroupDescriptor()); + mapping.register(View.class, new ViewDescriptor()); + mapping.register(TextView.class, new TextViewDescriptor()); + mapping.register(Drawable.class, new DrawableDescriptor()); + mapping.register(Dialog.class, new DialogDescriptor()); + mapping.register(android.app.Fragment.class, new FragmentDescriptor()); + mapping.register(android.support.v4.app.Fragment.class, new SupportFragmentDescriptor()); + mapping.register(android.app.DialogFragment.class, new DialogFragmentDescriptor()); + mapping.register( + android.support.v4.app.DialogFragment.class, new SupportDialogFragmentDescriptor()); + return mapping; + } + + /** Register a descriptor for a given class. */ + public void register(Class clazz, NodeDescriptor descriptor) { + mMapping.put(clazz, descriptor); + } + + NodeDescriptor descriptorForClass(Class clazz) { + while (!mMapping.containsKey(clazz)) { + clazz = clazz.getSuperclass(); + } + return mMapping.get(clazz); + } + + void onConnect(SonarConnection connection) { + for (NodeDescriptor descriptor : mMapping.values()) { + descriptor.setConnection(connection); + descriptor.setDescriptorMapping(this); + } + } + + void onDisconnect() { + for (NodeDescriptor descriptor : mMapping.values()) { + descriptor.setConnection(null); + } + } +} diff --git a/android/plugins/inspector/HiddenNode.java b/android/plugins/inspector/HiddenNode.java new file mode 100644 index 000000000..5e54f5bd9 --- /dev/null +++ b/android/plugins/inspector/HiddenNode.java @@ -0,0 +1,12 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ + +package com.facebook.sonar.plugins.inspector; + +/** Marker interface to identify nodes which should not be traversed. */ +public interface HiddenNode {} diff --git a/android/plugins/inspector/HighlightedOverlay.java b/android/plugins/inspector/HighlightedOverlay.java new file mode 100644 index 000000000..b887feee9 --- /dev/null +++ b/android/plugins/inspector/HighlightedOverlay.java @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ + +package com.facebook.sonar.plugins.inspector; + +import android.graphics.Rect; +import android.graphics.drawable.Drawable; +import android.os.Build; +import android.view.View; + +/** + * A singleton instance of a overlay drawable used for highlighting node bounds. See {@link + * NodeDescriptor#setHighlighted(Object, boolean)}. + */ +public class HighlightedOverlay { + private static final boolean VIEW_OVERLAY_SUPPORT = + Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2; + + /** + * Highlights a particular view with its content bounds, padding and margin dimensions + * + * @param targetView The view to apply the highlight on + * @param margin A {@link Rect} containing the margin values + * @param padding A {@link Rect} containing the padding values + * @param contentBounds The {@link Rect} bounds of the content, which includes padding + */ + public static void setHighlighted( + View targetView, Rect margin, Rect padding, Rect contentBounds) { + if (!VIEW_OVERLAY_SUPPORT) { + return; + } + + contentBounds.set( + contentBounds.left + padding.left, + contentBounds.top + padding.top, + contentBounds.right - padding.right, + contentBounds.bottom - padding.bottom); + + padding = enclose(padding, contentBounds); + margin = enclose(margin, padding); + + final float density = targetView.getContext().getResources().getDisplayMetrics().density; + final Drawable overlay = BoundsDrawable.getInstance(density, margin, padding, contentBounds); + targetView.getOverlay().add(overlay); + } + + public static void removeHighlight(View targetView) { + if (!VIEW_OVERLAY_SUPPORT) { + return; + } + + final float density = targetView.getContext().getResources().getDisplayMetrics().density; + final Drawable overlay = BoundsDrawable.getInstance(density); + targetView.getOverlay().remove(overlay); + } + + private static Rect enclose(Rect parent, Rect child) { + return new Rect( + child.left - parent.left, + child.top - parent.top, + child.right + parent.right, + child.bottom + parent.bottom); + } +} diff --git a/android/plugins/inspector/InspectorSonarPlugin.java b/android/plugins/inspector/InspectorSonarPlugin.java new file mode 100644 index 000000000..a502b4587 --- /dev/null +++ b/android/plugins/inspector/InspectorSonarPlugin.java @@ -0,0 +1,418 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ + +package com.facebook.sonar.plugins.inspector; + +import android.app.Application; +import android.content.Context; +import android.view.MotionEvent; +import android.view.View; +import android.view.ViewGroup; +import com.facebook.sonar.core.ErrorReportingRunnable; +import com.facebook.sonar.core.SonarArray; +import com.facebook.sonar.core.SonarConnection; +import com.facebook.sonar.core.SonarDynamic; +import com.facebook.sonar.core.SonarObject; +import com.facebook.sonar.core.SonarPlugin; +import com.facebook.sonar.core.SonarReceiver; +import com.facebook.sonar.core.SonarResponder; +import com.facebook.sonar.plugins.common.MainThreadSonarReceiver; +import com.facebook.sonar.plugins.console.iface.ConsoleCommandReceiver; +import com.facebook.sonar.plugins.console.iface.NullScriptingEnvironment; +import com.facebook.sonar.plugins.console.iface.ScriptingEnvironment; +import java.util.ArrayList; +import java.util.List; +import javax.annotation.Nullable; + +public class InspectorSonarPlugin implements SonarPlugin { + + private ApplicationWrapper mApplication; + private DescriptorMapping mDescriptorMapping; + private ObjectTracker mObjectTracker; + private ScriptingEnvironment mScriptingEnvironment; + private String mHighlightedId; + private TouchOverlayView mTouchOverlay; + private SonarConnection mConnection; + + public InspectorSonarPlugin( + Context context, + DescriptorMapping descriptorMapping, + ScriptingEnvironment scriptingEnvironment) { + this( + new ApplicationWrapper((Application) context.getApplicationContext()), + descriptorMapping, + scriptingEnvironment); + } + + public InspectorSonarPlugin(Context context, DescriptorMapping descriptorMapping) { + this(context, descriptorMapping, new NullScriptingEnvironment()); + } + + // Package visible for testing + InspectorSonarPlugin( + ApplicationWrapper wrapper, + DescriptorMapping descriptorMapping, + ScriptingEnvironment scriptingEnvironment) { + mDescriptorMapping = descriptorMapping; + + mObjectTracker = new ObjectTracker(); + mApplication = wrapper; + mScriptingEnvironment = scriptingEnvironment; + } + + @Override + public String getId() { + return "Inspector"; + } + + @Override + public void onConnect(SonarConnection connection) throws Exception { + mConnection = connection; + mDescriptorMapping.onConnect(connection); + + ConsoleCommandReceiver.listenForCommands( + connection, + mScriptingEnvironment, + new ConsoleCommandReceiver.ContextProvider() { + @Override + @Nullable + public Object getObjectForId(String id) { + return mObjectTracker.get(id); + } + }); + connection.receive("getRoot", mGetRoot); + connection.receive("getNodes", mGetNodes); + connection.receive("setData", mSetData); + connection.receive("setHighlighted", mSetHighlighted); + connection.receive("setSearchActive", mSetSearchActive); + connection.receive("getSearchResults", mGetSearchResults); + } + + @Override + public void onDisconnect() throws Exception { + if (mHighlightedId != null) { + setHighlighted(mHighlightedId, false); + mHighlightedId = null; + } + + mObjectTracker.clear(); + mDescriptorMapping.onDisconnect(); + mConnection = null; + } + + final SonarReceiver mGetRoot = + new MainThreadSonarReceiver(mConnection) { + @Override + public void onReceiveOnMainThread(SonarObject params, SonarResponder responder) + throws Exception { + responder.success(getNode(trackObject(mApplication))); + } + }; + + final SonarReceiver mGetNodes = + new MainThreadSonarReceiver(mConnection) { + @Override + public void onReceiveOnMainThread(final SonarObject params, final SonarResponder responder) + throws Exception { + final SonarArray ids = params.getArray("ids"); + final SonarArray.Builder result = new SonarArray.Builder(); + + for (int i = 0, count = ids.length(); i < count; i++) { + final String id = ids.getString(i); + final SonarObject node = getNode(id); + if (node != null) { + result.put(node); + } else { + responder.error( + new SonarObject.Builder() + .put("message", "No node with given id") + .put("id", id) + .build()); + return; + } + } + + responder.success(new SonarObject.Builder().put("elements", result).build()); + } + }; + + final SonarReceiver mSetData = + new MainThreadSonarReceiver(mConnection) { + @Override + public void onReceiveOnMainThread(final SonarObject params, SonarResponder responder) + throws Exception { + final String nodeId = params.getString("id"); + final SonarArray keyPath = params.getArray("path"); + final SonarDynamic value = params.getDynamic("value"); + + final Object obj = mObjectTracker.get(nodeId); + if (obj == null) { + return; + } + + final NodeDescriptor descriptor = descriptorForObject(obj); + if (descriptor == null) { + return; + } + + final int count = keyPath.length(); + final String[] path = new String[count]; + for (int i = 0; i < count; i++) { + path[i] = keyPath.getString(i); + } + + descriptor.setValue(obj, path, value); + } + }; + + final SonarReceiver mSetHighlighted = + new MainThreadSonarReceiver(mConnection) { + @Override + public void onReceiveOnMainThread(final SonarObject params, SonarResponder responder) + throws Exception { + final String nodeId = params.getString("id"); + + if (mHighlightedId != null) { + setHighlighted(mHighlightedId, false); + } + + if (nodeId != null) { + setHighlighted(nodeId, true); + } + + mHighlightedId = nodeId; + } + }; + + final SonarReceiver mSetSearchActive = + new MainThreadSonarReceiver(mConnection) { + @Override + public void onReceiveOnMainThread(final SonarObject params, SonarResponder responder) + throws Exception { + final boolean active = params.getBoolean("active"); + final List roots = mApplication.getViewRoots(); + + ViewGroup root = null; + for (int i = roots.size() - 1; i >= 0; i--) { + if (roots.get(i) instanceof ViewGroup) { + root = (ViewGroup) roots.get(i); + break; + } + } + + if (root != null) { + if (active) { + mTouchOverlay = new TouchOverlayView(root.getContext()); + root.addView(mTouchOverlay); + root.bringChildToFront(mTouchOverlay); + } else { + root.removeView(mTouchOverlay); + mTouchOverlay = null; + } + } + } + }; + + final SonarReceiver mGetSearchResults = + new MainThreadSonarReceiver(mConnection) { + @Override + public void onReceiveOnMainThread(SonarObject params, SonarResponder responder) + throws Exception { + final String query = params.getString("query"); + final SearchResultNode matchTree = searchTree(query.toLowerCase(), mApplication); + final SonarObject results = matchTree == null ? null : matchTree.toSonarObject(); + final SonarObject response = + new SonarObject.Builder().put("results", results).put("query", query).build(); + responder.success(response); + } + }; + + class TouchOverlayView extends View implements HiddenNode { + public TouchOverlayView(Context context) { + super(context); + setBackgroundColor(BoundsDrawable.COLOR_HIGHLIGHT_CONTENT); + } + + @Override + public boolean onTouchEvent(final MotionEvent event) { + if (event.getAction() != MotionEvent.ACTION_UP) { + return true; + } + + new ErrorReportingRunnable(mConnection) { + @Override + public void runOrThrow() throws Exception { + hitTest((int) event.getX(), (int) event.getY()); + } + }.run(); + + return true; + } + } + + void hitTest(final int touchX, final int touchY) throws Exception { + final SonarArray.Builder path = new SonarArray.Builder(); + path.put(trackObject(mApplication)); + + final Touch touch = + new Touch() { + int x = touchX; + int y = touchY; + Object node = mApplication; + + @Override + public void finish() { + mConnection.send("select", new SonarObject.Builder().put("path", path).build()); + } + + @Override + public void continueWithOffset( + final int childIndex, final int offsetX, final int offsetY) { + final Touch touch = this; + + new ErrorReportingRunnable(mConnection) { + @Override + protected void runOrThrow() throws Exception { + x -= offsetX; + y -= offsetY; + + node = assertNotNull(descriptorForObject(node).getChildAt(node, childIndex)); + path.put(trackObject(node)); + + final NodeDescriptor descriptor = descriptorForObject(node); + descriptor.hitTest(node, touch); + } + }.run(); + } + + @Override + public boolean containedIn(int l, int t, int r, int b) { + return x >= l && x <= r && y >= t && y <= b; + } + }; + + final NodeDescriptor descriptor = descriptorForObject(mApplication); + descriptor.hitTest(mApplication, touch); + } + + private void setHighlighted(final String id, final boolean highlighted) throws Exception { + final Object obj = mObjectTracker.get(id); + if (obj == null) { + return; + } + + final NodeDescriptor descriptor = descriptorForObject(obj); + if (descriptor == null) { + return; + } + + descriptor.setHighlighted(obj, highlighted); + } + + public SearchResultNode searchTree(String query, Object obj) throws Exception { + final NodeDescriptor descriptor = descriptorForObject(obj); + List childTrees = null; + boolean isMatch = descriptor.matches(query, obj); + + for (int i = 0; i < descriptor.getChildCount(obj); i++) { + Object child = descriptor.getChildAt(obj, i); + SearchResultNode childNode = searchTree(query, child); + if (childNode != null) { + if (childTrees == null) { + childTrees = new ArrayList<>(); + } + childTrees.add(childNode); + } + } + + if (isMatch || childTrees != null) { + final String id = trackObject(obj); + return new SearchResultNode(id, isMatch, getNode(id), childTrees); + } + return null; + } + + private @Nullable SonarObject getNode(String id) throws Exception { + final Object obj = mObjectTracker.get(id); + if (obj == null) { + return null; + } + + final NodeDescriptor descriptor = descriptorForObject(obj); + if (descriptor == null) { + return null; + } + + final SonarArray.Builder children = new SonarArray.Builder(); + new ErrorReportingRunnable(mConnection) { + @Override + protected void runOrThrow() throws Exception { + for (int i = 0, count = descriptor.getChildCount(obj); i < count; i++) { + final Object child = assertNotNull(descriptor.getChildAt(obj, i)); + children.put(trackObject(child)); + } + } + }.run(); + + final SonarObject.Builder data = new SonarObject.Builder(); + new ErrorReportingRunnable(mConnection) { + @Override + protected void runOrThrow() throws Exception { + for (Named props : descriptor.getData(obj)) { + data.put(props.getName(), props.getValue()); + } + } + }.run(); + + final SonarArray.Builder attributes = new SonarArray.Builder(); + new ErrorReportingRunnable(mConnection) { + @Override + protected void runOrThrow() throws Exception { + for (Named attribute : descriptor.getAttributes(obj)) { + attributes.put( + new SonarObject.Builder() + .put("name", attribute.getName()) + .put("value", attribute.getValue()) + .build()); + } + } + }.run(); + + return new SonarObject.Builder() + .put("id", descriptor.getId(obj)) + .put("name", descriptor.getName(obj)) + .put("data", data) + .put("children", children) + .put("attributes", attributes) + .put("decoration", descriptor.getDecoration(obj)) + .build(); + } + + private String trackObject(Object obj) throws Exception { + final NodeDescriptor descriptor = descriptorForObject(obj); + final String id = descriptor.getId(obj); + final Object curr = mObjectTracker.get(id); + if (obj != curr) { + mObjectTracker.put(id, obj); + descriptor.init(obj); + } + return id; + } + + private NodeDescriptor descriptorForObject(Object obj) { + final Class c = assertNotNull(obj).getClass(); + return (NodeDescriptor) mDescriptorMapping.descriptorForClass(c); + } + + private static Object assertNotNull(@Nullable Object o) { + if (o == null) { + throw new AssertionError("Unexpected null value"); + } + return o; + } +} diff --git a/android/plugins/inspector/InspectorValue.java b/android/plugins/inspector/InspectorValue.java new file mode 100644 index 000000000..15a937c36 --- /dev/null +++ b/android/plugins/inspector/InspectorValue.java @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ + +package com.facebook.sonar.plugins.inspector; + +import com.facebook.sonar.core.SonarObject; +import com.facebook.sonar.core.SonarValue; + +public class InspectorValue implements SonarValue { + + /** + * Descrive the type of data this value contains. This will influence how values are parsed and + * displayed by the Sonar desktop app. For example colors will be parse as integers and displayed + * using hex values and be editable using a color picker. + * + *

Do not extends this list of types without adding support for the type in the desktop + * Inspector. + */ + public static class Type { + + public static final Type Auto = new Type<>("auto"); + public static final Type Text = new Type<>("text"); + public static final Type Number = new Type<>("number"); + public static final Type Boolean = new Type<>("boolean"); + public static final Type Enum = new Type<>("enum"); + public static final Type Color = new Type<>("color"); + + private final String mName; + + Type(String name) { + mName = name; + } + + @Override + public String toString() { + return mName; + } + } + + final Type mType; + final T mValue; + final boolean mMutable; + + private InspectorValue(Type type, T value, boolean mutable) { + mType = type; + mValue = value; + mMutable = mutable; + } + + public static InspectorValue mutable(Type type, T value) { + return new InspectorValue<>(type, value, true); + } + + public static InspectorValue immutable(Type type, T value) { + return new InspectorValue<>(type, value, false); + } + + public static InspectorValue mutable(Object value) { + return new InspectorValue<>(Type.Auto, value, true); + } + + public static InspectorValue immutable(Object value) { + return new InspectorValue<>(Type.Auto, value, false); + } + + @Override + public SonarObject toSonarObject() { + return new SonarObject.Builder() + .put("__type__", mType) + .put("__mutable__", mMutable) + .put("value", mValue) + .build(); + } +} diff --git a/android/plugins/inspector/Named.java b/android/plugins/inspector/Named.java new file mode 100644 index 000000000..c0cda4395 --- /dev/null +++ b/android/plugins/inspector/Named.java @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ + +package com.facebook.sonar.plugins.inspector; + +public class Named { + private final String mName; + private final ValueType mValue; + + public Named(String name, ValueType value) { + mName = name; + mValue = value; + } + + public String getName() { + return mName; + } + + public ValueType getValue() { + return mValue; + } +} diff --git a/android/plugins/inspector/NodeDescriptor.java b/android/plugins/inspector/NodeDescriptor.java new file mode 100644 index 000000000..914a8f3fb --- /dev/null +++ b/android/plugins/inspector/NodeDescriptor.java @@ -0,0 +1,143 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ + +package com.facebook.sonar.plugins.inspector; + +import com.facebook.sonar.core.SonarArray; +import com.facebook.sonar.core.SonarConnection; +import com.facebook.sonar.core.SonarDynamic; +import com.facebook.sonar.core.SonarObject; +import java.util.List; + +/** + * A NodeDescriptor is an object which known how to expose an Object of type T to the ew Inspector. + * This class is the extension point for the Sonar inspector plugin and is how custom classes and + * data can be exposed to the inspector. + */ +public abstract class NodeDescriptor { + private SonarConnection mConnection; + private DescriptorMapping mDescriptorMapping; + + void setConnection(SonarConnection connection) { + mConnection = connection; + } + + void setDescriptorMapping(DescriptorMapping descriptorMapping) { + mDescriptorMapping = descriptorMapping; + } + + /** + * @return The descriptor for a given class. This is useful for when a descriptor wants to + * delegate parts of its implementation to another descriptor, say the super class of the + * object it describes. This is highly encouraged instead of subclassing another descriptor + * class. + */ + protected final NodeDescriptor descriptorForClass(Class clazz) { + return mDescriptorMapping.descriptorForClass(clazz); + } + + /** + * Invalidate a node. This tells Sonar that this node is no longer valid and its properties and/or + * children have changed. This will trigger Sonar to re-query this node getting any new data. + */ + protected final void invalidate(final T node) { + if (mConnection != null) { + new ErrorReportingRunnable() { + @Override + protected void runOrThrow() throws Exception { + SonarArray array = + new SonarArray.Builder() + .put(new SonarObject.Builder().put("id", getId(node)).build()) + .build(); + SonarObject params = new SonarObject.Builder().put("nodes", array).build(); + mConnection.send("invalidate", params); + } + }.run(); + } + } + + protected final boolean connected() { + return mConnection != null; + } + + protected abstract class ErrorReportingRunnable + extends com.facebook.sonar.core.ErrorReportingRunnable { + public ErrorReportingRunnable() { + super(mConnection); + } + } + + /** + * Initialize a node. This implementation usually consists of setting up listeners to know when to + * call {@link NodeDescriptor#invalidate(Object)}. + */ + public abstract void init(T node) throws Exception; + + /** + * A globally unique ID used to identify a node in a hierarchy. If your node does not have a + * globally unique ID it is fine to rely on {@link System#identityHashCode(Object)}. + */ + public abstract String getId(T node) throws Exception; + + /** + * The name used to identify this node in the inspector. Does not need to be unique. A good + * default is to use the class name of the node. + */ + public abstract String getName(T node) throws Exception; + + /** @return The number of children this node exposes in the inspector. */ + public abstract int getChildCount(T node) throws Exception; + + /** @return The child at index. */ + public abstract Object getChildAt(T node, int index) throws Exception; + + /** + * Get the data to show for this node in the sidebar of the inspector. The object will be showen + * in order and with a header matching the given name. + */ + public abstract List> getData(T node) throws Exception; + + /** + * Set a value on the provided node at the given path. The path will match a key path in the data + * provided by {@link this#getData(Object)} and the value will be of the same type as the value + * mathcing that path in the returned object. + */ + public abstract void setValue(T node, String[] path, SonarDynamic value) throws Exception; + + /** + * Get the attributes for this node. This is a list of read-only string:string mapping which show + * up inline in the elements inspector. See {@link Named} for more information. + */ + public abstract List> getAttributes(T node) throws Exception; + + /** + * Highlight this node. Use {@link HighlightedOverlay} if possible. This is used to highlight a + * node which is selected in the inspector. The plugin automatically takes care of de-selecting + * the previously highlighted node. + */ + public abstract void setHighlighted(T node, boolean selected) throws Exception; + + /** + * Perform hit testing on the given node. Either continue the search in a child with {@link + * Touch#continueWithOffset(int, int, int)} or finish the hit testing on this node with {@link + * Touch#finish()} + */ + public abstract void hitTest(T node, Touch touch) throws Exception; + + /** + * @return A string indicating how this element should be decorated. Check with the Sonar desktop + * app to see what values are supported. + */ + public abstract String getDecoration(T node) throws Exception; + + /** + * Test this node against a given query to see if it matches. This is used for finding search + * results. + */ + public abstract boolean matches(String query, T node) throws Exception; +} diff --git a/android/plugins/inspector/ObjectTracker.java b/android/plugins/inspector/ObjectTracker.java new file mode 100644 index 000000000..994699042 --- /dev/null +++ b/android/plugins/inspector/ObjectTracker.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ + +package com.facebook.sonar.plugins.inspector; + +import java.lang.ref.WeakReference; +import java.util.HashMap; +import java.util.Map; +import javax.annotation.Nullable; + +class ObjectTracker { + private final Map> mObjects = new HashMap<>(); + + void put(String id, Object obj) { + mObjects.put(id, new WeakReference<>(obj)); + } + + @Nullable + Object get(String id) { + final WeakReference weakObj = mObjects.get(id); + if (weakObj == null) { + return null; + } + + final Object obj = weakObj.get(); + if (obj == null) { + mObjects.remove(id); + } + + return obj; + } + + void clear() { + mObjects.clear(); + } + + boolean contains(String id) { + return mObjects.containsKey(id); + } +} diff --git a/android/plugins/inspector/SearchResultNode.java b/android/plugins/inspector/SearchResultNode.java new file mode 100644 index 000000000..2c6ef5ad4 --- /dev/null +++ b/android/plugins/inspector/SearchResultNode.java @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ + +package com.facebook.sonar.plugins.inspector; + +import android.support.annotation.Nullable; +import com.facebook.sonar.core.SonarArray; +import com.facebook.sonar.core.SonarObject; +import java.util.List; + +public class SearchResultNode { + + private final String id; + private final boolean isMatch; + private final SonarObject element; + @Nullable + private final List children; + + SearchResultNode( + String id, boolean isMatch, SonarObject element, @Nullable List children) { + this.id = id; + this.isMatch = isMatch; + this.element = element; + this.children = children; + } + + SonarObject toSonarObject() { + final SonarArray childArray; + if (children != null) { + final SonarArray.Builder builder = new SonarArray.Builder(); + for (SearchResultNode child : children) { + builder.put(child.toSonarObject()); + } + childArray = builder.build(); + } else { + childArray = null; + } + + return new SonarObject.Builder() + .put("id", this.id) + .put("isMatch", this.isMatch) + .put("element", this.element) + .put("children", childArray) + .build(); + } +} diff --git a/android/plugins/inspector/SelfRegisteringNodeDescriptor.java b/android/plugins/inspector/SelfRegisteringNodeDescriptor.java new file mode 100644 index 000000000..7095cad6a --- /dev/null +++ b/android/plugins/inspector/SelfRegisteringNodeDescriptor.java @@ -0,0 +1,14 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ + +package com.facebook.sonar.plugins.inspector; + +public abstract class SelfRegisteringNodeDescriptor extends NodeDescriptor { + + public abstract void register(DescriptorMapping descriptorMapping); +} diff --git a/android/plugins/inspector/Touch.java b/android/plugins/inspector/Touch.java new file mode 100644 index 000000000..9d44bad99 --- /dev/null +++ b/android/plugins/inspector/Touch.java @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ + +package com.facebook.sonar.plugins.inspector; + +/** + * Used to collect the path from the root node to the node at point [x, y]. This is used for + * creating a node path to the targeting node from the root when performing hit testing. + */ +public interface Touch { + + /** + * Call this when the path has reached its destination. This should be called from the descriptor + * which described the leaf node containing [x, y]. + */ + void finish(); + + /** + * Continue hit testing in child at the given index. Offseting the touch location to the child's + * coordinate system. + */ + void continueWithOffset(int childIndex, int offsetX, int offsetY); + + /** @return Whether or not this Touch is contained within the provided bounds. */ + boolean containedIn(int l, int t, int r, int b); +} diff --git a/android/plugins/inspector/descriptors/ActivityDescriptor.java b/android/plugins/inspector/descriptors/ActivityDescriptor.java new file mode 100644 index 000000000..12998afe0 --- /dev/null +++ b/android/plugins/inspector/descriptors/ActivityDescriptor.java @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ + +package com.facebook.sonar.plugins.inspector.descriptors; + +import android.app.Activity; +import android.view.Window; +import com.facebook.sonar.core.SonarDynamic; +import com.facebook.sonar.core.SonarObject; +import com.facebook.sonar.plugins.inspector.Named; +import com.facebook.sonar.plugins.inspector.NodeDescriptor; +import com.facebook.sonar.plugins.inspector.Touch; +import com.facebook.stetho.common.android.FragmentActivityAccessor; +import com.facebook.stetho.common.android.FragmentCompat; +import com.facebook.stetho.common.android.FragmentManagerAccessor; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import javax.annotation.Nullable; + +public class ActivityDescriptor extends NodeDescriptor { + + @Override + public void init(Activity node) {} + + @Override + public String getId(Activity node) { + return Integer.toString(System.identityHashCode(node)); + } + + @Override + public String getName(Activity node) { + return node.getClass().getSimpleName(); + } + + @Override + public int getChildCount(Activity node) { + return (node.getWindow() != null ? 1 : 0) + + getDialogFragments(FragmentCompat.getSupportLibInstance(), node).size() + + getDialogFragments(FragmentCompat.getFrameworkInstance(), node).size(); + } + + @Override + public Object getChildAt(Activity node, int index) { + if (node.getWindow() != null) { + if (index == 0) { + return node.getWindow(); + } else { + index--; + } + } + + final List dialogs = getDialogFragments(FragmentCompat.getSupportLibInstance(), node); + if (index < dialogs.size()) { + return dialogs.get(index); + } else { + final List supportDialogs = getDialogFragments(FragmentCompat.getFrameworkInstance(), node); + return supportDialogs.get(index - dialogs.size()); + } + } + + @Override + public List> getData(Activity node) { + return Collections.EMPTY_LIST; + } + + @Override + public void setValue(Activity node, String[] path, SonarDynamic value) throws Exception {} + + @Override + public List> getAttributes(Activity node) { + return Collections.EMPTY_LIST; + } + + @Override + public void setHighlighted(Activity node, boolean selected) throws Exception { + final NodeDescriptor descriptor = descriptorForClass(Window.class); + descriptor.setHighlighted(node.getWindow(), selected); + } + + @Override + public void hitTest(Activity node, Touch touch) { + touch.continueWithOffset(0, 0, 0); + } + + @Override + public @Nullable String getDecoration(Activity obj) { + return null; + } + + @Override + public boolean matches(String query, Activity node) throws Exception { + NodeDescriptor descriptor = descriptorForClass(Object.class); + return descriptor.matches(query, node); + } + + private static List getDialogFragments(FragmentCompat compat, Activity activity) { + if (compat == null || !compat.getFragmentActivityClass().isInstance(activity)) { + return Collections.EMPTY_LIST; + } + + FragmentActivityAccessor activityAccessor = compat.forFragmentActivity(); + Object fragmentManager = activityAccessor.getFragmentManager(activity); + if (fragmentManager == null) { + return Collections.EMPTY_LIST; + } + + FragmentManagerAccessor fragmentManagerAccessor = compat.forFragmentManager(); + List addedFragments = fragmentManagerAccessor.getAddedFragments(fragmentManager); + if (addedFragments == null) { + return Collections.EMPTY_LIST; + } + + final List dialogFragments = new ArrayList<>(); + for (int i = 0, N = addedFragments.size(); i < N; ++i) { + final Object fragment = addedFragments.get(i); + if (compat.getDialogFragmentClass().isInstance(fragment)) { + dialogFragments.add(fragment); + } + } + + return dialogFragments; + } +} diff --git a/android/plugins/inspector/descriptors/ApplicationDescriptor.java b/android/plugins/inspector/descriptors/ApplicationDescriptor.java new file mode 100644 index 000000000..00f83be34 --- /dev/null +++ b/android/plugins/inspector/descriptors/ApplicationDescriptor.java @@ -0,0 +1,161 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ + +package com.facebook.sonar.plugins.inspector.descriptors; + +import android.app.Activity; +import android.view.View; +import android.view.ViewGroup; +import com.facebook.sonar.core.SonarDynamic; +import com.facebook.sonar.core.SonarObject; +import com.facebook.sonar.plugins.inspector.ApplicationWrapper; +import com.facebook.sonar.plugins.inspector.Named; +import com.facebook.sonar.plugins.inspector.NodeDescriptor; +import com.facebook.sonar.plugins.inspector.Touch; +import java.util.Collections; +import java.util.List; +import javax.annotation.Nullable; + +public class ApplicationDescriptor extends NodeDescriptor { + + private class NodeKey { + private int[] mKey; + + boolean set(ApplicationWrapper node) { + final List roots = node.getViewRoots(); + final int childCount = roots.size(); + final int[] key = new int[childCount]; + + for (int i = 0; i < childCount; i++) { + final View child = roots.get(i); + key[i] = System.identityHashCode(child); + } + + boolean changed = false; + if (mKey == null) { + changed = true; + } else if (mKey.length != key.length) { + changed = true; + } else { + for (int i = 0; i < childCount; i++) { + if (mKey[i] != key[i]) { + changed = true; + break; + } + } + } + + mKey = key; + return changed; + } + } + + @Override + public void init(final ApplicationWrapper node) { + node.setListener( + new ApplicationWrapper.ActivityStackChangedListener() { + @Override + public void onActivityStackChanged(List stack) { + invalidate(node); + } + }); + + final NodeKey key = new NodeKey(); + final Runnable maybeInvalidate = + new NodeDescriptor.ErrorReportingRunnable() { + @Override + public void runOrThrow() throws Exception { + if (connected()) { + if (key.set(node)) { + invalidate(node); + } + node.postDelayed(this, 1000); + } + } + }; + + node.postDelayed(maybeInvalidate, 1000); + } + + @Override + public String getId(ApplicationWrapper node) { + return node.getApplication().getPackageName(); + } + + @Override + public String getName(ApplicationWrapper node) { + return node.getApplication().getPackageName(); + } + + @Override + public int getChildCount(ApplicationWrapper node) { + return node.getViewRoots().size(); + } + + @Override + public Object getChildAt(ApplicationWrapper node, int index) { + final View view = node.getViewRoots().get(index); + + for (Activity activity : node.getActivityStack()) { + if (activity.getWindow().getDecorView() == view) { + return activity; + } + } + + return view; + } + + @Override + public List> getData(ApplicationWrapper node) { + return Collections.EMPTY_LIST; + } + + @Override + public void setValue(ApplicationWrapper node, String[] path, SonarDynamic value) {} + + @Override + public List> getAttributes(ApplicationWrapper node) { + return Collections.EMPTY_LIST; + } + + @Override + public void setHighlighted(ApplicationWrapper node, boolean selected) throws Exception { + final int childCount = getChildCount(node); + if (childCount > 0) { + final Object topChild = getChildAt(node, childCount - 1); + final NodeDescriptor descriptor = descriptorForClass(topChild.getClass()); + descriptor.setHighlighted(topChild, selected); + } + } + + @Override + public void hitTest(ApplicationWrapper node, Touch touch) { + final int childCount = getChildCount(node); + + for (int i = childCount - 1; i >= 0; i--) { + final Object child = getChildAt(node, i); + if (child instanceof Activity || child instanceof ViewGroup) { + touch.continueWithOffset(i, 0, 0); + return; + } + } + + touch.finish(); + } + + @Override + public @Nullable String getDecoration(ApplicationWrapper obj) { + return null; + } + + @Override + public boolean matches(String query, ApplicationWrapper node) throws Exception { + NodeDescriptor descriptor = descriptorForClass(Object.class); + return descriptor.matches(query, node); + } +} diff --git a/android/plugins/inspector/descriptors/DialogDescriptor.java b/android/plugins/inspector/descriptors/DialogDescriptor.java new file mode 100644 index 000000000..4e16cc21a --- /dev/null +++ b/android/plugins/inspector/descriptors/DialogDescriptor.java @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ + +package com.facebook.sonar.plugins.inspector.descriptors; + +import android.app.Dialog; +import android.view.Window; +import com.facebook.sonar.core.SonarDynamic; +import com.facebook.sonar.core.SonarObject; +import com.facebook.sonar.plugins.inspector.Named; +import com.facebook.sonar.plugins.inspector.NodeDescriptor; +import com.facebook.sonar.plugins.inspector.Touch; +import java.util.Collections; +import java.util.List; +import javax.annotation.Nullable; + +public class DialogDescriptor extends NodeDescriptor { + + @Override + public void init(Dialog node) {} + + @Override + public String getId(Dialog node) { + return Integer.toString(System.identityHashCode(node)); + } + + @Override + public String getName(Dialog node) { + return node.getClass().getSimpleName(); + } + + @Override + public int getChildCount(Dialog node) { + return node.getWindow() == null ? 0 : 1; + } + + @Override + public Object getChildAt(Dialog node, int index) { + return node.getWindow(); + } + + @Override + public List> getData(Dialog node) { + return Collections.EMPTY_LIST; + } + + @Override + public void setValue(Dialog node, String[] path, SonarDynamic value) {} + + @Override + public List> getAttributes(Dialog node) { + return Collections.EMPTY_LIST; + } + + @Override + public void setHighlighted(Dialog node, boolean selected) throws Exception { + final NodeDescriptor descriptor = descriptorForClass(Window.class); + descriptor.setHighlighted(node.getWindow(), selected); + } + + @Override + public void hitTest(Dialog node, Touch touch) { + touch.continueWithOffset(0, 0, 0); + } + + @Override + public @Nullable String getDecoration(Dialog obj) { + return null; + } + + @Override + public boolean matches(String query, Dialog node) throws Exception { + NodeDescriptor descriptor = descriptorForClass(Object.class); + return descriptor.matches(query, node); + } +} diff --git a/android/plugins/inspector/descriptors/DialogFragmentDescriptor.java b/android/plugins/inspector/descriptors/DialogFragmentDescriptor.java new file mode 100644 index 000000000..fbc6d04a9 --- /dev/null +++ b/android/plugins/inspector/descriptors/DialogFragmentDescriptor.java @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ + +package com.facebook.sonar.plugins.inspector.descriptors; + +import android.app.Dialog; +import android.app.DialogFragment; +import android.app.Fragment; +import com.facebook.sonar.core.SonarDynamic; +import com.facebook.sonar.core.SonarObject; +import com.facebook.sonar.plugins.inspector.Named; +import com.facebook.sonar.plugins.inspector.NodeDescriptor; +import com.facebook.sonar.plugins.inspector.Touch; +import java.util.List; +import javax.annotation.Nullable; + +public class DialogFragmentDescriptor extends NodeDescriptor { + + @Override + public void init(DialogFragment node) {} + + @Override + public String getId(DialogFragment node) throws Exception { + final NodeDescriptor descriptor = descriptorForClass(Fragment.class); + return descriptor.getId(node); + } + + @Override + public String getName(DialogFragment node) throws Exception { + final NodeDescriptor descriptor = descriptorForClass(Fragment.class); + return descriptor.getName(node); + } + + @Override + public int getChildCount(DialogFragment node) { + return node.getDialog() == null ? 0 : 1; + } + + @Override + public Object getChildAt(DialogFragment node, int index) { + return node.getDialog(); + } + + @Override + public List> getData(DialogFragment node) throws Exception { + final NodeDescriptor descriptor = descriptorForClass(Fragment.class); + return descriptor.getData(node); + } + + @Override + public void setValue(DialogFragment node, String[] path, SonarDynamic value) throws Exception { + final NodeDescriptor descriptor = descriptorForClass(Fragment.class); + descriptor.setValue(node, path, value); + } + + @Override + public List> getAttributes(DialogFragment node) throws Exception { + final NodeDescriptor descriptor = descriptorForClass(Fragment.class); + return descriptor.getAttributes(node); + } + + @Override + public void setHighlighted(DialogFragment node, boolean selected) throws Exception { + final NodeDescriptor descriptor = descriptorForClass(Dialog.class); + if (node.getDialog() != null) { + descriptor.setHighlighted(node.getDialog(), selected); + } + } + + @Override + public void hitTest(DialogFragment node, Touch touch) { + touch.continueWithOffset(0, 0, 0); + } + + @Override + public @Nullable String getDecoration(DialogFragment obj) { + return null; + } + + @Override + public boolean matches(String query, DialogFragment node) throws Exception { + NodeDescriptor descriptor = descriptorForClass(Object.class); + return descriptor.matches(query, node); + } +} diff --git a/android/plugins/inspector/descriptors/DrawableDescriptor.java b/android/plugins/inspector/descriptors/DrawableDescriptor.java new file mode 100644 index 000000000..eaba20d4b --- /dev/null +++ b/android/plugins/inspector/descriptors/DrawableDescriptor.java @@ -0,0 +1,146 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ + +package com.facebook.sonar.plugins.inspector.descriptors; + +import android.graphics.Rect; +import android.graphics.drawable.Drawable; +import android.os.Build; +import android.view.View; +import com.facebook.sonar.core.SonarDynamic; +import com.facebook.sonar.core.SonarObject; +import com.facebook.sonar.plugins.inspector.HighlightedOverlay; +import com.facebook.sonar.plugins.inspector.InspectorValue; +import com.facebook.sonar.plugins.inspector.Named; +import com.facebook.sonar.plugins.inspector.NodeDescriptor; +import com.facebook.sonar.plugins.inspector.Touch; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import javax.annotation.Nullable; + +public class DrawableDescriptor extends NodeDescriptor { + + @Override + public void init(Drawable node) {} + + @Override + public String getId(Drawable node) { + return Integer.toString(System.identityHashCode(node)); + } + + @Override + public String getName(Drawable node) { + return node.getClass().getSimpleName(); + } + + @Override + public int getChildCount(Drawable node) { + return 0; + } + + @Override + public @Nullable Object getChildAt(Drawable node, int index) { + return null; + } + + @Override + public List> getData(Drawable node) { + final SonarObject.Builder props = new SonarObject.Builder(); + final Rect bounds = node.getBounds(); + + props.put("left", InspectorValue.mutable(bounds.left)); + props.put("top", InspectorValue.mutable(bounds.top)); + props.put("right", InspectorValue.mutable(bounds.right)); + props.put("bottom", InspectorValue.mutable(bounds.bottom)); + + if (hasAlphaSupport()) { + props.put("alpha", InspectorValue.mutable(node.getAlpha())); + } + + return Arrays.asList(new Named<>("Drawable", props.build())); + } + + @Override + public void setValue(Drawable node, String[] path, SonarDynamic value) { + final Rect bounds = node.getBounds(); + + switch (path[0]) { + case "Drawable": + switch (path[1]) { + case "left": + bounds.left = value.asInt(); + node.setBounds(bounds); + break; + case "top": + bounds.top = value.asInt(); + node.setBounds(bounds); + break; + case "right": + bounds.right = value.asInt(); + node.setBounds(bounds); + break; + case "bottom": + bounds.bottom = value.asInt(); + node.setBounds(bounds); + break; + case "alpha": + node.setAlpha(value.asInt()); + break; + } + break; + } + } + + private static boolean hasAlphaSupport() { + return Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT; + } + + @Override + public List> getAttributes(Drawable node) { + return Collections.EMPTY_LIST; + } + + @Override + public void setHighlighted(Drawable node, boolean selected) { + // Ensure we handle wrapping drawable + Drawable.Callback callbacks = node.getCallback(); + while (callbacks instanceof Drawable) { + callbacks = ((Drawable) callbacks).getCallback(); + } + + if (!(callbacks instanceof View)) { + return; + } + + final View callbackView = (View) callbacks; + if (selected) { + final Rect zero = new Rect(); + final Rect bounds = node.getBounds(); + HighlightedOverlay.setHighlighted(callbackView, zero, zero, bounds); + } else { + HighlightedOverlay.removeHighlight(callbackView); + } + } + + @Override + public void hitTest(Drawable node, Touch touch) { + touch.finish(); + } + + @Override + public @Nullable String getDecoration(Drawable obj) { + return null; + } + + @Override + public boolean matches(String query, Drawable node) throws Exception { + NodeDescriptor descriptor = descriptorForClass(Object.class); + return descriptor.matches(query, node); + } +} diff --git a/android/plugins/inspector/descriptors/FragmentDescriptor.java b/android/plugins/inspector/descriptors/FragmentDescriptor.java new file mode 100644 index 000000000..5f05bdb26 --- /dev/null +++ b/android/plugins/inspector/descriptors/FragmentDescriptor.java @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ + +package com.facebook.sonar.plugins.inspector.descriptors; + +import android.app.Fragment; +import android.os.Bundle; +import android.view.View; +import com.facebook.sonar.core.SonarDynamic; +import com.facebook.sonar.core.SonarObject; +import com.facebook.sonar.plugins.inspector.Named; +import com.facebook.sonar.plugins.inspector.NodeDescriptor; +import com.facebook.sonar.plugins.inspector.Touch; +import com.facebook.stetho.common.android.ResourcesUtil; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import javax.annotation.Nullable; + +public class FragmentDescriptor extends NodeDescriptor { + + @Override + public void init(Fragment node) {} + + @Override + public String getId(Fragment node) { + return Integer.toString(System.identityHashCode(node)); + } + + @Override + public String getName(Fragment node) { + return node.getClass().getSimpleName(); + } + + @Override + public int getChildCount(Fragment node) { + return node.getView() == null ? 0 : 1; + } + + @Override + public Object getChildAt(Fragment node, int index) { + return node.getView(); + } + + @Override + public List> getData(Fragment node) { + final Bundle args = node.getArguments(); + if (args == null || args.isEmpty()) { + return Collections.EMPTY_LIST; + } + + final SonarObject.Builder bundle = new SonarObject.Builder(); + + for (String key : args.keySet()) { + bundle.put(key, args.get(key)); + } + + return Arrays.asList(new Named<>("Arguments", bundle.build())); + } + + @Override + public void setValue(Fragment node, String[] path, SonarDynamic value) {} + + @Override + public List> getAttributes(Fragment node) { + final String resourceId = getResourceId(node); + + if (resourceId == null) { + return Collections.EMPTY_LIST; + } + + return Arrays.asList(new Named<>("id", resourceId)); + } + + @Nullable + private static String getResourceId(Fragment node) { + final int id = node.getId(); + + if (id == View.NO_ID || node.getHost() == null) { + return null; + } + + return ResourcesUtil.getIdStringQuietly(node.getContext(), node.getResources(), id); + } + + @Override + public void setHighlighted(Fragment node, boolean selected) throws Exception { + if (node.getView() == null) { + return; + } + + final NodeDescriptor descriptor = descriptorForClass(View.class); + descriptor.setHighlighted(node.getView(), selected); + } + + @Override + public void hitTest(Fragment node, Touch touch) { + touch.continueWithOffset(0, 0, 0); + } + + @Override + public @Nullable String getDecoration(Fragment obj) { + return null; + } + + @Override + public boolean matches(String query, Fragment node) throws Exception { + final String resourceId = getResourceId(node); + + if (resourceId != null) { + if (resourceId.toLowerCase().contains(query)) { + return true; + } + } + + final NodeDescriptor objectDescriptor = descriptorForClass(Object.class); + return objectDescriptor.matches(query, node); + } +} diff --git a/android/plugins/inspector/descriptors/ObjectDescriptor.java b/android/plugins/inspector/descriptors/ObjectDescriptor.java new file mode 100644 index 000000000..8a8d42fec --- /dev/null +++ b/android/plugins/inspector/descriptors/ObjectDescriptor.java @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ + +package com.facebook.sonar.plugins.inspector.descriptors; + +import com.facebook.sonar.core.SonarDynamic; +import com.facebook.sonar.core.SonarObject; +import com.facebook.sonar.plugins.inspector.Named; +import com.facebook.sonar.plugins.inspector.NodeDescriptor; +import com.facebook.sonar.plugins.inspector.Touch; +import java.util.Collections; +import java.util.List; +import javax.annotation.Nullable; + +public class ObjectDescriptor extends NodeDescriptor { + + @Override + public void init(Object node) {} + + @Override + public String getId(Object node) { + return Integer.toString(System.identityHashCode(node)); + } + + @Override + public String getName(Object node) { + return node.getClass().getName(); + } + + @Override + public int getChildCount(Object node) { + return 0; + } + + @Override + public @Nullable Object getChildAt(Object node, int index) { + return null; + } + + @Override + public List> getData(Object node) { + return Collections.EMPTY_LIST; + } + + @Override + public void setValue(Object node, String[] path, SonarDynamic value) {} + + @Override + public List> getAttributes(Object node) { + return Collections.EMPTY_LIST; + } + + @Override + public void setHighlighted(Object node, boolean selected) {} + + @Override + public void hitTest(Object node, Touch touch) { + touch.finish(); + } + + @Override + public @Nullable String getDecoration(Object obj) { + return null; + } + + @Override + public boolean matches(String query, Object node) throws Exception { + final NodeDescriptor descriptor = descriptorForClass(node.getClass()); + final List> attributes = descriptor.getAttributes(node); + for (Named namedString : attributes) { + if (namedString.getName().equals("id")) { + if (namedString.getValue().toLowerCase().contains(query)) { + return true; + } + } + } + + return descriptor.getName(node).toLowerCase().contains(query); + } +} diff --git a/android/plugins/inspector/descriptors/SupportDialogFragmentDescriptor.java b/android/plugins/inspector/descriptors/SupportDialogFragmentDescriptor.java new file mode 100644 index 000000000..71ccb8496 --- /dev/null +++ b/android/plugins/inspector/descriptors/SupportDialogFragmentDescriptor.java @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ + +package com.facebook.sonar.plugins.inspector.descriptors; + +import android.app.Dialog; +import android.support.v4.app.DialogFragment; +import android.support.v4.app.Fragment; +import com.facebook.sonar.core.SonarDynamic; +import com.facebook.sonar.core.SonarObject; +import com.facebook.sonar.plugins.inspector.Named; +import com.facebook.sonar.plugins.inspector.NodeDescriptor; +import com.facebook.sonar.plugins.inspector.Touch; +import java.util.List; +import javax.annotation.Nullable; + +public class SupportDialogFragmentDescriptor extends NodeDescriptor { + + @Override + public void init(DialogFragment node) {} + + @Override + public String getId(DialogFragment node) throws Exception { + final NodeDescriptor descriptor = descriptorForClass(Fragment.class); + return descriptor.getId(node); + } + + @Override + public String getName(DialogFragment node) throws Exception { + final NodeDescriptor descriptor = descriptorForClass(Fragment.class); + return descriptor.getName(node); + } + + @Override + public int getChildCount(DialogFragment node) { + return node.getDialog() == null ? 0 : 1; + } + + @Override + public Object getChildAt(DialogFragment node, int index) { + return node.getDialog(); + } + + @Override + public List> getData(DialogFragment node) throws Exception { + final NodeDescriptor descriptor = descriptorForClass(Fragment.class); + return descriptor.getData(node); + } + + @Override + public void setValue(DialogFragment node, String[] path, SonarDynamic value) throws Exception { + final NodeDescriptor descriptor = descriptorForClass(Fragment.class); + descriptor.setValue(node, path, value); + } + + @Override + public List> getAttributes(DialogFragment node) throws Exception { + final NodeDescriptor descriptor = descriptorForClass(Fragment.class); + return descriptor.getAttributes(node); + } + + @Override + public void setHighlighted(DialogFragment node, boolean selected) throws Exception { + final NodeDescriptor descriptor = descriptorForClass(Dialog.class); + if (node.getDialog() != null) { + descriptor.setHighlighted(node.getDialog(), selected); + } + } + + @Override + public void hitTest(DialogFragment node, Touch touch) { + touch.continueWithOffset(0, 0, 0); + } + + @Override + public @Nullable String getDecoration(DialogFragment obj) { + return null; + } + + @Override + public boolean matches(String query, DialogFragment node) throws Exception { + final NodeDescriptor descriptor = descriptorForClass(Object.class); + return descriptor.matches(query, node); + } +} diff --git a/android/plugins/inspector/descriptors/SupportFragmentDescriptor.java b/android/plugins/inspector/descriptors/SupportFragmentDescriptor.java new file mode 100644 index 000000000..7af9e65ee --- /dev/null +++ b/android/plugins/inspector/descriptors/SupportFragmentDescriptor.java @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ + +package com.facebook.sonar.plugins.inspector.descriptors; + +import android.os.Bundle; +import android.support.v4.app.Fragment; +import android.view.View; +import com.facebook.sonar.core.SonarDynamic; +import com.facebook.sonar.core.SonarObject; +import com.facebook.sonar.plugins.inspector.Named; +import com.facebook.sonar.plugins.inspector.NodeDescriptor; +import com.facebook.sonar.plugins.inspector.Touch; +import com.facebook.stetho.common.android.ResourcesUtil; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import javax.annotation.Nullable; + +public class SupportFragmentDescriptor extends NodeDescriptor { + + @Override + public void init(Fragment node) {} + + @Override + public String getId(Fragment node) { + return Integer.toString(System.identityHashCode(node)); + } + + @Override + public String getName(Fragment node) { + return node.getClass().getSimpleName(); + } + + @Override + public int getChildCount(Fragment node) { + return node.getView() == null ? 0 : 1; + } + + @Override + public @Nullable Object getChildAt(Fragment node, int index) { + return node.getView(); + } + + @Override + public List> getData(Fragment node) { + final Bundle args = node.getArguments(); + if (args == null || args.isEmpty()) { + return Collections.EMPTY_LIST; + } + + final SonarObject.Builder bundle = new SonarObject.Builder(); + + for (String key : args.keySet()) { + bundle.put(key, args.get(key)); + } + + return Arrays.asList(new Named<>("Arguments", bundle.build())); + } + + @Override + public void setValue(Fragment node, String[] path, SonarDynamic value) {} + + @Override + public List> getAttributes(Fragment node) { + final int id = node.getId(); + if (id == View.NO_ID || node.getHost() == null) { + return Collections.EMPTY_LIST; + } + + return Arrays.asList( + new Named<>( + "id", ResourcesUtil.getIdStringQuietly(node.getContext(), node.getResources(), id))); + } + + @Override + public void setHighlighted(Fragment node, boolean selected) throws Exception { + if (node.getView() == null) { + return; + } + + final NodeDescriptor descriptor = descriptorForClass(View.class); + descriptor.setHighlighted(node.getView(), selected); + } + + @Override + public void hitTest(Fragment node, Touch touch) { + touch.continueWithOffset(0, 0, 0); + } + + @Override + public @Nullable String getDecoration(Fragment obj) { + return null; + } + + @Override + public boolean matches(String query, Fragment node) throws Exception { + final NodeDescriptor descriptor = descriptorForClass(Object.class); + return descriptor.matches(query, node); + } +} diff --git a/android/plugins/inspector/descriptors/TextViewDescriptor.java b/android/plugins/inspector/descriptors/TextViewDescriptor.java new file mode 100644 index 000000000..4426259b5 --- /dev/null +++ b/android/plugins/inspector/descriptors/TextViewDescriptor.java @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ + +package com.facebook.sonar.plugins.inspector.descriptors; + +import static com.facebook.sonar.plugins.inspector.InspectorValue.Type.Color; +import static com.facebook.sonar.plugins.inspector.InspectorValue.Type.Number; +import static com.facebook.sonar.plugins.inspector.InspectorValue.Type.Text; + +import android.view.View; +import android.widget.TextView; +import com.facebook.sonar.core.SonarDynamic; +import com.facebook.sonar.core.SonarObject; +import com.facebook.sonar.plugins.inspector.InspectorValue; +import com.facebook.sonar.plugins.inspector.Named; +import com.facebook.sonar.plugins.inspector.NodeDescriptor; +import com.facebook.sonar.plugins.inspector.Touch; +import java.util.ArrayList; +import java.util.List; +import javax.annotation.Nullable; + +public class TextViewDescriptor extends NodeDescriptor { + + @Override + public void init(TextView node) throws Exception { + final NodeDescriptor descriptor = descriptorForClass(View.class); + descriptor.init(node); + } + + @Override + public String getId(TextView node) throws Exception { + final NodeDescriptor descriptor = descriptorForClass(View.class); + return descriptor.getId(node); + } + + @Override + public String getName(TextView node) throws Exception { + final NodeDescriptor descriptor = descriptorForClass(View.class); + return descriptor.getName(node); + } + + @Override + public int getChildCount(TextView node) { + return 0; + } + + @Override + public @Nullable Object getChildAt(TextView node, int index) { + return null; + } + + @Override + public List> getData(TextView node) throws Exception { + final List> props = new ArrayList<>(); + final NodeDescriptor descriptor = descriptorForClass(View.class); + + props.add( + 0, + new Named<>( + "TextView", + new SonarObject.Builder() + .put("text", InspectorValue.mutable(Text, node.getText().toString())) + .put( + "textColor", + InspectorValue.mutable(Color, node.getTextColors().getDefaultColor())) + .put("textSize", InspectorValue.mutable(Number, node.getTextSize())) + .build())); + + props.addAll(descriptor.getData(node)); + + return props; + } + + @Override + public void setValue(TextView node, String[] path, SonarDynamic value) throws Exception { + switch (path[0]) { + case "TextView": + switch (path[1]) { + case "text": + node.setText(value.asString()); + break; + case "textColor": + node.setTextColor(value.asInt()); + break; + case "textSize": + node.setTextSize(value.asInt()); + break; + } + break; + default: + final NodeDescriptor descriptor = descriptorForClass(View.class); + descriptor.setValue(node, path, value); + break; + } + invalidate(node); + } + + @Override + public List> getAttributes(TextView node) throws Exception { + final NodeDescriptor descriptor = descriptorForClass(View.class); + return descriptor.getAttributes(node); + } + + @Override + public void setHighlighted(TextView node, boolean selected) throws Exception { + final NodeDescriptor descriptor = descriptorForClass(View.class); + descriptor.setHighlighted(node, selected); + } + + @Override + public void hitTest(TextView node, Touch touch) throws Exception { + final NodeDescriptor descriptor = descriptorForClass(View.class); + descriptor.hitTest(node, touch); + } + + @Override + public @Nullable String getDecoration(TextView node) throws Exception { + final NodeDescriptor descriptor = descriptorForClass(View.class); + return descriptor.getDecoration(node); + } + + @Override + public boolean matches(String query, TextView node) throws Exception { + final NodeDescriptor descriptor = descriptorForClass(Object.class); + return descriptor.matches(query, node); + } +} diff --git a/android/plugins/inspector/descriptors/ViewDescriptor.java b/android/plugins/inspector/descriptors/ViewDescriptor.java new file mode 100644 index 000000000..b6883ace2 --- /dev/null +++ b/android/plugins/inspector/descriptors/ViewDescriptor.java @@ -0,0 +1,708 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ + +package com.facebook.sonar.plugins.inspector.descriptors; + +import static com.facebook.sonar.plugins.inspector.InspectorValue.Type.Color; +import static com.facebook.sonar.plugins.inspector.InspectorValue.Type.Enum; + +import android.annotation.TargetApi; +import android.graphics.Rect; +import android.graphics.drawable.ColorDrawable; +import android.graphics.drawable.Drawable; +import android.os.Build; +import android.support.v4.view.MarginLayoutParamsCompat; +import android.support.v4.view.ViewCompat; +import android.util.SparseArray; +import android.view.Gravity; +import android.view.View; +import android.view.View.OnClickListener; +import android.view.ViewGroup; +import android.view.ViewGroup.LayoutParams; +import android.view.ViewGroup.MarginLayoutParams; +import android.view.ViewParent; +import android.widget.FrameLayout; +import android.widget.LinearLayout; +import com.facebook.sonar.core.SonarDynamic; +import com.facebook.sonar.core.SonarObject; +import com.facebook.sonar.plugins.inspector.HighlightedOverlay; +import com.facebook.sonar.plugins.inspector.InspectorValue; +import com.facebook.sonar.plugins.inspector.Named; +import com.facebook.sonar.plugins.inspector.NodeDescriptor; +import com.facebook.sonar.plugins.inspector.Touch; +import com.facebook.sonar.plugins.inspector.descriptors.utils.AccessibilityUtil; +import com.facebook.sonar.plugins.inspector.descriptors.utils.EnumMapping; +import com.facebook.stetho.common.android.ResourcesUtil; +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import javax.annotation.Nullable; + +public class ViewDescriptor extends NodeDescriptor { + + private static Field sKeyedTagsField; + private static Field sListenerInfoField; + private static Field sOnClickListenerField; + + static { + try { + sKeyedTagsField = View.class.getDeclaredField("mKeyedTags"); + sKeyedTagsField.setAccessible(true); + + sListenerInfoField = View.class.getDeclaredField("mListenerInfo"); + sListenerInfoField.setAccessible(true); + + final String viewInfoClassName = View.class.getName() + "$ListenerInfo"; + sOnClickListenerField = Class.forName(viewInfoClassName).getDeclaredField("mOnClickListener"); + sOnClickListenerField.setAccessible(true); + } catch (Exception ignored) { + } + } + + @Override + public void init(final View node) {} + + @Override + public String getId(View node) { + return Integer.toString(System.identityHashCode(node)); + } + + @Override + public String getName(View node) { + return node.getClass().getSimpleName(); + } + + @Override + public int getChildCount(View node) { + return 0; + } + + @Override + public @Nullable Object getChildAt(View node, int index) { + return null; + } + + @Override + public List> getData(View node) { + final SonarObject.Builder viewProps = + new SonarObject.Builder() + .put("height", InspectorValue.mutable(node.getHeight())) + .put("width", InspectorValue.mutable(node.getWidth())) + .put("alpha", InspectorValue.mutable(node.getAlpha())) + .put("visibility", sVisibilityMapping.get(node.getVisibility())) + .put("background", fromDrawable(node.getBackground())) + .put("tag", InspectorValue.mutable(node.getTag())) + .put("keyedTags", getTags(node)) + .put("layoutParams", getLayoutParams(node)) + .put( + "state", + new SonarObject.Builder() + .put("enabled", InspectorValue.mutable(node.isEnabled())) + .put("activated", InspectorValue.mutable(node.isActivated())) + .put("focused", node.isFocused()) + .put("selected", InspectorValue.mutable(node.isSelected()))) + .put( + "bounds", + new SonarObject.Builder() + .put("left", InspectorValue.mutable(node.getLeft())) + .put("right", InspectorValue.mutable(node.getRight())) + .put("top", InspectorValue.mutable(node.getTop())) + .put("bottom", InspectorValue.mutable(node.getBottom()))) + .put( + "padding", + new SonarObject.Builder() + .put("left", InspectorValue.mutable(node.getPaddingLeft())) + .put("top", InspectorValue.mutable(node.getPaddingTop())) + .put("right", InspectorValue.mutable(node.getPaddingRight())) + .put("bottom", InspectorValue.mutable(node.getPaddingBottom()))) + .put( + "rotation", + new SonarObject.Builder() + .put("x", InspectorValue.mutable(node.getRotationX())) + .put("y", InspectorValue.mutable(node.getRotationY())) + .put("z", InspectorValue.mutable(node.getRotation()))) + .put( + "scale", + new SonarObject.Builder() + .put("x", InspectorValue.mutable(node.getScaleX())) + .put("y", InspectorValue.mutable(node.getScaleY()))) + .put( + "pivot", + new SonarObject.Builder() + .put("x", InspectorValue.mutable(node.getPivotX())) + .put("y", InspectorValue.mutable(node.getPivotY()))); + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) { + viewProps + .put("layoutDirection", sLayoutDirectionMapping.get(node.getLayoutDirection())) + .put("textDirection", sTextDirectionMapping.get(node.getTextDirection())) + .put("textAlignment", sTextAlignmentMapping.get(node.getTextAlignment())); + } + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + viewProps.put("elevation", InspectorValue.mutable(node.getElevation())); + } + + SonarObject.Builder translation = + new SonarObject.Builder() + .put("x", InspectorValue.mutable(node.getTranslationX())) + .put("y", InspectorValue.mutable(node.getTranslationY())); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + translation.put("z", InspectorValue.mutable(node.getTranslationZ())); + } + viewProps.put("translation", translation); + + SonarObject.Builder position = + new SonarObject.Builder() + .put("x", InspectorValue.mutable(node.getX())) + .put("y", InspectorValue.mutable(node.getY())); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1) { + position.put("z", InspectorValue.mutable(node.getZ())); + } + viewProps.put("position", position); + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + viewProps.put("foreground", fromDrawable(node.getForeground())); + } + + return Arrays.asList( + new Named<>("View", viewProps.build()), + new Named<>("Accessibility", getAccessibilityData(node))); + } + + private static SonarObject getAccessibilityData(View view) { + final SonarObject.Builder accessibilityProps = new SonarObject.Builder(); + + // This needs to be an empty string to be mutable. See t20470623. + CharSequence contentDescription = + view.getContentDescription() != null ? view.getContentDescription() : ""; + accessibilityProps.put("content-description", InspectorValue.mutable(contentDescription)); + accessibilityProps.put("focusable", InspectorValue.mutable(view.isFocusable())); + accessibilityProps.put("node-info", AccessibilityUtil.getAccessibilityNodeInfoProperties(view)); + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { + accessibilityProps.put( + "important-for-accessibility", + AccessibilityUtil.sImportantForAccessibilityMapping.get( + view.getImportantForAccessibility())); + } + + AccessibilityUtil.addTalkbackProperties(accessibilityProps, view); + + return accessibilityProps.build(); + } + + @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1) + @Override + public void setValue(View node, String[] path, SonarDynamic value) { + if (path[0].equals("Accessibility")) { + setAccessibilityValue(node, path, value); + } + + if (!path[0].equals("View")) { + return; + } + + switch (path[1]) { + case "elevation": + node.setElevation(value.asFloat()); + break; + case "alpha": + node.setAlpha(value.asFloat()); + break; + case "visibility": + node.setVisibility(sVisibilityMapping.get(value.asString())); + break; + case "layoutParams": + setLayoutParams(node, Arrays.copyOfRange(path, 1, path.length), value); + break; + case "layoutDirection": + node.setLayoutDirection(sLayoutDirectionMapping.get(value.asString())); + break; + case "textDirection": + node.setTextDirection(sTextDirectionMapping.get(value.asString())); + break; + case "textAlignment": + node.setTextAlignment(sTextAlignmentMapping.get(value.asString())); + break; + case "background": + node.setBackground(new ColorDrawable(value.asInt())); + break; + case "foreground": + node.setForeground(new ColorDrawable(value.asInt())); + break; + case "state": + switch (path[2]) { + case "enabled": + node.setEnabled(value.asBoolean()); + break; + case "activated": + node.setActivated(value.asBoolean()); + break; + case "selected": + node.setSelected(value.asBoolean()); + break; + } + break; + case "bounds": + switch (path[2]) { + case "left": + node.setLeft(value.asInt()); + break; + case "top": + node.setTop(value.asInt()); + break; + case "right": + node.setRight(value.asInt()); + break; + case "bottom": + node.setBottom(value.asInt()); + break; + } + break; + case "padding": + switch (path[2]) { + case "left": + node.setPadding( + value.asInt(), + node.getPaddingTop(), + node.getPaddingRight(), + node.getPaddingBottom()); + break; + case "top": + node.setPadding( + node.getPaddingLeft(), + value.asInt(), + node.getPaddingRight(), + node.getPaddingBottom()); + break; + case "right": + node.setPadding( + node.getPaddingLeft(), + node.getPaddingTop(), + value.asInt(), + node.getPaddingBottom()); + break; + case "bottom": + node.setPadding( + node.getPaddingLeft(), node.getPaddingTop(), node.getPaddingRight(), value.asInt()); + break; + } + break; + case "rotation": + switch (path[2]) { + case "x": + node.setRotationX(value.asFloat()); + break; + case "y": + node.setRotationY(value.asFloat()); + break; + case "z": + node.setRotation(value.asFloat()); + break; + } + break; + case "translation": + switch (path[2]) { + case "x": + node.setTranslationX(value.asFloat()); + break; + case "y": + node.setTranslationY(value.asFloat()); + break; + case "z": + node.setTranslationZ(value.asFloat()); + break; + } + break; + case "position": + switch (path[2]) { + case "x": + node.setX(value.asFloat()); + break; + case "y": + node.setY(value.asFloat()); + break; + case "z": + node.setZ(value.asFloat()); + break; + } + break; + case "scale": + switch (path[2]) { + case "x": + node.setScaleX(value.asFloat()); + break; + case "y": + node.setScaleY(value.asFloat()); + break; + } + break; + case "pivot": + switch (path[2]) { + case "x": + node.setPivotY(value.asFloat()); + break; + case "y": + node.setPivotX(value.asFloat()); + break; + } + break; + case "width": + LayoutParams lpw = node.getLayoutParams(); + lpw.width = value.asInt(); + node.setLayoutParams(lpw); + break; + case "height": + LayoutParams lph = node.getLayoutParams(); + lph.height = value.asInt(); + node.setLayoutParams(lph); + break; + } + + invalidate(node); + } + + private void setAccessibilityValue(View node, String[] path, SonarDynamic value) { + switch (path[1]) { + case "focusable": + node.setFocusable(value.asBoolean()); + break; + case "important-for-accessibility": + node.setImportantForAccessibility( + AccessibilityUtil.sImportantForAccessibilityMapping.get(value.asString())); + break; + case "content-description": + node.setContentDescription(value.asString()); + break; + } + invalidate(node); + } + + @Override + public List> getAttributes(View node) throws Exception { + final List> attributes = new ArrayList<>(); + + final String resourceId = getResourceId(node); + if (resourceId != null) { + attributes.add(new Named<>("id", resourceId)); + } + + if (sListenerInfoField != null && sOnClickListenerField != null) { + final Object listenerInfo = sListenerInfoField.get(node); + if (listenerInfo != null) { + final OnClickListener clickListener = + (OnClickListener) sOnClickListenerField.get(listenerInfo); + if (clickListener != null) { + attributes.add(new Named<>("onClick", clickListener.getClass().getName())); + } + } + } + + return attributes; + } + + @Nullable + private static String getResourceId(View node) { + final int id = node.getId(); + + if (id == View.NO_ID) { + return null; + } + + return ResourcesUtil.getIdStringQuietly(node.getContext(), node.getResources(), id); + } + + @Override + public void setHighlighted(View node, boolean selected) { + // We need to figure out whether the given View has a parent View since margins are not + // included within a View's bounds. So, in order to display the margin values for a particular + // view, we need to apply an overlay on its parent rather than itself. + final View targetView; + final ViewParent parent = node.getParent(); + if (parent instanceof View) { + targetView = (View) parent; + } else { + targetView = node; + } + + if (!selected) { + HighlightedOverlay.removeHighlight(targetView); + return; + } + + final Rect padding = + new Rect( + ViewCompat.getPaddingStart(node), + node.getPaddingTop(), + ViewCompat.getPaddingEnd(node), + node.getPaddingBottom()); + + final Rect margin; + final ViewGroup.LayoutParams params = node.getLayoutParams(); + if (params instanceof ViewGroup.MarginLayoutParams) { + final ViewGroup.MarginLayoutParams marginParams = (ViewGroup.MarginLayoutParams) params; + margin = + new Rect( + MarginLayoutParamsCompat.getMarginStart(marginParams), + marginParams.topMargin, + MarginLayoutParamsCompat.getMarginEnd(marginParams), + marginParams.bottomMargin); + } else { + margin = new Rect(); + } + + final int left = node.getLeft(); + final int top = node.getTop(); + final Rect contentBounds = new Rect(left, top, left + node.getWidth(), top + node.getHeight()); + if (targetView == node) { + // If the View doesn't have a parent View that we're applying the overlay to, then + // we need to ensure that it is aligned to 0, 0, rather than its relative location to its + // parent + contentBounds.offset(-left, -top); + } + + HighlightedOverlay.setHighlighted(targetView, margin, padding, contentBounds); + } + + @Override + public void hitTest(View node, Touch touch) { + touch.finish(); + } + + @Override + public @Nullable String getDecoration(View obj) { + return null; + } + + @Override + public boolean matches(String query, View node) throws Exception { + final String resourceId = getResourceId(node); + + if (resourceId != null && resourceId.toLowerCase().contains(query)) { + return true; + } + + final NodeDescriptor objectDescriptor = descriptorForClass(Object.class); + return objectDescriptor.matches(query, node); + } + + private SonarObject getTags(final View node) { + final SonarObject.Builder tags = new SonarObject.Builder(); + if (sKeyedTagsField == null) { + return tags.build(); + } + + new ErrorReportingRunnable() { + @Override + protected void runOrThrow() throws Exception { + final SparseArray keyedTags = (SparseArray) sKeyedTagsField.get(node); + if (keyedTags != null) { + for (int i = 0, count = keyedTags.size(); i < count; i++) { + final String id = + ResourcesUtil.getIdStringQuietly( + node.getContext(), node.getResources(), keyedTags.keyAt(i)); + tags.put(id, keyedTags.valueAt(i)); + } + } + } + }.run(); + + return tags.build(); + } + + private static InspectorValue fromDrawable(Drawable d) { + if (d instanceof ColorDrawable) { + return InspectorValue.mutable(Color, ((ColorDrawable) d).getColor()); + } + return InspectorValue.mutable(Color, 0); + } + + private static SonarObject getLayoutParams(View node) { + final LayoutParams layoutParams = node.getLayoutParams(); + final SonarObject.Builder params = new SonarObject.Builder(); + + params.put("width", fromSize(layoutParams.width)); + params.put("height", fromSize(layoutParams.height)); + + if (layoutParams instanceof MarginLayoutParams) { + final MarginLayoutParams marginLayoutParams = (MarginLayoutParams) layoutParams; + params.put( + "margin", + new SonarObject.Builder() + .put("left", InspectorValue.mutable(marginLayoutParams.leftMargin)) + .put("top", InspectorValue.mutable(marginLayoutParams.topMargin)) + .put("right", InspectorValue.mutable(marginLayoutParams.rightMargin)) + .put("bottom", InspectorValue.mutable(marginLayoutParams.bottomMargin))); + } + + if (layoutParams instanceof FrameLayout.LayoutParams) { + final FrameLayout.LayoutParams frameLayoutParams = (FrameLayout.LayoutParams) layoutParams; + params.put("gravity", sGravityMapping.get(frameLayoutParams.gravity)); + } + + if (layoutParams instanceof LinearLayout.LayoutParams) { + final LinearLayout.LayoutParams linearLayoutParams = (LinearLayout.LayoutParams) layoutParams; + params + .put("weight", InspectorValue.mutable(linearLayoutParams.weight)) + .put("gravity", sGravityMapping.get(linearLayoutParams.gravity)); + } + + return params.build(); + } + + private void setLayoutParams(View node, String[] path, SonarDynamic value) { + final LayoutParams params = node.getLayoutParams(); + + switch (path[0]) { + case "width": + params.width = toSize(value.asString()); + break; + case "height": + params.height = toSize(value.asString()); + break; + case "weight": + final LinearLayout.LayoutParams linearParams = (LinearLayout.LayoutParams) params; + linearParams.weight = value.asFloat(); + break; + } + + if (params instanceof MarginLayoutParams) { + final MarginLayoutParams marginParams = (MarginLayoutParams) params; + + switch (path[0]) { + case "margin": + switch (path[1]) { + case "left": + marginParams.leftMargin = value.asInt(); + break; + case "top": + marginParams.topMargin = value.asInt(); + break; + case "right": + marginParams.rightMargin = value.asInt(); + break; + case "bottom": + marginParams.bottomMargin = value.asInt(); + break; + } + break; + } + } + + if (params instanceof FrameLayout.LayoutParams) { + final FrameLayout.LayoutParams frameLayoutParams = (FrameLayout.LayoutParams) params; + + switch (path[0]) { + case "gravity": + frameLayoutParams.gravity = sGravityMapping.get(value.asString()); + break; + } + } + + if (params instanceof LinearLayout.LayoutParams) { + final LinearLayout.LayoutParams linearParams = (LinearLayout.LayoutParams) params; + + switch (path[0]) { + case "weight": + linearParams.weight = value.asFloat(); + break; + case "gravity": + linearParams.gravity = sGravityMapping.get(value.asString()); + break; + } + } + + node.setLayoutParams(params); + } + + private static InspectorValue fromSize(int size) { + switch (size) { + case LayoutParams.WRAP_CONTENT: + return InspectorValue.mutable(Enum, "WRAP_CONTENT"); + case LayoutParams.MATCH_PARENT: + return InspectorValue.mutable(Enum, "MATCH_PARENT"); + default: + return InspectorValue.mutable(Enum, Integer.toString(size)); + } + } + + private static int toSize(String size) { + switch (size) { + case "WRAP_CONTENT": + return LayoutParams.WRAP_CONTENT; + case "MATCH_PARENT": + return LayoutParams.MATCH_PARENT; + default: + return Integer.parseInt(size); + } + } + + private static final EnumMapping sVisibilityMapping = + new EnumMapping("VISIBLE") { + { + put("VISIBLE", View.VISIBLE); + put("INVISIBLE", View.INVISIBLE); + put("GONE", View.GONE); + } + }; + + private static final EnumMapping sLayoutDirectionMapping = + new EnumMapping("LAYOUT_DIRECTION_INHERIT") { + { + put("LAYOUT_DIRECTION_INHERIT", View.LAYOUT_DIRECTION_INHERIT); + put("LAYOUT_DIRECTION_LOCALE", View.LAYOUT_DIRECTION_LOCALE); + put("LAYOUT_DIRECTION_LTR", View.LAYOUT_DIRECTION_LTR); + put("LAYOUT_DIRECTION_RTL", View.LAYOUT_DIRECTION_RTL); + } + }; + + private static final EnumMapping sTextDirectionMapping = + new EnumMapping("TEXT_DIRECTION_INHERIT") { + { + put("TEXT_DIRECTION_INHERIT", View.TEXT_DIRECTION_INHERIT); + put("TEXT_DIRECTION_FIRST_STRONG", View.TEXT_DIRECTION_FIRST_STRONG); + put("TEXT_DIRECTION_ANY_RTL", View.TEXT_DIRECTION_ANY_RTL); + put("TEXT_DIRECTION_LTR", View.TEXT_DIRECTION_LTR); + put("TEXT_DIRECTION_RTL", View.TEXT_DIRECTION_RTL); + put("TEXT_DIRECTION_LOCALE", View.TEXT_DIRECTION_LOCALE); + put("TEXT_DIRECTION_FIRST_STRONG_LTR", View.TEXT_DIRECTION_FIRST_STRONG_LTR); + put("TEXT_DIRECTION_FIRST_STRONG_RTL", View.TEXT_DIRECTION_FIRST_STRONG_RTL); + } + }; + + private static final EnumMapping sTextAlignmentMapping = + new EnumMapping("TEXT_ALIGNMENT_INHERIT") { + { + put("TEXT_ALIGNMENT_INHERIT", View.TEXT_ALIGNMENT_INHERIT); + put("TEXT_ALIGNMENT_GRAVITY", View.TEXT_ALIGNMENT_GRAVITY); + put("TEXT_ALIGNMENT_TEXT_START", View.TEXT_ALIGNMENT_TEXT_START); + put("TEXT_ALIGNMENT_TEXT_END", View.TEXT_ALIGNMENT_TEXT_END); + put("TEXT_ALIGNMENT_CENTER", View.TEXT_ALIGNMENT_CENTER); + put("TEXT_ALIGNMENT_VIEW_START", View.TEXT_ALIGNMENT_VIEW_START); + put("TEXT_ALIGNMENT_VIEW_END", View.TEXT_ALIGNMENT_VIEW_END); + } + }; + + private static final EnumMapping sGravityMapping = + new EnumMapping("NO_GRAVITY") { + { + put("NO_GRAVITY", Gravity.NO_GRAVITY); + put("LEFT", Gravity.LEFT); + put("TOP", Gravity.TOP); + put("RIGHT", Gravity.RIGHT); + put("BOTTOM", Gravity.BOTTOM); + put("CENTER", Gravity.CENTER); + put("CENTER_VERTICAL", Gravity.CENTER_VERTICAL); + put("FILL_VERTICAL", Gravity.FILL_VERTICAL); + put("CENTER_HORIZONTAL", Gravity.CENTER_HORIZONTAL); + put("FILL_HORIZONTAL", Gravity.FILL_HORIZONTAL); + } + }; +} diff --git a/android/plugins/inspector/descriptors/ViewGroupDescriptor.java b/android/plugins/inspector/descriptors/ViewGroupDescriptor.java new file mode 100644 index 000000000..14a096397 --- /dev/null +++ b/android/plugins/inspector/descriptors/ViewGroupDescriptor.java @@ -0,0 +1,273 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ + +package com.facebook.sonar.plugins.inspector.descriptors; + +import static android.support.v4.view.ViewGroupCompat.LAYOUT_MODE_CLIP_BOUNDS; +import static android.support.v4.view.ViewGroupCompat.LAYOUT_MODE_OPTICAL_BOUNDS; +import static com.facebook.sonar.plugins.inspector.InspectorValue.Type.Boolean; +import static com.facebook.sonar.plugins.inspector.InspectorValue.Type.Enum; + +import android.os.Build; +import android.view.View; +import android.view.ViewGroup; +import com.facebook.sonar.R; +import com.facebook.sonar.core.SonarDynamic; +import com.facebook.sonar.core.SonarObject; +import com.facebook.sonar.plugins.inspector.HiddenNode; +import com.facebook.sonar.plugins.inspector.InspectorValue; +import com.facebook.sonar.plugins.inspector.Named; +import com.facebook.sonar.plugins.inspector.NodeDescriptor; +import com.facebook.sonar.plugins.inspector.Touch; +import com.facebook.stetho.common.android.FragmentCompatUtil; +import java.util.ArrayList; +import java.util.List; +import javax.annotation.Nullable; + +public class ViewGroupDescriptor extends NodeDescriptor { + + private class NodeKey { + private int[] mKey; + + boolean set(ViewGroup node) { + final int childCount = node.getChildCount(); + final int[] key = new int[childCount]; + + for (int i = 0; i < childCount; i++) { + final View child = node.getChildAt(i); + key[i] = System.identityHashCode(child); + } + + boolean changed = false; + if (mKey == null) { + changed = true; + } else if (mKey.length != key.length) { + changed = true; + } else { + for (int i = 0; i < childCount; i++) { + if (mKey[i] != key[i]) { + changed = true; + break; + } + } + } + + mKey = key; + return changed; + } + } + + @Override + public void init(final ViewGroup node) { + final NodeKey key = new NodeKey(); + + final Runnable maybeInvalidate = + new ErrorReportingRunnable() { + @Override + public void runOrThrow() throws Exception { + if (connected()) { + if (key.set(node)) { + invalidate(node); + } + + final boolean hasAttachedToWindow = + Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT; + if (!hasAttachedToWindow || node.isAttachedToWindow()) { + node.postDelayed(this, 1000); + } + } + } + }; + + node.postDelayed(maybeInvalidate, 1000); + } + + @Override + public String getId(ViewGroup node) throws Exception { + NodeDescriptor descriptor = descriptorForClass(View.class); + return descriptor.getId(node); + } + + @Override + public String getName(ViewGroup node) throws Exception { + NodeDescriptor descriptor = descriptorForClass(View.class); + return descriptor.getName(node); + } + + @Override + public int getChildCount(ViewGroup node) { + int childCount = 0; + for (int i = 0, count = node.getChildCount(); i < count; i++) { + if (!(node.getChildAt(i) instanceof HiddenNode)) { + childCount++; + } + } + return childCount; + } + + @Override + public @Nullable Object getChildAt(ViewGroup node, int index) { + for (int i = 0, count = node.getChildCount(); i < count; i++) { + final View child = node.getChildAt(i); + if (child instanceof HiddenNode) { + continue; + } + + if (i >= index) { + final Object fragment = getAttachedFragmentForView(child); + if (fragment != null && !FragmentCompatUtil.isDialogFragment(fragment)) { + return fragment; + } + + return child; + } + } + return null; + } + + @Override + public List> getData(ViewGroup node) throws Exception { + final List> props = new ArrayList<>(); + final NodeDescriptor descriptor = descriptorForClass(View.class); + + final SonarObject.Builder vgProps = new SonarObject.Builder(); + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) { + vgProps + .put( + "layoutMode", + InspectorValue.mutable( + Enum, + node.getLayoutMode() == LAYOUT_MODE_CLIP_BOUNDS + ? "LAYOUT_MODE_CLIP_BOUNDS" + : "LAYOUT_MODE_OPTICAL_BOUNDS")) + .put("clipChildren", InspectorValue.mutable(Boolean, node.getClipChildren())); + } + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + vgProps.put("clipToPadding", InspectorValue.mutable(Boolean, node.getClipToPadding())); + } + + props.add(0, new Named<>("ViewGroup", vgProps.build())); + + props.addAll(descriptor.getData(node)); + + return props; + } + + @Override + public void setValue(ViewGroup node, String[] path, SonarDynamic value) throws Exception { + switch (path[0]) { + case "ViewGroup": + switch (path[1]) { + case "layoutMode": + switch (value.asString()) { + case "LAYOUT_MODE_CLIP_BOUNDS": + node.setLayoutMode(LAYOUT_MODE_CLIP_BOUNDS); + break; + case "LAYOUT_MODE_OPTICAL_BOUNDS": + node.setLayoutMode(LAYOUT_MODE_OPTICAL_BOUNDS); + break; + default: + node.setLayoutMode(-1); + break; + } + break; + case "clipChildren": + node.setClipChildren(value.asBoolean()); + break; + case "clipToPadding": + node.setClipToPadding(value.asBoolean()); + break; + } + break; + default: + final NodeDescriptor descriptor = descriptorForClass(View.class); + descriptor.setValue(node, path, value); + break; + } + invalidate(node); + } + + @Override + public List> getAttributes(ViewGroup node) throws Exception { + final NodeDescriptor descriptor = descriptorForClass(View.class); + return descriptor.getAttributes(node); + } + + @Override + public void setHighlighted(ViewGroup node, boolean selected) throws Exception { + final NodeDescriptor descriptor = descriptorForClass(View.class); + descriptor.setHighlighted(node, selected); + } + + @Override + public void hitTest(ViewGroup node, Touch touch) { + for (int i = node.getChildCount() - 1; i >= 0; i--) { + final View child = node.getChildAt(i); + if (child instanceof HiddenNode + || child.getVisibility() != View.VISIBLE + || shouldSkip(child)) { + continue; + } + + final int scrollX = node.getScrollX(); + final int scrollY = node.getScrollY(); + + final int left = (child.getLeft() + (int) child.getTranslationX()) - scrollX; + final int top = (child.getTop() + (int) child.getTranslationY()) - scrollY; + final int right = (child.getRight() + (int) child.getTranslationX()) - scrollX; + final int bottom = (child.getBottom() + (int) child.getTranslationY()) - scrollY; + + final boolean hit = touch.containedIn(left, top, right, bottom); + + if (hit) { + touch.continueWithOffset(i, left, top); + return; + } + } + + touch.finish(); + } + + private static boolean shouldSkip(View view) { + Object tag = view.getTag(R.id.sonar_skip_view_traversal); + if (!(tag instanceof Boolean)) { + return false; + } + + return (Boolean) tag; + } + + @Override + public @Nullable String getDecoration(ViewGroup obj) { + return null; + } + + @Override + public boolean matches(String query, ViewGroup node) throws Exception { + final NodeDescriptor descriptor = descriptorForClass(Object.class); + return descriptor.matches(query, node); + } + + private static Object getAttachedFragmentForView(View v) { + try { + final Object fragment = FragmentCompatUtil.findFragmentForView(v); + boolean added = false; + if (fragment instanceof android.app.Fragment) { + added = ((android.app.Fragment) fragment).isAdded(); + } else if (fragment instanceof android.support.v4.app.Fragment) { + added = ((android.support.v4.app.Fragment) fragment).isAdded(); + } + + return added ? fragment : null; + } catch (RuntimeException e) { + return null; + } + } +} diff --git a/android/plugins/inspector/descriptors/WindowDescriptor.java b/android/plugins/inspector/descriptors/WindowDescriptor.java new file mode 100644 index 000000000..6b070283f --- /dev/null +++ b/android/plugins/inspector/descriptors/WindowDescriptor.java @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ + +package com.facebook.sonar.plugins.inspector.descriptors; + +import android.view.View; +import android.view.Window; +import com.facebook.sonar.core.SonarDynamic; +import com.facebook.sonar.core.SonarObject; +import com.facebook.sonar.plugins.inspector.Named; +import com.facebook.sonar.plugins.inspector.NodeDescriptor; +import com.facebook.sonar.plugins.inspector.Touch; +import java.util.Collections; +import java.util.List; +import javax.annotation.Nullable; + +public class WindowDescriptor extends NodeDescriptor { + + @Override + public void init(Window node) {} + + @Override + public String getId(Window node) { + return Integer.toString(System.identityHashCode(node)); + } + + @Override + public String getName(Window node) { + return node.getClass().getSimpleName(); + } + + @Override + public int getChildCount(Window node) { + return 1; + } + + @Override + public Object getChildAt(Window node, int index) { + return node.getDecorView(); + } + + @Override + public List> getData(Window node) { + return Collections.EMPTY_LIST; + } + + @Override + public void setValue(Window node, String[] path, SonarDynamic value) {} + + @Override + public List> getAttributes(Window node) { + return Collections.EMPTY_LIST; + } + + @Override + public void setHighlighted(Window node, boolean selected) throws Exception { + final NodeDescriptor descriptor = descriptorForClass(View.class); + descriptor.setHighlighted(node.getDecorView(), selected); + } + + @Override + public void hitTest(Window node, Touch touch) { + touch.continueWithOffset(0, 0, 0); + } + + @Override + public @Nullable String getDecoration(Window obj) { + return null; + } + + @Override + public boolean matches(String query, Window node) throws Exception { + final NodeDescriptor descriptor = descriptorForClass(Object.class); + return descriptor.matches(query, node); + } +} diff --git a/android/plugins/inspector/descriptors/utils/AccessibilityEvaluationUtil.java b/android/plugins/inspector/descriptors/utils/AccessibilityEvaluationUtil.java new file mode 100644 index 000000000..ddfa683b1 --- /dev/null +++ b/android/plugins/inspector/descriptors/utils/AccessibilityEvaluationUtil.java @@ -0,0 +1,383 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +package com.facebook.sonar.plugins.inspector.descriptors.utils; + +import android.graphics.Rect; +import android.support.v4.view.ViewCompat; +import android.support.v4.view.accessibility.AccessibilityNodeInfoCompat; +import android.text.TextUtils; +import android.view.View; +import android.view.ViewGroup; +import android.view.ViewParent; +import com.facebook.sonar.plugins.inspector.descriptors.utils.AccessibilityRoleUtil.AccessibilityRole; +import java.util.List; +import javax.annotation.Nullable; + +/** + * This class provides utility methods for determining certain accessibility properties of {@link + * View}s and {@link AccessibilityNodeInfoCompat}s. It is porting some of the checks from {@link + * com.googlecode.eyesfree.utils.AccessibilityNodeInfoUtils}, but has stripped many features which + * are unnecessary here. + */ +public class AccessibilityEvaluationUtil { + + private AccessibilityEvaluationUtil() {} + + /** + * Returns whether the specified node has text or a content description. + * + * @param node The node to check. + * @return {@code true} if the node has text. + */ + public static boolean hasText(@Nullable AccessibilityNodeInfoCompat node) { + return node != null + && node.getCollectionInfo() == null + && (!TextUtils.isEmpty(node.getText()) || !TextUtils.isEmpty(node.getContentDescription())); + } + + /** + * Returns whether the supplied {@link View} and {@link AccessibilityNodeInfoCompat} would produce + * spoken feedback if it were accessibility focused. NOTE: not all speaking nodes are focusable. + * + * @param view The {@link View} to evaluate + * @param node The {@link AccessibilityNodeInfoCompat} to evaluate + * @return {@code true} if it meets the criterion for producing spoken feedback + */ + public static boolean isSpeakingNode( + @Nullable AccessibilityNodeInfoCompat node, @Nullable View view) { + if (node == null || view == null) { + return false; + } + + final int important = ViewCompat.getImportantForAccessibility(view); + if (important == ViewCompat.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS + || (important == ViewCompat.IMPORTANT_FOR_ACCESSIBILITY_NO && node.getChildCount() <= 0)) { + return false; + } + + return node.isCheckable() || hasText(node) || hasNonActionableSpeakingDescendants(node, view); + } + + /** + * Determines if the supplied {@link View} and {@link AccessibilityNodeInfoCompat} has any + * children which are not independently accessibility focusable and also have a spoken + * description. + * + *

NOTE: Accessibility services will include these children's descriptions in the closest + * focusable ancestor. + * + * @param view The {@link View} to evaluate + * @param node The {@link AccessibilityNodeInfoCompat} to evaluate + * @return {@code true} if it has any non-actionable speaking descendants within its subtree + */ + public static boolean hasNonActionableSpeakingDescendants( + @Nullable AccessibilityNodeInfoCompat node, @Nullable View view) { + + if (node == null || view == null || !(view instanceof ViewGroup)) { + return false; + } + + final ViewGroup viewGroup = (ViewGroup) view; + for (int i = 0, count = viewGroup.getChildCount(); i < count; i++) { + final View childView = viewGroup.getChildAt(i); + + if (childView == null) { + continue; + } + + final AccessibilityNodeInfoCompat childNode = AccessibilityNodeInfoCompat.obtain(); + try { + ViewCompat.onInitializeAccessibilityNodeInfo(childView, childNode); + + if (!node.isVisibleToUser()) { + continue; + } + + if (isAccessibilityFocusable(childNode, childView)) { + continue; + } + + if (isSpeakingNode(childNode, childView)) { + return true; + } + } finally { + if (childNode != null) { + childNode.recycle(); + } + } + } + + return false; + } + + /** + * Determines if the provided {@link View} and {@link AccessibilityNodeInfoCompat} meet the + * criteria for gaining accessibility focus. + * + *

Note: this is evaluating general focusability by accessibility services, and does not mean + * this view will be guaranteed to be focused by specific services such as Talkback. For Talkback + * focusability, see {@link #isTalkbackFocusable(View)} + * + * @param view The {@link View} to evaluate + * @param node The {@link AccessibilityNodeInfoCompat} to evaluate + * @return {@code true} if it is possible to gain accessibility focus + */ + public static boolean isAccessibilityFocusable( + @Nullable AccessibilityNodeInfoCompat node, @Nullable View view) { + if (node == null || view == null) { + return false; + } + + // Never focus invisible nodes. + if (!node.isVisibleToUser()) { + return false; + } + + // Always focus "actionable" nodes. + if (isActionableForAccessibility(node)) { + return true; + } + + // only focus top-level list items with non-actionable speaking children. + return isTopLevelScrollItem(node, view) && isSpeakingNode(node, view); + } + + /** + * Determines whether the provided {@link View} and {@link AccessibilityNodeInfoCompat} is a + * top-level item in a scrollable container. + * + * @param view The {@link View} to evaluate + * @param node The {@link AccessibilityNodeInfoCompat} to evaluate + * @return {@code true} if it is a top-level item in a scrollable container. + */ + public static boolean isTopLevelScrollItem( + @Nullable AccessibilityNodeInfoCompat node, @Nullable View view) { + if (node == null || view == null) { + return false; + } + + final View parent = (View) ViewCompat.getParentForAccessibility(view); + if (parent == null) { + return false; + } + + if (node.isScrollable()) { + return true; + } + + final List actionList = node.getActionList(); + if (actionList.contains(AccessibilityNodeInfoCompat.ACTION_SCROLL_FORWARD) + || actionList.contains(AccessibilityNodeInfoCompat.ACTION_SCROLL_BACKWARD)) { + return true; + } + + // Top-level items in a scrolling pager are actually two levels down since the first + // level items in pagers are the pages themselves. + View grandparent = (View) ViewCompat.getParentForAccessibility(parent); + if (grandparent != null + && AccessibilityRoleUtil.getRole(grandparent) == AccessibilityRole.PAGER) { + return true; + } + + AccessibilityRole parentRole = AccessibilityRoleUtil.getRole(parent); + return parentRole == AccessibilityRole.LIST + || parentRole == AccessibilityRole.GRID + || parentRole == AccessibilityRole.SCROLL_VIEW + || parentRole == AccessibilityRole.HORIZONTAL_SCROLL_VIEW; + } + + /** + * Returns whether a node is actionable. That is, the node supports one of {@link + * AccessibilityNodeInfoCompat#isClickable()}, {@link AccessibilityNodeInfoCompat#isFocusable()}, + * or {@link AccessibilityNodeInfoCompat#isLongClickable()}. + * + * @param node The {@link AccessibilityNodeInfoCompat} to evaluate + * @return {@code true} if node is actionable. + */ + public static boolean isActionableForAccessibility(@Nullable AccessibilityNodeInfoCompat node) { + if (node == null) { + return false; + } + + if (node.isClickable() || node.isLongClickable() || node.isFocusable()) { + return true; + } + + final List actionList = node.getActionList(); + return actionList.contains(AccessibilityNodeInfoCompat.ACTION_CLICK) + || actionList.contains(AccessibilityNodeInfoCompat.ACTION_LONG_CLICK) + || actionList.contains(AccessibilityNodeInfoCompat.ACTION_FOCUS); + } + + /** + * Determines if any of the provided {@link View}'s and {@link AccessibilityNodeInfoCompat}'s + * ancestors can receive accessibility focus + * + * @param view The {@link View} to evaluate + * @param node The {@link AccessibilityNodeInfoCompat} to evaluate + * @return {@code true} if an ancestor of may receive accessibility focus + */ + public static boolean hasFocusableAncestor( + @Nullable AccessibilityNodeInfoCompat node, @Nullable View view) { + if (node == null || view == null) { + return false; + } + + final ViewParent parentView = ViewCompat.getParentForAccessibility(view); + if (!(parentView instanceof View)) { + return false; + } + + final AccessibilityNodeInfoCompat parentNode = AccessibilityNodeInfoCompat.obtain(); + try { + ViewCompat.onInitializeAccessibilityNodeInfo((View) parentView, parentNode); + if (parentNode == null) { + return false; + } + + if (hasEqualBoundsToViewRoot(parentNode, (View) parentView) + && parentNode.getChildCount() > 0) { + return false; + } + + if (isAccessibilityFocusable(parentNode, (View) parentView)) { + return true; + } + + if (hasFocusableAncestor(parentNode, (View) parentView)) { + return true; + } + } finally { + parentNode.recycle(); + } + return false; + } + + /** + * Returns whether a one given view is a descendant of another. + * + * @param view The {@link View} to evaluate + * @param potentialAncestor The potential ancestor {@link View} + * @return {@code true} if view is a descendant of potentialAncestor + */ + private static boolean viewIsDescendant(View view, View potentialAncestor) { + ViewParent parent = view.getParent(); + while (parent != null) { + if (parent == potentialAncestor) { + return true; + } + parent = parent.getParent(); + } + + return false; + } + + /** + * Returns whether a View has the same size and position as its View Root. + * + * @param view The {@link View} to evaluate + * @return {@code true} if view has equal bounds + */ + public static boolean hasEqualBoundsToViewRoot(AccessibilityNodeInfoCompat node, View view) { + AndroidRootResolver rootResolver = new AndroidRootResolver(); + List roots = rootResolver.listActiveRoots(); + if (roots != null) { + for (AndroidRootResolver.Root root : roots) { + if (view == root.view) { + return true; + } + + if (viewIsDescendant(view, root.view)) { + Rect nodeBounds = new Rect(); + node.getBoundsInScreen(nodeBounds); + + Rect viewRootBounds = new Rect(); + viewRootBounds.set( + root.param.x, + root.param.y, + root.param.width + root.param.x, + root.param.height + root.param.y); + + return nodeBounds.equals(viewRootBounds); + } + } + } + return false; + } + + /** + * Returns whether a given {@link View} will be focusable by Google's TalkBack screen reader. + * + * @param view The {@link View} to evaluate. + * @return {@code boolean} if the view will be ignored by TalkBack. + */ + public static boolean isTalkbackFocusable(View view) { + if (view == null) { + return false; + } + + final int important = ViewCompat.getImportantForAccessibility(view); + if (important == ViewCompat.IMPORTANT_FOR_ACCESSIBILITY_NO + || important == ViewCompat.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS) { + return false; + } + + // Go all the way up the tree to make sure no parent has hidden its descendants + ViewParent parent = view.getParent(); + while (parent instanceof View) { + if (ViewCompat.getImportantForAccessibility((View) parent) + == ViewCompat.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS) { + return false; + } + parent = parent.getParent(); + } + + final AccessibilityNodeInfoCompat node = ViewAccessibilityHelper.createNodeInfoFromView(view); + if (node == null) { + return false; + } + + // Non-leaf nodes identical in size to their View Root should not be focusable. + if (hasEqualBoundsToViewRoot(node, view) && node.getChildCount() > 0) { + return false; + } + + try { + if (!node.isVisibleToUser()) { + return false; + } + + if (isAccessibilityFocusable(node, view)) { + if (node.getChildCount() <= 0) { + // Leaves that are accessibility focusable are never ignored, even if they don't have a + // speakable description + return true; + } else if (isSpeakingNode(node, view)) { + // Node is focusable and has something to speak + return true; + } + + // Node is focusable and has nothing to speak + return false; + } + + // if view is not accessibility focusable, it needs to have text and no focusable ancestors. + if (!hasText(node)) { + return false; + } + + if (!hasFocusableAncestor(node, view)) { + return true; + } + + return false; + } finally { + node.recycle(); + } + } +} diff --git a/android/plugins/inspector/descriptors/utils/AccessibilityRoleUtil.java b/android/plugins/inspector/descriptors/utils/AccessibilityRoleUtil.java new file mode 100644 index 000000000..367b7732f --- /dev/null +++ b/android/plugins/inspector/descriptors/utils/AccessibilityRoleUtil.java @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ + +package com.facebook.sonar.plugins.inspector.descriptors.utils; + +import android.support.v4.view.ViewCompat; +import android.support.v4.view.accessibility.AccessibilityNodeInfoCompat; +import android.view.View; +import android.view.accessibility.AccessibilityNodeInfo; +import javax.annotation.Nullable; + +/** + * Utility class that handles the addition of a "role" for accessibility to either a View or + * AccessibilityNodeInfo. + */ +public class AccessibilityRoleUtil { + + /** + * These roles are defined by Google's TalkBack screen reader, and this list should be kept up to + * date with their implementation. Details can be seen in their source code here: + * + *

https://github.com/google/talkback/blob/master/utils/src/main/java/Role.java + */ + public enum AccessibilityRole { + NONE(null), + BUTTON("android.widget.Button"), + CHECK_BOX("android.widget.CompoundButton"), + DROP_DOWN_LIST("android.widget.Spinner"), + EDIT_TEXT("android.widget.EditText"), + GRID("android.widget.GridView"), + IMAGE("android.widget.ImageView"), + IMAGE_BUTTON("android.widget.ImageView"), + LIST("android.widget.AbsListView"), + PAGER("android.support.v4.view.ViewPager"), + RADIO_BUTTON("android.widget.RadioButton"), + SEEK_CONTROL("android.widget.SeekBar"), + SWITCH("android.widget.Switch"), + TAB_BAR("android.widget.TabWidget"), + TOGGLE_BUTTON("android.widget.ToggleButton"), + VIEW_GROUP("android.view.ViewGroup"), + WEB_VIEW("android.webkit.WebView"), + CHECKED_TEXT_VIEW("android.widget.CheckedTextView"), + PROGRESS_BAR("android.widget.ProgressBar"), + ACTION_BAR_TAB("android.app.ActionBar$Tab"), + DRAWER_LAYOUT("android.support.v4.widget.DrawerLayout"), + SLIDING_DRAWER("android.widget.SlidingDrawer"), + ICON_MENU("com.android.internal.view.menu.IconMenuView"), + TOAST("android.widget.Toast$TN"), + DATE_PICKER_DIALOG("android.app.DatePickerDialog"), + TIME_PICKER_DIALOG("android.app.TimePickerDialog"), + DATE_PICKER("android.widget.DatePicker"), + TIME_PICKER("android.widget.TimePicker"), + NUMBER_PICKER("android.widget.NumberPicker"), + SCROLL_VIEW("android.widget.ScrollView"), + HORIZONTAL_SCROLL_VIEW("android.widget.HorizontalScrollView"), + KEYBOARD_KEY("android.inputmethodservice.Keyboard$Key"); + + @Nullable private final String mValue; + + AccessibilityRole(String type) { + mValue = type; + } + + @Nullable + public String getValue() { + return mValue; + } + + public static AccessibilityRole fromValue(String value) { + for (AccessibilityRole role : AccessibilityRole.values()) { + if (role.getValue() != null && role.getValue().equals(value)) { + return role; + } + } + return AccessibilityRole.NONE; + } + } + + private AccessibilityRoleUtil() { + // No instances + } + + public static AccessibilityRole getRole(View view) { + AccessibilityNodeInfoCompat nodeInfo = AccessibilityNodeInfoCompat.obtain(); + ViewCompat.onInitializeAccessibilityNodeInfo(view, nodeInfo); + AccessibilityRole role = getRole(nodeInfo); + nodeInfo.recycle(); + return role; + } + + public static AccessibilityRole getRole(AccessibilityNodeInfo nodeInfo) { + return getRole(new AccessibilityNodeInfoCompat(nodeInfo)); + } + + public static AccessibilityRole getRole(AccessibilityNodeInfoCompat nodeInfo) { + AccessibilityRole role = AccessibilityRole.fromValue((String) nodeInfo.getClassName()); + if (role.equals(AccessibilityRole.IMAGE_BUTTON) || role.equals(AccessibilityRole.IMAGE)) { + return nodeInfo.isClickable() ? AccessibilityRole.IMAGE_BUTTON : AccessibilityRole.IMAGE; + } + + if (role.equals(AccessibilityRole.NONE)) { + AccessibilityNodeInfoCompat.CollectionInfoCompat collection = nodeInfo.getCollectionInfo(); + if (collection != null) { + // RecyclerView will be classified as a list or grid. + if (collection.getRowCount() > 1 && collection.getColumnCount() > 1) { + return AccessibilityRole.GRID; + } else { + return AccessibilityRole.LIST; + } + } + } + + return role; + } +} diff --git a/android/plugins/inspector/descriptors/utils/AccessibilityUtil.java b/android/plugins/inspector/descriptors/utils/AccessibilityUtil.java new file mode 100644 index 000000000..3d556894d --- /dev/null +++ b/android/plugins/inspector/descriptors/utils/AccessibilityUtil.java @@ -0,0 +1,357 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ + +package com.facebook.sonar.plugins.inspector.descriptors.utils; + +import static android.content.Context.ACCESSIBILITY_SERVICE; + +import android.content.Context; +import android.graphics.Rect; +import android.os.Build; +import android.support.v4.view.ViewCompat; +import android.support.v4.view.accessibility.AccessibilityNodeInfoCompat; +import android.text.TextUtils; +import android.view.View; +import android.view.ViewGroup; +import android.view.ViewParent; +import android.view.accessibility.AccessibilityManager; +import android.widget.EditText; +import com.facebook.sonar.core.SonarArray; +import com.facebook.sonar.core.SonarObject; +import javax.annotation.Nullable; + +/** + * This class provides utility methods for determining certain accessibility properties of {@link + * View}s and {@link AccessibilityNodeInfoCompat}s. It is porting some of the checks from {@link + * com.googlecode.eyesfree.utils.AccessibilityNodeInfoUtils}, but has stripped many features which + * are unnecessary here. + */ +public final class AccessibilityUtil { + private AccessibilityUtil() {} + + public static final EnumMapping sAccessibilityActionMapping = + new EnumMapping("UNKNOWN") { + { + put("FOCUS", AccessibilityNodeInfoCompat.ACTION_FOCUS); + put("CLEAR_FOCUS", AccessibilityNodeInfoCompat.ACTION_CLEAR_FOCUS); + put("SELECT", AccessibilityNodeInfoCompat.ACTION_SELECT); + put("CLEAR_SELECTION", AccessibilityNodeInfoCompat.ACTION_CLEAR_SELECTION); + put("CLICK", AccessibilityNodeInfoCompat.ACTION_CLICK); + put("LONG_CLICK", AccessibilityNodeInfoCompat.ACTION_LONG_CLICK); + put("ACCESSIBILITY_FOCUS", AccessibilityNodeInfoCompat.ACTION_ACCESSIBILITY_FOCUS); + put( + "CLEAR_ACCESSIBILITY_FOCUS", + AccessibilityNodeInfoCompat.ACTION_CLEAR_ACCESSIBILITY_FOCUS); + put( + "NEXT_AT_MOVEMENT_GRANULARITY", + AccessibilityNodeInfoCompat.ACTION_NEXT_AT_MOVEMENT_GRANULARITY); + put( + "PREVIOUS_AT_MOVEMENT_GRANULARITY", + AccessibilityNodeInfoCompat.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY); + put("NEXT_HTML_ELEMENT", AccessibilityNodeInfoCompat.ACTION_NEXT_HTML_ELEMENT); + put("PREVIOUS_HTML_ELEMENT", AccessibilityNodeInfoCompat.ACTION_PREVIOUS_HTML_ELEMENT); + put("SCROLL_FORWARD", AccessibilityNodeInfoCompat.ACTION_SCROLL_FORWARD); + put("SCROLL_BACKWARD", AccessibilityNodeInfoCompat.ACTION_SCROLL_BACKWARD); + put("CUT", AccessibilityNodeInfoCompat.ACTION_CUT); + put("COPY", AccessibilityNodeInfoCompat.ACTION_COPY); + put("PASTE", AccessibilityNodeInfoCompat.ACTION_PASTE); + put("SET_SELECTION", AccessibilityNodeInfoCompat.ACTION_SET_SELECTION); + put("SET_SELECTION", AccessibilityNodeInfoCompat.ACTION_SET_SELECTION); + put("EXPAND", AccessibilityNodeInfoCompat.ACTION_EXPAND); + put("COLLAPSE", AccessibilityNodeInfoCompat.ACTION_COLLAPSE); + put("DISMISS", AccessibilityNodeInfoCompat.ACTION_DISMISS); + put("SET_TEXT", AccessibilityNodeInfoCompat.ACTION_SET_TEXT); + } + }; + + public static final EnumMapping sImportantForAccessibilityMapping = + new EnumMapping("AUTO") { + { + put("AUTO", View.IMPORTANT_FOR_ACCESSIBILITY_AUTO); + put("NO", View.IMPORTANT_FOR_ACCESSIBILITY_NO); + put("YES", View.IMPORTANT_FOR_ACCESSIBILITY_YES); + put("NO_HIDE_DESCENDANTS", View.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS); + } + }; + + /** + * Given a {@link Context}, determine if any accessibility service is running. + * + * @param context The {@link Context} used to get the {@link AccessibilityManager}. + * @return {@code true} if an accessibility service is currently running. + */ + public static boolean isAccessibilityEnabled(Context context) { + return ((AccessibilityManager) context.getSystemService(ACCESSIBILITY_SERVICE)).isEnabled(); + } + + /** + * Returns a sentence describing why a given {@link View} will be ignored by Google's TalkBack + * screen reader. + * + * @param view The {@link View} to evaluate. + * @return {@code String} describing why a {@link View} is ignored. + */ + public static String getTalkbackIgnoredReasons(View view) { + final int important = ViewCompat.getImportantForAccessibility(view); + + if (important == ViewCompat.IMPORTANT_FOR_ACCESSIBILITY_NO) { + return "View has importantForAccessibility set to 'NO'."; + } + + if (important == ViewCompat.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS) { + return "View has importantForAccessibility set to 'NO_HIDE_DESCENDANTS'."; + } + + ViewParent parent = view.getParent(); + while (parent instanceof View) { + if (ViewCompat.getImportantForAccessibility((View) parent) + == ViewCompat.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS) { + return "An ancestor View has importantForAccessibility set to 'NO_HIDE_DESCENDANTS'."; + } + parent = parent.getParent(); + } + + final AccessibilityNodeInfoCompat node = ViewAccessibilityHelper.createNodeInfoFromView(view); + if (node == null) { + return "AccessibilityNodeInfo cannot be found."; + } + + try { + if (AccessibilityEvaluationUtil.hasEqualBoundsToViewRoot(node, view)) { + return "View has the same dimensions as the View Root."; + } + + if (!node.isVisibleToUser()) { + return "View is not visible."; + } + + if (AccessibilityEvaluationUtil.isAccessibilityFocusable(node, view)) { + return "View is actionable, but has no description."; + } + + if (AccessibilityEvaluationUtil.hasText(node)) { + return "View is not actionable, and an ancestor View has co-opted its description."; + } + + return "View is not actionable and has no description."; + } finally { + node.recycle(); + } + } + + /** + * Returns a sentence describing why a given {@link View} will be focusable by Google's TalkBack + * screen reader. + * + * @param view The {@link View} to evaluate. + * @return {@code String} describing why a {@link View} is focusable. + */ + @Nullable + public static String getTalkbackFocusableReasons(View view) { + final AccessibilityNodeInfoCompat node = ViewAccessibilityHelper.createNodeInfoFromView(view); + if (node == null) { + return null; + } + try { + final boolean hasText = AccessibilityEvaluationUtil.hasText(node); + final boolean isCheckable = node.isCheckable(); + final boolean hasNonActionableSpeakingDescendants = + AccessibilityEvaluationUtil.hasNonActionableSpeakingDescendants(node, view); + + if (AccessibilityEvaluationUtil.isActionableForAccessibility(node)) { + if (node.getChildCount() <= 0) { + return "View is actionable and has no children."; + } else if (hasText) { + return "View is actionable and has a description."; + } else if (isCheckable) { + return "View is actionable and checkable."; + } else if (hasNonActionableSpeakingDescendants) { + return "View is actionable and has non-actionable descendants with descriptions."; + } + } + + if (AccessibilityEvaluationUtil.isTopLevelScrollItem(node, view)) { + if (hasText) { + return "View is a direct child of a scrollable container and has a description."; + } else if (isCheckable) { + return "View is a direct child of a scrollable container and is checkable."; + } else if (hasNonActionableSpeakingDescendants) { + return "View is a direct child of a scrollable container and has non-actionable " + + "descendants with descriptions."; + } + } + + if (hasText) { + return "View has a description and is not actionable, but has no actionable ancestor."; + } + + return null; + } finally { + node.recycle(); + } + } + + /** + * Creates the text that Gogole's TalkBack screen reader will read aloud for a given {@link View}. + * This may be any combination of the {@link View}'s {@code text}, {@code contentDescription}, and + * the {@code text} and {@code contentDescription} of any ancestor {@link View}. + * + *

Note: This string does not include any additional semantic information that Talkback will + * read, such as "Button", or "disabled". + * + * @param view The {@link View} to evaluate. + * @return {@code String} describing why a {@link View} is focusable. + */ + @Nullable + public static CharSequence getTalkbackDescription(View view) { + final AccessibilityNodeInfoCompat node = ViewAccessibilityHelper.createNodeInfoFromView(view); + if (node == null) { + return null; + } + try { + final CharSequence contentDescription = node.getContentDescription(); + final CharSequence nodeText = node.getText(); + + final boolean hasNodeText = !TextUtils.isEmpty(nodeText); + final boolean isEditText = view instanceof EditText; + + // EditText's prioritize their own text content over a contentDescription + if (!TextUtils.isEmpty(contentDescription) && (!isEditText || !hasNodeText)) { + return contentDescription; + } + + if (hasNodeText) { + return nodeText; + } + + // If there are child views and no contentDescription the text of all non-focusable children, + // comma separated, becomes the description. + if (view instanceof ViewGroup) { + final StringBuilder concatChildDescription = new StringBuilder(); + final String separator = ", "; + final ViewGroup viewGroup = (ViewGroup) view; + + for (int i = 0, count = viewGroup.getChildCount(); i < count; i++) { + final View child = viewGroup.getChildAt(i); + + final AccessibilityNodeInfoCompat childNodeInfo = AccessibilityNodeInfoCompat.obtain(); + ViewCompat.onInitializeAccessibilityNodeInfo(child, childNodeInfo); + + CharSequence childNodeDescription = null; + if (AccessibilityEvaluationUtil.isSpeakingNode(childNodeInfo, child) + && !AccessibilityEvaluationUtil.isAccessibilityFocusable(childNodeInfo, child)) { + childNodeDescription = getTalkbackDescription(child); + } + + if (!TextUtils.isEmpty(childNodeDescription)) { + if (concatChildDescription.length() > 0) { + concatChildDescription.append(separator); + } + concatChildDescription.append(childNodeDescription); + } + childNodeInfo.recycle(); + } + + return concatChildDescription.length() > 0 ? concatChildDescription.toString() : null; + } + + return null; + } finally { + node.recycle(); + } + } + + /** + * Creates a {@link SonarObject} of useful properties of AccessibilityNodeInfo, to be shown in the + * Sonar Layout Inspector. All properties are immutable since they are all derived from various + * {@link View} properties. + * + * @param view The {@link View} to derive the AccessibilityNodeInfo properties from. + * @return {@link SonarObject} containing the properties. + */ + @Nullable + public static SonarObject getAccessibilityNodeInfoProperties(View view) { + final AccessibilityNodeInfoCompat nodeInfo = + ViewAccessibilityHelper.createNodeInfoFromView(view); + if (nodeInfo == null) { + return null; + } + + final SonarObject.Builder nodeInfoProps = new SonarObject.Builder(); + final Rect bounds = new Rect(); + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + final SonarArray.Builder actionsArrayBuilder = new SonarArray.Builder(); + for (AccessibilityNodeInfoCompat.AccessibilityActionCompat action : + nodeInfo.getActionList()) { + final String actionLabel = (String) action.getLabel(); + if (actionLabel != null) { + actionsArrayBuilder.put(actionLabel); + } else { + actionsArrayBuilder.put( + AccessibilityUtil.sAccessibilityActionMapping.get(action.getId(), false)); + } + } + nodeInfoProps.put("actions", actionsArrayBuilder.build()); + } + + nodeInfoProps + .put("clickable", nodeInfo.isClickable()) + .put("content-description", nodeInfo.getContentDescription()) + .put("text", nodeInfo.getText()) + .put("focused", nodeInfo.isAccessibilityFocused()) + .put("long-clickable", nodeInfo.isLongClickable()) + .put("focusable", nodeInfo.isFocusable()); + + nodeInfo.getBoundsInParent(bounds); + nodeInfoProps.put( + "parent-bounds", + new SonarObject.Builder() + .put("width", bounds.width()) + .put("height", bounds.height()) + .put("top", bounds.top) + .put("left", bounds.left) + .put("bottom", bounds.bottom) + .put("right", bounds.right)); + + nodeInfo.getBoundsInScreen(bounds); + nodeInfoProps.put( + "screen-bounds", + new SonarObject.Builder() + .put("width", bounds.width()) + .put("height", bounds.height()) + .put("top", bounds.top) + .put("left", bounds.left) + .put("bottom", bounds.bottom) + .put("right", bounds.right)); + + nodeInfo.recycle(); + + return nodeInfoProps.build(); + } + + /** + * Modifies a {@link SonarObject.Builder} to add Talkback-specific Accessibiltiy properties to be + * shown in the Sonar Layout Inspector. + * + * @param props The {@link SonarObject.Builder} to add the properties to. + * @param view The {@link View} to derive the properties from. + */ + public static void addTalkbackProperties(SonarObject.Builder props, View view) { + if (!AccessibilityEvaluationUtil.isTalkbackFocusable(view)) { + props + .put("talkback-ignored", true) + .put("talkback-ignored-reasons", getTalkbackIgnoredReasons(view)); + } else { + props + .put("talkback-focusable", true) + .put("talkback-focusable-reasons", getTalkbackFocusableReasons(view)) + .put("talkback-description", getTalkbackDescription(view)); + } + } +} diff --git a/android/plugins/inspector/descriptors/utils/AndroidRootResolver.java b/android/plugins/inspector/descriptors/utils/AndroidRootResolver.java new file mode 100644 index 000000000..c444f897e --- /dev/null +++ b/android/plugins/inspector/descriptors/utils/AndroidRootResolver.java @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ + +package com.facebook.sonar.plugins.inspector.descriptors.utils; + +import static android.view.WindowManager.LayoutParams; + +import android.os.Build; +import android.view.View; +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import javax.annotation.Nullable; + +public final class AndroidRootResolver { + + private static final String WINDOW_MANAGER_IMPL_CLAZZ = "android.view.WindowManagerImpl"; + private static final String WINDOW_MANAGER_GLOBAL_CLAZZ = "android.view.WindowManagerGlobal"; + private static final String VIEWS_FIELD = "mViews"; + private static final String WINDOW_PARAMS_FIELD = "mParams"; + private static final String GET_DEFAULT_IMPL = "getDefault"; + private static final String GET_GLOBAL_INSTANCE = "getInstance"; + + private boolean initialized; + private Object windowManagerObj; + private Field viewsField; + private Field paramsField; + + public static class Root { + public final View view; + public final LayoutParams param; + + private Root(View view, LayoutParams param) { + this.view = view; + this.param = param; + } + } + + public @Nullable List listActiveRoots() { + if (!initialized) { + initialize(); + } + + if (null == windowManagerObj) { + return null; + } + + if (null == viewsField) { + return null; + } + if (null == paramsField) { + return null; + } + + List views = null; + List params = null; + + try { + if (Build.VERSION.SDK_INT < 19) { + views = Arrays.asList((View[]) viewsField.get(windowManagerObj)); + params = Arrays.asList((LayoutParams[]) paramsField.get(windowManagerObj)); + } else { + views = (List) viewsField.get(windowManagerObj); + params = (List) paramsField.get(windowManagerObj); + } + } catch (RuntimeException | IllegalAccessException re) { + return null; + } + + List roots = new ArrayList<>(); + for (int i = 0, stop = views.size(); i < stop; i++) { + roots.add(new Root(views.get(i), params.get(i))); + } + return roots; + } + + private void initialize() { + initialized = true; + String accessClass = + Build.VERSION.SDK_INT > 16 ? WINDOW_MANAGER_GLOBAL_CLAZZ : WINDOW_MANAGER_IMPL_CLAZZ; + String instanceMethod = Build.VERSION.SDK_INT > 16 ? GET_GLOBAL_INSTANCE : GET_DEFAULT_IMPL; + + try { + Class clazz = Class.forName(accessClass); + Method getMethod = clazz.getMethod(instanceMethod); + windowManagerObj = getMethod.invoke(null); + viewsField = clazz.getDeclaredField(VIEWS_FIELD); + viewsField.setAccessible(true); + paramsField = clazz.getDeclaredField(WINDOW_PARAMS_FIELD); + paramsField.setAccessible(true); + } catch (InvocationTargetException | IllegalAccessException | RuntimeException | NoSuchMethodException | NoSuchFieldException | ClassNotFoundException ignored) { + } + } +} diff --git a/android/plugins/inspector/descriptors/utils/EnumMapping.java b/android/plugins/inspector/descriptors/utils/EnumMapping.java new file mode 100644 index 000000000..08719a6f4 --- /dev/null +++ b/android/plugins/inspector/descriptors/utils/EnumMapping.java @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ + +package com.facebook.sonar.plugins.inspector.descriptors.utils; + +import static com.facebook.sonar.plugins.inspector.InspectorValue.Type.Enum; + +import android.support.v4.util.SimpleArrayMap; +import com.facebook.sonar.plugins.inspector.InspectorValue; + +public class EnumMapping { + private final SimpleArrayMap mMapping = new SimpleArrayMap<>(); + private final String mDefaultKey; + + public EnumMapping(String defaultKey) { + mDefaultKey = defaultKey; + } + + public void put(String s, int i) { + mMapping.put(s, i); + } + + public InspectorValue get(final int i) { + return get(i, true); + } + + public InspectorValue get(final int i, final boolean mutable) { + for (int ii = 0, count = mMapping.size(); ii < count; ii++) { + if (mMapping.valueAt(ii) == i) { + return mutable + ? InspectorValue.mutable(Enum, mMapping.keyAt(ii)) + : InspectorValue.immutable(Enum, mMapping.keyAt(ii)); + } + } + return mutable + ? InspectorValue.mutable(Enum, mDefaultKey) + : InspectorValue.immutable(Enum, mDefaultKey); + } + + public int get(String s) { + if (mMapping.containsKey(s)) { + return mMapping.get(s); + } + return mMapping.get(mDefaultKey); + } +} diff --git a/android/plugins/inspector/descriptors/utils/ViewAccessibilityHelper.java b/android/plugins/inspector/descriptors/utils/ViewAccessibilityHelper.java new file mode 100644 index 000000000..904219916 --- /dev/null +++ b/android/plugins/inspector/descriptors/utils/ViewAccessibilityHelper.java @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ + +package com.facebook.sonar.plugins.inspector.descriptors.utils; + +import android.support.v4.view.ViewCompat; +import android.support.v4.view.accessibility.AccessibilityNodeInfoCompat; +import android.view.View; +import javax.annotation.Nullable; + +/** Class that helps with accessibility by providing useful methods. */ +public final class ViewAccessibilityHelper { + + /** + * Creates and returns an {@link AccessibilityNodeInfoCompat} from the the provided {@link View}. + * Note: This does not handle recycling of the {@link AccessibilityNodeInfoCompat}. + * + * @param view The {@link View} to create the {@link AccessibilityNodeInfoCompat} from. + * @return {@link AccessibilityNodeInfoCompat} + */ + @Nullable + public static AccessibilityNodeInfoCompat createNodeInfoFromView(View view) { + if (view == null) { + return null; + } + + final AccessibilityNodeInfoCompat nodeInfo = AccessibilityNodeInfoCompat.obtain(); + + // For some unknown reason, Android seems to occasionally throw a NPE from + // onInitializeAccessibilityNodeInfo. + try { + ViewCompat.onInitializeAccessibilityNodeInfo(view, nodeInfo); + } catch (NullPointerException e) { + if (nodeInfo != null) { + nodeInfo.recycle(); + } + return null; + } + + return nodeInfo; + } + +} diff --git a/android/plugins/inspector/litho-sonar/DebugComponentDescriptor.java b/android/plugins/inspector/litho-sonar/DebugComponentDescriptor.java new file mode 100644 index 000000000..39e2cdaa6 --- /dev/null +++ b/android/plugins/inspector/litho-sonar/DebugComponentDescriptor.java @@ -0,0 +1,696 @@ +// Copyright 2004-present Facebook. All Rights Reserved. + +package com.facebook.litho.sonar; + +import static com.facebook.litho.annotations.ImportantForAccessibility.IMPORTANT_FOR_ACCESSIBILITY_NO; +import static com.facebook.litho.annotations.ImportantForAccessibility.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS; +import static com.facebook.sonar.plugins.inspector.InspectorValue.Type.Color; +import static com.facebook.sonar.plugins.inspector.InspectorValue.Type.Enum; +import static com.facebook.sonar.plugins.inspector.InspectorValue.Type.Number; + +import android.graphics.Rect; +import android.graphics.drawable.ColorDrawable; +import android.graphics.drawable.Drawable; +import android.support.v4.util.Pair; +import android.view.View; +import com.facebook.litho.Component; +import com.facebook.litho.ComponentContext; +import com.facebook.litho.ComponentLifecycle; +import com.facebook.litho.DebugComponent; +import com.facebook.litho.DebugLayoutNode; +import com.facebook.litho.EventHandler; +import com.facebook.litho.LithoView; +import com.facebook.litho.annotations.Prop; +import com.facebook.litho.annotations.State; +import com.facebook.litho.reference.Reference; +import com.facebook.sonar.core.SonarDynamic; +import com.facebook.sonar.core.SonarObject; +import com.facebook.sonar.plugins.inspector.HighlightedOverlay; +import com.facebook.sonar.plugins.inspector.InspectorValue; +import com.facebook.sonar.plugins.inspector.Named; +import com.facebook.sonar.plugins.inspector.NodeDescriptor; +import com.facebook.sonar.plugins.inspector.Touch; +import com.facebook.sonar.plugins.inspector.descriptors.ObjectDescriptor; +import com.facebook.sonar.plugins.inspector.descriptors.utils.AccessibilityUtil; +import com.facebook.yoga.YogaAlign; +import com.facebook.yoga.YogaDirection; +import com.facebook.yoga.YogaEdge; +import com.facebook.yoga.YogaFlexDirection; +import com.facebook.yoga.YogaJustify; +import com.facebook.yoga.YogaPositionType; +import com.facebook.yoga.YogaValue; +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import javax.annotation.Nullable; + +public class DebugComponentDescriptor extends NodeDescriptor { + + private Map>> mOverrides = new HashMap<>(); + private DebugComponent.Overrider mOverrider = + new DebugComponent.Overrider() { + @Override + public void applyComponentOverrides(String key, Component component) { + final List> overrides = mOverrides.get(key); + if (overrides == null) { + return; + } + + for (Pair override : overrides) { + if (override.first[0].equals("Props")) { + applyReflectiveOverride(component, override.first[1], override.second); + } + } + } + + @Override + public void applyStateOverrides( + String key, ComponentLifecycle.StateContainer stateContainer) { + final List> overrides = mOverrides.get(key); + if (overrides == null) { + return; + } + + for (Pair override : overrides) { + if (override.first[0].equals("State")) { + applyReflectiveOverride(stateContainer, override.first[1], override.second); + } + } + } + + @Override + public void applyLayoutOverrides(String key, DebugLayoutNode node) { + final List> overrides = mOverrides.get(key); + if (overrides == null) { + return; + } + + for (Pair override : overrides) { + if (override.first[0].equals("Layout")) { + try { + applyLayoutOverride( + node, + Arrays.copyOfRange(override.first, 1, override.first.length), + override.second); + } catch (Exception ignored) { + } + } else if (override.first[0].equals("Accessibility")) { + applyAccessibilityOverride(node, override.first[1], override.second); + } + } + } + }; + + @Override + public void init(DebugComponent node) { + // We rely on the LithoView being invalidated when a component hierarchy changes. + } + + @Override + public String getId(DebugComponent node) { + return node.getGlobalKey(); + } + + @Override + public String getName(DebugComponent node) throws Exception { + NodeDescriptor componentDescriptor = descriptorForClass(node.getComponent().getClass()); + if (componentDescriptor.getClass() != ObjectDescriptor.class) { + return componentDescriptor.getName(node.getComponent()); + } + return node.getComponent().getSimpleName(); + } + + @Override + public int getChildCount(DebugComponent node) { + if (node.getMountedView() != null || node.getMountedDrawable() != null) { + return 1; + } else { + return node.getChildComponents().size(); + } + } + + @Override + public Object getChildAt(DebugComponent node, int index) { + final View mountedView = node.getMountedView(); + final Drawable mountedDrawable = node.getMountedDrawable(); + + if (mountedView != null) { + return mountedView; + } else if (mountedDrawable != null) { + return mountedDrawable; + } else { + return node.getChildComponents().get(index); + } + } + + @Override + public List> getData(DebugComponent node) throws Exception { + NodeDescriptor componentDescriptor = descriptorForClass(node.getComponent().getClass()); + if (componentDescriptor.getClass() != ObjectDescriptor.class) { + return componentDescriptor.getData(node.getComponent()); + } + + final List> data = new ArrayList<>(); + + final SonarObject layoutData = getLayoutData(node); + if (layoutData != null) { + data.add(new Named<>("Layout", layoutData)); + } + + final SonarObject propData = getPropData(node); + if (propData != null) { + data.add(new Named<>("Props", propData)); + } + + final SonarObject stateData = getStateData(node); + if (stateData != null) { + data.add(new Named<>("State", stateData)); + } + + final SonarObject accessibilityData = getAccessibilityData(node); + if (accessibilityData != null) { + data.add(new Named<>("Accessibility", accessibilityData)); + } + + return data; + } + + @Nullable + private static SonarObject getLayoutData(DebugComponent node) { + final DebugLayoutNode layout = node.getLayoutNode(); + if (layout == null) { + return null; + } + + final SonarObject.Builder data = new SonarObject.Builder(); + data.put("background", fromReference(node.getContext(), layout.getBackground())); + data.put("foreground", fromDrawable(layout.getForeground())); + + data.put("direction", InspectorValue.mutable(Enum, layout.getLayoutDirection().toString())); + data.put("flex-direction", InspectorValue.mutable(Enum, layout.getFlexDirection().toString())); + data.put( + "justify-content", InspectorValue.mutable(Enum, layout.getJustifyContent().toString())); + data.put("align-items", InspectorValue.mutable(Enum, layout.getAlignItems().toString())); + data.put("align-self", InspectorValue.mutable(Enum, layout.getAlignSelf().toString())); + data.put("align-content", InspectorValue.mutable(Enum, layout.getAlignContent().toString())); + data.put("position-type", InspectorValue.mutable(Enum, layout.getPositionType().toString())); + + data.put("flex-grow", fromFloat(layout.getFlexGrow())); + data.put("flex-shrink", fromFloat(layout.getFlexShrink())); + data.put("flex-basis", fromYogaValue(layout.getFlexBasis())); + + data.put("width", fromYogaValue(layout.getWidth())); + data.put("min-width", fromYogaValue(layout.getMinWidth())); + data.put("max-width", fromYogaValue(layout.getMaxWidth())); + + data.put("height", fromYogaValue(layout.getHeight())); + data.put("min-height", fromYogaValue(layout.getMinHeight())); + data.put("max-height", fromYogaValue(layout.getMaxHeight())); + + data.put("aspect-ratio", fromFloat(layout.getAspectRatio())); + + data.put( + "margin", + new SonarObject.Builder() + .put("left", fromYogaValue(layout.getMargin(YogaEdge.LEFT))) + .put("top", fromYogaValue(layout.getMargin(YogaEdge.TOP))) + .put("right", fromYogaValue(layout.getMargin(YogaEdge.RIGHT))) + .put("bottom", fromYogaValue(layout.getMargin(YogaEdge.BOTTOM))) + .put("start", fromYogaValue(layout.getMargin(YogaEdge.START))) + .put("end", fromYogaValue(layout.getMargin(YogaEdge.END))) + .put("horizontal", fromYogaValue(layout.getMargin(YogaEdge.HORIZONTAL))) + .put("vertical", fromYogaValue(layout.getMargin(YogaEdge.VERTICAL))) + .put("all", fromYogaValue(layout.getMargin(YogaEdge.ALL)))); + + data.put( + "padding", + new SonarObject.Builder() + .put("left", fromYogaValue(layout.getPadding(YogaEdge.LEFT))) + .put("top", fromYogaValue(layout.getPadding(YogaEdge.TOP))) + .put("right", fromYogaValue(layout.getPadding(YogaEdge.RIGHT))) + .put("bottom", fromYogaValue(layout.getPadding(YogaEdge.BOTTOM))) + .put("start", fromYogaValue(layout.getPadding(YogaEdge.START))) + .put("end", fromYogaValue(layout.getPadding(YogaEdge.END))) + .put("horizontal", fromYogaValue(layout.getPadding(YogaEdge.HORIZONTAL))) + .put("vertical", fromYogaValue(layout.getPadding(YogaEdge.VERTICAL))) + .put("all", fromYogaValue(layout.getPadding(YogaEdge.ALL)))); + + data.put( + "border", + new SonarObject.Builder() + .put("left", fromFloat(layout.getBorderWidth(YogaEdge.LEFT))) + .put("top", fromFloat(layout.getBorderWidth(YogaEdge.TOP))) + .put("right", fromFloat(layout.getBorderWidth(YogaEdge.RIGHT))) + .put("bottom", fromFloat(layout.getBorderWidth(YogaEdge.BOTTOM))) + .put("start", fromFloat(layout.getBorderWidth(YogaEdge.START))) + .put("end", fromFloat(layout.getBorderWidth(YogaEdge.END))) + .put("horizontal", fromFloat(layout.getBorderWidth(YogaEdge.HORIZONTAL))) + .put("vertical", fromFloat(layout.getBorderWidth(YogaEdge.VERTICAL))) + .put("all", fromFloat(layout.getBorderWidth(YogaEdge.ALL)))); + + data.put( + "position", + new SonarObject.Builder() + .put("left", fromYogaValue(layout.getPosition(YogaEdge.LEFT))) + .put("top", fromYogaValue(layout.getPosition(YogaEdge.TOP))) + .put("right", fromYogaValue(layout.getPosition(YogaEdge.RIGHT))) + .put("bottom", fromYogaValue(layout.getPosition(YogaEdge.BOTTOM))) + .put("start", fromYogaValue(layout.getPosition(YogaEdge.START))) + .put("end", fromYogaValue(layout.getPosition(YogaEdge.END))) + .put("horizontal", fromYogaValue(layout.getPosition(YogaEdge.HORIZONTAL))) + .put("vertical", fromYogaValue(layout.getPosition(YogaEdge.VERTICAL))) + .put("all", fromYogaValue(layout.getPosition(YogaEdge.ALL)))); + + return data.build(); + } + + @Nullable + private static SonarObject getPropData(DebugComponent node) { + if (node.isInternalComponent()) { + return null; + } + + final Component component = node.getComponent(); + final SonarObject.Builder props = new SonarObject.Builder(); + + boolean hasProps = false; + for (Field f : component.getClass().getDeclaredFields()) { + try { + f.setAccessible(true); + + final Prop annotation = f.getAnnotation(Prop.class); + if (annotation != null) { + switch (annotation.resType()) { + case COLOR: + props.put(f.getName(), fromColor((Integer) f.get(component))); + break; + case DRAWABLE: + props.put(f.getName(), fromDrawable((Drawable) f.get(component))); + break; + default: + if (f.get(component) != null + && PropWithDescription.class.isAssignableFrom(f.get(component).getClass())) { + final Object description = + ((PropWithDescription) f.get(component)) + .getSonarLayoutInspectorPropDescription(); + // Treat the description as immutable for now, because it's a "translation" of the + // actual prop, + // mutating them is not going to change the original prop. + if (description instanceof Map) { + final Map descriptionMap = (Map) description; + for (Map.Entry entry : descriptionMap.entrySet()) { + props.put( + entry.getKey().toString(), InspectorValue.immutable(entry.getValue())); + } + } else { + props.put(f.getName(), InspectorValue.immutable(description)); + } + } else { + if (isTypeMutable(f.getType())) { + props.put(f.getName(), InspectorValue.mutable(f.get(component))); + } else { + props.put(f.getName(), InspectorValue.immutable(f.get(component))); + } + } + break; + } + hasProps = true; + } + } catch (Exception ignored) { + } + } + + return hasProps ? props.build() : null; + } + + @Nullable + private static SonarObject getStateData(DebugComponent node) { + if (node.isInternalComponent()) { + return null; + } + + final ComponentLifecycle.StateContainer stateContainer = node.getStateContainer(); + if (stateContainer == null) { + return null; + } + + final SonarObject.Builder state = new SonarObject.Builder(); + + boolean hasState = false; + for (Field f : stateContainer.getClass().getDeclaredFields()) { + try { + f.setAccessible(true); + + final State annotation = f.getAnnotation(State.class); + if (annotation != null) { + if (isTypeMutable(f.getType())) { + state.put(f.getName(), InspectorValue.mutable(f.get(stateContainer))); + } else { + state.put(f.getName(), InspectorValue.immutable(f.get(stateContainer))); + } + hasState = true; + } + } catch (Exception ignored) { + } + } + + return hasState ? state.build() : null; + } + + private static boolean isTypeMutable(Class type) { + if (type == int.class || type == Integer.class) { + return true; + } else if (type == long.class || type == Long.class) { + return true; + } else if (type == float.class || type == Float.class) { + return true; + } else if (type == double.class || type == Double.class) { + return true; + } else if (type == boolean.class || type == Boolean.class) { + return true; + } else if (type.isAssignableFrom(String.class)) { + return true; + } + return false; + } + + @Nullable + private static SonarObject getAccessibilityData(DebugComponent node) { + final DebugLayoutNode layout = node.getLayoutNode(); + if (layout == null) { + return null; + } + + final View hostView = node.getComponentHost(); + final SonarObject.Builder accessibilityProps = new SonarObject.Builder(); + + // This needs to be an empty string to be mutable. See t20470623. + final CharSequence contentDescription = + layout.getContentDescription() != null ? layout.getContentDescription() : ""; + accessibilityProps.put("content-description", InspectorValue.mutable(contentDescription)); + accessibilityProps.put("focusable", InspectorValue.mutable(layout.getFocusable())); + accessibilityProps.put( + "important-for-accessibility", + AccessibilityUtil.sImportantForAccessibilityMapping.get( + layout.getImportantForAccessibility())); + + // No host view exists, so this component is inherently not accessible. Add the reason why this + // is the case and then return. + if (hostView == node.getLithoView() || hostView == null) { + final int importantForAccessibility = layout.getImportantForAccessibility(); + final boolean isAccessibilityEnabled = + AccessibilityUtil.isAccessibilityEnabled(node.getContext()); + String ignoredReason; + + if (!isAccessibilityEnabled) { + ignoredReason = "No accessibility service is running."; + } else if (importantForAccessibility == IMPORTANT_FOR_ACCESSIBILITY_NO) { + ignoredReason = "Component has importantForAccessibility set to NO."; + } else if (importantForAccessibility == IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS) { + ignoredReason = "Component has importantForAccessibility set to NO_HIDE_DESCENDANTS."; + } else { + ignoredReason = "Component does not have content, or accessibility handlers."; + } + + accessibilityProps.put("talkback-ignored", true); + accessibilityProps.put("talkback-ignored-reasons", ignoredReason); + + return accessibilityProps.build(); + } + + accessibilityProps.put( + "node-info", AccessibilityUtil.getAccessibilityNodeInfoProperties(hostView)); + AccessibilityUtil.addTalkbackProperties(accessibilityProps, hostView); + + return accessibilityProps.build(); + } + + @Override + public void setValue(DebugComponent node, String[] path, SonarDynamic value) { + List> overrides = mOverrides.get(node.getGlobalKey()); + if (overrides == null) { + overrides = new ArrayList<>(); + mOverrides.put(node.getGlobalKey(), overrides); + } + overrides.add(new Pair<>(path, value)); + + node.setOverrider(mOverrider); + node.rerender(); + } + + @Override + public List> getAttributes(DebugComponent node) { + final List> attributes = new ArrayList<>(); + final String key = node.getKey(); + final String testKey = node.getTestKey(); + + if (key != null && key.trim().length() > 0) { + attributes.add(new Named<>("key", key)); + } + + if (testKey != null && testKey.trim().length() > 0) { + attributes.add(new Named<>("testKey", testKey)); + } + + return attributes; + } + + @Override + public void setHighlighted(DebugComponent node, boolean selected) { + final LithoView lithoView = node.getLithoView(); + if (lithoView == null) { + return; + } + + if (!selected) { + HighlightedOverlay.removeHighlight(lithoView); + return; + } + + final DebugLayoutNode layout = node.getLayoutNode(); + final boolean hasNode = layout != null; + final Rect margin; + if (!node.isRoot()) { + margin = + new Rect( + hasNode ? (int) layout.getResultMargin(YogaEdge.START) : 0, + hasNode ? (int) layout.getResultMargin(YogaEdge.TOP) : 0, + hasNode ? (int) layout.getResultMargin(YogaEdge.END) : 0, + hasNode ? (int) layout.getResultMargin(YogaEdge.BOTTOM) : 0); + } else { + // Margin not applied if you're at the root + margin = new Rect(); + } + + final Rect padding = + new Rect( + hasNode ? (int) layout.getResultPadding(YogaEdge.START) : 0, + hasNode ? (int) layout.getResultPadding(YogaEdge.TOP) : 0, + hasNode ? (int) layout.getResultPadding(YogaEdge.END) : 0, + hasNode ? (int) layout.getResultPadding(YogaEdge.BOTTOM) : 0); + + final Rect contentBounds = node.getBoundsInLithoView(); + HighlightedOverlay.setHighlighted(lithoView, margin, padding, contentBounds); + } + + @Override + public void hitTest(DebugComponent node, Touch touch) { + for (int i = getChildCount(node) - 1; i >= 0; i--) { + final Object child = getChildAt(node, i); + if (child instanceof DebugComponent) { + final DebugComponent componentChild = (DebugComponent) child; + final Rect bounds = componentChild.getBounds(); + + if (touch.containedIn(bounds.left, bounds.top, bounds.right, bounds.bottom)) { + touch.continueWithOffset(i, bounds.left, bounds.top); + return; + } + } else if (child instanceof View || child instanceof Drawable) { + // Components can only mount one view or drawable and its bounds are the same as the + // hosting component. + touch.continueWithOffset(i, 0, 0); + return; + } + } + + touch.finish(); + } + + @Override + public String getDecoration(DebugComponent node) throws Exception { + if (node.getComponent() != null) { + NodeDescriptor componentDescriptor = descriptorForClass(node.getComponent().getClass()); + if (componentDescriptor.getClass() != ObjectDescriptor.class) { + return componentDescriptor.getDecoration(node.getComponent()); + } + } + return "litho"; + } + + @Override + public boolean matches(String query, DebugComponent node) throws Exception { + NodeDescriptor descriptor = descriptorForClass(Object.class); + return descriptor.matches(query, node); + } + + private static void applyAccessibilityOverride( + DebugLayoutNode node, String key, SonarDynamic value) { + switch (key) { + case "focusable": + node.setFocusable(value.asBoolean()); + break; + case "important-for-accessibility": + node.setImportantForAccessibility( + AccessibilityUtil.sImportantForAccessibilityMapping.get(value.asString())); + break; + case "content-description": + node.setContentDescription(value.asString()); + break; + } + } + + private static void applyLayoutOverride(DebugLayoutNode node, String[] path, SonarDynamic value) { + switch (path[0]) { + case "background": + node.setBackgroundColor(value.asInt()); + break; + case "foreground": + node.setForegroundColor(value.asInt()); + break; + case "direction": + node.setLayoutDirection(YogaDirection.valueOf(value.asString().toUpperCase())); + break; + case "flex-direction": + node.setFlexDirection(YogaFlexDirection.valueOf(value.asString().toUpperCase())); + break; + case "justify-content": + node.setJustifyContent(YogaJustify.valueOf(value.asString().toUpperCase())); + break; + case "align-items": + node.setAlignItems(YogaAlign.valueOf(value.asString().toUpperCase())); + break; + case "align-self": + node.setAlignSelf(YogaAlign.valueOf(value.asString().toUpperCase())); + break; + case "align-content": + node.setAlignContent(YogaAlign.valueOf(value.asString().toUpperCase())); + break; + case "position-type": + node.setPositionType(YogaPositionType.valueOf(value.asString().toUpperCase())); + break; + case "flex-grow": + node.setFlexGrow(value.asFloat()); + break; + case "flex-shrink": + node.setFlexShrink(value.asFloat()); + break; + case "flex-basis": + node.setFlexBasis(YogaValue.parse(value.asString())); + break; + case "width": + node.setWidth(YogaValue.parse(value.asString())); + break; + case "min-width": + node.setMinWidth(YogaValue.parse(value.asString())); + break; + case "max-width": + node.setMaxWidth(YogaValue.parse(value.asString())); + break; + case "height": + node.setHeight(YogaValue.parse(value.asString())); + break; + case "min-height": + node.setMinHeight(YogaValue.parse(value.asString())); + break; + case "max-height": + node.setMaxHeight(YogaValue.parse(value.asString())); + break; + case "aspect-ratio": + node.setAspectRatio(value.asFloat()); + break; + case "margin": + node.setMargin(edgeFromString(path[1]), YogaValue.parse(value.asString())); + break; + case "padding": + node.setPadding(edgeFromString(path[1]), YogaValue.parse(value.asString())); + break; + case "border": + node.setBorderWidth(edgeFromString(path[1]), value.asFloat()); + break; + case "position": + node.setPosition(edgeFromString(path[1]), YogaValue.parse(value.asString())); + break; + } + } + + private static YogaEdge edgeFromString(String s) { + return YogaEdge.valueOf(s.toUpperCase()); + } + + private static void applyReflectiveOverride(Object o, String key, SonarDynamic dynamic) { + try { + final Field field = o.getClass().getDeclaredField(key); + field.setAccessible(true); + + final Class type = field.getType(); + + Object value = null; + if (type == int.class || type == Integer.class) { + value = dynamic.asInt(); + } else if (type == long.class || type == Long.class) { + value = dynamic.asLong(); + } else if (type == float.class || type == Float.class) { + value = dynamic.asFloat(); + } else if (type == double.class || type == Double.class) { + value = dynamic.asDouble(); + } else if (type == boolean.class || type == Boolean.class) { + value = dynamic.asBoolean(); + } else if (type.isAssignableFrom(String.class)) { + value = dynamic.asString(); + } + + if (value != null) { + field.set(o, value); + } + } catch (Exception ignored) { + } + } + + private static InspectorValue fromDrawable(Drawable d) { + if (d instanceof ColorDrawable) { + return InspectorValue.mutable(Color, ((ColorDrawable) d).getColor()); + } + return InspectorValue.mutable(Color, 0); + } + + private static InspectorValue fromReference( + ComponentContext c, Reference r) { + if (r == null) { + return fromDrawable(null); + } + + final T d = Reference.acquire(c, r); + final InspectorValue v = fromDrawable(d); + Reference.release(c, d, r); + return v; + } + + private static InspectorValue fromFloat(float f) { + if (Float.isNaN(f)) { + return InspectorValue.mutable(Enum, "undefined"); + } + return InspectorValue.mutable(Number, f); + } + + private static InspectorValue fromYogaValue(YogaValue v) { + // TODO add support for Type.Dimension or similar + return InspectorValue.mutable(Enum, v.toString()); + } + + private static InspectorValue fromColor(int color) { + return InspectorValue.mutable(Color, color); + } +} diff --git a/android/plugins/inspector/litho-sonar/LithoSonarDescriptors.java b/android/plugins/inspector/litho-sonar/LithoSonarDescriptors.java new file mode 100644 index 000000000..773a3d89c --- /dev/null +++ b/android/plugins/inspector/litho-sonar/LithoSonarDescriptors.java @@ -0,0 +1,15 @@ +// Copyright 2004-present Facebook. All Rights Reserved. + +package com.facebook.litho.sonar; + +import com.facebook.litho.DebugComponent; +import com.facebook.litho.LithoView; +import com.facebook.sonar.plugins.inspector.DescriptorMapping; + +public final class LithoSonarDescriptors { + + public static void add(DescriptorMapping descriptorMapping) { + descriptorMapping.register(LithoView.class, new LithoViewDescriptor()); + descriptorMapping.register(DebugComponent.class, new DebugComponentDescriptor()); + } +} diff --git a/android/plugins/inspector/litho-sonar/LithoViewDescriptor.java b/android/plugins/inspector/litho-sonar/LithoViewDescriptor.java new file mode 100644 index 000000000..4cb96cf3b --- /dev/null +++ b/android/plugins/inspector/litho-sonar/LithoViewDescriptor.java @@ -0,0 +1,111 @@ +// Copyright 2004-present Facebook. All Rights Reserved. + +package com.facebook.litho.sonar; + +import android.graphics.Rect; +import android.view.ViewGroup; +import com.facebook.litho.DebugComponent; +import com.facebook.litho.LithoView; +import com.facebook.sonar.core.SonarDynamic; +import com.facebook.sonar.core.SonarObject; +import com.facebook.sonar.plugins.inspector.Named; +import com.facebook.sonar.plugins.inspector.NodeDescriptor; +import com.facebook.sonar.plugins.inspector.Touch; +import java.util.ArrayList; +import java.util.List; + +public class LithoViewDescriptor extends NodeDescriptor { + + @Override + public void init(LithoView node) throws Exception { + node.setOnDirtyMountListener( + new LithoView.OnDirtyMountListener() { + @Override + public void onDirtyMount(LithoView view) { + invalidate(view); + } + }); + } + + @Override + public String getId(LithoView node) throws Exception { + final NodeDescriptor descriptor = descriptorForClass(ViewGroup.class); + return descriptor.getId(node); + } + + @Override + public String getName(LithoView node) throws Exception { + final NodeDescriptor descriptor = descriptorForClass(ViewGroup.class); + return descriptor.getName(node); + } + + @Override + public int getChildCount(LithoView node) { + return DebugComponent.getRootInstance(node) == null ? 0 : 1; + } + + @Override + public Object getChildAt(LithoView node, int index) { + return DebugComponent.getRootInstance(node); + } + + @Override + public List> getData(LithoView node) throws Exception { + final List> props = new ArrayList<>(); + final NodeDescriptor descriptor = descriptorForClass(ViewGroup.class); + final Rect mountedBounds = node.getPreviousMountBounds(); + + props.add( + 0, + new Named<>( + "LithoView", + new SonarObject.Builder() + .put( + "mountbounds", + new SonarObject.Builder() + .put("left", mountedBounds.left) + .put("top", mountedBounds.top) + .put("right", mountedBounds.right) + .put("bottom", mountedBounds.bottom)) + .build())); + + props.addAll(descriptor.getData(node)); + + return props; + } + + @Override + public void setValue(LithoView node, String[] path, SonarDynamic value) throws Exception { + final NodeDescriptor descriptor = descriptorForClass(ViewGroup.class); + descriptor.setValue(node, path, value); + } + + @Override + public List> getAttributes(LithoView node) throws Exception { + final NodeDescriptor descriptor = descriptorForClass(ViewGroup.class); + return descriptor.getAttributes(node); + } + + @Override + public void setHighlighted(LithoView node, boolean selected) throws Exception { + final NodeDescriptor descriptor = descriptorForClass(ViewGroup.class); + descriptor.setHighlighted(node, selected); + } + + @Override + public void hitTest(LithoView node, Touch touch) { + touch.continueWithOffset(0, 0, 0); + } + + @Override + public String getDecoration(LithoView node) throws Exception { + final NodeDescriptor descriptor = descriptorForClass(ViewGroup.class); + return descriptor.getDecoration(node); + } + + @Override + public boolean matches(String query, LithoView node) throws Exception { + NodeDescriptor descriptor = descriptorForClass(Object.class); + return descriptor.matches(query, node); + } +} diff --git a/android/plugins/inspector/litho-sonar/PropWithDescription.java b/android/plugins/inspector/litho-sonar/PropWithDescription.java new file mode 100644 index 000000000..a56714366 --- /dev/null +++ b/android/plugins/inspector/litho-sonar/PropWithDescription.java @@ -0,0 +1,8 @@ +// Copyright 2004-present Facebook. All Rights Reserved. + +package com.facebook.litho.sonar; + +public interface PropWithDescription { + + Object getSonarLayoutInspectorPropDescription(); +} diff --git a/android/plugins/network/NetworkReporter.java b/android/plugins/network/NetworkReporter.java new file mode 100644 index 000000000..e74e3032e --- /dev/null +++ b/android/plugins/network/NetworkReporter.java @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ + +package com.facebook.sonar.plugins.network; + +import java.util.ArrayList; +import java.util.List; + +public interface NetworkReporter { + void reportRequest(RequestInfo requestInfo); + + void reportResponse(ResponseInfo responseInfo); + + public class Header { + public final String name; + public final String value; + + public Header(final String name, final String value) { + this.name = name; + this.value = value; + } + + @Override + public String toString() { + return "Header{" + name + ": " + value + "}"; + } + } + + public class RequestInfo { + public String requestId; + public long timeStamp; + public List

headers = new ArrayList<>(); + public String method; + public String uri; + public byte[] body; + + public Header getFirstHeader(final String name) { + for (Header header : headers) { + if (name.equalsIgnoreCase(header.name)) { + return header; + } + } + return null; + } + } + + public class ResponseInfo { + public String requestId; + public long timeStamp; + public int statusCode; + public String statusReason; + public List
headers = new ArrayList<>(); + public byte[] body; + + public Header getFirstHeader(final String name) { + for (Header header : headers) { + if (name.equalsIgnoreCase(header.name)) { + return header; + } + } + return null; + } + } +} diff --git a/android/plugins/network/NetworkResponseFormatter.java b/android/plugins/network/NetworkResponseFormatter.java new file mode 100644 index 000000000..728a2a149 --- /dev/null +++ b/android/plugins/network/NetworkResponseFormatter.java @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ + +package com.facebook.sonar.plugins.network; + +import com.facebook.sonar.plugins.network.NetworkReporter.ResponseInfo; + +public interface NetworkResponseFormatter { + + interface OnCompletionListener { + void onCompletion(String json); + } + + boolean shouldFormat(ResponseInfo response); + + void format(ResponseInfo response, OnCompletionListener onCompletionListener); +} diff --git a/android/plugins/network/NetworkSonarPlugin.java b/android/plugins/network/NetworkSonarPlugin.java new file mode 100644 index 000000000..1a2ebf760 --- /dev/null +++ b/android/plugins/network/NetworkSonarPlugin.java @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ + +package com.facebook.sonar.plugins.network; + +import android.util.Base64; +import com.facebook.sonar.core.ErrorReportingRunnable; +import com.facebook.sonar.core.SonarArray; +import com.facebook.sonar.core.SonarObject; +import com.facebook.sonar.plugins.common.BufferingSonarPlugin; +import java.util.List; + +public class NetworkSonarPlugin extends BufferingSonarPlugin implements NetworkReporter { + public static final String ID = "Network"; + + private final List mFormatters; + + public NetworkSonarPlugin() { + this(null); + } + + public NetworkSonarPlugin(List formatters) { + this.mFormatters = formatters; + } + + @Override + public String getId() { + return ID; + } + + @Override + public void reportRequest(RequestInfo requestInfo) { + final SonarObject request = + new SonarObject.Builder() + .put("id", requestInfo.requestId) + .put("timestamp", requestInfo.timeStamp) + .put("method", requestInfo.method) + .put("url", requestInfo.uri) + .put("headers", toSonarObject(requestInfo.headers)) + .put("data", toBase64(requestInfo.body)) + .build(); + + send("newRequest", request); + } + + @Override + public void reportResponse(final ResponseInfo responseInfo) { + final Runnable job = + new ErrorReportingRunnable(getConnection()) { + @Override + protected void runOrThrow() throws Exception { + if (shouldStripResponseBody(responseInfo)) { + responseInfo.body = null; + } + + final SonarObject response = + new SonarObject.Builder() + .put("id", responseInfo.requestId) + .put("timestamp", responseInfo.timeStamp) + .put("status", responseInfo.statusCode) + .put("reason", responseInfo.statusReason) + .put("headers", toSonarObject(responseInfo.headers)) + .put("data", toBase64(responseInfo.body)) + .build(); + + send("newResponse", response); + } + }; + + if (mFormatters != null) { + for (NetworkResponseFormatter formatter : mFormatters) { + if (formatter.shouldFormat(responseInfo)) { + formatter.format( + responseInfo, + new NetworkResponseFormatter.OnCompletionListener() { + @Override + public void onCompletion(final String json) { + responseInfo.body = json.getBytes(); + job.run(); + } + }); + return; + } + } + } + + job.run(); + } + + private String toBase64(byte[] bytes) { + if (bytes == null) { + return null; + } + return new String(Base64.encode(bytes, Base64.DEFAULT)); + } + + private SonarArray toSonarObject(List
headers) { + final SonarArray.Builder list = new SonarArray.Builder(); + + for (Header header : headers) { + list.put(new SonarObject.Builder().put("key", header.name).put("value", header.value)); + } + + return list.build(); + } + + private static boolean shouldStripResponseBody(ResponseInfo responseInfo) { + final Header contentType = responseInfo.getFirstHeader("content-type"); + if (contentType == null) { + return false; + } + + return contentType.value.contains("image/") + || contentType.value.contains("video/") + || contentType.value.contains("application/zip"); + } +} diff --git a/android/plugins/network/SonarOkhttpInterceptor.java b/android/plugins/network/SonarOkhttpInterceptor.java new file mode 100644 index 000000000..1ca385555 --- /dev/null +++ b/android/plugins/network/SonarOkhttpInterceptor.java @@ -0,0 +1,106 @@ +// Copyright 2004-present Facebook. All Rights Reserved. +package com.facebook.sonar.plugins.network; + +import android.util.Log; +import com.facebook.sonar.plugins.network.NetworkReporter.RequestInfo; +import com.facebook.sonar.plugins.network.NetworkReporter.ResponseInfo; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Random; +import java.util.Set; +import javax.annotation.Nullable; +import okhttp3.Headers; +import okhttp3.Interceptor; +import okhttp3.Request; +import okhttp3.Response; +import okhttp3.ResponseBody; +import okio.Buffer; + +public class SonarOkhttpInterceptor implements Interceptor { + + public @Nullable NetworkSonarPlugin plugin; + + public SonarOkhttpInterceptor() { + this.plugin = null; + } + + public SonarOkhttpInterceptor(NetworkSonarPlugin plugin) { + this.plugin = plugin; + } + + @Override + public Response intercept(Interceptor.Chain chain) throws IOException { + Request request = chain.request(); + int randInt = randInt(1, Integer.MAX_VALUE); + plugin.reportRequest(convertRequest(request, randInt)); + Response response = chain.proceed(request); + ResponseBody body = response.body(); + ResponseInfo responseInfo = convertResponse(response, body, randInt); + plugin.reportResponse(responseInfo); + // Creating new response as can't used response.body() more than once + return response + .newBuilder() + .body(ResponseBody.create(body.contentType(), responseInfo.body)) + .build(); + } + + private static byte[] bodyToByteArray(final Request request) { + + try { + final Request copy = request.newBuilder().build(); + final Buffer buffer = new Buffer(); + copy.body().writeTo(buffer); + return buffer.readByteArray(); + } catch (final IOException e) { + return e.getMessage().getBytes(); + } + } + + private RequestInfo convertRequest(Request request, int identifier) { + List headers = convertHeader(request.headers()); + RequestInfo info = new RequestInfo(); + info.requestId = String.valueOf(identifier); + info.timeStamp = System.currentTimeMillis(); + info.headers = headers; + info.method = request.method(); + info.uri = request.url().toString(); + if (request.body() != null) { + info.body = bodyToByteArray(request); + } + + return info; + } + + private ResponseInfo convertResponse(Response response, ResponseBody body, int identifier) { + + List headers = convertHeader(response.headers()); + ResponseInfo info = new ResponseInfo(); + info.requestId = String.valueOf(identifier); + info.timeStamp = response.receivedResponseAtMillis(); + info.statusCode = response.code(); + info.headers = headers; + try { + info.body = body.bytes(); + } catch (IOException e) { + Log.e("Sonar", e.toString()); + } + return info; + } + + private List convertHeader(Headers headers) { + List list = new ArrayList<>(); + + Set keys = headers.names(); + for (String key : keys) { + list.add(new NetworkReporter.Header(key, headers.get(key))); + } + return list; + } + + private int randInt(int min, int max) { + Random rand = new Random(); + int randomNum = rand.nextInt((max - min) + 1) + min; + return randomNum; + } +} diff --git a/android/plugins/sharedpreferences/SharedPreferencesSonarPlugin.java b/android/plugins/sharedpreferences/SharedPreferencesSonarPlugin.java new file mode 100644 index 000000000..fef931a48 --- /dev/null +++ b/android/plugins/sharedpreferences/SharedPreferencesSonarPlugin.java @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ + +package com.facebook.sonar.plugins.sharedpreferences; + +import static android.content.Context.MODE_PRIVATE; + +import android.content.Context; +import android.content.SharedPreferences; +import com.facebook.sonar.core.SonarConnection; +import com.facebook.sonar.core.SonarObject; +import com.facebook.sonar.core.SonarPlugin; +import com.facebook.sonar.core.SonarReceiver; +import com.facebook.sonar.core.SonarResponder; +import java.util.Map; + +public class SharedPreferencesSonarPlugin implements SonarPlugin { + + private SonarConnection mConnection; + private final SharedPreferences mSharedPreferences; + + public SharedPreferencesSonarPlugin(Context context) { + mSharedPreferences = context.getSharedPreferences(context.getPackageName(), MODE_PRIVATE); + + mSharedPreferences.registerOnSharedPreferenceChangeListener( + new SharedPreferences.OnSharedPreferenceChangeListener() { + @Override + public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { + if (mConnection != null) { + mConnection.send( + "sharedPreferencesChange", + new SonarObject.Builder() + .put("name", key) + .put("deleted", !mSharedPreferences.contains(key)) + .put("time", System.currentTimeMillis()) + .put("value", mSharedPreferences.getAll().get(key)) + .build()); + } + } + }); + } + + @Override + public String getId() { + return "Preferences"; + } + + private SonarObject getSharedPreferencesObject() { + final SonarObject.Builder builder = new SonarObject.Builder(); + final Map map = mSharedPreferences.getAll(); + + for (Map.Entry entry : map.entrySet()) { + final Object val = entry.getValue(); + builder.put(entry.getKey(), val); + } + + return builder.build(); + } + + @Override + public void onConnect(SonarConnection connection) { + mConnection = connection; + + connection.receive( + "getSharedPreferences", + new SonarReceiver() { + @Override + public void onReceive(SonarObject params, SonarResponder responder) { + responder.success(getSharedPreferencesObject()); + } + }); + + connection.receive( + "setSharedPreference", + new SonarReceiver() { + @Override + public void onReceive(SonarObject params, SonarResponder responder) + throws IllegalArgumentException { + + String preferenceName = params.getString("preferenceName"); + Object originalValue = mSharedPreferences.getAll().get(preferenceName); + SharedPreferences.Editor editor = mSharedPreferences.edit(); + + if (originalValue instanceof Boolean) { + editor.putBoolean(preferenceName, params.getBoolean("preferenceValue")); + } else if (originalValue instanceof Long) { + editor.putLong(preferenceName, params.getLong("preferenceValue")); + } else if (originalValue instanceof Integer) { + editor.putInt(preferenceName, params.getInt("preferenceValue")); + } else if (originalValue instanceof Float) { + editor.putFloat(preferenceName, params.getFloat("preferenceValue")); + } else if (originalValue instanceof String) { + editor.putString(preferenceName, params.getString("preferenceValue")); + } else { + throw new IllegalArgumentException("Type not supported: " + preferenceName); + } + + editor.apply(); + + responder.success(getSharedPreferencesObject()); + } + }); + } + + @Override + public void onDisconnect() { + mConnection = null; + } +} diff --git a/android/sample/AndroidManifest.xml b/android/sample/AndroidManifest.xml new file mode 100644 index 000000000..5d52b59f9 --- /dev/null +++ b/android/sample/AndroidManifest.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/android/sample/build.gradle b/android/sample/build.gradle new file mode 100644 index 000000000..5d0794a74 --- /dev/null +++ b/android/sample/build.gradle @@ -0,0 +1,63 @@ +apply plugin: 'com.android.application' + +android { + + compileSdkVersion rootProject.compileSdkVersion + buildToolsVersion rootProject.buildToolsVersion + defaultConfig { + minSdkVersion rootProject.minSdkVersion + testInstrumentationRunner 'android.support.test.runner.AndroidJUnitRunner' + applicationId "com.facebook.sonar.sample" + } + + lintOptions { + abortOnError false + } + sourceSets { + main { + manifest.srcFile './AndroidManifest.xml' + java { + srcDir 'src' + } + res { + srcDir 'res' + } + } + } + packagingOptions { + pickFirst 'lib/armeabi-v7a/libfb.so' + pickFirst 'lib/x86/libfb.so' + pickFirst 'lib/x86_64/libfb.so' + pickFirst 'lib/arm64-v8a/libfb.so' + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + implementation 'com.android.support:appcompat-v7:26.1.0' + implementation 'com.android.support.constraint:constraint-layout:1.1.0' + implementation 'com.android.support:design:26.1.0' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'com.android.support.test:runner:1.0.2' + androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' + // ... + // Litho + implementation 'com.facebook.litho:litho-core:0.15.0' + implementation 'com.facebook.litho:litho-widget:0.15.0' + compileOnly 'com.facebook.litho:litho-annotations:0.15.0' + + annotationProcessor 'com.facebook.litho:litho-processor:0.15.0' + + // SoLoader + implementation 'com.facebook.soloader:soloader:0.4.1' + + // For integration with Fresco + implementation 'com.facebook.litho:litho-fresco:0.15.0' + + // For testing + testImplementation 'com.facebook.litho:litho-testing:0.15.0' + + implementation 'com.squareup.okhttp3:okhttp:3.10.0' + implementation project(':android') + //implementation project(':sonar') +} diff --git a/android/sample/debug.keystore b/android/sample/debug.keystore new file mode 100644 index 0000000000000000000000000000000000000000..65cb6bb32fd169de4e86c0fce980c59c7154f768 GIT binary patch literal 2253 zcmchYc{CJy8^>qE7{)eZ%QB3$F*KGK`yNFYvW>EieVJ=FeeXT*J?H)Z{p0!L`JV52&U3!M-}yXTHkSwX=mBnY80CjZ%x=;-0G zIu#PiEfvc*zTo*v2fny@uJn|7p%E$4S zd$(4n*fsUNdR-L{{nd|XH}y4khKy(&@3RuHink4w&xB>Xj~j}p@3Ypu}k04-?w4R z#wg;nvs))dO87pjGs6ossN*`6nD^0}6-){Sa@n2=vZgnV~Vw3K~}YeRM{jL2XPX&dC@yZ!B9X ztxw4#6osy{De4|10`}-SzfN4Of(qQEkx5rKwM06pKR0(Ws+Q+;;+)ez`G(kPC)qQs z%VQSKBPoQ~Z@Lt>QcBsrw_{)A6hVX;9-;YVcP;Nc_Ylo%x;CL+iM{2qi>xRpzw`zm ziF}Rg2J+qHtQOH#!!pvFC|HR$4oVIiE;bttoM|pSFCVD*a@cPra~slAABByDd0+b}h5C&nKQM z{5FZ(^T_L?CgTFiugG3z(TVj5O+0O!m)FPtLv8rN*d5bzSXOiiI>0IAiu=(Q0LbFN z=&twPk{^HlO#PD1D{OdZpw-MFle*2u+4jK2;k<{Hne^=U5u_(yg+ze^t+|b=LFE^H zaPoDB_a{O-&|y5`GFRi^t+Ql@%7)LP3dt%Sgh<^_^1;_|?fnEk$Y(lZX>>pX`uOPcllkH#9W(lt2XU8M{Ki7(K)Sh@A+iHxm~H9u>%mZQHt z<&)ihk|1IA{f66yL>X>36k>@2u1$Da%%9N~?I@ljh--E|;5C2(8{m{&vypUGIAn&Q5CN zspZ$Y=||AF!-Lq8B0(!r1(mMdUYXGAXGVy620S{Y+c1r%;jB1+Q>}qU*4gsgxg|1_ zAx$oP;tPYkf*x}Zh)#I+u~V_FO7I(R-KN!6s>?c}tS()&zo3z5s%SxqPGoG!%5u5J z=rAtx%|nqKYaC~qJVCwLG;~Wo|8&z2{IFjbM4$jMu$+gejh68~D2f&Qh7QpfIg54p! z2#~v*w#WfJ4;m73Jk$#`5zMh?GgB|M*@fZV-6Sr|I4Fb^9QbR z@{(|E1Dq~STU%EbuZJf}!u9lU2HFOHwg2yRs6g~T139=BU@B1f;EVuaASw_DC?tbO zmyxB3ORcTp0 zU!IG5uzSK$aOj7t5l{t(u*EBjZXcvGFSV%ZT;*?iS)kx!D77ZtZ_3)Gk>nh#Hn!dm>l$s#^dgm z^wulp4v!|SmG*)veiT2s&nYJak$@nxaB}H)ROpmVjH~Wc@U;kL`5Ej#Lp=CZ2O$ChK_z@*28(3==-7+Z z9@hB+x%ZJ7Exnpl+l0dcdeXYeTFtswwbQ|igR}87)mAUGW&T(eY??%Y<&ns&m}m zm{FD~uUA=4BtPuX!%E+Fj)+^&OPnoX*u^mkVt--^FZtYD^hFwlN_D#gOjCRTqrY;MRKl~O0&^l!910#6N1akR;aegFUGA6 Ho}B+3gbKow literal 0 HcmV?d00001 diff --git a/android/sample/debug.keystore.properties b/android/sample/debug.keystore.properties new file mode 100644 index 000000000..3c06c8e4a --- /dev/null +++ b/android/sample/debug.keystore.properties @@ -0,0 +1,3 @@ +key.alias=androiddebugkey +key.store.password=android +key.alias.password=android diff --git a/android/sample/res/drawable-hdpi/ic_launcher.png b/android/sample/res/drawable-hdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..cc0c1f1de6553afaaa471b846169fcabc7aa9678 GIT binary patch literal 2843 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 literal 0 HcmV?d00001 diff --git a/android/sample/res/drawable-mdpi/ic_launcher.png b/android/sample/res/drawable-mdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..840d8da8ac6504d83de3681210767566e02cbd90 GIT binary patch literal 1642 zcmV-w29^1VP)@q4TO$s7xYUlbB+r3e=QqJZiJ zQs7~FchkEako1V#^qfxexqjVVwLCB#vg20ZyAQ7Wdc(o3Qeu+?${~?#8<4;#2|g(V z4rjQ02j2d2QPB2S9id|dYHDiTp+;FD!{QSOnXBXH_)|dmg-d?wEfqBt6)W#KW#CAG z>YW!hhNaj8DT|#7vZNQ{rc1~jmAh9Rv82@yxHNUss+3Yx@3^ol9LC{}xDa@bc zusl;Rx(-XieN|V|hWZA7pzX3zH#T9Pw5^VK(ocx4VBk`|SxcLc=YjSQ|dD4hq?HJn>Wx%AU@}+#;_svh7w7KkmEX zfQvDy%Y{v5)@hOgZ0CawxaP##q-UjI<69-j%JZQ9oF9$#0o?5z#6bU)W`9B(GO@nL zu-M2?O!A)Wq-X=$w)5%PDR}k0#Rzl{WB(WR=U5`~8=5Z1e;FIU@kQW6dy5iu6|}EGcgK)oK8s4yakaL4 zf}^HZfBp{m;o|kVvHJOW*zjgC&Y$SO>0@-ejH@utiK3nXzQay5Ti4j;H(d!}*&2J7 zvJkD#T!s+(regu0*(Ap4G53zn&Yf~Rm=)RDh?}5MFi7!!bs_aw+gmkq_nA>!9 zgh_=>X4Yt=K41lAV6D({ej)WxEPr;FQ_=q3*07mnk|W^Y5rQ$_qs}E7@p?4jqEGhMT&L#$=M zgE+-aOfG8MXR6L}75Op1GZs??xRX=coZ{x0;P06#EYD7Ao$;7%AuU+mPJ4IOenz3r zl+J{fr&*o%{Px`|KaRC+v}0{45E<}){72?U0aoOJ{!1BI34TAY|B1CqMCx|`)GL=J ox_3;c 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 LNkvXXu0mjfaSo3r literal 0 HcmV?d00001 diff --git a/android/sample/res/drawable-xxhdpi/ic_launcher.png b/android/sample/res/drawable-xxhdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..ed9c79e254bc2417ce48a27db2c381d36a0f3e23 GIT binary patch literal 5827 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 G7Wf~nnh;?C literal 0 HcmV?d00001 diff --git a/android/sample/res/drawable-xxxhdpi/ic_launcher.png b/android/sample/res/drawable-xxxhdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..4485f7cc1f9ec3175a471404d88504c5b34a8276 GIT binary patch literal 7987 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 vge?DC*Tz8IX)Kn$|KD!-|1ldwe{k + + + Sonar + diff --git a/android/sample/res/values/styles.xml b/android/sample/res/values/styles.xml new file mode 100644 index 000000000..961808643 --- /dev/null +++ b/android/sample/res/values/styles.xml @@ -0,0 +1,7 @@ + + + + + diff --git a/android/sample/src/sonar/com/facebook/sonar/sample/MainActivity.java b/android/sample/src/sonar/com/facebook/sonar/sample/MainActivity.java new file mode 100644 index 000000000..656a670cd --- /dev/null +++ b/android/sample/src/sonar/com/facebook/sonar/sample/MainActivity.java @@ -0,0 +1,22 @@ +// Copyright 2004-present Facebook. All Rights Reserved. + +package com.facebook.sonar.sample; + +import android.os.Bundle; +import android.support.v7.app.AppCompatActivity; +import com.facebook.litho.ComponentContext; +import com.facebook.litho.LithoView; + +public class MainActivity extends AppCompatActivity { + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + final ComponentContext c = new ComponentContext(this); + setContentView( + LithoView.create( + c, + RootComponent.create(c).build())); + } +} diff --git a/android/sample/src/sonar/com/facebook/sonar/sample/RootComponentSpec.java b/android/sample/src/sonar/com/facebook/sonar/sample/RootComponentSpec.java new file mode 100644 index 000000000..aec4b7828 --- /dev/null +++ b/android/sample/src/sonar/com/facebook/sonar/sample/RootComponentSpec.java @@ -0,0 +1,105 @@ +// Copyright 2004-present Facebook. All Rights Reserved. + +package com.facebook.sonar.sample; + +import com.facebook.litho.Column; +import com.facebook.litho.Component; +import com.facebook.litho.ComponentContext; +import com.facebook.litho.annotations.LayoutSpec; +import com.facebook.litho.annotations.OnCreateLayout; +import com.facebook.litho.widget.Text; +import okhttp3.Request; +import okhttp3.Response; +import okhttp3.RequestBody; +import okhttp3.FormBody; +import okhttp3.FormBody.Builder; +import okhttp3.OkHttpClient; +import okhttp3.Call; +import okhttp3.Callback; +import com.facebook.litho.ClickEvent; +import android.util.Log; +import java.io.IOException; +import com.facebook.litho.annotations.OnEvent; + +@LayoutSpec +public class RootComponentSpec { + + @OnCreateLayout + static Component onCreateLayout(ComponentContext c) { + return Column.create(c) + .child( + Text.create(c) + .text("Tap to hit get request") + .key("1") + .textSizeSp(20) + .clickHandler(RootComponent.hitGetRequest(c))) + .child( + Text.create(c) + .text("Tap to hit post request") + .key("2") + .textSizeSp(20) + .clickHandler(RootComponent.hitPostRequest(c))) + .child( + Text.create(c) + .text("I m just a text") + .key("3") + .textSizeSp(20)) + .build(); + } + +@OnEvent(ClickEvent.class) + static void hitGetRequest(ComponentContext c) { + + Request request = new Request.Builder() + .url("https://api.github.com/repos/facebook/yoga") + .get() + .build(); + SonarSampleApplication.okhttpClient.newCall(request).enqueue(new Callback() { + @Override + public void onFailure(Call call, IOException e) { + e.printStackTrace(); + Log.d("Sonar", e.getMessage()); + } + + @Override + public void onResponse(Call call, Response response) throws IOException { + if (response.isSuccessful()) { + Log.d("Sonar", response.body().string()); + } else { + Log.d("Sonar", "not successful"); + } + } + }); + } + + @OnEvent(ClickEvent.class) + static void hitPostRequest(ComponentContext c) { + + RequestBody formBody = new FormBody.Builder() + .add("app", "Sonar") + .add("remarks", "Its awesome") + .build(); + + Request request = new Request.Builder() + .url("https://demo9512366.mockable.io/SonarPost") + .post(formBody) + .build(); + + SonarSampleApplication.okhttpClient.newCall(request).enqueue(new Callback() { + @Override + public void onFailure(Call call, IOException e) { + e.printStackTrace(); + Log.d("Sonar", e.getMessage()); + } + + @Override + public void onResponse(Call call, Response response) throws IOException { + if (response.isSuccessful()) { + Log.d("Sonar", response.body().string()); + } else { + Log.d("Sonar", "not successful"); + } + } + }); + } +} diff --git a/android/sample/src/sonar/com/facebook/sonar/sample/SonarSampleApplication.java b/android/sample/src/sonar/com/facebook/sonar/sample/SonarSampleApplication.java new file mode 100644 index 000000000..6acb6a5b3 --- /dev/null +++ b/android/sample/src/sonar/com/facebook/sonar/sample/SonarSampleApplication.java @@ -0,0 +1,50 @@ +// Copyright 2004-present Facebook. All Rights Reserved. + +package com.facebook.sonar.sample; + +import android.app.Application; +import android.net.Network; +import android.support.annotation.Nullable; +import java.util.ArrayList; +import java.util.List; +import com.facebook.litho.sonar.LithoSonarDescriptors; +import com.facebook.soloader.SoLoader; +import com.facebook.sonar.android.utils.SonarUtils; +import com.facebook.sonar.android.AndroidSonarClient; +import com.facebook.sonar.core.SonarClient; +import com.facebook.sonar.plugins.inspector.DescriptorMapping; +import com.facebook.sonar.plugins.inspector.InspectorSonarPlugin; +import com.facebook.sonar.plugins.network.NetworkSonarPlugin; +import com.facebook.sonar.plugins.network.SonarOkhttpInterceptor; +import com.facebook.sonar.plugins.network.NetworkResponseFormatter; +import okhttp3.OkHttpClient; +import java.util.concurrent.TimeUnit; + +public class SonarSampleApplication extends Application { + + static public OkHttpClient okhttpClient; + + @Override + public void onCreate() { + super.onCreate(); + SoLoader.init(this, false); + + final SonarClient client = AndroidSonarClient.getInstance(this); + final DescriptorMapping descriptorMapping = DescriptorMapping.withDefaults(); + + NetworkSonarPlugin networkPlugin = new NetworkSonarPlugin(); + SonarOkhttpInterceptor interceptor = new SonarOkhttpInterceptor(networkPlugin); + + okhttpClient = new OkHttpClient.Builder() + .addNetworkInterceptor(interceptor) + .connectTimeout(60, TimeUnit.SECONDS) + .readTimeout(60, TimeUnit.SECONDS) + .writeTimeout(10, TimeUnit.MINUTES) + .build(); + + LithoSonarDescriptors.add(descriptorMapping); + client.addPlugin(new InspectorSonarPlugin(this, descriptorMapping)); + client.addPlugin(networkPlugin); + client.start(); +} +} diff --git a/android/testing/SonarConnectionMock.java b/android/testing/SonarConnectionMock.java new file mode 100644 index 000000000..c0979f512 --- /dev/null +++ b/android/testing/SonarConnectionMock.java @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +package com.facebook.sonar.testing; + +import com.facebook.sonar.core.SonarArray; +import com.facebook.sonar.core.SonarConnection; +import com.facebook.sonar.core.SonarObject; +import com.facebook.sonar.core.SonarReceiver; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class SonarConnectionMock implements SonarConnection { + public final Map receivers = new HashMap<>(); + public final Map> sent = new HashMap<>(); + + @Override + public void send(String method, SonarObject params) { + final List paramList; + if (sent.containsKey(method)) { + paramList = sent.get(method); + } else { + paramList = new ArrayList<>(); + sent.put(method, paramList); + } + + paramList.add(params); + } + + @Override + public void send(String method, SonarArray params) { + final List paramList; + if (sent.containsKey(method)) { + paramList = sent.get(method); + } else { + paramList = new ArrayList<>(); + sent.put(method, paramList); + } + + paramList.add(params); + } + + @Override + public void reportError(Throwable throwable) {} + + @Override + public void receive(String method, SonarReceiver receiver) { + receivers.put(method, receiver); + } +} diff --git a/android/testing/SonarResponderMock.java b/android/testing/SonarResponderMock.java new file mode 100644 index 000000000..76971b3ef --- /dev/null +++ b/android/testing/SonarResponderMock.java @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +package com.facebook.sonar.testing; + +import com.facebook.sonar.core.SonarArray; +import com.facebook.sonar.core.SonarObject; +import com.facebook.sonar.core.SonarResponder; +import java.util.LinkedList; +import java.util.List; + +public class SonarResponderMock implements SonarResponder { + public final List successes = new LinkedList<>(); + public final List errors = new LinkedList<>(); + + @Override + public void success(SonarObject response) { + successes.add(response); + } + + @Override + public void success(SonarArray response) { + successes.add(response); + } + + @Override + public void success() { + successes.add(new SonarObject.Builder().build()); + } + + @Override + public void error(SonarObject response) { + errors.add(response); + } +} diff --git a/android/tests/plugins/console/ConsoleSonarPluginTest.java b/android/tests/plugins/console/ConsoleSonarPluginTest.java new file mode 100644 index 000000000..023029aee --- /dev/null +++ b/android/tests/plugins/console/ConsoleSonarPluginTest.java @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +package com.facebook.sonar.plugins.console; + +import static org.hamcrest.CoreMatchers.hasItem; +import static org.hamcrest.MatcherAssert.assertThat; + +import com.facebook.sonar.core.SonarObject; +import com.facebook.sonar.testing.SonarConnectionMock; +import com.facebook.sonar.testing.SonarResponderMock; +import com.facebook.testing.robolectric.v3.WithTestDefaultsRunner; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; + +@RunWith(WithTestDefaultsRunner.class) +public class ConsoleSonarPluginTest { + + SonarConnectionMock connection; + SonarResponderMock responder; + + @Before + public void setup() throws Exception { + JavascriptEnvironment jsEnvironment = new JavascriptEnvironment(); + final ConsoleSonarPlugin plugin = new ConsoleSonarPlugin(jsEnvironment); + connection = new SonarConnectionMock(); + responder = new SonarResponderMock(); + plugin.onConnect(connection); + } + + @Test + public void simpleExpressionShouldEvaluateCorrectly() throws Exception { + + receiveScript("2 + 2"); + assertThat( + responder.successes, + hasItem(new SonarObject.Builder().put("value", 4).put("type", "json").build())); + } + + private void receiveScript(String a) throws Exception { + SonarObject getValue = new SonarObject.Builder().put("command", a).build(); + connection.receivers.get("executeCommand").onReceive(getValue, responder); + } +} diff --git a/android/tests/plugins/console/JavascriptSessionTest.java b/android/tests/plugins/console/JavascriptSessionTest.java new file mode 100644 index 000000000..0f02200e1 --- /dev/null +++ b/android/tests/plugins/console/JavascriptSessionTest.java @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +package com.facebook.sonar.plugins.console; + +import static org.junit.Assert.assertEquals; + +import com.facebook.testing.robolectric.v3.WithTestDefaultsRunner; +import com.google.common.collect.ImmutableMap; +import java.util.Collections; +import java.util.HashMap; +import org.json.JSONObject; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mozilla.javascript.ContextFactory; + +@RunWith(WithTestDefaultsRunner.class) +public class JavascriptSessionTest { + + ContextFactory mContextFactory = new ContextFactory(); + + @Test + public void testSimpleExpressionsEvaluate() throws Exception { + JavascriptSession session = + new JavascriptSession(mContextFactory, Collections.emptyMap()); + JSONObject json = session.evaluateCommand("2+2-1"); + assertEquals(3, json.getInt("value")); + } + + @Test + public void testStatePersistsBetweenCommands() throws Exception { + JavascriptSession session = + new JavascriptSession(mContextFactory, Collections.emptyMap()); + session.evaluateCommand("var x = 10;"); + JSONObject json = session.evaluateCommand("x"); + assertEquals(10, json.getInt("value")); + } + + @Test + public void testVariablesGetBoundCorrectly() throws Exception { + JavascriptSession session = + new JavascriptSession( + mContextFactory, + ImmutableMap.of( + "a", 2, + "b", 2)); + JSONObject json = session.evaluateCommand("a+b"); + assertEquals("json", json.getString("type")); + assertEquals(4, json.getInt("value")); + } + + @Test + public void testNumberEvaluation() throws Exception { + assertEquals(4, evaluateWithNoGlobals("4").getInt("value")); + } + + @Test + public void testStringEvaluation() throws Exception { + assertEquals("hello", evaluateWithNoGlobals("\"hello\"").getString("value")); + } + + @Test + public void testJavaObjectEvaluation() throws Exception { + JavascriptSession session = + new JavascriptSession( + mContextFactory, + ImmutableMap.of("object", new HashMap())); + JSONObject json = session.evaluateCommand("object"); + assertEquals("javaObject", json.getString("type")); + assertEquals("{}", json.getJSONObject("value").getString("toString")); + } + + @Test + public void testJavaMethodEvaluation() throws Exception { + JavascriptSession session = + new JavascriptSession( + mContextFactory, + ImmutableMap.of("object", new HashMap())); + JSONObject json = session.evaluateCommand("object.get"); + assertEquals("method", json.getString("type")); + } + + @Test + public void testJsFunctionEvaluation() throws Exception { + JSONObject json = evaluateWithNoGlobals("function() {}"); + assertEquals("function", json.getString("type")); + assertEquals("function(){}", removeWhitespace(json.getString("value"))); + } + + @Test + public void testNullEvaluation() throws Exception { + assertEquals("null", evaluateWithNoGlobals("null").getString("type")); + assertEquals("null", evaluateWithNoGlobals("undefined").getString("type")); + } + + private static String removeWhitespace(String input) { + return input.replaceAll("\\s", ""); + } + + private JSONObject evaluateWithNoGlobals(String input) throws Exception { + JavascriptSession session = + new JavascriptSession(mContextFactory, new HashMap()); + return session.evaluateCommand(input); + } +} diff --git a/android/tests/plugins/inspector/ApplicationWrapperTest.java b/android/tests/plugins/inspector/ApplicationWrapperTest.java new file mode 100644 index 000000000..d85412b25 --- /dev/null +++ b/android/tests/plugins/inspector/ApplicationWrapperTest.java @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +package com.facebook.sonar.plugins.inspector; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.MatcherAssert.assertThat; + +import android.app.Activity; +import android.app.Application; +import android.app.Application.ActivityLifecycleCallbacks; +import android.os.Bundle; +import com.facebook.testing.robolectric.v3.WithTestDefaultsRunner; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mockito; +import org.mockito.invocation.InvocationOnMock; +import org.mockito.stubbing.Answer; + +@RunWith(WithTestDefaultsRunner.class) +public class ApplicationWrapperTest { + + private ApplicationWrapper mWrapper; + private ActivityLifecycleCallbacks mCallbacks; + + @Before + public void setup() { + final Application app = Mockito.mock(Application.class); + Mockito.doAnswer( + new Answer() { + @Override + public Object answer(InvocationOnMock invocation) throws Throwable { + mCallbacks = (ActivityLifecycleCallbacks) invocation.getArguments()[0]; + return null; + } + }) + .when(app) + .registerActivityLifecycleCallbacks(Mockito.any(ActivityLifecycleCallbacks.class)); + + mWrapper = new ApplicationWrapper(app); + } + + @Test + public void testActivityCreated() { + final Activity activity1 = Mockito.mock(Activity.class); + mCallbacks.onActivityCreated(activity1, Mockito.mock(Bundle.class)); + + final Activity activity2 = Mockito.mock(Activity.class); + mCallbacks.onActivityCreated(activity2, Mockito.mock(Bundle.class)); + + assertThat(mWrapper.getActivityStack().size(), equalTo(2)); + assertThat(mWrapper.getActivityStack().get(0), equalTo(activity1)); + assertThat(mWrapper.getActivityStack().get(1), equalTo(activity2)); + } + + @Test + public void testActivityPaused() { + final Activity activity1 = Mockito.mock(Activity.class); + mCallbacks.onActivityCreated(activity1, Mockito.mock(Bundle.class)); + + final Activity activity2 = Mockito.mock(Activity.class); + mCallbacks.onActivityCreated(activity2, Mockito.mock(Bundle.class)); + + mCallbacks.onActivityPaused(activity2); + + assertThat(mWrapper.getActivityStack().size(), equalTo(2)); + assertThat(mWrapper.getActivityStack().get(0), equalTo(activity1)); + assertThat(mWrapper.getActivityStack().get(1), equalTo(activity2)); + } + + @Test + public void testFinishingActivityPaused() { + final Activity activity1 = Mockito.mock(Activity.class); + mCallbacks.onActivityCreated(activity1, Mockito.mock(Bundle.class)); + + final Activity activity2 = Mockito.mock(Activity.class); + mCallbacks.onActivityCreated(activity2, Mockito.mock(Bundle.class)); + + Mockito.when(activity2.isFinishing()).thenReturn(true); + mCallbacks.onActivityPaused(activity2); + + assertThat(mWrapper.getActivityStack().size(), equalTo(1)); + assertThat(mWrapper.getActivityStack().get(0), equalTo(activity1)); + } +} diff --git a/android/tests/plugins/inspector/DescriptorMappingTest.java b/android/tests/plugins/inspector/DescriptorMappingTest.java new file mode 100644 index 000000000..19ed24765 --- /dev/null +++ b/android/tests/plugins/inspector/DescriptorMappingTest.java @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +package com.facebook.sonar.plugins.inspector; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.MatcherAssert.assertThat; + +import com.facebook.sonar.core.SonarConnection; +import com.facebook.sonar.core.SonarDynamic; +import com.facebook.sonar.core.SonarObject; +import com.facebook.sonar.testing.SonarConnectionMock; +import com.facebook.testing.robolectric.v3.WithTestDefaultsRunner; +import java.util.List; +import org.junit.Test; +import org.junit.runner.RunWith; + +@RunWith(WithTestDefaultsRunner.class) +public class DescriptorMappingTest { + + private class TestClass {} + + private class TestSubClass extends TestClass {} + + private class TestDescriptor extends NodeDescriptor { + @Override + public void init(T node) {} + + @Override + public String getId(T node) { + return null; + } + + @Override + public String getName(T node) { + return null; + } + + @Override + public int getChildCount(T node) { + return 0; + } + + @Override + public T getChildAt(T node, int index) { + return null; + } + + @Override + public List> getData(T node) { + return null; + } + + @Override + public void setValue(T node, String[] path, SonarDynamic value) throws Exception {} + + @Override + public List> getAttributes(T node) { + return null; + } + + @Override + public void setHighlighted(T node, boolean selected) {} + + @Override + public void hitTest(T node, Touch touch) {} + + @Override + public String getDecoration(T obj) { + return null; + } + + @Override + public boolean matches(String query, T obj) { + return false; + } + } + + @Test + public void testDescriptorForRegisteredClass() { + final DescriptorMapping descriptorMapping = new DescriptorMapping(); + final NodeDescriptor descriptor1 = new TestDescriptor<>(); + final NodeDescriptor descriptor2 = new TestDescriptor<>(); + + descriptorMapping.register(TestClass.class, descriptor1); + descriptorMapping.register(TestSubClass.class, descriptor2); + + assertThat(descriptorMapping.descriptorForClass(TestSubClass.class), equalTo(descriptor2)); + } + + @Test + public void testDescriptorForRegisteredSuperClass() { + final DescriptorMapping descriptorMapping = new DescriptorMapping(); + final NodeDescriptor descriptor = new TestDescriptor<>(); + + descriptorMapping.register(TestClass.class, descriptor); + + assertThat(descriptorMapping.descriptorForClass(TestSubClass.class), equalTo(descriptor)); + } + + @Test + public void testOnConnect() { + final DescriptorMapping descriptorMapping = new DescriptorMapping(); + final NodeDescriptor descriptor = new TestDescriptor<>(); + descriptorMapping.register(TestClass.class, descriptor); + + final SonarConnection connection = new SonarConnectionMock(); + descriptorMapping.onConnect(connection); + + assertThat(descriptor.connected(), equalTo(true)); + } + + @Test + public void testOnDisconnect() { + final DescriptorMapping descriptorMapping = new DescriptorMapping(); + final NodeDescriptor descriptor = new TestDescriptor<>(); + descriptorMapping.register(TestClass.class, descriptor); + + final SonarConnection connection = new SonarConnectionMock(); + descriptorMapping.onConnect(connection); + descriptorMapping.onDisconnect(); + + assertThat(descriptor.connected(), equalTo(false)); + } +} diff --git a/android/tests/plugins/inspector/InspectorSonarPluginTest.java b/android/tests/plugins/inspector/InspectorSonarPluginTest.java new file mode 100644 index 000000000..d3e1edde0 --- /dev/null +++ b/android/tests/plugins/inspector/InspectorSonarPluginTest.java @@ -0,0 +1,424 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +package com.facebook.sonar.plugins.inspector; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.CoreMatchers.hasItem; +import static org.hamcrest.MatcherAssert.assertThat; + +import android.app.Application; +import android.graphics.Rect; +import android.view.View; +import android.view.ViewGroup; +import android.widget.FrameLayout; +import com.facebook.sonar.core.SonarArray; +import com.facebook.sonar.core.SonarConnection; +import com.facebook.sonar.core.SonarDynamic; +import com.facebook.sonar.core.SonarObject; +import com.facebook.sonar.plugins.console.iface.NullScriptingEnvironment; +import com.facebook.sonar.plugins.console.iface.ScriptingEnvironment; +import com.facebook.sonar.plugins.inspector.InspectorSonarPlugin.TouchOverlayView; +import com.facebook.sonar.plugins.inspector.descriptors.ApplicationDescriptor; +import com.facebook.sonar.testing.SonarConnectionMock; +import com.facebook.sonar.testing.SonarResponderMock; +import com.facebook.testing.robolectric.v3.WithTestDefaultsRunner; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mockito; +import org.robolectric.RuntimeEnvironment; + +@RunWith(WithTestDefaultsRunner.class) +public class InspectorSonarPluginTest { + + private MockApplicationDescriptor mApplicationDescriptor; + private DescriptorMapping mDescriptorMapping; + private ApplicationWrapper mApp; + private ScriptingEnvironment mScriptingEnvironment; + + @Before + public void setup() { + final Application app = Mockito.spy(RuntimeEnvironment.application); + Mockito.when(app.getApplicationContext()).thenReturn(app); + Mockito.when(app.getPackageName()).thenReturn("com.facebook.sonar"); + + mDescriptorMapping = new DescriptorMapping(); + mApplicationDescriptor = new MockApplicationDescriptor(); + mDescriptorMapping.register(ApplicationWrapper.class, mApplicationDescriptor); + mDescriptorMapping.register(TestNode.class, new TestNodeDescriptor()); + mScriptingEnvironment = new NullScriptingEnvironment(); + mApp = Mockito.spy(new ApplicationWrapper(app)); + } + + @Test + public void testOnConnect() throws Exception { + final InspectorSonarPlugin plugin = + new InspectorSonarPlugin(mApp, mDescriptorMapping, mScriptingEnvironment); + final SonarConnection connection = new SonarConnectionMock(); + + plugin.onConnect(connection); + assertThat(mApplicationDescriptor.connected(), equalTo(true)); + } + + @Test + public void testOnDisconnect() throws Exception { + final InspectorSonarPlugin plugin = + new InspectorSonarPlugin(mApp, mDescriptorMapping, mScriptingEnvironment); + final SonarConnection connection = new SonarConnectionMock(); + + plugin.onConnect(connection); + plugin.onDisconnect(); + assertThat(mApplicationDescriptor.connected(), equalTo(false)); + } + + @Test + public void testGetRoot() throws Exception { + final InspectorSonarPlugin plugin = + new InspectorSonarPlugin(mApp, mDescriptorMapping, mScriptingEnvironment); + final SonarResponderMock responder = new SonarResponderMock(); + final SonarConnectionMock connection = new SonarConnectionMock(); + plugin.onConnect(connection); + + final TestNode root = new TestNode(); + root.id = "test"; + mApplicationDescriptor.root = root; + plugin.mGetRoot.onReceive(null, responder); + + assertThat( + responder.successes, + hasItem( + new SonarObject.Builder() + .put("id", "com.facebook.sonar") + .put("name", "com.facebook.sonar") + .put("data", new SonarObject.Builder()) + .put("children", new SonarArray.Builder().put("test")) + .put("attributes", new SonarArray.Builder()) + .put("decoration", (String) null) + .build())); + } + + @Test + public void testGetNodes() throws Exception { + final InspectorSonarPlugin plugin = + new InspectorSonarPlugin(mApp, mDescriptorMapping, mScriptingEnvironment); + final SonarResponderMock responder = new SonarResponderMock(); + final SonarConnectionMock connection = new SonarConnectionMock(); + plugin.onConnect(connection); + + final TestNode root = new TestNode(); + root.id = "test"; + root.name = "test"; + mApplicationDescriptor.root = root; + + plugin.mGetRoot.onReceive(null, responder); + plugin.mGetNodes.onReceive( + new SonarObject.Builder().put("ids", new SonarArray.Builder().put("test")).build(), + responder); + + assertThat( + responder.successes, + hasItem( + new SonarObject.Builder() + .put( + "elements", + new SonarArray.Builder() + .put( + new SonarObject.Builder() + .put("id", "test") + .put("name", "test") + .put("data", new SonarObject.Builder()) + .put("children", new SonarArray.Builder()) + .put("attributes", new SonarArray.Builder()) + .put("decoration", (String) null))) + .build())); + } + + @Test + public void testGetNodesThatDontExist() throws Exception { + final InspectorSonarPlugin plugin = + new InspectorSonarPlugin(mApp, mDescriptorMapping, mScriptingEnvironment); + final SonarResponderMock responder = new SonarResponderMock(); + final SonarConnectionMock connection = new SonarConnectionMock(); + plugin.onConnect(connection); + + final TestNode root = new TestNode(); + root.id = "test"; + mApplicationDescriptor.root = root; + + plugin.mGetRoot.onReceive(null, responder); + plugin.mGetNodes.onReceive( + new SonarObject.Builder().put("ids", new SonarArray.Builder().put("notest")).build(), + responder); + + assertThat( + responder.errors, + hasItem( + new SonarObject.Builder() + .put("message", "No node with given id") + .put("id", "notest") + .build())); + } + + @Test + public void testSetData() throws Exception { + final InspectorSonarPlugin plugin = + new InspectorSonarPlugin(mApp, mDescriptorMapping, mScriptingEnvironment); + final SonarConnectionMock connection = new SonarConnectionMock(); + final SonarResponderMock responder = new SonarResponderMock(); + plugin.onConnect(connection); + + final TestNode root = new TestNode(); + root.id = "test"; + root.data = new SonarObject.Builder().put("prop", "value").build(); + + mApplicationDescriptor.root = root; + + plugin.mGetRoot.onReceive(null, responder); + plugin.mSetData.onReceive( + new SonarObject.Builder() + .put("id", "test") + .put("path", new SonarArray.Builder().put("data")) + .put("value", new SonarObject.Builder().put("prop", "updated_value")) + .build(), + responder); + + assertThat(root.data.getString("prop"), equalTo("updated_value")); + assertThat( + connection.sent.get("invalidate"), + hasItem( + new SonarObject.Builder() + .put( + "nodes", + new SonarArray.Builder() + .put(new SonarObject.Builder().put("id", "test").build()) + .build()) + .build())); + } + + @Test + public void testSetHighlighted() throws Exception { + final InspectorSonarPlugin plugin = + new InspectorSonarPlugin(mApp, mDescriptorMapping, mScriptingEnvironment); + final SonarConnectionMock connection = new SonarConnectionMock(); + final SonarResponderMock responder = new SonarResponderMock(); + plugin.onConnect(connection); + + final TestNode root = new TestNode(); + root.id = "test"; + mApplicationDescriptor.root = root; + + plugin.mGetRoot.onReceive(null, responder); + plugin.mSetHighlighted.onReceive( + new SonarObject.Builder().put("id", "com.facebook.sonar").build(), responder); + + assertThat(mApplicationDescriptor.highlighted, equalTo(true)); + + plugin.mSetHighlighted.onReceive( + new SonarObject.Builder().put("id", "test").build(), responder); + + assertThat(mApplicationDescriptor.highlighted, equalTo(false)); + assertThat(root.highlighted, equalTo(true)); + + plugin.onDisconnect(); + + assertThat(root.highlighted, equalTo(false)); + } + + @Test + public void testHitTest() throws Exception { + final InspectorSonarPlugin plugin = + new InspectorSonarPlugin(mApp, mDescriptorMapping, mScriptingEnvironment); + final SonarConnectionMock connection = new SonarConnectionMock(); + plugin.onConnect(connection); + + final TestNode one = new TestNode(); + one.id = "1"; + one.bounds.set(5, 5, 20, 20); + + final TestNode two = new TestNode(); + two.id = "2"; + two.bounds.set(20, 20, 100, 100); + + final TestNode three = new TestNode(); + three.id = "3"; + three.bounds.set(0, 0, 20, 20); + + final TestNode root = new TestNode(); + root.id = "test"; + root.children.add(one); + root.children.add(two); + root.children.add(three); + mApplicationDescriptor.root = root; + + plugin.hitTest(10, 10); + + assertThat( + connection.sent.get("select"), + hasItem( + new SonarObject.Builder() + .put( + "path", new SonarArray.Builder().put("com.facebook.sonar").put("test").put("3")) + .build())); + } + + @Test + public void testSetSearchActive() throws Exception { + final InspectorSonarPlugin plugin = + new InspectorSonarPlugin(mApp, mDescriptorMapping, mScriptingEnvironment); + final SonarConnectionMock connection = new SonarConnectionMock(); + final SonarResponderMock responder = new SonarResponderMock(); + plugin.onConnect(connection); + + final ViewGroup decorView = Mockito.spy(new FrameLayout(mApp.getApplication())); + Mockito.when(mApp.getViewRoots()).thenReturn(Arrays.asList(decorView)); + + plugin.mSetSearchActive.onReceive( + new SonarObject.Builder().put("active", true).build(), responder); + + Mockito.verify(decorView, Mockito.times(1)).addView(Mockito.any(TouchOverlayView.class)); + + plugin.mSetSearchActive.onReceive( + new SonarObject.Builder().put("active", false).build(), responder); + + Mockito.verify(decorView, Mockito.times(1)).removeView(Mockito.any(TouchOverlayView.class)); + } + + @Test(expected = AssertionError.class) + public void testNullChildThrows() throws Exception { + final InspectorSonarPlugin plugin = + new InspectorSonarPlugin(mApp, mDescriptorMapping, mScriptingEnvironment); + final SonarResponderMock responder = new SonarResponderMock(); + final SonarConnectionMock connection = new SonarConnectionMock(); + plugin.onConnect(connection); + + final TestNode root = new TestNode(); + root.id = "test"; + root.name = "test"; + root.children = new ArrayList<>(); + root.children.add(null); + mApplicationDescriptor.root = root; + + plugin.mGetRoot.onReceive(null, responder); + plugin.mGetNodes.onReceive( + new SonarObject.Builder().put("ids", new SonarArray.Builder().put("test")).build(), + responder); + } + + private class TestNode { + String id; + String name; + List children = new ArrayList<>(); + SonarObject data; + List> atttributes = new ArrayList<>(); + String decoration; + boolean highlighted; + Rect bounds = new Rect(); + } + + private class TestNodeDescriptor extends NodeDescriptor { + + @Override + public void init(TestNode node) {} + + @Override + public String getId(TestNode node) { + return node.id; + } + + @Override + public String getName(TestNode node) { + return node.name; + } + + @Override + public int getChildCount(TestNode node) { + return node.children.size(); + } + + @Override + public Object getChildAt(TestNode node, int index) { + return node.children.get(index); + } + + @Override + public List> getData(TestNode node) { + return Collections.singletonList(new Named<>("data", node.data)); + } + + @Override + public void setValue(TestNode node, String[] path, SonarDynamic value) throws Exception { + if (path[0].equals("data")) { + node.data = value.asObject(); + } + invalidate(node); + } + + @Override + public List> getAttributes(TestNode node) { + return node.atttributes; + } + + @Override + public void setHighlighted(TestNode node, boolean selected) { + node.highlighted = selected; + } + + @Override + public void hitTest(TestNode node, Touch touch) { + for (int i = node.children.size() - 1; i >= 0; i--) { + final TestNode child = node.children.get(i); + final Rect bounds = child.bounds; + if (touch.containedIn(bounds.left, bounds.top, bounds.right, bounds.bottom)) { + touch.continueWithOffset(i, bounds.left, bounds.top); + return; + } + } + + touch.finish(); + } + + @Override + public String getDecoration(TestNode node) { + return node.decoration; + } + + @Override + public boolean matches(String query, TestNode node) { + return getName(node).contains(query); + } + } + + private class MockApplicationDescriptor extends ApplicationDescriptor { + TestNode root; + boolean highlighted; + + @Override + public int getChildCount(ApplicationWrapper node) { + return 1; + } + + @Override + public Object getChildAt(ApplicationWrapper node, int index) { + return root; + } + + @Override + public void setHighlighted(ApplicationWrapper node, boolean selected) { + highlighted = selected; + } + + @Override + public void hitTest(ApplicationWrapper node, Touch touch) { + touch.continueWithOffset(0, 0, 0); + } + } +} diff --git a/android/tests/plugins/inspector/descriptors/ViewGroupDescriptorTest.java b/android/tests/plugins/inspector/descriptors/ViewGroupDescriptorTest.java new file mode 100644 index 000000000..c176374f9 --- /dev/null +++ b/android/tests/plugins/inspector/descriptors/ViewGroupDescriptorTest.java @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +package com.facebook.sonar.plugins.inspector.descriptors; + +import static android.view.View.MeasureSpec.EXACTLY; +import static android.view.View.MeasureSpec.makeMeasureSpec; +import static org.mockito.Matchers.any; + +import android.view.View; +import android.view.ViewGroup; +import android.widget.FrameLayout; +import com.facebook.sonar.plugins.inspector.Touch; +import com.facebook.testing.robolectric.v3.WithTestDefaultsRunner; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mockito; +import org.robolectric.RuntimeEnvironment; + +@RunWith(WithTestDefaultsRunner.class) +public class ViewGroupDescriptorTest { + + @Test + public void testHitTestVisibleChild() { + final ViewGroupDescriptor descriptor = new ViewGroupDescriptor(); + + final ViewGroup root = new FrameLayout(RuntimeEnvironment.application); + final View child = new View(RuntimeEnvironment.application); + root.addView(child); + + root.measure(makeMeasureSpec(100, EXACTLY), makeMeasureSpec(100, EXACTLY)); + root.layout(0, 0, 100, 100); + + final Touch touch = Mockito.mock(Touch.class); + Mockito.when(touch.containedIn(any(int.class), any(int.class), any(int.class), any(int.class))) + .thenReturn(true); + descriptor.hitTest(root, touch); + Mockito.verify(touch, Mockito.times(1)).continueWithOffset(0, 0, 0); + } + + @Test + public void testHitTestInvisibleChild() { + final ViewGroupDescriptor descriptor = new ViewGroupDescriptor(); + + final ViewGroup root = new FrameLayout(RuntimeEnvironment.application); + final View child = new View(RuntimeEnvironment.application); + child.setVisibility(View.GONE); + root.addView(child); + + root.measure(makeMeasureSpec(100, EXACTLY), makeMeasureSpec(100, EXACTLY)); + root.layout(0, 0, 100, 100); + + final Touch touch = Mockito.mock(Touch.class); + Mockito.when(touch.containedIn(any(int.class), any(int.class), any(int.class), any(int.class))) + .thenReturn(true); + descriptor.hitTest(root, touch); + Mockito.verify(touch, Mockito.times(1)).finish(); + } +} diff --git a/android/third-party/DoubleConversion/ApplicationManifest.xml b/android/third-party/DoubleConversion/ApplicationManifest.xml new file mode 100644 index 000000000..60e2a288b --- /dev/null +++ b/android/third-party/DoubleConversion/ApplicationManifest.xml @@ -0,0 +1,4 @@ + + + diff --git a/android/third-party/DoubleConversion/CMakeLists.txt b/android/third-party/DoubleConversion/CMakeLists.txt new file mode 100644 index 000000000..3e9993f7e --- /dev/null +++ b/android/third-party/DoubleConversion/CMakeLists.txt @@ -0,0 +1,12 @@ +cmake_minimum_required (VERSION 3.6.0) + +PROJECT(doubleconversion CXX) +enable_language(CXX) +set(PACKAGE_NAME doubleconversion) +set(doubleconversion_DIR double-conversion-3.0.0/double-conversion) +include_directories(${doubleconversion_DIR}) +file(GLOB SRCFILES ${doubleconversion_DIR}/*.cc) +message(STATUS "SRC FILES :- " ${SRCFILES}) +add_library(${PACKAGE_NAME} SHARED ${SRCFILES}) +install(TARGETS ${PACKAGE_NAME} DESTINATION ./build/) +target_link_libraries(${PACKAGE_NAME}) diff --git a/android/third-party/DoubleConversion/build.gradle b/android/third-party/DoubleConversion/build.gradle new file mode 100644 index 000000000..9dda53405 --- /dev/null +++ b/android/third-party/DoubleConversion/build.gradle @@ -0,0 +1,34 @@ +apply plugin: 'com.android.library' + +android { + compileSdkVersion rootProject.compileSdkVersion + buildToolsVersion rootProject.buildToolsVersion + + defaultConfig { + minSdkVersion rootProject.minSdkVersion + targetSdkVersion rootProject.targetSdkVersion + buildConfigField "boolean", "IS_INTERNAL_BUILD", 'true' + ndk { + abiFilters 'x86', 'x86_64', 'armeabi-v7a', 'arm64-v8a' + } + + externalNativeBuild { + cmake { + arguments '-DANDROID_TOOLCHAIN=clang' + } + } + } + lintOptions { + abortOnError false + } + sourceSets { + main { + manifest.srcFile './ApplicationManifest.xml' + } + } + externalNativeBuild { + cmake { + path './CMakeLists.txt' + } + } +} diff --git a/android/third-party/Folly/ApplicationManifest.xml b/android/third-party/Folly/ApplicationManifest.xml new file mode 100644 index 000000000..2b0862478 --- /dev/null +++ b/android/third-party/Folly/ApplicationManifest.xml @@ -0,0 +1,4 @@ + + + diff --git a/android/third-party/Folly/CMakeLists.txt b/android/third-party/Folly/CMakeLists.txt new file mode 100644 index 000000000..ee9c054ea --- /dev/null +++ b/android/third-party/Folly/CMakeLists.txt @@ -0,0 +1,81 @@ +cmake_minimum_required (VERSION 3.6.0) + +PROJECT(folly CXX) +enable_language(CXX) +set(PACKAGE_NAME folly) + +set(FOLLY_DIR ${PROJECT_SOURCE_DIR}/folly) + + +list(APPEND dir_list ./) +list(APPEND dir_list ${FOLLY_DIR}/lang) +list(APPEND dir_list ${FOLLY_DIR}/hash/) +list(APPEND dir_list ${FOLLY_DIR}/detail) +list(APPEND dir_list ${FOLLY_DIR}/memory/detail) + +set(BOOST_DIR ../boost/boost_1_63_0/) +set(GLOG_DIR ../glog/) +set(DOUBLECONVERSION_DIR ../double-conversion/double-conversion-3.0.0/) + +list(APPEND dir_list ${BOOST_DIR}) +list(APPEND dir_list ${BOOST_DIR}/../) + +include_directories(${dir_list}) + +add_compile_options( + -DFOLLY_NO_CONFIG=1 + -DFOLLY_HAVE_MEMRCHR + -DFOLLY_MOBILE=1 + -DFOLLY_USE_LIBCPP=1 + -DFOLLY_HAVE_LIBJEMALLOC=0 + -DFOLLY_HAVE_PREADV=0 + -frtti + -fexceptions + -std=c++14 + -Wno-error + -Wno-unused-local-typedefs + -Wno-unused-variable + -Wno-sign-compare + -Wno-comment + -Wno-return-type + -Wno-tautological-constant-compare + ) + +list(APPEND SRC_FILES ${FOLLY_DIR}/Executor.cpp + ${FOLLY_DIR}/lang/ColdClass.cpp + ${FOLLY_DIR}/lang/Assume.cpp + ${FOLLY_DIR}/json.cpp + ${FOLLY_DIR}/Unicode.cpp + ${FOLLY_DIR}/Conv.cpp + ${FOLLY_DIR}/Demangle.cpp + ${FOLLY_DIR}/memory/detail/MallocImpl.cpp + ${FOLLY_DIR}/String.cpp + ${FOLLY_DIR}/dynamic.cpp + ${FOLLY_DIR}/ScopeGuard.cpp + ${FOLLY_DIR}/json_pointer.cpp + ${FOLLY_DIR}/FormatArg.cpp + ${FOLLY_DIR}/Format.cpp + ) + +add_library(${PACKAGE_NAME} SHARED ${SRC_FILES}) + +set(build_DIR ${CMAKE_SOURCE_DIR}/build) + +set(libglog_build_DIR ${build_DIR}/libglog/${ANDROID_ABI}) +set(doubleconversion_build_DIR ${build_DIR}/doubleconversion/${ANDROID_ABI}) + +file(MAKE_DIRECTORY ${build_DIR}) + +add_subdirectory(${GLOG_DIR} ${libglog_build_DIR}) +add_subdirectory(${DOUBLECONVERSION_DIR} ${doubleconversion_build_DIR}) + +target_include_directories(${PACKAGE_NAME} PRIVATE + ${BOOST_DIR} + ${BOOST_DIR}/../ + ${GLOG_DIR}/../ + ${GLOG_DIR}/glog-0.3.5/src/ + ${DOUBLECONVERSION_DIR}) + + +install(TARGETS ${PACKAGE_NAME} DESTINATION ./build/) +target_link_libraries(${PACKAGE_NAME} glog double-conversion) diff --git a/android/third-party/Folly/build.gradle b/android/third-party/Folly/build.gradle new file mode 100644 index 000000000..5593f5fac --- /dev/null +++ b/android/third-party/Folly/build.gradle @@ -0,0 +1,39 @@ +apply plugin: 'com.android.library' + +android { + compileSdkVersion rootProject.compileSdkVersion + buildToolsVersion rootProject.buildToolsVersion + + defaultConfig { + minSdkVersion rootProject.minSdkVersion + targetSdkVersion rootProject.targetSdkVersion + buildConfigField "boolean", "IS_INTERNAL_BUILD", 'true' + ndk { + abiFilters 'x86', 'x86_64', 'armeabi-v7a', 'arm64-v8a' + } + + externalNativeBuild { + cmake { + arguments '-DANDROID_TOOLCHAIN=clang', '-DANDROID_STL=c++_shared' + } + } + } + lintOptions { + abortOnError false + } + sourceSets { + main { + manifest.srcFile './ApplicationManifest.xml' + } + } + externalNativeBuild { + cmake { + path './CMakeLists.txt' + } + } + + dependencies { + implementation project(':glog') + implementation project(':doubleconversion') + } +} diff --git a/android/third-party/glog/ApplicationManifest.xml b/android/third-party/glog/ApplicationManifest.xml new file mode 100644 index 000000000..381f56f15 --- /dev/null +++ b/android/third-party/glog/ApplicationManifest.xml @@ -0,0 +1,4 @@ + + + diff --git a/android/third-party/glog/CMakeLists.txt b/android/third-party/glog/CMakeLists.txt new file mode 100644 index 000000000..346f24852 --- /dev/null +++ b/android/third-party/glog/CMakeLists.txt @@ -0,0 +1,45 @@ +cmake_minimum_required (VERSION 3.6.0) + +PROJECT(glog CXX) +enable_language(CXX) +set(PACKAGE_NAME glog) + +set(glog_DIR glog-0.3.5) + +list(APPEND dir_list ./../) +list(APPEND dir_list ./) +list(APPEND dir_list ${glog_DIR}/) +list(APPEND dir_list ${glog_DIR}/src) +list(APPEND dir_list ${glog_DIR}/glog) +list(APPEND dir_list ${glog_DIR}/base) + +message(STATUS "dir_list = " ${dir_list}) +include_directories(${dir_list}) + + add_compile_options( + -std=c++11 + -Wno-macro-redefined + -Wno-macro-redefined + -Wall + -Wwrite-strings + -Woverloaded-virtual + -Wno-sign-compare + -DNDEBUG + -g + -O2 + -D_START_GOOGLE_NAMESPACE_="namespace google {" + -D_END_GOOGLE_NAMESPACE_="}" + ) + +list(APPEND src_files ${glog_DIR}/src/demangle.cc + ${glog_DIR}/src/logging.cc + ${glog_DIR}/src/raw_logging.cc + ${glog_DIR}/src/signalhandler.cc + ${glog_DIR}/src/symbolize.cc + ${glog_DIR}/src/utilities.cc + ${glog_DIR}/src/vlog_is_on.cc + ) + +add_library(${PACKAGE_NAME} SHARED ${src_files}) +install(TARGETS ${PACKAGE_NAME} DESTINATION ./build/) +target_link_libraries(${PACKAGE_NAME}) diff --git a/android/third-party/glog/build.gradle b/android/third-party/glog/build.gradle new file mode 100644 index 000000000..9dda53405 --- /dev/null +++ b/android/third-party/glog/build.gradle @@ -0,0 +1,34 @@ +apply plugin: 'com.android.library' + +android { + compileSdkVersion rootProject.compileSdkVersion + buildToolsVersion rootProject.buildToolsVersion + + defaultConfig { + minSdkVersion rootProject.minSdkVersion + targetSdkVersion rootProject.targetSdkVersion + buildConfigField "boolean", "IS_INTERNAL_BUILD", 'true' + ndk { + abiFilters 'x86', 'x86_64', 'armeabi-v7a', 'arm64-v8a' + } + + externalNativeBuild { + cmake { + arguments '-DANDROID_TOOLCHAIN=clang' + } + } + } + lintOptions { + abortOnError false + } + sourceSets { + main { + manifest.srcFile './ApplicationManifest.xml' + } + } + externalNativeBuild { + cmake { + path './CMakeLists.txt' + } + } +} diff --git a/android/third-party/glog/config.h b/android/third-party/glog/config.h new file mode 100644 index 000000000..1e20b0da7 --- /dev/null +++ b/android/third-party/glog/config.h @@ -0,0 +1,179 @@ +/* src/config.h. Generated from config.h.in by configure. */ +/* src/config.h.in. Generated from configure.ac by autoheader. */ + +/* define if glog doesn't use RTTI */ +#define DISABLE_RTTI 1 + +/* Namespace for Google classes */ +#define GOOGLE_NAMESPACE google + +/* Define if you have the `dladdr' function */ +#define HAVE_DLADDR 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_DLFCN_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_EXECINFO_H */ + +/* Define if you have the `fcntl' function */ +#define HAVE_FCNTL 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_GLOB_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_INTTYPES_H 1 + +/* Define to 1 if you have the `pthread' library (-lpthread). */ +/* #undef HAVE_LIBPTHREAD */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_LIBUNWIND_H */ + +/* define if you have google gflags library */ +/* #undef HAVE_LIB_GFLAGS */ + +/* define if you have google gmock library */ +/* #undef HAVE_LIB_GMOCK */ + +/* define if you have google gtest library */ +/* #undef HAVE_LIB_GTEST */ + +/* define if you have libunwind */ +/* #undef HAVE_LIB_UNWIND */ + +/* Define to 1 if you have the header file. */ +#define HAVE_MEMORY_H 1 + +/* define if the compiler implements namespaces */ +#define HAVE_NAMESPACES 1 + +/* Define if you have POSIX threads libraries and header files. */ +#define HAVE_PTHREAD 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_PWD_H 1 + +/* define if the compiler implements pthread_rwlock_* */ +#define HAVE_RWLOCK 1 + +/* Define if you have the `sigaltstack' function */ +#define HAVE_SIGALTSTACK 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDINT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDLIB_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STRINGS_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STRING_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYSCALL_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_SYSLOG_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_STAT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_SYSCALL_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_TIME_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_TYPES_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_UCONTEXT_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_UTSNAME_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_UCONTEXT_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_UNISTD_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_UNWIND_H 1 + +/* define if the compiler supports using expression for operator */ +#define HAVE_USING_OPERATOR 1 + +/* define if your compiler has __attribute__ */ +#define HAVE___ATTRIBUTE__ 1 + +/* define if your compiler has __builtin_expect */ +#define HAVE___BUILTIN_EXPECT 1 + +/* define if your compiler has __sync_val_compare_and_swap */ +#define HAVE___SYNC_VAL_COMPARE_AND_SWAP 1 + +/* Define to the sub-directory in which libtool stores uninstalled libraries. + */ +#define LT_OBJDIR ".libs/" + +/* Name of package */ +#define PACKAGE "glog" + +/* Define to the address where bug reports for this package should be sent. */ +#define PACKAGE_BUGREPORT "opensource@google.com" + +/* Define to the full name of this package. */ +#define PACKAGE_NAME "glog" + +/* Define to the full name and version of this package. */ +#define PACKAGE_STRING "glog 0.3.3" + +/* Define to the one symbol short name of this package. */ +#define PACKAGE_TARNAME "glog" + +/* Define to the home page for this package. */ +#define PACKAGE_URL "" + +/* Define to the version of this package. */ +#define PACKAGE_VERSION "0.3.3" + +/* How to access the PC from a struct ucontext */ +/* #undef PC_FROM_UCONTEXT */ + +/* Define to necessary symbol if this constant uses a non-standard name on + your system. */ +/* #undef PTHREAD_CREATE_JOINABLE */ + +/* The size of `void *', as computed by sizeof. */ +#define SIZEOF_VOID_P 4 + +/* Define to 1 if you have the ANSI C header files. */ +/* #undef STDC_HEADERS */ + +/* the namespace where STL code like vector<> is defined */ +#define STL_NAMESPACE std + +/* location of source code */ +#define TEST_SRC_DIR "." + +/* Version number of package */ +#define VERSION "0.3.3" + +/* Stops putting the code inside the Google namespace */ +#define _END_GOOGLE_NAMESPACE_ } + +/* Puts following code inside the Google namespace */ +#define _START_GOOGLE_NAMESPACE_ namespace google { + + +/* TODO(vjn/dreiss): revisit these when use the android-21 (or newer) NDK platform. */ +#undef HAVE_SYSCALL_H +#undef HAVE_SYS_SYSCALL_H +#undef OS_LINUX +#undef OS_MACOSX diff --git a/android/third-party/glog/logging.cc b/android/third-party/glog/logging.cc new file mode 100644 index 000000000..6529caa76 --- /dev/null +++ b/android/third-party/glog/logging.cc @@ -0,0 +1,2088 @@ +// Copyright (c) 1999, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#define _GNU_SOURCE 1 // needed for O_NOFOLLOW and pread()/pwrite() + +#include "utilities.h" + +#include +#include +#include +#include +#ifdef HAVE_UNISTD_H +# include // For _exit. +#endif +#include +#include +#include +#ifdef HAVE_SYS_UTSNAME_H +# include // For uname. +#endif +#include +#include +#include +#include +#include +#ifdef HAVE_PWD_H +# include +#endif +#ifdef HAVE_SYSLOG_H +# include +#endif +#include +#include // for errno +#include +#include "base/commandlineflags.h" // to get the program name +#include "glog/logging.h" +#include "glog/raw_logging.h" +#include "base/googleinit.h" + +#ifdef HAVE_STACKTRACE +# include "stacktrace.h" +#endif + +using std::string; +using std::vector; +using std::setw; +using std::setfill; +using std::hex; +using std::dec; +using std::min; +using std::ostream; +using std::ostringstream; + +using std::FILE; +using std::fwrite; +using std::fclose; +using std::fflush; +using std::fprintf; +using std::perror; + +#ifdef __QNX__ +using std::fdopen; +#endif + +#ifdef _WIN32 +#define fdopen _fdopen +#endif + +// There is no thread annotation support. +#define EXCLUSIVE_LOCKS_REQUIRED(mu) + +static bool BoolFromEnv(const char *varname, bool defval) { + const char* const valstr = getenv(varname); + if (!valstr) { + return defval; + } + return memchr("tTyY1\0", valstr[0], 6) != NULL; +} + +GLOG_DEFINE_bool(logtostderr, BoolFromEnv("GOOGLE_LOGTOSTDERR", false), + "log messages go to stderr instead of logfiles"); +GLOG_DEFINE_bool(alsologtostderr, BoolFromEnv("GOOGLE_ALSOLOGTOSTDERR", false), + "log messages go to stderr in addition to logfiles"); +GLOG_DEFINE_bool(colorlogtostderr, false, + "color messages logged to stderr (if supported by terminal)"); +#ifdef OS_LINUX +GLOG_DEFINE_bool(drop_log_memory, true, "Drop in-memory buffers of log contents. " + "Logs can grow very quickly and they are rarely read before they " + "need to be evicted from memory. Instead, drop them from memory " + "as soon as they are flushed to disk."); +_START_GOOGLE_NAMESPACE_ +namespace logging { +static const int64 kPageSize = getpagesize(); +} +_END_GOOGLE_NAMESPACE_ +#endif + +// By default, errors (including fatal errors) get logged to stderr as +// well as the file. +// +// The default is ERROR instead of FATAL so that users can see problems +// when they run a program without having to look in another file. +DEFINE_int32(stderrthreshold, + GOOGLE_NAMESPACE::GLOG_ERROR, + "log messages at or above this level are copied to stderr in " + "addition to logfiles. This flag obsoletes --alsologtostderr."); + +GLOG_DEFINE_string(alsologtoemail, "", + "log messages go to these email addresses " + "in addition to logfiles"); +GLOG_DEFINE_bool(log_prefix, true, + "Prepend the log prefix to the start of each log line"); +GLOG_DEFINE_int32(minloglevel, 0, "Messages logged at a lower level than this don't " + "actually get logged anywhere"); +GLOG_DEFINE_int32(logbuflevel, 0, + "Buffer log messages logged at this level or lower" + " (-1 means don't buffer; 0 means buffer INFO only;" + " ...)"); +GLOG_DEFINE_int32(logbufsecs, 30, + "Buffer log messages for at most this many seconds"); +GLOG_DEFINE_int32(logemaillevel, 999, + "Email log messages logged at this level or higher" + " (0 means email all; 3 means email FATAL only;" + " ...)"); +GLOG_DEFINE_string(logmailer, "/bin/mail", + "Mailer used to send logging email"); + +// Compute the default value for --log_dir +static const char* DefaultLogDir() { + const char* env; + env = getenv("GOOGLE_LOG_DIR"); + if (env != NULL && env[0] != '\0') { + return env; + } + env = getenv("TEST_TMPDIR"); + if (env != NULL && env[0] != '\0') { + return env; + } + return ""; +} + +GLOG_DEFINE_int32(logfile_mode, 0664, "Log file mode/permissions."); + +GLOG_DEFINE_string(log_dir, DefaultLogDir(), + "If specified, logfiles are written into this directory instead " + "of the default logging directory."); +GLOG_DEFINE_string(log_link, "", "Put additional links to the log " + "files in this directory"); + +GLOG_DEFINE_int32(max_log_size, 1800, + "approx. maximum log file size (in MB). A value of 0 will " + "be silently overridden to 1."); + +GLOG_DEFINE_bool(stop_logging_if_full_disk, false, + "Stop attempting to log to disk if the disk is full."); + +GLOG_DEFINE_string(log_backtrace_at, "", + "Emit a backtrace when logging at file:linenum."); + +// TODO(hamaji): consider windows +#define PATH_SEPARATOR '/' + +#ifndef HAVE_PREAD +#if defined(OS_WINDOWS) +#include +#define ssize_t SSIZE_T +#endif +ssize_t pread(int fd, void* buf, size_t count, off_t offset) { + off_t orig_offset = lseek(fd, 0, SEEK_CUR); + if (orig_offset == (off_t)-1) + return -1; + if (lseek(fd, offset, SEEK_CUR) == (off_t)-1) + return -1; + ssize_t len = read(fd, buf, count); + if (len < 0) + return len; + if (lseek(fd, orig_offset, SEEK_SET) == (off_t)-1) + return -1; + return len; +} +#endif // !HAVE_PREAD + +#ifndef HAVE_PWRITE +static ssize_t pwrite(int fd, void* buf, size_t count, off_t offset) { + off_t orig_offset = lseek(fd, 0, SEEK_CUR); + if (orig_offset == (off_t)-1) + return -1; + if (lseek(fd, offset, SEEK_CUR) == (off_t)-1) + return -1; + ssize_t len = write(fd, buf, count); + if (len < 0) + return len; + if (lseek(fd, orig_offset, SEEK_SET) == (off_t)-1) + return -1; + return len; +} +#endif // !HAVE_PWRITE + +static void GetHostName(string* hostname) { +#if defined(HAVE_SYS_UTSNAME_H) + struct utsname buf; + if (0 != uname(&buf)) { + // ensure null termination on failure + *buf.nodename = '\0'; + } + *hostname = buf.nodename; +#elif defined(OS_WINDOWS) + char buf[MAX_COMPUTERNAME_LENGTH + 1]; + DWORD len = MAX_COMPUTERNAME_LENGTH + 1; + if (GetComputerNameA(buf, &len)) { + *hostname = buf; + } else { + hostname->clear(); + } +#else +# warning There is no way to retrieve the host name. + *hostname = "(unknown)"; +#endif +} + +// Returns true iff terminal supports using colors in output. +static bool TerminalSupportsColor() { + bool term_supports_color = false; +#ifdef OS_WINDOWS + // on Windows TERM variable is usually not set, but the console does + // support colors. + term_supports_color = true; +#else + // On non-Windows platforms, we rely on the TERM variable. + const char* const term = getenv("TERM"); + if (term != NULL && term[0] != '\0') { + term_supports_color = + !strcmp(term, "xterm") || + !strcmp(term, "xterm-color") || + !strcmp(term, "xterm-256color") || + !strcmp(term, "screen-256color") || + !strcmp(term, "screen") || + !strcmp(term, "linux") || + !strcmp(term, "cygwin"); + } +#endif + return term_supports_color; +} + +_START_GOOGLE_NAMESPACE_ + +enum GLogColor { + COLOR_DEFAULT, + COLOR_RED, + COLOR_GREEN, + COLOR_YELLOW +}; + +static GLogColor SeverityToColor(LogSeverity severity) { + assert(severity >= 0 && severity < NUM_SEVERITIES); + GLogColor color = COLOR_DEFAULT; + switch (severity) { + case GLOG_INFO: + color = COLOR_DEFAULT; + break; + case GLOG_WARNING: + color = COLOR_YELLOW; + break; + case GLOG_ERROR: + case GLOG_FATAL: + color = COLOR_RED; + break; + default: + // should never get here. + assert(false); + } + return color; +} + +#ifdef OS_WINDOWS + +// Returns the character attribute for the given color. +WORD GetColorAttribute(GLogColor color) { + switch (color) { + case COLOR_RED: return FOREGROUND_RED; + case COLOR_GREEN: return FOREGROUND_GREEN; + case COLOR_YELLOW: return FOREGROUND_RED | FOREGROUND_GREEN; + default: return 0; + } +} + +#else + +// Returns the ANSI color code for the given color. +const char* GetAnsiColorCode(GLogColor color) { + switch (color) { + case COLOR_RED: return "1"; + case COLOR_GREEN: return "2"; + case COLOR_YELLOW: return "3"; + case COLOR_DEFAULT: return ""; + }; + return NULL; // stop warning about return type. +} + +#endif // OS_WINDOWS + +// Safely get max_log_size, overriding to 1 if it somehow gets defined as 0 +static int32 MaxLogSize() { + return (FLAGS_max_log_size > 0 ? FLAGS_max_log_size : 1); +} + +// An arbitrary limit on the length of a single log message. This +// is so that streaming can be done more efficiently. +const size_t LogMessage::kMaxLogMessageLen = 30000; + +struct LogMessage::LogMessageData { + LogMessageData(); + + int preserved_errno_; // preserved errno + // Buffer space; contains complete message text. + char message_text_[LogMessage::kMaxLogMessageLen+1]; + LogStream stream_; + char severity_; // What level is this LogMessage logged at? + int line_; // line number where logging call is. + void (LogMessage::*send_method_)(); // Call this in destructor to send + union { // At most one of these is used: union to keep the size low. + LogSink* sink_; // NULL or sink to send message to + std::vector* outvec_; // NULL or vector to push message onto + std::string* message_; // NULL or string to write message into + }; + time_t timestamp_; // Time of creation of LogMessage + struct ::tm tm_time_; // Time of creation of LogMessage + size_t num_prefix_chars_; // # of chars of prefix in this message + size_t num_chars_to_log_; // # of chars of msg to send to log + size_t num_chars_to_syslog_; // # of chars of msg to send to syslog + const char* basename_; // basename of file that called LOG + const char* fullname_; // fullname of file that called LOG + bool has_been_flushed_; // false => data has not been flushed + bool first_fatal_; // true => this was first fatal msg + + private: + LogMessageData(const LogMessageData&); + void operator=(const LogMessageData&); +}; + +// A mutex that allows only one thread to log at a time, to keep things from +// getting jumbled. Some other very uncommon logging operations (like +// changing the destination file for log messages of a given severity) also +// lock this mutex. Please be sure that anybody who might possibly need to +// lock it does so. +static Mutex log_mutex; + +// Number of messages sent at each severity. Under log_mutex. +int64 LogMessage::num_messages_[NUM_SEVERITIES] = {0, 0, 0, 0}; + +// Globally disable log writing (if disk is full) +static bool stop_writing = false; + +const char*const LogSeverityNames[NUM_SEVERITIES] = { + "INFO", "WARNING", "ERROR", "FATAL" +}; + +// Has the user called SetExitOnDFatal(true)? +static bool exit_on_dfatal = true; + +const char* GetLogSeverityName(LogSeverity severity) { + return LogSeverityNames[severity]; +} + +static bool SendEmailInternal(const char*dest, const char *subject, + const char*body, bool use_logging); + +base::Logger::~Logger() { +} + +namespace { + +// Encapsulates all file-system related state +class LogFileObject : public base::Logger { + public: + LogFileObject(LogSeverity severity, const char* base_filename); + ~LogFileObject(); + + virtual void Write(bool force_flush, // Should we force a flush here? + time_t timestamp, // Timestamp for this entry + const char* message, + int message_len); + + // Configuration options + void SetBasename(const char* basename); + void SetExtension(const char* ext); + void SetSymlinkBasename(const char* symlink_basename); + + // Normal flushing routine + virtual void Flush(); + + // It is the actual file length for the system loggers, + // i.e., INFO, ERROR, etc. + virtual uint32 LogSize() { + MutexLock l(&lock_); + return file_length_; + } + + // Internal flush routine. Exposed so that FlushLogFilesUnsafe() + // can avoid grabbing a lock. Usually Flush() calls it after + // acquiring lock_. + void FlushUnlocked(); + + private: + static const uint32 kRolloverAttemptFrequency = 0x20; + + Mutex lock_; + bool base_filename_selected_; + string base_filename_; + string symlink_basename_; + string filename_extension_; // option users can specify (eg to add port#) + FILE* file_; + LogSeverity severity_; + uint32 bytes_since_flush_; + uint32 file_length_; + unsigned int rollover_attempt_; + int64 next_flush_time_; // cycle count at which to flush log + + // Actually create a logfile using the value of base_filename_ and the + // supplied argument time_pid_string + // REQUIRES: lock_ is held + bool CreateLogfile(const string& time_pid_string); +}; + +} // namespace + +class LogDestination { + public: + friend class LogMessage; + friend void ReprintFatalMessage(); + friend base::Logger* base::GetLogger(LogSeverity); + friend void base::SetLogger(LogSeverity, base::Logger*); + + // These methods are just forwarded to by their global versions. + static void SetLogDestination(LogSeverity severity, + const char* base_filename); + static void SetLogSymlink(LogSeverity severity, + const char* symlink_basename); + static void AddLogSink(LogSink *destination); + static void RemoveLogSink(LogSink *destination); + static void SetLogFilenameExtension(const char* filename_extension); + static void SetStderrLogging(LogSeverity min_severity); + static void SetEmailLogging(LogSeverity min_severity, const char* addresses); + static void LogToStderr(); + // Flush all log files that are at least at the given severity level + static void FlushLogFiles(int min_severity); + static void FlushLogFilesUnsafe(int min_severity); + + // we set the maximum size of our packet to be 1400, the logic being + // to prevent fragmentation. + // Really this number is arbitrary. + static const int kNetworkBytes = 1400; + + static const string& hostname(); + static const bool& terminal_supports_color() { + return terminal_supports_color_; + } + + static void DeleteLogDestinations(); + + private: + LogDestination(LogSeverity severity, const char* base_filename); + ~LogDestination() { } + + // Take a log message of a particular severity and log it to stderr + // iff it's of a high enough severity to deserve it. + static void MaybeLogToStderr(LogSeverity severity, const char* message, + size_t len); + + // Take a log message of a particular severity and log it to email + // iff it's of a high enough severity to deserve it. + static void MaybeLogToEmail(LogSeverity severity, const char* message, + size_t len); + // Take a log message of a particular severity and log it to a file + // iff the base filename is not "" (which means "don't log to me") + static void MaybeLogToLogfile(LogSeverity severity, + time_t timestamp, + const char* message, size_t len); + // Take a log message of a particular severity and log it to the file + // for that severity and also for all files with severity less than + // this severity. + static void LogToAllLogfiles(LogSeverity severity, + time_t timestamp, + const char* message, size_t len); + + // Send logging info to all registered sinks. + static void LogToSinks(LogSeverity severity, + const char *full_filename, + const char *base_filename, + int line, + const struct ::tm* tm_time, + const char* message, + size_t message_len); + + // Wait for all registered sinks via WaitTillSent + // including the optional one in "data". + static void WaitForSinks(LogMessage::LogMessageData* data); + + static LogDestination* log_destination(LogSeverity severity); + + LogFileObject fileobject_; + base::Logger* logger_; // Either &fileobject_, or wrapper around it + + static LogDestination* log_destinations_[NUM_SEVERITIES]; + static LogSeverity email_logging_severity_; + static string addresses_; + static string hostname_; + static bool terminal_supports_color_; + + // arbitrary global logging destinations. + static vector* sinks_; + + // Protects the vector sinks_, + // but not the LogSink objects its elements reference. + static Mutex sink_mutex_; + + // Disallow + LogDestination(const LogDestination&); + LogDestination& operator=(const LogDestination&); +}; + +// Errors do not get logged to email by default. +LogSeverity LogDestination::email_logging_severity_ = 99999; + +string LogDestination::addresses_; +string LogDestination::hostname_; + +vector* LogDestination::sinks_ = NULL; +Mutex LogDestination::sink_mutex_; +bool LogDestination::terminal_supports_color_ = TerminalSupportsColor(); + +/* static */ +const string& LogDestination::hostname() { + if (hostname_.empty()) { + GetHostName(&hostname_); + if (hostname_.empty()) { + hostname_ = "(unknown)"; + } + } + return hostname_; +} + +LogDestination::LogDestination(LogSeverity severity, + const char* base_filename) + : fileobject_(severity, base_filename), + logger_(&fileobject_) { +} + +inline void LogDestination::FlushLogFilesUnsafe(int min_severity) { + // assume we have the log_mutex or we simply don't care + // about it + for (int i = min_severity; i < NUM_SEVERITIES; i++) { + LogDestination* log = log_destinations_[i]; + if (log != NULL) { + // Flush the base fileobject_ logger directly instead of going + // through any wrappers to reduce chance of deadlock. + log->fileobject_.FlushUnlocked(); + } + } +} + +inline void LogDestination::FlushLogFiles(int min_severity) { + // Prevent any subtle race conditions by wrapping a mutex lock around + // all this stuff. + MutexLock l(&log_mutex); + for (int i = min_severity; i < NUM_SEVERITIES; i++) { + LogDestination* log = log_destination(i); + if (log != NULL) { + log->logger_->Flush(); + } + } +} + +inline void LogDestination::SetLogDestination(LogSeverity severity, + const char* base_filename) { + assert(severity >= 0 && severity < NUM_SEVERITIES); + // Prevent any subtle race conditions by wrapping a mutex lock around + // all this stuff. + MutexLock l(&log_mutex); + log_destination(severity)->fileobject_.SetBasename(base_filename); +} + +inline void LogDestination::SetLogSymlink(LogSeverity severity, + const char* symlink_basename) { + CHECK_GE(severity, 0); + CHECK_LT(severity, NUM_SEVERITIES); + MutexLock l(&log_mutex); + log_destination(severity)->fileobject_.SetSymlinkBasename(symlink_basename); +} + +inline void LogDestination::AddLogSink(LogSink *destination) { + // Prevent any subtle race conditions by wrapping a mutex lock around + // all this stuff. + MutexLock l(&sink_mutex_); + if (!sinks_) sinks_ = new vector; + sinks_->push_back(destination); +} + +inline void LogDestination::RemoveLogSink(LogSink *destination) { + // Prevent any subtle race conditions by wrapping a mutex lock around + // all this stuff. + MutexLock l(&sink_mutex_); + // This doesn't keep the sinks in order, but who cares? + if (sinks_) { + for (int i = sinks_->size() - 1; i >= 0; i--) { + if ((*sinks_)[i] == destination) { + (*sinks_)[i] = (*sinks_)[sinks_->size() - 1]; + sinks_->pop_back(); + break; + } + } + } +} + +inline void LogDestination::SetLogFilenameExtension(const char* ext) { + // Prevent any subtle race conditions by wrapping a mutex lock around + // all this stuff. + MutexLock l(&log_mutex); + for ( int severity = 0; severity < NUM_SEVERITIES; ++severity ) { + log_destination(severity)->fileobject_.SetExtension(ext); + } +} + +inline void LogDestination::SetStderrLogging(LogSeverity min_severity) { + assert(min_severity >= 0 && min_severity < NUM_SEVERITIES); + // Prevent any subtle race conditions by wrapping a mutex lock around + // all this stuff. + MutexLock l(&log_mutex); + FLAGS_stderrthreshold = min_severity; +} + +inline void LogDestination::LogToStderr() { + // *Don't* put this stuff in a mutex lock, since SetStderrLogging & + // SetLogDestination already do the locking! + SetStderrLogging(0); // thus everything is "also" logged to stderr + for ( int i = 0; i < NUM_SEVERITIES; ++i ) { + SetLogDestination(i, ""); // "" turns off logging to a logfile + } +} + +inline void LogDestination::SetEmailLogging(LogSeverity min_severity, + const char* addresses) { + assert(min_severity >= 0 && min_severity < NUM_SEVERITIES); + // Prevent any subtle race conditions by wrapping a mutex lock around + // all this stuff. + MutexLock l(&log_mutex); + LogDestination::email_logging_severity_ = min_severity; + LogDestination::addresses_ = addresses; +} + +static void ColoredWriteToStderr(LogSeverity severity, + const char* message, size_t len) { + const GLogColor color = + (LogDestination::terminal_supports_color() && FLAGS_colorlogtostderr) ? + SeverityToColor(severity) : COLOR_DEFAULT; + + // Avoid using cerr from this module since we may get called during + // exit code, and cerr may be partially or fully destroyed by then. + if (COLOR_DEFAULT == color) { + fwrite(message, len, 1, stderr); + return; + } +#ifdef OS_WINDOWS + const HANDLE stderr_handle = GetStdHandle(STD_ERROR_HANDLE); + + // Gets the current text color. + CONSOLE_SCREEN_BUFFER_INFO buffer_info; + GetConsoleScreenBufferInfo(stderr_handle, &buffer_info); + const WORD old_color_attrs = buffer_info.wAttributes; + + // We need to flush the stream buffers into the console before each + // SetConsoleTextAttribute call lest it affect the text that is already + // printed but has not yet reached the console. + fflush(stderr); + SetConsoleTextAttribute(stderr_handle, + GetColorAttribute(color) | FOREGROUND_INTENSITY); + fwrite(message, len, 1, stderr); + fflush(stderr); + // Restores the text color. + SetConsoleTextAttribute(stderr_handle, old_color_attrs); +#else + fprintf(stderr, "\033[0;3%sm", GetAnsiColorCode(color)); + fwrite(message, len, 1, stderr); + fprintf(stderr, "\033[m"); // Resets the terminal to default. +#endif // OS_WINDOWS +} + +static void WriteToStderr(const char* message, size_t len) { + // Avoid using cerr from this module since we may get called during + // exit code, and cerr may be partially or fully destroyed by then. + fwrite(message, len, 1, stderr); +} + +inline void LogDestination::MaybeLogToStderr(LogSeverity severity, + const char* message, size_t len) { + if ((severity >= FLAGS_stderrthreshold) || FLAGS_alsologtostderr) { + ColoredWriteToStderr(severity, message, len); +#ifdef OS_WINDOWS + // On Windows, also output to the debugger + ::OutputDebugStringA(string(message,len).c_str()); +#endif + } +} + + +inline void LogDestination::MaybeLogToEmail(LogSeverity severity, + const char* message, size_t len) { + if (severity >= email_logging_severity_ || + severity >= FLAGS_logemaillevel) { + string to(FLAGS_alsologtoemail); + if (!addresses_.empty()) { + if (!to.empty()) { + to += ","; + } + to += addresses_; + } + const string subject(string("[LOG] ") + LogSeverityNames[severity] + ": " + + glog_internal_namespace_::ProgramInvocationShortName()); + string body(hostname()); + body += "\n\n"; + body.append(message, len); + + // should NOT use SendEmail(). The caller of this function holds the + // log_mutex and SendEmail() calls LOG/VLOG which will block trying to + // acquire the log_mutex object. Use SendEmailInternal() and set + // use_logging to false. + SendEmailInternal(to.c_str(), subject.c_str(), body.c_str(), false); + } +} + + +inline void LogDestination::MaybeLogToLogfile(LogSeverity severity, + time_t timestamp, + const char* message, + size_t len) { + const bool should_flush = severity > FLAGS_logbuflevel; + LogDestination* destination = log_destination(severity); + destination->logger_->Write(should_flush, timestamp, message, len); +} + +inline void LogDestination::LogToAllLogfiles(LogSeverity severity, + time_t timestamp, + const char* message, + size_t len) { + + if ( FLAGS_logtostderr ) { // global flag: never log to file + ColoredWriteToStderr(severity, message, len); + } else { + for (int i = severity; i >= 0; --i) + LogDestination::MaybeLogToLogfile(i, timestamp, message, len); + } +} + +inline void LogDestination::LogToSinks(LogSeverity severity, + const char *full_filename, + const char *base_filename, + int line, + const struct ::tm* tm_time, + const char* message, + size_t message_len) { + ReaderMutexLock l(&sink_mutex_); + if (sinks_) { + for (int i = sinks_->size() - 1; i >= 0; i--) { + (*sinks_)[i]->send(severity, full_filename, base_filename, + line, tm_time, message, message_len); + } + } +} + +inline void LogDestination::WaitForSinks(LogMessage::LogMessageData* data) { + ReaderMutexLock l(&sink_mutex_); + if (sinks_) { + for (int i = sinks_->size() - 1; i >= 0; i--) { + (*sinks_)[i]->WaitTillSent(); + } + } + const bool send_to_sink = + (data->send_method_ == &LogMessage::SendToSink) || + (data->send_method_ == &LogMessage::SendToSinkAndLog); + if (send_to_sink && data->sink_ != NULL) { + data->sink_->WaitTillSent(); + } +} + +LogDestination* LogDestination::log_destinations_[NUM_SEVERITIES]; + +inline LogDestination* LogDestination::log_destination(LogSeverity severity) { + assert(severity >=0 && severity < NUM_SEVERITIES); + if (!log_destinations_[severity]) { + log_destinations_[severity] = new LogDestination(severity, NULL); + } + return log_destinations_[severity]; +} + +void LogDestination::DeleteLogDestinations() { + for (int severity = 0; severity < NUM_SEVERITIES; ++severity) { + delete log_destinations_[severity]; + log_destinations_[severity] = NULL; + } + MutexLock l(&sink_mutex_); + delete sinks_; + sinks_ = NULL; +} + +namespace { + +LogFileObject::LogFileObject(LogSeverity severity, + const char* base_filename) + : base_filename_selected_(base_filename != NULL), + base_filename_((base_filename != NULL) ? base_filename : ""), + symlink_basename_(glog_internal_namespace_::ProgramInvocationShortName()), + filename_extension_(), + file_(NULL), + severity_(severity), + bytes_since_flush_(0), + file_length_(0), + rollover_attempt_(kRolloverAttemptFrequency-1), + next_flush_time_(0) { + assert(severity >= 0); + assert(severity < NUM_SEVERITIES); +} + +LogFileObject::~LogFileObject() { + MutexLock l(&lock_); + if (file_ != NULL) { + fclose(file_); + file_ = NULL; + } +} + +void LogFileObject::SetBasename(const char* basename) { + MutexLock l(&lock_); + base_filename_selected_ = true; + if (base_filename_ != basename) { + // Get rid of old log file since we are changing names + if (file_ != NULL) { + fclose(file_); + file_ = NULL; + rollover_attempt_ = kRolloverAttemptFrequency-1; + } + base_filename_ = basename; + } +} + +void LogFileObject::SetExtension(const char* ext) { + MutexLock l(&lock_); + if (filename_extension_ != ext) { + // Get rid of old log file since we are changing names + if (file_ != NULL) { + fclose(file_); + file_ = NULL; + rollover_attempt_ = kRolloverAttemptFrequency-1; + } + filename_extension_ = ext; + } +} + +void LogFileObject::SetSymlinkBasename(const char* symlink_basename) { + MutexLock l(&lock_); + symlink_basename_ = symlink_basename; +} + +void LogFileObject::Flush() { + MutexLock l(&lock_); + FlushUnlocked(); +} + +void LogFileObject::FlushUnlocked(){ + if (file_ != NULL) { + fflush(file_); + bytes_since_flush_ = 0; + } + // Figure out when we are due for another flush. + const int64 next = (FLAGS_logbufsecs + * static_cast(1000000)); // in usec + next_flush_time_ = CycleClock_Now() + UsecToCycles(next); +} + +bool LogFileObject::CreateLogfile(const string& time_pid_string) { + string string_filename = base_filename_+filename_extension_+ + time_pid_string; + const char* filename = string_filename.c_str(); + int fd = open(filename, O_WRONLY | O_CREAT | O_EXCL, FLAGS_logfile_mode); + if (fd == -1) return false; +#ifdef HAVE_FCNTL + // Mark the file close-on-exec. We don't really care if this fails + fcntl(fd, F_SETFD, FD_CLOEXEC); +#endif + + file_ = fdopen(fd, "a"); // Make a FILE*. + if (file_ == NULL) { // Man, we're screwed! + close(fd); + unlink(filename); // Erase the half-baked evidence: an unusable log file + return false; + } + + // We try to create a symlink called ., + // which is easier to use. (Every time we create a new logfile, + // we destroy the old symlink and create a new one, so it always + // points to the latest logfile.) If it fails, we're sad but it's + // no error. + if (!symlink_basename_.empty()) { + // take directory from filename + const char* slash = strrchr(filename, PATH_SEPARATOR); + const string linkname = + symlink_basename_ + '.' + LogSeverityNames[severity_]; + string linkpath; + if ( slash ) linkpath = string(filename, slash-filename+1); // get dirname + linkpath += linkname; + unlink(linkpath.c_str()); // delete old one if it exists + +#if defined(OS_WINDOWS) + // TODO(hamaji): Create lnk file on Windows? +#elif defined(HAVE_UNISTD_H) + // We must have unistd.h. + // Make the symlink be relative (in the same dir) so that if the + // entire log directory gets relocated the link is still valid. + const char *linkdest = slash ? (slash + 1) : filename; + if (symlink(linkdest, linkpath.c_str()) != 0) { + // silently ignore failures + } + + // Make an additional link to the log file in a place specified by + // FLAGS_log_link, if indicated + if (!FLAGS_log_link.empty()) { + linkpath = FLAGS_log_link + "/" + linkname; + unlink(linkpath.c_str()); // delete old one if it exists + if (symlink(filename, linkpath.c_str()) != 0) { + // silently ignore failures + } + } +#endif + } + + return true; // Everything worked +} + +void LogFileObject::Write(bool force_flush, + time_t timestamp, + const char* message, + int message_len) { + MutexLock l(&lock_); + + // We don't log if the base_name_ is "" (which means "don't write") + if (base_filename_selected_ && base_filename_.empty()) { + return; + } + + if (static_cast(file_length_ >> 20) >= MaxLogSize() || + PidHasChanged()) { + if (file_ != NULL) fclose(file_); + file_ = NULL; + file_length_ = bytes_since_flush_ = 0; + rollover_attempt_ = kRolloverAttemptFrequency-1; + } + + // If there's no destination file, make one before outputting + if (file_ == NULL) { + // Try to rollover the log file every 32 log messages. The only time + // this could matter would be when we have trouble creating the log + // file. If that happens, we'll lose lots of log messages, of course! + if (++rollover_attempt_ != kRolloverAttemptFrequency) return; + rollover_attempt_ = 0; + + struct ::tm tm_time; + localtime_r(×tamp, &tm_time); + + // The logfile's filename will have the date/time & pid in it + ostringstream time_pid_stream; + time_pid_stream.fill('0'); + time_pid_stream << 1900+tm_time.tm_year + << setw(2) << 1+tm_time.tm_mon + << setw(2) << tm_time.tm_mday + << '-' + << setw(2) << tm_time.tm_hour + << setw(2) << tm_time.tm_min + << setw(2) << tm_time.tm_sec + << '.' + << GetMainThreadPid(); + const string& time_pid_string = time_pid_stream.str(); + + if (base_filename_selected_) { + if (!CreateLogfile(time_pid_string)) { + perror("Could not create log file"); + fprintf(stderr, "COULD NOT CREATE LOGFILE '%s'!\n", + time_pid_string.c_str()); + return; + } + } else { + // If no base filename for logs of this severity has been set, use a + // default base filename of + // "...log..". So + // logfiles will have names like + // webserver.examplehost.root.log.INFO.19990817-150000.4354, where + // 19990817 is a date (1999 August 17), 150000 is a time (15:00:00), + // and 4354 is the pid of the logging process. The date & time reflect + // when the file was created for output. + // + // Where does the file get put? Successively try the directories + // "/tmp", and "." + string stripped_filename( + glog_internal_namespace_::ProgramInvocationShortName()); + string hostname; + GetHostName(&hostname); + + string uidname = MyUserName(); + // We should not call CHECK() here because this function can be + // called after holding on to log_mutex. We don't want to + // attempt to hold on to the same mutex, and get into a + // deadlock. Simply use a name like invalid-user. + if (uidname.empty()) uidname = "invalid-user"; + + stripped_filename = stripped_filename+'.'+hostname+'.' + +uidname+".log." + +LogSeverityNames[severity_]+'.'; + // We're going to (potentially) try to put logs in several different dirs + const vector & log_dirs = GetLoggingDirectories(); + + // Go through the list of dirs, and try to create the log file in each + // until we succeed or run out of options + bool success = false; + for (vector::const_iterator dir = log_dirs.begin(); + dir != log_dirs.end(); + ++dir) { + base_filename_ = *dir + "/" + stripped_filename; + if ( CreateLogfile(time_pid_string) ) { + success = true; + break; + } + } + // If we never succeeded, we have to give up + if ( success == false ) { + perror("Could not create logging file"); + fprintf(stderr, "COULD NOT CREATE A LOGGINGFILE %s!", + time_pid_string.c_str()); + return; + } + } + + // Write a header message into the log file + ostringstream file_header_stream; + file_header_stream.fill('0'); + file_header_stream << "Log file created at: " + << 1900+tm_time.tm_year << '/' + << setw(2) << 1+tm_time.tm_mon << '/' + << setw(2) << tm_time.tm_mday + << ' ' + << setw(2) << tm_time.tm_hour << ':' + << setw(2) << tm_time.tm_min << ':' + << setw(2) << tm_time.tm_sec << '\n' + << "Running on machine: " + << LogDestination::hostname() << '\n' + << "Log line format: [IWEF]mmdd hh:mm:ss.uuuuuu " + << "threadid file:line] msg" << '\n'; + const string& file_header_string = file_header_stream.str(); + + const int header_len = file_header_string.size(); + fwrite(file_header_string.data(), 1, header_len, file_); + file_length_ += header_len; + bytes_since_flush_ += header_len; + } + + // Write to LOG file + if ( !stop_writing ) { + // fwrite() doesn't return an error when the disk is full, for + // messages that are less than 4096 bytes. When the disk is full, + // it returns the message length for messages that are less than + // 4096 bytes. fwrite() returns 4096 for message lengths that are + // greater than 4096, thereby indicating an error. + errno = 0; + fwrite(message, 1, message_len, file_); + if ( FLAGS_stop_logging_if_full_disk && + errno == ENOSPC ) { // disk full, stop writing to disk + stop_writing = true; // until the disk is + return; + } else { + file_length_ += message_len; + bytes_since_flush_ += message_len; + } + } else { + if ( CycleClock_Now() >= next_flush_time_ ) + stop_writing = false; // check to see if disk has free space. + return; // no need to flush + } + + // See important msgs *now*. Also, flush logs at least every 10^6 chars, + // or every "FLAGS_logbufsecs" seconds. + if ( force_flush || + (bytes_since_flush_ >= 1000000) || + (CycleClock_Now() >= next_flush_time_) ) { + FlushUnlocked(); +#ifdef OS_LINUX + if (FLAGS_drop_log_memory) { + if (file_length_ >= logging::kPageSize) { + // don't evict the most recent page + uint32 len = file_length_ & ~(logging::kPageSize - 1); + posix_fadvise(fileno(file_), 0, len, POSIX_FADV_DONTNEED); + } + } +#endif + } +} + +} // namespace + + +// Static log data space to avoid alloc failures in a LOG(FATAL) +// +// Since multiple threads may call LOG(FATAL), and we want to preserve +// the data from the first call, we allocate two sets of space. One +// for exclusive use by the first thread, and one for shared use by +// all other threads. +static Mutex fatal_msg_lock; +static CrashReason crash_reason; +static bool fatal_msg_exclusive = true; +static LogMessage::LogMessageData fatal_msg_data_exclusive; +static LogMessage::LogMessageData fatal_msg_data_shared; + +LogMessage::LogMessageData::LogMessageData() + : stream_(message_text_, LogMessage::kMaxLogMessageLen, 0) { +} + +LogMessage::LogMessage(const char* file, int line, LogSeverity severity, + int ctr, void (LogMessage::*send_method)()) + : allocated_(NULL) { + Init(file, line, severity, send_method); + data_->stream_.set_ctr(ctr); +} + +LogMessage::LogMessage(const char* file, int line, + const CheckOpString& result) + : allocated_(NULL) { + Init(file, line, GLOG_FATAL, &LogMessage::SendToLog); + stream() << "Check failed: " << (*result.str_) << " "; +} + +LogMessage::LogMessage(const char* file, int line) + : allocated_(NULL) { + Init(file, line, GLOG_INFO, &LogMessage::SendToLog); +} + +LogMessage::LogMessage(const char* file, int line, LogSeverity severity) + : allocated_(NULL) { + Init(file, line, severity, &LogMessage::SendToLog); +} + +LogMessage::LogMessage(const char* file, int line, LogSeverity severity, + LogSink* sink, bool also_send_to_log) + : allocated_(NULL) { + Init(file, line, severity, also_send_to_log ? &LogMessage::SendToSinkAndLog : + &LogMessage::SendToSink); + data_->sink_ = sink; // override Init()'s setting to NULL +} + +LogMessage::LogMessage(const char* file, int line, LogSeverity severity, + vector *outvec) + : allocated_(NULL) { + Init(file, line, severity, &LogMessage::SaveOrSendToLog); + data_->outvec_ = outvec; // override Init()'s setting to NULL +} + +LogMessage::LogMessage(const char* file, int line, LogSeverity severity, + string *message) + : allocated_(NULL) { + Init(file, line, severity, &LogMessage::WriteToStringAndLog); + data_->message_ = message; // override Init()'s setting to NULL +} + +void LogMessage::Init(const char* file, + int line, + LogSeverity severity, + void (LogMessage::*send_method)()) { + allocated_ = NULL; + if (severity != GLOG_FATAL || !exit_on_dfatal) { + allocated_ = new LogMessageData(); + data_ = allocated_; + data_->first_fatal_ = false; + } else { + MutexLock l(&fatal_msg_lock); + if (fatal_msg_exclusive) { + fatal_msg_exclusive = false; + data_ = &fatal_msg_data_exclusive; + data_->first_fatal_ = true; + } else { + data_ = &fatal_msg_data_shared; + data_->first_fatal_ = false; + } + } + + stream().fill('0'); + data_->preserved_errno_ = errno; + data_->severity_ = severity; + data_->line_ = line; + data_->send_method_ = send_method; + data_->sink_ = NULL; + data_->outvec_ = NULL; + WallTime now = WallTime_Now(); + data_->timestamp_ = static_cast(now); + localtime_r(&data_->timestamp_, &data_->tm_time_); + int usecs = static_cast((now - data_->timestamp_) * 1000000); + RawLog__SetLastTime(data_->tm_time_, usecs); + + data_->num_chars_to_log_ = 0; + data_->num_chars_to_syslog_ = 0; + data_->basename_ = const_basename(file); + data_->fullname_ = file; + data_->has_been_flushed_ = false; + + // If specified, prepend a prefix to each line. For example: + // I1018 160715 f5d4fbb0 logging.cc:1153] + // (log level, GMT month, date, time, thread_id, file basename, line) + // We exclude the thread_id for the default thread. + if (FLAGS_log_prefix && (line != kNoLogPrefix)) { + stream() << LogSeverityNames[severity][0] + << setw(2) << 1+data_->tm_time_.tm_mon + << setw(2) << data_->tm_time_.tm_mday + << ' ' + << setw(2) << data_->tm_time_.tm_hour << ':' + << setw(2) << data_->tm_time_.tm_min << ':' + << setw(2) << data_->tm_time_.tm_sec << "." + << setw(6) << usecs + << ' ' + << setfill(' ') << setw(5) + << static_cast(GetTID()) << setfill('0') + << ' ' + << data_->basename_ << ':' << data_->line_ << "] "; + } + data_->num_prefix_chars_ = data_->stream_.pcount(); + + if (!FLAGS_log_backtrace_at.empty()) { + char fileline[128]; + snprintf(fileline, sizeof(fileline), "%s:%d", data_->basename_, line); +#ifdef HAVE_STACKTRACE + if (!strcmp(FLAGS_log_backtrace_at.c_str(), fileline)) { + string stacktrace; + DumpStackTraceToString(&stacktrace); + stream() << " (stacktrace:\n" << stacktrace << ") "; + } +#endif + } +} + +LogMessage::~LogMessage() { + Flush(); + delete allocated_; +} + +int LogMessage::preserved_errno() const { + return data_->preserved_errno_; +} + +ostream& LogMessage::stream() { + return data_->stream_; +} + +// Flush buffered message, called by the destructor, or any other function +// that needs to synchronize the log. +void LogMessage::Flush() { + if (data_->has_been_flushed_ || data_->severity_ < FLAGS_minloglevel) + return; + + data_->num_chars_to_log_ = data_->stream_.pcount(); + data_->num_chars_to_syslog_ = + data_->num_chars_to_log_ - data_->num_prefix_chars_; + + // Do we need to add a \n to the end of this message? + bool append_newline = + (data_->message_text_[data_->num_chars_to_log_-1] != '\n'); + char original_final_char = '\0'; + + // If we do need to add a \n, we'll do it by violating the memory of the + // ostrstream buffer. This is quick, and we'll make sure to undo our + // modification before anything else is done with the ostrstream. It + // would be preferable not to do things this way, but it seems to be + // the best way to deal with this. + if (append_newline) { + original_final_char = data_->message_text_[data_->num_chars_to_log_]; + data_->message_text_[data_->num_chars_to_log_++] = '\n'; + } + + // Prevent any subtle race conditions by wrapping a mutex lock around + // the actual logging action per se. + { + MutexLock l(&log_mutex); + (this->*(data_->send_method_))(); + ++num_messages_[static_cast(data_->severity_)]; + } + LogDestination::WaitForSinks(data_); + + if (append_newline) { + // Fix the ostrstream back how it was before we screwed with it. + // It's 99.44% certain that we don't need to worry about doing this. + data_->message_text_[data_->num_chars_to_log_-1] = original_final_char; + } + + // If errno was already set before we enter the logging call, we'll + // set it back to that value when we return from the logging call. + // It happens often that we log an error message after a syscall + // failure, which can potentially set the errno to some other + // values. We would like to preserve the original errno. + if (data_->preserved_errno_ != 0) { + errno = data_->preserved_errno_; + } + + // Note that this message is now safely logged. If we're asked to flush + // again, as a result of destruction, say, we'll do nothing on future calls. + data_->has_been_flushed_ = true; +} + +// Copy of first FATAL log message so that we can print it out again +// after all the stack traces. To preserve legacy behavior, we don't +// use fatal_msg_data_exclusive. +static time_t fatal_time; +static char fatal_message[256]; + +void ReprintFatalMessage() { + if (fatal_message[0]) { + const int n = strlen(fatal_message); + if (!FLAGS_logtostderr) { + // Also write to stderr (don't color to avoid terminal checks) + WriteToStderr(fatal_message, n); + } + LogDestination::LogToAllLogfiles(GLOG_ERROR, fatal_time, fatal_message, n); + } +} + +// L >= log_mutex (callers must hold the log_mutex). +void LogMessage::SendToLog() EXCLUSIVE_LOCKS_REQUIRED(log_mutex) { + static bool already_warned_before_initgoogle = false; + + log_mutex.AssertHeld(); + + RAW_DCHECK(data_->num_chars_to_log_ > 0 && + data_->message_text_[data_->num_chars_to_log_-1] == '\n', ""); + + // Messages of a given severity get logged to lower severity logs, too + + if (!already_warned_before_initgoogle && !IsGoogleLoggingInitialized()) { + const char w[] = "WARNING: Logging before InitGoogleLogging() is " + "written to STDERR\n"; + WriteToStderr(w, strlen(w)); + already_warned_before_initgoogle = true; + } + + // global flag: never log to file if set. Also -- don't log to a + // file if we haven't parsed the command line flags to get the + // program name. + if (FLAGS_logtostderr || !IsGoogleLoggingInitialized()) { + ColoredWriteToStderr(data_->severity_, + data_->message_text_, data_->num_chars_to_log_); + + // this could be protected by a flag if necessary. + LogDestination::LogToSinks(data_->severity_, + data_->fullname_, data_->basename_, + data_->line_, &data_->tm_time_, + data_->message_text_ + data_->num_prefix_chars_, + (data_->num_chars_to_log_ - + data_->num_prefix_chars_ - 1)); + } else { + + // log this message to all log files of severity <= severity_ + LogDestination::LogToAllLogfiles(data_->severity_, data_->timestamp_, + data_->message_text_, + data_->num_chars_to_log_); + + LogDestination::MaybeLogToStderr(data_->severity_, data_->message_text_, + data_->num_chars_to_log_); + LogDestination::MaybeLogToEmail(data_->severity_, data_->message_text_, + data_->num_chars_to_log_); + LogDestination::LogToSinks(data_->severity_, + data_->fullname_, data_->basename_, + data_->line_, &data_->tm_time_, + data_->message_text_ + data_->num_prefix_chars_, + (data_->num_chars_to_log_ + - data_->num_prefix_chars_ - 1)); + // NOTE: -1 removes trailing \n + } + + // If we log a FATAL message, flush all the log destinations, then toss + // a signal for others to catch. We leave the logs in a state that + // someone else can use them (as long as they flush afterwards) + if (data_->severity_ == GLOG_FATAL && exit_on_dfatal) { + if (data_->first_fatal_) { + // Store crash information so that it is accessible from within signal + // handlers that may be invoked later. + RecordCrashReason(&crash_reason); + SetCrashReason(&crash_reason); + + // Store shortened fatal message for other logs and GWQ status + const int copy = min(data_->num_chars_to_log_, + sizeof(fatal_message)-1); + memcpy(fatal_message, data_->message_text_, copy); + fatal_message[copy] = '\0'; + fatal_time = data_->timestamp_; + } + + if (!FLAGS_logtostderr) { + for (int i = 0; i < NUM_SEVERITIES; ++i) { + if ( LogDestination::log_destinations_[i] ) + LogDestination::log_destinations_[i]->logger_->Write(true, 0, "", 0); + } + } + + // release the lock that our caller (directly or indirectly) + // LogMessage::~LogMessage() grabbed so that signal handlers + // can use the logging facility. Alternately, we could add + // an entire unsafe logging interface to bypass locking + // for signal handlers but this seems simpler. + log_mutex.Unlock(); + LogDestination::WaitForSinks(data_); + + const char* message = "*** Check failure stack trace: ***\n"; + if (write(STDERR_FILENO, message, strlen(message)) < 0) { + // Ignore errors. + } + Fail(); + } +} + +void LogMessage::RecordCrashReason( + glog_internal_namespace_::CrashReason* reason) { + reason->filename = fatal_msg_data_exclusive.fullname_; + reason->line_number = fatal_msg_data_exclusive.line_; + reason->message = fatal_msg_data_exclusive.message_text_ + + fatal_msg_data_exclusive.num_prefix_chars_; +#ifdef HAVE_STACKTRACE + // Retrieve the stack trace, omitting the logging frames that got us here. + reason->depth = GetStackTrace(reason->stack, ARRAYSIZE(reason->stack), 4); +#else + reason->depth = 0; +#endif +} + +#ifdef HAVE___ATTRIBUTE__ +# define ATTRIBUTE_NORETURN __attribute__((noreturn)) +#else +# define ATTRIBUTE_NORETURN +#endif + +static void logging_fail() ATTRIBUTE_NORETURN; + +static void logging_fail() { +#if defined(_DEBUG) && defined(_MSC_VER) + // When debugging on windows, avoid the obnoxious dialog and make + // it possible to continue past a LOG(FATAL) in the debugger + __debugbreak(); +#else + abort(); +#endif +} + +typedef void (*logging_fail_func_t)() ATTRIBUTE_NORETURN; + +GOOGLE_GLOG_DLL_DECL +logging_fail_func_t g_logging_fail_func = &logging_fail; + +void InstallFailureFunction(void (*fail_func)()) { + g_logging_fail_func = (logging_fail_func_t)fail_func; +} + +void LogMessage::Fail() { + g_logging_fail_func(); +} + +// L >= log_mutex (callers must hold the log_mutex). +void LogMessage::SendToSink() EXCLUSIVE_LOCKS_REQUIRED(log_mutex) { + if (data_->sink_ != NULL) { + RAW_DCHECK(data_->num_chars_to_log_ > 0 && + data_->message_text_[data_->num_chars_to_log_-1] == '\n', ""); + data_->sink_->send(data_->severity_, data_->fullname_, data_->basename_, + data_->line_, &data_->tm_time_, + data_->message_text_ + data_->num_prefix_chars_, + (data_->num_chars_to_log_ - + data_->num_prefix_chars_ - 1)); + } +} + +// L >= log_mutex (callers must hold the log_mutex). +void LogMessage::SendToSinkAndLog() EXCLUSIVE_LOCKS_REQUIRED(log_mutex) { + SendToSink(); + SendToLog(); +} + +// L >= log_mutex (callers must hold the log_mutex). +void LogMessage::SaveOrSendToLog() EXCLUSIVE_LOCKS_REQUIRED(log_mutex) { + if (data_->outvec_ != NULL) { + RAW_DCHECK(data_->num_chars_to_log_ > 0 && + data_->message_text_[data_->num_chars_to_log_-1] == '\n', ""); + // Omit prefix of message and trailing newline when recording in outvec_. + const char *start = data_->message_text_ + data_->num_prefix_chars_; + int len = data_->num_chars_to_log_ - data_->num_prefix_chars_ - 1; + data_->outvec_->push_back(string(start, len)); + } else { + SendToLog(); + } +} + +void LogMessage::WriteToStringAndLog() EXCLUSIVE_LOCKS_REQUIRED(log_mutex) { + if (data_->message_ != NULL) { + RAW_DCHECK(data_->num_chars_to_log_ > 0 && + data_->message_text_[data_->num_chars_to_log_-1] == '\n', ""); + // Omit prefix of message and trailing newline when writing to message_. + const char *start = data_->message_text_ + data_->num_prefix_chars_; + int len = data_->num_chars_to_log_ - data_->num_prefix_chars_ - 1; + data_->message_->assign(start, len); + } + SendToLog(); +} + +// L >= log_mutex (callers must hold the log_mutex). +void LogMessage::SendToSyslogAndLog() { +#ifdef HAVE_SYSLOG_H + // Before any calls to syslog(), make a single call to openlog() + static bool openlog_already_called = false; + if (!openlog_already_called) { + openlog(glog_internal_namespace_::ProgramInvocationShortName(), + LOG_CONS | LOG_NDELAY | LOG_PID, + LOG_USER); + openlog_already_called = true; + } + + // This array maps Google severity levels to syslog levels + const int SEVERITY_TO_LEVEL[] = { LOG_INFO, LOG_WARNING, LOG_ERR, LOG_EMERG }; + syslog(LOG_USER | SEVERITY_TO_LEVEL[static_cast(data_->severity_)], "%.*s", + int(data_->num_chars_to_syslog_), + data_->message_text_ + data_->num_prefix_chars_); + SendToLog(); +#else + LOG(ERROR) << "No syslog support: message=" << data_->message_text_; +#endif +} + +base::Logger* base::GetLogger(LogSeverity severity) { + MutexLock l(&log_mutex); + return LogDestination::log_destination(severity)->logger_; +} + +void base::SetLogger(LogSeverity severity, base::Logger* logger) { + MutexLock l(&log_mutex); + LogDestination::log_destination(severity)->logger_ = logger; +} + +// L < log_mutex. Acquires and releases mutex_. +int64 LogMessage::num_messages(int severity) { + MutexLock l(&log_mutex); + return num_messages_[severity]; +} + +// Output the COUNTER value. This is only valid if ostream is a +// LogStream. +ostream& operator<<(ostream &os, const PRIVATE_Counter&) { +#ifdef DISABLE_RTTI + LogMessage::LogStream *log = static_cast(&os); +#else + LogMessage::LogStream *log = dynamic_cast(&os); +#endif + CHECK(log && log == log->self()) + << "You must not use COUNTER with non-glog ostream"; + os << log->ctr(); + return os; +} + +ErrnoLogMessage::ErrnoLogMessage(const char* file, int line, + LogSeverity severity, int ctr, + void (LogMessage::*send_method)()) + : LogMessage(file, line, severity, ctr, send_method) { +} + +ErrnoLogMessage::~ErrnoLogMessage() { + // Don't access errno directly because it may have been altered + // while streaming the message. + stream() << ": " << StrError(preserved_errno()) << " [" + << preserved_errno() << "]"; +} + +void FlushLogFiles(LogSeverity min_severity) { + LogDestination::FlushLogFiles(min_severity); +} + +void FlushLogFilesUnsafe(LogSeverity min_severity) { + LogDestination::FlushLogFilesUnsafe(min_severity); +} + +void SetLogDestination(LogSeverity severity, const char* base_filename) { + LogDestination::SetLogDestination(severity, base_filename); +} + +void SetLogSymlink(LogSeverity severity, const char* symlink_basename) { + LogDestination::SetLogSymlink(severity, symlink_basename); +} + +LogSink::~LogSink() { +} + +void LogSink::WaitTillSent() { + // noop default +} + +string LogSink::ToString(LogSeverity severity, const char* file, int line, + const struct ::tm* tm_time, + const char* message, size_t message_len) { + ostringstream stream(string(message, message_len)); + stream.fill('0'); + + // FIXME(jrvb): Updating this to use the correct value for usecs + // requires changing the signature for both this method and + // LogSink::send(). This change needs to be done in a separate CL + // so subclasses of LogSink can be updated at the same time. + int usecs = 0; + + stream << LogSeverityNames[severity][0] + << setw(2) << 1+tm_time->tm_mon + << setw(2) << tm_time->tm_mday + << ' ' + << setw(2) << tm_time->tm_hour << ':' + << setw(2) << tm_time->tm_min << ':' + << setw(2) << tm_time->tm_sec << '.' + << setw(6) << usecs + << ' ' + << setfill(' ') << setw(5) << GetTID() << setfill('0') + << ' ' + << file << ':' << line << "] "; + + stream << string(message, message_len); + return stream.str(); +} + +void AddLogSink(LogSink *destination) { + LogDestination::AddLogSink(destination); +} + +void RemoveLogSink(LogSink *destination) { + LogDestination::RemoveLogSink(destination); +} + +void SetLogFilenameExtension(const char* ext) { + LogDestination::SetLogFilenameExtension(ext); +} + +void SetStderrLogging(LogSeverity min_severity) { + LogDestination::SetStderrLogging(min_severity); +} + +void SetEmailLogging(LogSeverity min_severity, const char* addresses) { + LogDestination::SetEmailLogging(min_severity, addresses); +} + +void LogToStderr() { + LogDestination::LogToStderr(); +} + +namespace base { +namespace internal { + +bool GetExitOnDFatal() { + MutexLock l(&log_mutex); + return exit_on_dfatal; +} + +// Determines whether we exit the program for a LOG(DFATAL) message in +// debug mode. It does this by skipping the call to Fail/FailQuietly. +// This is intended for testing only. +// +// This can have some effects on LOG(FATAL) as well. Failure messages +// are always allocated (rather than sharing a buffer), the crash +// reason is not recorded, the "gwq" status message is not updated, +// and the stack trace is not recorded. The LOG(FATAL) *will* still +// exit the program. Since this function is used only in testing, +// these differences are acceptable. +void SetExitOnDFatal(bool value) { + MutexLock l(&log_mutex); + exit_on_dfatal = value; +} + +} // namespace internal +} // namespace base + +// use_logging controls whether the logging functions LOG/VLOG are used +// to log errors. It should be set to false when the caller holds the +// log_mutex. +static bool SendEmailInternal(const char*dest, const char *subject, + const char*body, bool use_logging) { + if (dest && *dest) { + if ( use_logging ) { + VLOG(1) << "Trying to send TITLE:" << subject + << " BODY:" << body << " to " << dest; + } else { + fprintf(stderr, "Trying to send TITLE: %s BODY: %s to %s\n", + subject, body, dest); + } + + string cmd = + FLAGS_logmailer + " -s\"" + subject + "\" " + dest; + FILE* pipe = popen(cmd.c_str(), "w"); + if (pipe != NULL) { + // Add the body if we have one + if (body) + fwrite(body, sizeof(char), strlen(body), pipe); + bool ok = pclose(pipe) != -1; + if ( !ok ) { + if ( use_logging ) { + LOG(ERROR) << "Problems sending mail to " << dest << ": " + << StrError(errno); + } else { + fprintf(stderr, "Problems sending mail to %s: %s\n", + dest, StrError(errno).c_str()); + } + } + return ok; + } else { + if ( use_logging ) { + LOG(ERROR) << "Unable to send mail to " << dest; + } else { + fprintf(stderr, "Unable to send mail to %s\n", dest); + } + } + } + return false; +} + +bool SendEmail(const char*dest, const char *subject, const char*body){ + return SendEmailInternal(dest, subject, body, true); +} + +static void GetTempDirectories(vector* list) { + list->clear(); +#ifdef OS_WINDOWS + // On windows we'll try to find a directory in this order: + // C:/Documents & Settings/whomever/TEMP (or whatever GetTempPath() is) + // C:/TMP/ + // C:/TEMP/ + // C:/WINDOWS/ or C:/WINNT/ + // . + char tmp[MAX_PATH]; + if (GetTempPathA(MAX_PATH, tmp)) + list->push_back(tmp); + list->push_back("C:\\tmp\\"); + list->push_back("C:\\temp\\"); +#else + // Directories, in order of preference. If we find a dir that + // exists, we stop adding other less-preferred dirs + const char * candidates[] = { + // Non-null only during unittest/regtest + getenv("TEST_TMPDIR"), + + // Explicitly-supplied temp dirs + getenv("TMPDIR"), getenv("TMP"), + + // If all else fails + "/tmp", + }; + + for (size_t i = 0; i < ARRAYSIZE(candidates); i++) { + const char *d = candidates[i]; + if (!d) continue; // Empty env var + + // Make sure we don't surprise anyone who's expecting a '/' + string dstr = d; + if (dstr[dstr.size() - 1] != '/') { + dstr += "/"; + } + list->push_back(dstr); + + struct stat statbuf; + if (!stat(d, &statbuf) && S_ISDIR(statbuf.st_mode)) { + // We found a dir that exists - we're done. + return; + } + } + +#endif +} + +static vector* logging_directories_list; + +const vector& GetLoggingDirectories() { + // Not strictly thread-safe but we're called early in InitGoogle(). + if (logging_directories_list == NULL) { + logging_directories_list = new vector; + + if ( !FLAGS_log_dir.empty() ) { + // A dir was specified, we should use it + logging_directories_list->push_back(FLAGS_log_dir.c_str()); + } else { + GetTempDirectories(logging_directories_list); +#ifdef OS_WINDOWS + char tmp[MAX_PATH]; + if (GetWindowsDirectoryA(tmp, MAX_PATH)) + logging_directories_list->push_back(tmp); + logging_directories_list->push_back(".\\"); +#else + logging_directories_list->push_back("./"); +#endif + } + } + return *logging_directories_list; +} + +void TestOnly_ClearLoggingDirectoriesList() { + fprintf(stderr, "TestOnly_ClearLoggingDirectoriesList should only be " + "called from test code.\n"); + delete logging_directories_list; + logging_directories_list = NULL; +} + +void GetExistingTempDirectories(vector* list) { + GetTempDirectories(list); + vector::iterator i_dir = list->begin(); + while( i_dir != list->end() ) { + // zero arg to access means test for existence; no constant + // defined on windows + if ( access(i_dir->c_str(), 0) ) { + i_dir = list->erase(i_dir); + } else { + ++i_dir; + } + } +} + +void TruncateLogFile(const char *path, int64 limit, int64 keep) { +#ifdef HAVE_UNISTD_H + struct stat statbuf; + const int kCopyBlockSize = 8 << 10; + char copybuf[kCopyBlockSize]; + int64 read_offset, write_offset; + // Don't follow symlinks unless they're our own fd symlinks in /proc + int flags = O_RDWR; + // TODO(hamaji): Support other environments. +#ifdef OS_LINUX + const char *procfd_prefix = "/proc/self/fd/"; + if (strncmp(procfd_prefix, path, strlen(procfd_prefix))) flags |= O_NOFOLLOW; +#endif + + int fd = open(path, flags); + if (fd == -1) { + if (errno == EFBIG) { + // The log file in question has got too big for us to open. The + // real fix for this would be to compile logging.cc (or probably + // all of base/...) with -D_FILE_OFFSET_BITS=64 but that's + // rather scary. + // Instead just truncate the file to something we can manage + if (truncate(path, 0) == -1) { + PLOG(ERROR) << "Unable to truncate " << path; + } else { + LOG(ERROR) << "Truncated " << path << " due to EFBIG error"; + } + } else { + PLOG(ERROR) << "Unable to open " << path; + } + return; + } + + if (fstat(fd, &statbuf) == -1) { + PLOG(ERROR) << "Unable to fstat()"; + goto out_close_fd; + } + + // See if the path refers to a regular file bigger than the + // specified limit + if (!S_ISREG(statbuf.st_mode)) goto out_close_fd; + if (statbuf.st_size <= limit) goto out_close_fd; + if (statbuf.st_size <= keep) goto out_close_fd; + + // This log file is too large - we need to truncate it + LOG(INFO) << "Truncating " << path << " to " << keep << " bytes"; + + // Copy the last "keep" bytes of the file to the beginning of the file + read_offset = statbuf.st_size - keep; + write_offset = 0; + int bytesin, bytesout; + while ((bytesin = pread(fd, copybuf, sizeof(copybuf), read_offset)) > 0) { + bytesout = pwrite(fd, copybuf, bytesin, write_offset); + if (bytesout == -1) { + PLOG(ERROR) << "Unable to write to " << path; + break; + } else if (bytesout != bytesin) { + LOG(ERROR) << "Expected to write " << bytesin << ", wrote " << bytesout; + } + read_offset += bytesin; + write_offset += bytesout; + } + if (bytesin == -1) PLOG(ERROR) << "Unable to read from " << path; + + // Truncate the remainder of the file. If someone else writes to the + // end of the file after our last read() above, we lose their latest + // data. Too bad ... + if (ftruncate(fd, write_offset) == -1) { + PLOG(ERROR) << "Unable to truncate " << path; + } + + out_close_fd: + close(fd); +#else + LOG(ERROR) << "No log truncation support."; +#endif +} + +void TruncateStdoutStderr() { +#ifdef HAVE_UNISTD_H + int64 limit = MaxLogSize() << 20; + int64 keep = 1 << 20; + TruncateLogFile("/proc/self/fd/1", limit, keep); + TruncateLogFile("/proc/self/fd/2", limit, keep); +#else + LOG(ERROR) << "No log truncation support."; +#endif +} + + +// Helper functions for string comparisons. +#define DEFINE_CHECK_STROP_IMPL(name, func, expected) \ + string* Check##func##expected##Impl(const char* s1, const char* s2, \ + const char* names) { \ + bool equal = s1 == s2 || (s1 && s2 && !func(s1, s2)); \ + if (equal == expected) return NULL; \ + else { \ + ostringstream ss; \ + if (!s1) s1 = ""; \ + if (!s2) s2 = ""; \ + ss << #name " failed: " << names << " (" << s1 << " vs. " << s2 << ")"; \ + return new string(ss.str()); \ + } \ + } +DEFINE_CHECK_STROP_IMPL(CHECK_STREQ, strcmp, true) +DEFINE_CHECK_STROP_IMPL(CHECK_STRNE, strcmp, false) +DEFINE_CHECK_STROP_IMPL(CHECK_STRCASEEQ, strcasecmp, true) +DEFINE_CHECK_STROP_IMPL(CHECK_STRCASENE, strcasecmp, false) +#undef DEFINE_CHECK_STROP_IMPL + +int posix_strerror_r(int err, char *buf, size_t len) { + // Sanity check input parameters + if (buf == NULL || len <= 0) { + errno = EINVAL; + return -1; + } + + // Reset buf and errno, and try calling whatever version of strerror_r() + // is implemented by glibc + buf[0] = '\000'; + int old_errno = errno; + errno = 0; + char *rc = reinterpret_cast(strerror_r(err, buf, len)); + + // Both versions set errno on failure + if (errno) { + // Should already be there, but better safe than sorry + buf[0] = '\000'; + return -1; + } + errno = old_errno; + + // POSIX is vague about whether the string will be terminated, although + // is indirectly implies that typically ERANGE will be returned, instead + // of truncating the string. This is different from the GNU implementation. + // We play it safe by always terminating the string explicitly. + buf[len-1] = '\000'; + + // If the function succeeded, we can use its exit code to determine the + // semantics implemented by glibc + if (!rc) { + return 0; + } else { + // GNU semantics detected + if (rc == buf) { + return 0; + } else { + buf[0] = '\000'; +#if defined(OS_MACOSX) || defined(OS_FREEBSD) || defined(OS_OPENBSD) + if (reinterpret_cast(rc) < sys_nerr) { + // This means an error on MacOSX or FreeBSD. + return -1; + } +#endif + strncat(buf, rc, len-1); + return 0; + } + } +} + +string StrError(int err) { + char buf[100]; + int rc = posix_strerror_r(err, buf, sizeof(buf)); + if ((rc < 0) || (buf[0] == '\000')) { + snprintf(buf, sizeof(buf), "Error number %d", err); + } + return buf; +} + +LogMessageFatal::LogMessageFatal(const char* file, int line) : + LogMessage(file, line, GLOG_FATAL) {} + +LogMessageFatal::LogMessageFatal(const char* file, int line, + const CheckOpString& result) : + LogMessage(file, line, result) {} + +LogMessageFatal::~LogMessageFatal() { + Flush(); + LogMessage::Fail(); +} + +namespace base { + +CheckOpMessageBuilder::CheckOpMessageBuilder(const char *exprtext) + : stream_(new ostringstream) { + *stream_ << exprtext << " ("; +} + +CheckOpMessageBuilder::~CheckOpMessageBuilder() { + delete stream_; +} + +ostream* CheckOpMessageBuilder::ForVar2() { + *stream_ << " vs. "; + return stream_; +} + +string* CheckOpMessageBuilder::NewString() { + *stream_ << ")"; + return new string(stream_->str()); +} + +} // namespace base + +template <> +void MakeCheckOpValueString(std::ostream* os, const char& v) { + if (v >= 32 && v <= 126) { + (*os) << "'" << v << "'"; + } else { + (*os) << "char value " << (short)v; + } +} + +template <> +void MakeCheckOpValueString(std::ostream* os, const signed char& v) { + if (v >= 32 && v <= 126) { + (*os) << "'" << v << "'"; + } else { + (*os) << "signed char value " << (short)v; + } +} + +template <> +void MakeCheckOpValueString(std::ostream* os, const unsigned char& v) { + if (v >= 32 && v <= 126) { + (*os) << "'" << v << "'"; + } else { + (*os) << "unsigned char value " << (unsigned short)v; + } +} + +void InitGoogleLogging(const char* argv0) { + glog_internal_namespace_::InitGoogleLoggingUtilities(argv0); +} + +void ShutdownGoogleLogging() { + glog_internal_namespace_::ShutdownGoogleLoggingUtilities(); + LogDestination::DeleteLogDestinations(); + delete logging_directories_list; + logging_directories_list = NULL; +} + +_END_GOOGLE_NAMESPACE_ diff --git a/build.gradle b/build.gradle new file mode 100644 index 000000000..6a444bec6 --- /dev/null +++ b/build.gradle @@ -0,0 +1,68 @@ +/* + * This file was generated by the Gradle 'init' task. + * + * This is a general purpose Gradle build. + * Learn how to create Gradle builds at https://guides.gradle.org/creating-new-gradle-builds/ + */ + +buildscript { + repositories { + jcenter() + google() + } + dependencies { + classpath 'com.android.tools.build:gradle:3.1.2' + classpath "com.jfrog.bintray.gradle:gradle-bintray-plugin:${GRADLE_BINTRAY_PLUGIN_VERSION}" + classpath "com.github.dcendents:android-maven-gradle-plugin:${ANDROID_MAVEN_GRADLE_PLUGIN_VERSION}" + classpath "com.github.ben-manes:gradle-versions-plugin:${GRADLE_VERSIONS_PLUGIN_VERSION}" + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:${KOTLIN_VERSION}" + classpath 'de.undercouch:gradle-download-task:3.1.2' + + // NOTE: Do not place your application dependencies here; they belong + // in the individual module build.gradle files + } +} + +subprojects { + repositories { + jcenter() + google() + } +} + +ext { + minSdkVersion = 15 + targetSdkVersion = 25 + compileSdkVersion = 26 + buildToolsVersion = '27.0.3' + sourceCompatibilityVersion = JavaVersion.VERSION_1_7 + targetCompatibilityVersion = JavaVersion.VERSION_1_7 +} + +ext.deps = [ + // Android support + supportAnnotations : 'com.android.support:support-annotations:27.0.2', + supportAppCompat : 'com.android.support:appcompat-v7:26.1.0', + supportCoreUi : 'com.android.support:support-core-ui:26.1.0', + supportRecyclerView: 'com.android.support:recyclerview-v7:26.1.0', + supportEspresso : 'com.android.support.test.espresso:espresso-core:2.2.2', + supportEspressoIntents : 'com.android.support.test.espresso:espresso-intents:2.2.2', + supportTestRunner : 'com.android.support.test:runner:1.0.1', + // Arch + archPaging : 'android.arch.paging:runtime:1.0.0-alpha3', + // First-party + soloader : 'com.facebook.soloader:soloader:0.4.1', + screenshot : 'com.facebook.testing.screenshot:core:0.5.0', + // Annotations + jsr305 : 'com.google.code.findbugs:jsr305:3.0.1', + inferAnnotations : 'com.facebook.infer.annotation:infer-annotation:0.11.2', + lithoAnnotations : 'com.facebook.litho:litho-annotations:0.15.0', + // Debugging and testing + guava : 'com.google.guava:guava:20.0', + robolectric : 'org.robolectric:robolectric:3.0', + junit : 'junit:junit:4.12', + guava : 'com.google.guava:guava:20.0', + stetho : 'com.facebook.stetho:stetho:1.5.0', + okhttp3 : 'com.squareup.okhttp3:okhttp:3.10.0' + +] diff --git a/docs/assets/initial.png b/docs/assets/initial.png new file mode 100644 index 0000000000000000000000000000000000000000..f8a2bf9a574a8d38f27f4e944d44e0137766382a GIT binary patch literal 210671 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 XckPm}$P|e02f5MH)z4*}Q$iB}ohayY literal 0 HcmV?d00001 diff --git a/docs/assets/layout.png b/docs/assets/layout.png new file mode 100644 index 0000000000000000000000000000000000000000..6ba7a37a1d8e5a7981a8112e305136ea7f5b0411 GIT binary patch literal 536975 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

tK&#X!A@MK`>n2q0!;EiOfN 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 NtRd$u%FW$l{|^C$gp>dP literal 0 HcmV?d00001 diff --git a/docs/assets/logs.png b/docs/assets/logs.png new file mode 100644 index 0000000000000000000000000000000000000000..38edd03adf2e5830491f6d7855dfb86c75bccb56 GIT binary patch literal 305272 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Ⓢ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

OF6Kk|W;{-8CvVXC4xAt3?6(^p1l>}bv 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

V`5exv%`tGoSF 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⪚tB^!-Oad4MS9NYDkyld7)IoA1KE?y!LlnIj!5 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%0AV#@i{ZdGZ`xK?5sVe1$VU5 z>bJKTD%k!@*Uc>TzZx`WW(TpptKMmf_d8$9kF+eIoSp}Wt;S0Ve$KzqAce)t{h}ZE z*i!e$hK$>tjwGM;{+U+77e%?!iRQ(Lqng zygI@abE5g751z8$`B2Ell0H3k&8aTQFCqT?kT(wa)6%PM3SxDg&>k~Ck8m#jQD&ky z7rXJ6-j_P;wH3YEq1G zociLqJO%}aBVqTBrj?WMBzh4O;wq5kVU_?;kenLaTYd|AIcpO>^JedGLv7e1ETAGYX|P0LOL4Y8Lq`56Uma7LZA&!> zG#Mi+Y6nRB2SGk2b0H`lesk;6*cNYSc_{i6$DlWg4p9-(Q^aUwc#kffi2^EEsew;j zRtO&2DWenM>wBQ6U@Y&Ek6is=85brz-E+sPb-_&Y>p9XD+Vd<(W7VChs&e$W2D>ct zuf1Z`lSBB;-gd_7JA@9)Mh*BP{7cf%=wL(nt<^{}^%Ntdqdc6#5Jb7+ zUj1Yrjkz)(x@Uyv)<{~hu!aU&Z{`HOo=US6MEBs-yil5jzEqiKFS>hVz2Fih;ew^wiNK^G=K-un9Q?P&+gU`K)7El{GLiy zn6>htiowlzD)eMZEPDabvdi8Th}sQeP!FWKQBc$4t7puen-qxJldhs%25q|z0`!U# zC9sHR=Z(Q!VnD>potXH7kUqrEovP?5@T`H%t<%~AN}Zyv-Mtv~hD7f+6z9=h?`A!f zv#o%3$niQk!Z~~J*9$K^=2?sXW2kwpj~27fpeRbtPMene`6^K6>uAD_NkxqeW@3BE zXa1pRt`sEnt!!q|#8eULo zCxuD+`}2~Z*VVC;Ow-mv398pS2gRsF?>s4^kwC3_QvP$lqHI+&E!lJZAgjb>MJQX~ zs#pSnn>iRCu1CgRR!T|+9A`62o50sp{hIsr^wI(nlmG1VwdI9AP*1#12ngrvuFZkR z>)ZMpY}q26NXzRd__OmtJgNJwjEwgEBf_^jeMGOG3_fX0_Uc%oj5-Q+=zL(X7JD!} zPk)Zf)iJ6Rc7MN|N-CHtDGanTzU+e!t~dGU(3jx4cR zp^K4uOD<{winlsZyT5zEbLOx{vP^!5&46TNa8JEOWvkByok~Ip@8lHgt1k>xb)K%%r>#!srgLsifI$D`*lW4D};dMYODD%F<2 zpRnc6H>nl1uMM~nq#&$uL-Yd+Bz3ek-cXj43~ElE|3;5^X$(G`EG|5}TxJhp-Ydc* zd_ljh6Evlr1@8+Tts#YAhtW+V)6n7S8pUs1Wa)+SkiU>bzTCL{E4OCm@Qkg(ppzOK zV5`N-2Ij`QTcz!T=jBLB3DXYO(KFW!@X1A?ONDBg1{A)QdIP+|cq3^z4tw9i*$Uk^ zC0Zjr&*ZfIMvBs)znTg*tlz^yuMw&~G#T+!r|Og1+V-8*yNXV*K6*JLZ5of)BZ~_T zO!@j$tb3mQIjTf$SDj#M>gey60z{8Kc}QhrdmeU88CjuU$R#yoWx(~rFHlv>ecXq+ z!sAm88$_UneFM8lM;DaUi90G!=juayg@nF}Be}M^c~r0vo^>X{5!hx!4Dw5tJ@*!$ zukzJ%Z9-2LTdg(`yv;5aByampGpo0OEO6jxwW;NhcBSs&AwF!4(kl3?IY2Y3M``H# zfTdpDm{b)e#>7K2fgf5vz9I>nzcKqINuKg0*%I8mAJorjvyt`CcW(XXSm8lD*eJDb z;Fk@8yw_#>_A_Y`dzmfmW6asp#Pk4yo{= z8cEucwCEQ9?Ls3WHN1OD>vDuYdMy~8wJY>T0Oc~cj(HqJo?(Hz^u4&bHKEUMXDM@HI!0~@;|Vy&9e)xrG!GlUdm62DBm zwntru&`uvHwAwe9DboRX`l3HDwnOCDw!&)9(Ny}DR%q9L%rAb)I;CRYxrH&wUEK|j z;e)e&Tvv3bFV!Y_<+MwwAkq{mqm!zDlk8;p>;Od!j%0`w&r3CIBX;ZCxRX^@Lgp9N zRC0D_JMl-s%lyvzgqy(vCI0=}5F(J^XS)H#&*TIoEXbf8*WQr9bFePClH&BoOeTPH_g=VG(01Yb(w5?g?7#N7xBlnu9%XiKe+qB+w`}Wip_eP zMKBtp-lJQ)ft91Iu6506`ry$9M%>^XhpO`{*ayX~kH%9|wB)pVMGZd|2$vxoJpE}H zEFW#&uR?(>dr`Z5MU6FXhXyVvw!QIyW$}tWMZKoO3blxk)_~%uxxHvmV7Jkgt;oC< zJ@}uQ2y3~$J_)YlJS#(d-&=*W{e4Q^J%dhC@^A$Y@XA#}B0Pw8bh$z4m66Yh*2;61oGhU~M zxVDE#X`r``f(aY(a|DjqLtiNdJ+rSz0Y3hbr>D3LgoHcHh^`mW^ka)CV0Ee@hD9tK zpA;IM9uC8z@rrjl3{bmsFD<_7o)8ymYoC}F*Onh)=LSy<6bbonV`~h~Nc+72_zYN? zZkwGz5alF=wDh`Xq_$XRkHvr-{N2d7q2a((Ppg_)2ok=A1>ailE#=q<#`p=4j)wG_ zPOb>dc~ZfjjtBj%excL%6g-&zc5{5p*2eqdQ90&&&`e`Yo8*IcLM2_OjrLYZcEnqbUr^^Sa!1T4jzaAsD2DiHOn_V`p{-HI%m>}{T6RqCsJ%x*{a zZGBNS8EJng@H!h@ud6p@qayr(vk7y?pF;moXSl?Yv;XJi5lejb4ujZH%IxYu+ zHGgF?F9zZUg$(6bOBLba-LIPUnzo>NZ&ozLnnRmLmqG_($!tq0DQ_^i79Zp!;-`(C zvFj57pxN}VQ2}7e@`4AONwA+sAf6gE#7!UH>36bJTu_OH|8%W?VvkyY0;szX>Um_A zHX-Bm-DV0Z$1-qUf9t2v0;K_-9T7E6@ZrU3UPn(P?V~*y=AQ(1VXx1DXC(Y&w%T^9 zE!O@lsSPVu+%)WkH5?=K7Z1d84R|sqHPh%%Xid=^v8F-B4qf_O$c=i&R>AoY+cLVC zw(M2>Nn`puIHN7(Nx2e#DzKn;kreMQjwLY&xYi|fn_nk|j`|la39JfZGfX=ZHR;U?EE? z%gv}mNg2$DdKLTQdLdXsA~){afbHin~^l^fhi2U(WW9!(z6`Kv++g@&@q-q*6aPM6JG?-njtAxF;Up?7*7x*ts! zRPJt**3ON~+r?IAdgH--G)xk;eE>eH38Oc#AlvvR z=lacCsY}F(xDTU400#3iFaR0|a+~zB{aIG?ONZ{Ag*&^zZe=>WT-vY*LGel;XuFzd zc@>Lv0_v1Iq|!VvqTb(im9p=XAye5GT-gP&g)Z5{O_DTOxOiZF&VB+I>OG9Q9 z^S=EaETvECD5joClUsE@cw6u&-!DDjtBM_q#b0P^7k14V>8S3=);1 z-%I%VN0krXF!L(cez7%3CrBv8OZwrZlu*rwAM5G`N?IiEukV-^HT*F5iL!9$`Mrf` ziRgaPWsvh7S$(l28br6s=HFKyLptOJg~4}~1i5le2WJ%N%8;DIy2YCD)Ff!W#cM}m zAP}C!O!k5&Q_On4EL$P-n$w$NYKru1dMA;{>jV#}KLJ%V< zBe^ZW0mHpsW(DUqa|0V11BzWN4nZiP- zqrf~aESbC1?zZ6E7bWQ2wBEwyF7DZ5#O}D0p6srQ$lA+OG(wqt3Nt-1_Y68dyfbj* z(8#YE9MXboCWhAty;T{&g>2B(oq{)wOe1hT-d5b>sV=Dns9pC~cdlg%_|xhF--CJ6 zv-4z6C3GNe?jgEj$g+{!&+{PEJn?S>(QBNMa@^Pyz(Ywobpm&3eBmXFov{HEp>wXF z#L3#C7%HpT-)Zzx7IJV=6zi9`Bhm!0a2%TPubFX);E&qLC{^9txnB6Y>ckW{E=oC? zQ(9fMHT}r^;B5X+W-jd~q%-a>Es7`8#B2bM^r^e9S=p^*zrthE9p|lgnX=Ertc%I& z3wIAK5UUDUW&uF6F*>jrH>o%4h-`9F*$5zCX$V+P4>W~N)e=BYqUb_pJY_yK-c#E{ zS+O+_<&@(@>Kd5Ar=em4+H`0#XrlQ_2ww=;M@|bUuSNBZk$Lmx)AV|GdFVih1#yN= zsc)(u7|*P&Fay3+-_GeXJ~}YOo#+tiI|pL)mp5CnP`@0W{pwJAb5M-180<5-{YLD~ z$=5#Bhw_}kB~}Y&+oR&qs(bwW6LAyAVlu3iEQDgj_;%-!S>sSfJ+~3wuaCi0dt}1! z^RgEmvNtfqSMEzXI!cB6mP1}xT&tI@&)?1kh%T;sovqa~b~rN7on zP^ps6IDBLx?5YU1%GP<~wdA^d*Q=P9m>95k(8iv&))jdV(%jy*>0VZn;517Hgn%VP zyt{QtNR%s>^JYJFFEZciXkB$ayzh8XGwWWfG-*eQ7pPEp z$T{wM74fL9F8eFlYH^~lgmPITlL~&;czkqqz}1BKi|r@(>7jW=U}LGJP$stST}G$- zeDky9DzGblR&}+De?8M$4R#iI>Q1F@y6}1U`=@1?He2a*#dhFEOr#6iS59-#iqF20 zzsEDAU;c_o+VhBovxTjq@os&G^U5#?)pL~tKbf@d+n^N_4ZXMYH((@&rUS5>dp)LZ zy0`zv#*+Ze|6)ir-wkQ>qZ@|yPX+FVXd}wg%yW)*?HkA6>#6qlII3>dH_yhC-tVP6 z6m|0KyGBQk5*4F5lBf874>AooNSOM-sv!mNyUEl4dy-JGK%7=hx`DX)!e=)KlU8Rh zMm>|yHV)tpbjzol_h=qksYQ|2%`7>7zy0JOlJ@Ay&a96N76ydYFC}eYrb*}^!Z&m% zM)I1b5419dP?2?@xX6Vyr4n1%bj9|yuGCv|@PPHy=(sl!M{<2bGJFP~^|pg{F!>|m zqbJXYmgw^6MR55hHmGD>UMIOEBN@qB7UzT4`1+?2kESVd6PY038$NL*6&$H&JU~cE z{0sn4aU3MV4y!TMNLIjHoMr+_%9!FUC^evDU^oum|9#A)`AK7DLZ#;B} zQ4HK9)d^43#ZD^)AGO$U%NXv)3E=aROVXDq zbQ7x09|Tdll)!AM=E^&~JZKUj=}H+=o)j~+qJ5nmeIs{|>g*IpESg$_^uV)6aFc$P zn8(@VyfoG8M0!R4iIg#9aVHzg2(*^Cq;tBmpo7pfe*M5jlkP0%SiJ|R5=!h~g| zoW=@>r)In`{suPC7GJ_=8c5u5*_{pI<45mk!s3?O{(!R{V=wi(j#eB_F{4tt+8EUB zJR^a}_lliX-dSx6nc~TP9!j4tw~J77hCYpO8g=D4#C!j-_pS)(Nf})KrM_f~i)2Sj z5u>egs3g~of6+9+7XL1o;=~QO@0`)FcGraeDLws4l!NRek8$}xJHLx&&w~X6;+_Eh z(~pCMk^I62WN~YAe>EQZ4iEc5i~f`yz};I&rVZ)od2hMUf`?)sOPnxS8p zQjI>2f{!ya0QNIH|CB|O^_nMG`XT(lH0!Aqd*ok$z(RavbVYB57oYnZUXs8-wRp7D zg@5vg8S^>q40#wKK&h@G^d`(-tj?OdW-=O1F0vvq1Bu(+jGpOIR18b)lYgF}Q65!1 zGFhJI!JdLL&fN$+-&i0L(MBI95L4MZLxnUMyeq-G_C^_y%=GyOS}02@yKtM=QU7}W z!rp$LC~%2%`a&=i(_07zzA%O&G#mQ;yB^TXoqf47D;U#bJgxE0=^KB0|8*)EVp9s( z=Y)2Wd42VdF!^5^E-?oT%~JVy!P~7_0_9Km0dGZ2sKlpnPyO%Q4p#@pYNyx<142n7 ze@HwxxPx~_n(0;l4HSI6M+GDUK~yj+Nkx#|JcBUTanP%yNMgnf8`n6(-eBW7&FlYb3H8eIC!A)qP^G~xKE*N zd?{^*xo!CB@pl%>4F{x%&NB^dY;f|mKI2R`O01U_yA2b_fwM^R8uolB_fdLeAnc?L z9sJ?5(>u^5KO7rpkqZd6N$OuG#Z14>k7b>vav>Q0iFcQ3ObyJ$c9R;ajyP|9Q~e<= zO-T?n3N&$nipqWThalkZbed6jM50C)KoF_#go35=kCL!_)W}^}YJ}namX{y-G6Yic zBDc?)Z(moN`V4g*R-g4f1oD=@m3T6y+{$(!yQ6S1UF%OPM8vQv=OM;jE6D+nZ? zm8Ea#75Lou2hR63BG!ic$31tBI1{# z=oxqess0*TEAwJWAW-w;$FN&B{`b;pULDtPWgz*CdAG48G^x4xV;ev5+B6bJI##K{L{@FpdhMnz%8ggY*5y`&T_oO^x1~bWoV44RdVhYeJmAD{ofQO<$}K|?S*Z0@Q%Fv%887Uy!z~EQPQWOFYhexI*?0f zQW{7vd}5Z*gv{tlKaY89?YWgch&O!U)N}8+#Ka<%W9{oidfmt(DjVQLbBgW+O%9ZZE-uD zSx+TE$BhpInRcy-i;q67?7Px!n_1o1thzq8+8{r+j?v_pWvYkiKDnQm8}jbm3v=;? z2HJ@C7^Rn=W7O|K3QWwu^a{9|Mow2qXhhNegAM=QZRe8(=gi+eu~`_Vbuu9-a9_(a@!`wkQAz_Y*Q3_>F85ms?A+9*7TCxjE3jK_6z?YdVPF}Q&|T=suSCQJOp>y2Sm;Qk@VsK`^`jydzjO* zpN>vmb4dB^v|29{F0lvn9P~;1tz~HSq;kGKSrm)#sJy1m`FOLO$mz+FTrLPE=JIPX znXDLklYdRZNUifc1zZ*PHD9UYf}gw<(8YbQcerSp^In5P(j!s$f%TZ9!gJMX^pq4e zsKdJKv>(0hOSuw2y1BWfwCEi`X|!@b#IA%FV*d=|Gb}}Sv6nnbG?{Jj8si_BXMzt} z2Q2?X9k3}gNAG#@wEy0*ybCKEBnAL5F*bjvlW140sy8XsQJv`OGl~pEmbX0%QxDq_K%DR8}Mq9FrhL& zFOL%C23#PwqedOT{~%!nzCia>j$6i|$P=IVC$HfOLy@)sTYnRn>R0iFQU}7lr(FKC6eaQ`Pg#;sO)X zeor~7j{U!Mz?r!c;uIn1Y!s$`7%=5+{?6h@bwPuJqgVQ`d*+tr>?)d>>yK6q9Ayop zC|L$DN+NG<@vwTX=t9;x}R&1 zKtSx%zEmPC#G9tl)_%5P69+oiLxdC0wG~|S-cqKT1Y37X-d=&06fsUFIgl%9ZYC_c ziaNb}`L6nVLAhOpiJAFi3SWMVdak;q1|mD_pW;7qp^8q*Iu4x9n7>mD=$T1$Nc+-K z)7WsXyWz^)*4+?2RO1Y^uF?VSM~WdJm~qs0p+`S3PcljGC%d%`q#?|1VF zKHvl3)JAWyUf2H@O~J5e(CzP?Yjx_>vGE&y%!XWKy=bgGYW@C8ub?ZB1;m4^Z|3k( z11P5sa9I8pkW+RqV$F_gu*=>!FE=c)wq3-FWzf%T%)wJEj%D7yn+I}>4e~wpuF^HC zx^U&=^MAzudhS{mK#immWhbWh3HFs-g^wUZ^fJMA;8C$IlM zb$xj})Z70*LMbgq5>YXR${4bhB@|+e{kB+UM7Ab7AxqXQ#U*6MB}=v_AvFV)jJWhTZ48ot=mUCk9IS%Z?loYBxiw6elxVP($nGsC zcR(Jiiacy+?B^?wuCj_mN|US3XNk~dmX33lCXAN3Z5RG!vH0LHTO+HJ{opG#w_)zY zU+QD&7Tc6Q6@`BXfE75 z*L3lg62;Wu+}W?kgWFbph@MTyADlit2;!BR7p8DM+(ZhKHui( zZjtLCe>%aw>r(CkxtNI$SA_PRdBg~4P zA{(g*0@~ewD(A>ucw&g?YG&eGUxho>l#OIe`e(A-$+UaJOWS2YZ!T$4o8yT36@;alhVV5q)o*DN$LJ? zrg`?d6A)&pR5XH|#jr~n&!NV*%LSY1$Y?ku}l zpi;PuJ8+B%rQ_Hut5|W*@8(sZ7Y}Lcegh!DNQ1^<)+Ub76$?S>#)v61%j~bkgkK$4 zz=uMaVdw{1Y)O$#hif$0@Xz&lw=C{->mfz4BE1@kMGihVcHE$RU%nT#D2qMZD%1*8 z+v$KRq=vDj+H_1z@t@}Afm#dZdZO&E#grcj7Wt1nQ_Z{khk!uAzDx<&c%Dc*O!iGl zt2Lc3=*$qb#z;h5iBldJ9)4@l{E)0v9G@97H@1C6n5!4U@d`Z~{~0nblaK*AeB9u5 z15fQgbfnw1k)(;SPS;>I2Xw=)rSz6HUd2P^ zU9ekID#yfCDL*Zer8U_Pfit*V0mCi0a8*Xb004LIr~qx6jws8|)@3ZeG{1MpQuke` z9kO()%Kz`S3XESWF@H(oCY8)LVf;I_#ZZ&D?j64b1M=0vHSKR+kjwW6Xi+=MJHCT_ zXGO()N4iy0O9&;-xx-#_GWD(%Yvpg(N*Gx>=)9@5dR2~+3! z-rxnK7P5MGR$pYlkuQv%Y6ma=9AaHt*ZIAa6s&T6NUxK?dF&QkIxybKCEfD~k+G!(!fp5^!_hN;nNReFqYTblfp^Fm-JMHYQV+1yF%T;sqh$}}jY{kVbY0UP~ zTiM1_)tCgzk57D*@a0LxH@ILfVq}?;w&<0NFSdh%aZeg~;iL9epZN;^GC_vkk7vc% zT=pBlX9VP3yLTW2{?87pn%a`e=g%;*-H^6bO?3E`mxNB@FYjakG7kl1wg)t^znihj zAc*CldrOd5LEa3IoNgRJ`6e~0>ZGj*=#3L(sSc{n)vPyMXq}?9`jTL1F!j^agNU2%~$>njo;C1QB(`LvKQP`{2S^sZNDHJ3QlR#3tkiITDw~%1t z_JUAL6vzYd{1T3LoEMI>36{R88}6gzy4&(^RI)#O>I_PnX+?xz}S%7cCx~u$S$g`%|5y3w67B8eRIiNkSYt z4}r5|MbtUNB$S*jIEK!r^nQwy$5awH9t-GOCU~HnTHFuTdV*b^a$h^*3+G;nx5>*~ z1cI;sJPRy>`>M5j`#ki3*23 z*4o6>%XN#1m7p8Td_Jl|yCGN15hPAn;Sg#n#4^5i<*S=lM?Lpenl}B=AFZti!6`n` zX-(QOWUJK9C4Wze%7o3>0vH#*N^slOZF+WHbimpLhaC4+F=WJF{-)uVUmktz)-m$% zVMU`H4smB9Z29x_YrE^28MHHQ=L#=f>4wC<4Mnym{lA$r3h5P}fmQxHIq#(51Wi#> zxyMMcvh;KJ3*{SsxSJaED-QCSTC#`VJY?mbrgG&XZxdOdda>5c$Qj)EizLuK=7~Zt!Z8be z?P~gBm<1rWyY8Hh5KS!hK?X!M`rRa)esR+B#Zkw6dr&QP#{##g8*h!ZQSd=ZwSGBJ zQwGYhb1hr&eXHDHPRd`%#c_{k4?wl)w%3JI9;QP+Uu{dye>cAPG&ES?TGP5wqh*cM z17rmzFC#JUVq(V2Q)fgHfQf?S)NEt|Cxi@ypfj!|Tt5%!|6_&{&S%_P-tVNV?*xjq zjRAF(L0K5V4Hek8>z%1T$aRnEAqbrL-D*XrZSKrs^0uY|v_49r*|EjCG8@UE#zfY_ zGLP2GY;}$5U&}QkRSB(SKQu&+9N;a0R41WIPP3ToKyTp$Amlzjgo<}`Ax@;`(e&f% zAZV{tE^mF#GPgr|oomnara`N(p3JArq5;CsZ4KaxHgVT$y*f6DFD4`61w0aHPsxdG zki{nHI$z>}Bxg4rV|pvatAG>qT?F(feZ-R_s}8Ex=k|1rXD<=C5da?}nDO>@aytZh z34ITC?dTVdhh7(T+@AVrX6%1{18Ax_Rcx@VeB!3qix&#Px-Yq7p#QW;`q$i~9KoBc z%k8ton71$A7Yz%}KjhY@0BO|Zk5VFZ|Dop%>u~A|!^%mD*2(qCJ1=3Sh)e zqzD-pVW|K$5{J*IDJ>GDTK-}#_0eN9-ga0hMXx3h-riB3#z~nucId{_sbu-C@j^~vH!6f< zL_3+RDPsBxK?=guvRIaIULconVuf-=G;e6*sI339M;p_Z-)`6(cjf>ZAoycs@sPz* zkzlcoKrunPRylD5vfAeIxc)$>#rs};cHf`b*A!rqPEwlv(J;`OH_}yy1eGMpIt`Ae zsuUJ7Uq**U#`kAso1(&-;V1vYfeh-5+&8`RpCvj1-|wH_nMyabgAEXPk!n+(e9Om2S{r6+)FG=0?zY0=+iB8LklKn*I2CN!TxeM#m>|T*= z<>hgsmLZ!0RiFNUE{6ZB(??k42xtk%SS8=C*Ks?Jo!VYg6!Dk7qF(<%VauiEA6>@d zZ)Usr)1|wo#q!#$lA#p1(jB92X~o1Ih+Z!Cy|Q%ulM>iWTnA){75qOTlUik&!=P}= zkKe$l%vv{qxGCk9UX9V}qtq^H5N+2Tzy2MNq4i?c?2aeHK{HdJCD4Yc#ZB?MKF}=g z7Afk&8h=b=5buA6XIg%^*HEWq?v8BEWO}UlYp+393ztQ++x9)>nv`9hMm!?)*JsJ< zL+m3D_|xXykVYDKa&LK>RnjnaOX7E-oVBr%bJncY{jCJ(`aDzfJCv!87q>!<17X=q z`J1tOSDX~#o#J@AFYw-CBV3F3;ZbC3h~&Skk~VY#L{=@UgD}Tm)Pp| zuH9lhFmes>>6zR_N+ACazZt`}71_#g8u4nEy~W`zX34ZOzpb__ z)V2GJG#mDuhuQ$C4BozuSNss$(-S5Qo-f&nWjsDBt~{^gRkn1UhU}M_pe_178O&KX zYf}oOd>H;5P>_1;LuZfh<++N@KNQ~_e{`HHJ6sV$UTB=l8nF0{^0={R)<^IAg<7kw zsP(KLLNj2~L~rGZ0R;wzr29pnED|-BkM!=Sr0>G2&&W9&c@+HI?e}jVb-DQ?qic}*jt()P97HGc^&wE&G{Mzyfv^g zz7U`LmFr`quJo^>*E(b4w5;VW7(M9^B2@a?AE~aTE7dp?%E7K+R~N`L$$)~qNgk7Cz3P{v6h%%;4-pV2jH2kuG5!D2_kfTWKQMb3Yh0}H}%0{NxpKw4M|-+)*~J#7}KL=#V2SBz8ZPphu*Kh zd)b>_9f`N^xXFx7@|D2-xla0fFU@!BP+bx5KunAazf>RtZtle?jSoBUV(;66)nQtc z?<<`kK*#XF{%^;avB~D4XQ=ZiIq&nxa52%|eU*Ha8G48?oQ{)D;3aywY5Rkn3d^hssxkwK)sVSbt{;djH=3JSJN^c2uT1tf<|0 zd4*`a)jHQ-0-jDd+>!9A!s|rUFIld>;5u(NAMcNwN3w`gaGOiHE%fjG5`3zYjNCFP z(A@1B7PE?QND`4g&Akzj^ZU*)wPy`nkSfE9Jm10UIa~0GfTNu@wBH1XlXjz%z_<3f z{to!aQf&$%wyWIJY)8iZn{U^LhI6M}^PL^$ULiVe}Etoos#Jj z&wK?<*H_H$SlVb9lG`USuPRuPBvLYuyU$&D@t?-#Vl}mM*Kc#1Fm{$1IV^pEKO^!| zI*-l^&XRAOl^R`FnX#%JtdieQe+zFHZmrW`t>;5fp68S0ddQe&*LJLYv;^pdmqGYY zVj+~+I-MA^KKCA2ZnG2Qx{Y==HvbTTv`GB3Ub3ckz@#JDh2cQpZ=^))mJ9@yuG3z> zF^Tqe-bQQVAq5|egaCh*VG;jmg-xbf$f%${RWp#bI9|ExPmgyOSvq$F{`~lulbM5ehsIl+lN2U}HhxXX@jc=}qM}91@ zA5NP`s{L!^Jq}|cixGtK$WQ5lc3ioPi81XdDyoP3qK@Le9mT&^!EKmz0FnOO(hv(w zwL{-glC2LeNa)4W9mcA&8+vDauD*BrSF)fpK5r}h!co40R(+IR64kxz!djC8NM)`Q zfM(en)pdOfJM*gujnRGwpgH%MR4s-=KD2X_(8nJal#~)8X?c{ouXXqR_FT%Yrn^_x zr?AW3MefNw%vay04!z>1R9Mj0J1f7|jIS)$uQKM#CmbFf28|_gdA)$T{ND91rk#Mr z&hkDg^0beicPMQ)Z!l=8>Ky#D`2^#9#b5HtvfosGKR>*2_Yk!DQv;2~BX?Lpd5ud` zHP$4fE^^vixDhJ1wXW!U$#Z_K?56+&G)y{{GSoGKteaL~Jx=8TMVKGMq9e3NNW85{ zO6e_F`G6gp8FAthj|D@O*F{e{gS~52q_f?_ToFa`d+1**%-9y|GiaHqBWa1Zq&`yl zzl&wH1d!(#E6jAHr5vJ=^$LOa%!qS7EehU1*Su+?sIqfB^ClAWAh$a2^v*PKhUB=x z$<|Ep#%(H%NKd`JzTgz+wHFW>M0i~R4m~du0^=G$&?O|4ca^#r)ojb-+h3?@p_Ib2 zzAt>YNGe^pu2FF|WWf1q?UcC5nD0ec|M9Zcq|T>|?Su!u8eku-So0`?lC|Sr?z7g_ z$coIZtZR3M895aMaK>fq_acv0&QIluk>nq`jRd#x z2F>9awE(d0md$b9#SKMd(wB>KI%t#6U< zJ=Rm5*|uK8-jq$>+K)U8(?fnKbiXu`|nj>VXr!pgApAKPpKM(YD=*_~b5 zhsHi;?^1gVQWyJc=^tskd2FI*8A&7(HMZm4Yuo@=-T0d&O6GW)2-^5uxfS+4x3X^p z=1E-hWk-fWlnM27uQ%^q*SVD9;I_hRs(~(@D-X9d`vNNxea2rLNrcbx|I03ZXhtvX zlkp|ZD#+k(;Es~hW^I3lPOQ9h>JIUT215nE$q9ApDwFgj`84$r$tuI%=PzELL5mA7 z(VXJ4qa^MKo%?s-MBWn66xn&q-%(O7z3`0dwhSIk%+~qLEz73AF8hc%hr3gZp(XM5 zb1Gskq{APSy_4x-yrznuJ^ZMx@uDzkr7Xs(-{K55m;6ftYG!V8dLMHqIm3FoR(e+Q zx)DWemqqqXueVu<8t(k+6@x3k;dBizX9Mu=2jMakbM#hnV@xP zXdlyU8q;FQfk(CJUtugY=hZ*$OADiWU1ovprJY)6qOK}0+*fkeKE>GQmJ-{URPbQQ zS!V1Ow}^x^T#H&0FOPcj~i?>WmDDsi5VDDy5;zofR2lkX<(4q<;(sn`8u%K@Nm5G=0nLWe{Tf zxlWY9dRfmD_j3k%4k9)Su}g#nR^+0X3CWT)(AgnxS`6-#D>~g3ouwJ4 z-$xbas$op5=X%^-G^=)q8C%7XB#(lA;R|@qki+X$-IgauRg*z$+4e2aQ^o{Kwjugj zL=d8ZBU!%!&-#EdcwUIE;t!r627bvs236bVnMtLs9xTC%{Hizc!{YsCk{?OLD zYs^>$Zbj4X2#&7|8qq>|Z;LRH3F*MhW3C0;S(c1DeL<$r#iEZHup;}-m~Qa|Br%4Y zMC=Jl-oo3Ch6yb(_A}EoM>$j*ZyU=7{_n5fN6Ml4c-yWpk=6ZC8?0vX;0gDbFwy`1 zqH>fu>f_0^$BgC~b_x;)*(nGyV;v++-tOnmof=7GVOAt`X^+c)Umvz1P+qZ#FL4)G znD_5L`GPDb!OXmw0ouUrQ0xMVz6%kU=A1cm>WR?NQoct>O-MjMa8Ff5L63mob{zr1jm+CO z@o!j#eqzyN$*-0-6b2&80v-K?KGfjt>*!1fLhY37|q1T&+9tu(Wdu;yb;H+k?2 z2Ni#Ju)e>R!E=A7=i;`^vNDWPz7qHeT)>{zjJ__;5Dy7oY3Bc#R|5b0pVvTU#{U8F zbdqNNU!;sRbr|Jc-NB5)01>|D{6dczMa2R9B9DcH`FR-y9`lO=9}5E?i|{?>mv}5D zA;8c0@578=&E3{cLQg^I-?i{9Y33K6o^BFAppTCaz()|^>TVC@7Z(=?J{AB92=L({ z_&od|p4Ps65D%8$Gbn&Pp1V7^c{;d482_2k+Q!w(Q<@o%>Hm`8;`ZOP5RZSi3BO@L zUu!oYKj85{B>e`|)cpSjb#eI*+QU;1{0HCv*NHt0{M^7mJ+OzXm-}-(FRFa>gxP^7j<5^db)bNaCKvpm;Yzi#27WLpF2SQdG|kKG&LnuAs(LAkmq1k z1!-pdEC2@wTM0!0enFAPa!P_vMHKk?6~)99M1{rp1(gIIi^$2#35)+8tKj|Gfh4FvLmT>sLaZ&g`=lgf8?f;33oZ|mE z7Kld%_z!dcV)pM>cnSLF=YOJ$Z~Q0xUR_s_@jncWM)PCzIAI z>+(|j=+ImmliV$w#(G`u>h*W`ZFPTz)cGJenNf55iN7u*@vEIC8!G2!O`KMmbTYuZHt$e zC=3(W66TP8^?wfLzkkTM85;j?6NE;G-2M9nA@voCzuRO&R{?*wIbU2i|GTa8>mMcZ z=gG}|;CAItlipn2_`}yv)vlXA!}MMMGZ#T+L8GfCLDA0#ZVUJRqAWx%bu&n`HC5p0x59G(HoV_KD3NX7WxG8P!!lhhN@b9U(s-_;LwcH;-Ji z`HKRA*>}y#+7pEY58SwB?*7>j0)l0F>(r|X-wHngh}{0-QHYM>0^_D0Tep695)e$pZ$K@+{KSx3r_wUc>(#juIJ5le z&83{Ew|7oyJ$~r9ho|)1@|!csU%j*i4QtLR6C$LZdjwZfXDpKr8UFN!q$MDWMWO-& zZa37u3yH!|&|dsS$hZ0v?4(`%aZYa3-P?6_!A}Q``v2ONcgkH%0ZQ@PMy~+?#`(qV zPSJE#d74Ue-;FCqG|L8M_4%0m50siFJI1+>d5ZnZH>}F9 zjw@FIvz8MpQ^40ee_(XdH)lyi?tZGYd$q0p8X$7t?Iq?aUoq~!&0pBCCZe*dObDO? zcb%;sxU0SiQD3Dn7e5Mr{MV`a#uu^uG{X<|#^f3HZLT`$b@NOMot0lCZ1k3ITrTzIVW``wK0oRuW_5%koFaL-bO+n@t37K_6SZ z;K_0MUJG75@l6T*)iKav5{DLy3_J~Fc;hZU{%3x&7QNf_l;RUwqG3$#f}4v!j&=Gv z6btFy_#>SylpX*wVxbnd(SLT3K$37HyC|)AOUUBIz)zb~=P@fzdB#Z#tL`xK^CnfY z@BY!uCjDrry76CQni4A)B4#KPI5WOQEwuSZv90S>F;U1;fGx)pdqX1Q*Psq={eN(J zqO?zCyzA(j?<@~gO6gtUS(oc#lP{!n;|gC~fMLnihw);?qBz&L7BOb;l!b!-bv8ocKJGP7ex{NABxI8&-QC~7Yg5e@7y z|C+Nypq6Lo#jkc~{^vx7nD=@WJ}O2F3z(0U5=6y6Wyo}P5|J18qx0lK#YI`CPae%Z z-cP6E9C3>>vVOqQ=>q=3P_p`$hV5wO4LQ~zSrzt}Nuj}x@K!x{3GOgi)ju~cR$XD9 z(JN_9aW7d-*zvmd9|xYWH{IqWlN)`+Ax}m{JpB`7ws%0W7^kRMYRpqd7O;|H9jK6x{U+Mk+Tb#{KB#yFiR=eJ)%dc%)auNt z(vw!Vmr$jfy_4lrHg!_5X5fi1f?m+)Uu^O3-}Qp?beiCyap`zDq=I z-bCZr*$d}`z2+m2Uor(tbF&PL3Rw}KC2z>|d8P%{{H0q%izcoDAordY$niZz^Mj?? z%R3d8{d6*KSh!pCbvUr4R#hzO@m`_$_+-kHWyZ$$lk->8D8jEJvoAa8?6aZAlc}{r zwPj@$71=8Xr|`GAe^diOu25Q@&I_Bsz@{~~xrNm1!2NCpbHA130pnq1Hd@~ZL$8Px z@UM>ExTts7r>Xh32PliuEEw*!AIvE5hnh9rt}O89ldu52fWcuf2h&;zl8=s#t`r(p z39t<-E1gJkj^+QeGX$X;U<#rfCYg4QRvovx+FH!#VQtxqvzC^YpgTsMca-cjy{{qr zAFF6teK}}A`pp=#Gq}(@NKFT-QQb6;H1SJD*tWaCKtUZEF$ZVoXt%!@ zo4W}MSVPhKYkKvm4#-}fiE&Qb-69P6_m<^e5Y-Mf5B~*X=`d~j=tpna}WsJguJvZkY=^nhTZX*3UKV6rKZn* z!*J%C3_^joOTbS!O2uDA6!N6vS&yXCN~x)-weE$=HL?6rPXuux)DAm(3 z9n%l~BC1<)yS$W{F~Xe`GBZ3-kRCPNPL+JPtBli=k+sO4D@XCd0K^;=@%{$JvE0cb zf6+n^K^2wQoVH=D9In$otvWF921-`N;zswb+QsDDPpH1U@{ej<{93>a9JX-RZ| z6%_~c^`q1J&By}5L2Y(t{vr!08UWJb!kE8S_@?0vul1!1R27y+I(b_HO>hEYR7e@7 zs(ZC!SsY+;ieVwYyMHb4EqlT(l1dcWy_43T_`g_fd$#1y1LG1oQn%{pAfIV`U!Db= z3vt)w&cnWqe*a!@M48&%t?GSye)U$(9B_1WR1XAV3u~SJt!r~V@uJf`G4Vk|Ln8@U zqr7t^Nk8vRPfyRTbX*VIeCCR_cg}3|DN^I0LB;MVjP1F0J9%q!%1P2t!Xox)xsl|j?kiD0fh&IuLx^OXm+ZrtB3eY zBUNrqoW>P<|lvawUC6zGBOpHUBmV#1@+Y?rlzKc%^W!c zMuymhzCKsA;9vx=xOc=X&OMj=h=`b2&DFJ1=GKVH11~Qx%W{CsOak{rf@%rd@Dp|R zcFIY==7OX)x)+t<>^((L(KcSLX}b@E%Ncl-l%MN=^z`!DAOsN16jzjoh26ZEK)50{ zr)ym$jDMTFPx$raNnwQaJ?A$L3hV3Bvh1|?u;bpWBVh&@7<3T zC&MfgG}Xs|KzV>7Ll{>o>0L;;Su`&o(zCKKJ(Uo^$%#7Gcj);M##+h;B-|rI z)w$|55G1#}y!@FD38BpQIgi-MY1MFEwZrsx7r)f2f<6E=e5(5MjW&J0M@xOp;*4Ij zD}2QAW+kLaXQd5Z3NI{gj&Zvi$AXg3w^}tdHSzV~k)FVs=8`1&8x-vw*Iul>_4uNv z-VpVU5YWZr_1q%)W~pn5y*+_=QAP6;izmc~w9h^;|9kSD45okhfS0|J9Z{IhwcOWQ zw}@%u_V!*{baa6C$jvi})sr;Ash+*l8v!OpFS|P>-^RC#%+RKHbv>hR?3ILWj|E+? zI&b68b1f@H@o`(+WfV22)4iu|uu(a}M)R8-PQ%vuq?UmKZl4kq-%8+sDoLlHw4CmV zYCXA>&UC39A4=w3IB4@BGF-GH=u?NP3fpj8RH{6AhpW8^_Hi-Ci;8Q2P_mvbcKn4| zuTlDC!Vf|=k5dp2{&lr$nj=lMj_6-jSG*C!-n+RTsL6Wm86 zA;3F(+C*k>r~7Qhu#2rY6#~F64(x@gzA78&s>;#`rzg!g0P79jAkfL4JDL0~2_aRY zLP7HpccIaZ$ZS##(yT&E ztb%`QL$cTF2rv76*I8~AckEVeZ`eJWLmlPQ0`6`iBBCx?+>)%Ck5BFOH?7f_@L}%9 z4^;s~YkNRN#&U=0+}atYRJW}8;y+d~A9Lq30rsfQ-ce%6fk0!Dm(`Q|!i>miy> z@?7ruM}wc)e5*q%HrZeG7bmAe1yTStc`sMsA`M;BZB|0pfwjo?|q ziSXAT*;=#b)RcP*Ms8eXj!9-Fj~|wq;1Q@d3d05gZ`By8b(CS=)$e{}KDz5M)V#$q zy^O%j@*%`eN{GH1s#?fr8GJR2tjrfa_jgmP(P&{pQ2Ciq`yiQiTqLytX$KEBhjC+&ZxK}g&DDuY0250};X zA_aJFu_L>JgUTxhjkdaM*qlSiR${*fk0f0-)tEL<$pDkdSr?L{2+)A$=!Wedo#3 zRh~@)H&qJv2dWHWOv{U}YzXn!SredrWvynd&uE44@*yH|9x0nJS$$;>Xv*n7|MjGz zgi+P2dPHPI-AGxbNTdZ2V2MjG2wWCOlUOr%m8`=u@rwqVtyYt$tbFEMD6z@Mfk5gO z(B_fq41vi@n#qechVRDiSzS%Cn6Ck`$LFy#RZERSg1sDloqegqrNK%C!Gi;oRt3RV zN`s3=5trM+hS|oK(dLNx%H<}L9YBOABPicxtv}0srx~MWWtC%KXgFo*9T;ey9dzb! z=lWHNWxW^Eg|T2_c~Ml6c-#p}} z5Dn40;Z3LoBi2pYW~~;K9+kp-==P)#t`b53&gw#snxV;x+SE+Z(W$+-A*kSX7?sRk zZB5tfL29ZdY^T8E$DH~*m${<1{L#pvz+I=I3Gh*6k#JFPw|DCM2WnvTQr-}^xW?oMD65Ef4UxFukJ{?qo<`B>Rk-1U-k zYDaW=CrF6N>^Q6d-V?XLuOH+Ft>*oZj11a6Y0+ROHy5CapfBc1Jd3BlBl!?os zu&~PRRw;68em1;NG1Sb?D~#u>!W%w2&Y9YixG1&M^;%Y|lOxpBZk4oEqWowdvq!&A zbwKQqOny6`hlHJp>q)ZmYd-GfgmXHnCYo}R<@EHBYUjf9_E(aH8&9IjAi+j=0v-6h zK6UJ1(2l&`FdzdrZKA5zy`vQ+X#;nkXV1FMzLh8a_;FL2+?F)>9Tq%YL${x`Gs~pe zr|I4|YNY0&pIB^_G~#VwaI)+ZE6sE{5Mz}>&ZCtCoNqU3J{*;hqYhYlD2-ISe<_vWrvB8xZEtIqD=!D9Lp?R!wve(bsdiY-)(y5+ z@^?_UWj@?1^0lUmsg!SS@j07NWp5TSu?xlX;l81|Twz+sU}@}IvjmW9T6TpTX^Y!@ zhiT2{Y7nuROWHkkMO353#%#sl)_#o3T*~|H6t}t#(`4;?!K9O}N(nOQO1|_t)j;{N zAcJ1-uV2?|-j_;ht&V$BT!acsNWeSgnvSQOTtF{%SC9sahHNf$Ii2yq$I~@CaSZ3X zfYTi1AdXI6Q_h@bl)n4%^gxdUnShWGtCJOy@h*jT_xF>x7%S>BD8H~U7Z!tAC-FV< zxCk5f`gS92vgLWPvoHR_tHpQpoP4hvF&Mv3`Jb!78RX4VXG`kdUC^LDX<+s84N#fm z-NN2JZ1rWSe-v_D0JgZuIz!snEPk)f;Cxjk&5Y(YiFyHWM`7WS;P!(H>wfbej`G!o zQ=VJ4vq7mp9T)~dHf`w0yR{{2++3vC$MO+t)l)hyFcG9XX0{Q0$(v(fHl4*eW5d3l zlm6&l%Xh%X|LMM~=$t0h7`yKN*`P4mGj=`jbNlXu#oYJh0;%JZ#Qo4qkB{ejX~GTe zQI0Pixjzhg(~2Lk$ZMPiHZVs&&_}M9fER1T6QLB)l3$^O(tMUpIuiCiJ^L%2y$-J8 z!h8N5r~XJ(@w5vYL=+pu*+~}=o$1kUGBh>B+)3Z)D>0K$RW9X>xNYV0`$jHg+`C9} z-hRqz9+h_CFR&4wxFR1PkQzowRUv!+D}L0A<`{{uj%J>6QIxCKn9`eRBA-Bk{Ww|bkY*(cub-v(%; zWo9M`&NZmf2hOhz%gewV_70S-qAV(5a`Ja-F1wCz97!CWkFhL2E9+eM|A>BnGs&h{ z*-E`7rs%EUQ{^2RmVIy10HP5$%{@?v-F78QyG>}g5Byg+FXbIA*u~h$2np>_1XemuQ7FveWyf+_$wek65OomBA%@4b@4b9-1qas%*Xx83&Y2YJr00eYh z7gk=LjF0w|yU+UB_liPJE25*LB^;Hr=$Dq3s_X}3CYu9lWvomy%xni2x4U3l>UEj! zb(M3bc9pc7(gm^B^3R)j&401Q#Keqo*{|zAx3yI`-bMmPg-0dc>g!ubv&{303$r!f z@(0^`YDkogXQWdfJ=VrY>)~+6jm^z>cWfxnh<4BnamdEwuGTlrhPQYM1{;o7`!ZPg z`W(B;A~$-(2JeSYaRgwtlc89D&l8qsTVGBsJj#!%wQsrWZGG(S<`RE)q`OsIQ)B3a z%XOY^(Z^ePya%iO$>83Uo;>;Rg3fehmyhri(&_Msh&xV5?9qyN@fUsWQuv`Kxyn@S zWysf>nst|n&(Bkj0%Em}@PFN2*JnmWkUa%eB;5)Kw5Kc@_iWptp zG@%RWoO3ikIIo#$}wlq`~eAXYyhz_+95vd#LLVDXgT3hF8TQR zoC0QTp&eQU#R9}_U4p&5PAK_4jY&#~K(^MP{@CeqQQFtszh#IZTg|gl+QgU*^y#~5 z7u(>zckwh7A0n~bd9Hmn56pY`tM4=`g+NUNS>D5^y4E+@_iJ24#U&SFca-9}kW%td z4j^FBp;+rs?PBR>?R|j`HbJ4TD#L3vNFvA{Lim>?#4j4P?cSO%tI&A83OO`&$yjAG z@p9doH-$ODCH0yWhr-Q@e5~*yI6!3d687bIZVFfJKDeoVeFN5P?n*a|L0|$;dwFEp zXhfUy-Y|u|@p(YLt-}<>aCr!+N3S79*0LIim6bb}NA!)lZmd<-6pi);vb=jsD*_3W zhhPUJR|>1q1vN!Vh@z{EQ53)gbVZAvmbhQ&N%=7dfm?OGd>U>kbFiV^6S@;T;7R@f z6tNo9XSRG9v@&OlnT5Kaf*F!|0GDr_Yl@%?t_apnhFS&4*%02NP!6vEN?cts+`3ANs8?D0@DWPy6uU z>y&dU4{q_f`!>p>ZPY3uvlbr9?R>ChcB!9jc~F*FWfM9YRM>Q~-z#9ZRZIfiz3}HO zw3@x7IXx3au!x#tQ}-uJWu)ndbbAp^$K>^UMU^P%u4oQIOH0IL5U% z03c>1F=cwV25m)2sPI9!CF;ND#1fEfE6t1`g8uV0~PUjfJPj;C$7DWo-}pzQm3>OM4M72)uuimk4JiGa^aGe`H!^GRvk zBbsqMJnb&_(}>SV=DuX*O3{T+3K7)rHnmu)G&~33I9Sb>uTIXD249Wnp}&^e_*&}j zYjKj+MTD6z#`=bi%8q*D06Hu~2%R4c0Pjx4pWfo+wCm}z+AU|vKvm4^3OB@?ypMoF zgRPSJj&I*W0x!dTx(9aZwT-rPlBM#kNkD^3tFFkRcE&9ZK#t7Oh&%9N1AJOs8KkKc zrVQ@i)UxQ1r((#7+nV<2>YF>SFozx`@7v>}z(=mHnhvt;doM7Treo#Pj10bWHv|WY zEgF}rV=`=4dJ@5-4m|B^?*}OEyr3MW`broadcILuy+3g2{e@O$21rNeGBi2K^(x(T zvOXY{i0EE-a3F?Q+_OYm#_Lr1$a{0*vwq7F!zI^%%w_)1bYUJ^+QeNQDfsK|TF8Yq z+CC?6^JD6|L-%niDi$7@KNaYKHl%aYC07r-6<$zX$mKqnMp{yyW~uCKR#c&9kT-x` z|0K&Tl+WELG%{|61vguE4n0pb?#z99cJt=SeCwP2%`d>NEuV9hmXq3?akRm~bw@{5 zN`^yaDZ^K2;+SZD~LrfdJv(B-7wLQmKjh>-trw40lUf^Wn zS*iU-4%?oony?=?VbMe{S8Pl2*H02dB_1*U){XB!^y9Lm90XNUVzmZF8Di|JWCY1@ zwU_IBpfzlJW_{2wdMhUS+UPRg0RT#8C_U6^@0vq+Ag-G|Ko3yAMiUB4(7r;-u|2)cV>^FryW3sIL(aO_1(Un648^*yhBeK+`P?A7KGwF7w_(2`F39hd1E`I|RyfhUL9+>by; z>uynme%G%G?=O&8aZ*6%r5k$G%d#YWy7jfo6Sycf6o>^xaxksZ8HxJy$rz|rWvlPo-dC@KBMD-BWYX|F<} z(1HU}!0K0~Ce3GC5;LUb3hqA_75DdIgNz$i`yK{|THP`~JHvvJXXC7tMBQoj6+;V; zgey_#wov5QIfc5JSq46(scGrE0j3GyV`VXH+!4dNxFdygMzK0K^s6oe^3Tpv^tDrX zWG__dAi7Y4Wc_{%XwA!2{^7lSJ9C2AYfDeWa$!#Y`c}!`EtSmDt&Kg`qZ5*(S#z|hg_NK}O3y?nSZwtM9 z7$?bHmYbs68iS8dh;I};Jo@#d^@DW=@iBdpbii>>*<_Z)c~wxm)6kr3E>A*9qyXMu zR&nvFrWbgz(?TzfJ1HCjS6}phxzvDM;#b>HT2;_e!{#^vZ?qaMGt7Jcogo3aKkRtgfe;sSO~CCh(ZnTDrIRnVad<*QFgkmEr}9RX!DmZ^6#bbQiyEmlgP~b5OkeQhaztB<%N#H zGi6Zc9W8n)h-%h=fb^lZCvss)oV;qxrCgbhq7eeh!^c(?{ZC5Pzaj%L-DuaQymkeS zN-?JW6w*u_?5ap{mUorZ-pKHnz>jE`uL0W(liI)4KN--AL;)#!yJN=cC3lecQKL1b z!X!Ks#ql;g~Vag z{oaz%>3)W00g7 z3EB;t$7)R@Y!H<`{!X&vwc%xhV*_P2D~DBC+roYF_d3>bXJ=_5|pH4}R&bRE|8Q#^>);Q}`q;jf^%n#5r$~&?giXDNWWn ze36k|>&xK5J3gaKcSmy+3_h_?5~^ux#s~?GFdWrW+>6r4(KeI?1>iG``$N5zJvn0) zIWHkFXl@XwvJ@X>Yl#l?%+QAcrQ1&_N_Bo|?1DM=0`eWLT-HWL48|CM@FN}0J&N)Z zuhQCtxavzMC#Q0#q3pp__1VX;Zbw(w@y?mjJ%#^F!^kvc%#$XfdR9}TD#mE!TKCjX zTT@-0v5=^R{r#|B=u1;Swqd;Md+dYF1FM4%<6ZPhT@#eI-LG^CF#6Ca{{ZP- zqvb578YEezb=C0lr-~XQt??d=7Zn}XtJ?^~Cy>tUsRtRO^L!RQRbLuRcU|0aaDL31 zLg*146N`RM?Ziz*7?ot5aAEpA6 z^YY?12-HpzNI0OWv>wrS^P*Mi*zk3<20yGzKlQ)Ot(IMC7nX>CY=ykSJ%tk8dlT|s z)#?*s)`szH)pu-(ztlxuCEB6~>=?+9_qcJI<(M|;XopbJ9?=z<5C> zTjBfbbjh{6lG2D#8jbFJDbrQ(R2A2bNON>G2{hhDHcx1)~Il-Ei84a$UHa}TydH^scCBR&VtytJJEoT#9b3X#g!xIEb%feUrD+6`$jG< zG1pO!Ucs|7RiLTq>7q5G3lQ2M*_!);9B*~Q)++CeLY#G6DW?pMmpUk@+tXD;nxzM?R5JILa7!Jm_Qe}n zLNzU+UT>PfD_p~^k3e4bJG0RJAFJhKxXR2y2IcXPwA0hyHE>Uu1}~N91*A*;>8+Aw zIi{C(=}ph2qocQ5HA&naSjb>H_tr1sPVXzy(^e{Akk60Jr*a1U@P543Ced@&1QYU9 z+iAOox*P>U-s?*|pD=tZw|WCU6H5*g-RdoXpV+9-N788YnKAy@a82%(hYs>9zW3~W zw~?-GCxd4*^A(cO6i5B)ta2TT+7EO)i4iR=X?e*nKyTMQSRf?qgtZE*`uON8XnGO_ z-$=pKwx|;y(-DSq8LUKiZNIzs>E!T`C01b}B`zD#z&Bdt*hr>ujf{Ifemf5n3aoXt zf?rkE*H7fNoGCBObDnF_&o(*8+}19ftGssCtQL}7oNdAa8uMru6Zr8=IUs{qHVEcC zQ>RLQGU^KUbpC1DPceB@9?xXW?eo@wL#KB6cD%_kW~8sr)5&Ye%E!l7<-O%!zeYi# zVqx**5x_jRn2pYz!+mOCJClur*UGLObMJKPO>EEZ?z`<`Lexnh`TqBZ+TDt&=Io-l zB}CVl%d}U=heR!7?ncaJvaHNSCapxEifaz4*uUh-58yWRNs#}z^w{xE90~<@Ml7r^ z&CbmMuU%a8@5+Y5)&B7uMMV%?xBLUVtfEFU#lPT_IL~c8Jr%N{3v7O1Wa;qE8@R;C z8xm>eSlLs&N^+h@nEt-0XE>`5tX@fi91SB?4cT2UGZ1^2WOQtNn0PE+}Gu zcEqjM$X1k~9(Z~9N#G?u((B>usUShD(cRH$VNOi}ueN{-yd#t-L9uO=sIlWKJH+qR zm-H}mhrIlmA6nJr?>yN6f;3*-GDL9LcBpc6SKu9G4%tR!d}yUh5w-_P++lp<(}XyHzNe%W8C46>-W*i0T887Ywm`pg}u`>p3G zuO#VfRh_w+{;(1oZ81Q*xHyf0T(Y4!#nXPwcAU1=9tA0(R(EC4Mcn!38b%dr!Dwei z#sF$vF>tbyK5y*AmlKXJUt*{D+;OL+VC(TfzvaQXUVW$R#N!$f3&sBmC)`2bYp?1Q z6r2AXn1J)@ZgAI9QsKzDH5DmDOY6vJgCFF$L3q)2`CQ2Rir%GP#QgfYRz8vGd#pyh z+~Ba?&2B8n8A5tJ_X=IJ5U4)!r&_O9rMCCN ztM&n+`t`KMhpaEjEj=%bZ0CP5m6m6)+E#BEUalJYbl*Fuh)0MAM*Z9w@j8})v$K=jyjVewi>;EENb=8Sr1&Bua~@nCJ>pU7`fX=%y0 zLGDV~msxJKXcGX4b10WO+qUA^04#>>i6XUm8@Wc+3W+I0t!TNF5zg`>jrc9l6^L?YLR@BaD4p#02UV|Ihsf-i%kXZRCILnMTT)A8* zRq14r9D=?ho?cVgp91SMy;0r!XGMMcjh&Z_u`21~iiuNf#0UwH9LD!r5Jbo$}F;?E6deASae0J;R z@;}i^Dq7m4#+?>X(kcGsGC{))M`;q7^AdU-XQ@Y;ujFsN!TFRPpR(a_vstTFI8ck+ zfSs)heM`{HEnIJVT&UOD5#ufs_6EFVpujky(4d1;~;-^bUzjv`J` z2m?~nj4q_i7F`xjyH87+4kXiXko2aKoU2Hfnie#O+}}>E_P0t9UDL5u;b76L$0v~? zWz8D3AQcAQw4k~V@z#zbEE4B&=|$PMu3ov&zo=*DF=w-NIPMSRy2B{z(8$-ZbwYLUmWX#&kG~DMsaG=p1O}IhpdxM z4_15T&X3lX*Dy02mj_)-V}<&Hbc^DvA42!LV=cIQ-&;9aFn<&rE0*K#r2V3D%gJDV zvEX59#9VsOvEpXU^)jc=jRCK|3W-L|P1!q|RL}PJo4B{H;nY_9viJ}|yASB-b+K;d zpc zNBVuD_OrAOjt(POMa=_~>FJ>vRtt-R;#A$v=E8d2)t?|VB=a+b+(r-TFQ_;doMl@-5T9?~j8N|=p zEm8SQ|6*iEF=$UP&4}iHuty^IjrcQC(CGcMGcacTU01j)`;u!wc=1K) z1m>NA^F_r^G-X^*QHtB0q@)W$aMk6fO_^Vut%|{Ht&=2PS%DX5tMON%oaAB~+uJDvfvbW;v$GXE)>7xY?e23>%*K)8Jra^$SaCM@xVcAP z^s{$~7$Etq4#(5L(O6G|dFviirLAk^wtJ`Cp2l+3`U?je!+exP^iYVQ!TNmn{4?Ko zh15=IQ|akR=-7LgC5+1XYOI5P`K^&}(OKz9Ois;?>!ql4M_B1y<4(Rke-QYA@cGbu zoG`+R)X)%QaxjhpGUTz6Ymk=fAMu#ve8dh)w1RzYH7d11jj+*H@ibzYj%^xYgrjHy zypZ*UU_<`|Snr5sGDsh-8#@8cM~}6V)1VCxcJMV7;XVf6?C>Ve;b{?kq{I()(GOzEJ|9z!H_V8$D5hbIIX@kH@OTS#~ zEPozp4$W|FF&Qf}VG%`oCej9<@15a>(Upjb%lUc)!m8z@1BlxA9IUV@G8$V6-E!LB z?**cRcrBa6ToliZQMlG)muc{e7b=hVEDNSRs$@s_QU;Lh`{x-$#&?whpwKRB98 zvvkZ@+(*lcn(DO+rho!ckRG~mP**~Ik-3YeRqb#RLr{fWgQP~9n;VZV^7&+qSH`Rl z>ZIObV^4j~?qdBjJ?a~+>LTrhxw(H||A2GO^eM9YtH$c*YK@vxGFjKO_l49-UH#{< zRn@Ved_sU9U5wTZgY&4^_-2v|wV!L*$?wDb@iCYP14C1L(1}u$#tlVw4zQ=KF>y%- zsQl6+}7Eij>zLLx@T|2`KC3u z{DKnK2KvbGc{rgj2X&-?))L6?k7bcga)3bL zv$_9{rQ7$UvYk_f(smvr^OqgbgDN8oX>hD|Lqk(|KKf_xeMSB+hLk9hK26xJn+FHG z0&b_%{uoF}NFk)lLU>~59B$jhFe9VDFZ=L@nN3cH!>X5u7)!A{DI0Yd=jaZsD58L5 z^_>_4d-sNb!>P2`gUFb8JDO-A4k$dw=J}+-@Mf6RzS<2VPu~^f4)Etd+nJ&OteuAe z(1nA|NBWx^=UyBnz=s5!#(3*-XJ|p$ma%YC_V$NYEcL+$|KwiHgZr#{NP^Ei@S!tC z{W0;&)r{%GX&-fuFJ)5TQ1h3ko#5FSajKlon~l`}-dj4~XNVq`xJ6KtKe@23PRx5X zlOIMFNmtEiHG(1`iJ)BKsHPKU(QjVh!RwZy@p zn|LL9c6RG9wFlOn>k0e-r28V_`O8VDbWi3~?6-kOCg_99GP`IDWV|0Ixzi+AnLGdr zr4(k>YdOn(&Gw309*48Hvy6pR&_1Um<(^3d;J&Mq*+k?(irb>ntb^U_&0CKB#-K+O zKPBJ$?1Y5%`P~cewG}vz%YySJ*v`I9wxvwDNuG(jK`K1kz%+rc<`@p&<4X&N$|pUQk>*Tcd=+3x#FJEE6Sa_Q(QYTHl@eIS`|&;LKQf$J*i4opNpe;O1iGFNcYUy*sc^*#{lhx(08hTX!ul7ief0k6S9< zko>)j&euShoS+h{rm(OuxEXlZETWIREmB2Y1)G3j8Mv1h7o_9XFOEH1AH^?^T4WNL zE!!G1s}8=m<=0l_Tn&ke@4%NnY9~3$NVcXpbJx*U)4sa8jJc~E+R`l}CB=)c!@O=D zVr~%-rmgft$=2Cf<2*=qoc`ZE%PoP0L^aHjmE2VUgV`>(Eq;tJoWebxUc@&`0Hxsb zq*y7?C$_TyI3XaSNIk)eHG{)Mwwb!9%c7O%O~zlsYWD zt@Y-%XmZXvKLZ2JIEH@IZ+;ZcdIa_1!0fWM2ErmOSu?Cyy=oYz2OVcVAQ+b$Uq{7< z*AT@LH!aM2akP_AacOxEMRj2*-s6+I&_rnGd%B^iS?-v7G1n~!Vk<8kQ(%5Qj+eRDPwynl~ch1x2{Ll5~L%;O8lYRd%vu4d&vz3}x9a7d*wg=AhJ6x6e{kGrBefnFL(FmVEDmY z@5rbq*&x2J$xFO9{ntQ0B0inV`RIudko3$=^Rz(6mi_+PauG^$&%+B5XUa?7jkc&x zHZ2#H+Ks$x6-?}d*@l3D*N{X@4Z%=%|*-->vkG%@(9{*c+LAyIozMrw>BFrE8_yGsg!yq~c&spl+AF z=th=~QtQ|hPDg7&OENcdcl=5>Xi?{W!sm_4ZJrJb%G3qKQL1$h67qooVs*t*Bm8aFW0Sa0QT>b1S5A0qOAa^ z0)E}@h2DQ7G00spUzQ3g_tMhRkTZVKX7Wbzg2(Bk?_jv%7vqkF_0Q6^*w)pbjU`y6 zVv>~ALo2qzI)!Drlsfm#+b^f5;N*9h4`OZGl?MJVvVn9}3xguG{z|-GKW$4iZ*N}c z$ie?TpbABvx4JLmQ;?cysh#{uDE{c*)AIh&salUWp4mF3PRZEy(;Ya*K`QYS-gp$g z{mN2w|Mbsni|2q6ctkA&aIF2`4|{A`N=Q0z-xC{|gpq1?w)4_2nc^N41Le{JbQGi| zcEfZUR{>}QxmpmI$sC_728WQseh2i9y;|B9O&bZDG2a!JwK-f3WhKoUav zpGVsWkMp=Z6xEYZz5We=^2Xl5tDJpmzqs+RTZIUt1at3J@}kWRqMA6Ye=q6#1KutI zr-bGt_UP{3Or{oEN7<6{sLihuMz+Eem%WudEj^BHHIN_jzaRjMhX0q_z!6?dAGHXG$q z-Km=?cI5d1>ieS!=MO!p%OUqZ#Vy29dY!(wvasyP7rD=FzbC^~Wfsi8(9xwc%dnOdI=EHSxP zx=uks!4H?e-aQo38-#}=jp;{*1phBYyBTv}Xj1gwPO;w)a5do~vk{t7sFc#TXU zMTK=a`h?f7&cQ)5E|3yhzj|d@l9F}#k;e_#%7`T9&PDUlx%AN4s9G@0ZiC35ja=83 z;0iG?+pJ9%9f$L=w=Meq6sEb?gv&}@TK|*1eRFcbAicbTc3q-)i5&LF5}4LnLV?GA z*?{JYuJpbswSPP;9G=RT+)c5lNNi}hts6dFsMgMKKZ<%6nhndU(E$$KlM$jEFe;zN z=}g1^vC|sMMMjR(x@jC*zAs-0=-V#*ukpAEs8uUw_JO3?>-G;Lcq z9shG)vsM<{`E2ewI?@k+h`q4dSJD3&Qzar#m_HuObC=4ATN}I0D_x5%lK!91L~GPM zoh73beTl70HpPn>sevL2j7g?|=|JWHJ(Xdzw~hXkO71F=srEmgL7`|oTij>-8EXZV zbKn5QJEplz9voLA;4Hgm2wSDZ7oorj`ajWVAjUAaAg@)-rm-e0E=GHbM+^syE<_fY zIBY+5C%|P1owygW>q7W{{s4PYS(R{!$FVb= zi;Jp^PJr`INlEEBM_4Zaa^-ZTvZ`vBSwSbX3C54`hzJQUua|3gpy;Ynopudty-!ziSjPWN;nEy>TtW-8(e92&{l^A=~Aw~Tgu&xr%;T9FUOG33CjfX z4bfOPZ7~>wHIzyy-SgJ|^UX;P;$T^cB&$)>ze`0y4akP#&wbvW-j8)N@C6nL6JuhK zFflNqTUt2HOieE=d2}C!RCm^2PuF*TU|UB6)Dp+(GvCwV_|8@4TU(mX>%*T28&3ny zaL4TkwxKAWX9KTKg+SogzkBd}MEVeTP5c#7O{wazq_iSd)4Ewimdo`bOUq@|sm6E| z>+tAk>Q|ibj3X-N!;xwyRjF#_nEBHz=XuAI^}|$BM_y*X0%!)k_hp#eMYOBk5Q57R#N2jhS(*}h0 zjbDzPSZFzQ9q)?|&X3gkgVdA;4Byp77V~u4BBYy*To!K1H>BzyeRQYh_PGjSh6^$hSLhQG zN&~0)7VEZEQZ?T~WAt@|7(Xt$wtgmh%SM!zDWwnG41&>Pe*aed)uFF<6_3SuN0mQv zr=_LCR(8SMR~ZiVfL}+a{TRi z9Ow~0)_6YHKNR{rlDFdy#Zfkj z{z71d@IQl`Du_S!?h!3Km!2gkfot@yjP&XqdC+Ew& zC2!{AFl*)wK32&m!$1^M(f>plUzFbo5>67&mkgNIudQq-AClG(Ai$>NbjfdS;I{5c zv2}P~);j`i9rzyCPXPz~tZqB#j7nhRzSezDD!iA-xB!UlcP!&Qpt&12uj`|Ypq=Ya z^j;Bw`UieQCxdG}@HJOXz+>HicL9&4vK{+$Tbr6r43~&$Yis{Dnq^#Wu!@sTWtI3( z1q9eJ2Sdm+C?peUCap&9`@XgBTP@azAOtx8Qf3KB$*?lrP90Xug{+_g`D4zz6^BA0 zy6@k=*Ek)kv`e?Qw?BH-*48RU^1ZsYOCNcNGMeL>dpJM8ouos5Q&N8H?UW#FcbS4| zSB3oO+}n`juZ`kiW1;@m($eC*s;oM%Gv{BlAV;&npF%)2W#Ky^=zjk4HkQ<87dt`{ zXQ)81A2cpuyaqJ>Jl3W5yzf@7P8V~*FzM;(dEob9;Na@dpal>Vt_+Qhhk#^#!+~>k zHO^<@j_>2+Q-17663imPW2){DhG!w4k7&K-DV}s9+qvURqj0 z!Ag+svEJN#2vPf?6YRU=7Rn{TnoB@*!wX8>EkIBnEynkWCnvD5KvI89=Ms3 zh<$B;hN%All5|#&m)m8VBxpR>ti@`?hK>4WhyA7U`I~uN`Y7JVqEI!di*%6wkyJL> zik2g)!{x@xf+7Zvm+R@-UU2?Tc5g3t!xok8#*NP&=k2NhR_Q#vSp>5i%Ml6NNz}BK zua;5VaP_y478jpbCoB_K=AY27vE3A0?MgPuIK04;SoVz`LZMHHk7q}z`exnx+#%}s zkuc!8O)r93R({8_B|CAbj#ezsN7M zqNJmY@%I-T9373Dm_USOVwEa#n&077Vcs`1k%(ciW}7DDx8xT$@%O;h)D!TtCM3*8 z#=UQ4DX|e>uMFv`Y)DbGfwWb3kWK>Ij z?7PkT8MTQ~=XmdFV#V`n^pQ)Lg94kMIVLfY4A2cE9ZnYxL*sj9(J`^3jnOrc&0y1! z*_MR_2T!>A0Hh0c2#qa#{BGF=m=muYT4MuCy^>}~WMm>JIMe_DpPe*;!6i5jBMfs- zs8&xvr^y^2G>@!?e256RAgAp1igsiy^3&VPDGf#CP7cb=(9C$yi=*=y^IC3F7P}nV z16wCfj^?36o|(Pq*DEWYt33+T9UW`PSjc6GLAGXpZv>*C`^TRou(0q`EY1zx>3Hoyquhmwud>R zwB`2;1_J9~9QkrNUjVhOzTeX)w8)foXxp^IEc+$1!og*mPAeyKKh05KvR2*}R2Ecyk9!{pHhzB56O8JJvg`~JFw|d0Z+PM_o0dl!0ZNDZ7s96B zMgeiISe0 z>1>cDBshHLDGpI^2@K~;v^JQ^WZgrMi9_7&>XIU z?qNWjluBhSU$n4Q@XLY%{38+(Q;5IhcL5-mG|u}ZwY9yC&EW}L88)h_UnVpVG>CFP zvp(f<{Wdu*Q?IS_UT_)t$uQ?Nat=Wo!cO4(>vHT5fPr)SKWdG5K%GL{p(sfFIvtzK zhq}U#Ba@EJjpQs5+V}qn=}(at_*Ft;Qb|P`76Bp2Wz9_tQXN=7cbrHFYAcS4_I(Rk zbzIb9926q-C_HZ=C#U2@_;`cE0C(pS$uOQQEjlVX){YI6BdRZae7Yg$*tD;pN@$<| zhBd+l{)1S=byYC1XT!JGPn1+tiAO_ULqfw5b#>Qe_f}^YvgdS9!;`j^8!}lgqh`7va~Ba#Qe3?Sd<4-=7f0u>`huJC6Q!;0Eg+!LLG*e6SXFrGu6arDdM5M*+;3>ETyu7@ zuK~w|_xtD1pGhex2M>7#&GW$n@xAW_*u*yQYEhehQl{hhz5Z@DOU;43+XM#U<>gRb zodc6{1l4Vq{H8IrJmGn+<+R16U?AFonl+lHFe91iy0-~B4mn$; zOfoD=nZlXqXw%8Of1&GmZVn9$OyP)Z>Sgz#--%z^7Fqx~=s(#RaSJAo_Rr;I;)@xk zf|?pl@zXRZCzS#ir(L!93s{0+x}ksu5ocrcS>O1)taikgK~)8%ytpouruXA4jQedO zOF-pPLUE%)zu=-8x(7=r2)_Oa3rF+$`T3e#I*`itnx6`jy^g;QL>_DkQ$Wr?UbNNu zRACb@jsIja)&eyE4snkF6K&%Any`@6`R?7?Z~9xMj*k&Lx+GvI!|~j9kfaR)u9ZMRK|O0f3yR+v zaE+gd<4ozepnDi`Qd=K>3QG7+#u5`EM&Dt!{FqWIOm`bVlgK((uGm2-xDuO~Q9N`% z5G)7R_irX9%yWufW20oy>7`xdaO=D06v{lOiTOxYO*KUA$QbgOG_Up7%fa4R!5tCV zk74Q|j}>8Z!n}P0PJ=E|Vmi7CZ6gAw7|M9F4_b=RbWp$&WPj+P5vO+qkO&)c$%ezH zoX-yHx1kb*Er2R9XeQkl=s!?F2)h$n8n@%QZh)dn^7rUxEL%qH>=;VJ1?*dj(A;DG z{=gpAwF(IqdIoiBa%`&~HTL=hQi$XG+IHHooW=`(n0?_gqVttp3%y6V;cgVbI^^$k z{tJE62H1ZRHouWQutURv=sHC*4ER3J)dkstUvq&XI@!iq5ay8M=T=mrFaa&B_6e-6 z7Ok~igLOL;!de~f+WMpeZHO8U&-|1d*Nvubbph!R8Ulh#NaUv^aRcIi18wltx8G!R ztfDI`G_lDE)R>sboMU}GiYDypGfJw*91P7O;<8O|JWsAiBv~BI;xL3(zn(RL8EYkH zloe>UInMQBm+%$+a#>4Do~#=2tK0G$n8f)dNxR>Faur+ zO)_egGC<6?H{i1FRcK9P{2{gT^`a8?3O`4*+2CJ&1WPv%&f7IQ+iXvmsg#)6XK{b zlhu*Y(W&vARlr?Pq$rZ(grp#aT2e(nC$!hz2yPwe26VJzxFt=3!LWW*2EAK+}|7)7B=yq2*x|_zjqH8*l`Uo@R$6$ zHm!6mOI5Jr;#BH+Jt^kgo66;K79WJ~tya-`#`yqXQ7%uJU^49G>{qEORqizPH?jLYRh+x0MX^o%s{7Q-U(eo@r!^7i?ii%X&PE0nbTs%mL#dcQuHJe<^y@BB1~ zi~(@Gyy6RJ-n83k{rnD~Q=3}fESr)iAo1HC=-V%eC%!zYSv)0UQt2$nM}$w5$&L1**eZ_xg^YQqg6JCuGpygux+eck_lEbN}~bk-^h7^$-zAP#hwz2KQQ%C26Y&X0Ng zUmwPOUULNrG^eJgSs>AFLCf=P-r@a?kV~-(huPq19#14)y1J_BsY{n&zTdHRQ6!Fq z-7j7%uHpi+lIWE-?#tUVV!P_etwn)NSfzn`#z^{=``DD!)Y1}%V9l(PAHT89tu5t# z2%Y@9<^ecmt{!g3t{&rSF90;A1_gc9x)uNyot=P^QUZ{)gE@iuseuu}!hDh8dvTevsW#IcQdxUT_$? z=6+1Oig3mf#rN72styeDDE%F>?(?R7m(J_uUK=k%NJ#h?Y#~HNl;#0sdPetaQ;U+c zg$1=$POt!pByH#9IXDLh#8pqAqkkdB(#;yNuV zDhhy&99YXg!iJw8uAG>D2})Zc#`72HeH8vgQCoi{`0R%wQfoXqg(3{-r$lP)x3;!+ z-YIpx?jP!zVjpsWT2)Sj5Loi|GR;PrUfu?RQG_X~Rr_Ju(XlWuz}{E5FPcJXiD<-6 zvu#dr;@e~dR7q4P_W-5gWbu`s-xtSiC+5$BK@^JvmtDYOL*x_<3#2~b#Nr_#(9kM7 ztN|_?yw$d@&r7}f8%Wc3mmBoc(ubeGayU{qT%AaZkdK9`S&H43jCk&&l|veb)m=v3Ig2N`wW+Nck>IZIHQ}q+b}&HnQnWS9Dr+MXOKKosSx3F8uUkj zO>g~F?*S5CUL8dQLfUCyc63e-oWn1QBk0EXWG0g(ZDCHgKZXwnxluc3t><%r#UQ8C z>K|n`g~3%5-wB}Q9+m6w9YP+fKp~~E-{9LJxc(b6pXCdiAM;o7b%;qhlXq6_sQo*$ zk}XI{QPIRL%enf@J`hh;8gbv?X&A|XP-Df89I@cB789Ibe=X*8%HCO8A-w~F(yPYV zQuBN3xiR}TSPuVbTT0P)K z0HJ`O&*bW%Pl)WbZfm@ACX9QezaTYtpQ}ZJdR+43)AAWHd}N%;Z31h@+?2yu+wHy# zE=tk0@$x501j_D)GCDiQ;*yd?{~Y~GhK{_T9}tbT;Z#m~4861q(XF4Gne@UI;sO3) zlrYrlc&>z#xAH-2+az{0`Bth9kqGWKo9AZ_YbH&x36 z$2wYtf2En)&o!?$kQo=L0EdFk_9sHu+_LH5U=X6<0H}auBrQ<|a4!RyBr7E(W=>jX z1nhI2_Bm*@9qGcT$KZCq*y|C6qakkCd_v@2))ELV+4${WCtT393!J~X=k&2Jh69Mr z06)UKPtijMRIf)6;E-%qkN>?=;rEZOVV#+kD5y!MEjb$-1W5_2@-Az}zkZNWM`%*x zKXnHRMdvi>^)j0A{nV~ z($K9{^6cA073GiKFqB^+N?qByByD8*IxAy#wFk|%3pL? z*}n0f59r|+quGbsd0BgRu$=z(3s2Sb(yTLa5Wxa#S~WJ=7Z(uFYmEewO43Q%ExzpE z1!(t8+*{F1X>D}0_tL6g7YKts2Zmhf(WJNegz>NV@`pqcKX9IMahxa3> z`Y@`#z0?HMT$(jCM~zERpzwVolQA(Vk?a%{AY`Mqgi^h5;!UDF=tT2;F;^ zRS2G=#|SRMVr+0QPPuem(%rbBA#=`-Nt#?YS3V+2FpbiC+A@dbeK6fG6v=sHo9w-(B=Pm@3?zL4KeRr2Q)8KWqYnBM!ON82hYINVdh1ou zho|pRUroiuiS=M~*hC~;*F525^%x?el9ISD@4;h#Mo-YqtHr}XrvbA!%y5T>sPbA$ zM5iUWh~=u)R+z18?WWPx8=Z5N;#Do&Y!m-wNv1q8NN@aOZu7_)3)7BUsxnrcJfr-H zSH?OQm!4WAds$&(yV~<}+O&Ep)%<4h5U-ayyjl~X3lrplvAab&z>h{BzyQ^s;Bq-P zNp1LVjIYfwtGBrZs&TJGINUHCos|2rgH(%&s5iH?&}g(Mh=ya(aF2 zacq2S4TBx}d+_tZf(+3vS^B0Bn}7!eejz|tz|TNCCBLmA{8_?2KgvM}CIkZq@10-P zG(R%Wud7oE4gDHkePgd)z2(w;b~J1_B+;*_t!rzI(D;ZVn$jl@Z`p_lqgYZ>+Pgfh z*h@6^#q)<2q+J4^2rb&BFlXV9Z9wPSJ6#%80AX#D`Lq90e#6HY|~W1-N2F^N}XmzgIi7w2B#(; zFsr_%vvyhnqw>15w|6uS)6~-sgs9&HtOA%={3RtdiKibzLqmZQ=?#$$!G%XwP%Atf zk45TxNLEgb!d&G#P3vvJS9SGf67uudqAJ^v&=33M;D5I*TIQEjOxUHHO93V0s$fUP zTl@3*>0%271n@To)fHtEVu*hnsy*B(m+l5ZhLN&ysZy0t?bfrcD;FjXis8*wI2@7r zh(4w{ar%Lm9$e;_#cCj1Ei@D__MxR3XmXO@hJ~F{lczhT*`*^AsF#KPa6Vt92F473 z*3Cr_i@+g-4Y8Z!oWZa<+&iP2oRoJSW`h(Mo9XOru-LyGiw}95WlTW&=TUby3iI9W zIML&mb@akZBkg*tdC)kU>R$G&&pXEQNbLhL`Uqh>l~k0AjmlLsc~7ap1+dE2z+lF{ zDa(mn-rUsBjngcn&Zoqs7Mi(kEHRq$^I@_X19kiaRFD(~@g`DsjqBl8>6rL7gF+!c z$#$5+rN>q-l?D#LE>+rTZed=|1NSRJ^P_-N+VCfD<@p(LX{QLNG(?(O7a2tY!!=&3 z;?#`pBHf6&N||wsmX&`IgPmUVFa7Gs+)|*2-p>1US2+BH?_E|LC)X$hj|n(u?P@t2 z1SkCL4zm2f4UaGjhlc4pN%?5iOSbz}b$m4YB5?Bs(M|lAKJ``X?(VASL1kS1Pz<-D z6U+I`p8PHC!@O#mW|RmQmVtY?cKJAmsf~kWgi?EbeIEjLunzmWjzDxr>3FVK=?1Tz3A?faPz1}jwSs0 z5?)JAco6i67>B{WpnmbUJF(6IR_ewZ#kmAs;C>(ZISV$0pgC697`e4_h=1qTm1(W4 zo^+CKK-KcmDo#yJWBYSkBjaFEygZQxXGT>nu`h#z)@{WiFV=fxqM#?0I8_JPg)lJ4 zBV&Iq-@;x_FhcxgXlNp-ClJ#kEOzKX+3F&xW1S7PNklAUv=H4lub>v(l8@~)Jn?6h z_6!*XnIOcj8hPVfdb)KEAjv z!goUleZYvxz3H)tTHSP?3|4Sw@&%CMoNeGP;6 z3bE0y5#X|i;+TR(M^`kAH41mSJ6WUFY_v)mD*1Y!BQEUvGaQ3KDkq0%RsfLFG^jsk zH#G?}*46;x6O_S`kvRjN6`s6I20VQBtWJ5+CI+1bW*9MH^nwkXrVaql7+B)cQc|`W zY5s8rI+|1aGF-bP5fODLg;f#C8(5CNWYyigzKEi~#n)4eJk-AS#%7q!`1H#R4h_lc z#T5n>UP~U4e}^KGP*W>Pw2_s|xdhwp^eTS3d33=(4chkd@-#Y_5SUu006)yLd>T&v z2|qMCFcKf1Zkm*?pr}b|jm8$C9FD`F1<4&uy7Ab8HLVx)i1p6_5ibl6S}nV(X>d48 z=KwPU_;%_e2f2@i2OCpvY$f^73DbxqMbiX+oPJI9m1+>aU|?V*KvArEje>?|{w1H- z34r7CnbqzvMy+|^Rak@NI*$InpM=Q@R_zrDd^uj5h*^w~R3cf*bu~m2Xc!8GPa2~(csM_ac16=eC5L*t+3^HgYC;)HyC4O`U^Ely-n1PW zg$%#53O^Jr|A5mp`lbNH66b(fu;m^UO2UIi{ay3&*5(xWNQOZ!7tDULfdD%L3ZPs3 z&tXFMw=;VAIp(zG*U)11ZA42;folD&Njyq~YMq*{RlNWEZCBIM^t2FN$G4U?t|ww# zz5=5>&2deW&upc&#Zk>!2FG)TZdc{%fBI9LZVsKoeT?g9yXIvpI*t@L&K7bVrK~+@ zrZ9Z&2lp9W&gT2BSmtWgumnjbV>a!tr00hSKlibOJFVtdRf%VK??EnR#t^=2Z5#Pt zE~Q2B&DwoI>+b368My4nqkVnFvodewyQ^nzkr6W@IEzh4pgs4wFCKX^f6X-WrMbCj z#OUnlyG>ZO?vUvV$2FoYt>Ar&c3SChJpACcU4BR6^yVGmFvC_X(iTzuc-fCjtg7u6 z(q}Xw*3iE^x4a@nINIWby)*mPPMgX`I^WNZ^#~4@8(j6JdGnEacYv7u@L_356xYuC zSN$fZ{YT0CmKuM2w7=_^w7tDQe>Bl!?7EDkr3`O|rFuv@Z+5upR9kn+x#Y!jLmjrX zjsv4FA|g`Ul@Gk)2%yX80P4ra#ZAp9fN`Xbono1kts$s2KrFz_79et!R9>oeBH2Ct zXMZg)sQRz#p(ubkF=(p|By}ouJqo7du^+Dq+@a*pFe3dsVE?ZA4+xjWg7gY^) z9&K*6YhyveL#?T;;Scs4VF2!!ucM<^je>$=`o(TGB?7sqayBf$whi-yhJtF&Q2{BN zP(xH&J3=@xNd36M;+$8#Z3n$x<@S!{2o0HpP~f#Cl!mQS4!`kqfzoJq*M3AkPU%^H zjo0-2`kH33lTTm)w((KBs?)UORcjt}SCG-gCS!1vE^3 z;q~=5IYGfya)Cj^v-2r#;l{L zt;H{52m%W1FmrFUCN=GE_%Hij<#dLO>5eLuI@B)fchLnb@Guvus+z$`1h0eC6ml-} z`?{X9rt93vyr(o)#}!^a!LC?NwXXKkc>i3@o*P%@F*5y%cH6njyuvUQcM)^qNVH`a z12y;KUSjmCiEJUG?Y;;F6%{g|9zKrlf;^*rZwnB7R58!CR7JwVA<-iwj8#>mNM7V% zJWqw3;-i##BquY+!h;ASfPYZDpTtl@f9o(${~$x~1(VIZiG-ANVWyowUEBWS2cz}Z zPZCE-n;>K5m3*Rd0Goub`kowz%kq6>x3%E#z;ygHOqV>LC@E|IW;-HekP?7gY2lVZl$Z zHM@bRvAhAZ73>}(R^4`W7IgHXcVoB=>x~?~^%bItX zG|!u(AMA$@Ko32QWIvNh`WgILX#kX5HQ0mmqm~E2O3vXE#TFI8G+(w*8;u;uKWZFx zy!^Q>Loghy*;PN0x%-~Ra&wKQ_#yj+iIH)4^^OZJnW{#HKg99LURvVv{s7HZ7O@TkrtNkLa{k)v_b63+*12W$R56%O217)%I^*KGO?O zM*)yulC&KC(mcl0Zw~W5hV24sAD1SI;D0aEx3u)2Mn?zSmfSMDC}^7{I{HE$n;&>i zion}3hVmrh3=gOBTZYWfR+{aB9uh!V^QR8I_u<~{T7hUV6Z|VvQ%9AzzWk$yKnNcQZiD)Zvf%Jqi3J70~R8!nfOCBnlJg%B_cOPfG?xSBcKuyp+|j4!%gu`bM( zXz@f>b90FRSDhmz6=iJ)GBOSYIUe8QBNv!8OcvqBkDs5*vh?t^6g8=Pjf^6`mY3F= zf>4sMt1ahKYBaWS(~=LEUJ-tWT4;BMIE_rIb3iWp0lDVgSohhV|ueMY5BPn zD!Ib5V)Q$pdW*{=GCnb>6g#9DhJ@k^zqTgGP**jEkiq2#eP~yu5>gs!qzRDSQb+J$2K$Va~M$u z*-~~AAw9yP684iaPG$`K>o=()cYzM0GfXm*@n214YiWAqMd9%a%#vdp&!cN%6$S@K zY0k8#c8pOU6!=Qw}W*KdAM25~$f+%~#>!j}|*d^C_v zJ*#YiUlIEYRi?mAEkZMIIjfqe667kyC1y|%*78Dq*N@}n}6`zU%DjJ$ZhrEiJdU1t#X<1p!A3%yqOR22+%_S^-R!&WOH>)4Xb7+)) z>gvhW!wj3V#X8sqXYC`N^$~~x!f2(n-Sjt%e*x}1=;rUt?W?nHm0+MEP^){+$q_`& zjaO9}V!QH*-q|@#SsHNHG2qrxQK{HMLlsjyief_VjK?;(4IiOd%uFO)49Fo|`aT;9YKq?)WhB8zqd!*TKePmBDNTtW4e`ri(2s>OjeCWMw2?rzB-{%Lp_=&``tR4f23sORI}|r3R1H>e z&#&s`blz=u=kI8?#82m&&_@dMXs3og39>p3Uj9H6IL>pYh1$ShRpWML{4NrC7n{f4 z-@5|ZL9;zx|CKdJNXVllfJ#)$&LfI}+7wsaalE~{izECFeFWuvvO=25N-n8q7ZRVC zIEe3K8ND6Jp#{#ahWX=>P_E8w_!ey$RUcXN;bVo-@NGKavJgehYie!{3G(o=g)!Pf zBEn)im`AI#W>MCNB({^JCOvp)=jM5^{x8Ychl1kj=x~ItJu^Y@%@;9OM`_CaDEl#< z#R-lspZ5HGZ_ipfs#fm`ZL!L%cJ<{;LoYigJ-KQxI?$j!QmZipVE*n+qY{Qfsez+Q z1Peii9|J>=AY$+}GmU6E6;+8LP$uurvaQ9`OieuolAOWaxUe1TZchxNNr!nwgEhNx z&9~OLy0#R1MCNDPXq-B*A>^*p_VK8Z`jlxGrnd9mUR|olBWu|V4^z(w{18O{C#nnx z{5VbHg64)sL}_B~3~9Z3PEQ|}d~|g+m4oriiGOAjWh)|p3;}guPko?uiKFLRAn1LRZJ zASpY$nonhUX#zlI4i6=i_V)K{0+I_-iY{4j#|*rTEh}zvCzvx*NogmM)+xqj>^Hg0 zp_CHmdbr4PJzGGS`5zXuC5=jPV{6fi5Hmam7@nh~rl2EF*jb?g5aGPKiZgZGV-+#a z&tSOy?j9cXEqr}D7);yT24e6@7Zcz5w`Vli6CsY+vHHu_t0XeqAKj!$!21$p&if!s)6--Ssr{BpAp zz)W3wMq}&no&YE0R@uz3BG52AOGTI4`))Ew+B|@|x@8`AY5I2%jN> z8_pN<&HQqRh)H?r`ZhaE<6d7r8_lM`$rXwx*p&qpw%$LuN*GH=KtMwc1YG8(^RlIV zYdBrW|BdUTi_c-WVj6OYJ!^_z=DSqOChhR8(FqmBUlMWH&~P6}w9?&F4SQgCD4NRJ z`CHf!GOZp?1ph_^=P$3{TZG4``UgfN>83=O$ren+zJ|U}pbleR&KfHatY^JBbj9ZC7%Qlb)z9TgqSMaa z!U^`3;oB8%-r4$?7c~h_CjQVy>(*+y+);&xHK4SKZs}eE-uIRp z7C7P>)@YX@+P}PpZH!B6TUw3=z|mxmZBL*oSupo`K0MoA@e(imdj(+#(?hURyXer+ z6Q_|>(Zu>2O4}YmRPePWlr&WKYWn;&hszt+sKoHx@`Qzj#pUFp3n&B;p-bzkHcfyc zK)W6V8=D%C7d5Q_oqT)1PgY_e8L{Vb8-0E4==O3mKYQ5Air}b8Nll+Ld(3KXo^7@4 zT$l1%R0p&=ofSYMgCL-wOI%4hiw25R6T1z3}@er^OQ zix!HsljLea)+cxa(S^f8#n_jYmTYXr_xJC7>ySyL(WC@MgzvVd{JnGTAo)hSkHMF2 zVrb5e5aHx6FJ3z%OfnVtxmerNi};@U;a*I=(-^6##ZIH~!bKL=IvFFc7oXK@t=p@u z~0Wf>^P(OLxP%g%txB2PUR^jh9KNYm-NCV`b73O>X(tQ(tgU zP+@#x{LqgG&HS=5JMD=`K>zn=m+j-u6@4e*UutAAx3N^Snw_!6sGwbLEIjzod(-~{To_6ny><{S)R!E%$OCN?wdGyscpzH~>fy}o#K73Vg zvaODMv*Q+~7#!r<>5kev(#PwOheE*1`WS}OT$tqpy#2aofu5N}?djWQPUfyj?n!8< zy@f`8TAJ2_{@T3#!z|lixyu^0uIGbvsaetA)*EnWP#x|Q@l*=GqZLpbNuNuFiFmfP zUst!434RyMpc{LDOF|3Qtm2SVQi?Ai^>_FPL5OI}PjLzO9VD%-E7Ab{J`hHI#R1}8 zAT~KU*RPr7nAI%HcqceJB^HJ-6AL2HId5QYCmjpI|He+=v#kD;&vqJk?3R((5T3;F zNPMrPifIYaNzkn9)ASUeH!P?62K(V6X<)#X2fnn}^Tmslnq2m_&}6WLZw`AOx2%#d ztKNMTN{Lf8c=4&2ZpH*WN(Xw*nIberS4_5TC&zE4T6A# z{Ho9yz=v?=t7$8s7xUcot(dbv;78yB)xr@RjzCZBWDCrsvO8>xTNy?7<)_Vk}WRH*#-t{yHPUV{GLcS4iV2TN_* z48l9FA{ex5R=oGucm1yli%r1{=74G2!%4d1^Ou~$=-JtX_G@*;$S4>GRa%OsNQf8& z`%+I~Z7*j*R1<(lQ#VerkYqRjc02sfkkRhY`fefV|KsW`doZQ@E>B_1< zlq@tKTCN{xPV6tEO>-=(9jbS4){c(oB=6TKL8W$--@(z0djeX;sx9w(`pZbg45o*o){J#A$+k zyjLRd)RM-=&4^utQjw>`>UevW4(HHccjr>xg`JFW7=mP9Z{Tzoa##s;;`bEO5_A=) zwWRN%-9qK29?e<@r8W;^v9_L-|Lk$7DW9kCgEZ+S&^HQN8(%ley1^3vzD5_=m%G0| zP$&KF42>eYP&hWNV2O=s;pOzb0evUb`gTM#DgBlUN8|QDO8+ zn)*9KvAk|!>w8NFOAY=p$xP2(Y{`LMIU9^LLxH3}g@Y;gG4f1d-JHO5!?t+Zrx+Pm zch&N1!CbSkpg~bf^gk=1?AYk_b%Sg%7J_n#ppVq_;{Kw%<;y`C_ zwLOH`w!4f|k(29m(f>Y~VH&}&5;6A)pl#uAVV~Bb%kbdcn4>cS!CThpYTEFbnoNkF zP2&kZFad1I3MdBRuiI8>5#gDJ8z|N!zz+nx)BZjDDC>D| zQGLd-8##h}A*9_CPEhzW=3B1>&OjX{w=ru_S!S6{si=dVP})xn$ii7fNCFLso80H- zOP}J!@#+jW_uKZe{D8vZ@Cp0 zgg=E^&RSSg6SPMszr^^)!Ft{h6C_|J?9)ePI2|Si zIxO@LPCM(P;!RD>KNulpD+|`|eEdSrlfcD!Vfy>~wWflsC3ePvH8HY;fh%Wj3eKU6 z0uKPT_j4>cYtF^Fa8SWmBYc%a2BO{o1}w;YLD3vsFXb*CoaJX7@^g z`L_1!%J74rJ8UWQkXCAr8{$EFC5zbI{XG?PVe6u2^>pd=wM*r8K>#Ke)=P0>hxmbI zuWvoTM_@2rs-1H2ed*J*_RpU`&(a{+F^32?yG>2J+RyO9;WSoP&9O0XY6mm;G(n?C z8c-Zx^ThjW-n|(gA9tvr_74~x9gR3l3=e-!%g8u2t#P~XbBpl;1r=49oJOH{6(ci< z;aAMcADB!6PBiG3ZeK~}YpoKCi;DwW3p^;_zEu#=q@bwljRIT9jtRckJX3e3_49)_ zO$n|xA=hd~e;Q|8T87%~h7MmIxXbR}Eo6urdDUDt=4_?8{JL<{3W9x|26fba#DE~s zNJggbPL7TS1Wm0zcKC2l&kDZZ*(aM`yAy>e3C5rW1b46C`#f@yz`ET1&Z|1KFBoId zkp&FS7bo!__4mw$=jA#64w%3Z6rFmpGJ=`Y`wdi9TE<$wsit@^?cJTb;f&lovvYdG z@JHY3Jbg{9*fu^`LIv3QgvD4XL_Hmx-756{J3D(U%$ZzUx*g=F6fo>jo&D)L>- z=*Py!j_sd=1CI*;ZftgA43qPj5BEOXl6*)1g=uEWq93 zaRMyA{cO`(FP{vqWmkkgm)f$jk)eaa!on#?xTD?6p0_2)T4V{^4A6MN8o!4#nSe{R z7`Vlm-g?~FUxRJ9M}eL9sK=aJ<4WbdRFY0)ZD1FU`jjW~RRONKeHRmA9A|o&N(HmI{85uc`l2sH&jSucQ{^!A@EI;<* zQUYKjOmjc&YZ~~^KIl&rjg5^fB`+T$Yx#-y(9}jse92(n#z;%ob%RJ;B>)jQC+?QTXvki&9)k5On9vmkShl}_R&t9^?%-a~ z0&HBm*I%u4hiFWb2(ThgdtXNNqA)dm^e8PvgoDQWfzzoBEdAws27#B{7c6345P7J& zmNo{&GC;oQI;?O;yIr@U81frN(LBC;awq}klhVoaAsjrsf-w5kI=HQ5U;&hu1s+Q=VrYp1|EF7(RU<^a_sW(coQO-mlO#W*M^NYc?U(!k)eRIBHS zDbIqU_m=}PJnhcLe+0o^C{!&pAWu4EKVP?IaX=%_wQGmHwy0gq&&GiOIR#J0IqUAc z%uBfkBUpFI?T8P!0Gxm+_&W$7xdBw75BtxMv56OfvB`_c`8+m12~? z#LfLtNi!p&kp(aj68u*yFgVEMzn_D-utEBG71R(sZ)T?`aRyuh{l0K0XIfVa<(t4p zBM0@OlL68O)|x{R=T=K#a)RSlYYQ391^^1dcacPW_Qp@2-EeM|7)_0?-YZKRDC|1> zhlsiLH`-dl;Y<$!Z~?KpO1Z*`y@&JrZ$mH73 z^mHLLA3Jidj#oQ2ffSqwEL;l>=oun&*ws|G1>Ogy))_pXB7H6mHYH7_g6TPH_;qb=sDuuG{qsHC-> zbHSOJbnma9eqdB}uemp$Z((v_r+G*-fx6YP-cAuN)IiSZmV-+E&Zi1fOG&ySjG^vP zmgj(VQA2MuTkMAOW81Uq0o{jeftQn5u(S+Ncv--?q2v|lHpbjT^k-|?DaRAiBNXp{ z`}hQBD#-MlySWL*c&VfW12qWleIh|z%9MQ_={ycEm%XN!V`^T3BEbOIMYv8bu%S&mio4|ykJJDUwlV@L zrzON<+&Lo#QQ`+bQ)KR0L!+8;1;xR)?<==Whi*o><{ zNwleEHsd#%esRLJ7HAU_lT#4p>|T?p5wLugW{G(&O8gD$P$Uig5_zqO6XE7NKx!bI zxjA)(;<$QPYx&~CMoL+WRnS=51Rk|MF6}P8HSEXcIvWv5=f42N5IF?gvugmNsMeJp z$!vYNDSB{U3!&);->i9UI5-?=Et7(T(E(=KQ<2Yxci>urtS@xp(p~9W_!@kPpa2z# zQf5S18JWZf$&lCX{~nJeZVSJCd(%Bjpl9P0cN`7TRvJ^Eks1(`Q1!coJi7XZqhR$z z{68wVoo@6+q~YyDo&0o|)-KoyA@lZDYj=F>27-@M;0aV*^1QWZ?0K2qpYF6&7 zW^lVsN6nYJqMnLmKift5E^1|(VKI81hyWB2&MCnK8-S|d;2~MVf;lhAJ3+JjgO^FV&i}ET?(~2P+`ce*V)CMh~L-c{rn_N098PZGefc2(KPWC(;Mr z6aOWe78zVb;j=$rTkdZK-|y!wB39$*C!p0XnZKu>K14yk{R`~D14#O)U3PJO;5%2k zC-_O3`^)sTwU0CW<*Kr(_T+vQsqYIdl*4Nn97I2|F`qaTf8916U2d38O-QkjbAV^v z8mQXl$33DQZ-!grsN)3)92EAmVVfReqh=awS(bGCLjuJ4k*L4ct4;^Gm9g`)q)m;_ z-znI_tguEM1TQuu*yOVh%SXXVzUz_ z%0}gU^#i_>9^@F)kmXXi)7uJH$E295krh|u^zwiE(7|YNST6uVo#E=wfCztP>LmK0 zI_T#_oN|kwRup1lVzLZ*!M67z$8Q9#%>kZ~6vFZZ)VPd_jGXH8;+<=#Z7bQR9AJ#g z^mtBx&u*B(mCf%z)MhcCm814H99u972SYp_By2fIj zdMnebMRsg`4n(UHNN^5*w}{kd@}#_0H6NV3T?GxGF_698B6g;r#R(^Hz-z9i*KU~5 z(EXDEWo?nn@6m7p=g;TtuLgDCz1O^z;imM%8elm}v&IYU^PbD;#0^3-@xsb$wwyr6$-tbA`SAM9GJTrnWF7-O3qEdCs4nokE|XaxCg)@OZgNVT&x2V96hKHbh=?N0Orw~3|}`CSnZm%H_xU?pE*&UG2K`l z%vJA(`VW()VR>+wj8TF>XGSPa_^<8RF-uVjZ@rs(yM}OaVa}~-0RH~!CowS&t&UDc ztkv`HmxuFAlap-wRR6r#+z2J%g-RM_U`=C1wN?`41eSGs@}zz7T|Dmz!AJ$H*_<6w zZdl|ej!&p2*&EJPe=JrD$XLfmzX4dH7tj2$BFEyNah7R$-Jie4Z?6Ci!IXvIVW}YU zZPj@V4H}nxd&O1uq=;{y!D3k(wc92A5ZH(oIdci#A#-dK-Z-qEdK?(!g}Aelh__>*KBSqPo_vK=^Oo%U>M zmt4(i&v=O3$R>nHg*i`wOHp&r|Dkck7v)F9@vR6t-$wZ|xq){o$_>J8b}N~=Pa~Qr zYkpA>(%c|+ZJP_Mg=K~l@P_YRjVTd9k)?T;BY8mkJa20@T_Uw=K2KPL3;uoH4%f{) z-2a76+28-3+}T%u*aulur3QGdgp@N&D-wqIDr6MT=Cl7I3TY;3|yDASdYUpot zonopwE_t5(f@yx9U3`w9wx%E0q4R0S=Jtd|!1RiiEqG~nPMo|)L+lNmm~jrjTf+eb zKkIS(4w$GjVpCPg+%67T;QJ=`asGK}os#|i1BTP39tvto#YJa1IWM~w{eIW`+fzZF zCH;IB%t;1q!UQ1{l<8`-8zv{x&GSqQ9 zU@NkQ2PNaeaGY24eyIcCaQK24X7st}3z@xH;;#p*88A@DqSTN-g61DVu3Faxz&uKZ zg&-3@N}#mZM`%9qUmN6XJpxSE6Zk`~*)mrc8los<4NFET{5l(Wb$eWiU{##a)`AiQ zACnJ^^J{HjwS+)_WjF^)WAxAOyw+Z477CDY*5xrGw8`NeLn;WdGMwhjB_G$F4fVe`URsY!%JuRkbqE7!_64 zc@cqO#l+Od@G6#=#|faf$kyJo{QKOQt%Z7j4JRJZy5-j8ir(G3=UGX|Gg9wNJoDA` zP%Eg(SLr!isB_o~y!4SB650RA#i`e7J?;Gl7Hbm1Ipg+$hLZA|8I0fy!eH4H-w-P| zG)%}^65}gKjG&x;n1%F^j=Lo&?c61Svgrbcr4kQsNqa=Ta-jvk5D!j2L0D+j*!)cG zkAVM^f>}Td2^5_1v+JPklwXX_?;*MF-lCWr8LhF~k}WY37eXelOM1pRD4oGOI|u(e z&|VB61M{m(Vz|H2N*vh(LZaR)F4OfGo+Ri7#jAD%NSmIf4I^=FsiEsEhlhfNmJ9(inG~P zdYij+NJ)X+`SmxSkzD|hn!Y8Bl!b6XaXt=a3S{a&nVO?v{PO?&!LB)bQx_i0`au7BnLszz*Y zur;xW(}gdFbb|_;w4PhNTZM?kWee#_f`WP;BX<5vF{jB6?B`z@EiDgpmyM7)KrMx) zv;!-M{rK>f!ak>D<7-A`u6adXC5Y!`ST62n_v=50jkj=8xfR{h>(!a!yRCe^@HSMfiUSG7W`=x z8_Z6G-w%0tc?X9ycBH&1n=2&Nu%gn|7u&&Y?fWl-^Y(pO*t@Wa>$lM1M}{OwKR48Z zAaba1eI!$&>l}R9)!R#B@uNB71CI}v0tCFy);U{NjR)*}4}fVG1FA)?!8x4m{_mov z9egEvA~pL4;pcv=W&9qL{Os@ER@&y0waQ)O=SzBi$`XC|F1WR<%-OlFiss+vYWijt z^iWSuo&_bipTqO`s3=+0es=sUj>JuWK~}D2AM@T&EPzq& zEa9z@4u{-Ev9$!TpD~NLF)I>(ihWUNr2)NTLB{BlgOEnr0A1x-CyOZ70w53X%5u<0 zIFgEcw%``TSKeYlAR|=g9WH>Tp>#ZP=Gk^6QM-E&ecpE8h0zW)UQ*JdSau6ZV{Cl?km@L6DGDHZS$Sb+N#mH{&V#MF`|76W&FW`5ii>9+#|i>xK_hiM!Ci~!~b;FFx3 zpRmKX)_3C_E9f65QnYt}Wu>QAx^wrihaCKVr%L_LI?!y;q@_tW$;Q@wRVQj|YX?jW zYUvtx_ji=MywZ2~9uXc5)YO3?liuEfIcRX)>YxJ$9e=l4ItAX?mlYrV{{CYpdGO&by#YDzgM=t0IS%)^5T|D&3C zMEsfTQ{$?L3vor}U>6x)zV3zFiuln>p5v4!Hhn+ZbE4JP}7~ECX&&Pay zp~KtjTMf20Uiei&Yo{j|@ls?u%UOSgy+H^zB1O01fVaa9BZOo6=e&&e;>{{tJ2DB~ z>(>#?Hd)N(4@Su|PFz>?tTHC@R7#Z3QLT>9#T#)IBl?cuhxT06kNn zSW&l+YYbt|Dmj3vkd!KP(^5xg2^a>2vl~GC*^S-fctrD#kH;?Yo297%ZMT(=7{=-a zzg|4SOl}FX0ETpZPNbO~~BF3(@E}+1C!N4qOZ9zAV7A+N${UM00!E zMo*!h!!hQH4XzNK1_i+*Na_e>VdLOPi5cdB+*W@}%5zY=_ZI$`f6e0g=jNuH?L;^9 zOV{>)X<@b>BmDNXHCEuC$)j}AcjXx>sOw~5CGO6w9hIR7gMw~{_8{&o$GB7*W3{^Y z7w7Z!b_KHK-Q8Wgp*EZioVLnjoj4QUQsrZ04?pMTNl6%gvw7^2vX%%Atm^*E^Zs159x#X5w1cL{0uZk zMDi3YGjr3WRsb!TQ1gBs2f>?<-l0;*OFe9$5WOZD0)G#RIH+mq=oDAcBW-Yg*N?!L z=9}=;iUM$fbkZB4MGnvFO}yC({h-CY!QNgu8XUwJG6P%6L7RlSI!-Rouub{Se?rL` zjq7&5itxbi5>XV-+Que7lN`Te8Gp?2sYOPn=S^YDaExBBx{b2pWx}{DPsyYkjNaP? zySn9;ha0nd_ljw&fkdY1+m1W;C-o7LoDrX{94WX;_iQn|T?n}4eq;5lJV!nstF%Sc z0OlG=9SfgBRaK)HjrGic1b}J%d#ONsvrCU_(;64TNN0bLM^9w@KvZBt*gGD;^WcAnvrs_}bLpEGHykwSbZZNVm81kcIt&h(Do$yC~ z=#K1)u`LLhzP*H5P_+a*0gm)vQCbR;D8f?#p*X3BQWqQ~;8zlJ$LmtT?=Oj9pimTu zo572*9pc(jQ^XOPIRP~<0|1gy(AvS*`GxT{q~NQpb?-I!Qa1shWD?04t4`@jIelGx zwc>}q@hvA(;Sx#F!0&1ioTDiKA0^-+Qc32iS;+vun{@j~C=T5Z20+@?c0GV>&fF4J zIYbKS!okCva_81AduqbT)GpYDHC@b^VGks?m5PP`4VmAb@hdG zVW5W3+4T&gj6Y*-bDe>IX^Gn=u%suC;LR?p^$1x=WJpZ-8Ed+6cW1fWiZJ(e^V;4P z&8JVRm^e6jarb;e3wqG2?Y}sd>6u!tvKunnKCM2<$xpfpoEaoS5dZXds+C5Rj~xtk zp$v#tHlH}=PbzM}+baS~CP+OQaX)y=xram_d!xypYW3M&%%*1VXJJ6t`2C(G`YQ#M1|dr$q)xYPHCp7Ur~>Gy3q53>1bX%CwPzEf(gL}c>0Q~E1SH_lYR`4E zopbKO=_r_X3_{jEAnv~O0s^8^9W3)0IDv0~avIejG$Iav2piLB5ay2wmukNm|%4>?+Q3yGDL-k zlPIql2J{^tjlF{WTS5ABki;n}UjqW4k}4@;Byd?ze?^mU3E+1FnVJ2B5HoKW)HLfA zL7368Bxd~yVpwRrc*7bmDT=p$*n&;as0YoQ?6tS;5VhJ?+WnNB*XU~w86dS<_M>95 zq$u+9Pp9;H018%KfK8+_uMuSR8-{BVklFg%!9B+O%9@-J>GKT#Kl6+{*R6YtPdivd zLKWKP84(Wkhm2yZQAqvAN+LbjVB2GEe+o!s+esHj(pd(lO*XeLy>3g>sG0Sw_ty?~ zwh$y(Dsax7wi6W>pJ(79Cl|W(Aq3bP>740k(`}HCn8fC_P7z9%*}~N%(-FG2CI$j; zB|kbj{4T;Lv2pzsG(R)o*iZsoNx>$lRrF2{0N60T;3lFas}pMcs?D5yRBRWR^WY2f zd@hHL?4#)}wjcLT8Tg<0!Cyvn@@LQw;A1dhrDWP|IJdl^V3g|g(Q|X#`5|(wiwKdV z5CU>IYz1|paQ_xU04~iy&m4GC&JN9n*$`+Q$eMogA={t|RU4N}iTl=x->ngQX#8wIitN ziIpUbSRc%(_3c%A*1nW4(U4tchx!Bm^j7Ps)#xzQz4n~bRuxx9&t+uZ9m8X2HL=0c za_3n%{cnT6_sOS8sc;w_a<#ERNv~b021lZ*?J&7~p}D3lBJ3PuEh0(?4)znnTVcW2 zLz_G6%RhfBZz;$u3xot)J{&>>C`yAvLgYXBJDbCO_z#%DZw+H-ZV}H8HX{LBnLa$?%R{t7C;47YvWd=)(?kLizCnTIe zE2#2v1_Z;&#_$NRk(q8&W7JAWZtOVZ=3HKcd!f8F^h$NaTB>_6ecUu#qE^=ONS z+c~WLS|`#In(wB}pDMOoAqbtc`f!ca)j{vID5hB&{kZ5RwG)PIjxi#xbZ>}%a$Pj@3W(C%Opqs z9v(mRz`uuOJ9=__x+d~!>*;T8?Ch8yowoe`4jKQtz$TiykV#)3bLMIBt})yBo$hK1tASft}hea=l||9UQ32Zz;;r?LI_OS)FAP&-{&+YgWa`V90V zfI`Fm2Q0>jhK44X(UtA%`ZTit`PR$g5@{Ga{(Owd`{IJj|L)O4ok;UKR z--!J)JPFDF@298x2A2PMuhFqz|K~UUy^hw{|Nhm#cgtwD z64`npX+9p@{0jacvC%=6i->^Uqqi8yAR#HU*+I5tV08v%9=wo`b?qO`qDGHvzFdJf z?{t{=Ed0MNW&Qi*(>Kt&84k2rEv>Y3U15n&KporcXm9sH_lqZQm(5-eGgAXxqPpZ)U;!9S?a{S-`Ls}6XTej-8oG11Z9AVuS^ zT-F`**8?GEK7o}@lMwC-eQ3DXToqOLklEe05!c(_FP!)O%gXxtuSC1#n2Zb`P{b24 zxBB~cx7?>(CHe$j@VwL>-w<>!ZX}NFGFJSFBIU_H*L2X|;^C>9my&RyVqidZyL|U@ zT2H7Xg>7YTujAMva>JRM=P$LRrsNiG+Q9vS?_ek@D>! z1qDH&jLl6=4=t>}H&^$V*Fn&!e*z%AYlSo1Ou8YX>(msk%brblKNYv9 zFI7Hg4?OGpV`I}(Zu9{=8=XX0ClW4F77Y;o15x|T&Z8u&yii@pA zSF93C6aU`W@ZX*M{#B(UMZ*XeyFAw@cYRYe$n3Fud;lw_^#;HCmyQ2jV(;K!CrMn- zpHq6OLnpg0{7p>I(61lOD5k=MEG-!m=(Qtjmv8Y84?!16XQoTJ7&jM-zMVs_0ce!UGPe$yzSUX$NuA) zwol?kStdc^{PCFVYmBo$q~(7!N3h;M0vBfEuFI`rW%y=D!D|z$qxb9sKK?n_WuZ zLDpWfxaT)k^Yw&0fvsVd+GSn$en%=%jGM^-exv23ji)^e>g$OEUxAI$R^Hmy-aoM* z$VAmcNeOr^Re<#?{|ap|8i_rNCN2-}p#{w&ruUYp#hh z-JX^YrAPK5(raOtoM5-Yfq_CB6ikGQD;VtDFkw;tNQ8-5Oag7F+(JczXVVjD)|*|{ zdOs8&AgynQRvD(Yaf>c+jS1LRU2N&4o#m<-V!;(#jQ$7nPI?~loxKhcBP*dfiW1-kbEmED+mfG6Hoq?@g*n-xx)ffa5`EeGO=y-R`Q3SNr#Y=&A zJr@VZy^rvOJTJFnn=<`7MS1_+74`NH2{$)5oGfx=&RhbL+Ek z?|8z_d}{{=kD1BO*S|H2Km90Kx86_?G)Em569S=0`u;#)#dhN@2V``)P_e-JbVCw{ zEfhiS2pQ*L63pbk-sYVm*hQoZel=h!a4$2Yu!%i-)>5$W4A{>QRk$7LfY?TB(Kl>n zGpcIG!?fn(EPC;MbJJBAFT}RJp^|)v0CBBDvK(*mGHE zrbpdkAyQPuDVLXjI#7oBTy%CYH#E|&z@o2!o6Eq1>4ZJ+xG&o1s2V@x*-6Y7c+i+_ z52>anhkYyUX3(dby!Cl5H`f2PZ8~yB#_`ETpsv_sRZZ$HRQp}c!Q9yIKG+KBSLrAf zD4j52l=B@OInp~HShhGf1PF2F;z!?+J)(kTaW=o-Rf#YMG3{ z9Tua#7NofRwNMp?(R>*?vx2TJxTUw&N7_(0GA)k3hHI(F*}raV@#;rq{Bp#OB3%OI zcDK%Zx!#D)Ow>kWpQ@|GdPVw&D%MYCD%_&@#dUQ_&vrbpT+esGbixU@$Ot&1k^Q;g zf}$kN`MWX1*iMWNRh^ReenKCQk565FHa~K3^elKQ%Zu&@A^F&nMl*pr%?Q=Tp|;b7 zNQU2;7qQLp$ftu2Qci5Yag&0I!{G=CDX9(~t7g~HKP6|kdAy+?l@CHFYP|jNs{-Y1 zUsW?YI@$z86$VvRR$<_))z3TtboW}=F#jtN!Z@F%yB*_`VAZJ+X$r=np+1${&U@aW zmmB82YD$3>ZWl)arkC6*#djMT_ILfu%cNgkhpbF1_ssVOOvflphX{5hebf+7AFdx8 zBIUM6L_#|0es|6>T^=uYscr$~Vg;JQk}2)n_4v<`I>Qm`&ou?wMNr*E!E1aEe$|Bj*a#%(q}3i zcvA4JiRl4#MgPNujy5VC1s;Jp)(2XK6b|LYqsr{Icc!~0clDog9zIXL&T`%FmWknf z;iQDn@`BCOzdM4kZM*}9$LV0|OEu7d=R)Gn*i07W5TKALie}J=xWhf%axe(pL`4|t zla`AW3)pujOG->C$bFOV5ztJp;MEP6zZ;_5KTH&2o6q29#RX1&5Bz>*B+~i0v#V?8 zG+ZujYU=k4XhQV)iJ!G)tjTbEdL}H|iMxN~4ypb_ql5BPnr_Z!VcIT7Pi1pDK`VMN zTf}%bPPq^W12Lb=PWYAjve;Gm_N&W&%*&Z7qf8SPEc>7Qn;W#_kru)~LqwI3kc0rY z_CDn;#_zTLP=9~XaZi%53%*}JhH>uiMkandI_xD7LBA_)?#R_2Uh-e6d z9!I^)kVUzX7A%u$v$FC@#!Ny2GWWwWptzU_S)A!*XFgAIY&I6EcB4)N!cl9%$Svte zE0coaSoz0MOdPx|jbbdg(NP3eq9Ffo7%>v=dK6QS^%ziJ=&~%+HC_i}Y^1#uUn@7e zB*8H<`fONOLfZqK&DYg1UE*Jf2M)>x}hFoJ%00aF#? zQ6%F{@n7OfD7<5%mrWO6YthVG^yb!|5mMBekMq8|&Wi1G8zU_=yCJ}Ci1xxN6zS+l z%~r4KzBo!@H}Ow()hf$wClDB(;%(|Vi1Od*D(lAhmW>xdUq(>Hu4 zqL?+wwv6jY?cJUrJ}Bp-GSu9?Z_X#Fm3cE=j1d_4`!1U#&45UF*Rn#)z^kdk2Z)M3 zot;>(tz-VAuvz(jZ4>;=Xe(4#U!P?AgWz(>t`?aRIWh=IufZs(GTEfR9WZ4)=^n$)7Gc>bRD)8qpZD|UL^43As6<)Q{>5_gT+^j;FwU$JkmAq*U2 zXQcgwfuTi3WZd=9LpzMk?uI12R+BVB$L9y$c}6g9Q8hroL079Z57?RD+WVT|u;~W} z0w(8;toH4>%@?<#$j}jEqQEXlWi=Lx#lrpFNo#0oP#C9lfqG zGcx>~rBVIed2JM7B+ElHy*HEFfx6}DbFu6QEUZ%Zi9f76=PpXR@e9kjQa5 zxMLaxB!6t~eBI?G_z*$Jlm*ZL0<&`Lbgq_@P(vBpY){u^6S6v!5aj$#k2K$zG z&1Qoce+auh1dxzuWM^n%iKLe>F{EzUOODS*dY%BXI5SP`ciQ`NI00Y3KGQF{(Ho83 zOuF9Fs%zj(HuLnQjvy>-<}vIZc0FMJ&6CVpLw<3bxa=MT%5Bz7^%K$Dt_iB8@`whi z`5$drBZ5o$SJKI6ZJ*y_e72^RFvVg>x6UVJUHAH(xN=9V=tA5A(=oUM38acJCVoX+*vK z+RS86S;a+$IIVG`2j9MYOBqQniw|)`nQ?Iuz&wOsdvT~vU8d@PC)0f89%Y)K=PQqa zn!)XYT(!k8;#oXlqJYq6(|Ebha=%}zlzVzpzJ-FMl{<8Iw|AuUb>`ohviP*w4IH^BwBtNQxPK{FW*SM zj2ZC5Cfi}!XPft*>7KusEK(Mekb}H6#OWSgml%)`->4zJ(jQe=uwO?_iIhpDU_R{_ zwujJtwSDI6XV~?{4=n`{Lx_U(^-q>=GeM-aRQq9qtDdu?XIfJ=b(SaSb7rd-mCST^ zu*_?76RWW=M%?u@vXrR@u$WkwC!;jFtAC=zcSWDT6bjhM5Oh?eQAc`yavi>yJe^F9 zZ@)m7Khce;bnbe_PpSsOl0$S78XDaE>=r|5%bwyA*5#p4XD@J3^wuN4JF%EN>bQ); z5zp0%q&HNLmRb;6JQ`q?8LuhlsYI0PSw1%N@m1(eYFG?t1ageO5dkR^&KPUxg2C1} z>S4iOFD5aTvg=8h))Fv|+`ShYFDY1A)o2PkrNV=y*QGT?&5yf}FOTQwhF5oGRd>18 z2o7@Ob+>noO)lwFi-X^H%SN9a2{=o@RlYqLgqj_IVLDgZ__)viVesC<$8-AjH;D#( zCr{`G%{9HIPzsxgxp{e9cRp_(dv-ij@?D{3V?xDdv5s;Aqppw5It?Kq8$q?{q+H^O z-f&-M8KTJp>*hg^q$0CH?;~rj%)swo_Sqt(G%jl9Js{TJHcBO%@9B{e@!(3i+tKMv zjj6gW^(|mCh|Sc6b0b-5upN{HC$b{^);v^ zb|kJ|Rs0d-eLH!EA{tKN>!Lfp9DPXCRYp6{<8?U~)cq0O~IV#W(}-C+bs zt?c)v0+zn@QuY06w(Rs38<<$vI4x8(HR=`p=5G*pBen0Jy);M31pMlzx;p(?zt&^I zk*;p8cB|2Px(gFaxE)M)uD?jv$G809*QaaZImO~*C;N&i9C5Jrakq!wPIjR}e^+QT z{ZgRY|EP7eaNY|ZZ9zoZ^KZqw0EZp@hQc?#;aCFseAMLmyu*7Ck-)mIi4z(l7Sjn=Fw zy?+hBaLlfQm(C~k1tod}!VeT<-4fRjpRgHd&}maar~$c^s5q=EHZE2sgQvJ>IEh(g zJ_pnw8sm>?N!eJDO^vV`%@NiI{?Ii%k=5gwb}T;NrFCPMkG#`9)-ak^9b?7~+e~Zq zYB8w|%}F2174hszQ=PL4nf@L@$e!f763nO(XLPu2O?@{~UygiQyn{XbYKmX&U>cM4>N-&3MgVCW-tFQ7RJ!`q9#_4rG*~A~zEtjLA6ZNKm#@m4mwEeitFKZ=j&|MZ&O+)FC zHo7RO73iEIZk!;#j;YH*EYgudz)CatTH4u?TCGSE_lCooPs= zONpN~DB1ng{dDAhjuC2a>=c0Zc|f!;#lb7Zkq%SUY1i25k&<$$RNHN&WPr_hrkq5j z>>8B8QsOiW#ZnEFdv;J?Io}#1#`loAjm$*~QR~orI{l$*pY1TYD=_-qP-^_aK|G4E zv}ez%r6>z-zNQ%(>?4%lRf|-<9pKo~*1 zQRgEf$gqsx&fcxST&|@Ql?;E}uR}^=w@W}q?%nipHbAnPf<-_l_AN-H!DZ4ebrFT7 zJ(#aiDWiQWM1V<@8<)&}*z87T*}VC=>8*KPU?g_?01CD4?QJ?nu!QG%*>=GepYt-A zmYWRCy^gT)dlv~={*W(b(^*bOsrILiV|jGP=SfF4D{bV}90*IZt>t3Ibab;^ zM(O2!13WB!WSeSDo(7){^#oh_>rT4&&fQLC&JNvjAcp-);T3stAE*^qY|%P9L_8Fy zL7&WbG#gzVL%FmpXN@%_npyHWt}ob?s55v`&X};%1#JaOT@Gt5XG*mR7eh~Xww8BA zYtK|~mgWeRi&Q3$x{5mc+00@rZeGMPWfI)HN@1%G^ua*KS@%rJ&HC5Q@ObrP5UU-o^DS1_8s46BnJITPX^QeD?OJN#2y(+)K(OoyDnz zjRCWJW&#CNZ2WNb#rPnd`9kw^Kp~GUeLX&hXZC}N5Oax^xPP?Y;eHUIo7&z^a_eCC z%#oK;qrr5BG0v$oc8Mn9b=X9a(HzTozS67M0!sT!yJ3EP^Vqzb%TjHg^E$J#LnVn< zB5p@-P_^SYwW+0ku%_Kkm|kicB@?4r zl3x4PVdB)jyuoC=!OkxRSdsOd~~Surs&ArLhJ56gqXHQZ$D znDxW$W%MBZNYkt5T(Y7t=etv*LUIHX)gOkoHWHHFouG|3ndtMragGkv^e->p1xsw{ z?iU%A=((|%YuuwKezHO>2Zz>fkK%T19+gQz$=&X?DEneTTRkNrm-YO6_H*3_sdj_)c+ zT~h}vyx!x@bImke)(*IlR2eQyA$8i+z$Ej$#pu}!w&F4@KLu@vy*UC5jMNI-bJx!9E^=C~WN19w zzPXnz*XI$Ta*V>}tc5IHdy_mb0}H1UeC-=5Uuv*hSrbJg>-U<5Yo6HO&9` zbEE5U_ltzEPlE*Ybcb|Fw{*93 zH%JcM-6`E5-5o>oo?h2;Kksw@{^5f%472ylKKDA;I*#ul?HsbJP|SSiaJcM8H$l>W zliAa=JG&}XWj-Y(iYD3|V0`@=S19zd}?(cgO`Ellv9q(PnOdh*qz`;V3^@f_ky?a zA^OzcI@>&1qQ0=4NDUU2k#XZaQ~pGiGVNA|#YK%NEa`2tQZb*G_7In0HS_rjoUh(K zV+EgKEVL)i{AjPP`t+C&RT^G(NG;UqwCkb5{Y*$H*6Qnuk#f`XKEj)Mxy$m~1)!0>3da{5(X@>}vK%u#z z;Vk|)-EIZ#DSAE}at?89)@UXxfpU%imvTvPTgEdN zORmxFn;tVp@Ie*$z+31mBRM+Mwu>F39UVPX>CiJ-D6szL(Z}g=j_kE%PO$_D(fNZ& zstgJ$QdbBgil3t&D{WRp7s-?)$*yN0M+xZOnmsbtzdS0neD46MzZxAGsDVa+Df$pb zK!^Kv$mh|ZK=}?#Je=Cuef`QO>miJ4)tnUuy`ISl6EGb%4l?Z0>n~doB}z$jXE>LN zYH68ePKx{UL(fnf_5(2Hc60?zTpVL77^Rp9(5aPn7pbf|bUg>X{i$x|np3p16`^?} zvw~#XV)qI^2Z##XKAv=-X0&(~k$#188Hs=6OVkc^3NhnG+grQ6#HNFT;=|#K-HE@l zokr{IcV$gyNF<*3Hj2gAI(Y8_KS}#`vVI%tQVPNTo%^U3Y#=S=*I3;{I6oTDdq!kFbzhLqpTLt?E!X-R(u? zx6${fX?%RmCpX*LI)B=ptK}(|srfyJL2_LWnXiO*Og1WVPjR^{ce#9hnH2q52tPAA z@=-<3k|xb2h4?T_G%Vm+r=t8gv&{78Xx`+wWkXtKZopJ6r7jQ7;=PT=nY=5P@bR~Y_nw+o}AMdoC_k@Vi6heGxzq5 znZ>L}ZGC7#0DZFdnO?$V4y*2-FpL7NX46Cw7;L?mjxT~3SylP>L`rHV{)zph_r=n%y4s1z?K-o)K(i<>&gKjId~Kr; z2T+<|lCz8Hc|qb>u!IA8xAm5m^yEWr>`2E(P+j#E=~vsJL_PK zM!wps9w#uH5#LcNeOdz0J^BZ7_q>~@*;V6Q|DySosv?1mWR%MO2NdnATO}D7<4_J%9lI$%bJ6C-0x179QD}_*Xk+BPGS9k51faKhA4B`t1hgkTN1dR~*=)vuN0iiIWJE|A;Z{_%;T%;N%m zoCb&HSCvMi<4u%l8sUi!Zvar;PyEbsW9e|QUZI;_C|^!F+bq7c;m=>N4;V9?JpJ%WV=`wq*DF;!>@!9 zr;ObyIK^MSzcSmc9c+4PQX3%_3*qNaWDK)^bs5i9lmoUhzYgLWo78AFI_e*{xF_&! za~#Yy%4>e+Fq>9U<~G`F++$ew-7;CADdH&G{rwX37`{5L*7Q3h7DQihva%9Rb^dy^ zfRZ0J+v}{5wFc2~mArl-*7fX_kqDRvt6%r16l#mBDk!hD4(TPYx} zIP7?jNIeG8=UHkY;Ct0N@+eEKBS%2Us7}Q=x*8;ZHV04Y9v((WF;(<2a_*NR;?(oU zkLS+2!Bc_3^U(Nic(sw>z|Y0BZPFukm=*h5T1yb?RXy{$2ADz<6K(>E3;4U5t zaouY(MiXO}FWi`7vLZrf9+a>_htA3uQ1O}4nVqW$hzx>GqVyfd!+?%b#p z0@v8R5yUfyW$ivMGgQy1C@1BozutXu3=$vso$5!vBn7WLsr-sr{X!}|SAvQ8!cpF_ zBw%!kkq-{D+TaLCCSsC-bO1O%%nsneX0jhJc%aK{7V<73$HK#-HVgO6ZTtf~ z0Kz^mFRc%pUMzchzHPa=rM)}>U=O{aL>@FSuFMq*fq{Red*GOT*h=x@XX9}Tp;ha7 z+WeMw@;U$gA9pYq)PQcQeV=6g64jwJJIx5;&6;H{r8?Z7wraym_bm04cAYC(K)v3W zi1?iEU_lhb;}1e~3D?Qw+ar%_UGHG+3YN+tR{O7v z%!Z=3nn0=E1uS|t(7$R30o2Dw#o3yEjX67CK^!iE= zd9<*NJ6WvCI~0Lp9CAI$E=Z}RWIhv919j`Ti1lCeLD?C2`yC{itc8giOf3=;hhBtO(F#0WnI zYz+s8AkEjB`AnH{{Bd#du$j6)LX>`4h zp_1Rm5q_X^2=&#EncCW3r;m;dSqX4_&y02~ zV2uuL8dDAOR~#1eze$9$b)48u0zx(|^j%XJF@p_?Xd*BhBsw&k?xxKU3N&_Q2+N%c z=URzHhLhM^{*=>`O9ci7ew46g8kfs&A70WFrBbgES!;$aSI2jP zfc0$UvgEHB#oZTxVFtV!@%XG59 zEBUOO{!GI(@$q+Zr+9|egUh_qOp*G^YtzMHV*X{E-*qV819C$eC zfp50lnoa{tI6;E@lGJ*G<g4N~>A6K6CRJwpOY|l&xeuw`{q=Rl@#f zR+*zA*gBhozH5>Q+Q%j&}R&m?a3AM`0NOeHh zsaKucnjG*AV~=hHIP`iLZKvP>%$8QI#@u6Uf{u7)ogZ=e`l#;O=x{9a-FiSP3JH2q1AsS_!{d=4UD?`gz`Y8FVd5ZmLLeZ0Z*^W=y$GJ7((SO!>1!Rh7m^ z`FoR6%4KGvosP{4os||C?)rLtD9Jsy5yKTJXAbS71reXa&_?cx9VMjB7kYN)YuhfV zju>HRKCrQ&5Evm}?g|%et^FlWWDy4wvmoZZw+xGjnB|nU`1B_Nzw<=>7Cc-UT5-LI z*Xp$=?^PCZ%4MWV)SBh^>=B}&`NP+6KmtUM>tZ%yg?zFckiO<#DS1sqXdz4dyH1dA zzsuW6(ASRuu=ml87e+Jz(3Seza8eODSF-p^=X6LOeCf(`3 zextlRSx)DBPblHk78+`~(88Q+*f9`;`KTnH=g% z#b479@=rAVcSZEF0H$jE?clv+C7n|u%Y#uP9yP`r2K5@GeRdIJ_x<(tk}K?bx2P+P z9$%p%-?%xfkPS*@We)u(|1~|%XY+(Oej_s)VeHCPVns@;bqy0=jR}^Cpo@G6JdOu_ zq}u0VD<1BjOVn@zX>13627o@nE@B|*}bxaPME~p4&}&8-O`D} zNAXPTHCyl^@lSc?v!`6B#+DqTi!iM#rwXTNMc7f)LxeZlg>rA}P) zNTj32Z!L7f&mteDk4K&i2RO44yu5vU?2!=>ry!pQiTK3!mSSO*@r+6)UiA|7 z#Pvxmk>X?f0`t3eH@(U3^lxK=#JPf<;}D)>q5@=`i$qH5B3W7@UZ>w44|izh>MX-0cvo}^9Pzb z*SgjDqB6Ea_lz`(m|I$Ec4bkIB}H(hLjR?V#C@~SjLh@M8Ayo%uNA>#eL<;=*&E>6*3EybnWTP^L4 zq#DVEC7$eZw;NMUdm_^GK>pe*kx$k?{N>eZzL&(s%zrR_!^W8aR+@{3!hqcXA|`uT z-n?XJgRL@lgG2qx%*^)p?-F@0jm|^Y?S-U;eok|^hgJH0sVP26J`Bi9@lUA&I zwnQ2dw`UMVIm1mu6{Ee>U@w+Yn61uc<^Q_c^o?#OqWN+KDrwm5i)NSQXQN13+|DiL z-S2S(rixXCy;V>AqCDXW&A@^ZFk8pTxfy^P92C?&!uNS^O7NRn5tvh?K3FNV7r(iT zt!n;aG|*+WaYg)ops_-q=U@phEZs9T-@bH-RfFKX7Qu;dvc%_-kYlxPEIV(=&0h}a z=YdgXo-w}Mc1<$ZmFRew!L+%*jXN_QN6{-dq;6!r^U3IhgikxJ7~{O>LzVd47m_#vfnj8a3UV#zDoyXh zNFM0JySjfNbdU*%)EVp_F4WG$5sR;d7yK^CYE3s;Fi$(~@=?IjujIr=64XC`IiBeb ze}D2&7oyIQ=Yf1QA@Oes7{Yid(uB3X+W}M+Lzk);cX|ElCQr989BnlX*_o1^{>b2(W z@&d9QBnmSSb8777_p-U|_cL`ndjbPz zGaj0R^IrXIn5UYKTCp0hD)eB$SCi~$dihdO$SK6y^<93JerkzYbx$l9P>6=$l5umt zrd2Na7;&@|rFW1Kcz+_oGQE&19e=-XR9W%wst#i zR3_)g*oKG8b#s3nkBS*-OwqPWA7+(ls0$ul+1}qTA~Dnp?@D~NEvYHWufJtpmn4^8 z=MgU%(!AC3wzQ;~)r5JbpJk?BV&)k6vF4RST|?Y#eT)(1t{lg<^$*}4laLJ5QB;y2 zXoW+x8Y4m_d@4LN-yTuUbUtTYRqgT#s^Y1+niab&H?8ZhvSCSdCFde20wbqrL)vP- z7)e4zO~qPE;>F4AWcSPTPen?osdU`2Nx!_kxmq8>bs715?v9$JM~7Kj4Q2ID@h@s{ zmc~i8Hqz!i4?id;Iy`bx$=;}rYBt$%d1%*3P+w~I^OZ<8e9cX#b%w5I%{`#Fs)md@V=PNRqa?-!lZ5g0p%rHBUll2-m!J+EzQS z4+h8fY(#l$`V5Ma8wuY#IqUvTeXz5)%sk(p5(H8-307y5%_MtZU!tpqY1Ev7qwh>! z1%MD*)-FYRn<}Q`GSxPEBgl8ihJQ| zjED>d21XEENSyIb2%INfdx~?bSzjr4wJA9>jcS>C`Oq?JK`TUIqTEK|ZO!3q5GqD8 zo0T*d##m_J(oy~0EB$OGLw`>AijHQp?V{=ttf&yD$Dp4lR9ntc0)l(QXpW9J!b`5l z&rqjyI_I?|g!2L#A08w~MO)${srqbtnr@I!_7BXl?cT(i{M{}|z%g_PLsw9x9m0`z z4HrOmnU*}2*n><9Qt@XPMtqMZ#r9<}N!!OA+yL!%>) z1KuK(*RyCP>i&4#+9HfgWyj`w)rQ;z49jzIWoj^ZMtGOA?@1VQJkBqM=-9}>ZhAKa z@1n&}n73xxY5kHDA1iyCL8}Jo9FOkvsCp(@``(l+EM2K+N4umm5}MU7t)wmz6@!D2 zYER3L36cRw8dWkzv%>y`O9uQLCX>$|ZWqC}+Ou~|zn9r_Rd0yhzG|^GRJczl0T|-e zr`0X_C(=hr%_3K-G>hKoh4ep$zR-uwxu)+IOs4zw&UGNf1Qa@L<$SEaN2$^YR3p2%%dAU+!_di=%>9A#TF1f->Uv z_e=J)%$q%_^G3Vf9nN%*GYIiYHuCB_i@kSaUYRM>M7C<-(&(nQ5f8`b`IA5*V71J< z1Y1A4+9|Gc^2c>`Tf4A}#XYmHa)17k+wQwS<=hG~=Qm21=ZNbv}>tA4tT zu7yz+i{W!?*~cPjbR~}h#FFBl3dd0rRIj&HOb-+LWyfNP4FC8jX&ixri4E7Pk}6C( zl$eqDUC{n}n0sZ-xt6YTLm?q0*RMrdaM`_&KYXv>YVuK~vSP&B?fiZT1X;Nf+snkj zG#D3SZ)h;)KAgnn?GvL9aUZuSQ?6xiYHt2qq@?1JKaIFlx?c=qTJc(gd_bzf(B2Tb z-}oluyP@0lDIT{M**0P{gX-z(?orS@T!*m4cC|@m&n=H`^)I|eWoKLvmMscq$9CU+ zK>bG(T!&*d!A&$(T-jsh; zyXr)sB+ndcJ2I~=cc#C#-Z@Y68W?@sGl-S>Hiv** zt*woCuqtfS^1KvvW4&?}5k0I7HWP_9-n#<2 zeO(YUh=7>ML2@=q5px8>!hTRv*NTk7k$ijlkjlNrJ;4ytmNWY?va%8)`7-%-1dUdy zv|1h|gd?`a-AYW%h3eZ-3LL2dsY{*f2DDpKmbAeOLR*2ZR4E2A3og$QzGLrswC;YZ zPaXJ-dbEA-vif|Ac#5L)uc9;^Y54>ypfD;$(0o_=+~qM(b~^I=7siEfj0ok`JTwL^ zRbe4-r2911my2WYsDzX4zNGnYmU0GZv|%Y8ZULbk7a~ohc=Ar4ltt;yTDo_iEjF6n z+OE*RIs|up1cD@p3wPygrQTfN3y)x zWTyOp3SDGHU^N>0y`tId@&Qx+?fx1IB&HkVJ6stOLXj?US@d_i;SV!^@{(Ol@k@oA z@utf|sKYFdv>{n>I2b7K0cs1>7-K{N4pm)tl9!)xkEv@S!wnyn7ZzqN1Ue2(j_0e3 zXkz%-s!YbJ25;7;J`3GQ)Z-q%C7(7~DW!kBXMNE+oE%^>k*{~2C+orpJZdgYMCWTE zj0Gw?$yTk*4k`LUyN!_*DHa|SG;^=n3o@XD#I_gK3Zs8>!Fv|#ZQ1NLlRlU!{sF;E z2IfCa1H+e%_B!lRq`3T~wwAD|M~~da_e`s;Qiz5s%dgs5SXiy;9WA2+v2wN9!# zetqo>oYDG>*Hcq2l579gkmC(w!i>(8YLYlKJrU6R8N4OUuhz!8O|q*!*#oiq#n zy%CF-Ha@zh`|%~D+x}**ZflR$o;Jw!xJ98B)06fc`Y7MINZ|}lnR!M37Xgd&bLH-| zuoK*2yUJ7rYo@EyC%z2AdN=g;DcYX27)0XJA>IDUw*HMwU=sKR-%>etx0P&1%QdQ< zs~&VG1;G$aIP2^5k$&LAGcw{mo%OlpqGd&9C>?okiT-lMHr`ScL-5ka2Y%Nmu?n5z zVa>w#{(}fQ+uEh_q`rurUREhfTz~lhRqIc-LMmRqi&MRopuSHv=iL*7Fv6s@E?HHw zb`2>M>6mAZ6w9b$%}>*C+WFcm>h>{B^cK$TEMI?9B)6J9K>yi?ZQj{ zxj2f~KFsHH#HNm@5C2t|d9Tw^s+PGUd7tXCM5Fi0%7zEUc)U)x5L^(5E0soQOMRYL z$$hz^PIWHB3G5b9WD)!o+En*tN;gA6v|pf9^)rn=#l% zexD-iEa1*f?0R*;4@KR;AziVxD|aak4dGD}a{dm<*AzNh^n8M;+l*V@z9&E&eY+dW z^pT}_$NX20_vV??JtE!p14q+S``v7dMWZu_C!VvI{uKWxDl&AHqkd*h_9~&fNJjF3 zTTtXT4y{`EG@P*R0Q79c7qANTJ8w~UmYdZf=iRKb2T>{ybfZPzTR6BmlpS4Ltvb^Q zC$FO1OlyTxh(8>tU$nUAwpQ>KMs$8vVROG_>mn5>UE5!3bX-`G-Y(TVxcL`{9eD;D zpA#7p?yDLZ&Zx}$7r22(sv70YU^6H%`6vD9S076$CS|;&c-IE8Y8YeM2LsCHeM*Mc z=uyEwoi}r}HRxI!hKIFVSRlE zCG}5E4#`vKT)ny7eFO*}fMbc5kd&Nit*o$(I-W#5GaLmF=F==k-Rq{8g)h=@s7sBpK+*-=VDrY$&@_M-C8O&4s`6L^dq zPTAGRkBnp+136pn_h@m>X2;W7sa}oUp{>Ph8=1^27i*MkDv!Ip;eLI-J<750;%}o< zpYlKscq5su|D@szczCxodK)fN>CwDn12K(42T}Ne>nW}C9t%RM&KoPW7BMR-btjHP zNte=(wl=jZl}?$z6#Mreq8%`@DV$o(qkYcgdA1zKoKsEbGzxitMD(&qsJCCjs=zTU z^Wzl%;_b`}L;yK!B7BY5Zdd0+;8VPvn48DLLygxi_}tjN8|T(hW{Aw~Vl03vf^Mo+ zy$V4*enhivXaC=>7OxQ8i@(JfgPFNctuxUQMGihL@*q4{`aSt7ae^`eO^I8d7{U#7 zFl+Y1>MH#h0QF7&`br3zgp=hWYxcrT(f3ORhMO5*L_HU$Ys>h4I+&Z&@!#&ipe|6D zU^6mmmhB_8y2-!UpDybKh)DmP9b*9AFzIUs9@o>w%FztyaP#k{s}}sr(|0(vf$UkD z0aplCbMK$#nen*|5CB}l|N0u1i0eD-xkqxujFu~E5F#SwMMPw)_3(Q)5INkAr|lLF z9C?!`AA8r=FVDqEJ$_V?lf}SVSuxrjPRsg{{GF(t^dwW1dp>#KprvxhdJAxf{3*;7 zww69l{&1+Bv>y^E49l-TCEpXq*O2WB-M5*^@S3gWky;6HvJK(b)x7T|&&f-xcueq> z{BBM6X0lJ=_=k{2O8sd4x%J5(!I-V}+vQPlbH-!AwA7SVSNWfFS9-wu42IXJEAAY) zWv>YRW2oi#AVB#o3}lcWh^x(}K8~hwbiVdQOyF~^app*Wvt^9}5GR)|R;>@XJsuol z(2%whfI;#zYf;IUjxPmGuu>0TiW%U|r-qnbzJ8nF8W9qr02x17wK67ohnmb;sCoAa z0R=@wZw*lf{|N?{Q7z}VCbypu_WyBvK!vj79cz$aZu+Y(`u7o7hXhQl=P6 z;ewGzamIvybeT!#Ea}7P8ZzTfb@zf~*y|4`zlG8C`>rfr2b-+4H1Evk zvRby(bF8gL=!0rBH&0V&TJZw#M zJ7R>>J9w;G{ZP*Djw9UgSdC;l^&XL;&ZjR@xaxPyvk?T`rNu>?{Sx=z z<+|>&0YxELE*Cpq+QY1Bz+{(`lfrVmpikIPY-BoQ@V^r+wt^U1R6%mOJN+BRW1{%HH*CK8aM_)ZFv`NRAjG{vy95Lt}Tb~ z@1U8PU#&H3E&T@mxy%vBHW9-WK|dLwgz|tRssTeNSb>sFg+pjSD6IUK8-nl8AAv2v zQr`_P*heYmpoIHasv}a*#U(L_HW-r@r!{07=tKeFA%f}rwT0Ion{op2;xRe{^m{^g z`}*OUXq{F)(Voz3#MhYY_povDh`8<0M|t@sJ&5ZqQ@QP#{*3U9)mRYb7^#SIgAmfX zhpUAt^*%r`D@;=p8PY*EqtL}8WGg6Jiw6=0Y^h|Ilz~CvS}-L%=|s~%sDntzO8WJ^ zqmqA=jIeQV5Nvk2WP|;zr{`TSm-Il=-5DC;2*>+)jm2qs74lBJDdJ$E77YmaDn2gl z7>sKX0$?GdS~ZHe*f;hR&6KffGrXqLt>pI%Ty{H=H(}XMkM%~#xy7wln4Ah3)r#i%`9>DFoy`g$v5xYva^W~CxAT$k3CGqm0$x)^GO)%E>sZ+LA10k_AS{JNU+YA5JYtqu2O)g>q5 z@cM@Dv~pGZ2?oU{%D1yX8qUJPvbwqHhtaw6vC}_{>8!bSiZ#S{*v9UA7YJrw&5q#j zYFgP^t>Lf5ZHz#%E%`BkbJ`w|{i#~b9@R>pN83ZWixKEk81m$k{n7aGgUZX9Kw-Ai z9Fib3u2uh?5>TyY>bB+?uKzqZ0>#+pcZY{Oc3sI`0U4e#m(1 z0KVE&RTy))i**{AT;G!+=)+{N6JtFjuxg*_iLxTcaluaW+*$I5fOFoOyI7iQ(R2wLY+O#_Kkr}USzxE%uWI4}lBUU3 zUMN?}=CQ5&BkdFJgU0wuuDc_D^18FzvC6>8Sy|)Ui{ZQEK69CWO>cj1sriPFA zHwdo~KkIgOqu^c0Q|OmqK2CPu$n^1JU||#c#I}n5UOQ6aR5TsaH{6+WkdZP?dblMy zD!tWo2p8=}rbHdX<>gq?Q0}6%EH#?u@p$Zxce;m&uWlXr1CBRNS<`*Arui2(_p^nw z+W7p&NBUJKB(0(xI}M5XZsf4+8#OyZlN&ATF5A%LB89@y$*W|`EshW^NC84_4wUN7 z+=Ld{NZNC3o4Nysn%W2l$=RhY^@FVF=!tzYpO z3d?t$j_+2_wQp*R)1_}4tBwaM$}*Z=1z+H}{1;~~GUP`fibz++EBO(dl+gV&X=5Fp zp7)E^m7dC<{@AdO`5$WZ-s^AhV#o(_L}cmx93NLcsYQOY9IJ|dJ9%AX68}luJLhZD z&!2XdCeW161FU=t+{3ISiWMVw?&HCi%X|(EM-%1}IVKJt$QECl% z9AFOn!7jY0l9p78OT4)*!PD_*(FCuy&+&uV zRL28U;D;8Um5`DH0|-|6`)=fD{68Ew4XW9uEW4v|IDPNlj^Qa(vdqjr!=0q>VNNcP z1V@!xOHJQeb3}PG#!0K+&j2fwXm6&-Cv=F&Hq;O8-$=HfX8+G}HVCWUmkbE$lL$q5 z>9*g`Bl~}U*nEu$L#dlja|_{R>Hr6>HGMHmeb`bK^a^toZA4N3c#tqV?83L%ol0GG{a zkc2>L54_<2x%7x%$vqhz)3t5<8WFfJapfg+q$I0r#Cvyy{SG@A#{?N}AYCZ4dnp*3 z{s`NVhJg&xixbgiCbszaew(jf)$-f%(1?^o-2L)){piSu1{ZWuAL`b6?p~;*)i6G; zpb$&&&wB;FV3K=D(^7Nr437Uq{m=jTqG#bmM9p>i(t){C!(RFeU!{3&s4;v;NNy zrp?}3{|7Dn??eCR0s9{?>;BKP{qN5LFJB{S{6A0f&p*3dWE(2}wXOX7dl3G}=#IFo z{{;_zM*Hty+)t5stA`W&Rq3m0;m|)T0lH8Xr%55^M6JVrzo=q`FA569zkUq>aiP`J z)YJg_{~T3FOloqGjPd4wADqf|PF|jxrDgck{DjNPD;w8GCCRUKh|9|$^$p7m({`XB$DT`|R&k6spGgLhD z-!JfgU%<54cr2VAD2%Vb9Z5|}D%b)P9&zdE=@&MjB!f&&PKpszisoJ0D3VtoU&TW?*p8qCcAQNVVExVH%uVBZYjqYKO!5IWa;D z1CZM`@b*8aB%!YGq;q$DAvPL(I z00+t;i2Ezg$|C1EteP;7;JYeld`vV-+nrC(6b_gNFnJ@;C{Y%)c!@Hpb%5}_U+r3Z70AgKN#UTwsS`u-A)G?ZM0>9ky>u2q6;7piG7DR@6qGw z0eS^g=iCsYj!!jLhYO8OB)m@Lx%v6j#b~^wuzHh)Oq?q~ds+g{<8+ZSBa}Fc!q)~N z)Tsuwoj-6LJ^OPRX0Bvl+z%Hoou~?R1%-8yzx@&Wj=GeTl$R0PKo8a1u)Y)`TQzjG zJJHL&;&%SQH|q2w0yhxcQ4jb?yj>gM@8y_mMI>A6ybgn~>WiU0Oem>a7y=@O`8Zc$ z{)OMB;ht~0eG>l8>e=mMn@wgCFA}VzN57vhM4Vg>**+zNAi88yd z_Q(6V4JcJct^>x79jYs z1_)ZF5jC7hoWfsF6?2v0%~$(h#oevm=x(UaSYZ1v#cR3rKiq>Mk|ir$kLr6H?DzBJJ{IGk=e#NB-~6di3`)`A_?QbjmDi%u+L@^`Rb^~bi zQ+HvvSG@v{V`1>?UKp3bw58?ZB+fa@R@5oh-dKBNaTr2uuS607v%Yc(Q0Ol`ct9Gh zW_mz*CG&6XC5HuzD-hPlO-AId{OQw2Qn3X{H?I2Zb9f>haLq(uu?0?df<#dbAiWl2 zs#vgWoYQn%n%X!&UG6%4x*7G<(6$C+fmth$^W=sV@o=KuWoGoRJ+!tzX+<7FoAFyc zA8)p&TRoo|+*|I?q!-M}np1YtPOb1SY=#u9oBu%mciA)M#;h~{qq8w@UOBw@mZGQh z0i;TnkkqobzYECpMa&6dY?&q4@ik@ubOXD!=);-?%hWg;s`J{pZ-hp_h27e6ta#D0 z-rVniK?5>@*c5G9)Av+on6uFfE6=;+^NJUNbW9s8QSu1ynmlxV zxZG^Ur~ZBy6&1)Ln80)EN9?#b=0~$uZ=L>gp#&^zJ{AH1W4FzVx0?H+j}V3CA~`lT zcH|CLO9?#?@Y$P3$}7P!_+QokD945%Jq0*_U%fAuyAmTn`B9~fZ-`#@Y^De6OL^%k z4NN9x@28c51tQw6`5zUY06Wdoo@3={yg-wU&$&I6xIQm&+Xya)l}z$R5O6hHo%z#n z;GoS5M$^@&;QQ6VoLpT;-3f?NLPQPgwE|0`PO1u_4T1ZsHK|+o&>g3=k91T~A?W>` zdN3le2+yDS@IPR#zv{^kM8zir{hIaCW%if1RL2Ce(hyX zhu#BxCW8A5Z=DQM<6jb_nTTm{1lu6Ur~-?}Qma=tIt6XCseCn?!|W^|K}QYm1>sm3A|nJPRGPa zxg2{=HDHm)@R^X-wTMqr${F}9KW(do$u)O=itKCVdC5a{t14T!o0rVK-++&V$R~Ww zq7xl=>-Tw)a0tuGD;-gX*Y%BrByK5&QpD*yFZ5?HFJro8WNLA(i=KA#(;ND&HImAt zPZqt6h}+tHYkj~nz5Ec7A1Te)JQ`T6o6lfb@#Ydwvx20`kx9Y@RAtRec6SlC1Apmc+rAi-`pF} z)0KY3P>{GG#Wv>GPHcnhFZ@UagJoZeie=l#4+>A}_GvqjJkiy1 zz?OV?u~y!dm(#Neor;7?FL4nb#kGIhkBNx{^U*8FsBMWS3ljyQWtokN{`9Oz0Q$$E zW;BASFI(mLN0!Ub^MF|7Qon@$##*ZbU+!KZ;mzq!wDFYkKYwRz;Xd0yb0eyvUp`(r}%oeO{u@>)a{M6QCRgD!r3$y`3sc zX{W67j%WJnbkUA4-}h1}WgQV-a1PXgBxQd~+B_;D=ywnr=!pbG_PnfyMe+j;Q z(*@?+M8*o}t$*{>%`VD(vxTkw9C7DyMW}q2_GZeom-z9APLJRM)h!!#^BN#Mpq@F{ zdwqz1h__9hqRm7H+hf0Cxr&N9Dyj9`Pbaw{aL2FQEGO1l6x_P<-ttESaGIz7EE zHUw%+zxP=C4#gs_VF-v$z3tKzn{U&UV@2M?=`ug-h3PQ6#q(9vebYgOZA6Y;B{dQ)C(9kq>&?j=7al7=9m)Q)%4AiOd4*UXr7*9t&Us#N45aa;b;6_@eSGPLe7V+X-Grl%Cd*+1Q#G1wn?J@{FN9*g>fctCtvtrRY+E z@MV35P4d(hKJ5v1d-Jm*4|lbWqo7Y@DaoIRh=h}v*uPtj}+`V?fCcO5Uzh#2vf1H(=eQBMZEPJZlL%j0u6`{UOq?^$@oS}gL6 z&Xu)w>WC~`FFDb&C1y|v^oA0wgAe$3Py9*=1tx9Y4L&W3gyQwZ4ccYbI(99D1ettu z45h#z-T?%YY?&y~>0hl*P^7k6YZrL{HPrS1vskT49m!_+_6VOX{fKztxmJ|-r)8C| za+<62zIqv@C(U@O*7P38=fPbA-;a`;x-1+M0^mA2KH;Lf9fEkQBc1_5=&Eqn~}F&Io5Q=Tbqx}LgWdV2V}u-j<1QV z*5V!{VJ?$c_E9N*lI~I8bU=aYOdn}9z&*hY$glJ7LrM7NEqIZy$gF5=i*Hc}^UL*V z?zF0eZfR--_1_E8q%j-*tdP)J&wU1g>HVVReMb#rfn*r;eY=d{B{ZB2v4FOiDfjT| zXqx%{Wj8&^yb3IXla=6($Q&|OUF54{I5H43Qz4wXr5YJenDoQDC92|imGES$)6uR8 zM`^>}`x)x7BU?HPTa^XzyXh|v{GU9Gu_&!E1gN!Ayzy`a7!bY5Quuv5{A+w6*#RDy zFzkj2EhJvj#WpFAq{0-J!M49^;TBYy6vy($df$kI97>xEGB%wE&5TAWJ&vajyn83& zhQH8syH`}oUqQwja>*`{Ds0}CkOb-GIc~zb)tW$;j%To6Pbhc9T`rtG3GZ=5cTa(3 z*ryH^dA+8Bk#JsfCxqY_Zh#iEz5Z!lP6QjXKO-HT-7>2F zHr$T3+nlAj`zoK`&9jl=JD%gM(A0XgTe4gFmhDvZvDV{JC!^KoASiankF#ZLt7UH+ z%4E;pZ*&on?>HSP{9YuxW=paO<9aQ! z7aYb=yI}`49K$VL#cS8e>Dz#bz$w!5?6r2F6d zrg$j`1#fupR@c(f+5mCY#g5Ct!AOoRz=h~fG6Qy4eIWhlQ|%L$JTFE=`U(jsIUC$* zX=y3`=0zER`=<@G6-1a&&?*%d#Fu7eW%Ys3UlJD?DJiMHv2h{yM~&mw6t`{{dxLR=-(Ws z%kaVe{-CCtt>h!;V-O#mx!nTdfXTbNyTcfSL7j}!oVPN<2VLv~TibnNasCys$!5^* z`2QGt>#(TW_FY(|OS+^(I+ajT8l^;}yStkakRDp38w3Pp=!T)Y1u2Q4q+@^qhUQy5 zzx}*>zx(+9*#B`HFl!BK-RoZ0bzW!0?EylCzh|??-j_swfe@*9kKL)k1NV8`VmY8x z$nxv|{{6c=5F7{_NMhGu1Y)>6wl4$EN{!{L#N{xY{?tww_S1vjmLq`mMH`S z-|Kn_D2}j(dx4;q{qqH&hhd5)=PlQ^0)A@vb-fJy(vW7^B2i`0Jx1jL2!Nk6wE~Eb z=dvUa^?3x}yAL1yN+HlBuVhr3z1zm^t)fH$+(*YgCwtqqewNfj-Xv+Bp z(0P}LFUYfvPQW#|k_)aw*Cl-=Z0T9Gm?9-`W$i)pY*Om9d3^f3JbBEqF+g2Z2D!)huwUY$h1R zUojAM%ms_cWt(OVT$@l#>Gq}UHvl1l)3KUV!LFBKPxhmGrT?&}ZFL6!Pef%p~;5@2nWUmy0<1;zmDu0K|j z4zyn-pA82jLtb!$!iV_1GURo&x0*^R{C4d67O28M!f$}g!gx{VPI-ymIKf$RMNxOw$i9E`Stf`~%#9uG zmwoFF{3E98FC4WOHXDo_OP9^+4gzYX>u(549k08!7p{c$9Ixr1dN_P8bwYXfc4cpt zr{{xUrFE#{+V(ij6*JE~@V4=>we5*S&^)kdw16RDT)yL*<(0FiM)xac1V(hLXGBJl zgi{|;>&T?=X3SC(kfQiJ1H?%mw=U=K^ZOKwZk+47q!1wN8&r(AoTXC zA)I*f&>9moveIaA$g_3I%6AhLJmzRGOWT2+E35yR*4_Gfx^;*(9+aCvAq&*2fm_M| z>|$hFmMdz3R~nNWpFymnFeOx^T-)!C%9Hf>6p*g&%*Um>H+D)|risPCnAhJhXYC+D zGxx7>X}vFtPg*08I=>IBs2?pXF!ZDPZbZ+^Co2b^#g6*@gr}46hp3Er8qs&wUe|oZ zQUxPfyr%a;UILH%%=WN?}1aSTGD^{Iw5V8+hw5kafAqSqQU5Ef>F# zv(YX03bj$N9cY*qt;N=S;3N`IVn;NmW2{k>sh1}tY{G^3vzI^3KNM zEy!jbYNyb;bUfzyi}7pI72<5)m52K~{Q889H-^T@Vt{z)rRU`OFfDRBcR2is<4^Ch zc<(F=naua)(9Am@f#;|h1bbAWf8LSU;ly*d1?H9E_z4skA{b6=+$p-lr551V*z*eW z##gwz#rW5swaKoI_$VYNtbu9pmQ&V{56c`mCc{iZVqGV1yc-}sl9A4eV+z;@7l%6E>1kYJs`r=TqhU1-5Lc7)P8YQpTuc~z7^An~Se1p6{z!Yw8g6Sd< zs)J%tNE@Z}V(0aoZC2m*qA`Aq&X%7@l7Tv3wWgbs;iY?M1Yg{iKN>ziG;>{(NG*1% zo3A4OU(BiJD(;gbPCrN0yjozQI19{`V*c^^OKEHa)b(I;6cGj`KBwzj7gD(C*G(YF z(jzw=+}SF?82$hoQ;Hr!5vsyi-4+{6@nUP|3%*;~OHGkAW2nT85f6a0;U3U~d9|Yi zW3z~-yY%MycjF1aTIafU6(cr-y&ttcN4hxj_PmJ+R{yh%Pb~NFBIm4=edgK z-WXyH#zvmxj6eR+Nw`~PT1RY0xe!a>8-Wf4k=ePYj>?%Np>H=HKpL!%C0h>tz`XD} zcF=5>;Oy)9V;OL}#0L19bxE0RJwpuh+Rqi|8^>WU-7xbpaJRNjVy!!SURdG;5w< zTGraN4zCk#oc2!UCos>|uIx8{=R9lb>ijx$Km^g35(;=Rzl#h-gRWmLXA)gS`;Aa! z2aG$%EK?-D{Qj*%c01mNJ_l130%Aj{T1(mN(5WlxIy`DS?LfhAJbA0g4J$H}TI@=T zk=V#`A9H13SChE3K+^j4l4>`~adSOe5v8kt0lRthgc7Dk*ogpYDJ{_N_LfpL#3+;em_0 zEG$Ns)TlB@;L+L-eMB7}^wpkztwS-+6@>}MNP#a4qmv4CM+6wn5N%@gt(nJ*&(H!T zuU|X=V8r_ndq$T(0G2#+k$ulEvhEoqz@I>E;JOjZyQpw2Bx~pu%2!7JdXg0CT>^t4+S+;-9O)V!dDFd^=h&bM%6< zfcXJW`+$a7Y)#Zyg)C0+*GNY#69-4;T52WP>j#av-#JeKew)fU6rqElYvY9gc^S-Q&oWgvVl|E4a;S60`^6 zNB31q$9cxyB($6mz~YkmWIWOD20-y=u19CBS1uW}u>9WVQ!^A6#F|Q;{FX$CJ0tF# z5@-3=`uS-ZYO(*L9u+bDlbKZUdA1z1oppEje8ZyHp5dp#RY3jch!;X+Tg)}N$#C+H zY%=cs@NBXVZFbsJ@lqZ)mf!37U-{G*TPtBcRrJ#NF;&KuxA`i61BbNdc29xnU8iGY z-c63@jIJNSH_c!qS6^&QH$^c3jk}iTp0Dsn@ykN1j0pNZP_%}eeUbQs6WZNVCbb=3 zGTvr{&9Fv%8W-9rnZOpq?~&#rlzvP@Z}avqO>A4T_aiu-47hKlwc*$7Q5@0v-Oh5W z|7$CQackN1nEO^%4QN#LKrk9bl0IBl2pp)5j3)ey6oOs*N}fk+Q*2>u=^Sx%caiMM z9r=H4!^;=1bYVQth}rX9Ud?9S_E-ORMrES{3|MD4z&OEcWcWrH1nBg&9oZETSkENY zd+eS=nf9Ca%E#Ue|HTI!b+DKc0M5P}I9bzyHinEsA}z_1XqZYRjpA&l1C5XP!{>Yv zBOQEPer5Vq=~uKqzL8rgxo=repE`7&UV2pdI@1^O+8jMT41$}7iFR5Cb)Y_$dB3>k+OCM3 z+q$Ei&zLMJvM{c+!qa@iv`~EPk8CYTZ-wwJ!K0F_#&>IBh*fH^MVD4GBc>_oit*hE zIV*%d9?ShJE-Vw>cT@Y;mq40NH;UlNI5j{3@r_OkIb9JidVVw>?ct)<`C?s0?dVgt z)(V2=3^zzgLu*t+n7}Gjs%1?EzF+%WRdq4grPnw@C|vU^Wajh5NGSmr4iSzkb`*b8FEvA1V$sg=PtXV&8ct8d>^ zc$-4I6O|lvB6QSs7}tEAj{1c?Xy+w%6QK>56MUUlQ}36g1r|xhxjPXr+ls~W0!}0Y zvCyJRKDT`dAi+*o2!V33ygP=%!I;zkn!hmRhK$&C2JbKN=5PWRYBZj)JSUwJF`FBD;kpYbK zA(~JVW-=DqTMOl1E*+t)rKu0W)Xk)akdIxKybLl&--0?x6W(g{P|)^}QZybzK4)G7 zd9bgTgaXsSQDLW-nq5Ahz`_g*KQvg$-6bf(Stpv-_`MGe$OD4gDSU%>%)7X0l@F`K zHeQ<%LVVaI}8T~y`>q<_Zv`xlDqX#_pka z_x3y^FHyjZBxrm;mY!5Ja&;uz_6ZnE+>Mqalk|BR8K5e22(uT$2`(6>xYBvwF{ON9 zrW;S#$R)(kU^mD7jtZvw{q2|vpTJ7C<>pAb)3QY$OBGz*!N;moDHp%u9nHok@E16s zND!7_P2$F3*D3t$YV4`Qi~`3zm8`vugf={avqOhhZb{(zQutf}pOk$*$ReN%>r%vU zf9P^w${t_5*_|PJzGa#)g5mmJT zq!XR3p7M)s865uaSmZq%VlidHOCA~kT5pfV8xj%Dr^bA2asr+^@?rJ?#*=%uV}EVZ z)UyOGvF2pEo=tXzs=wI548h`HvEnyc8+!HUv^S@KLF$cCx$HUd9E8t4W*gHyG4L=l zrbC6G}etRrG?-RqC|&9r-g37*vx%grM7#2`o38qYSC+BUn$y1RFiNGzXI?_ z@l#l%DwH(gjiL0fP4Vvn=qHj!;(7a*0$)_2$)QrOyIq1CW4uDFSG2KZ_#hL_s1;(h zVWFg51w#+4jGPW%82IM#C zSESDL_|kJcP?0~8CObuDAssU(*XU3_nOFjZsqju=d`B< zjJM{DA%gyazY21kTVA(U7~@ewbuU$Omy_OeNITfP=cPn4xH**s@Xwe)HpSBf&szzP zsifEDn%~kzM#w@f2*ShosaKhOiycNp3+7x*9h6Ew4pBx^2OF`Oo8IiTLiWeB z%BBwBwAWfIUvZD6jrvNXLx<#&?g8Ha>nc{br339Q7R-`}`=9LBe-PFgYXNi48PT-& zU9G&ty#EXWoxA@M8j&1j1g)kV013ub0KYHE4PZ-ALCM*uT9l**6A z@_4?Z(B_NDc0mG@LZ7%KXGMlt43b`;!yFG8&OpOUU5GD*za!Jw!A#0YMm5wfE6}T< zBz9v#wIv%9+Hz!Zl%M~ZbaK!D#hGa^NSq{vb zb49A4|LzqN^Iw1$P6Pe6i5xH03jfMO`-J|chofQ1EAwS=C=j5i@?tgYu`A9s@jJ|h z>8k!0>7<-4ogD|UbcGB#{HW$Q(m~&Y-vEDL%gBX~zBhN>;Q}18h(T{su0fcB;bTYU zTd^P%Zn-#4+Ju6#J>ictm-i?<%^!=L_R)=%4dW@IGmfW<1}kO69l^mk3LT$ zJH(fsoUu zI1P+~YHy<8^*+#wJ4xrby#|O+NSd>R>W~38LW*R<8hXZ_3j{EOp5|#>2}ZAYD{k_E z?pO`#24x5t09(fpK8`o7dXmZqU=^CPs*Ib7{g_n@ZzNp+$hw8VzBV=0z%5c=JqPp3 z$hqWu1q(#oK@x@HfN%404uk^a168M1vkFblTaF34>u*4uW~%7A^7e$Iu2Z32LR%_L zKELNOeWKsPO&54mMa4@b)QcmnPeeDFbWC;-)5AGhy(lgn2g=`H2YCJi>So{5Z6lbmr*=pBXnh>f)7EP7%jr-M-gM(}X343~?jxY)30X*ysAPt2XZ5{X1RqVlSx7H|m!U!bK z)cR?>v#9PF-uIi!Qh*`1b3jvkZuj+b_OUDDV}UhC`0CDV7HjI7eTv_=%==t}Bf$KD|`2K$r(!n!e zR31hKpLCNobSBg%;d6Yn+<5ZdT8P!RPsXvU5_!P*-<8wXBx>}q3n2Z)v60NUVO7K; zMr8U;_M@4QFr|@ZdbCo^1B~(0iaz~ z%U|)ME&(8osw~1iWaUZF&|B8*zbCA0L-f!QLIvto3G<`=Qq^BJDt9g;0NH9c2g?^7 zG6e%V2m_ego#gF~n!Qg?$3Sc&+U(G0sZ##cl8g|1HQ5US=e(!ED}$26aM#Wd%(_+?$ve{Vl3*L^0L*b5wQ4Mpj&csj_IE<^f820;fvs zw&(OT>;3WGoNN3BJzYph6lxCtH$i7vRI%+9qD3lsvtEnQuq}l)GwR;oBTZX5`r14} zSoUq!&o_Zvc%UVA)jaSsFiy@Ttbt@+ex4b>3m>-}7zovY+5n%$)n`1%AvyYKK2M3) z1WCo}T*@Bc#)mmGlE#re@zj*>a_e!TulTMB z21$f{arKGAk^t@E`>JNH_Ht3nWGea*uF?k^EK3c@&5?#iofcSUxrU1)Mqb)adFQnj zj(j2CkLY~5F3Q-!$7Y^HHJ?3a-5cJ)qki#{VFrV(IPhkjF58tLPGpx&_$emm>^>DI zy5(Y!0@-dCp77$zRh9{rs_6E(%7W0RizC4}1?X;TJ-uw93br(rjIlCRs6r8U{hTzu z3Ygi%K`r~S*o$85Hp1Ft)y`LR>Vnt8a*czHp>j`aDLZ2&NL^2WJFks=8Y$eDJB(9! z;hX0u&pduj1XtyLyb8fw=myGwAK_h~7e-7|Kj>y_eEL8%XTKDx8oNP?QU*lM2C%OL zw24hPFx|W3_&^AM@f*59_!K!z$?RI;f1_7R+N|70|ML~VJI=lcN%jFdT+pU9V)=P@xWsy+$5bf4 zcg2-A7Sk}f=pW@P^&vzt`D{g$gvG_8+eF*n6QZd)Yv3OHviyZ^?>lamPy!>q^spdW z{Flm6VZNc5*dc2hShEzbT=MkQM=VItZ5G$eAwBNVNE<@*Eu=54S|~}%a@9C9F766N zW)M`acBK{P%NE5?{->r{@_a%4(EtEFSwxkO5pFy8FgT=k!B3nAW8MKn;#X3S#}l`t zFBuIU!{nfkKD#vljB=_Anj093gTx_LxpORWF@O(O(sm?Ria4cUt zBs0$TzZ$fYA9@vx-orS>9+MU?b^<2O6Wq{6AC_h0r|m)+;_7-5!|P+!wGwQCBEx>z zjHS?r=tsPFd2t1Z`@F}&)uTNkXOB_X5AbrpPVKi|tkNcHRJ=T$=Ip|?uHaJ}=K-9d z+s#a8*gl_Rl2q5q1)r@!#5of#)F1&KAjiIf2EOiiPvEfuM;t%Q8F5&{*wBvWX+ish z4U0YYh_v^`P9Q>ZGX^o(BS*9+(kqwrFS?IL`Tv$yPyw8d{IVHV8~8T9&H9CsxV4N) zUrqn32ygOb$IR{ev)2$}c(|qG~U%`*@=GU$a0X+Y(1^n=9MFAwg zh)NiBxPbRJcp=zv6kyV>NUN9$^bABkA`4PR9xi3irFez9uTr8{1j1GhO`+i>iMIrQ zCdUwzYTS2$Kq3PB6D!I`VTw=tUV~>#)S$-v0SbBJuM&@6Fh1h7v%<}a0gFQJrQgK7 z$!Pl(FMOe7OhuB8I8?};pM*W?oqs+d%DK!BlQ`-?S-KD9{XXh61d7HuJ_csM8xpMR zt-amXeC8su$vy!V)MKKkK=dEuU;psa$I(~>{%GR(f&zE%Hj$P71TJf~Nmm_agjX^> zIhd_JYUV*`{xonN36k3Xsxlkj(&2(BEX~6>q*C{llT0Y^Xd~1mMg}&qaCFy?`_W|7 zO+w!QI|Z6nP0f?pimo%04*F0O^sn@W%^t3$E9oE4h&3H3Mp{?t#?c|W-D$(2iMbw6 z#Pm(*`WIYcEVQ~9Y zLMQ#~NV)q>%x8wUNY5BI2(2}O{&Oe20_EnS>3GN|X5Kk`CgWefw#GXz&3jSq{-BLV zD~6I*-Q+@q@p>L(auB3EVvO!vK?u}yF+7vG`So6p?Irm8(Ui2ff(;SwYVa1}JQXTM z)xn3ObcDV`)1zHis2{qr*zbV%=xNNXi%+|f>1)X;toWu-rCxO*Heu`yn5GYe1Hp6C zX;$>)nlX`5BVYMNnYQ)hjs_`Z31RJ($ufOm@&JHkdJ(hz9CyeNLQZn0_LmZ^lXN5e zVbt!tKUh4ejs8!ny(`BjsJ#W!tt}!H-y7cGhuguUHKEDewNt~(7%%A^GPd7bGv6t$ck7r%;5ffvnAHS?ST@{~g zn8IURez1*Bm|PmIboys+cREq5-gg|hV-!{)zNDe2u1-0Rch+wTvd>pew$*@2{{KScfmP#x4G>LyxK{GDIrpI+C^a zO-Bb@S>y`K3snRh{R%xn4!R}#`b|&A?F-Z0Tw>(A8!uF1`n%j&Mw8T>|5~pRb+WO!Dq= z2RrDPQj$ct8vATTYI|K|N4kV+Qz)c=Jn#QdPTS(4zwIcW4)Uk%Z9%o46Oq9Z`n&Bvgd?t?Y90#ALtQT2_raO%|?q?47Kju2J!?)%k)pfPW7wS$#*4SFMTjf9TaniLEmk{ z5;Z1{pN|twD9*h~w1&49oy0AF*?QOaDu(x%nq*V=t5B}{3l=lzuykhM=Pyx}I+%(_ zJ%cwW8wp74D-zhBqckFezpL=y?H~kSvgVvCVz@BbJxD}kxxvJ>5zhNT|^sp9(+u1@KSlK9SOpHUA(*@aP=UKvNafR7hv zGz?2s>$j;vUmh8Yyd4*22p<_es&onAY4fRj2wN;E9L!1(#9%=@81w}Lu6!)ZPD>Yu zTfoIB5a>ievld6QioKd`Ca22Ck14I|IQ$FCl}wt)H-g}sugRi$n1m-bli&N8Y%a`g zK6*xvJ`?s(8%hFeMrsoVw662N#ZN;^@Ha5?1sFUC<(RAta!rn(u8Tm&k5tJFzA%18 zQKv?*fxVuc{Q8#^Im+<-Ioj+EP63sv{E;33)=g~Br6kNdvQ5pahPkcg%ecyA=KfaY z{knhZh_mFulycAmi6{Zpr|1pz2`gY<;0~h09qs(dr}c!%>9`bAZtqDDQDPCrz|1)U z0dvg2DMiJ?LWOkcrvfT~7zu8OVp3y~D}4ZVxUxMalta+!KBX(-v8iTR4|gnvt3}$I z5111k+s+vaTR!U1V$ZN9s(r?Zo{>kTJUT`(Y9WXV^}RHhMQtVfk3z%j0NB|H-hQ4< z0VcMK^6|8WTLEeB*&64JYi$w`b}Qob1TQr|p-Fk*q6@TOlJjUXec3!M`Pftrw* zG9xC|>5RT}(_5HlYnS8A#jz@V=wl}J5>mpat3GTYgVj7aNFW8nu`3iyHA@b}_RsQp zAgUWs#IHT(HG1{_-`ZXJ<^&k0fSI>{7so&F0C`A8{thN)=Y?@&mYzi7sije!lb7L$ zHS7a~1uuZSI}@D<`>=8raRK*fqd)g^m*NXy#go+xMbk_D0^D)OmVbGjPQx%|C}%2>5;)m7m=9L@mTo4|JG$vv9OQgy7s&~v{-j26gX)}LcJG0 zZDJ2JmyEcjgSYfK{D{4f5FER|d7kHPdU`4T-RuS-MUetfc7Nvt-uZ3;9t5(Ej%9%Q za(*>}&I#alHk&y{H*y&^Px!I{AX=tCXonR(ta@KmMmETT4}W_ipHTLK3Gy-`Arw)+wQ5SuyKjQEgva2rI3L;#>lc z-eADfYhdjS-kkqd9VIDITsiq|{9mfti}e3!P>KNSIYd|E;S1&xik?6|p+jg@uJ|#Q&a6 zK(Vo1XUvJ+H;W%MHOu}ZDxRPxYOHmO($>Rv&5NY}NTHwoBf56-3Sap5 zI{}BVi7nKNou1)9ZTMdo3mguk`?tXO=L*rN>r<(-{QHG%2>xHM@Qgj9+v)#oI6dfU z|E;5D$dJDrdX{;yL{!REQ3bnQ(3>@CD!a?kO3_;QTcrf~Sv_-wYiAy|gqX4Qi%QX) zOXDTiv(n1IgEh8#Zf6w)&tmI{1s289)y#>IZO-Mb(kvnt2ugBZ_jB~C)lUhbrSLbl z7kTcQB%ENEW(Z9G+~Tf0%~|4d-+ohbiazo(0W6n7uJ8Egozmb?eUcYi%GYxZTDS6{ zNDZzcA+z)l3_ZOHr^B?Lbl>%-r*=~2+YC=dP`K(GsYvA?uJDc77mWW}H8zaVn`N~a z6?EomOX6dFpPE+4UDXg)$#ed*v2MuICE@59U%$<9BU?3?;8;#eAk<&dEdkq*bG0P_ z=ipqatyVZU)2ervLn!T<$N!!Y}rkBcU;9o&YyPkR$C&)O$CRe zpNXkWC($_$jw0uRhn;FIz3=<&tj2WLkx>=>bNiA8rY}{YJ?|uM9HvtR1?$(2$sMmI z0_%KJVK&LjY9FN@aM>PSY~TNq$%9$G=A@fBidg6texGqe1X9v+ym;{&lILGvR8*+r zw})01ta{`Bk5K><|@?qgGMtQD1Wvi%;m8pW#U`hkiKUcmB)}Dm+e>@YI69OV0WA%nexH)G^ ziarw79`l|)yZP_DQ~RNL5hq8Pens#Zqe=pJNYB0izT#EC5OfO}@2F2nPyCK+i^{ot zJ*Ndd$uB}~+pte`<)-A?v!|z@amc-^HIn^lKVoN>Z2NGwIeK7*@$WP6@T5GGa&+t& zQYtO0Zl0N({NRX00kyQVv*Xc;26_R6$=O$Mw%3=Gs`MJ_wBp*nj;Hq?TW8;%m&AQ{ zJibXjgtFVRr(|T9>HhgK^W8AT(yAy7_IqeseEQ?Gh#EVHZgTcRB9vA7ndV1GbMay@ zuKhCm0>`l3qIc7!{W7S(x_5);mXdPf+CEnkjx16dDznhF%vNNnPzm?kt^RHuonaG@ zOrojlsL~@Iv7dFNv2~;M;Unde@SViq`}*pkcLlR+ms=awJ&^dkTlns1)#{(m;g_BKe7bzGmUpC{_+FsPfBF6EC|SBOs4i!jh~FnWzo=8X+3Hzd($^w^R+k>Ax12&A^Ux_Wvi3Z|y2TDuRC z%nABwJzDoI6;_v&g*&{x2>VIK%@i?p^iN5U_TRhv1X~I(dxJLZb?4CVPi{dPLd>-& zfd#wbL!nQlaryo9d>2=Ni2c^o?+ab8pR2O{0=*Gk@IxNfTim_VuWszBUuN>VA-awfHsDDI3S#q14cCF7EoYgw;*AI&Z|tcMaoVD?5$( z=>2_U#ACs$!AZ!X<_Po?e0aSP;l3o!9cdH++HFt=E!b@x)|+@mavN*eipo_8S|rBV zZ@i|rqrBbubiLpDN6V0=YE|E>-v8-=HWH+1S*Ai=GbP~*`mS>2RYmMc58Dwf%sy~6 zF{Y}vRTv)C7nF;8vo_6IETSf+e=tAl1uNEW-5bp{wBwZ&`SbIqy}ygE3EKnfHMc2;=a_3qO2fd3Uv!4wG|5 z6Cg;OM1=qqUv29FZEJDo1axe$jF&A#B%rDFbby(v-q(8JMaJPoF1O3&hvsixky60U zZGTNI(Sh!`7~lz;o`cx-p8pZ8aU3B>ltBuIs@*2JD;!fi_p+T^4i<*Pu!rzabTKDb@$I(_gmfn<(453Ts>)bZQAugNlC40{#ni1MzSi~M1iqXNeAFq(I@fA zKSexn*~fmCVWIhytFr#!rDNyf2his7diGXARxs|KaADq`C#m0T^m1CAgJZ8Oa_Zn| z=B?DXaGi)bT%>G{ z$A*6&6h*M;U8}yHsq+r1vrV-{Y$eTWAmiMTNp#}0ow7>U2GDFeXO7%f;r^WVK&TS$ zx8$5woEgPsjEd3P)Vr61zE?KJY4$Xt)(VK?E-PhS(|DM~%(+-??t!~bV5*kvo9A+* z=eGl4V=sq=T09yc`?;ZvVA}wS_K~(bpE%D0O_PM(@0=Jz+FE~V-wtQd7g*m5)o(mC zoVoCyIW@aJiq%|8>|_cU5*53JA|`P`2gidGTS-pYEt`7R+u~(9dbS#@JT>VW(GJT6 z=yS9fXRgvY^uuH+f2Ot(Wo#976UJPXmo-sk8na@1;+5INX`c|sVtaGX8&p?bST4Q* zU2Im>R~HV=dk)nb-7c)L^(CJup9h*)3at@=R$QQ*ZrrO~K2>#KiB;F^6%$ubv)eKF~eCY^lla&xmn2{DIa@T%=>DlNS%mvgH*6 z)Y6jkHi$T{4%d(}5FFZU$Qq|>Rv{+xXWnb1zI+1Op)qE);92zp*dj2TM=E!SQx>%8 zMrsaQu^kXJ&9ABkyg;Y5SOsK%zWH(TK~8v;O%aJA|rfY)7`L3#LaZz(1*{tpQ%;@ zF`tDt3n=G)_#4XXk6vE|Y^tXE3W#86j*x2;;^|bYvD9{}W38NmD1%?b2rDi>UA}u9p9YZnGFtK|HvXCA*uE8 z`4&UF1Ucvw)t||eNSSF0x#j_i+TjI1;-n8Lf}g-ef2WW<8a1DQ+4O0OrfR0OA+Kon zi}0tl0L}gzMnnUrZCIFA<+TtQdqwR?j<}X)Lao5?Gm(yY>dJx*+57M1ZEX+5Q4cTL ze|HJr2C;e(3<0xmqAA4I^$Bfwo^? zUnNTFs0LU?7nXg4%p2A?ws0+6R|a@~i-$6#&v+~9Bb$Vn%X~N~UzkmcduC*s!&}9e znvET|1%Co>+J@aByud`YtNWWi!Sk1%_GWgSDWxV*{pI)z00&s+t06Q8hQ^VU38Ahjuth;_@dyu

osD52^GruJZcDU`>rPxnYhhB#GFN$3eRDt+3wnUu?SSw#$Jv z1LBEJ6CODi{VEWZYfZ*Tl?F}^=_F7&?MBY*Q^ z1|mbWlNY8fSC(hvs=wI;aO)e$M@bJk*A*3448cc6MjAJuKmP7lw=M)1df8YXsEWcI zT{)6T+b_boL3b#ebJoDB^PD~gYk&CAHLN%Dy&J;U-21_0`_Abf^S6uV|Mx4Fu&Ym& z@woeQ5{c%YQ+7@+ZoyvcmW`Q6eX;I_eFx|Eivl@2eU>CeyHk-Ytb~4Gi>TxF-nDa_ zw{GU+fl=XHGee83=ckb*ZFHt~R=1z|72xSXd%+QqRrG0T#cc6ywx^4dXja#3eq-KL#-GutrkG!47y_cf3&)uA@ z93@Z9GGbIUC0lvL5q>6O*&-5&0oAga2WxCxM6 zTgeEPRxo`RyG^d+t&m-NAJP{sod=a7$Jocn)S-4l{yeq)rWZ@0*&FWUIA5!~b)dL0 zhoyD8+mZsS%dQi*aaN+6^Vam228TRiz2f@tL1TL5p;$KyQTXpSmW~oV%OJfN&Z?)| zOX&c$I_OPIC}VoxuQtAZ-wT}=?ISRdZHE8JrZQEtZ~wM8+Dxl;+Zp9lpNK5d_E5aY z(!?Pi2sXbZkOj-REm-uO+5ILtviYE{Wr+YFl)}EOPN3Xrx@6E;teZ%ZYuLAGyL)BY zWC(&4^V|~(d>OwP9aL$kwV908{`iXU!@^Tt)kgw0I-udv;mU`?Yk`;iPY%XeRTx5R zer|kA-^(il@pH0HA)p2xLGYm!qaG+#wC6_Xv|a__*y{6@PNi_OH>~QD%>Uv>G1B?g zp6@=uIZ!#c%u|&>H+H*|^X*dk4ruB~$isg^3g=H2%5`BsIqV_!@K1XU^NDI=J^@R9 z8!bnwFIma|gsivMbsb&``N)FEpZ&027MiIE3^?^0#W@J+Py1?f$D}pnsBv#_@NK*h zbn53bC1pVp3K|=H>pjk_n0Zb)lkcu|n)Y?uKNQCmfFDI0%6O;9fJHbApBv(3)!(X# zuLh=VCGEtT?BXhTKOc5(As>MCr=_Q7XB>E22TF$l{zqT6AgM`7jq8)&oP#r++nS=a zIeK^#0ADgr9v&}GbHfw_U_Uw!_%m1og5vVARcXOP)Xt&gdO+7}zffORXFuzd-M|k> zqP=$L#m!V6{MkB#(aIe>0rpaI9RSY0Mm9c3uA?_7w+yQ--Y&U=w_slW-vO()4N^~6 ze;vc;{|m1g40e3BD&+;HD6Ib0_b!?vyFV`Fk!cryv9m*ksavYJqEbM6pf|M|-}o zD*7PMdBlw|Nl@n?sId9ljELu`tC3q5eU?V5k#9=Q*>CrqNv3h%Jj$~ju}neFFyd^k zEN!dbEIf5i{_}eGrU&|e12D5|kA=d7F0YH~eeT{NAsoZ@4wDVh+~VTg8F2=COYmY} zHluadtPkp%_F>`(hxIb)F4Q6jQS9li5@yjAOu{akjkz0pUVvJ}4gt&t@i_}5v*Drq zJ_nbl2Y*y`z7mdB7}LD&*Z^5+{gxwtK8(fmarIDG89PiOYRkw_WA8k+RaSMh{DXV&C3IM#V4&;*eki67PF~mdKTFH2@2}hMm982K;zWjS0|CC; zyd1eDMTJh0)(ao@tX_r22sGm*?7H_N0RA06V+AyMC7-&AoJtj2Q=u9{+EE=qfLv|BuOzF}16$TYoa98U{BA{eZl z9h7cS)iq^!BPSPzM%9i}f8<3egb!y>=Ww9k;=8 z^}uUzKe?Z^<%_s+o8-dPQzv_r@Oqs67LInp#+bSK=mT%r`@#yD?Hs}dlKFx7tv@G4 z8$vrRMMBP2k(vr{G-pOC=ZPx0LyX7oa_<}sbn=>hM>|e7D3!@EvhyK_Oza29qym)LfcTPZekjW!!qn6#*L>%nGk_A-_cE>a4zwoQT zeY|(3aTeKQiBmH=j=t$d7S?ms#m05LNQu@VeI?J>BJ%p0)ADSt54x5(&i*|g;GlUw zBkzQwgZhwX+7Ixh!Tme6clI!~iZr;`t@<{>fF=}LR z@Ty@BKw03k93p7}95t3uci@1g+%qK(u*G~Z%Df&4-3RU`wf0J|)b-spya6!!n4%=o zivkGvFsH^L0 z-|ZNZ`?*UeIJye!aSvd(Fvo$w;r|8bXSc)_YROpCa`vwjLtg`?ac2R=6<2%4_jZ8N z7K}$DB5+E5I(#|~m_fNcA-QVO!55>rA;@Kj^SfA$Sn_^w7bGrcBvCY^Db9Rr6eEH8 z_$HKg;|rn+Up^lgAuUhqhQE(n9VBi)5c)tk0!>G zP_P~qtO@v(7=SjCwHGh2dA~wKaB0OFVQn{FJ4LC05TbRnhb`&HTovig^H>aOm(LH~ zzU#1PwEu%;hF?3wV$*{{+KjPB+YE)?vW`JKE`>=@ycbJ?O}|%eL+gWq?t=nR#j!nc6dHa-lTwvN_r&e+W01uB~NJa-=i+^R`ze)8a+)aQ3C8-%&-$T1Hxy ze_l&2{XTiVp+$1rR%z`Ny@b;h1NBPhQ6B3sJ#c6*z?kb6P8K;HELBskN*r70nJ+&N zPRvQLO8>K?rT1Y&Y)~Kt$Y_Sx$BXHU0hN{iu|g?VX+2a(ccw@i(S3r-zMo@{B7A6) z*w0f1SKz5V^hX$GTsu#7hC5HZ{{NVI>!>K(ulN=E6S zL6DFJ1-+%ay9A^}xg(e6m%|P$1-zss}2#h>Qy@VV#6(=x2X39mDfKNK| zFm95R#I|(QB6f(q3=kv8;q(C;7{~tA_GX59d;IU!`ZX^Oe}^En zEGGKdz_)-Nr9WX^B|u+x5ceJ-0Uekdc!5B_)q3BiAHX+k`lImu-Scg2`Hq-KFX|Ay z6~nnXiHqf^lm1LT3nQZya$}6{A}p);=&BDszs4s@tEk_@H%qeJiO$*C;Ks}{U9~Fe zZ(_fc&XN&_XWIWAU^qx^bXfR+Yk$%GUDP#S>Dt5q*1~UT=587CY+O&2PABczmTX7U zaQdiVZAH8Hve@nlG4WKnTl7;dYM`D+Ga&J7^ohTA)?}x3q5DGJ&#KVgg+<4s(K=io z^@HA7gGj>RA&puN;t@cAJ}u7If7)*%E+fDw%R6lN+am%J%(yWApsxM=r1$5J@%TES z$XTmaYuVd%j*=l)a&s_d#H}ZjqhZp)g{UA7FfnVCH)ksJ4W3!fkbIf`;#lFI3lD#F_*+>HuHqG`Ex9t*! z{qT&^#X7H-xsF*ZY|>@bWH#UICq;f2`lQ!8ub%zYsSA%Qw*NQ*T@J3Ksb~!uq<{HC zt$O;uZHR+|O(oYf;jE)-oTAE5N0!viWQXiXfc>r4ls8p{^WTB*hu>T|3hODAk4i_S zeSapTH>bP2%#uL1H2H=R5`k^mpX0lCYw<%SQQw0}pz8}`_CtMko)@s$1@vDBF zq$w7WLb=sih;$6LocsbN zxwlQCSd}9!!|LbZWO8%mY8ua2WZah|9diaY{e29fB2sbSDLPi!X;BX$Z5(H7*6@J5FG%{tkbRg$nEjOqE~6bXwpZ(#338p*i9 z$ut!@PJL_qEy@!^iG0v1em#@pWxAx-($z#|oF!*v=UoeV1%^e;-?RN5OUl(ELU-%P}7hx%BAbV;-VQ+mdkoYgvTD^Rcp8?4&_45wd^T5LiC1#eO?=LwJ zXX@l}tQD0Ud7>>FvK~pb53nR)d7MV|t5YgQEbtg+_O87gCI~PuA8OeF@yyIHLr$4b zlc@D(5?wAo$(@)ur_~px3QPeb{Ed=cIaE!|1%Ut|CD)M)N*u7+Rg8x<1!YO-TZs05 zyn_GNZbNqTm^3sqqCx6QB*~>2wlF*yiYg`R9$_pZA6P*!+RDaWo=}K0ay@yxV$;@S z4=i)k07qsoA!k-bzyn5f?!)miusC@@$;*8AxU=rW+~w3EZ6WrHeR^)TH8JX=$!q0u zdxuh~r&!BpIcY1)0BsPIZ;=vRW?MNiqukucOoKyMT$e3m&SDr$ju*9c}4GxO* zMb2IaZNY|5+x{u>)7$9&$>8DosUo76;~KRB?L`lx>V2VGx#^L3gJjTse!JMnZwOS7 zsa@)q3S4q6f7^jiz`MN}zEuWOlUMeZcOHokc?8m%pUjJH_hRk%tR%G5KU?qHrP+dV zpL~zqvYgEeoN?3{35w?&4?6qVSk^}Jy~3gQ9k({2nhcH8 z%fBj%(68n~e!qSFBUb(TCR_@bj5%O)F-oq3?ZM*3@v8ej9pQCe#Z>bwTqF$wvfkz< zFJFG&|K*g$&;MWDVf%tnC#FkD>a)>I6FZ*!@s+@?!PjOX*G`7tSK>HE+O6ppo2=Pub?oXp)}75&*}+;3x!yBs4twyTO+ zA98cqZ8<51Z=}XTu4**$f<3G0L#{wC)V0zAwWJ)||4hHLQHV+${V2=jo1f4pJLqUJ znHq^8?1rZHaCb$0F&A2{E8>nV;#T)B#-jRS&$>!6cR-6?_+>mdH_-`iEokckTR*a* z7QeM(2}7nDwy{!?R8ucY2WyI#E2+*-gJ%!}Qf((~-frT4P{)e#=OOw>@VIB$pTdq- z)4lsFYRi9(36Q!qdF>YQ4LF%HcFc}s{s_M4==Xuc-U0Bvy^_QBBHq4q8e2ERLvs5q zxnmF2+20m-{>*yenqJ|lZG5w~-ILK@@f_KW9Hq3BDqrzcTP@YkhP^K?u9?4^n1_Yi zu3Qu!z8N&{Zs;7Vv&=RL58l-3pQQ1^bc=3@YaH)axm#;-?yUPb_9wgHfRX#?V(j(L zLta=E6Tnpxai03jc&qV6%WDcbU0|^dk=$J#H;H(YVGhd*TrVrNtp5Ixo0h+|=(-8?}J-uxvCXOVz$Gjh$( zt;5ienb#8P>{8s|S*hBS51UQ3Q8a*vP4V&M1o`rd|EdPfGgi~6_|a5kr&!PB;$xo0 zSA6KZbz6NVdIo0A@A`u6*N(K+iKWZ6?B-FDn?`3llrQ{ui|(rqQb}`zmTbpmvLqbK zV>U$J*rdmwfPLcU__Pyc{mB9kV!r6LR2v+2xaH}WeC5&i*`3GPfe4K_8@dg~dg}KP z1iRwoTok}-PCnTE`o!CO?f($-)402d^Zz;C-G}qS zYeCP%;X|3xD}i^p=)xDGk#qL@X{^oLErcITlWoSl)~d1X$6UVK?S$zyA1wH14_16G z_?51t_l(<|lR<}dhsJWzq)5|7PYkTc*${Ia9AXY!%Edn&xs0dV<#R0m)@sC0i3)OF zdc~nR=BKU{PTB>W9kE4kk-DLAHk`*Z%%avkIO95hEvobnfeWShAQ&^sGZ7a07g*={ zl-%}NsONoT>ibt5H;;O*K&Jtiw?7H>rsa>P@P>PDyjnMz zmr@%;W0T2L{T5?QV@8WRtIb&t9B%mS&Cm?823jmPZ-3*fND{hDi;*4>9!7hHRO9jY z@OGXI^9^K1oo0wwuW{VsMnPameKJ55(~c_y7t^<9@Q@F(D0HoDQw+;9&XgJ3j=fmc zLr?SI*$*o(uZ^CIf;RekCbbtxaIhp7njM!MD+$=C1?T5~-hR=T=G#QI@{p~*{6w{j zrNnry9g@l!VcYB>*~;w^90nd6Y`5ad(_}(M1xI-0!Jt{q+I9FH*&>6|H_c3D`1Z)w zZ=x`SPkuQ@ym>_%%HFQOS^K(JfTwZR{rMr!ZIZ}>O9=@ywd+Th-{gJUA@(NACjwT= z#4ov3d|+(8L>w5C9w%&TVY&H0F+^XkA~JZ=H90o(sE|y^UB_a$?`S^)=So`@iH(J| z`@y@KFY`jha>GJ1SGxW+5#0izTYS*Kga(s$Z#yysb`#V-ehf7!e228#ys5UO5S$YC z61XBqXTrKh$cA0?51ZIvLIOG-(-hB1_vSYJcXNX_X`R^4uorl2*w;L!>28~By=2@{35sQWoii|wB-L>ZU8+GChN`JX0bzp z)sw~nTkHFOjQdgB8Ise#dA@Sr{moI4{2`MfwQvs7H7Lth2e-d` zR)_;zW@)W`lst^n-|UCCZWh|Z=IMk@8O$)UvqP`8h>(daOB50bhY}Fl~jY} z1@-j8KBS~>EM;(>X0=}kED0R&aLLa%kIAW|g&Ms%`}~}3=@<)hq)zEtJ;f(!H2@w7 zzU@mV)Ez63U0gt)5b4`(+_l?R={rDq4?-pFC;qx-?VDvZhm74j)yCUmqG(k$xn0T6 z2S!oBrNd{%c$rSmLZKekmLYCNS7aj}rl%cdae6-5jx#zyZJ=(1kyt;!`Ox)#FwNu? z)nY%<+6&gYjnC3!-^pS@iIy*Vdz%b>3ztc~8&cVi!G$!`FW1~%)S6!4Jik?ENB8Y~ zknt_R3EEjw(S4$<`=nn(y>XL+Gu*+fQUOv~FvusoMd984!K~75md}2V&u@>54bUR{s_xRxV_Y9Pmv9a+a;5$@po<0mrDAfKQKr?an zI|Rfc32E0kq1Ex#0A#}C)YO#t>}vx9%60&;9FlbXEC23^>|R;z=s2*L?cui%obXn6 zd7nPfwy#Ig6)7t#mnVh*uRn^~-QCqNC#8Khgbs$^?pdmijEtD(-UEt>bKrfc{H^oZ z*W$!CK4w5qm)z~yugSpEE#*>RsXg!zU}%^9Y(}~fTdX=;Qknbe`T~72d453va9CMi zPfsRkWPCgcV7jN4SS-B-XdIJmZ8E1>M{iM(Nq`eQar#dlSVo>4m%o<@>LKI`=y(7J zD|cS)@{Nl`_O5R~oK&aHG@=f5L6rbP_zL*vNtx*AtOZ&)f*IR^IrArKY3}q9y`<0; zK+;zx11giok$}`YvHjq~Y<*&c|Fb@oI~N0*dB*oT0JQZ_M^3Grxv4~t_Vbx^pZoL5 zcjq$h0GW9b5NumFjn-&OG_xrm6kt<1G;lRUo3XMdv|*G`9*4x zn3!1kie-bVvG4v|H9x9BhjJjJr|0?jUO|FhR8$n+xHnMMb1%I4Id?oyw)OYwfs~VD z`tY#&FUrenK<%P$2cQ-*of&(9Kv~P;+trVT7S1d3Kv#h#WM{Fl5_N27=B4a=zWY0G z_6C?FRFZ%ar_~mDU_HASU^%<`k<8kxmL81f%Xj|1PKy&?UGZ`1kEJLv$HNNUes~|8 zw4;TSYS_8B8iVla2OnhqZ9uekT-XJSvBlkXKwO^9IRdbyhv|E*o9U*bm!vX(ySD#( z{k) zHyhIL*dNDO090y++aaHtqM{yjEdbSUekLp|EFJLIO4RWcOuz>9h z+b~B-DQK}&(~t)slZ|`lPer*bs;oj$UZRd;&+@I8+r5wj>9A4hf`*2MMBGvh_k(&KxnM)6Y-KM2I>U^QMFM}M-x2WT*twM33wBZU>}}cOlD~{O zdYfBMvw0L#<=(6Er*UR^*|?$VY0#x}CA6~hU-|a_>?ahr*zZS^C;WbsCpA~3mK0xp z-p~9Nub1-Ix9!XM-cr;}qwjB))p29zb2gP~nYi*dys_x0v$-LV!Tk3ezx^(6&iAQr z(NR}bzdU*w;P9Oc`^mjddA_S+eTzi73v`36Iy?Q2Ue@kjOQlA=Si;tdUWsSG^|F=e z%l#XNm{u!O3*6@Ix7fE}#hoa&gmj}dY`TD%pZ=08?%5B;%zJs3*tL`5>7_V?z~b-0TLbCH_npo;k!9th`Lp<;-S z1?0v-g1Fwh-FD1|C*_gY?}DtZmdibPAzG}s3(cU34q z_iNoFZqizioMh6H-eLC%IaH&7Nf6%t=Ig_OD%1Rl%R>T< zCH>vRmO=r3Xe=uhW>xD4xxuC$M;^$*`|4PiFGqpDr8fWM9CG9BKXVvG${adD_7M&m z;Q)-i?Th=)FRMWVSh1czfQ9|+$WB#}O$8!Em=~Q9Up;DlPJ{ZFktTfzQ_0N(Y{8Pm zP&ubT>5kMRI6yu68K7i>(JFcdga(9cF>X^D?z2~K2KIgHb(Pc%ZS+HhD*~16*79^L zEx^7(v`bvsa*Vj~0E;@2htXsC$>d&6(d%%5b+x;3-T2 z;&aCzgmbFXQ6L}2U=n1TTb;+zC}KolIigwZ*)xlV=n&Q+pTN&V8u4)Z_;7ng9{mfd??5E-mAEaxk*mJ z8Tu}-G8QAl8u!hkoL-ep_E>dS9Ko3wdL@VqD#u3yhkAk0$Ig}FZJyLKw_K!gYd^fx zT)P^N>rH08AchM;o_SfWvA(C)jOb{)R3eJ~)P48|ZPsN;g8J~P+Hc2S=xRI%%|T*Q zLVNaI-fuVm+C{%*r5!HVan}R|ekrps;JJ;qdjYeE#R=1DH8JF?wJ>pJ%}q8ze5Dcl zt$A`29;dlbWMwm$@}~$~R0m?=)V_eUowsv5R()gR)cVnR(~zRZ-LL+PF2|WQWnx^S z;@d}m3v;*Ov@Dtrn89{0UfYNBkn?zJWIg`edq+zOaSMDKy6@xp0zIdoAGY=T&WHag z#g|7@I!x*Qt491ThOgA_t(!%HY!)xqO3uYj7W79(Z`I=)H4=1F^Bj+M`j_=e(xw?~ zSF{P(GZD&=u=vqrQtJP?(sRcO@_Oo;P#PV+L&^>uN#-m%93!8;5#9&IX1=0(KS{tw z`VJZLoX9kkn3V*|_`VvKB^0tRkhu3!pt+B_mOwbkmfDdEkB5GmzyRcDwG`{eyYP&I zx>|^t#m)<2By^So^au@PMkrkY-mh4q<(ed)dv{iR_=9)gAw`La$HPf*zt>FQOLHvA z#hMNDLe{@_a?9q#MN(+Fjj0L*j+7bK#)~rG3)`zkY{2%7qRFs|0ZDH4b87YGfOC9u z#C2E`F4s9QCQh*Kb`ijU3Oi~ghN!v#Tmi(ZuP%N3)Qcb$P|#93F*dE1TLkX(5!2mY zeElPZOnW|e#fS*64|_G9jB+n?AIbvLfp+T!>a7lO?`Ms|e9}$VhpndZbMLNx<;Mr$ zA(;-smQWGh4R|u~Wdt!olr{==&Yzan_EoKV+Pf6o3lCD%Bd+_-m%K;#2SPo%tCI@B zn2!z!gkubc-c(!zRD5Cdj~OawPY~ytM(=i#^$8FwbNQuxd&Rq1DCjA;9TgqV@< zyN5!6oI&F>%|UM>A%VCn4F-yc<%e)ns=!l&wXox?YZ9~0*4wO!Nz*~YE1*eAxMZqy zzkMJyt}6Bf2+oCD{>Qp-lmtIxOYP}B=_A+9yh0l7X2D$sndy}uuFaa}lLAhy)8&4o zzgBnzcL=`<4hTZ|8xAZ3)*~HqtlHK@qZweCIe^Ex1^@fBV02mv*-AxV_KyVFPN8)E zirU|`h5yjaUz(J?WeWbJR)OO%a_=|gTRuWc^2+AzW+6&n*ADxfRc(Sr&RmIh=8Ff*x zA0re9`=dKsirL&B8H*E?8GVef8Y$#*1azmY;2 zU;8kveaOn4cEh6jpV{n*@?}XO7L|Q#m~cP8J0?9IR7p`Sl#RkMJTkX_AAuEtTP^h^ z3FzQNeje~dice!eO7{<8eXMS@!8S$U=T-_f(fVZ=QMuZk*ULxoY_!ExQEc?7l9^sQ zi!Q3J>y(XMWbnV(r^^;8_)EZ6e+E_JDsa5mOxp|!=@Jd~A4GABA$UNco*~p9mRmoS zpW<;C0yG4VV@V)(}i2&Mnb5*qTtKX9I0P78pcv^)51H@ z&k4NkMvDn}GumC45UVQxcHdEDKN8fxoUt4NUdKbvst984#+-ts5F%40;1a91Do$0a z@M{_`@^@Ujpoyff5_GsR)sd@SH5k{L_l;A`d*Baj$v-C`z@Vr6Gh|P zx#%9pOoB}5ehK}xYi+iBQ=U;aq01{AQQ*FqQzJS<#M*vsH#9^TIc3C@5_nXR;b{x~ zpcf_*5Ks|MYsjpczd|1=St_LLKre5k-Z=e&TMA^j=&<^0P1eUhAWQwKbY$qb{qr~B zr%dg&D^P_OFNl9kq)3Sbd8dp@RtGLy7^QJW=Ls1NkL>1(;C~`_tT*H=nv&e4mE(LD zogPCVN;fmD27|}OsQ>c!Ow`Do96zmXSD(_nlKbe+a-txD>bzFeN|6_%71 z8a}D?gEjrCvTCX+JORI)Th^`iG;bUCyABl|_Q-g$sq%E4QlqIdiOPmBIHbBYF)+U~ z_%|79-NMSQcakai>5)Ij@Ow?%2%m*Yvn2>Daebnm^$8S5+=d{k(a0;VRZBPw$=$f) zzBE9`EKPX6ix#9WT=-Um8HJm=lU4KDoVpcqb zwGFOJ#ecv7WYpv@{#Le?vUyfgY_8g6{H5_%zQd1h#BZanW9M)}iO-|I#$LqC;pmcJ zQC)GPN*sFnY4LU}$vEk3YfZrEx37Z0(Cy3N|No8>6t7>+H7K_g_4iE>Ch zC5c%@sV0fs$kU*N@-%Wbc`T~kG2(?N%XiBEqJAJSTHdrzG zB(?uA4tz2SB~CG%TOSrM8U{d61FQ=S=ZCWw|J)BD5KUYE&cpwhMWFG}dFSXl>)o)c zO^?rUKB`gPN%D1$*T(4D#8v0nTrdx>x^|c&c_MUxVT)Z7ZBty=7u&PY>yqQ0w9Jqj zEu7%v%h^&`^j6;sU7C1Bc^X>*b@$58zf2E-FQ8a9%pwS6i07XuKt}?8;qbOnmNmK( znQh5J4gFM&b_izPh;M+Zgx@!3Xr5vt__MxOQx?dw{O7GYi^Nweg?#c$Tyu#3oVUVh-`@EoA52rX)ybQ`il=PnmOT>lr82sS)L{| z;)J$zThPFBO7|Jp)vJA@?L$)rh9tFQ;on5VPn1(&vyvChv&<07eE`yMk#g6qun8Bb>%@H%x;NO z-aM(#8i~0QjUAn^A+>|j%GXGzIG|^VD7EWK<*Hv3hFc#l7@lJ%4|^nCZJ1b6Byo~sgwqE zV?^kL)jgA}vhDu2$w9jQsSLB>bDum)kn|{^sNmlL&eoOCkcHpx*Zj^#8_gYaKE6+C zR!2ZHugkiV5$uNy9t@$FleFMP@+Qyn86$TFP4P#s+YWdwLJ@RDmdsY&&6L@^v8UjW zFm65|X${Xl>Kj^_3@KV!;ERR?B|{<&gR6+W0N2$4U6juq{mg9N8(Mb^@N_eEW(j=N zB5|OaJEXQ;qdYDwYa%rH z$3#}!U)(_+0L8PBW6WRyv+zRr{a^{L4VtZp6BZz%HK{_=_>_9AdEh~?kEOO#hSgE+ zw(+^XgklORb~gAuOmIIJS`&otpW1~8pqLcGxGY+onw9+KxQonP6`BUns$d6neRQyY%Um3-1*@!Sq^I(-3%t8zM9}sL=6G&&x z`oZLsI+fE#Z+IF!SZTK|)zhAdzYx+&{%;$o+zKh3iB}(w(gXmkS*PBw#uu zY~v#B+txhWff7Rv9O8K0&n?VtVy*vq3fQFeS0}JcYx*!E9oQ&)@Z=FH3U`MUVaGec ztJirvOn9ah9@`Uz{Ik)X>p<2;EOGr}d&v6NM>T%95t0SPe&*fQeCW2zv8~o+{V0f< z07=p4N(@}czLKA_i_2oUCFj1SMl~}Yl0V0bFpNmv@&JN_1u{TYWXEb~@1hFpaZhZT z=honsCOW)9m9Dh?pYkuowNT6pfEXpp%8MhA_AyOFyj{b;ODbk9l>0M8e|W;db$RVi zsr(|hP<6R&IN`W!7?-huT$>z4%mmC)uAp)4f@tW0}Q7#3m zdig+!dlT5t3S$tYMQ1(B-YOmQccX&oN(w#0r~K<;Kt*BOsmv1+S?)xP|4dL`F?%_3 zxcL_6-REBKQf-^1{^o<%odoe9HkM&$!7u~uFz>mV>I#0&q9Rt?Uf zu;d%5q>_#{n(g1Mq)(gWhF&BNF=CQ6JYm&h9pD1+4digH77`e^v+m{pDpJ4*I+Y3} zO{Q!Wxw|TOTH~ltw}96}W?Ka%3G2cgtjXB!9s!36ldzEv7_bsBKSzkYvCc`LXz~DlG8+D-yD6O2+E_6B00*>4X3(7gxnN7ng1|7f6Y ze~5Rv^Ss$ks+^+`-l3SY#K6@?fWXX?*M?+E`u%cr_2iotEL7d>b81(4l#-z*T@-jM z2Y$7aE1efSaA?6yL5*j5#qgXShK&sgi#VM{}L zIB+s4-doY%148!C03U$Wo*iheifl^g3M2TWW@<4mv&A0YsqjV=T|1QMg4hEw1tmm| zy6o3xq8!?6^nu%d&rPV`lT+L&wW;W~ssBJB;deilK3--(BAxxM``yX{sRf_OP98== za>_1$#t{Xf_(GPF$mzVKjIO zKtP*|6{dd-Fk8Iu%D=KYOmO-%lnO|f4{rMZ{J@m4OmNjz*Ww3hmOj1`%*8z>&~nrx zShs?Ohi(CNPohOwU5fEu!#2f_s!kb@&QA&KnC0ayfvvh&@c}JXxrZ$Vx5U~ajIORt zE~kHhkv+xBtLWGbB9WA6maA+ze%!uK0Q#zPF}ID0z!jpLQUQqi?&D`_Y5(J-J;+$z zs9gU~onVT7mC>$HJN-X>&rR24pJ%4h+N-_?#UePN`OH@;PYJBv6Hr=MmwzLUk2>g< zQgcDRwwxAC3Bo9rIjCn7%6Y7aGx=U~5Q%?2CM6Y>dqS^z`}n+{NT>l9hlL;lBsmwn zWX@br(?c{s(D%fGd8L5#Md}l}YJx(dR$6c|*ccb#YODWeEuN+PF^c&{3bht&s}vx5 z!Tf$*dX8Z~iW^5_$um4A8T*V5awlW}O6h|ije$gfbe1Ksf`d7Z-u6fvnQ2V0>Z`B0 z{wSP&W?+$0z)gn&0*t0MxdsvHjwGt=;cMaJ3vyAZ)?+zRZez~(Q3c;bohM-8K$nH} z%PTP)`~44YNdS+1WnZBoB<4$#W-v6N;T)-XsO#1Eg+I(@psgUaRBnC?Qr;05p-w&Au1f{A#Im%yW#mrUl&((M?OG1}tli0TX0fkHp+~lb(gz+IA-z&*9O>vltP8pl) z7k}fD4M`v+jy!#M)h4i+<_5;F&MeUqmIgQ+KRj*g zxRmoC`NY~+#ZKX!zY-BEjF+{>Dq1*d3)tytXiF;YS8-9aQeI_iNl3V{sdg5l{@!t# zdsGMh!?IN47E|3@vS(ddsu}kuL;a2Fd#`M6rF~bwMz#ToVU<;1Rfg_D*CQ?@-@&x> zJ2%Tg#RMH}M8igfVIIRnRf-pe4l16DKq{bNjeQM5p!ZL*ZXk@$-~^Au~XzM$~|8) zEEZ16AP057G?>-`cYl}I_7}X(Lp+T?deFa3r-&9%7%BfUeYz%9nU;rn2+xGK1m91H zUSuWcC!<7BgDJzJ3c6{D)`{~$J4kkUQ%E5W?*Q82Y=0OQGq<5t6{ zi?QL{IYG}+1;QyU*CX2Mt}iFG`HLovBkBZ-c@jK1=Gvz}#1k}L3<7Ke@K@iYBTyG-y_i6Pw>kRwbl}EGVq62b!nRLO*68rAJwyfI> zm+J(JbkSmo0+d!EZqIxG{)iBt~4POy9 z3Jq0iff)bFO78#2O2FPO2qzVpWco_hX+H2?X>g`FpWw&$4%?#`D#;kvKNNj3)T2UA zv79kG08#mqxeYbGu!-%GZ8W`>0evHa0K-uZ^5^LiT?FQ5FGT`{>G+3!c4}6yIyUN> zG5WcTpYwzi=a>y)dR%4a-XD&RoygVl2&MMf$PQFI$79Pe^}e!pm7UgES9V2 zSx4y>iGvWlb)tg=Ux711*oF@iND~wiJ#8;3wjD>EU0&QTJ0L_l=WBCApZzH&SYxpP zTm)+DYru_AeK3QY9jPmtqaXIae|pss4iNKo6qYXz(bWk;MQ?s;uWbmt+n;OU_d`V; zKj9L_QW;R&CBckMP*Dn80>@Lk(A?8-(Lf%|e$k6b31>2d#6GohUHRO$Dk9SJDaKLt z2%XSHDk}~?7AfJCEGyk^c6AQbM&FNAt|RYp1A12kGeAdhqNp?6B^e|j#m^BCZz1*@ zt&L3MgHO0uwwX+oV;4?c??DC@S6)5GgRh*Mrs%V!-mEf%}| z`kySMyRn*ijBUzshFo{;3D9^|NV5tCu{N*`Ga==9l5C1!tXtW^e~g6;$R(W$4W><|$NGBg}p|77>aJq+F2V z*~7Z3Ob8<=V+bf|nT=B)ua>XF_o1Ibj7o&o+c@@78&K~wylhf*((=`X8o7!W$W|vR zJb4izNLT;6gv#a?+#2(~o;79AsB9}Y`t{C(A(CT*5oK|KA@BcsJ4p$&df}hx$bxSer8DZqqQ_{~IK2yGlKgI** zGNqoVutZH~|URN zpK}@%!|8hK9fD8*{YdVK%D^p!I4gp(`Yf2v6OI$F*QlZvOP;L51Fdtv93n_B@{B-_ z`b&noq{jU8;ClI1MliaJW=0%lYSQINHKG5k>!1YTR+#G`QeFu}l+d#prNso(ob``e z(MNTg$8io;tNyD0x)3q7B*mqc>`x+?&B#>LU2c3!%UOAG!?=nvJ>4s>LlyHFHlg3U zexP7ym}55pJfT`y&8`~HgdTp;CP@VP{r4J3rfuw=o-uW-s!%JMP1Cs2#kjpZgXF{= zm=lK#F-8v!euw{yZ?AltaV;vz`R&~mZxP`@jFF?oLN4H{3d<1}bSyuma@$?RZPR!n-UcX4J1GS{_~QGM~dOB8#OsnW<3 z%KWx)HCSrH^)vSXeV+4yB4kf(&1MnrcJwIgGxs9)K;4{IuL}GGTe#444GTdN$hn~a z1u5F8Ndi=}TVX?-k;RVL zBszqQO`i2JaSuL8n&isT;QDkgO{mW*keqI{@shUkjP;AK_3YMFRAv{FZq^B*WB|8Z2aE5%R;JV{`h4G zs2@WSZ#71A*@8@$gLy`0P>UCeBk2!z`xnZVv8VJWTzAfbY0UgN*QrEN-d`I3Cb#%T zAiP-(9%%X%W+WmaGFk!O9VoH%>TMqw8Wh_wgN5sosmkGrte_WujJm(c(f*8L35ydO z@;X3ZbCVUN7y*Qg1Ro+>)+mX?dWuRA2W~al^Kc_4{3ZMdRtvY#6Hi$H0drACw$?F! zVl+t#L3{T2JT0P^2Yy2pN7~?hx1a6%FATbd)c@w4srd-7`W_+PZyU~91eZIcNA<02Oz*wvCt~S3g(bH@oHhf7ZIt{ZBWc$(Z z`Z;s&zX%Xw?=0*%VaNc=pjg-CXA~~x_r5ENTZ2-sf(64yCeClBW!SSkN0whO^h(|@W!Y9{W$JHi4j zg_e^RF(nFDU*|gd0|qWVRoI#e@~DYHqw{j>V(@)loqR+Tb+6Y~ACLXHF?W+iro}kD z-eB<}9o2w@nCdyl$LJn@yVq$4j}911KOL+duZelsSoDg<2R^cq%n8oPu8wcUJS9c{ z+r!;>MV~mTlzGo0fRu@sfWldx=N572;5* zl7Ein0+Q<$o%J{@IU~uW5+Sp0OQd*(eGnNagcR{v85_d}_xZrb4*cN6doN~4T+I{^ zqv!=k%t2v~_O&qLw@D~b*H;Qpf0$5$DGyS_FnwgMF!zviYBq22UA!w&E~{tFNWgMO zwF9R$FRf6_ysUdzTT|`AmjM^;;u3==7T){&(j9l(-2jn{g;?({diKV zBV%Ihh~akW<2&1T7gx(i9=UPn`J?m&*`7f5 zV*WgTMN;$*bgMY;*OeSoO*V;>A_+3|lX&;9mub{p8b<)IYTq?}Ht!Bpm}b^%uOfy! z5@F6Q4~;3~fCzM!Sf46u{3qN8CD;XRF$?ImRex*sbO%+li%XAH5G9h)%@gXTYhIRe ztIsNeqUX}&`p4mu)eG2|!sFTz0t9*UWc6a9ull1b-KYl0{3u&Bo!S?N-*^c>k4Hdy;D*bL1$?L8w-TO(*MT1?HwK|?j9v=Oc%SE&`hC`gzx^3>9Y|`|Jva=@p_}>d^+8B_^P>#VSagj733<)`EN7Gtk?qm~4j8?2ZaDgK3aplkl z9`8)~+^E8Dc0Ow`n`5G3!B#$9wS39uTZ=^BEG>XQtF6ZJJY-4DI6{E{RY26X&_n8g z;|Y_|T{z-0An7|a*AxHW4_mAJXS6jEGg)skm(^GoruyjX>S=6*SD?x26uN!@W$O8f&?c(a1ZY8E)=F4*9!D9G{1w~|? z2`0>RIA_~KX|}WC0zUmTiT=-O`=-fdaT&EfN&P>Ykv~SjuA9#3SB;@)>rr*P!ulN` z$zLrZ-rNmi>&Ky0N&+67@HJR!G%9^pUK}wift-H~#XpOHMr>-Jzee;s%=a)t*3u&! zu%cJ060QCsL!wrq!0rV}p8uqwL2QgNrTbSgS{3guCMKglRWc!TsZfRauhl8Z0kJ3s zfKyayv(~XtwUq#MiBFnbBcpNtG=TD1x@6)vBSGwHCy&H8LvQtANBS$Tcsch;%N(&_IYLB)-FXYJzE+x<8iW?@++)L3B2`}g;Q{nz&k{^17HSpHU) zMsSpcj42&qL&O_KnS_P)|00`Ofp9_1uF^hNJp`EP85^u5;wbTnOUII0Ik(*cWZull z@LC!T%f<$=#S6eh%Sz%RC`q!2M@=B??Ch^moyLEi_mA+R!ZNFsDkTGH{iuP@aWUW- zeM1ck0|vhXUya3^?ol7R@5(D6%K?%{Y7jiNFmsEYTQWH~D~B$GzTF$y+`SqW&oLT8N?(fLB#W-(4>?(jJS@lviX#$*>Xc9{P-=Rs)=6!yAiJ*Fy zim6$+Y2PfR>?Gny&Nhli`vna(b=vHE%;V}rX&$+%XqE=Vpoh3@C`G|dL- z(T9T)0s0laQ$5X3cb~j9WW3$tV=dvDMelr4Xv^sCq z)Mlt1x@uMNCm>ApM3EqFO)k=8ibChz_-%Mke+=la$`A;3jc|ixir=Ph+~xh#7T3~# zya=|OToSA3GM!1u6&NP=59H~-Y{-Jl9=wpN%>Zb0WnU?@FGdpO&F%|0sI2M#WV3Jr zy}~%9c=B=z8E-?WQ1dOjgII1K(}j#)dkLFv+;^atEHfDnANY~W z;^LOxIZo9amI%04xbP{KJM||5XJ=Agqbb&V*;RF1Z#mrT1X}b*=JR@tbg38qK_fK@`hUp`v-y|kv zGa-;J`6|rb`&|wY16>~q^VMbGhc?hKt6U=1Hu9KL1anTiLju;0f@nd&s0TMs=&xk170p& zjs~#lb-kSS-LSdrD6*`#xoY#AkF#n4ll~`A?)aLeq==6qJx78azJJ@2Xyc~~?_$~EKn0u_^UE-Sd&?UE?WPtzC4Pq@g~gh(Id)c|i)5kK zGs=M%p|6xr>B!G z7e7!3Qy`G8DTl=kC*DGIXd4W*tzxO(N9k_VpUp5|%nBQ(eHZS0C>kw-@g8j{m#X(Q z{xarm+{)zK<#Hl;RP6DpkPft4@|zD66kjak$QRY}DI#Z^m}l{6!Ji~hHRKrD7qoG4 zh3XbxE@@<_-BHV<Q7x#uw?OF4i+Ecdso{1aFI^&AZ!F{|ZX24kGs&$hzCb*M05N zarqYJOAW(Feg7C8h;pfkc>2VQc{>%`>gZBAbhRkJ$Bj9SWZQO`Owkr!JT#0J)zYmM zISV``^-eo{Y;vhd8S!bD2U3Bf2(E}|X+@?aKnqVpl6~oS(_5keO;E7)?XE(V`0xjZ zw`$iPA4l0tXCTnY+S^xSwJhfTBgm0D2j!{f{pXFsCR0>YDX*?bHDV*D8pIzlP(!8> zrc(LpQ#yK8_%M2}8JB$icw_BCN*^o-Z#uL%`~~;~)&ovDd15RD&j_(!&foOanHjqo zQfGH0)4vBeq&sbi;RKoXbxAp|w*H8*q=f4HGI%a&DXWYz9GwV1+!cP6&|y$6t;adR zkH0C~PcI>%zv!F7C2|Q_GrAzbBHGO&i%lsHzX8w(@zJEItPr=684IHlTWv$COUO!X zBRXaMPLwkeuQW9yt#+)CTUqo{`$vxKBdU?nBpCUk>iW9OBVkHF%*%h*0wryl2*wA- z-c4#q92q&lP~fSmNd|(Ojfk%98nq!aU2^}&kIt9i-87f5;j+$48cteSbOG}`Qtv); zwLy{v{=tqlUsM&_6ecE4EN{#XQkOlp(kD1@!dvim);6uu5wm(Snq75enPJ!;?pB!! z24d6aLu(xF!FqqU7~h9=ZAZwwchB2tuCNMGJduYz-O?EN+WJ#R>2fb{G?CJr`j z&>I!iU{%dEY7~N`5kS@m{7ckCM6zJ;x~)ALsHwZAwyQ*z_%MSyD4y{hW{~NR4B|@% zW7#%^wE6bAN1A7jqSsnm?Ygqn%e#Sr2rL7Iv_0%)KEpW&nI?V*O~b7MPK2p9Q_BYKqgg?6XciAGlK~!DLqN1NU5UQI%!UxA$q8^%&-Kj zuZ5ywI3P#IS{39*fcWtNeJH6;4O#cu@7I~$FtbA9$h7xTZQICG)kHbuEAzGV<4k}| ztStBJLz*r9VJ1uF!d%*RUf;dPI7g|%M3saum+S08!Y6EKB#^)u(Dy8Bn}B(Z3Sm@U z_cHtP%|L~oth-qSr0CFPc%-2*?7aUDPtc9aQ!>_~_2Tk!7m&Rq#gOm{T<0>G493nW zmHcxpMgGs+Cn-BDcc`!woRUr*ayyplQa z?51UB7f0Mn0P?!Nb^0m@m7R(~Md%N+u0b4jP?J5@R@!Y=H4=KT5F zAFWLy&zw6^_qtg&Ry-aHbKJ7pR@tpQ1?&C5D4_K$5VX5}^$ihqOzX-i*iOF22!>A6lx31I$nJ>-Or zsH=kYGadOTH)XUK-~aEtaA{Y@@x{i{cDY!RWr<(b`DsalW|c6de!NjteVuNUAZ4^K zu9@&$!q_Pz%WL>IkBVZO933uOx%(;?mt;{vhY~c@sSLXeTSq8i1aq17dS#766Fo>W z^Cw#o(+I0vGP~MW;Yr#4^uE7yer9&j*FKi&P@XBlayG&+nxRD3O1H!^kH1fj>udJ+ z`{#@b5KbhBeMe1HFIO_guF=|tfrje$l1>RVMv(mXVg);TpzYqI^g2ZfWyJI{Ooys= z^HJ0*Af(8QM)o`qRaRb8t>d2=Wy>f~x&E`f%r1Vpf}slWe<#CcsZ{ZVNrzuY^jW^j zEBV*^-d1#)9*;0+HhkX83d4u*Q?vbylvD$FBj@|5M`w!}hXP1~x%*vGLXu=z0$W*} zgn!n(Z>?#N6801Wr(kzju`ZjxM^n@PP6kz`YRJu+IFM^b%g|B~T9#{0^m0EYM|N|C z73RRZ6>Opsr!X(I4uhDd5FD!A{FM@}Z7R%m?tGUV-U+EVtN~&~pNagf8SpPf3jIewlCyaOW13Q>T=O_W0(_Z6gFAdNql`!~HC$^s1 zIv^>h-CUpp^!Hx~p|gkKrQJpPyq84+aUiLD#t&%HzR8%a-0fVhkk-DCO0Pq+XB6Kj zr7w?ERa+ug$3r`Ri=)6s{}uCRl3g|L7N*BY;X?(;rTS^>`-u%>P~fMO1wn`=E&sjY zio~cqiRlu-E;tEnSx_UU-jsiRM~JR@ncaM+GW4uBxt?6OS< zrxjGgrald%gJ%(>UIBa7OD)yXdtHr6ATq7bz?wBjecIh1tpHtNA3cU6hdlH!H+KO^ zx7mqEM9A#s=8@dF#Nd@vR1Cqr9Z!M^acNqQ$}`=k)QcR+*iF7bGRs&cl`75`VY*z` zW!2@Gle4ekQUeV+i-U%jZy)nJY16Kd<_3Zy82E)_qxYNwnR3r=9 z=P>$2kE9~ae5K(O9HvuG@lyvm2sJAJ+mydES!H-(O8(cW?fOSX#_o#vS=WMMF4=<; z9jaxzHJQ*9)$%HP4zjU>WXflFGg;$YSE6nQhxE%_y!tyJ%ez}M9J-=<9JL^`O-dzu zm8-u{6;eCU!WQ_2x+I}C9n4`5p}aSm*U@e*djIb65qf_aUJe44z6Zn}>HD*6w~O;t zH0K?93A2Gn7)97rW2O7csOjv7GVnrotgmaF5$IV!xuPO<1P5eU6ot!E-7^p8K-LC6V0mdb&&X+53 zMdSBhAI)T?ygJKY!7oHrl&78v>FM+#2pB0CqE8>EXJ(4?^289}{t0;Jx&)SZ|1rA1 z7W99hqal}-h4OOPV*svOGHCAOdvc?KU*sKhL`lYyI48epirVi_No;o3A(M&G->7l& zX@oh45%omwjY2Nh8N_L3W-);r?Kbh$P*8lj;l1-BJ&f7&vYd8z{W9Xmb#LP@kvY>2 zGCaMq(J~+&IXM%P{vrg*X$7WD(0=CyJQXfd3-sU>Sq3w$pGQ&0+0f^u?@c=II-b=M z-4PWIbBuy_S;kYzrge}M)nE>xdWWgl;OwkSsfjhCE%4@>M+?WY10E%~C9 zWS#RiX!2uomQ60qql~n>>L~j&yv5LFDS84hJ3oiA2XwsXC)U$(GA_}pwS7vN&wM=A zEcq-cJM(q7IGiBe=13jPqFqfVYQV+KEo)^}e&5>GrbA3j{5|pC1!au?t-ShI#uu6R zEz5N2bqES5_O;4TGsJ90P)inqDCK~T69xWS$*`03l|#aQYM3zdVTwUC@DA6h>$b|i z9;`Z%2&iV);mc1e=i$lQ6pK?s>f+2pYKmV^&%oj|+^5Vl3hbJ;(6@r`3Rk%E6#_E$qrGQ7_4JzSR7#ECHwWkd}v^9E*QNi&tsWqj@OLkAazsE(BXiSO|9NJ zad-4SbIb=(0|;7X51W2wG78x^Dtom!2(lXPVBfQO9T&eHLS!IaA8b_yw$l)LHH}IW zx|zS*VWZDtBHk8N_o;20UHAgmZN_FXk~oxL!=1O;VcVPyIEutY27Vl-i)9_?qp7K> zv_LO>7L!)37{Eg@y*t}n9{zV8?ci5ib#I5WrCgNpYxov>`M$F-xBbH5&!j>3<8u{f zjTr6AyR-Z3fF+ix(bj-lD^87n-ubUd;;s%@2J8Yl6)+f#y#$D%JX()FjEPm`^&9md zlDfkJbtLC~*8P!Xb#;z|Ky3c)0^#=SC&?hIiZ~fn>mDttkf7L6b@e5>1ER<+GZyIx zRb3n&EbFaC(1&b{k|J1Y{+~W^=8A5KkxYqM*wGCW844Lxs-KG=BBGal!_`VY<#Kqb zXy~wFJl(6^-*uvKSb0ZgJr+)ZlSpTks{b{2r$Zd~-2YbO9Sz(R)PMF%+urjYUbaIZ z%a1-CtdZLeTjwsCFEO_kHIU~Q{7E0f080|Mf0g9__ZP)2jeettn97Kb4 z5Cm2WQB|2IKb_E{lJ8>TrgsDgiN`mmG@VLiiJ#x9;@sDnnPhid^kY*IQZUE?nZwsm zDQRW8ct4Ee?fdlaR}<+?SP(9p*JruWKU#<;(<16za&GD&V~?lO_dCyM;KbC=s?_Bz z|IWVJ2>!21!IhYXzdA)Tw!g)hfL``Lw_9=;)Xi+_Aca$AG&f`IrzQM*-xFyh8U)jgGt$3pq3FWKzgSda z`?k3Fw`M6+4RmN_i%1X2>G+`u`q_ML*gqYn{D;vL z?YqLnY+UjaoxZH)Om=Km@$hjY$)<{mMgIi!6}bQVa(=9@Pc&WKp{$B{C+BQkfJ&BF zikJV->jeV?HG=;068ukU_%A*2|L2p1|JTL)U+?_?@uci5!$$@nupc)=QpCu~f%Aog ztgNh-xJ+)F6lxG?MC9=g6@aAHNguKQo604nrpg0V4O26-YH@w*Yo{G~FV{%D?-dBy;DlGEt+fex=Uq()@nh!JmrE_blk? zEL;@mbmuoK)%###Qn(7hc$@(@i%bZa_iqY*0L0|?NP7x#ThMm~aP`B0L~+e-q0VVr z`u?!8CVHbtv&KMGPj7Wo%jxy`b`+2(dhi471b^KZ;*NY$n03tu@cN}hAEx4V01FJ8 z`xn5OLd$$2iyj6ZmF*RslLz-#j<;zc20pm`!`0Mz&k& zY<>?{8htXNn1)>d{aLyPA%el@_JsNIxH%UW5AOg?HHjry<{t3iwmr}d6uSXZ_}`8v zi|ecLUab($m>1oTAB}QCMtCy;XN=6I51E95?zZidFgd~i2`Yt2ujOM#Mux)5);*{H zlPA!=qEOnMdD#gd3%~%PWiQ~nkACI<q{bppSI zi;HUrAgV{JAPxF-Bv9fO3rFDo)n4@y3IUM$>1_A6ZfDsqS0kR_YgN2%0JpgqiZ9DyrZ{Zc7$EOc*hLibwu0o_>GXU(- zFds*(z+oAF&?uNjeg~k9af)uI6-8Tft#|#p$@M;@S6cueN*|r%Y4bZp04EXYtUVf~ z-h&I^6Se*x$SncPRH4c9%iLGJcL7gMGxJz^8?}*e;beZVKr>1L0Dyw*IRI2>(U^}+ z+}v}3*xCeudPV1j9c?ZRyWq4m1IQ+}=NOYn@L%l=tnS#`zr(`kCJGS9jzy4Qwci0u z9f!2ZzvM5w_4ci=j5`3iA{jtlLALqPjcat^ort^(^s0N*j-aEUr2216R~bZ%Z< z;oFd>D0Df-DV-z?^vZEU#Em-kb9}u0b0WU~Rj!sk7Y4k(n6GU&uU~{%Ad{dz+#K6b zl2e}jy$NN!AO5G{(FXMF`u^ypkgmXSkK2Cg>zz;EUR(;5K&6_PFb9BP19jnr=u~rm zPat@;mdx3vw>NSH+$z}9PMO&Ds5Cac9W|O4y0CKVT;kt;;~AN53Opy+7f`xUuhdBI zrT|?!*AHF*%mflA6s53=iqSk8ihqIQ{IUe=irUCdWrp&>^7{4pyNkqN-Of-bH3eC_l<3bu-1qFl%D(#BurvjuzH>1iMCTrH_?H{f^c2IN zXb3CVeFG3s&pv5J)71&QR+!{r_Y{Uj94123D%+&a$3e z67+%;U}g`k`<&YO58UIQI!T(4hYF!bdd98f)Jh;*P!1@ytLdvW!J&fr+TN793LT&~ zSs0p?3JR(oH~?BWX>IrZIDl)$hu;L375I0g@5TzASYCT%ZJkSA)J|!%#7^*WtfG7I z^2sjtMopz(VcGA8)%zJCFdYZ(_fv$E7T{si0-AvwS*x%H3;;w&_m_F}7nsIe9tc>5 z7x;!rvZeujgZVgzU!?!w=?Sh8A0un) z4jA7Fr9jsGpg}kH(+APJUJQi{;IyBPjc?eePe@b6TL6)!rtPre@2eKOpLSWLv!Xqt zyB>OAFw%a@zMj55izfDA=gX~zp_GzcGEwcKQ1Vf7Ewz3IJcA;$#4Cs%ZWwDiK0mO0 zhEZ&8_W6+(i%DWkWzw9DQ-}Y#YKz8kQ+PQFubJHWY3`mGpHX?tV} zc{zt;b*80awGO>~o7z;GfRVfwSvDhz?Oj_n{w?T^B6jwhx1A1w90su_c9xS==8xEu z2;mM4jzQ(c$T^%C#_{I*6*ttWUKtg4W{pc=65E%_bY}z$J}bMfDuhVd(u)9?Z|ld zTYUn-v6Yau2)=nJljA1BYxYBM%E4bkaCd`l&RWdvs!QBb5CrSQhGO}vAxXpSnjLJ@ z^(I2>kmoX`U9gLLiSW|4ZOh{X;-0PcpS15(j)o4JU5VSR_9G+0UylX((B4c*`5aG{ zp!~M=JB?+Vz|4o9LcSJ<{8fPH2-`$v1XE=b6cF^Y@JTsVkkefrvPQ^ZjrXH$K^fFx zY9j@q(3f@r%6yXEjDkOOo?&OcM(DDkxRP}E1u$E0MEBB6qI+QTQTkXta0y8FBpu&8 zU?|C;?Dv%`ex-m-$;!>e^4H!QOQ*WrpX3$ANsmeLmz0GGW%>)aEt+@^WXA&SR&uI$&aB2`b3f{3I6Y9I>J# zeEliWKF&3#NbqRPTYc%e7OS;ozsEDCCDoF}pKSnV69x0?LYo8+>?L|cw&(CPN}9<} z3Y~Vdk#0OW>>Kl`;v~ZBywA5ym;}Z};o-f-eAfJ4kB&Sqv>R)JqHfV%w+l^L3T3`H z47F2ygS4INym?fL%#Z0^?6L8bow`D5<0Gv_Gc6KL4cVe^@3DoJ;nBAO8_-d4ZNs_N zCOmk3yJUz{nNlqkVu->&xWA^B(=4#`Ba#+tn(qWSuT=D zE^BfL_fbanq|&pKVsD=>lBq>wRrdu0QfhMK?5u#>JNu?${)NQFnr3QOBLYjkCe?!7 zqOO=U3!C>!DWULJF_p5RytXN@w%i9wOPrirHqz>Is-mxIR?D?g1(L{BHt`>G4Zz<| z*GrChP0k!>-ldMVj$D5mPC@ZWTqdTOzJFAAv%9i_W76nS( zc6xQvz=@HPerWbh3Uj1ir=4g*z1)nb&>&^$DMGfl%#dAx%bV-zv!(Y|I;}c=O1WS1 zW(?IpijK=Z2ATfz-(8EXB+OZUM~g%4KSe&vJ)KTH#9-4ibKc5iHBt2jQsWcc$0n@K zSV}b#HFS*N4o%puAb4C|ny*PCsg=}LDs)B(l2Ua($o*(1lU>_Kp>cZ<0e}CnlGKA$ zTK%JPo^M-SZB#31vAt}qZh}-(m(ln{-7myy<~!DjdJoZ$ExZpI`-kl=*>!oJrZLi4 zdPRO3cJD`HVD0lKVP3T=`=(B&^;&=I@8YUjGs@W&G8uOfm`m?Q zy?S@qvR8KbCwk))@h)ljpav>;Uvcri`fOmFxto?vvp~V=f&TYp!q+{1DK^oCboqOS zD?6RGJ|T&3d^A&D6HP)h+s7tKk7e0{r>_mSZ_k|6H6I{XB`T@A>prZDivx?eGrEYO z0C)nL1Q8Z`)V$#}UhF+0JvG!c5{)aW{UYJ**Sfm87{L?8`ft@!SCr4E9?}k1=3ET$ zFeri+0XjHVd!4!y{I}~aU5{_MMW9+(_)6VGOO|meRYc;OWFQ+dkk_8CZV^dIJ?zG) zW6$0Jn{PJLmI=5yGq(46zegD7J)8udKboW4)3g4(CYCk7?YP$B1<6 z6dukR%o5xtt27SQRdBbdvu1W?)a? zc_|unVpw`Jh#!L(=S^a(>G6h8GhD&eZJOjhA697J4j)V+Q+Bbkuho0uEuq@u<%V(- zU*3@5KQM{sq$uzgcY5$0vXK*B+jj}U8PCUnKVju@!Ni5&?54{Ef9X%iFkye|=h_^< zJt3!W_x6Vp43?3@HaE!+o;OPtqqk-4I;~_k;j(;9QP0YF{{H7%Kl|2u{1eBi)%i-9 zAQE}015LfK&?_VTZ*h08@vE8kYn$h6Ye#KAUxJ2P+)08-4LZko<`>pXVv|3DgRV*NSv)GXlMcY^mil1CQ* z-Ay<58Qc=<;yaL~7LT+^<5rAfO4(M+cM$AFtzs6{A=^s-Bxld~OA&m!RRF1>BEd9` z2O?X6e=Wv$Wf6H+)C?Q%s>W3RVD}&AN^rbR(dmo3ca{%7ILKz@;U5kXwUs{9G^0*j zmT=P~t4rd5@|OZ0-W;+Irh1RD+nhEXEvQ?T>Og0A1tP^Y`H~Yc@P+B=B35jZ7MmDu zc{?(MJ`@PY9evPk%T9>)efOv|0`x3`H6{;Ut$44PO+RnsfZWIi0$SI>!!+u@1GJQa z$vGcbq4lrc5I|f0K5Zp1qDRq`n~r=*`-8n2K7}yNQmUMrBa3WKO=Sm{J^L^@ZLrGe zOeP6J(aZ>C(N1q6*j|><-Qzzt6|XZ5$tRN?eCcaIhjNCUcFO%ZY4(Q2&|#DR>jwVG zHIM`{80YMGm2n56xFsJ!-}cXH2AfPL3v~h(f^gKsjS*%we;a2sf_7G6M1h^@1!T3x zg-nKrg9EK`9=_TknxwXfX@L-0!0X-KOYZ5^1iuiDGsYw*)XKP9B+r1b=*rqM4Qh3w zP{X;P5DF)#hm$&2zI`+aBFK%soz!2VhQMg(Lt@LZ$P~@|3P9ase+0lCddJ z(r!wqQbuF$0Cdwq{*B&en!(Lrv@B4FbKy4^)p|QH+UrKK2kq zTKM>t1zf(poA)ou+1Ci4OA@(4^8qf6l$h;XI(-ubZrD=xm#m}eKs(>3juovV@wG|^s#@bpYh4W? zqKpphBuVw}>j(?|>_gA%F;*)d$YthEU%wvmrj~i=nm$o}u=#klhN26t2bi1iID}iw zLwlz91xgzt!l%C7Q}P-TxpXzHyrIEXf_-bZ4mJ7o6Y*3y`qw6Q|KYRc&X?46{dl(< z>K4}YcL;jLvFX#wuYGuBna!v{Zy%>N(0bC$!d-UAO$}Y~NoPQPpY)OpAh++t97oY% zXO#=Rb8SYfhT8TnZm!GLqn7s}Vm}QH)zAW|0}5#m6Z|$kU5UzU3(F0A$5%c+{~=+c zxhnEnH3`CGf@>Y>ytmd0N0TGkm%Cfnj$Q_ww*)*%W2O)lSP)icXem!qY>bIkr(cLW z4PfVOL-*H;&jMP|rk1^-;Fcae!XJan9SvP$12w>1IFaP_&p4j5?T4w=QbiT-q$`n9 z`t(e*ec+wDoJ16!A3-$DA!PRA*WD27C0cGxG`Yd?Y~*;KQSMsw!`tF}cF?npK~~U% z)T#US%3q#g4fcM6j)!f@^B+Z0BQ+xpF%u&C8hvc z@;hbfi=@r{@Vy>gx*d;wm-AbvK>ldrD+c=8o-cW^4_`(%wQI5Sg~NaD#auC(gi}6l zxkwsb_u$;noNa>c=Iu1R+feE7WCN$h#&s%F_iBe$Sm;^6W{+Vd^6;^0H z;qt4HYRWLYjnV8oqhXWz5SPLryo?HYP#k%2XVkw&J`4355%J)tXAvObxhXGvv}zPB z^D;pn$<2sdXBC---gqx~JLZjXJvvXRV-Ph!-V3LF!E#Hp-^XK3XJm);kz6cfTZ=P* zh>}K~P2d|F!A=iPEdg>@0OvOe1h+D;&9z6B>xI;0{S&EE-uB-7d*Q~oasVCnl-Wf8 z=ni_^1+9&?{vmCtX)A&Yq^y_^T;|W(b}Mj+$)_9p!apS9P*8t;P#a4MPGY;Q(u%qe z?fUj7kGJjS1Zp&}>v(cz)1=I2Q!#XuL8?@3A;z*10Z#M|oiuTv@oYG#kwk^pCFpSF zq$PIcn`11|xB24H4T1f!Nz}l?*bnZfUjoMAJ(KN1F-X-fiNQQTr(hIw>qI89%j8ar zkuAh{wu1{M;VbbRNIpvBXA*>|<&NQay6bUM8!H0W}UXw7jA>HW4&w2|hE527VY&fPnFz@YVvfst6b{KOMPx zLa>T?4Y=qGtr$k6Zg$w^1}B3RkC#x>Th$RO zY)PRv`ot*d*U~>31!o5lOiz{~Sh-&s?^@ePsY=k!|&GxO4*3Y z0^r42I-n-WkRka{dY;>n%{xSS(`5&0Uxv}AmrCI!(%-!7vIYQ?#h2swmT<@{9clf> zj8dy`zl4qa8rbq{VowyE?C~8v4qRX=TwrF2FZ(wsSFU6;C@h}wP{Mr5z>LU`83cU$ z=z7_MqrsCK@cDLoLJ8K|CT71z{{nr|8J`;jDShW9FodaH5|q;VKNCgIVsn$KO>n~m zqqY?z!z^^L50a!m1b&v4jl2pHBLM9X5n7N7s{7xzLu7m6A6krhgYg3_0<(FW`CpjP zUk*10itvj8n@L$DqZEAO_OzsV+V!jV!kbkN!LeM%t)aOuSEUzB@P@Kc<2~kW8$z$r zVu=QX5oR25&t@B3KnQUEutKdR4#UMB)N@|?%U$b`PMxpBmNoIhWFQ(V5T*Am>a=s# zq9*cSQKLvHa;_96d=UDR>>Sbhh%!Qw@vmgN*|MK%UwHb?O~{B`=L5n_BzaJSKTRXK z#n2eY*whdN+gd&XPS!Gy!q78i%H_jav2YI5iO_~7xW7=YQ+P#c06*+dWs0-dV_LeH zu1Kh3*FX?}qLfJYm%wn$AHVcCxXS2reoHEGXulP|cNzIIMOG&YOFT_x-Nz3w(|0yV z#g(6oDf#i@hhD%3fj7zMp5o7Qkcj7QY5>HKx3>SJMwVXdAde_e_-f`HFUAU@5mBCc zqfRt37wt>*o=oA4Vc~S%KF`L7y4uCNmg-ho;Y6jyym4SpYJ+V78Tt*>D#I(HC&8d%LvydGXkYd|Vf@=#*d$9^U7>~V#g)rMaTba>AEuEOXa{7< zD)mr2o5&-C)IG!e05iv(Kgu5oCeLRD4W_LW@80I{BbMy6J_1(9sW+v_lXXn_AH*I3 zhlo^n(GQqPhcDUWY)v6%nbSy*=Kyd+;NZQIv`8`E+uEBGSa~OZA@&h3cH+4JiyzB{ zZ_HcG9+pOnxF4Vq?N?%coxp&Nc2|!^?*|V3*jn{VJABXvM^&y@NuXqI&l80Wz=z5)d=zxR>o|3Izxj57;wXa=dpKad z8qF5MEQ`19uXL>Tz53mr`yy|ju1Ed_SaWO_?bB%jEASqFz67j@5W479uqx&%G6}=aVT4czRO#!s z?tU}aFzkYF zfU52=7GA9EVd{5@Jsz3oe~z3adc#0kdaLow5Nel4f+o`aCV}DgLf}yI+lO=I077MH zn@erOxI@wIh>?I!G~L_xiwHM?jXngS@*`M_tz=!-EAfxx*+T(mqDkoc)ayU{-He_= zvmN|oL2nU~yY?w`w!f6SPzdxvu=U!p=2$0!s~kM;>s(L2N;ewTULC^kaEIU&432CV zUa~8!Asdl5h|LH&t(J$VaMzqv><~Jcs53K=1;BGRX!OjNa%OFZ_hcPQpY^EBRzTox zN#CCbypls1e4X?{%ptmT+~S>NY_CH~j6RC4t59}BB>Q9$Lz@#4@Qjc9`t(6oc5!1F zjqg0F6pKaea=ig@sSp80LdNn{<N-6he5Bb8q7g%>A<8~7s&0)ko9*oQr^^S?*U(l?k+JN{4Z>wj z#JBI|29Ne?LM^6ra77&%^)&U;j6B#v`w&k>qXQ2U=_l9fmCfel9DK;-mrhcl9Ls&& z@J9lkvB%afjZRd_{R-rfQ?ta5SIx?FYl*X8AC>r6MM_P`2@;7)NSk#Ek-w-&u;#}# z(RW|q2DfAMt`-tjM^c5dNA~<&UXtI`Zo}92_h_v`(aIZ3Y{+``j>CdBI_X&^2xf~RAB2LFmHxV_*Z_P*| z-!ZEDyOL3w;T=BDZRfsh|P%rsiQ=o_*Z_wY+p&*B5`Ucm#z1yjw%{AfmfKD}%(>Q_E?((@*q zsb33R_6www`3?8*(Ez;X9*cPBH^bftAf0@V)p*K5+ZnY1IoyX}$7fXqC_@o^iPg;8 zDo@4Ic&R%3@H%DeE*P?crWQm@_8=(Vz>E|%n*(F5zZiO`xlgI1Q|wADe~cIGh)VS4 zkqBp+Lnr;hCFztkG+}>=mF-4OxBO*g)H<&ChRwYp@af|8iZ&ojthxJ%B**Nu(oa_M zy0B(CQZE#}j2}`@(uKA%wR?`RDdYmKed{;%KK_&Iq_`&m%ZG8n(K(%!H)<&ojoi_z zB;Dn{zN4pin%|N;r3)WKE0?2|+XpU1@+FGP)VjL&vhjXjH27?^{m#-LGUB+HOB%B^ zm&A5dsKz36<|zJ3C}dijn};P#9z5&;O_XM7k(Vf{fX$X5{}Ck-U%~#;$Mg$1CsevY ze^9wpNTd&Q;Ezlx1v<|A$~r4HEy*5Oh}Ta%O+<+|iRZ9_Y*xLdyfBp=Xi|-1DwWQc=M{vEce)Mnmz5gq!qG3w=RFN3CXu znhYda@j7l?KyC>Z7X>*G&Tb1iRui^R-31{zfxZbcpx&$jf`dN3ylZ*+9URME3(nzw zG0H*1M-rSCSh!l;aGsJ`7<*{`bp;uAzCl<*hi>*a)kyov+sbcxfa76Mx5-5=l=HI( zKdmo|LlxHd-q$_&L_3g zsd|*#3U6s$WCQ|H?7)GzhuGJWKJad;7%W?SZbeziUCg9ZRmZsN)TTXJF!_$_jsDKI zL#Fx3JaQh7nwM%9q9Dqxjk`4L8;8V?jrqoemZXB ze)jyT>A^$!wO^_1meo+XT<*+EpBM~(n7*;gDfR*|L2JQ&dq+%H-NwoIU=Gxz01UKeHtX~FOT6M4b@SwMzO|J%Vlho7pA+1+p6MmMmCiiwlah5jSD zpMgytUbPEsx8wNE@(>SDjR6v)6`S0FB3ZHYrhP@cWwKj8)8&~(VP*V{zDq@$Nm|ag ztR#+;KRU05gKs!5=5P*iCet1`C3N4=RZ|eNWj;(16GpXF)MYsuP71pNw_}N{@sf8` z2Ak_Wrl+pmFS!O)OBf+4%X2vYxO4Pngvqx|#e*&alRU7uE`F3KM3Y2+P$n~AZLKZd zEmN}2SZ?4~7wS!VR&Or_Ke`OCENbM;O$YtqoOWXW%_&^YL{_Rgn?9L$!_D;NGs!f9 zHqPKc`2tRO1KrqKd(OoIPnnUUp}4 zMj4YVlYu}JB$?X0 zo<2hTMWbKcpqc70Y`$cN4=VZ|xTcWBaU+}izNqO>;oO!tC4@ya&*B-2K z@p;Wk=vjgZ+pVP%Y`sE~-AB=#HJ-N<6fo+72tA8cD4z#MH}va?U*c}beK!aX4YDIC zuldm|F&`W`tsw@8f;h2$KIE?tqehuR?|R)bRW1*iLfucoZ+}$PvKpY>HnYSGVj^vQ$F-e-x`ub1CkGChp#U8>N#3Gpdyax2V?VYDA;%m0+a-yNjyyk_L zG6CrpM5k+yn_eFLWA`jtbM4O6U6R-arlu8sekrQI_0Q}UgC1H@5_}ez&qZcEKXyCP zP~y4OV*C#KgHqc2JRVj2gxAYqx`sq1ggzO(OGnD9`hazsC^15X8MsR-Dkn#7wHvQh z5^ge;lM`S-DVCdR(bw!=NxX0}lr92SEkDcWTTjOAFec%+ApWVl%vC0))XnILk|~G< zK3s7`GTyjP^zU#O%6NgybK+D4GKDtZIf0rF< z-Q%FY-phW@sZTc>NzDzkSXb2wM-MBPf3j782akvfS3XS`6pspTkP72!?`M}k+0lkJ zordY(6T6(gqphnY-je*l)Lz1v_{H#xI$56mKs&T6{p)4-l%ikUF1l!A z|CSkQ1BgMFNJOlPC?tvHI*!xin^sg0Ey5EbiqN{C2feSIh^77*xV&IN)ndomVIvy$7!ot2 zdZf{IZdX<+tGB=h9-=XW%oo_9Cyz`$@R*n*GW!_={9Km3(> z*$c4qk2=49=*HT3Z>*XXO@KP`J0wNn4Tt#nDb_|GHIFu`XJx7w7Q8T0gbZ_JUlDv_ zqk*1VPz(Q!X+3#h zL|;(?y#1!4QY=Ec4i^O#%E~yk@T>HL<#9=)!Qi4{EKa)CcO%~G7>LKDq2PWkywo4y1f`f3#i}F_xl%n4~Wh~i}8Dd`ki!;k~UA*H7 zA}Xa?6pw*I!Fl^E@5JSHoG8n7WpkD5YZcOUoGm%3?;(*IBAZEku3fQz!{meH+uY(H z!8>iVjSFq?0jX{*+4XzFf^Y$uUvRyktoBjXZoNOrfn3P@nQeS7dkRwriRZGg@J_2~ zvqgUK>M}Uc;hqwSNO)Nw-g%i2R&GH8n1z&~Vy zlv*TjdE5!UWWRtPhD5CVWnR%i;pHaYqKO&brqgl|xn^Oq%L@PCeA$qK_WQ2efE$yN z{pMX$oPy4c`(a>!eyBiUoigTA$-zxI<{``Vm&+k;iOK%=zp!3+y({k9qD^-yL06Bf z$|?)xlUD)WVzho811WPFs#!;Q@J}-}RI4ynk&6D^%snOWh_=7roH)P<(cimnrbOt4 z2EQk-(nh5Dm_P^594D;coD8-MPM@x|))YcE?jz0ahCX`&^~NmM`@(47>re}{QCZj+ zBAj0==4V1l)w9VUA>F1%rT+&PLFm5ltjRTt>kRkRJnL%vvi5XaZzJ4G^Grd8MGDVJ zWDe6x?*BEQ3fsh30fiuTo(J^jKE8)-=Gw}$n#KZ~kuPD- zQ&odlb*(TLFo_1EL6X8|GDf7MPiOp1ouwVa1|s|BZ=Lk}c>9^RwGHt{!BkuTbC=?l zuL*@!+o~lQ(okLj*eoy#K%!9?705QyXf(l;my=*Xunr%9E`R%Vi)UHKjD)pER~&!z zX}M7x+`YFM;39*d`V>)p8a-6?>FSP+o7am5mXooVr5u#eY?0(N!Xd;es?@&`DW72~ z$ZH-)j-4+AOXniw-f>g=zzmxWj&r8SPdf3u_$I1nyoa1IL*Sg+9P41>ud&91MztpK z-DGPqSk-!GwIOz*QpS);TS+%bb^^Fw3(V%{Elf3HJe@4w)3)TDMV`AcK0ZHaH2mOMG1;cQR=nMB*r^7yK2*P^~!oP86+w4|>| zQv=xmoadhvkEztuB3e-^H^OtTybxJe#hGzzN)HRvI7EN`BqB#EqzsHEvC2v*Rnr)b zA$#iS$i4HX#NTr7xm6OZReNWnArwS|YFDBZgz8hYPW7p8Pt~WB_qSwNX{f4=>y8=` zQ>TLFQdMmTOZ5;)5?^nOYR+u}lG3xPM0W0mf7>o8=aDsWl(LN*VQ@JG%);^;Eb%~Q zpU}pw34lxD`DJx*OdN~s4wR^pVetCI|IjvBvWoUg)+_!_{0jY`+OyHGXgBMbj1*>< z++yV4@$Cc<#(C*<^;r{6{Nm4|V=P0FFx{a8(CG(7$RhYi?~BHbRCaGe)$?y7e7Fp; zLq~wo$$)|Ai8{EZOhDG<7krw;iX`?MJU%HECP1K^ELg};(Z-%Qdi1!I-AK%n%OR{5 z23-jt`-nj(?$-;>ly;Goh+viK*XAL7phN%!=>RUGLzVIKvoXgFW2bzv%NAV-285A_ zY#FZ8Mj-#*?Q4l;}#>#n6GUPZ*7gNB_HA&s%sY7AoQuHj zgRu7RA$yL7I&WGKv2XEewhPtV+9t$vi!OC84RF8FDNlfj&a)=9V2k1SMGqa5 zHIZWKS}fx$C6F2nDW44qD~MxcU)a@{xi2^qwQtUczoeplaI^Y5_Z$sszZa#gHvwPG z>U~N2mSl_ZwVQsE`b7UvpTN(P>8efNul9PLcb3Us!%~>9)?8m&Tk@{msMhw7>_C z8GuVhK3Czbem%HF4o?n;lnHs~op%HTz=XCY`kU`$LD7R-C}a^J@PP?>{f%Aa_A$YuPhx5b9D*%0aEmO`YJnz82>}Dz z&9l^UK4ga=;Dky1tdl^c^A;G(9&z)^_v*`?Xu&!HI2dSSd$qacJQIka%`-nk3TC}9 z*v39F@z3w^CK{9Rsr{vH@o)N@oSYAW57-~x;%0(fKUQQ^V3{WZDL5zTg75^JFkwtU zlb*SP^Gtvcfm>wyNYzm$`3Z<1OA5cA4m_i^fu+6l!drU;R}l!oBmo&*IBp$fR^p93 zmi%Fx^*T!3;*CGHok@ZD^XJRBYQlscK|fj`RAVUlEJEGj81hymK`ffEUks*Fn7AZJ zLeK6(o8#|j;{>dnjL-*Yi4_ghp$Wln1UV55$NALsM*|FKHpb8B+e1Jc0c{!pO=H{P z_c@OAU(`J^nP}`#n($^Mb)C9EpcR>aG=K{Me4J+jTsT%_{n6i`)L3k&pL(zo1KwmF zqEHW0OQ!L&1mMt*ab8*ShBv8Gb)3m1f==2hAH?}1Acz30R0bCIoqZyBgU`{*VQIp^ zIme7XmEb%AWm0|G*H!3q^{id#gvkm5pR@#D;sD;1NT)8OvwMy^f7%iPpwiLUXCxzE z1))FT55bUJI|u~TCl~2gw33EgU)vI{|6JSj02KmrwePoA3XJQQ#-f)g=arF+v=hu! zcBO#~coCs3fO1>xOKpi}hul-N#R5gUefsIA<-C`XjHC*6Q)3(AI>5bJYvu9?EMW;G zelB$#;B$DE;~AR!b(R}yuOwwUA;5;LrW&|~LVz^ET8w@0*<^auz%5!#f)`Q?vctqcGq2ZNxx`=yx5SDQ>t9)|2tI}BlvJL>fc*|!1hlNDXkKa18Mci z7?N}TnQ)vrF_Apfc|pl>lWP8Cgb85(vNiC`UIhQPy+AkySj})x8H1b~uMkEAeOZg} zuDz)I{XbwX$U)TWm*iH=7eMtZbKv`66JoU<7@cp!S6~5ZJvRCWl=T*VbNL;QMGBLPvkA zerH3p+Jme!Peac4;$`BahmXOxb|VaG{AhAV;HWi>*(0c$a>ZgiDa`a4cg{ z)&68(&)-{mbVfrUDz;!q0XRyjl1Ny9PlgU&`k~zhSFJ?pxG;*)I z6!!6Bl9?*B@6~$|T=x+??<|4${Vl>0Lr{ygS242BnIfz+rf%`Mj~ppQ=wPXoeQ-`X zEs+!ttXzxwRUb;yk$|n}i3$NC=u0{n%tlH2c2xXJSEJ_5ca`2L8!f96CXR4fC93}R zvM?*LOo~~JYyNH5!=ikKHs+0?C~Q5t!laAQ#q}~*%|jky$4(^Kf@A9BR@-3f(?d!S zMURxpxU{exvnlQG+uZ|~lu0=<&wTpy{qcmh%cgX)j{vBg=T2$C{=#H;;Dh))`99nl z2c9WEZ0p+%?&(vIt>($tDXwQ4Kp>r1dn+H54eCGG2><$>qW8A`-I4e0Z@_io*)8pv?;=R3gKJu2(2oXR z2#)c?nn7`z|C%xp_C>1@+;5gL9=hTGX1$pJ<~$pxp@~NwO#>6w%B^8J&FbdX}3=nbDYsc&1WjJoUwB! zrLS4>`DH9L4f9EO=N{CrTqo;w?)6u~w`?^+hmWV(OGSlYjHTWjQ^&zFDDF21rma`| zglHA_DmH|U9FKzpbpV%G$#K-rStNjmNLgikKYsCR zdyk4w=b3{HCho~&kafXXu#uT6ot>#MsrviN^1ghfqXeJuIqCLT4gR2f-Z6F<3@MCT zWHj?GT_bCEV8d3})%y&(yjJw!5%`v@M%{wt%Kl4)t;bxLhwKZdBKwN-VHuMCd_kaf zK+Ub^z2yk*Iwbotu1{nYB6FQf>8)l{mO*Mie91X*tKXS=bW=XA4hFUN`?PF{4z<^< zU-|)zb-q^jPZ{~@N(SJPkWJ`p93RpZyi{JG z`yKnu;9jb<1>|91kmYVD1bpb3C#atULZp^0;ybmu(g0RW%B8!#N5G55l9DO}c(5E3 zZ{;!gN;Ac%|r5GGNyU^B-=Uowh9-C}!qm|F4eFXKKYXEha{)V?}NlBk799QZy{eNmrUw)T!(AG`ljAZ10 zv#=x{S+BT;a@`<%TWYdU4+?89c$O}Ku4l4p@B6eRKBMvTEIE*ojC@VxWI$ltgMSv# z7{AN?rB-H^K7n>hP&oG-+?Nx0%zah5wKO9cUDeKK9a%^Cqu*=m&k(=- z38lR?gy)QO=PzvyBen>^%6t&q60NF3aQj{aw|;``ZM#wU zanAD!;`4qTTtgDS|Hz{In#o~ZsAnbc+<81pz@5l?=p&%~NyXKe|S^nq3D zrThYIfy^N-Y|^ayRCXe%Po}~`SO)ZM@p;}tZuAEbsbpNtD7W%i>WIl9f^bk;g_yS< zQBPj{Z~FIGE$VMR1lDd4b{A6J8`YSZyLW4Gv%B>UH6XNiKf(t~;T+K)_Ax0XBh|mB8Aq7?xh$5IuMl;X_9ma1a&) zQ*p7BC4sqP;rqzGgYd4|Ab=UUd9MTW2s47kEG10>J3fJ1S1yAI(@1GWeEeH|>Kv_lh1$;w%L~WpG-g#8F_?IvAZU zH6DHeJn%+(OCVdk@Z-lx&k&!7Qca6unVpTQp z%vvbrmdwg$kliJ!+D`TkJ#&B|%Yn$z5`@-o7MtVf8FTYs9o(-adjy}W<}rFg*|*6c zrO#;hv<)VsS*|G7#7^7jYhG{3azF;8;NfEk?>hiT_vZNzD?5yqSHr0ES+y(bR%$jcM^Gdk0=TSt$T;l!iAhj-~lHAe+-oi+q!HBQkw zrNdix%%=2m8=oN*B5!@W~-m{P`7F3Ugu1PM)Vmf(__1l&zB4 z$60zJ0pR0W5;=5C-bHYd(b4oSGEJztYfx)~`>ct=77^O98;zd$Y@7AaHi2GJ|7izd#~&;dzc zO?i(=>yrh6&D(`>O9PTnr^81}Roj&h;#!jme016nJa7cQbz5QSUWDumCMh3Trq<7L zl>XQ6(OLD?ef4EYtVmMEPU&N4>kb*SSWUHzm#Iro6-(>12?VH`Jt zYG^xTqtO5^b+67re3}GOO2G46Ph>!f*ZHNGPoJ+5c+tRS{JGXL?!P@DNjT; znwn={M?m@PqWf-wbMiR&R;`UQ)TG*Tb&agC1ZgcJ zLcp!gkptiu(ieeU2T;Fa1N__fq1zKbhGpo$#2OY@y-v;T>*4^(>SoICCu?eO-x1Wl zvs~@n)}iZfe*zoXeo}IKfki73+_6_m^km<373yA|i5P)NY1(OQItz(!OJR7Ca)F#5 zquQSxFIN+%p3$@&jVPNa|M`<@53x_yXxHSC!cY_3a|pFF7b5V{Run(>knG{~>oWHy z<-dAb0H+3v5stC6`7E_x^QqtMfp5)b^cg=&?Z@I5RBWS%$xlMaj`u0!as+C6m%T4* zUPCzC0)*PI|8V9&^A(p2z$GJ}tF(4|oqB01YOA`L7;qqYp}HiCZR{TN5q#q-RfQc^+EbH+l6y4SjnEKGTDi(j{Y#7Nx$bbx05KKf2EzZ#`KnvjASJJd8s{{VF^=y_GHTw zY2|UbAA9Y!*JK@~PoORHU+&FWGLaV(2rT9gODYnGoU!4I==Dh3Pp2~Jr90CwUXZG* z+zXRgmHS&>w$Mrw>DL!+jcKn$C)c!e?6cZgl|UCg%cK4bqdynu&(ADZ%2KVgH3I$# ziYJRC*HxY?c>X5fB_p3*O!;}pyZT%KOxXJLj{nkWhjaWWNmkl=^?)HK`DUz9`AFxe zAut!`!!=>xdzV z@7hKTl7x%F=|uSOVO0F-1xZq{^hDOB=b^FAE8q!@&OS+>2|n3-P#u=TFeu&ju3nFt z*^6QBln>{ap|B1gl4cMs@GM%3>X+VCeKHHsz@o+`_nQ~M{f!Hfz$Z*fIL@AeuKoH* zDUaaBt*ChF->?twi=3-3fo)KKDP>^HaV3KxSZabv$GwMf?4jRC=^5UtX1NsSxFIOG z^9I<*j#38K_TI3eyb}I38zu40k~8*6$?-u`aS`&r_iZV=LKc+zcbBN~T?qHt6Oeb~ zl~O)}H|qTuE$k#*rYFzUXS_&YZR)+XsGGe=5=GX&UEw@^G>iq!te_m9>~kl;yM8M?bCBn$44tG)qCF+ zoz0qh8tfCswypT>t*OfYxh_5@ely+eLSXq?RQ~f#NoeI=dzsR;p27q~Ab_b;f!;yG zm}Qp)T|JYH(U|BO6TGg;qfvOrjj)Uy(wv+kkfwotP-rDuj!nH6(UKD~_xgmTZ9sqI zTsRFiGZ(_U>;sq!@?jm&SAc1Cug{UPJg(D+$8X7NUFy~aS!Yi|X!iklR(%MQ8awCN zljW_RcbB1l**XCcxK1CV=FXMWCo;v*);x>WCH2XD<~XGnyQPxZaKRDJIq<&Sb;@7F_a(!0(&L&kwD z2o2@Qk@f7x`WN+w)O7Zw<1}8Y@Z5z?NNcaF#b2;9|~mq3#{k z&gbWdA0lIexzMeA(YeUI>FOkABZ_PKG}s6Bmr_`M>ccB@U{W@mcg>}$52KV{@xY+Q zjb)TH;f;IO63cpf5XR0h4D%+p10mX?VP2;l0}9gvb@+QkCzfS^@~?3|F9aS9C!Qs8Ltn)-TM$z zeX{i`hNW{eSSohxI6N%JQR#twa8Kla=UYl&&wzi)DpbEb8!<9k#9Ah`ofF53{(F~g zP`Z*2_eE#NneSG70Pp*o)VLMEeclw9o5rt!EMMxpOh&8F;SzX$@dwrKbz+iImdxou z?ltEl@Aey#7`5bi^rdP}ouicx{@!&k_w9}P8S_v(cd-B<=(p4P9#f7JmH(cD*i)~> z=gDM-rIVVcYc594wck*Fvf1Yu)jF1?*4faWBdA{zxAm;)Qw7N2Te3#k(hgXqPiMlE zGQYH4gYq%fe%+9N;}udiDEPiw(_Wm3u)&1t7iOyUa!B0I>6@s0f7!48uEr)12frx0 zvJdZr{F|cPZDz484aOC{+UZEOR2A@{1Yq-2~^_0Q6$rvOjt z=Pg$Kd>_G`2jP8hIdXe;ZI?AFqI4*Dq*PeB97C0jrd%M_+Ew<*pM`D4;IvAgoTCOR zyZ8oN=S@vw`>~E53g_72N-sUAdTq7y^)TqwdvN@F=|`%Nb5(g=*@N($lO-BT=B%Ftgfgd1lO2>&8k% zDr->p<~-y*@I9EC;=?B8kKJdVE+r(Lr;nAr20@|TMaxy+mLqb!0=2KqL{Xm}N$WcS z!qsYB2p>6t;)iaJgUUE|e1DqpYiNj{A!6zbVn_k3N?E92xXCX#1Sn=`+E-Tn{_lve zq+;K0s!!vPrS@qiHGbUh)W5e1kcEeVLnd-|q+uN^6KiwvPY>md#05nuQ5aeFC|)XSDViZJg5u!qUw{M?||> z#(7|=l8y=kiCQo*T>>kyK&!TD!96CbP9_-MUVqyX0wf4DA}}JAF^JFm;DZl@2}ENe z(Z7>pl1`6OgPv_svugoSf@XLVwIiaHG-9y7HBb%#988Q8$VE^E0Tp~c*+VD^ zS%p9>0yfBolFBG#Z9>%3mI(A|O&D}#86SV`gVPcoeKI~^I3zxnG5Brl^noRGrs80mb5H$9GMc8kR>Yg@C zpPWj4PbM&eHaU(QW7-OtewZxLe?L{2)N2bImywKo6@_~%?F249;Dci#Gkn|}$L-Ml@ha)pd8A+U9_2sMD(n0RsxtHd?S_5$L zEXeZ3EIrC+u_S3~sULoZwm^Mt@BH2o>F9+A3fH*1@4j2sNtT2@eE6_jX3#D)P-rLL z|Ni&WGQ(u#6kw3bW;AJQE>#w_cxIf`R)pvH{r5aE=)iPx{582pv3zNLdxCUU(a! zy$4YAi~ocvx0z*?&(NMjut_|Z+RZQ*c(!bAV zwhdF)&hjIDEIp1`g&K#>MQ}`=B>I#t8rBd92>8f0av+?OawK6%{bnhhz=rKOe)M-J z{>eSCPmTkN$XaC1R-ZF9BD8xyqNQbt#5*OpZZm?P9D*s^E{rnlE8lHY^Otk$wFn<6 zfp5b$l>O!(l2B*DlVB8U<*R3Z=E0hVFFAOQ~mX=|5(1m#DCE*9!dau z?B`5D(SW`v`|;!Ot=)#eM;|8uE=+FvHt!J7kF8HPbW-DF?$a|q7iyfcZ@fxCQnC7` zi$}^HVgke>JA)b%HUCU>d*&}!`kjTMyS{^%T1Ut<6)7u6>_k=KX1yfcO-8uJHTfbX zq5VgsJQx9WVb!Nj%HQaLTm&*{U?%I~V=$=qv+R{^+(=mZrS~h=F~g95+jZ)>&mgdM zH@s^$i_akQgHib@`>_7VRev{kEpAsI{R@_&Zt)sn;K@1fOjt$_)j8!jn+=qIb&VPx zPpUUU>@QkbCxDlT@~531z8?l1$S3f@Mg+F)k#b~NXN*I^19v8vmMla1BVYZn+=!lG zCR%b_09;J=+XnVR@xwn#BwNXRk^9~2;8ye07;8Vn?tNzw>Q|5Jr=?(pP)eCb)mx>xUrus(Nyu&E5Zg;_}_OWm4tF#b2-8# zCz|^69;#oRCwfGn3@1A8+gC`x)9$~jJ?Q-X8=0=uSz^eZL}sLt2Y-vMj|P#Y#!u4;6B(VAJ_ipT6=n=QFpNM{ zewR!#WKq(W1Y>z5cS^}2(VshSLZk9I;iF~nZ`%!bc~zSXWsNm;sDAbp+Omh=8ETh7#O!SW5epJosyLdn}AB`n@KAC|Pv!?zj;V<>P1{ zWxx04EIl%nfn_X!}1Y*wxAjY~?Kz%Ob|v|D5@ zYo2`#ft?4WTvp+O|ADHfpHpjqvg5J}@p%L|1UGL}zRwG*>Qmu=-L3i?-!tVa`;C-W zsI_KC3kH|ZA_fA<)O;8H&pinMU+$eZBUV`h&&mz(zP}MU*I$tUxY);zY*A{B*@x_# zzoqmmBmgk~_B{gH(F0s+|MeOoCFN?5I6zAMX!|Uw1evB?M!WK(YCQ_=Ii$wEG>K`) zH-D+H1{p0TM0q*AsXSG1-6lkk-#2X7Ah)Mj%7e@hOw2QA zbl-jVb@-WNY+I+z4akb;^w;@BR}6B!d&T8gX{{2c?Hyjj|6U?d!FlR-oK z8xsZk0Bl>rl1eNCMZM-t)pWx0RHSNu^UXH}W2oX;X0KiVtVCQ@0C zw0Y-^NZMp;wcp7~LY+EU;1%tKePh1}93f*31JeY`@SSA8Ab^C)4}wKB9p<|Trb{jD z)RvxTy2-wFM3`7jWfbBVah^G5^mk-1VEfo+0+mwdL~AdTLbu<3y9B7yvE0zdQ6I?C z^J&VDF$hjyOPiiDWl9U1)cStrnP=jzyY5Qdo=ztWu(zg@Uq_)I;G9wjR^*zK3Y6pR zSv@n4rbh&JlEI?2WXPvs+R8{q{x=I57YO*Gf2Q61<~P5=HP>9z>gNfJWTKIvSMDDg zTe*?K#J0xt!u^v54x~@i0H$O!OUH1f_g&ie&F0LJDI*zaOK86Y3KP&uAUO91R%`lO zSlpk`KD9DnCo8mX?vwQFkb2=I2mDy#FY|hmXTE;~nJwN4#`20US(@2@^m#iqOY9 z(V+aVoE6D}P+1L2w<3fNACp9PI%(9-BxD(>_qE$Kf-|zGPf#{vl*A*G_~DWYSXq)r z^_PiUEm}Ls}U2&`rk8ctN8v5!A($*WH*jsAFvBHrTWJS730^nK~k9R)Xk1Fj3F z!P2j{0EohywxMpuJovYMf^caiJhR?~b?87CbKOd3^5Gmc7`5|OsCnE0^FLli&b60H z|AM>rqVC zy&*e5c+WmbQghwOK6^?6+>&IU1$l{ts6l`&W@*1E+a)Y7p1F(QU$YCH9{M({$}YWg z7OF9ds^^>IOc|U@H8!?kgHYJ3JF+f38%CB`Qt$K;K=RhR0!r|{zXi_O?;-oU*S07H zA>&9;m3lwHOk@CQHRe|5kupduL1SoCW;?t;%td(!A1f1oN5-evp`!w%F|-jY4u7;w zN@qllmMcFxRM>@#`hB5lvtz^{*ar7U)_K!ZpNeE${qq*1?(GHAC(rT?aExC9_jOk$ z`V={MM1T`yVsV{4DQy|CR3@A7)?La*kD(zNL-u9UTd=~&chZ!tN|oUH&8VBZRM~h1 zoD+v5>w>eBm^xxr)rcs+<{UQ^))c^+W8yg2SFcCiyfrQ3?Y=jrPW!4RTk z1ycWJpFai09?9`ayYjE*)f*5!QPsj%I!6zK^UMiwojFk$SI9KsoAaLX--`ucL0>@T zDwp!38W=Eov{aJv^greT)u(QqMR!8V2SkYg-6Q%~c;iJa`YLQ9)2F~TWFTy#hf1HguGB00_AFVW`ea1)E3;r9 zuI5Zv@{XS&dj{7cGErGN7Yg_%eCz}aVS|9jtYd}?!;Z8?%}veUUqWEdVPu^(4$f)3 z)MtpZ3^CTz*i`;a&&+FcNC`Y)$x`RgfU*g{TBBKBE>EqY1g?mGVW~6vFJ7#usYQ&e zFX|`zvU3w<<}`7R8j9d22ZX8SR0+o+hkBluyti;p8IQoueQ^LzO-%yyDc~$M9|TX4 zX{jNo)?@ykI)^ky!osZ8K!C6=1{Pei9{!EngoUi&?(fJvH637@|4oURxh9QAaOZvj zan-y$6S-Gi0)twE$c$6-%51fVs2A{Nq_kYh`f%iZ?{7ei%tThTo~ylAaP3C*w-5|! zzhiW`;;}h`NR|FIRH*&tz<8M=&P{_qULG#@+gGPw|2tYvs{=y+?mp*q*%NUu7CKlW z8t%n)ScfA6{9EH`+yTf7V&J^%dkcSuupw#Ex<`2mlmAtNK%b~ zdu^P^@Srb!q8BFK$*97hEc?Lk@fIzGK$O%Z{HGCpTiCzU#36wf)Ip9j%kZ=oROR^4 z=37gSv?rrRjglWtXz!0d{x}w-@D|JOFkDn z;P`NJN&sLg`wRQ6`4J`rSXM40$-=}5=ZI_7?AfzBWLq<5&XnW`6YyUIm@gw4`Lc!U z5Wy_;kz6atuyxBVx3u{kuDzPC<(}(?8*WJK(e$!n#fk(28vU%^m*zIn?#`b-Ul;-P z<>xfvnxL)41RHh~Y?_gb{9hIB83;z_K931~0teE8$GEp6_?Vzru8rJReI9Mm*q34}v^_xPF`9J^p&oVc^PS%csY{csPh?Q4$B#_kZN67Hf`M3X1l1B~xApEP>!Sn8N1UBzN*`t3#@sICH zuy3#=K-M*vB|kv*JL?-43Amy3!N<^0<3V`e!Hx#HT8~?e8Y(|}VOf)chx^0u+rOc9 z)*?wD2G(zq7}KavF15O5H3-Oni8v;EbMO3i;&1lT z$D!a3KS~~a0^za>1h?*nD+Rb<8$Sk}M+}t&Ui9!Wc;8zA@B152H)jQ69v_N-^3rh*vL2@pi4(s^Q2yfYrni=yD*tioX9{V$j?)@%YS6=k_7(g3iVV``O z{3OlO*byig+#h)SX+##R5dcbP>rObP#!IBz$B%;htg-NK*skVr3A}4Iz?ADoaPKjg z^Rr{>zPMeJAkz)cj@vq;C6HmS%%mumM z|BfV98>(ti`NUsPGj|1?V+X-~(KKX{%^?pk**gQn|4y zvCOe>U)%CxT-K%M!`izCPW=22h*sAjtaOn898-21H}czYDZY1?;KXnLB{%P#lgA)O zwTs{Y|LXNp%8N`3$M+sV=bzsX`;_z-s-pW3q4JsMm457mZ9oqc{_r;OnMutsn&7_S zs^s69jpB>U-MgaV@n?jkBz)kQFh*!|OO~C+Kp4(p17PV~+#&U+el*kvVeQcgCS4iu zlacTz`%v}F3-E8+4f~*;DEiSIF!$+^;*8b$5styut1C=-$!BGA=RyJHG=`Gd;aJA0 z>gj)>cFro;hxCN|+%u4M{!|#%`Xf5NV42eKIS7}Qq3Eag2_QsR@VM_*`e*4fK0?CxL&#n3Q2Lq{LB${iz^N*eFs0k;uO7`s8`C z+0;66g@8*co_Z0nDkDOB55f@)$vR3MW=R##(sgRAdPylF*STj33lM!J%h^=^YbGMc zPoPlQt-g#BfjKrc4hCm(`v}S~QwMm#PpzZ$^HgPXzh21ccT-AVip7U;jjws@Jz)%o^{0Cm zK25^b&QvUU4PYT%5F=~*q+jHSi>l9h0ShmZzaVw5L@)vYb zzAXD&m&v^P7q3KsC2Ex2k=-TH*OYvS!J3*EY7~Z!@XkH(C>;%cas(L!%rSBo{sk>O%7*X$HIiZvoFH6kHUQfV=I+mv+ zrSL6WA>|{3YHYOXv+<>|iwlYM;o`k7Up><+%lLOAs0v08NSN8BNbp=j-xc{7va*Fz&{i)+d%@ zGv~Sl%n~iHh}(#o!ze+%;i&QnUFExC;gJa4vF8Z=ioF69adGng! zBL>e>0Y~f?Su+^iW4V=wAAVR^ESNZF85<^$7B60m^Ugc3#d{YnTqwX9CiT+=9zPG! z%IokJDsPpi3X@(GCcEyr=bjdSCwPTH!?uLaU@(;I8>xwG-h5?3TsFIEqu-H|K`f_4 zs%$3I+bdr}&;%3cOe{Y7=%d2aLBIm%!+r`j8f3U(pqTyQyHbUTf7&(!tYl0gNG&xv zNf6nL88e#BFdYLn5m-YO6qcmm+@vywu>L%C^@=O5kU8Qw6X3!!RAjaxsD%1P+tb)L z^tMNvU%q^~07{sIWwKODiV`$K|G;;o3KOUr@GV^umSfJbCm@P|pT{11OaM6aI~QKq zk|uN5uwlYr!1*I6hIW$<1Vlf|o0=^1lx`l{3?wLjrjZ+?+{XA`+j6<4@QZLg6jlUqEUq&+Wc?$uF5R;lrq%G2SalPOT_H+Oj?ziZpD7426`$I-D(oRr8 z?bW#t;@Zdcnl{Kif2wf5L+~esdzeqNo^#*O*7xWixX;rAT{4mpy{>Za&3!4)WYkrH zwNw2(&!{|)P=9z<&=?W5bCbprmMYx4G9E!a+gkRt+|bBwDO$E>i&@OoE#`=Ob3*5oU!J-)F+EDJf|g*bjN?$6S<; z@#!5xPZ z;4Vt=qb&&TIsn_i-pIfGI@qVg!7|puJQNW8@We9+&svV4venqpQkZ*nNAQD<@UGn? z0Fu0KUWlygn@cm0HHqaOB8QHv@!N&qx{u&EZ(7^)uI$65bi8iPa$!g@8smE2$Z{Jd zBVv9vPs(mBm!&C(t@=lH6UV3_N@vXpJ)qAZsK=P=YIjV@#KICUraYGbq6ko6(wn83 zEJNe^O*Q~BE0_v$V9d*D-)@HwLDtj>@PG7*lwvY`h7zxh)pZD{v1I8e_nCuG_~2a$ zHXQ={%-y=6;#beW|M6Y~Hf@D{;+Pi6aI%q{`1N1lUA;xkb$1m12{be zI!BW2CYM7>1m#_QQJm37AHPz%WbNBc7?z@Cl}!n6lNS6FriT{oX6dAcmhEeEo~BNQ zbJ^Ost?Oclfwdci@rSGuIagkY>>Hb7{5iK>uj~y{p2V}{Lu6mJ8;*0PwDA4uq=6-j z8#=Dvj?>4%w{DA+WlCL#S+bDe1K;{BYCWz;LnH?0$N@_CMj(2;621)|$H$^+Z6Ii; z;&*?AcjabSdv}KG^pSBEBkGp=49m}j_8eBv2??`K+L-VBrKo;$o|J&gnluKT9{NE7 z0NCO4*u?S5_O`=URulJITC8{Wds32#WvhzrzdfO!rf!{4Fk&!b5C0a?Dv$DgOW-_X zg7{b8()We2$I`PiBKwb^p|(!7-JpI~F6D$wS#|_I*$30SC9tYzuAZg0I2(J~IRvX>~)XJQkDv1d}jP%923@hNRXzKb68{gH{Wg z2@En#Fqx|f6CqmSmC5SVTYqdblhM2hPw;^L?*&chXa<@HKpJ^D1l%j0ycj4yWh$G?%K7h)CvD0L@P7J1b!-Wg?^qG5Pjv9R|F8D-3;eg zvBU@yX6*^tLO5OocxVArf`AB~V96i~^{yjjpEx%Jj0_z*RH(1p5+?F^H zxGmZiTHK3Ekl^m_?k>gM-QA@)1ovXawYWRQDef+%XmAK}bKZDY&KdW;^Zm(4ek40< z?={x9=A3Iz?)$)}38V2#9jfn>WMyL3#jso~Nja!Z5_yFVZ$bAxFhbLNYj5^-x*qKh zh97WQzSyfPa1YyG$L`AjG$^Cs*HUnczZP+jQQM=^ z1P1`7$VfJRKBhZXk$R4kaaFheTDj%lSgZ{uwxPa9R#*mY!!Tr zc4{)CVyZ_2PO(T`7jg?H29VK)m1Xk(VjUv`*0QKh07A_hXw`qZdo!<3v04fkW1isl zK1NLP-e(yL>uAXSzJqCrMO)z& zmhl}&*O&QPVo+W_?CK7Tu}F20xi)4XtvG_Fs*OOqq?|lLAckvT<9jZ59xXO8sxh*; zy}4^xv;frwFIN-c{ty#wDJaF+4B+A>0cgzC_e7h+?I-$f0;$dzBOrRs-i?jJ9 zBDWR%M<^L(emxKqp{5;{1JkPQ-Po_q&|K-<&f3}?g-+C2$TjcyK{_yMg7V$f@a=$F zIQbRfm~(qOWe^L$2yx7A!_Nhfv`T&L6^F3lC403h8r|7 zNZ*VX?Wrr|^?mSPuJWhd!FS#R8)DpS#M z=*y#=>1tfNESD?WIwM(yhr}(vX|MfI1y!k(ndP&{38_YZM-=dkJM-kn^s7?6`6W!+ z^jCZ(>Rz&Lz30;?D;DB*)X*2~<#NM5HIDXZ>nDQ{R=JB+`WAE3O_zhV1Q(0FWM|ZG zpWaaqaTOw4rv>GsXEM#SduY7-F&K!^N6Jky+D2WKp77mmZnn#e@ z<#*{qcfJX0#-26_Tj(;NKkP1^(igmh@{AApdPU8;3I6|bb8e|KXO(!U=YNop>!EzadTMUvKE8}qG zR-#Jxl_U0-M2p5gC#EG~m-7SPE%`N`ebcYu2b%jR^Wji(>t~hy#tw92H4XCB(Fj=k z!cl2Yf}@$8y}gyFL7HuFN+kYFv+W%Feg?VRruarUG%K0dCp5=XFIQSJr{^evaoM@a z6D)T9!(m8eVZ$Y(!(>t=v7t#EoF!7{D3e zy|Z3<=^w~ zsrZu7)3y8C>VP3mqVeKfyv8zsoOIaB=<{&tZBi$6z$&&b! zjts%cBdLOefggoRC~3)jk4m!e^{QBI&oBl2B{Asbi>5CRd_PUyu9fs4t=ro|O$wXaIx6k!evZ zf-NQ>@U|EbZ3GfYQeD}#X}bt6(|dAG4V;cjx+P2hQ~1jEV1n8Es_(EZ{3grxQB+MS zQhx!T&6WTk^GpBy`8igwfnfdlWX7ZKPsUs{e{cQ2Z~i|fd6fWGV~o!N$Gli1z@JHv zYJUR_;u**A{F4-dEat+vN`*l*QtKd&{%s6_sZ6qZbcJ-+1l53}emKC_P&fnxdo%=G z`~l3AAMO9-G!9AeBZmkK<@bgiS~scoMH;aX^s`cufiBo;ykvN-f8XO2@d?4^)`iy^ z0-V0kPGk=n&W9}qt1SJiTVb!UJ8mAohy+VMPP5(fbh?Wa9PW|;OM;1l6w+%ZU@jIs z2E2cTCSVrE@vcigxlLn)9>mM0P+8QK*7*3Q{@8rvr(E%q}{G_OJvYlw2Fywpj|*yoYo$l#cL#Zc_m26h(O{+ZHVcJTHa z8MYao*=)YQA zD_g&j!Wsy^X?MKZR=BW`Q#BW9B(5{jKiW9(!;6(61>%EB_(#<9Td1S!lLlfVBc-HS zqNf8ej&UBYfR(NVlY(T&1P@dC5crEHzsl)M)zbsRD3=gB6U)Tkg0K(7?a-{A4C;zb z{zDf!GjP-ae;-J+52=D2pP zvscLdo*~i>zxUXFrCzkhszF$vTlT9#w{P=Vvuyg&+Dcl-kCDQUSf{%lgpwfxyuQ|O zuJZo#T(H}EpLxze)qimYRKtaInJJ?bz%6!}XJ*l1C2K~*UKaypKP7SHzmvxU|1xaK z+m*bEN@&sZ^H$4H??*NHC=kepM%!|M2V@r?)6e0Vd;yjPNG*jh#XO^I;q&nJa=$3NInY7^zR+yt2RVp*k>TrDBiHB9gw*yu8wb@-^`1&C zyRt5-aE&@btlV;EHIi$o7ofl5&EMmm;W0A#0gTMOFrzz$^@m9wL#UMnXUy{A-`0k0 zWIN;r^jB*&MP)z}mD>soYM;x(o)&mi&%=e*4LVCIPfNQHQVLF%j@uZ(#-@8Z@ni^G zn-Rn6ux=H&4bPTC4;o%G58l28!`UU**mR2BndCq)PuNOy7rb=U^o!!>oaz)rh_sk+Rk zIT!fueQc%}Hvc=_UGz1?bB1zCqf%`jds8$1>x4_(TF@$+n@chW&_Pe233ah-=vW z(J@G5c!?`i%JhL`NEY*#N6>rzO0)DcP|kX+#f7c4mj6Vj>8eZf)kId1tg5M?wbBU8 z*eRh&=|o&tE9uItS+>|AdRODx1Or422 zagMI%&V)ivBeLjhGK`X>9m$@8Z?v8@NKqwmm?ftG0Cd-AziXY_w}N%!6HOlxH;T%O z6nkq-$Jiu=#{S>ra(dA}MMU!*=?GFXr6X9>>Dz}m1Dke(l%x}cbuHd8*BjNJRN$fB zs=N6dsMFE=ao0hZ1&pT3&z2{W&_k5%inOdPf%KU1f!OMc0uF)<7LM^|x64;CoX$!G zbgV3X@i9hS85R6+kf|DrtyDlUQmMlhd!s93jAa2Oq8EO6dW}eB!>W$F-X*RpPOV%>N*N2j97^pQiwU3qNrIyg$Qy!7KF1n6 zd4vutVn(MDTeVYVh$SixC#MpSpa)a=&}=km#{JxMyl zJjqpGSWE_B$s$<34cy~qj{I{X3Qd)w;g3ByqWT(zMjL8hSw>ik(;;}3_t=dT~%r{dlT;H@op3V zN4SL1wf{*e6mk8}o5!@tGyAdFPvF;A+E$=;?Hod#31n4BD9Oo4>Yp=g=|#I?eYbvW zxxGZA23Z94TDILJvDbzwi{+Kf#^kW*=m486wKTPx^N7n7oL@Z={ccv3@$W z00Di`J-8rO(QAQTiY8{-^}J*H4Z8;7^WIjg9&z)v-<;*Md?`=06Wh3SQ9}V7!u$_A z=%RZ9Xa>#+;C9iYEE&kFUOL*-0ZxXqCz<3xb={fRLTWMfjk4g8ao(V}Mms)qDu) zr#fb_q8@~NgyLNyn^aIyhn)Q;m2BWQxQ7{f$|30Fy)nXV#?b4P)A7ZpUXFL=7*_j9 z)@Tbe;M9{-_7BUjN#SW+jZ=wki}$?9e9khwCFN3MLFO8^Wzjx~@6kT8E{AcGT-2R_ zThnMir?twn189>TA3OfG>!q=d!vK}ghn23t*^BQv*b|=sJ&=Pv0HZm~Q6y+*S0VF*vQrkupfHjxZ^x%3a2Q zZ0E&Nm%{Ob^|&ROOCjbh>-GK=K_EK zoUDbmVeM*Gx$&mThZX5Wm75tA^(!T!&vu&MJRMO|duEhaIzGbeQ6yYw1K49pEKolMr?+pUKg_ef!=;vMw&%^s z6^60di1fCMGr($2N;G<09x+mJ-TY;#N3*_Zr1&7;cHwo;5f-;D_1erLqX2EWf*tX8 zEML)?{|ide+o%qg{OZi~$_%T9U(_tUliV4n-%Y`}`k&D=H;Tfg@EtvQV*q=jLx3rR zuckq(TjJ2Q!YajD1Z!MrLnzXAnBSZpO~=7T%drw&PvaR$G_j`zVKLG7j-N&PtMg%f zAndEIs#^ZnlIp2Xu^AMLn15Bs84K4G#6FDD?mw6obaPqsjx{B=F4b$Lr(c~PU(Lp3z zFD+S;d#vCw!5)N^LUJ$TWVS3nAJclNYza$e(mhKnWDMmhT#mi1zN1Fh@Xy|61d+B_ zL}eq9w54vF3#(7jkBDJBOS#A%%56T%Wxb#HVBbfbMjgI(@{S!zBCfCrQQOsBGc?Q=-ID>~ zl8x~-As-*`9S{v09<;{S7!m1sVbMliQVz<{2`)O|80&f|)>sc2Zql)SmCn%JyPQvJ z+QmAp#63d*+K>sV%$ROxwu_dn8MkqFSPg;b^IFM?TwE3ZL&^GEyUuh6dFS5J`!7qo z;*H=rw>9L)MUue-wBjdlJB_*!g`KG-Do1O%;FKj#0#S`=Ed9eoQsLWxpc@UW8yn-j z>=&_mSB5!SvUBqn&c*{6v+Z(IMM$^x&Iv9?o%Z(Fp6p8MyVdWit*rS!jqasyq1X6P zRBhJ3!=x&yld3^gwj!k;gcjP5vhBh@h+CxTH^S7JVaAUc2+52EAAF#qc>KWDYA(s- zO_v_6yj9#S_CYxIP){b?IGQ{#;hRp6O*?f8CeY9Q(X?DB7EK{5>9AShfDJ*;A{Dv( zhsfOrOnUFe{DKK)C1Bsx0S+K{4o9IHhYs8)!6|Rc!aEqHsG)1@$1Zyrx26bzvjJkw zrZYsR>bX`3%A}f*XOtyou}n85E~`ftJRDS*QBAp>hO2)ImG#RP$zd%n4yPdl;Qez-1W8Efo6g4xo}86>69 ztRWERPhb-TM24IoApHPttE}6f3tQM44#eXMfWIMlCPm=)ub+roTU9Jri*vhBLn%k+ ziK>9@yT4L?Hn!CF3F^t`KXw()0EfQ~G~xlb%}I1qR{A8A3)K|QMduJ@O@SG+Ru5j4 zSuxaIk>}&(x)%1odstZ4g(Ck5btQ}erdP#`k;!Z#1J|)-Ww}BP>r%lx5T2l?AA;;8 zaUM_@!=lJF)e2%vpk=|p1Y_d5IxOTruWF9Y>+x`4R zmk>Y6KrS=xfNWTik>9m_&5;m8s`0GvljxUt{NEDDxxd)_M?=M+JOs;kOtb8Mk=7=> zw?Up296k;6ahU;gehsUd_o1D6hb&@}gjJhYY5xX}PInHiO{z&7Y}@-D_#eS#e(pc* z(H^e!(H`SMPs8^=V7hljJ{%uolP6!@JP~JH?s`>;IUGDRPhPekGu;Mc&e%Lo7Qa4x zxsN?iB^mgE$WWkYo?mv=3Fw8p*ASK6Cp{1IH*6b;mzbZgBX9J9Be)ENm$WJ%kEVU6 zcPid3v@#*qv7uQ#Cc6G!tsj=hy%};{HIp(&bfk934yO6!)D@e4yq$WGTRI6hgFpXk zInz(O@Ns}W;$@)ZricGR?6W+6)3ctd5oh*MPuxmvz~6^Xz@R|Ke&9svdV-Qh1PCR* zy!+HJT-!nH>CkFW$g`wFy5aX_)Ru1OPuwk)H>-$tvF1x?{6WTUDSiFv`g?2)^HikU zCrC+cwA4Y-7#~5l45lG|eSv2( zgAGMtpsh?PwUO&Qd8Ltww0oy#>|>sgoU8djT^KqP1w&9KxLE#la#^AwGKM=H((U9VdoZF^ zBfUS*Ox94Q^ffw0DVIFFnqd#2>E#q3+7n5fEaHxz+^#I0Tl@Z#lvuLo^#7Z>Uka=K zWg1*;a;Y9U)Z@!BmBrkU9iF7Yz!d)FU2j4Xdx+B#$N==ZBCxU``MKWA-L@^cbGZDRTt(kjDX#x~xoy8$ch0x>-)6;y><9A&@Yt6xDdY5Y_Mpi>3Ncc~eR8`zGdu|E`R`s)A(2l1TpH zEhFzR!O}JK$Er|4mSm?I5UNl-=k0Q)y?@;^{F>(}AOO|K7cG&eJilRkKQS(D4a-RF zRTf~YjZB=mpKasvf#IrRjFdP5uTH&X_C2USq4^(_+PTcp?$2iXSU2eFEpS@cNO}9x z7FhLf$3~(PFOu~Sbzj$iF05SyUGs|57T$fscKF8&UAPmtj->uJOO`+F4_@WDeA-}$ z($M;%&PKLB4q*>*0H}PPX)?P3y`XZoc2Sd5tu^Qk&wc*q_Da)z=FjOBcO3a?DGPES}waaHm zV{~HH_GH9$MUc0D1O#b;27Cgtd5IGcM%Zb$-Uf+HYUJg|!c|Oa&~_Fden@Ku zS@lQ-IJu0H*9lM}WVMdkuB|_1Fq+wqS=P8rLzwgxXR`?@J`sE+uj@Z1e2E>t^{O&u zR##qiKz?;LVeS3m^EjPLB_UoLMm4>9Y$)ZtN>?&~0i~kC?ABPtxX}5D+`gVMS8<)y zithIw$#z}k2NvDZUX7SO;`TBhwr@zs2V4BzX~~ft!)zHVTRLnPlWovddfT0aw$fK7jjvBf@$aa=X%l~ z8zLO;b;Q9Vg`C!?c!wrbvA2wq1)#*uPmV|1^O8;od0K2m-!6H%7&}(YRX`e}@9?4j z_x=V{downCNw2_(m7T;rB)Kz$s&~G3L4?R-(`8qyC;fpogWM2>Oug5Jd$b_!8wY?K zGmp63r>uo$U>Ik4=7gFxLyflU1+A_9y8W@>t_~Ehk|>foN4a>V9uF1e(PW?`Yuvp| z9D7c&M=gE<(GtVso|`zn=2L4XWvZ(cB+HY6^M%BRqcm*=?tf_A)sd%Z*r^*?L|d~#!L%h|IEd-lB6asyQe2CnN*(_SN_3+hmM^~)tsKJ0t*sA!kCZ^^xr3L-Wrym zrD9h=2W!`kA+J4szk*yi zI~R<~Kyb0W4R6j`XWN1h^N%H^ce~4Rea0Su2~bHwt;flT%*urMMSOW15^t7L!F zsY_AE7R^+NJ;3_{TVgSn>}j}mi4`+V=BnzgR~TV+&Fdc+YDwGpLa}^zHE?Jfpj#Qq zNlPgxNUgxC(QfV5+|y1~&IzG?B|c<-ef_sDH=olHRQ+dRa67Bx@!{<)kTj^}-LEjn z>t0tma8l5Fb7QRciCVjgjx+Fm*3tj3=p2kD+hctUS{!0BnvPRGEOzA}i%m{4=hCBn zuq}cwvLj zyfT^z8*V0Ak=l!|bBscdyAq;ez1doJXC8`Ao?3w+83|NCS_)b0#B6y=lH_9Mc6Y6< zu|T@-XI&@KYM4wa?IH;oFs=vu9ZgGP5_K-b~NuVeLtgx`II5r9fhN zAa&KL%6nDkpT}E5wRBQqc{wPm-55Q^csMM^Lep~{+ND0Zx^i{tv*Pla=bUg78&jwM zal1Lg-6^QjRQ4v|y|1?J6}3Ci8J{l5)9?6F)9j+)Mu31M04G}T4hpC6j(!Ig#9;DB zp-5$Q)ZM`DU*RHPLISVthCDSW4$%k?t96e095HfoCSrDoxZo|cjbM+PxYRH-g)?XE zzFnbWE~1Pyk6%RUMmI)uXpdE=qzW>J^Olt$oOiuu1Lz=G5$2|MxlJ_7F-WqVOH35z8X zGz|uQbOPr!ou^n(_kpeFVpH#L7*M_*8x#u!xjmcLFhn>ljnTB*b17Ij%zXAn6ndPL zw|*I&|9-v^B_XboN@l*LW+GanoKL&2^0Zmk7kH4FJC-RWa#tm4fV-_})|C9__;ok5 zrV=k8@cF!2H!{-+!o)!%jKc6NvVf_^h|$nHd>q*wgk9;_jgYXvhFTg41sD8+uKj?v zIVcu@^gFh}D+Eq2hi-Zm&sU49To1XjHxl1B?6ZznCZ5P!@ymj(HPJ#U!l0IOiJL*? zzV~|w2wv$6xhWi-9o_?-_=zN)l)i7mbE_z5~W*=(EpDUvuIL#v?>2)Ssi1gGi z^vEu6v|M#$%BwZND^a|gA$uTW0Gr&kj_xwj=uY5xZ||z;YqewzyW)EwLUe}|cJE81 z6%xiMWy1zx> zssYOZ-!C0F?0?+T#=SDY(G11%Jh0jz2Y`i|9q~%9@3&rHU~y}M19XI=O&T`upeC6k zY>-@ArUa2X{@xUAs>&y)#3I$zgnzzGc^ed%DL(RPHIFTVVrzJhznyNz5wXQy-(OG_ znY(Dici+%nsS*WDAI~lqx(!8jhXXFYl^8Wz(T5$k$;#!Up!VL6#%_89FQEuBbg zD!(oe@V1;zAnOukFeROV{b=QitQl`nKm(TI{;|?LHAhr$cS2VX|w7B&EfY z!4;YK!*)Bns{0>?r(6cxf5!hb$L1Y4k;7QX?f8yo+^OF$&YEitFE7wKzyydduOe?} z7u!g$oxhelZaO!tIsmahih7&vtleQWC=2OOM6Y4wqg6`DVbU4)PW(Z7eEb!qF5Y3V zltKz-p=T<>3KKLA{`xE!8MM2SX$8tD8*@F3*&ElZ(1jURp3ug1q8~2J#Z~?ty45Gj z+4-HM%h4{m?>stcAkD$ifkfqA8R$!&eesTqDPS|j9;Q%x zd&)??>qE}f=xQQdek<#9S;$QA1D3%^8g+eL z+J)H-GWm$ENIoS#LiH<&fPn-}KP4f!)Myu&QZW>@_l>$jO7HO2v;QF#r}%H~yoslu zWIt&h2MASRNbO@JB~y%29x7A|c3o?h6@5*wQ6RH2c8aCUpgrKVWm6xI|EHPJPqXla z-m2f{08b|dDT9p-+h@m;Egcq)iX`j%uG_7*7$((O5EGaR?O%WZqe0+#mfG5Y$DGS1 z!1@<{0>+>U`0kr)BGW@76Scp#0di~|{F^o|!6A{ioS+hC+*W14@d4#e@9f^ajtTT< zYvQ^7q!lHQx@_17QS7w6iRlUXud*q06RMu4+J_Ijl=MKG)Rs)|YiygtsEaXaMEsIh zANBQ}kn)#j3mNGFpHd7q8Oh>tH2RVQMY8%hiQ(mGj8X#i8r3=lB|5e^KvQ$<%$dff5yDR7t zlMU0;GUr~=^w_z&8*H`48nIsHA4T_p%c3>i$|(Js#dsBQ$%hPKaz9i)KFvXc-@|#4 z1alzn)NrhGy5!6hzzI7|G18I~^{NWa%P~IXg!`koUUG}zP@n}ad>M~5wv!ezd53N? zh{4YzOT1M_ypW-iniyQD67jG?_iJt|%yZ>TCPL0NzMaMKjFfj><9bi+^9=|2_%bi^ z997eE6}}{ULIfn&zuBBlGS$$tBeg<=`nUmWDv-x*k8+IqDL~DQ+yYqj?PA0WT&-k= zvG4QbV5I4A9y{BJw&;OA7qOxD`c*Nf=tyrHRYkeFs!ldhjW#Zo^ju)uy- zz=yyWg(N&Zs5kiWqPyr?%opgsDog#w?)ZolwAFE;9OeSM1_+M;dn;#EQtElY0kO zOMH(Jrs}`HxY}soa}T*r!wee)RIA^d{Pr;?y9#UojkcHsnfnN_TDE0JSw-uD z#w=;Ag=sU=Z@QMN?gh25aVva5<+YObqa=ld*_gIYs=DEzoVt`omv&Ow_y^RUy0vs$ zgXP6nyqj~|o=6;~wEL`>`}gjM(oH$@DK~T3V4ovOABA|zhrC-tOdB3t1Gpef$<^aiP%M{p%(I_@25PpW}ewiYIZ=c>hx{a?lGI4Uh+OE3ZDuNHOtjRDRI+9O``Ll(s#YUQ8h|sp{J5u zzPZP+4P|V3_?#wf1AH zol_=%SE{H+89~v9lKtM#fhM$x7KQy%Gq~J&R%9+FSE3c)JpQ#g_VUn1k1B8hq8J5o zR$xO(No7b3$i!Tqi=Sfg(M4nS7{uAbx-FHEgD2nYQ6>fUNQ;G?s0%P?mJ3sXJbeX} zZ1xvgvH=29o97T0A+RnTq^;8?%KKAAxGH(tp$a0UDt{ctt3dxLrWn&{AcWjiaO^|- zA@9AP0S~#`xPoiO=8_=4bKsRkcPC+>1UAOqQ-#D_W^01Dp9<+zIL*1j`(Gv3mk(yR z`;{~$EP<51gwFDgu~>U78H^|nb$vaD6&&EDEY5+eHaUng1+XkiL-e^ zAz?~v8Eobn8O45F$D9}90xdw=?6__?*)hQm4s;F~^$PREJ={7oe-_G=DBwkDe1x_P zG~v!k7%V?*RI}6g-i!O}WmV^K?A7iEtl23lbSdxW+j`jaDo71|f}SQVc|i?Y!i)Yumxzk_?}@+=R+hSk++|oCQmL&R{Jf}8qoy* zVT~F78=c#~CtlfLxq}*ecsjekXKP(YJz-_bQO!_`4A|ar&ws@H;3uX(-uHr#G@$^8 z4lqY;nI0s$8`X9f>G2iWKR7qhO(`jbiGSC!dx$2kDR8>j4Ja@AL*Y8{vAPuwc{JpX zR-E8Wwo5=IQ_oCCdE_=lA4ajpPDI%u@GpuL+mYnA8F`P^$a~wecDCjb9d}DHb zFt&zH@c&bS;oovZ#Q&SxcaDS-oc~=BEzQE>qWm`%KS+=bebD}!a?ugT(&zZ^3f1mE zq~QNejhLV){-0y@KL_%0!I&+p3FANg#ywIMSHBfuv^nCKxf-F^e;t*5b~uopX+s-T z`+pjWGu-SQCUf4x)j$|w~Y|JXO*+}Was(uuz_Jbl>ZJjJN14eNGdP7S!z z)mbPY*laT6LrHl?`#D(1NSmpUoqNmcE_N71wP}fha-K*4*BCi5dkS85Q+<%$pZ)*1 zi>T;ObxZwaf)RP6EBhoRiH=-AJ&sQ@VuXoJfO2K&=UvGO6FDlA^L4m;+5JP40Mla< ziLG~doI0c>j6q|(xaUR__6t6wcZG@VexfvR*F&!w&P5BiNq!fj|ebwv4 zI5C!4oveQ2?&tIVFlj*vDZr%*lvvc6KdP-rF(Kw^+aIm+{EW*eS=oVFi?41%$Xa6c ziVBOd-KIGb8NkYWRv%A-niB9H18$P%`|*6}+^1Ib>?r76@iUbm(LA8|`6ZZOCpCGc zNl#NB?}K{s@xJnnG5T1ffO3i3#aU?IjR0apgAw za97UbrK-Kf>vw_)?wr=D0)&xj&nuZRuyH{i@mIM%hztQ$e0f#0cO=h@=Lpl(oKf}x zepLk+XBdUw9}!(~j=TNw zAs-nk@{kPc`MQZ#d{W4*>OX~i`*z}GqWbpGFsU*h{M;)LGZNGjT?sIVuG9*Z zH$Q=_fJ^yJm^_Leyn4QaKEdKrS>}-Ve%gJ|9@Mu7F3Ox4UoU$s@TB@b$z^t3B$yFK zlQ&rKgW?tIQSjmAw`(Cu3B%|hu|G~5uxX}UAh{xf0?5ASO!y=!%831`Vg!|9>MYv_117-ZxEp86KuxNmMw=6 z2i)87miRlQXPF`tDH;mkWrn368;Te8NZt*@`n}72HS*^3&&a2jC=Bf>w8u8+{J3jD zkFnk?4SJ+B;z3&~3`31cl-90}e2@72y|Rs9vkR$0WQCLoij{NUz1<!kn4sr~2&2{ydS=fIXc zp42# z=`R&1*p?aF<#YKU3}Fj(Vp6T^)I-p>QN?R0_gj@l4LSYI>P!@%Q5H_zemuTd4%r`s zXWIHsb^|x48N7q}YRxDHmAINON`<#xh;^(cYS4VKvtW%;62RG-FT-!3iOR+BKC)<< zg!({INEIGDPw-DRKaMccMG8g#ZP~0($0>eUs_Uy>>P)vfD!$Nm`vb|~{$bumAlwQ` zdNMLKLLrac7N3Z%qqyDWTl^E=n1<34sOg+QjCxtYzLU*Id+Jp|C7k_sR~+J!pvU|_*_U%u` zqHfK-FVwP-;*vpn6F?$mZ-o-s#Zoy6n{hRVrV=z$jJXa+%uXxsOlDJc)EXr2J&bev zdYPl*ei#uvnDA5jJw9D~OZ8L>9_GE`%ne9B6pHer#?gJ#Ei0sqSOwiy! z9lh%R%xnU38%5cU8r~PV1o)#|xGC|s?c1>RpLq-lom~;3QMD88`}MC$H_xogku>Op z`%L}QqB=w5PM5ao%|tI*>DvV!C*E}b zE5>FEQa@!C`f3kcckdl#+l&yUQGX#;X0GRc(`%dIlN>|kIXKS`BQS{g?6oQmlL#lp zb+aj#+-i@hr3$B3cK=!^@gRLfSSa`zt^g|9;q4j)(9$s{qpZ(99>{-pTn*WJe`VB> zM!WQ{u87;a8{n!&{%Pv8%U$8ASGw8#%e?4zOs~8-u7y#<7%oY74qYxT^ooYhm8)J+v9)e_xpzc7r%q)f9P-q*)`hD=Of~> zaGUsR%6kV`{}%roRUkDHI{f!_FlRU0W#i*EMUNX==)`h)o1W$Ow#>;@Aphu!$}q;aP1_5%-fnpu1I0X9G2Gn76eYWav=e^(Rkp#nIRx8aQPEIwKN zY#j(ziF;{e|(mu7;R78SvYMr2P5ak8cJvIW#-nG|gUc9rHS z%hM-A(Hgj0gM0c1-%7Vty78p5Z3f7U0)I93p=}&}s#Ao7>dB84(P4(?__0H4yD$QE zJ;{og6ID)LZGJt9ic9yDeWD(8;tr7kVRiR=&{B% zOFBBjb@@N&daJ0m+O7+*Q@C14;sWY zXaB2f#(qUiOu>0Yu8t&UXtC`DI|w9tNi7|m${KwX5T|*`^BE)7QJ#AY20do`N!MR- zX7?vRqS^BvnNvp32%#Tn)V(&6S)PN5BhicVE##xM`EQZi%pZBrm?#sO&mVwTYbK1W zO2#gw1Uz&tDLphQmxc@8(#`tuU;O@Zg41yrlQJ!W8ODVkygG4{)b*P@s}MaBLaK)|60VScnw)wVo9(M5)*n+} zzo`>%srU*I)PPus>ys(6v{Cy{{|F{2@mKufkhBvR5mPaAmHRjn4V6{;M<=_a zy3hSh-GMjy`J`5c2HsM8sdfH9MMzvHt%kA*PrcY&z?Ns<_W5?|^1WxFQTJmf;v3~j ztc{MxnTZ>nB;^R|rQI)9j8Kd1o#;SFY_g;xPCwv?D`)X@byJGY`^ay6>OxCHZxlv$ z_LwbJo~%4%h*SnO2NtEU^SIzwcLl{j#gAQpWJD@!X1@r9)*dNJfq!Vj1AqArdfo7e zvah;#3^^%zp z+dqls?I|UDUoSu)^hw{CjH2HF@E5x?J%87c^dXCGgxUa6R2aZfXDf)=} zod#Gi$!kSnc&4!R1)_Sgf-1 zKGyinLy^%gmfRdwOk&H$QRL*Ko0d2Dtaoa_Tr#+PYj(p;*s{Q(x+FXp1b)y8ncv}yY5Shue$qR$I-tJ z6yY#eb8NjTpyq8$t;*))I+MvtSPU$+rTOWudf6LA0RkQLS#MyUB1wS=?FgAH;_12ii#Hc02OTz+02R*F@$3s736= zia`e;N-Q+)Q}gsM7=kilE2iN*9rutregkB~S&a@XyTRQ%Z5cN*CDCoB>}TpAy)Fq? z#9?WwGu$jx8<38Dni>;FsVU$5w{-^ZO>GkMkZM9=?Mg%=@JBhwinAk2vUc^&xp+ty z1_f}#^VNFAgBYM8_s)#|gjtrP^~tn23;pg~KJ&2_%U0{TAn$7tXfoLJ*& z)HsXGQFKu1VgvS>^c_6E?3pf3+NelxIelM+rEAf6ayOFEx&z8t_u@2msPxj&DkISS zXzUmdjz(CrWCZ`BugyAF$LtiJ6}XXHKkeG+2=ZCmTYeN*QI$LR%xyht^ykA*dlEPO zA~CwCv>4LK+}SrTabp)`;kbCrQAc)EgOuW*dpFGou1Z944}Nk(tu--d2&zN zNADa_{wEryF{M1cLr#{Xs;2wfx?0s`iO*44{g#2Wba{#$#X%Y{4s_n`Oli`%`X%$p zyz0>fTb_|I)dWQqN0C33s;M00rAZSGEeh6Nt#d}h5-D*`?e-WUwZh~qOy3oIqaA~+ z$M9m6jw&$wh)2>e5h_{Jkk`HKeh{kJCe=u$f0Yyt=cL|F4@+t0*xxxt^E-ec!-JKs8hHmZ|Y4(E|>MArBAv*IIzQTXv zzNk#(Gz(1paalVYU-RPANeK16=pSYn{RkpJSC?40CPNo7o3l77!&PXf|0!QEDZNPE zGX*FF_1RPwiWd$B!WdKLuDq7uJ-= zF6tOz?iH0o|AeX?$8|`iWS-XwYDFx~eHZ(M{m@HJR=hK?K!|cw;R(yCZ$#JMcje6Qe2$m zw=g~S`E)?esul|sy8i8c|L!%Bq~lIRN7HzGso>}0ZI~y9 z-4t`JR=_1IJ%}a$TkuXvUmHQ67e0)b_|L@IEr~7$cE}%o2qtC`H~D?#frd!356lJ1 zUt-V6WHERo0=DEMlV(n`t=0F^TH6omKID9V_B6+dc26zn>Lq;jB4v@QX7E2l3v3OC zclUMt$`Oi*e$Ui)m`~KUbj~xm%N6xtZIsjAW=}MzYH`Z`N?h-EPJx$WJ>eg*vg;I_ zreqkWZAt!{=`H3+6?!-nSDbeywQ|#zezpcl2Op(6$aen>`RSC}mI~xBuZ=_qlo&Yr zi;@)l$Eo2$xOnVFC-`*No}8h%%rxz=4U0UjGmkFh^+uvud8b~U2(FTj$A-9Dp?NC{ zzM3PMubgkH$c?Kt!Cr_R8avG|iz?Y19Mc(3uWFWoEw-k#gq=8JTz^+p$jJDzG+g}inF3-}BcqED}M@>=h ztjg~i^3OtyyRKR(+6She5Vr>yj8bQ^ATT$6h~g5%$n)i4hFvX-i8C5gY1ff!CVXhl zwrc@n6jJ#To%to`(qwT|L#c_S)waC9ZM4pu&$IG6w1Qv-hTom5Qg(hPii@)&M`+ne zlX|rhA*35{6^XIPTD#8?z`@pVRk28w#%*m8uT>mFmM9 zi%mV6TYR&9V?15H$NgxT{8<=Vt&rr|7w%rxo0-Ee{u^(FCnie2FtcC=&J$&hxK;1H z-5vA=w0V4iP33 zMyIjqIzC$lm>Ga>z11;NeZtd9-fP8Wsm>Vt?U60riL&2@K;yVs@ih+%H_O|woy8Ik zi7PA;3qK!hBH;G|=a$jcY+75=bh?vMrqeq4i+q21m~}$&Oxp6N(t9(j6FI!mlM9T{ zbZquwTF7dk6YKGY6wQ!H%7ch#bE4v1f%HBuCxrQTG_!o4yHb8c% z%eXH+^}|~0%op17N(b#<{_hc?`;)&Trd%(E*E`fdg40wRu~I7?v!btS$j8*+H*3l{ z@m);6Lh66cb~ZiUsbH-c<2f2|{z+HXfJE5_3(9lPGp_xP=(bV$DdmyVS;WQpFjUyP zR>=pT|$cSV?(R{mD@q_Cz&is|Ey>HAS@EF)L>Iz9!8w~JBN%4bUzssjIoFJeMV&`b0Leu1ns3IV@-QTl3MqC{O3 zR;~6JVAgK~&{MuE`X>78#DR`GjUi4eE_NON<=edM#q5*x>)%;RUYG2);1|DU^P2>6 zccjLt%$-tyqSaZ-%F(;l7|2*{7Gln>xmD7UO_89FepEctNCX3h-P5mftO3q^1Jzv`R zE4EFjSeGci?k$eE`OLpzo2)T}qtR-)RwpAiU*EBvm1SjT#jFOPx5;t>se$bI6(hS} z^UBblKK0epR?^w>^2(Qf*KI0G?BB{0w+MmRWXIZAd{z7XQ;)xRcM9XMRABS+*E?&1 zG;htA>h(D3bu=#~a`*j`Q5|P~%%u0a^c_J6DDxdZFN^;6tPoRtc2z?cb!u|+&v&00 zI`xwDABeN>;P*#Q6)_CpoOU#tu^ zqxnKh;{cxl$wPg{R=3GWS>y1JEVb5$44l;cFm7)U=o#b-&B_0nF)Y*fM$-4*j%#pG zi?n`(6!RT_7@!zLo02|<2YJ6i;A)&g6}lhF<`hJ9z+)MxC!KgM6K^TC1&Zv?4dm7`v zN5)E)W|l|i{~F`F&eC!-nHM^9Sht_CZ^z3ge}U`D&|QI7i^IGjxkI5S;!NJBew7SL zmg(URa|Bjx!n2O$+1~Oc_6hq?m;)0(IeZ5;H51V7#N*6$XBlNfr>M9iREQK62}hk( zK5htL!sUpVbbW1@GIN2a577i9f6@nsgOVZQbjFSHx9Ye7==EbD8ZmqIV7JP)Bv}vF zo6Z%4=kp%6o-TIdHuc;KhMk76AiPdSfWiFyq|aza{2$Cf(IqNL#H9FJVXfz^Jt>bf zXU3KZaaCfDXJVQ7bonrlS`#v6PNa9hTY$aTO**dXt}J~q*9qXbQb@(9!zOxXXQeEe z6>`f(QmUJ7YjRiBQ;A+M75)sY`|nDXQWCR36gOp}9w%{A!0{+Vef%+Kyu0?gfrXs? zFuXKxhLU26$q{~2>EGLG{Wm<~`N*A#BP+53mc@J{Ya1ovA88pbH`ul?-!b(g}l~aQ>%E;(SWN%o) zPJ^(97JEyzbiD>g>Jw>``oACl>$!YM^!BYkkdy~GeSW^;mOzPxjL_xi-j-TSqF`lT z|Ao0|z2;0gdv#xZ5HcGJngOwO1>4hLPhE1lK||O?PUZe4Dq+YVr_PpA61xS9PZ^sH zCIo(G-a_||baCIc6%U%SN7O9XGb8e%);1dVuYnLzbTkG^nUv5oXD-yz7cfCjo0-?ax z=MUsok<0gqCfVYkFr}r$3K;AjzVb4MD+lAf2d`N`ijKf7I9Sm<8ViUJA)v zmA230E$lOLpl4X!vW zn7kwZy2$OPSE=(eM8Z=NS(h*p|BSb*s&~J>{<>{&A`C`K>#|wHn!dEhDeM(+vBnTl zH<#YV+7lYX0PsQ#i`eJ6mV4`7-Ta=!MU{r7q2_jpoY455@d(YmA?d)y^Zd?kUE>NI z)gu$Pm?i!1gXC)ru8i=V|DgKS!0{HOIo>ia0KUv24t8A{SeQ28oZ@6t_z!AhDeG3MmyfEFs%Dq}~5$ zf6DW78#*caaJ)DPoZoa|VN}O@i}i{itV5%LX~3Z*viWBZNd<}NYZ71X6Rm&6@1Nti zBdb@&|2*CnED5$r2HG3K7;*Bm_hg(t@2&-&h_9yxb|V9O($>++iL_Sg6AAtRQTtT3 zb1c*~(4avzGW@vIm{nMJPV{cT+37iRAhLkfb1}=*In16T_})%BZPKBiwL zo+e(Le6sLxZ+=F)tv=zpu8fs@iRLM|>OZ%)%otg$rjYtme?%%sFeH^W$Dair$G9 zrm2)1WwvAlgUZJ;dWN(%Pp5?;6Zd)h_4j#Z@eDM@b(cgYkN?6b@!v1Ce!e$ zdjiSBH3h^EVJAG#lWpov=b5WLr&O<}B3&dGmAL9r9ipA#7aWpPqZ!ba zbtA{5WVkV%8idIB`{3_9aoj7vtdoUi%e@c%_*&htNxY0Tmbse}O4PHG${z1o0ek$R;z`3RNF zV)~zFZd9a&zUt{yf-3mglTrU>w0=)+8Lg$uWy_DyN&?~@{XTDY{Qb=fR;5iH7^9NJ zJw!D1y}?6P9}lYU&X;W#+1sg|JWao1X#cSQs64=WRAWVZp#%*JHr7Uc|Ok z_ELSCQ$_U}JQ&CCJ=>jnjxi>9k%D)3w6U*h)dLY~FUGKZ3c{?LY%70&0ew;uxYDNY>YYw7gSLN<00YM!k_er_@QYBBCJw z`8B+`<0wzk>vi2#WUbX`F$#AYsX3TDN=2(%OB+7|)g0y1jH3c2yATE3*+6bxTz=#V z>iCZowbqan1_I>Kr8-NWj;n70cUymyM`Z|Sc-&o?{z{krEt_jv=4f!f|1N?(@3@BcINxQ-L?KpA#j74nGfnOdlH z-`7X9lRIKNOIWCOSD;o*02gy! zv3%w{p(M6lpI3YaxMF!szYoc07{^VDbCyWyd0nd!wVi*4ppGPQgqhUE+hr8OQL1h_ zvIRhv`^h1|^$h#WZSsnmTrim-S_=Ln-Vi*4z^bV|x}m6^J*W(!Ju+sZd~q1S52-_B z*CnKL-4syaGQ7IY)17d@d)Sl@-iOFrWa~3b<|{c&L2fTKAO&4I0v-aa@Zzu+w+!$f z>G~i+vk6U&c|vn0Lc3()WlM;{*^%~K-q%gV!#Sy0{={S3RG);D$VXkO`7?e$e z8io3IQX-BB;pc@ z{Gbf2J-sRf9qbL%NaC2>N7sy=UCMdds7`crJ-~`f_FL^9*Y4E6{SqR-Q{vca&e^Tv zLT29;-Ktu-Md)pmm%@6Cc9T&nNPC1z(ww%8r4vn|z4<~N*hW04dPc9M4OZupI(P-? z*<=%5=gVF^Cv|VCCFy^qABuoey%bLEEEt4(f0)((ltQ5+5qgs$`U%XIl-KYpd&TTE zik`hK@QAB>(>sC`z)Xtgl4s3z`a77lu3#bN7PzMU(jn;e97U>+%=pCgHkSoHaJ=^B z)g1MyzF+lQXm@_?uEb!{Bp_%b7e`+EEV8011UxUYj)sF1b5?NSIXMYD!?K7kBgWwZ zxDlWAku#j+yGNpG^ob{R^W2g4G)3n$!+%RYoe9~6Y8BWXGf$~SA=Wo)TGHf_KWBh; z`O}p4%)jq;*_oE}F1E?tr@-QH!P_ugB8TBiS8_hxC|go<5nto5_{jh7QPLoYSG(nQ z9lIyyOaC~PM05mT=$%wb>p)W+xQ$Lz_XH&|U*VEDVk`Q6)E+6^Kdyh}b@*q0UF@b6ac@*1c59I;rteSpzaEDZO+ud%?3)ovIVJEy`Lc=R8R z>s*dL8I_cdJi6T>(AY{bQ*($5%F3KCfA&83R9}C9HhCI8`5qwK-{>h@ma9cL8_X%? z@udvT_b^Gz>ZoG{L2ci82P;(t>8qOJORzkdQTTgb^+mFm73LNTpD^R-{=*}zOs27V zNtyO8up7ANQNSfHNv&4)K7ex0NH_am#~>>RSqt!6tj!yLdGLIIHO4B%8?ndtfuPLq z8pS%+G%K~(^#frOPmS#DlRxIcC)rU)pBoTav_U7ZvWL^`h^8IB1*QF%^+}xJD*2r% z46M}eytA7nc2Ia_C+yx4g_S~xr&=AV^VL*YS*&`5GuFMi1}G0U0c#-agE$C zgq-mqxYIMCPEn;spSr7CciszweA13qeboJ@zW6th&~@4qXC{7BD>2-IT2=4nsL#13 zQmHAtmdvoD$@m1PsM`AzB_vL{B!1SY_;%;_*2ew@p!(?D%^yb$E-usxCN*g=gxXK) zq1_6r{kQ!&#jjKk+_poRmQLC%68STm(t42nSZzvmqB=C(al|e{7~B2-IQ2uI>wZ=h ziD5VCRrCCmbPjN!Yyn%UaJhtZ319e-Il=yl&4nc}E0dEr_IshdVKv;g!Z^5K`?SN6 z*Z_KzY6iV^Dlz=(pj}L%Uq99F7r<<%5URyWU5lqa=C#bB!aHhRJ)6hadgBRW1U7?;HJ!|I=m~ec45`2iBkF z%wP}&JFX;LigZsd7Wh#mY^$Qff`a)gMA|2#^n+hWklW-eH`COeLmoD#CJYr~XE_Xv ztG*Gzp7+aV9GZ0u_qckMeLtYbLRlH5SZ(2Hs-{CJ3T zCJt(Vv+lQT^j9b~$mcsOvyR1n)34w=P8t@ZkspjZqogZ$(9>PvA9i*q6FCX$YfoJHRc9gfsA#7IJgr z2+5UEX}1K$Mkv2=FsC0%=d+m&0~T?BP^4U$M+NTdAhRle9uvd*x>G zOHde~83a%7_;Ym?;4-*di94*1n$9==MMHX}Z;$IDt`j#$SRiQy?YTDu+D~QgLxllX zbNKD(EDO(U;IB2JHUGet>A_=$47ljCkTd%omWN4I8=g$P3dlp3`m7X{HL=n+D6izImo-Cvdk%Y}BH|&}5?|h1UHYCf zDS^Z+s7v$=ISpL9+3j4r`Mq(o$2Q|@v*>&+nHh&C5vB>#Nybhm^;qP%|KAf&_5@pZ z-e>FbDOX{Ln&IkIL`KhbiQ+<*#sbKyL3gZz_Cc{b9mOID-y|WaY$7QPsMea&YjJ8* zH0-A}A*KH?i&sDXR2n>HHI+I3^7fuBMq=6hJFV-tXIxz6E+eCU8LiRezot2*6}j>H z(@4yPtli}mKNrz0r|MtLy)p5=QLA6FDVpH>p12(!vqZ*TK&uo z6U2P7g2Ux3WoY3ft-5J&kQlA5wVYZR<4nlKiP+#%#D2`t)iZF>OBLU!>}Ri=r$R6A zD`b%$;8kS>KQ#{}$&#~Nu~k4({W#AlV?|t+o3-Q*N~O)6-p0|Ug1>+?y8+(Eo-Dhl zNwMsLsCEZH@bpcSj(VK9Gk+1=6jl(CUhuoXn~x*wfkp+^9Br;C)@;8aszG$Nc?sig z`Fpd>8t2+E>4aHzokmcZJ4>L8D}`BYPe39)^afqUJvB9I2ul-o z$!@}dpFwzi0^Re3s_9OMq#*xk}D? z(mQodhup*@%@-a@MD^Ru@Q+ur>4GvCF@ev5ApuS*@@x^vmF&C;nr5Wg|EgC{#qTuJ zP~y0Db7lNr=8_e$E(Rlffc7zZx}4KW8s3P6tgji^1KEY_ss8cclc8LIq)jt?!jhrM zlkCe?sxVTTu^<{hse`wzBn@?j1DHoNUTwa<060O{bYigXo8jYFVt>_GN< zMn*W5hMS@ar_6>9rW;Am%f$tw4k=;R&Dh`@{0cQ?EuS(}QkH>Qr8d3=h?0`>7?nSh zv=E>AI<8SLMOOa(*+$Oz@Zw)*(w?@mIf?x0@yj0eNOe!BaEjr5$efnJStCd7zIQ%y zdZ+4AxV1(7S#qzckC-=AC0U|^u0=&EYk8XQgWrg>ZP8Uo!g#6z ztK;w!&Vnu$-IgT7h*&jS??~HZI=0BY!p>gk^m;>?){1f-%UQh*pyr?vFk(Y&XX^w$ z5mdktkPjgC-BeWK-yyO}L%fav>!?p&^XN@HFUq{B2R7OJO%UBTdy5uBWJh z+WKDs-i1b{?Ue}aly5;M8?B@99eBF8`%4BDjOV^QSw+-KlBWzNuATf%vMIYNiE4{q z5k~D!(6<7C-WqSj+wQcp5T~Ejz0pY6ZUZ@M=MGt#wEse@x=Ol;gNc=BGd82L;8&L4 zG50fMUN;kj09oIL48A-jZ_nK!z5SitMh6~s<(bFtO@fW@!B|5OsYY)K%R6v0hs{HcF<2|J^rnp56g@bq$T3MA5YrIR*yF z3aq}+!4+2RQ4Ay(0whsIA^E%T0h5xTZ|mD)8lDUmpe0NoqS%UnSpB-=m6V!gap(_^H5AZ&Ua zJ=vQP;P@@(TyBpjHu$c?f3l>~JUIsY|(+?#>d{ z?&c#c`j9?OZkgTr3+dXbtDOJpx6b<2`c#Gv?yNleC`KHBJ{ba>?P9xo=XH0np8oC{ zSfGPSHstirXC3HsP^#S-PzpCmG`$$yn3{4`-ocK}CpOwqwc7-f9}xQfSs2e__m-VV z{hbmTd#d}S65u?x_ToU(Ey&T82J#NBD{0@YNX9cSQrL=N3?(%29GqsZeL)N%yd+p* zYdvp$PFO+8>(IpM6rhR>V9tPeu(%C@9Dqr%Uj`3C2EqX9xnr5q2L#MaBxz>RYFd3 z4QKi*hwiWkZ!Lpi7btJ5&oO4mYSAozUm)p{!nb`2VCqd$0tggs zW$i=F*nIKdol||D7uZ@e!I77`j&vc00xdK-Ixv%-NOkTp3yYe;iE1GQy>PCqsRb7- zHI)fsVcE$Ubw86)nP<{^b!PW3XdBguxts}`*rp+)BL4xu2XPn_fy!366`Hg$H0GDI z{wOo^&n&1SdoCGiHrsvi8q-Yf&eeTo$5PbNMdygmVJylOlyPpfW+)POECKM^B-}im zwMn-qORt@QK$4B@#PTZ_imA+iLGwKgZ5UcQWG4nXFcQz-&7ndc-1vYTAh+THJ>IRG zd9C5{cQOpocqTj`tsYTEZTIJ6&XE{1hkB14_1l&82ezUR6eQnsQrzQaBic2?174M# zXy($URNIXLqEE5ugZ`U#{dU6Hzx{s++>iHrvL5|}D#P@TH$y($LomBBTh!%2+P81q z79BpBC#xNzKY9q$vFZHeTzb$x;@68dJIJ2L;P?|k`$?L%%NY&fhW*Zq$@GzQcJ>nx z>Y!rm?zD$rI^Z$|W6Gg|LY}(5^?tqusVGbX-EYyu)XK_=aK7}NXp^yTtQ)z z7}N!X{LL%R=P%!+95=6MrGL=dsH*FpX~u8k$O;Rdy1LPvDwMX{|6PI-RCOmvXDDq3 zPuyslnB=mRzNHdUEwcaAz}QP6<2cWwnK#({<+|Pt!^E;wSUiG% zEjKytq-)De`((aORaJymRoVS%b?4l}x)!dVqZItS4+F@ANctQZV}5`5vGef+g|V>M z#sri928R?zUlE_GVX-s{`3+lNs7Q^{Vb6U(D~#ZcZr*3_tz`xD*hXexZoG(>m+4=} zo|2d~DND+RA$+6${LL^@U9G;w5UnPX%S5kGtUB=b)=kr`dg7vvTl1po)X+(r9Rq-< zO>>0rpTSuNyaSd+h$1mR(0)8MuVpR!U+vb`l$8ZDX=Vyoe{c*$c!#w11=eqdEZJ>*59AqsE#~*nQ4~i zRLnoD@aK}$97O@2-!JN-x#KQ`$c!l6-IzqcmSIQoJ^wIGTy8i@ZIBu>XTmPh`24t* z_G9WKF~2^5he=p7*=4ze)`kY<5_KaeI8ZlvWmo5zJRGJ3c(|_uh`OfU%%Rb3?kh3K z-fkjC2{$DZ5wRdrZ*NC(f=4dVrHftwuH+O2AzjS5@- zAM+m6*y)^KYFD9+->=8a;5(QCpvNl`9&}Z({kwvyyZW01uNKw0U1j^QItN8$3pMwK zuS~`$sU!Gkr)5qIt_EW}$PgdCNi6Je#+8$Wr!1&@}pfJ2+A)X z1leu9@DDI|z91+;0ar`QiFoTU^mt2p=Q_=Hvqre4NymfzAc-55%&TGxh(vzVdP?|b7?N?;DqsS5qy)EC*;!g)0fz3i=+ zGj3KTe)=rMH4V9xHcD1l-?hzoXLWaZ2tcoD15o|A0Ix|kP1SH}x2J@43*_rM*8~|K zgp*zf`+u?!ca*s|2k!E~4~hh^E4?FO@z-(_cY3TaugrcRQ(DWAA5I2I`MvWs--<>q z0@R&ZRem%=K44|ez_{?|bqU1qDmMj2YNZ?P!)djXkqkbX!xw7cgF!!d=u?WY^eQ2z zznB}Sr3)kLOgT0-m^{q+aLGd-a}hov4d` zZWWP964aQk3N0(X^kvG!5yq7!bBwR!Lm#l$WjWFF2MpHuJgSG%EN9mLQy9(HU$6Ea z(8%?5p3sTD(weUcS2tV9W0+vZ<6E>tMZx!xL^G#UiStbVl3}wyHWdnkGY4+Ni+~OAxw#_XVWouGXJM_J_ULZ+@ab})8I?RlmruE;uUNA&b@zY z`0i}}&JmjRgP)S02!I#-@Wj*phE~Nq-b;zb&jT0fq(eIqr=~klo zy5Cx3lk5dLpHE#d1Y-*Tg$m4r6CADR<+Z|XvG78V`jUdeEQ?#-R z$&Dx$ON+b~L82z!NIk&AJT_5PO)4Jtarx_#$z*7Ifw+d@`dvoE%j-0kM`sDX&tel= zQODNgV!zyVuwP$z1p>q5iVL1m!xzm&K@B{Qd(4=*EzQVkAo=m{#7u+XWp+!zIxjKk zeKS_zcgwPLLoOXaby*EYgrJ`;fw=->etfREnOl|-vaW}1h)pvK`4!tHQ!*J8X=lS) zWZ+y<8@dW!EP)3X967c6YA zgJPk#quB+V!t0M54{6UdpM*Zi5Vys}xkRjaNV>0hB-f^Op(!9Y+td(0B<{$oKfEtg zFx~|WRi_|zU`RfDN$miThoWlmDY+U8Rc4;AObV30$LM&`1lWE1-T>aoH=izXxz3Q}Tm?3csAH&ekIUHe?Uo$v@y zw+hfUl)bEO?#Q=jiO;4c>T40qa9-mdV5i~0?3GM^7GzH}^ZVl_9b(vd1!*q9!yeM( zuW8?UFTI9}KhK*FhHgw$jZi)NraDa&5D0}=o;hBHYdade9c*9B^Dw#F{{awoj*5^V zQ}w%avrFHIYCdMV4b;xaqx39C1qz>_4?{SO8%*WVfd`Du_qPjRmotIb_xf@D25-Zj z&ryikew2Fg4T0T&q8eGpWdcO$cioogcV09o8fB@Uy^~bm{R($H+MS^=0NvKWC(Wt{ z3+iw55}rS``_@}aJ4Yd)jo9N&`JJ;tL?tA5wZc0mIFSk?U(>TOYTiEX`q5l2j4#dX zjhhAOUeZN+Pi2T43WkVWd`N=*AYEAHyNWkbjehQ%J>HAn3}yqcV-}46kIr_-Q0hOl z$(`$Bk=a6aqq1)N5Om0Q{kgfShAlf`mA5HJU2GzCA-1&#-9Dx(o&Xts=kDvXmhxXu zw^&^_uiZ;OGBBjJ;o4;)tWtLzg`VLd2c%R6AQf=D4#0CiY3Ln%2V<<30#5pA!KM=} zsXJA66RXL<7Yrklx`&BFUOoQ+^QKmEEN6S7SopT{6$Ueo>#x;6=|QElEYS3XcF)^@ z5PZeuUp#+{wUi)5|1N9&hjHwR_zj%=tGt-C@^aYU4a+H?t*C>Ul^ z-v(xAx@mQ&(U1IGLSjma!=BLO$<>Q*J!0eTu&oR%Fbxo=`|%-AGl3zmSr{QIhSsh6 z`RP<^0A6P$+hy{hU)mNogP%tvi2f`1z2s5bUSYGm=~JeFgYa?fuN-T-Wy%NQBzrWI zlqm9~pO`#*?J8PKOXQ+io4)!FrrN`-L}?=jXSNdL1n(oo{Jr3xIlx1ByABF&8*9on z&j`x%v$HGI_?{S0%EUJ_&^JaZnaK%BkAfc2r=Y8zhNVxxq8ub6hev39R-9W7+@odQ z{chTDd~$H|TLA-8HS(9uT)Uc@EmR>1CLB2%ei0uJGO3c=93Iig1(pwAf6#8SLC$3E z|0&eCw0a!?j*GQbU=8*4U*5zFj|YO&u*y`D=M@F#J?TOB4N{myBU8?;SoXq{jbG6% zh~;sc@m!kmily2_eSn#KkaBGJR(ZB%THr~WN}X&C;?H0&)Szk`6O#?+`ufC9Y$hJo z&G7T{TBpB6eUxt&rWN~8=W6g z^=4X;beDcN1yk59iMzBV4!~@Co*;eJ++;Zn8WE0-3WQnS?S69=GRZmBEo_V!v3g43 zD3-xFIB(dmS9JNO73d~*dyc7A-|Ow8{QwSC%_c!Rr8{%O!5 zHI+6^IJt|>kuFFnxHu%*T4S6Ll>KakO4`^1xj53{s*EUic`zN}s`}C-NGKeN%5@xo zRJ%-{KJRK*+jxh)pCKydmSv8jcLy>PnZT4^Yv=K-o_6w`t^Cb;UcLoU8AU`FreY|@ zk$XLU(h3>2?&@MJ3DPef8qvY*2aV#1qxxl|LXJ)S@IbS&uDAx~@_#YGwzoZW8Rw$k z)$6y=0F0}@sV?~MKQs%>x?Df_tSh7Y1~XK?ziPEf4Y<5xVdmD8I1+7e?=o0WMIX&c z&;rsWYHHHkbGcbfb>~!_KLv*p*I3SF^0Tu{pR13=G?DucvX>NEur5{^kFGzOt6SZv zE(jku=rn%SPnY#)A6fhKEo0#y`L4#A3~>`cs{po2+9Jc%FcSz4F@ccKw#9q3odGoe z`|a~zadJk!dnZo^f(-JlLow@d%hDZDO0;iEz~1p@pY??b9Yc3*!Tgfex+NfJln`2A z=!lKllwAiSx-E%a<%8QRCF+d4%a+R~l{{hxg&Z7~Nb%L{ts2-~-AdXzRxBgfEsdNj zo$Rh(A9&oV9lqjwy>UELc}~mB?Gk7V>@Hx%o$3ZuHQYer(}G55WlhhKd98dCcsdu8 z%N=y7<&S=<723s#&uArM_$gB6kkZU!u70Y>q5U}Z1Mh`_G|=Y887RBT-TuJTU|v;E z5(+ik`pI?W)Rc&%^jXz?O~#XYp1q!V-XfdcH1$FEID@tKgq3JNh5H5eDdPrh`b?M# zQyxvrJ-xPCy>=?>j^|3sWK`L)sY{RC`$x7K@^Dg%z+9d=N_FI5Xbk%QP<56uc|}{d z#)=eor??g`?!}8sp}4!ddvSMnr?|VjyGwC*x0kzn^4;W|9l|dX0@?4HbB^)Mv3QjE z#ZurN;F~{3HgvpJ?0q4iaaUltUYr`-lNc)^4GswiL1T4|F}LL zlGMFw_2tl6ic+-g2Vd=^>&hbebKxbXvJMj2<;OviH13)=_u&*dO|Dv?+02kI@6~!> z*e&d97gc;1eXV_Hp;3J4^(f1-pqS79#nN;{5xX}pdeZ7t=9QP22=^U6jN@KPC2YRm z3bEL&pk9;iZ^}2p5@w9j8tZ+ZFG;H_;RzieDZ0d?R>9mdjT#KX&MHIe1=q~j{Ijz7 z*2A*btb~`qF{5LnkHs>a*631pcxRdffW$Bh%)NyVW!UDfyH>+xoq7AP!jxj(&*UGn+#=um@c$TyE<9;<3Em&} zuvt;HTuIk_+Z!9tF+@76NbFDnJ;H4a-8UDX$vj4{R~tTD(ohr=(DVqMp0VXw=2{=) z!Tq`BYq9iZGtLcDV0GxEjQiSltbM#v)dUrcG|R3m;E|Y>ABXzWtKEA*-6%K{eJP@> zrrbNVR{S6(XibD}p3Pgm!iokYq)cit#^yI@=DK+0+lfZRE!EKDVt#(rBAY5Aa8r7C zzfZk(x*>Ywf?u`xi44ENu0UGL6(t4Z<+Ie>kgj zMA2)Igfq6tmhop64z|WTg*z<#%BZ+(dg{f$=Z4W3m$#a}y!Ytu64e=5@!-f*j|T1t zzVsm}oa!nb!#YzZ_nQ>uF4QO|nNVvJx(^*rvzMtin7lJTb=IirPp~?vcPu>NufY%w zCj+`o#*ZgDwfpW{bp@FZc9d*Z$1eoS;uZIlKXi2s{I#!+0z{)4s+iMRzxM2_BC&rC zo%cR(Sh@pTatDq>nG8;avG>~4`Po}`a@&+@+`#<4%g43BhF><-JtIYQ-OpH?A+<)9 z{HWWoH538@IyPBF5DH<^7nZY?m&UZRf{JtNPD@&mItR6N8uL@s;iUqjb3309!WpBJ zktG;8)@=he#}6(AyJZdV@i;x~xOWAOJF89II<|c|4AF*vl_;i2=ni6s7?iZN1EqR3 z6$GfSDm?FTWNV0AfiF})@nne!7)H8!xT5o7Nt&6oV<197=Cg=Gz`R+MUhfXQmD~Rt zGW*6BF(ZaEpj`qS3+o&_!;AAB%p4w=!VAwDmb72CvVA};DumxNKP@oLu3dL{O!k#Z z==iNel^ZZQgyO|rdIHr-F@WwKmf&zsonz#DMVtuGH@$gvh#gVuXrJ|)IiG_L;mNN0Y@ z3ulT7hNhn?pdx{y^Kq8Xb6zQc(Bvm2^w7 zAwEVqVsgFuD|QQOK_hIf7dd`Q;5aSxvK2$GP~1bQFeq$=Fq_ygpu=A8>4`dutWc^| zt-QDn^4&wVn&9@7*SR*b%1GeH4g92Nzw#V+KTfB}bq{}j*L_^H^`(}Dg4ewHsjb3+ z1)4iq;`$m!^89Y)`kP?811Ix26};0qIafT@4^w%8DGyXNP5V_48qspGLRgUTOpJQL zUi&+_$y$ZFr~2aW^Fk%rDCN%EToqD5v%%7`xT}!CSEQ1*J;KgxSt&)(OWUe~2rZl< zvVt)|V-L7jT9TQ(&#~(!cwC3mE(x9xTbpN}g}6atASfv)Aj83tnkrDKH+6$+Cw;IX}fcpIgoiFxDN8 zuoOMd3^Tn+=c|$p_v)v#u_tHFv|Qq%ezGYx+15C_o7qDgTV#{~F3DFyqzzSaDzBHM zapu0lTgMAsNzCFujc@ynuCP4&8accGW5?gYm zPfqGQV&&zTjVt1n+Jj2;r>o|PU63Q0sQ5+cU^uB3V`=xYg5!zZj?!g5Aa@Tw>MH9@ zt(rIY{}?kohqp1y6W)1zU%+wcaPjNy=c6itj z{)4LA{@mGrazTIKHC8C!Rc6_N9Y<=EnXf*Y*6u^k;d85v7Mi z2h>5~QT`tcFPXoU@fRl41VLL+HIO{?oDaY!D)5nb`p8G-!L6?kMrua#UVVca6Aoim z29$;FIGQ?6{~{^YueQX#Y;mYxf%0i2&;8|VXeGlO(g*QLq@+c~S*&p3({J+;f^{7_ zpN3De!1b}_t}1NE`FHKQVmZTbgNn?g^#TL}n1m3Q>tp4QXXg-U+G4yzcd*xz2*cutA{s8O1ZY zYO%74!+hF!^yQrBI*q&&m=G>RYNhJ^n~*0ZU)#|)of=b-x0dt6wn9d%68^H#mNMSX zIK(C$u`OV0sC_R&o32xKfM$v4IryBc2V{<cet#kalY$PTBz0W(cQzWt=xACK zy-KcY*0I{}Dj}EOtK+ocn9Q3Mc4x^YkS`nwW_K)Z=!$;`SF{MldD2n!Yf_Z7w9e<} z=j%_}S69`&w7tB%R<|ZHxaLMCC!K%%_>lpG`nQQLMTwAF(JFnz`*}I>^MtU`y5r=x zN3jPx{~><`eKz=^-MgcchML-nEZ3>#{Muy7-{AZbRF#@y@p&OaMJx3s8aTTMOih~ z0eE+7%HC&b57t&~DYw+m=`yV_nxbtUvE!%inH9ytb>(gxhT$^nte1* zUXx)@?4$V}rtc3PUo-QgxJPN|=%k)s=VW;%;GhFu9;vci_2ZeJmkpv9w%!4a-8A`T z!~L}4#ogn)A=!#CJex3{N^bFC$lYqS-b|)br_H&d?w@bD6+y(OUUj+Nd{#Sl*FOH} z^E{@LmLcHrU}^Gnwf*wi69B^_0D3aWzuW?9au%G|_ur^hPd{#HbA2oG2*X8!S zpKO({_NyN3&ScKUdEHKYs$sga?IP`IA_2%rt6b^WBvT6r`cBe8Bol}%@HTxsTNvI6 zDpAPKNTgF;4O)Ty)nJ~;YQ4_6fdt&%u(aE{^lPI+gX2Bj4-%&F#4Ew2D&4wuWMp{Q zR+j&HPbC?-jcMP2|LN^^D*f%C>*Kwu@#mt+VTOZjyi0#Z27wnSM<^g|TnW1C{oLl> zCZ$f>^Lha561iZ_!1Usse}k*St7-+OTjie@aJb>Jwei(Tpw_XaZqFr|v(ANo{n>7e zFT;kl(cbvn{cPh`rM}COuD5g(IL^mJZF`e7>($9Fo$7*TEu_ zm0ppT8akZ-pBbg4Qc=C^FXMRgkZ8M$oHn%q**_&<}@HPd3FuM z!#Z?+__b?~wpjZ<*YV+R{ce`2!vji18A#2t>KlD)DLVJjdRs3>yTwqVR z_@HlUt&2!GJ4A(T-a~2#YazI#O=as(9xZ=R%LD$}yIYC@HsjpmjKed&QvEwU@5|TX zi&xxp55|pRb9Jk_8Wtmu3{};wR*!{x>+DwJljO;_J~;&czhKkSp2dP&E8|zt{uH!aeUZiC~}S3sCzav zwE5R!tET6%(<^|{I~{uKtr=S9{Rn#Ny#!hZbOpTynugZ-h=Jbvz(UmY1xH->^+we6 z<40Wg(?-1v z{Z3cfK2UGw!Wnr(U_=t;23Iofof8JJ4x7f#-HJLUr#} zKu3y35aYbPpRAJvysIaslnMADF)!P}U+y|WP^iMp&z5VlN^uY*&IOgRZw7{C) zu4j+y+uz?;pMm7kCvOBGCKp2H5IiLNZ1@3SuYeED(FIlGnYD z^Yl|=?=8+6`46$=ROWFd(({hgtg#CKvr!nen*UaMHHdF>#GcD<%1YW$Dm>c${vdNp zoX^yKo6G4NhZ4IW0;><{X*}yIk1aB)@Ub3X%1z2!Dxi#1Env{3E!gp!ooy-xVHIV8 zxN?dWokUj4Ab;Mewij-REDyuu+i_4e_G&74s;S_pa0_*|Dk1v2c!y#Z1Cf0cFPT-i zRw_tzgA_jcq>rKPEblc|^*349^G-Npfyq=Bw-e;!F0NZ8>m;YJIJ=_k>I(H*0i^Q- z;LaUm(5!RdM!<>KDh@5vJV;?2$nu;QoH8e}U_2I;&!f^f#1$SMXM0AUz@A6)q4G(8 z6cJn`h+Ct;{qT^tHXOsn4*6QtK`EV*W3-^;=l#3mwvC#_Z&lyF2y zOW&Gw7wP%4_F3fA$4EfG{kewhAS^Y9Vds^P23*R381}-q%Wc4W$(i8S;J^~a|6*Ek zFreArdQtYLa`raJt*N;EE&WckbdxI8Kpwr%Sb>qn+$h2C@yn*1oA}BJ#W0p;PHY*i%7#Z#nBDAB0XA^Sdc`y2o$M%4a zkg`eS4XuluZduLgr6ti(*Wp<9C!S(yozm$xSwf_P!>G}PucSfe!avzL|pcUE%@ z{Ccg0G>-h!RwtYCS~0qE%NUQD?A7UF`P<=Tu*a}UExMXSi-u8!@;t>+9XF*DY=*fL zj?Obg4v^8e_P#@+_GnJ0``R4=WXTDCQ8cX%u|-uz#zylk3n7m*$$S^ZqU^ckws!lC(mAx<2*kvy}#Z|sg{7W=v#J!q-^_>(*JT= zYrRLFldP%qR)I(Tw0&NnYxV@jZn!{b(nR$zo6cuSyG<>Zjl?HUplVM}=L+8+qEkxS zdINJcm3OkID-A1(mLs5(a6dmkXC0!nxBwPCxwp@j*JEKj|IokcO6?8+Jl1yZ4`-=2 zk0LOYziN6}(ar(wUD|CEQ&n^Otm^~xVnZ6d;d+!Ce0M0~ms=M5W+_6GYC?rqVX;(6 zbLntBfPGrqd<}ZNr0NuSJ*&&ibY2~~UH?aliL<8-AM6FdHt$(9L1la1gx38-qrS3+ zky6{cicV>{9~W}JOrG+R?p^@Dhf=|O*-}Wz4}|!cM8w`b(`VtQDi^@8nUP_lJ=RRH zuN_&qp;zWle!Ope9B;{_eJh=DDJ(3UOjOlA-a9xb@;tDpY$*!W4`>0j+xmfrHJeK} zhHMW}G=2b9dwCTk&dJyA5cImn&qJGduWGw!?Qf{@VH{8An8IbZOaV=(Xjl~rkev`> zhK(_H@m}++#!^dpFJ<_{zpwGi*=tQRh%CDE3821edJM;qsK1lCWe|tOZAId;7R8>x z6R+BY(>F@2Fi?+tRjVzKR4bOtzW4_}&`go-JcTo+vD`0}tL?74?ncrK(dF?!ZxRYc zsDC~I^W184u_5d^2^{+3!)uob&(NGRcIt_n4xa9&77CF%C6 z54q_GKy1$Zou7fu5YNj5LsM4Z{mz-@i^JC?gLUm@+uXu?jkj{wlhWdhaE8`l2Wd9J z5me`E)bhhzW^|5(Z3-LU_V~|gB%1*yfxZg?ZR~DB=qSAR-+m! z0s}=`b!*%!R=;QK@umLY3f#(_?qBu!SBoz-H^Bo=F*N@bhWav7lMK5cZMyv4X3G_p zHBNl+l9ya>x7!JhVr34Y!v1nmH!9OeS~v@{O~x9S&7O@{*b=oOrQ$y5e;(H9D;6du zmr}8;%yZj6bn(TdMD^xE{|eB)PNu@c!!rR8h0lsBn(F}PUE?g)C*7p$<>b%(p_`lA zBt^33PD_$;rr7iPrTxed-{bn+UgzDPt@jHTnkigneUWfXBX4WVi_Z+_k*&w9nc0n8 z-Kos>jEBV)k4va0X3=)9+^j)o7hk)c@HE`8y4*#u80;3;-LsVhraCVhKkZMo?iCYu>br8LJb0j^DDL5PN=^mFseHc{rFlU+dM_~Il9D) zbUO6xkobGZky@Tks4nSh_N^?}K1Sy4s)!6~q{z1|U}`G);4_^juF&+ghba53iN1h3 zxtsNmXX#{*RV_)%!4e|JioFyG%mwo^4=~0ALh?rGs)jGUA9>zwvfRc~n7LfUZ+5s#m}2?}P^`vpl^8`z zP>sYySj)bYu;kEobBT1L(l;88ptS&}O@sXp3;P^&Oy_w8@nh<5Ox|y<70SYdXj~%= zU)+yKHk?JY@B?wqBDvXGrXp8A(PGSVl#z-2%BSx6m=gGS>*rH|>S2(l6(WR10UDIn zsr{FE4j%`rlXXv#9wwaNS80jZUURp>6} zFjSFRH0Ci@^uQ22DHeI_T>8*PzMEmPdy{2|A6yrn*UJVupCWWe^)bF4by?qk<`+0f zF}S;hctP9$R1!DsU7YEh25L$UgEyBd%5F)NYi0-oi$Hw~;x|@SEskZp5_q%aTfF95qI_Y+E#fU{$MInHLVC>sH52`y`GnXa`5blF0(v<$y51S! z_FpMMm)B-h$$!&-A@mCM7V@H?8_7uuP=r9u3xKH_(~`lU_6olquCKuz!nG)|u}o!7 z8~!=@(csIRIPB;Pk(lfriw%sJhF%52jYioTZxFVB{a{YWFmV_awjs(y=Bgz%{OJt<@7lcO*p^H-cQT_~w3Kz^orG!vT@}+EueJ=D>j=llaL%X*VJCI@7->XX4MAu?y20N6lOLe+=b3^`U5l)yRXsFG zHLQzR)n7}Bd_KQz?@MF$)6K1Sqy63&7t=N^I+dUFvR0Y>^LX^~2~?dIndI|r!Fyj? ztDbJ`EBrow#5#17!y%mo^JstXgI@VuQ@t#r3&((E&6cGi`Buao-8E5!9HmW=4v0b? z{-(V}@O!@a*3CjT(=qCUoMI$Ye+8jArAZi5Zo!~Jfk8^k28s`8Bv#$H0ombPa3D3D zECrFRazZQ`e;qrRIbE1jsPSPYezx{H7 zAu^1u19TW^)7vf0PF#^Klu(fDwd-+!k|FbK%e@=I!7>OY&MIpi!Y~gn>(o@vk8kNa zH3{GzVo-#JFR?$3>#&1g0BnKU1%SeLJoa9u_#QQ7PP(r*6#e1Po#tdX%D^}&inPeSb!D(Xg$3i8ioHUD{{n;^wV$Jj60Ov<|gn-4}wR|QD8|LqNzei z<>}nU=TFsyL$=#Ns?0E}Z=~ul4@#W0mk7n*XH)gtP!&B`G7O~`mXhLE_I=|X{MR3_Uo8oeIX8EiR) z{n%XEtyF-07*`6QO4It?V$5A-vx4u$VqPNN?SarN91X4|zR704TVHPr?^7Zh{+FZt zejNV^ropyQf(V;C#FxLo7E{U4@O@431RN&|LeHneFjd-`Mt^31t~lp!$M@1}EJN2m zXMtS(z4{JNyZom#gPdonYz1qvh<;OdjKa=$5Vw`8W$^JTy&2h2)n=0>L^nUkO!V|> zknW@wJBd?$GY|-#?-UN0eDL@3N$>=-T;loF>X@vrCcAks%{2abYhvV9;W980edVRN z@oGA)TO%3}t0^vco1$>E5}zbaQO2p{vet)HT(hBL2<8f7$T@q)(XG?jFR$9=1S{<> z;hTlBiEVqvrAi-QTvZL|trU0k$J(iCD}&d2)o->wKuz9A@xb7wjDLw){CK7E?p z!4co|krl^gE_H)DFn3ex^b^>|nRrb_+SI6RTKPdRE4{FA+QR8DFK@BjW&b1zw-J9JOLBHQo-*%33Y-Q zO?>g+p`+%8XNX*lp(w(b2I*FfW_Rx)sAToR&cMfL9vJg2->U6C)j(UhWny^|K%kK>WpCK@C$zjN-CRoCk06ZAv$Y1Pnk6)p zK=E`zPFoucgY;!|cCl>X#DNNoo`YJ2yBq|u4nr?6W{6rGCzzgLuwtm^zu-|)s|!{R zD56gY`cPdKkxHmL__~%7lvdSl;a=Zgh!y9Sk?$kUA@fM%$Aq&v${6P>jvX?hZ;<=B zy&?4`f&a(dPxcvwj2$;(D_k^K1G003p1@XrUg0hdU15CuL4E})mK<4`dOGK$3v@7h zNZBu0U;J_R1Wp86h*~~69yk9C1vpwsa8>J6o(=-rMkU#yr-Isce+a-cu-b#gePJtqb zpq6nt@ig_J_NPU1-TEqPl!yGX`ohhZjRzbLicgStdo$)?!&e@;WsthL*=iYaRF)}> zqzP>Er)!g7Y+~*8rtvVn@8O-u{Co*B@U z3qx$iNE?VYi)}jp55Ko0?88Ma^1qe(@CjX_+Ml{LB!0K7sReo19^PG>u-~5pOf?@5 z#b(nk<-vWcdnltNd$v^qZ2Kx6fCx--Eb5+|&1IH!jRO};bD`$Hz9D*}dhFV0+`Fh0n$4yzKV|lsQ249bGMuImQj>4q&S=MXx zUw1f zrF1)$(1p=?2p&cM?jmi#FH2WJ*nf+A_gn4hInb->C}$8{>+SI0OPtXKe|5!?Cfsva zC=V0M3B1>98|VpG+uLz7!MILPl%Swe_jr6dwVh{NX<{bf~3JuO=Hj_^Mr5aAP_l7N9xD3;cpkSZfI z!`{YrM`Dmh2IQELSFqjFBeaJ(Yrq81I^hJS#_wQ;eAIs{P1zf38AiC-CJnW<_8rb_QtV zGqSZHr5*Z@YItD?W?5TCLFw)hcr|~MzuqIiQL7I3T@KvrpqmES!MV0|JkHs)j6=Y* zeKGu6Kb`m2P0Pl>nNo#_0EZ5V+I26YvH=)=lJ?Z$r#wiKGBA$NF<*9lR&;-OGg;|0 z(vt<0W@2PdaPMj*lt!6Xi>{jzvj0%8m(1=~!{`xN?o%7h(n320(u z1qaavDG7ojwl0{LHo6eD3tHwWW6=E8Vvn^QilpSAY=JOKgxvAoUQ)KWx!|Hx*7hkJ zeQ%4)o}N~y{m&S8%}8FUHQ+b&wDK{H3ZM7?+AO*>BHQ2*8&T1w`4U6SCZ##qS#-Bz zKyaQ?CGe1xw)L#y`ome6C*Y}7)lT~R`Xi>^e><&rG{oLC`(;8kg}uzM=X?f_hUk#2 zT1LJZ@at9xPp-*&@4Xx4CVuN@Y5=VA^{U+UXQ;pLQG#&uZz)5rT{)E`i?`kb4aCJw z!TQDjlOQ%Q=nn)3Svr#2aLT4I3H_l!nHVTSFofJYK_qU<06O1Q)Sbi^3d{(y>YImdFs*wtYw9SKD+1k6Y&ZlZgSrA8qPF|R%L zO>P(--OT9) z<3#C~R2j!S8IlWJQIeD3kRPxN)OEzglSOrsa{WO*_V1}T5E3f9`N{g2_#gFbjl)6w z_^TD*4<7)9ethWo=f`niK&_TR*D@9Ut2Prk(y;M`vSXJcQ!-93dOz#np5d`ad=ygg zXBaC{LuUKCH}*tje#277ekP!Tp~kQtqjNstuo7R!{+Nc3(ZRtdxhzyt(bFV<&w5^q zi04F6LPd-BQ%~ZWDg&~e3Sj!BFkndPYgJ?)wS}tv)aE=Y^wKnZt{H~Y7*kWaxue*a zZfPtu<99G>ZKYm227(|@MQ3-xLMRJLWFCo9kWh#f-pw!gFn=;_Mw|L1sJAd?r?YjD z$P_|YxD3;k&&6%gq=vg*>Sm6&L0jlserYp|oT|It?D4=R_w2M7)9mFshG32B!MmxS zlbv&*y~MfW*u;(Sr_9ODa6c)nkVQ25Pu>3i-)c&`|249bD6xU7P$C!@RJIRjLVh|hu*S7+IV491Q-L;7 zS$u?WgC$e8e52E7)n+4N{EAzp2|*#7!l;Kc;$LJ6XnKuFl!Zb}8C%RxkYQlFBHXWQ zabH;b;j3W1x+%YTH8%9qU5Nkq8uI1NL|J6{?>^T`0jTTaRX~Q)Z6}na;tL^LJ=RPN*%6w2X}6UO6JCS9b*ace=HJ}? zsi#0(7!3{;u8kcOIZxVgd=WuHc7po)6kS-tLmz6UblfvVz;zm=bSjJJzuAq_Y}qt^ z&zU3;6N>VnQF&KbBcTy+(TtcL2m#H>Jwx~F+mHY#_vfo3xPE~`f&Td5^&y*_AOmZZ z!wcDM18y*)P&D(T)b^+^OX{ssDYM$IU;RDYXmJdajuMkyuN#+&5BLW>FU4vcO;{zA zd6dazmn=d57U$Hp0vaeSu%v8Pnu#$FfvLV^jgW^VhJq_3hyK!Xq7a{Dl&W0IZ7Jw% zN`0*Su||~tQT>CpOV`4f&tjH>D!_@!5OtHyb&4GduWqvKpO*Zg;3Vx7>Abb4bW2dm zw8BcVPj@MH_Xz@@nySoxu~!CXHW{z=ztG&{gz z#~dx*2!2v2d#ik6w^?{RoJ zSQN#*3|f=O3fbl&+hs|5d}1~P)@Dw%d}3Ur)6uj}Wn~Jf2=959b0quX%^lVXHtpz= z>Y<0198g-|Lhw2OW%#~`0Sfyp?19Z`9Gb%r3RX(H8!qfK+@!*=N(B6%ov<1S5xD@J zZhrc(j4wLX3a+s7H6X*}53y%dSiULo3*!ATOr$kHUdQKpFqC|FfHQ{Ti1Jk?v=f^wH-l7|PGozjJd!C4B zD2XNnpdq;LsrcoR5&rPIbLGD2v3_i#s-T9LUd`o5+(eDdz!GI+$xBDf2TZt&-;kD{~GGEGl z72w1M6|ZbawfK1OzElvjXA|#^?(zHXQq*=k6S|gHche3ArTXGf%ioD-N%ZHilpeCE zWP*07G0H0}&i4$w7=V&EOd= zQl~&<7r@O0fIamr0}~uuu_i zw8eZF_SNX@VI%^%l<^3wGo0uxO`#FeL@>nLzDZ&eb#O8T7r;(#xfLZYr@{y5v5V?# zrC^){5wlc3qN8Re6JZedf?$pT&c&N?Ll}d$-r){hTvp&+1J)gbsWONqcH3uQ#6v34&=uqH8t?IqwuXocBgN!;U$hczQ73CC& znvo)j*8NSD?WwqieCzv~8S%&mn+k=LBOOmm!SKlO`~BYQA_>Bt?R4@V1UHfeYbA&$ z7~eX7$_I3t|MloQ_yR3l0aUub<=NljErwWM$lhyBZQ z+3wJhMW_$2iym>)G8RpCR6E8nH+Am-c@GCmDvrQ_%2B6 z3it)zp1X(N>r!Q2@Yr8%iS4`;M{uf1MuK(#{J;2PqrpN|j%6gsS5gitv^!kcU^Udf z&Mle`7bVhrgd*9rSi`}0T+l03#{2QP00E*TG-YDh(U%+wF49q8g2uf%SMsA5bUcSb zBJr%dTElmOTnw>?oVOV-lo>|}H+^uJ?c@DjbZ~hbSoZrfW;B?a1jd#o#n_>|MpK#; zC#ketNP?s%hr%K4_5duu|3=JqT2yQ0-!OnY|80-9OY#E}x&Y<-Mrh|tQ`fr;y4pC- z$Onm!rriK$tK4pc9>G1tl3#Q0ukSuWqOirtu~{R;0O7~@8&;9w+5-}n+fwruA0zRi z^|Vr@i3AEiLpY*Fd!__z0XHl3C3iD&0?(G;fOBemP(Wm4k3Gn-KV@fAlWH`PS|@|# z&8l1T3PAO>qXa;%GL(*wZ8E6i*vq7Q#IQWenCyljKcSb=MaVmcNc_+VNfWVgKg+A$ zX@TT4+K|r>G<j};20 z-$XD6QIG}^4up|_xA+l=P%#gbyUiNn$)G5)BDmrgl!rUD*nG!1RKsU(Y#VZ4oT*Qi z^fBu`jKL(4x{Wdfd(L!0n5&GL*73SupggQC@_tw`x$h#W&*?Vp-b(l+nDATIdQ)kl z75xT*++|Y~a7q)zmV!g9mA@!d_HS-@z-Ne?lcMAFc@$#Xc?tV+#k!$=pAf~?nm3j6 z>l}K8v=a1TxfK5IBO41V9p5sHH2n7soGnlM3Yd^rH)kM8(%+JABC*Pc*G(%qKlU>Y z9P(jzL5O9zoFXe3B0Yg!c5yo*L9l|~;z)>Nu=+Y^M#X55;Mr4cWvg34{h?xiid^R5 z3E^Q$ur#gPhf`7u))EK8x|J$qN&tm{Q<_-+Z%N>9-#RpLE?OwffYZ8d)(PxQVe}iClTXezpN}H2)DYIbi2lGFBTdv^6d{CHRE1!m@{~;0|kpZuJ z@p6mlVV3$k)OjE~YN6kHkP`{%GG{;_5tE%3C=wn2Cw3(~bAWqc#Y#W<&IB*|qi_3m zr7$|p((0ik4EvCbIhG=xtEeZbTx6zxbWEPDe15kd*?2*!8JwvqJ0A(Ud@<(<@vl^6 z;k}Sz@3>daC{ePZ_A^$V z@81a>2e#^44n8cm7f-fu?2CF0quiT9x@6}QY0NS%;|y(sT@T*f8!|b6=k$9M&fW%D z<_VwWXyNuDl?a7Ppr%Mh{hnPs-Lk{VBD<{5HI z@1*{{FX(L7tPg1L&NbnAq+t-G9RYWp9hur7hp818t~L+nl|WIU>@BB`>cfmC>1?;d zmP1@TqhIV#E6b}*6m?#CO)Pq!sO2o!sd~ls;JhX?B9X4}i^{cM880I}4{i+e-;IfQZ6H zxJ<`r#lXgPdCE+*f)Z^Y2&j(2vw|K%!RR08nzAeJW;XF?e8u3#?o_(&m>fnvKp(PE z)wC0ZpCP?XG|=u;wL3G)FrTMWSuU zwc7zK#l59_!3^nP)XDQs*x@#vZhJuTo#O7+0Z6yZmuq>$ks7{%1cJvK(AgNZ{9zl? z7YNEQtjKe=8VIO+6y8p+?KH7!GlW;nz@^2Sd*usRbWgWhDrlGyrtz~9>-gl zR^iIk>L|_YR#H-Dj^~OwyuTno=l}a$fwG3W{UGx_9xtrkyzWmH6yiq;d_0Z|lkvJ3 z85yIqfJB&=SJ3+_m8Y?pnb}=Gy4?IB0ugWXhz&l6bwrkJFWk)C-QA$c&=(*LFiIOZ zc2VWAwK+MLf<_uhc^qxL!j@Di!H4TocXKV~xNeRl+yk{26(kEKd2`mAdJHW3+$ z{_MxIz8?mZANs_h@GzJU?0h)ZCf19UZ*A^T_)VfXr{o#%Mg5flK(!RKE8L zpvGvp&F87#U97FG>&wf_uUkLCV|~kVIjv}FY`$!?TFd)S%-TBu5?Noj4ef?%1H)tF zG0N0wRoABL<<8E|5fJO8q4{xKoGk|6MJd0x59|OOSsdVCH+EXf%F2$|mNd~P#>S*v zwYt3D^ZpH`>Y7bPV@XGV{dM;rW(g;ouCh7rdL{G;7nhs)=Y|_G8dVy8!_xu) zE|4{Fw6!wSFn|EC##%LVtJTTkt|ULo+;bC1H<-S7&>slHobmUE@Y?v7iL=MCm>P;s zbyEEX;8ZrZ{5C+UnfHPBk^P86aSes?~5L4r}`vpi1%pjIF&gKeW=QT^rbLz*>5K2OR;~k3{E- z6&k&#I7tF;+sLhaR^k5=ZLZTgyqp1*iM>7_eG-9G_~95(hcz~eZYKvS`Z zpTE%sq|4oN0d2BXx}I)_-n(T5C@BHBY_9!!&{R}ZH2(D88#L%>td=I=<89EyM?n=5K?^Lpz6x%j;O zJ97@B2)I~U9S$c;h&?r`Cm3jH&0X9Mu7Q4x!qS7w+w?q5yTe^{%k40ey|1^irJ=@H zR#x^d`{T_do?i^*_k-PGrpt*-;o`}n49A9}pcTvz#j6D)r^?@_bc2!i$im;kFk1@| zb{ZbYyBmY9RsW#6!mg>w$*4-5F8*!K1cSxJ!CYRkXd*(d?LcgG#KU&C+dEAW4TG}L z(NUGE!!|Vw2YB8m?X5Sy!H_KgUCW=c<0Nng<#V0&J+;jpOF!{!jYJ&wPYvK)?|3L$ zT(b2AAWD<9o}iY}jk^DemntQ^$<_8jp5m7HcF9{KqkilfyWdTPsQyuG1gWPAK? za4UA)f#cBU{<#Jc;d2}~?l8h1x<@1kUcYmbneNc9)52UUMBAbBTlmRhgYxMo#M>On zW&-AmhwUkaY+8CTD>cnT8OfnF&j)`#Yi{&!HTMo(ZR%?d{jAc&#OTTkqZ?~ckD{wl zckmd)bkQ7`Oq8DBgPN9tXrju+#i9CIZa* zPSM@+|CX6ob|08?9N?;Y-0)V484%fua`2Us)7Gtf7Xqg&-0s+uZ6JqgF|%dpU+t4| zbU+$pg;i~}3#1uS&2tQ6gz;oob)ItwkCls{Q>~o!7_#xcO&6=;pU}fSEc?DlSb1ci z7QtTLzDuiGX>QdyI`tGeRg{d?_lZ}PaCR5&F_5FNa^=gNc`t8n6Gl)W*`LRw#6YvD zg$wCE*A(x&yZ-8$uT7uUunx`vXt-i7{CLRG5O+Tb-MUF58F{nL4ObV}h zho21fPNeT=@z*A?wne;gGX89{p*!O?lf7UCadf`mP4(rh86|{Wz4}ATxn@4p(@(i{ z9*~t8`)qfU-4FUcdOR69F!=5zc}=v|+1<`jOjS50Np9{0;g^5V_FaHv$%fVjf#$Nz zdq1DtjF(4|v+-Y0)NWee@K|RkIG* z9Y3n0X5gXLB;0Xh63_i@b*I}1U%y!^^w;1Fkr8~EIUVSkr;j>z>pHkp8^p=Ty5cl0 z2yQwsP~Kh(yllVwf!)<0uTj0hwrLgNVrHNr{{S93I6x3=pFZ?YCh?%%=D{6<;FGE4 zJA7psD!n^cz&oSjlnekGyo1 z+w}@EI1tfLx*?40asUN5QO&$EbtKzqu6TO;Jsu?Ku76M6v`nFlz~92=bP+<9K*%PB z4ThaOC%=OJ`hQK!_d~rfq5=!|_|lDhXC)XP)`n|0AD=J79}^$4cP$N<-1aFvR~;?? zkF&Q5i{o4RMiYWN!QI^VySw|~E~m5qd!P5+ z-}juGb2HD}G|lwtRkf<>CrP7^*~x>3Ndcn@oT8T?p)?@=SW^oa;k)FO2;iisns!AB zKaa}OuKx~{VO5rxkml)q-^a_I`3J~PRZY$7G&DDfDl}6E3^-b2xWdw;OSWY##p{c| zBFG2DZrW975V6pm7&LRwe!x?;Iyen7P`Hv1efWAz$grbGQ-A}TyQ!L^v`HEhg`?(y zGowhP*uo=CC7DNohyaf-uPSHr$c}g%h$7z%3f(~M$aWU*dNzF+_5Tvo|Hg~_qZp)y zu$Q8J#r0L64K*rG<}Y>`EWw#ipmkI@6+=Upg10L*#A;Da(+|~!6c`*$##upjGt`D! zDA@S0^X1hAbcc3Il{16R)`#dJ?#D5#Ott!E%AdOpzoEF;)^RG)M1gEtS_5!Zq0;Y2 z#y3zjypfMYS~VQptXKV*N-;~yH*B$WKi9c>*UOcGnS2W^BfR}M$t8VN1_r|#iWU3G zes19EHsEEA;&rW5@c|y8Cq8{U4#i#pyd)y6-8^PW={7zbQiq4@cfPMB4BWc}J~EK> zz&D6h*xF*Pv>?QLW0(*%$n+)rKsTt`Xw25riCb&^5CQvi5X^+ZOKk6_V5%H{qx7#l z5%QGVH;G^Ja$Oqiv;P@m&U)!(TwAp1+Q?wF>E^vqhh$JE#@5UAbLO6l-D<;bQ#0jb zH9!@u|pYOU8$wd79Y1L;n=7g_kDGty-v1(!*|tKOF%xyv&*-o-DnwbElga6(fy}e-N&d8DL(&b0uq!PVTO= z;0bCQ(A)@}HXR8oPz(Mh=*9&YL)w@rJ&+N|fLm8%?Oq~}OtPk>);0_p$b_oy5GL3& z5M{HCt8vKFZk9k^xTVIv#5`32flI4K6KsJfp{yO!%xjr9JO`cnx#u?cRAimDsw^Ok z{h05Jo9kKp=rfL?td)h;h1W?mu~>)Wb!CS9_RI z(gdF&*|+Q?Ch1T%yUAh)MmwEx*@M?qs;_>3q2-3Fd@W-3c>!yw1^>!~Ma!lcX5T6+ zrxo`yDdFGm6yse68>(@3_>A#&+g|%TyJ84O&-Sc{ zV3cUYjc?FG(_$EW&e3kCUc5Y(VC^F9W$FG2-M(U2fq!= z>IG{AgL|%7_Cw6>_O^T;sTrv179gX%`pdCs9`&*60*|z)2;FExzb5$^miV8v?AkgJ zuQtq5goPRiId|Se_3f!i2t>0nG=3^|12WH1e@o@JQvW(?ir;FlyT@8uTJDYKBhaa2 zm9LJ&uFFxB4piRckE%V5SXJX&P{AawAop9?9T>3@A?96Ad#FA?E`qL4kYz`y3P{Ar zuJhrk+Wqj`FYvm*Z#cSNFtlIbn?e0ldh}D_43zQIid4;?~bGk@vuHdC+BX= z^O-^u&~(c==-W&`^JTtpq_cuznIz8V%$U9!trPLW?tG`YO|FtTe#nM2nK2(UFMmV! z7|<&^y7}Q9U8K!TztC|Z_&U*B`yGkQI~@C6xKDGMS%Oh*T>{1I8E+o;SWAQKI>m<< z$$OeUVISaEe%Va&_~zV$TeEljSnRWF?uqC0#m=;5V7Eq2;6XFB;*(}st=2{N?m?PX zvG0bo#p*Nj6=I#H>c7wMKH-Rlu(_F+hqD-UpN1iTv}h!twxR)rIvh=Ae*Yc<)HmyZ z5KBUcphWKbE!Ai#fcE1G_QP1N_XtCbVkRO7Nb)^YPhlA3u|VCci9CU&1XPjEfGC{2 z#J`jMD$>$NzyJVoRP=!*Dmt20JcK&zbmy4C$3oD4*~M&lR2sDDp0CL#;&h0vIeLp3 z%hsYl7wS3B{|ucr_cOSW>`_OzF5u%0@p z9`D_I$J)_!#TID3gm~1luRO(W7#Sfp*5alc+Hf#GI~{Ca?LH`Lt~cv<;UlK7V5?evO|l5)}Y9=84y8dWz1u1IwXPItzn zX1y$@;&sw)w}3lrIo!ie#F3vjg>i{-;qihRQ~ zn#@NMNtyEFAl7p74I4r!qOgH5d|$aBSaaM5&n)B<{5g;dX;6G!-tyzrX&DVR&08Y3 zD5Gm5so4A3ZOWI6JYE5Vgw{*$2NxwBo4k9&TPtD+57`v>0qdaSk;pBZCFqZ1sEa8Q z*XRS*61`H00P|+fB*jPG?ju)QE;THSLR9><5jcT@7w*m53uwzm2h$= z-nI~*`OkIn!k-bDOrBqzA^>5~I#98ok*s?{;i?I(F)!%n21z24{H9FaLGR7lYBOnv z^q>KvAr%>Wd-jMVusd^3E~F3qv*y69#jY9ekV~vGCrTM){s~8z==f4=RR4Lf|0KAv z*L!Zig*+$+vVBSan8Q;a(-%=|>IYg=WSlOkS|;Jq%(ZTJ&(sO|ny^R}^db36{NBm67+_2Y+gZ>&_s5~^Z8slK`gyW%8Kj@ylBW(VY zbUn66Gsqybw%;Vk1;nWy;3{m-WSDzSq+2^7nEbOF6M|!uswttDjtmN7p80t5vJ&03 zLn?@7L?0_@twP9@<%d0UcWKCaqJb{lnuHb9@@Xw*zz z`I+hfhq|24fnW`o62rn#>>dzp3MGOWR#d%2!sRy$Fq z^qRykD)2pGhg*8}!;Q)*((l%7{gS2sywowkOZ`u*`p>7}dkYUjrfg5F>qk@?a&DN$ zXYiWI6}qW>_3j6X2)PfWL-Ob$hX-m`zg)kIJ;77CiKnuBN}V*6Bbq1In>9r4FV3y8 z%TtpAlckdKN>Qs#4gZKsyAca_+SWc!`lS>P`SNk=@sS=xE++0YJDG7ByNp<_S2f~6 z(Oibp0C>Ew@)@k}jpP2o?sHWZy!9>iU;hBxbS%BoJGmzO>D}W6K3{?4!_7-BKEZ09 zC8CaIPeLZTY}Ls_mYPQN0-qJI!BXx!h$lvc2^p=jgSx_oi#;y|fRrFv-(bZ_N{z+u z?JjH&$u+ z_}zy%_A}3&A<2Dec1UtMl8-!oL8kNDrT!QlOO{uoOLx^CPXvuY!XVcNJ3UBv-WT?dRzHO;VwRLT(*9OUl`t#F@?}x?_tigY9hapR z`V&JsyBfAOqVCyo+p4w(;pYta@PL)O=Q5m}x{F8s=dfK)-E6e=q^R0;cy`s&&qW!T}1gn>uS$NO}|lZq*0(}Xzk)!TI1`3mq@$c$5PKo1>IikT@W z*ba$Bin`_&perVF^S!qgnj)4?!O%_q?Z~f87oF?G= zDala)r|ST@NY&Qn}LT3>l_|p%`__0C(vcY_lsuW|) zcPV=Xo_C!6h?2Flrxj9O#y*pW?9H}5!>PsIUeU|OQw1)9W7FpsAOC`9EoI6+B;H4B zMS1tNsX&Mq%Fj@5OY(d-xDLc_``A2mD4Rw7H39#+W8uc)l%HD%6 zc;}+p_FaMv8uL#oFif4>#*!hlL_gQMk#{3g22+*Pn3q(*ufz;$@wS4KLk~pE#phH{FHIx z-(!w+KLHzD(>zF4(v1J%${wfb7nwz<&xWpMI~PjsxdLp5jnSHfn!r29KZ0wfkDJ^-diqRRx|)e*r=7+m>lQKNLtKU8 zxC{?HZ)i1al|gp^?qI%=tRwQ#z(QKfdn!N}KajM|^#?~ou13_)&+kVV6~#sfs?&dU#A(93Im5nk7xj6*=AgPV zhShfZV!qeax4Q2YocE@GZk?$Z4|djGYPhXV^`)0e6MRnz0o2pM7oS+|5i1|y7pqGHP$xJx-!zEAO_3TSBH@cgwUQk5b4CI0D4JEW*c-~2?5OW4f(}i_=~Eh`g4Fv zp8E_8zXI|%zq=MtEcyHv2`irZzQZ56;0B*ry3QZVY;&z!FwdqN2(VPuKMNq*sjHV+ zjPlj^xKu=lw(J5l&Cbm3PbaUt%(PY;D2F1YFc-9=+YQ+5ahg*Zq||4BBpR|R^R+E= z6!E(ea+X~xdn(2uB;AMw4(wV%#_L}Fz|TUzv7zTds~e0gNQ{+Uwle8%`oul(Ec7P1 zNi0^{Ws_~r2lwC-arVJalJ%5)CSs}Ita-D-rHh=fD9l&gg45C| zpaN9F|5_+WQ`r9f+yS~3sI+j$zrJiEtQXwX^iBp$NakAR0%yD0{P zO%$uhV@1LBH?bfi5eSoE1a>n)s?o_Db?iZ$y_+tX=Ud#-q4(BSj4*@RJ)GwZa|*5b zYbrWj893Nx_3$F!Q?(39B;hG)T`)>DJ&%_^U*WwM#k~P}5e{iH1IY%GaU!GHJNvLr z<+f^}i~QNlj!rqU*tN9zMNP9qlz4LFpH=vDT_$g8VmdM#LtbR@Zd0QO z&JfnU!T6#ek3bL3qPDExazurl=(%GHPP}P#BtlklV5F_tSH*3;M1uo*8pLqq{O1Z> z6$Z6{S6Uci(X~Y@U-D_lONz3;OkIr1c~*i|Ft%2&6*WblVS@>Nh$3#7pJ*3v;1L8VrP6{-Ao=rEyxzZmG6P?*>bJ-a%`S?Gh5s}!SSD< zNkj$0`mdn5F4SYsODYf;^XnJd`Z<$k$33M2xi1`DnY@#V1@rHa3Pp5C5)Y8*Bte%9 z?^D8|GX{{kR(J6!@`;rXY0>ly{u~;*ZzH|FaE40Mxc(WLS|oCgBS>s0r2n33-7`gT zj@ZC_D^IWd{!XKc(hw?cI@p-nRj9*R>-3@(p3vRtiko*phI2hNWE^q6D;nV-TLAeu ztP%=t#vC_AOkxlCQcG_|@uJfCexdN8z5R3{>VaIc7lpfFH~DMy$oun_B3fVVcS|3x0c|DI4Clfy4$SkUZF){)aavrnjp6u*RY#|zZ5?adxm{UNQ%(Z>Dl_+ zBVfxwRjM>&cxHDD?#Iz7VnF{$1WGSjOU`_#iqqSd1MiX8r2g}SLwep~HIuA|K(Im< z?_ik!E2xEIaIrXNN#%XQR*GkUS@h^`vT3^?j`>;_7hY%L zq{}s7er7+{N~gXl4q8OlZ9T%aQN6{StI>((AL1ou*|({&EB~aczO7} z0P&JJe9v?zKFI+`gr{He?JPFK3pD+2I=$DUr@l&XSzw~^CeG~|0iRasR=|iE zJl5xz`|yy?Y49`I0n{7w+7a&eoM86Uy-nK|K10orhv9vptAdTFBx;yl zfmf7&JuxCkD6c`s_l#FkB7KF;p10BIwC|9W(1#|uV7Y5s#g9n5@*$5yPqX>Bajp*e z^WWop;IWTdrzz4>BK^Cc@w*pr#o3*jPMwL>z5?ZlN!mch*#)5zPcV?34H^ncE$3wI48h#g}3SGLm5wjg^m#587I9L}mUqbhg~P)C^%4 z$NXUMqnWtn&11s=VQ{zdkc*ffpltV#*eVjwp@VLBbr=WqF$w>y709zQQT{E-Jimi> z1qAFwn($bg!_ih!c;^Y_(zsqXxZrm;xuYn&TvKqdiE8+)6{lYj+KN3Z zjG`<=N1G1FP0zw=m-i)KIEf$3Z^m;0U5;hsSK*|&$8Bm4C-!dH!yE$kplilJ2h(iH zM7+!9JcwKs^Kg^-IlDp3M7T*vzAR;qf1LMIvCkPA>>$&Zuy@hkV9@1$WPuHR??h!W zW=WB9UzSf+h||8H=Hr7rO_?iFica3gdsL}MaW{2)p8`Bpe#<5Zw-aM2nLpl%bI;!q z1@36+Vf*Xmha`%-g2+tuS4w}_ZuuM}=U+rZ%R#FBnUJ(Jy$e&VyG27?XA5|l--etu8w&-r}<^xwWdLrY~!5>d=9d} zyFq1nE@u(lCH?PRIP`ZH#wvopo&USN@b4f=OZ+-jvI0ceXqSqIx0L93(=kHq&G>ECTy-KR8fJ zb~6?vd?#$=*Ka7R^WP?yyGn_y&~>V{zb(0;HZ=Yq##(&;2@mLZVAB!zyk&lq8#Dd; zb{;7P20yVU@H=CoW-DuSWU%oArlm^z$Q*Ez0-U`)#=WHu4$?)LF+&0_jQJ7pdos2p z=JTs4KEJpe=<(t$^Bt)&t1Ww{qIUN^ zC9+LIOejbR_zMaDbYg{4LB zH~0ZhQ{<9GqOhpObu0oF26Vk2 z_}#@H)xYYYcB@1Q!xsU}~@_C(X zIOe9U{pI{WPK_ImzdO#AQjJDZJ(6Ihw36M=L%5*^%und?bru&y#WTXVXk)v?A+F6f(_I^Psj>aF7iy zK&%|6F5vt(*aZE>qbk^l)Xeq;zU3!?)3x2aczzcB_LBbcud$)q7Kg{0j|+45U8gsS zROLXYRUrY&KS%6;K4qDvr>8vusG*v!ZUhoG-6IDTDI&#ND66*G2)CQ6ietpYxE-lMtl)Tj98BJyPpNI zNXfc%n5ZT1G`C0X|9z^*KuY}M8h`IpCFnc$jE)uaAhs~DJJVrz_;5{T-R~iHdK37# zy3&d5=Xl(9{n!XC2*xRnK*0a+#!842b{pv@A6a&;?(Z2>>#}Ny=Jy>D1`)?yy^M54 z7X~Ol|6H*ON5e3NKYbbaMTxue??V!V62c#+4d z4-uqG4fB8ei~n=!dbP}dYMTGK;y-^0V)lPG@&4aSLwbm?n*Tp;3E&2J{?9}A|9VL1 zcK=rs_CL1_q9B?1|NleHlV~sjAl~Uo8x&&OumPC9$!cqBw^jK7;4IU+c>sP$Pr=Qt z@mAy3Sl!sTGVbW;2wI=vG+ztnvNI$uBNJBXqFhur?P6zZTkWvOyS24N!N+$a^r7?M zz}9}X!zes>J+i309Mz!7Q5vAbIH<&tiI~>tuH8J;ctDL|gT*sXN=i!9F)_Ybzbl>m zv9G793L3Lay;-cYieocxH&IZCqN)AYPko@pK{f**jo!W~DJkIv1vK(F|LXz4=1N9% zZ6hf2lk_b*b;bay47vdwcRT540BWqkXcl}mW6%s>-7a?liIAIHK!t_{iOCnrz{=YD z@(g|107Q);fH+FT1weKYLPCI}z!1HqcwT*Z2)Mrh=#I;}FKO73Ql|j6ZT}+RJTZF> zBj8rDDAXLV$I-3%7>dW^dc1(U-0HUIWN-%D0UrPZR-;3m0v-&WM9_!KfZ}? z?xYt$cJh3_+g<0dxPi73F6b~Y8T_`~UYQ&3rn4&d#`S9~u%{1u{UJ}50i zKky$S-l3LO{3~kA;dO2yzx8DL{l@KZCby%5>{A^fT_V!{{{G%_8(*x*wJs}{LrhiY zvpzAb4XQ<^0&J*Rc{boW&3{mwf9Zh}2M}|R+}n)AoB~cskS7>qh&fEZbSPt@(~|q1 zzUH-`%Yk!YS#)e72Baz=fLiDRZI(f;1(N8?ql+I{4MP_}S>#HShMpdJ^vGZZ?}^&9T_N-vT}mVdMF-O=SU8Uv~iy-E|PZJ~+(z6ETHvXD(*evDm8D zwT{0hdcPT<5&A)wo}qQ)V|Ihx>_MlO*tK-NOpL7#;qDUvEsfDC)86Ogd!S@{m52BU z0BXNWzyF_|3PQvT9K;||-mqV4t~ulGWjn@dJ{2UQLEZba-GrjA;PlxYAOT-+u~4%f8j1? z$0*MC^5Z^k4z+(;s31qQ+j^xX1FvBJf+}f;jzZ&C>B|kib-?i@!>JBLI?78;ucoHSj+T zrRJhR8yXrGBIZemG_2POiX8yQ-upIyaD?2n?4HgGudXTS$trCjoGn8L0AsDk)&3u5X_K?wC2C?3kbjF+=M2#=-bYj9c(rB>^gi=5=^hSAkUL)xXH3 zhsT|2u{_i3fal!+L5r^4=C~jO2&b`++3FSGp0!@nPd2&fe64lVgE|*b<3ud%S&fHV ztx~9~eCscfI|Z<`D@5!YX+dUsX7hl5(92B#D;|^T)ZgH=@mGTa!ZorwmtB9Ab@A7f zGw!UJAXmV51z;an4gy$=Oxbq|&gps^G$aG4xurT2;+P$63dONdS<)^3sb9@ zsl^|59&+^VmBnu%P^nEO;(4_@yFJ(nHZp7v7`^`%@d_&OK z=nj*Cw|;JXrol2M5&dG_MsgWp3cE=q97~vLXrC()oy}H`+(s00<=A=wL(DN!u6UL) zjrHT&DkM;n^3CLrv0ImFP%lgFnf=!9_=GNp_ms1LwFeJbbFseJ^a98)8nr+6&DwuZO7dWUohrz!mqa`&vo4W+g;zK3 zxtFQYqr!@zaD_Ln((&2L!%Q60Kn9CfKUux>`u{Z~>zXK3bOZ0rR+&Wmv;&;pRuwZ5 zQ-Qy1HP@$)*~6mY5C!B{p4n21m#hYjN^xHMXhEumeXWvCxQ3A`Sd52@0O94^>0QvN z(JWWk&u>8ga8P#;z#^=S`FWAZkcrgz@`yz2^!B zCUzN*RllIK6Tos`x~IN7ZSp9iyp}ym;RlHAE_zgRGS$$nZvSY%+;JVXA;p?EhwO1T zD?TbWB}&AJ1jQX594dOTx61L>?GVnmn!=xF##rq2^f;(50M2>pqv=GQl?v;(k5760 zKW3i+n(^$@5P;cP-XQFQve<=?8SIJ2UC@-{lWeMihC*MLt5BsrK4WQFQtRu-M)Zdl z&rfLwhVt;h{rp-VB8H${DP2&DOc!m7eas6?>rMC7U)2rH?_Bh>U6%$>aR?l7?9$*7 z$sCFx9xwFtHCa~gy_TOwQ#3RFDCy7ewJQw`m?rg&#HE@384YYGuw;PfP3L z*PGDL$~ZT(HILpN>#JZYZ!@RDNcZ+ogEAyndU5poTxwh`G+EHLXAcLPpS}Xx?uWWr zaFU3X##NJrHDJ}VCO0R#1D(-GO-;&j^ywC=Pu3s4BVpl+;*KmeHhIN)wnx}6BJq=Q zSp7V-+sNKFX-2)uX8+>z%aotKepE=`dXm?3*S~Orm(V>4Pa8M9csBftLUz|r)@nEA z5c6NEsn;5@*Rlma@j9wfsOnuXNc?=teEJq@*OHGgZTP#(HE!ll7qi=Crh z2CJ}^+R-X&s7;B-iZ;(OxiS3Rzy{l)o5ind?DP1lY0K6OI*6`UXaz}?O2HV=IkZ&> zZA3BG_R%VSV?F|zD+wgM3FxMCDwX;Q#FC*JWRul=2CRo|*=LHmzQ5kBrmWtwY-)FZ zU<16QSKnl!L6G4?`!zyMwDD((cE9teX%8I!9D2-@855N1xzZz}7=pl7YFzIL6%%SgR&JRAWVz<8fHTt`_ zhhRI1uCAWrRO%$36KBw(dspd#FEAbc@K7XmqX$NRPCCR?Ggs936%w%;U9d^lHB;tk za;I_3yE*VocYv`c`1{;;cyw|*|2UQc@g?f2^+bx=ELF2*db_DXbZmFlfp1Zu*t?|v zwY=lp{msN|qtX0y-Bc>YfF0{6w+%_qopC>mt=OPb-OZ>7iyD{={~~Q)i)Uysd_YB|yTi0#5r% z=r(~UI#r*kioszP#{CYAd)jG4It}8#`n5Fc)5n5QBmeQHkE|39;^$ zyQCPo|KR=Yya+Fen1JYgK=IBUlpY@(=oVErXJhd-oGQH$GA7KTB-SJM8#fjg7xy0e z*K&BZv$w0wtf3He>iS84g5Z4*UVP+zBWF8~^8>4d8Uq?l*jRMXTOxX!_q%wE!f|Em zfchfsa#Npqghn$=s?6}zl%~U!&5F!ev#fa*B}m|~yv|jq>)!S<`iQz^B6WouNb|ve zb<5k1t$h0JtX&J{ScHTOxYYP*+5uN+&z&Dum#fq=U&jnG3CkAecb5R+M15HKTsjfW zu{u-V7sbGBfO?Z36N}RT@)=%z+~I3|R9}M#o&&;kc0JG3al&~4apd^57 z#(cuc%bxTfOoTCFC!wDtW{NqTO*m3}Cg&vPM(u8f?y>ZQWENd!d z&@&xY2+A*hRbur)dO$$T_O7zD&ob-gQ~rGghT2O~R3bZ~Vw$%H<8SeWxLC=7P%9hB zZ((73chS|G0naf<#LCcbU9|OX;Zc)5#doJDu)N1pqnxy5{4u0o-{I2l>f#o`=c*Ru z5oxJ_VMlcaO_e{ydR!Jyz1;i zcyJ<74b^)&170??OymJbxTAhiz)bSJV{lh*6Ns_V=rjJ%Jloc)@0}Sn2Nw|V72X17nX0E+WdnP$FMf#gvl*f7#ez%*Zm68`VTI)QP%|O~r8DY|!N`A|H^WWD4#S)Hl zz3@7O?$+Hgk!t7o|4;}&Cz|f7{va=L{%c)MWM7wG^I>}KXLZFjg4)Hz;@s0H{I zJ$oA8u4?M?hea_Avg_zxL3oM22VemfpNzxd*t)NX)t-M1p8B_-(=rXC0Z3vh+|l;1 zbJ-QiZif`=G8Lq67Sd1sE;To+qtwlnIMSofNQ{{jpfle~xa;RtSE++X2LF9BR#2q3 zFoVvM#IRy^w}{OvWN1snhrsB7=Z{Bshi^__FCHw`n}va2NlHf)Ci@mqUe9-n~fe4K3bn6DXi^bnf*Gld#pA)dRl^y^(F zbUm}aBZ0qpf87_efk%|Nzn;$uWo?HB*1ulG*Zs727LkYBc#Lo48qfRdR}uF`^y)=U zO=g&{H`OK{D!}YhOwE=IM?d~X&sZt5GfqNe%K+M6ZfoK-j7p(dUkowEofG~1fIx)5 z854HIyvO;KY!GNyxJg<4I`d-9b zZ%Ne9KIFwB8Zt<5H}+bPn?=|lKDaxE>Zq&d_4kzzUiSSGlsMbYjTOpP;e5Rqv7^e+ z1X`E)OX*q&o@|45ME~s@QO!M))pmMto1>0;ASM$c9}8S_=8Uai{#IT3&7}logL%Sn&XRU&=ss=MxE@cn9;2=b8~191qeFGl?$<{82ogJUalI6HALG)NIFwFKB;lO@;-X;5s%y79^HU3VQh%JY`m)@z< zQq=t&^O{jB-oBNSMBi0P4~Y(Xi*4r-^hJDouugMsVx4H}O(VoGWPnNaW?Mmf2@eLp zvboBCL;AbOBbO5T)r!G4G}$UDsY7tFNjvL0}btbYOEF zP_)|m#s}Jr(U8p+0#;;8=tCb5qk3r_KJ~4^$*R((JcQWDwe3))?vpBQm%OC2o>tDI z+IfFAPuowLtr_9?^leoG4)FKh<=$(_^PjN-hz2~mD765%PHTT+>J?DZscU6;Z$T20 zCr%z=cUzZzc>c1n<(?fUA+pi{1!Z7&cy-Pr%Mc7z+zE1FM)dH8lS1>m4j)_Em zA-!)s=!bEndZHQgNC<8I<~o6AOr2t&pA(vnH?sU92oH~^*q>B zF+C3psa>r5PK_8xWSAI!`HnJTO?7hW`zUbzye+0b_YtZVacM4V+Z}4P4X-JDfp@UW zD)U^y*Tw06+rec36(7FfR=t+9_uboD{y;qW#=zsSm1L*FEc zVdL+F9MSPN$$F&EAAB%HTUzDQCB#jJ5wc6%op`A_augmcSoP&aZG1Nbe)E0$IQs#k zdx2Y$_**75!d^X!{X%To50jjee7N6t+m>?AXC491hWipqgt zA2ua-MHI8K*Si(ov0y98JhEvgf~<_xrh^vu9S3}^Q>Ieuhe%FhbIc`$x)L@wEPv$0n6g@Khv1- z-utQ!nMS?QZr>ct%N#lnZpwa+s%|^-sne69?S5Gi9HN{?;72&VKtD99h1pi=2r|_} z1HkBO1V0ZdTC1Fb51jDJ-(UHdQ0Yt;)ibkOZ`?(@9Va zz(*pEw$|}>U(`(L1E~Tu;B5mrdkCvZQuhg5smZ8JaV>l|sgLUQn(H(^o776SV@O4S z2Bi+D=hOG+V{sl{y~0qzlUzS7(SnlaD#K-{9q!4;V;f}oaAm`f!>VQ{@%fAIy$iW` zb~Jd8mOpC-WTDkvE%G?eDg}`8)a~{Z+~28MvT`w(>1W{pRFv%|)#tfE#4?vT6PNP- zGc!|Q!1%Q5TA(C^b^QqjzsfenEy$GF!LvKB++Mco@W0u>wsL?*?9-yYVjr z(*YR;HW(QM8*Uk21WuYaiDD4m4RoCK5qonbVSjs9>k<_1xNGxmtpJ%`&xYi~I{};b z`GWMH_BT=zxia3dvan3Si+cNUnW!bfv9pjr|&R*y(c*lvp{6u?q}j3K#P|& zozH0oP~G{QRL@x=bMpkSRVHB2l@rGI27I{DBMtAG!qJF%_mXUsJa*pn44sYzBcjzh zd?@E0=BFI?1aT!$VIY(1%Iq-~3tXyq9V6+o@#iYzPrJSzw&E7W3FHuIal?c5y5_`3 znY}xY!Hz@KG1$&zelHOC=W{pLN(P_`p-cSG@)W^I_~&x7POmXNI=PuEbCIlCn5%-& zxG!_oWg=cCh)l$LkH43A6IHjb#Wv;4a!!vtt;eVKq}q`1D#S7pUgRf=&OF`QBv9V> zG9$fRhL5@8!Q08RoMeW*&wo{!b}=Rs?i$2W{oAw1tWwEvRzaUr%-%J&tY0*%XSqeg z6FK^rE46be0d#FcuGMDb1e-42=>6VXm(Pp34H<|#7>C${f{WzJcrJ%@%C6jK2H08E zMrJD<<*0o0)p`gmF*13AbNrOW2gDbtVOm5wx@3e1L>anSKc0tkQz(dXbY*2@hzcho zR%SN#pRwKWWXJGnQ!Xp>+0UY>KiYJ2XL|B6379-6$^YDl>P{Gff&!0oWB zXs@2y8It5)WiLWIOoUVap|V@8;UG}48L`w{BkjTATtEzK2DsZVU;BHYEPD%?q^!V4(B#SPO4qsnlJj7y;8G<75n|?{YrrUkRkhb+0a>h2o0b2QDE_!Wg zmF4wQbd+FGBLd<>1Pv*Vd(3pf%rNIXpg+uA=b;;Khg)TwLpZ-HU-S*%dca%Fe%q_J zN09tzzx8yW5W>uyj%+xDCuL3X{1L02dB*Ow)cJQmsO~#Kpf*HjGWNt6SutAQGx|D( z-Pa>(@ddBI6Q3oFv1Q&z@&hRod3J16(Q06Y9o~|pPfz*CnbX2+4dy;oWO^mGaNc_X zZ&&Go$W8M_!+}uN#3&?di6l`ZaH25oZ9jIO)Puo;dJ>pwt}1WSXU@`0DGAxgF1F1OMr___)R62WPR?89CzkVJm$wT-kkd< z6*K06P#3vF13maAd&zA@r=H|Ycy4^I!lK5ZMNh%nLSq^>th{(hkz4C0dbSzlP@tV` zb36mLFD8I?q9&R?aSlx!m#;RR#@vM48C2EUGe<}GiaQOU}MIA(>gfD>} zH5_b(WGIU@fB^*`5kn%zQuWPYJrH^fCGxTLf4M`@sC(*s2Yj*Wx*{VMNJI%}`uR}0XMgypL z^{C|s;>^r`b2>@I6m>XSh9Ig zeSHTBddqwT=QH1Pd^sJIWSgn&d|tACx9+io43?QP?>F<|f_0NDX>ewa2fOQ45Egf8 zIvpow8ZUm}{Hjq76EQBxcH>%_{7Iu+w&5rzb|Gc_%BmB`RYG) zD97L@#0!5aJ}GioZli4WD)a7}tr0z4eEZ>@ipM7R;GZUjrBhbjs09^#>(|i&B5-)# zvyF`z8t1;JjDJZ~SXJaF@o(ZkLpV7(zbWWIH?|QSmsTXo2VIvRx+eAa4v*&17_nu$ zMV!l5HaMznS$*@h_Z?W$hq7bHk$l9nh-7h#xu(!&*zO{Vo%5|$W=o&4qCr}uOk@FA zUSJ;YRq4>A3i`J!cuN5DZboWj~IW{yr!dCCH_YSAaQda1Ku_uOe zb0bDi_M|v;3dczWUsPbFMO+t!eQ!_cR=H#UYS_9N(+A1;{OkvYcXLvz?}M=?b4p7U zqLp;%`1fZ?T4{@ZZ+dh-WM*a9qsJJskPo9>)tspnIEV7ZyqxuUwfb5$?^iBkYVm}h zZ0NB~Zd}I|@`r}m|71TzJT#!nMeJ4h>T%(q;K_E8eP-E?jbvyYVSca5Al`H(b7%gH zxpD)j8rnINhFUCDD!iwC06iwo2!P$NyIm+Lo_M%L7@@_X4ME_+rRex~&kMkU68 zAQ>Z@p$4M7SQ+Z|GqP|mMf6K@E?}z&=k_fARh~lBG4?9Nhk zN3P8f*wd#GfBJF4g3Ur4Y3kd2kcPc}_7R~k`uOc3U8p7tKD;pWyN0q2PBRA^4$*ke zdn#S+I|I87@nlNxZFyG_G--Rj7Bp=tYiq6p*rrDLNSA(jYNAC7UY&dq*e#nMYJWLSka!*yHUp zLv{@%srY~H3K?FAeut@_SwLoce+NKZmJU))tam;2W9FAN=;@!;8giet4ja^Z^uN97 zKlR%VfiFBDB!`UC;$J8HKLF!E9KUYJzUk`5EgZNa*D-E*%ejeQNN-2v8dQRmlg7h2 zun&TJ%i&%2)PBPm_4r{^_fPprJMvrg8Iihry@K49pM$KcE{3Hz_8#hg>vvAIyI3agby&mRC0j~C%xdtg?5ck?Zpi+$IK~Wv^VqRKJBB}jm1_~<%6ocf$<5K8SuFGd(aA=03TC3J%rlN!won;7Y+7c&lDMP5H4iSG4smG5;>iK7) zp>ss~HJ2h(T?^mJ&4~B{h^q5U*_kn6nkt{6U8SmS=OgRN3mUzi6fsnx78e znvDqW+yjfMbM&g=I%y(W^Q{qBy&l2s6-YZ}5*$PJ*&||YkyW*MqmX*ycb3U~ z+`?^U6AK?G>~RzqskXW40>yNd4)kbK{@66VGTg>3LXYz*yfpMD+WM#2 z3q||uxZkhS4yvw4=xvYU2i2Fb?uWL~{uI?=(9dni58Hq~$V{+}8n-aAb;(EB15YEO z>TS5DHhyAO*FkPWV^e)@=8ZpZ97EW@S_03~H7d_D;F-S^uF=C`%Al|^8L1~v(gL!0 z4=sF-UDcVg+y9}xzIYd{RPDrG*c!a1`Q|T1P<@8#^HV2|LiVjUG`79mUdwfC+uH<2 zYU>bOw@G`2ibld(Bxh6Om$tSNqA--(nlZUJ=CBP?>0@hSA%!X@rX-h6|DbA1B2_i2 znNsQeB5|G=YsoG6UB7YZJDaN>s(DKu7d1rd#) zTz$()Ov7t|G2z6OMt}U{AN6MnMff`n-!!~)Vu)f68tCaw;r#Q@*Q<}X!iuYLX^`e* z6g?Qwn*qZ}4>HERxr&R1YeJ(4R|qq_#zYql@D$H*@;Kf|&9vbPEDBQyjm;GA@L4qW z)A+&dC=8k#LE;TKhC5^mFDQPXQJL{%7&y^o2niVHF=NJPgA9M;q#Dzd0u_*0(z<7y%{%7^wYS-@;W30F zu`xH$I1+fZ|u>GM(D9 zN|)(mgvE#h%Nx_%C>NZ3=JqKp=RBY7MEt!u;mdY{Wu8!cM==;-nPC1iziD_R@gf(t z6?897;SL2wtZ$4Dp*V>7#5&IQi{3SiiE7rd^Uga@rv<;G=MmN!qpUNJ=%$=ur`I4u zctyj{z4zYR*lw^5G=x)(8`}u3_M|9~<-iEDQJx9Yg$L7^^^wTX6z}a=JIp>&j%rV~i4s3<7##}~#obgDXWCLXuh;v+*nX}Dx zLFU5lxHnW_AnRZg*c#Wx+{Ro(nFA~7>tF<9)+p;h?CMTo$O^`UbzIotqaeRHaIn7t z0k1m+KS(UhCxCg>>QgaKCE8CivL@tOkC;0Rkr4lcq#|n&L}yb9khv-sp_lo~tX=qD ztT_(B#la^9__g>s_`LYA#*gU@AjY5`fqw-F4Ii2{93Ke67vIUg4<7;|SuW*@z5>6B zLl4HUhZt|&>sWzp=OT`x@Q4qD@5TPGr_!Dd4o)zRQ1HV4h3H{jD_BEJsa4hmJ0&sW zJF}Jmv#&M&uPL9(zebhJ4!mv-tzc6SPZ+zVT#$(~KyG25LVN*m?M8(Xat?kzge`nZ z)-d)I#8bEz_EzjC@x6^73US_$TbKhNrW5;Me}pg3fd%Y?_03uW&_O@$2i{yM^>bg+ z3Ll{(#&(twQhguayj9w^?vl{>!=&WOi#ifh-2v5){4-}r!RaSUcy@Y^*EDy5q$06i zT@Okqy@lQv$KpEa={Yo0<Y>5!nrcUS82Ms*KABW>$;h`YcqdB+_orPo{{foaF-B&+qF zQqh>Y{^BktpFQPjjr6*7GR@VC5?;}FR!PmjpB8U^UQryVc( zr%jcHd5a~rZC8$);+{eh-@aSj)BRHS;4>20v{O9!0STWtQOZ=C2B#iNjay4cbtd?Y zB8DbqWGK7z^T5s!jY;Z1UFLWD!)}(Zls&(_Qzuf3Z@ela`5arjQ7V7;H(eT|?D{Lj zYf<`u_)_=xe@kTbI$f5??e%DKS`~+O9}h}o-DXW6Ir)O+2sZa_b|UT&s!)B&o2>AS%Cz`j}e!}zw?hB zE#)`Pk-S+m)I2#v_p|G%1!;Ai9MB~=a=kWes4n>wZ)n!Z@ZR)oMw|DG4Yl{Hr0o0C zrf>HO$`5XM=qYJ<_GPKK`3n-BnMp)wp1)YC|Mi5FTyee>Ts~XP>*?{{GXDjse&9(d zx#aBh^Zw3xG_veXsrlz)5*#&LioWn!@eb}h1e#dCS!(Z2lZSK}D&=>Pq%Xbcb2;bs z_|DzZ{N!^|`@{l?s`(D$WZ_vSO6c%WYD`9TX{g@JMOwWh*>gWZ#H_jJQHewRX>69V zFJCPolreJjeW#L6=XZBZyQx&?yldvDRcqDvQ;McRE4ak#8^kw!pjrnW5zpL3+K%Ft z)lzZG7bG-&YL8ur!isl*TAx;JOs`SqcQ$R+#HD0QOo}f(yQ35sXs5q`x>9WC9`Ot;l~Og1`l6B&UG;%9DtoP8 zuv8ObQ;~%D4lR|!b7xB7rRRxn)QB#&5n1w@8e@-2%j>Ho(by`1VFRUj&bhkX+(Ey+ z&!WZ}B-X}9=Sjm0uS#UqCQXnEjT^2$d%ol;pULI(_1iMY@3g+ZNy5h;Dfu&5+h5S7 zgSy;5B&5a`Ni|2M^gEYjkXv#NYsw>T`cRM0!ZW95kXyQU+`1V@kPQ7^NlL;w;OO9> zg+p+0kaoz8{8}Fzsa&7q|0elh$N?nRP4I}yXA};sqy)XVM58)+4Z#8;1PU4`BN!0qx%%p>bwZYF zLV?316A1(vati@n64}<|F~1L?f$}Lig9Pp1J5f6L$xnWg5o{y4#q|-qA^>&UZMS8V zVj>_#@{>Rmqyxws*77Q*4+xfVI-2V@fP4dKg64WHRY2)64Ylc8V z@(3ah1RBT!CYesKnrk7c&UF*0rtJU;bwh4}*Z_%v6K)3dJ;80-l%OBd%>?Jny>c&l zlcL&y03F00leFTL9G@jgMqr)*J<2_hNz6*j2;GQ6On6b3CU`#-0qEC!1Lb^fW1TdBs zt_+z22cHBm@1qI__hlVoKV|lDltV;?(~x7cfp5e9r?*5-+u*UXt-g?30Dc&JkmgHHyq0mgxydW#t=M#+@@TzBMQ$S7tES=RxxM}joTzAYDN zlQC%&PP5k=>-XU=vR5_xH}=0MtFl*t+`@hoKi%95dlwWLiLtPce)dI4wna2C!ChP^ z0i^1OW|DU)86tk4PHLmj5Lx=V1gCfI3nOp5-I4rqm!|zBzAsVVATCk&tM11)WRSGJ zxJ=y>Wrfvss=1m|U$4rO2walBdR(Ar-~9D_dE$Mvr+&D=B4j45wsujl^rxbC_@Nzz!l=)BHtJ z_w>u+$qQ(^Pc^h^)tBx&T;1oIP0D7gCGVu8C6J|Lfx>}R$x=>l!7xmcEVl&t5mC`fyLJvL)3%?R`u8Ce(b6-3CVYPw8mJ zcoY)h+_$A3+@Nra?|o*M$wEmIR@!$8nDP>^fdu-~F7F;kUGD zTZd?da!ALVhiXq_ic-9NistzlavIC6;O zoqduf__VzFzEt1!sIv3>8h9oin;B?Zc^M@V$VDmAa}l9ZYQP>J&m9wh$BM`rfBnp?FRlJfEL zW=>V}{Ra};x`WLNv`4l6l}O;YNf`v*Zs)u$+oa`~#$`JG+!E68t#YoSSSjaw6MF5qgIPb}>IZwiaWIE2dT?rLaV;kiH zB=4<>VE}OjQVApr9A=W{1bzr0QFj}V3?Y$jCAR>Q+@{_^33gde6BCR!iWAx24{73o2OiJ_8q`LtCtym#!YcWW4ML0o zs0m>o`w9pTs3Kuk*@0z<4yMg>m3XoSej&RNz|C%JWW5(k}Qx!AdfJj87 zWCyw#qa>y5R6J-iLq3DBL|G<7_%a~S&3B`c!hJz>$+l<6WZ0>d;AG}x5@d`Y({|Y~ z<+PZKtYd_^GSa@mWPZ(_*O-qO?<5iWV{9GhpgoPv(;s#q$&M}ZKDXthpqV4-TRXdl zG?uG$mI3n}r+FPX_#}e$96t|RK$VL*);d=**O=scB+`ArhV`3y-b$8aO*WtJZv8Q9 zGQZu|5-$!Me3YPci6JIu1GT~I{Z3DS@N34qA(`NZvA#px#ovN}MoCnBCVVIS2kfn{ zz(>Q6gNV`_a*Mex{9Opg-L1nMWav+Vse?}r@Pmzd3q+1=e_JQ=+Sd=(0m#_7Nd1(k zg}iRvyBJ@beF5Zm{A%{stXEcW4Up{d$Fs+<6^4v&J)D3&nNqu48{^%&pJLyEuZOBA zex$YZDfeW`{BfPxdjSr4u>Yoga+T?Guy3F&NBx2&;x5S3WDn~pcVzmL^^M}r3rJk; zx$6Ga&bSVx`VNk-yPLT4Ou93jh?&t4RFMSh87Lj+>$d;#;>Vz1-<1NmU zylKZs$@N!coUSMN5uALq6wa6=t!p<+?cW}fV#=xb{L;n={RiiYx1vOSc8YpmIx$0X zhcYLqs-WUfbH_iV>Yk_dsbzl4T@;eM6ONSfFJIHCGQnZFmX>r$o2cqzShj)YWOwJdyDpZt!j*(~*Q7fI-( zb)DJ_Ti_+H>gbVXB;Q~qq{$0o!C_= z%`d&K6Vi}*f+uwCBg!T?6^O`nm_!eh-l{zxgiVU7gU zH8(x`g1GK|R3`}=<}TE~=PpXyv~T2a8Sw2n;vYItd?V82A$L)M@c`fs!b7kIYwN*009d7}egF>!cwi zvuf^sNaB0y=#b3*QFCob*~Y-{U8!vJX!YIcYw(RYR7yX0p~QDqspq>Xd84kMgs>;% zPpd!pa;Iaw!w;3R&&`$;>(jU~?Y8OB?O*ZzR`HJ;hd?1zt=DBf`+d!F<5a!ZzKYSzCM zuWJ(jh#`8+bk2Jo$(wqt>RUCZsQY&X(>?*jJl(gut0XY7e@bop$BvS+Yi4V;67ONd zP0&p8rysB9L;u*r#9dyt?>|JTEp;EBLkesY`;0~JfIRhYC{2(s&*!Uttx(U0^7R~< z@fl^G*q^7cAX80>TR3v8lz;sOO%!Z<_dTh3a9)~BnS)f&viKEgT>6%>YmelgG+9c& zc!hX}4VU2K&*(Wh)!3?uQkjkClY$v1=y@P?{88$&>1zn7`3HN6Ro3eE%{jl&9{FKS z;Be=wHJ}?clEB1qQg-zP+E&dP?g|AZ|Fmi18&Ia_KTmO{GIii+wa(pAqUU)?KsA4R zKofQI0rk~KRBo-Clu%R~de?p>fzb6T`hPnc3ZBqZI+*hi(RSM5KL5;;u+elQ^ zN}{Pn_l3J%@u+plYtsDM3h|VcNN~(>iS5`WQPfx>Ju4Npz4N|Aw``S!TC)p}9Iw{R z(hh$`$TJ0f+NNvnxLX<)y)KD8YP}DuepT05eEvyNdgE2%MSZC~u9;NVS98Zb65Cy) z*40T;sOFfwvrg5@GQqhEq~Xa$(!BgVX?$d!6n*JxJ-0xlsd;FwR@P$eFZt|j3C}uJ z+E%R6Yj&IRt0bC3xv4!jl&5?r6x>47Pn4DyUzOUsAC{CFGqrdATf&o$5^ol9xX*J) zG$yrw`KR)Qwn^~?GsUm&xpmoFX~K%l+RmIqzxv7w)p|2m8lQVrBJXb1{p$|<#6NDB zlwLJk3NAUngRsK5;WL`>x@@^LEqPN~mah{R<(<@XzVad|x#B!2y5>^t-*oX&s%j+m z!8%QfN<~_wVczo+QGO4fE&0qj;_gG$4hIfCNpJ`*4)!ZhBgjrlo8S%!cLJm&iaQ3R zaxhH!3Z5s}1K|WBfgvdHIa|jaiOlwe&6>=xem8+A9@ftg)FR=*17!;n7&WK02uc}s z0)kCe)fX#f%$T9?)tm^k0|7FK8@Br$^?L-4t*Q@P9|=;fjej|%nSFf*D4G!9;ySuG zEb8<01*8ePI^ndz-UNZ^BLaTNJDajL*&s-+5$(-bB2aDSCQe3L zLBhn?uOT%tzRh)FbM(*5nKSixWSp2lHDeGZDr@N;uAlK>Y#36Sv30kN{4u`?5hRzb zF<$}*JK5wG1Jt3IW3WkUDIn9%i~}pV#ehIJ$|{U|GY?t;$&5ff$eu&^Eyg-?(7pHG ztH&#IHe-KCIuaW%5KV|RI+i{;g-tl)Kt6TRM_zC!_D7f%{4hW!_5$>j*x*brNz`sH95PO3t zY%Tek3)~CWg?+Mqa^GAx`wRSL{4ds62*cL$l@1PmKpHf`fotQnY_cbNAV}rd1LSlF zIQajNU5r`{2U8sEACRbxzQ0al+xAG{@L>|3mP!6c0i$j6Ht~c*(za!Xw60t$`O}V) z@T3V^DWGNLYKg4gD7$X`y$t;E*Clw|F?)Y8uJoyFPK@WDJXs3P$QPH_r+#;vw0*Ei znqFI}u4TIn`sp__NG`rn!*wZw?O*$(0gsS+RtV9w#MVys|^-frL~{ z-4kV$S~qN!~cGHoCgi;K4~PfD-8SVA*SNbkqb zIZdqz3EB07|4(8&c1!bu7o}iMIyT@te6*B(ooBc6-sjB)*j0rB_lBj z49%C)>n@i-JINsb{8>67+WLR~C~cdzOY8HmsJ2L#neZPmPAYzyc_7fGY&`!nXX{6Q z!BtYEOX(CyW;q?-_%TxUgRl3i{bZK>=)M09G0QhPJ^v<$4i^7{CCawe+m|bWb)glEmrkBoL0afp=MbZxJ$6I)C) zMjV>9QJd}Uj)P1~gQ z!DpoAfq7DW=OfxS+$CwBuK40}Bz)>goiVQJT8UTHYT_K^2<)}tk$KYa*m4>4v+Jes zl5?c)?uVpd@d}C8H+Fk%tt(dPInXz_T!O0q_UC~D%272fcty|Ag=f!@z|rHa3##N@ zc$R)-th3`rOUby={dygNqmR&!Y~)>Vrha^Mi&YN$N_As@-Ry}W(J&|J{|EfyS+G>1 z8+X{hIi65+{%VQusuuqt1Eu_H*NbOlnxt2F)x}yNr1s%wG?6g-H}Wr^tsfcoa?AuN zKBhM$yOdUV(vOBt1syvCPne<~nf{|&3NF1sKWy6|7|^!c5sP^EX-U+#Xk{Y*xb6=E zK!(`!i$6&HBd>{fXn}YKmFTi!tg98@`>J>>q!`NcC7WAx*%`Omd$9)BJvdid-dZO^ zfAI|o9z8*7{`^nnPi&AxLw)yiQdN!A-t{kOU9&|KF$&K*RhJFauQfDjr5K2UO)o5$ zxbjg7W*#SjF(dRmfZ|od;^h*ntd>Ey{+D=%r{n%jPd=;Fd}#0T8?VYB>lR*psV412 zYwDza{)=jjJ6+skMoR1ArIJ$LpK6Os$rZCDZ+3bO3#zrSBo>wGJN_wc^|=+Hl8voW za_wajYM-mZXUx$4R?R&ROLX%tiLTusUd9-EM&(nu(jD5PKc|U^?Q3`QGtW!w2OBl9 zsN~v9)xh&=WghKF*dVHWJgqJkiAw$B&x`NSfimD5b2L$^W%;{$9^LihKPq3QP{L=Q zs^_7$jUTEuZ_{M1`X`^)WtqyaKTnN?Qi*)9LHTdnrRuK_OQNk!%D#Gi7ZN9mfIENs zM~QE#7I$e_{D+n!J1Kcnj*!CZv-ZSBd94@iz`eTMj{1v(0~Zd##le0>EQeGjNjQ?j z*5Hj^?9{|gnV`9I=W2OjP9CDpK+>9Ihfy}!ml78wX-V)y79ruxgP<@E6AU8C0D)lhdS74& z2#^N4Ya5cW)}%W9Z%(sy*Ovt6P^5u?!Ef=oY&8_Sy63#toXpNe4vBRmqsllywTD2x zUBD4gD&*ByU(Fatls%xI3=tt0MvNF?TLQ+woPy;ZdOD$Q00Dt^0@><6fTTC%6$ma6 zolKb`#)c_R#OG-5eFX#`^PSm>9({pPzkryM3ncrQ8wlVU^(TNWLL#7_Py;aKkRV>5 z;KE#zeXmwx94Z3zqbY?!KmY;)eS&=g`kdFT>OhPM?wxUA>=#88#s;T6d$Olo^8@3Y zv4xG>k<>aicRrsEV0Yb%raFS;xjt9W&i=QP^Ji>9Ai^fI32FQd!HqI*%&j~Kq%$Wl zmMNEW$|`Ucrvr>j$nA^?%4gY;Qy4?W z=Vu-0u2da+8c6in>jj^IJkJ3E_8aV@`Mqqghk;bWn6&!i+3OnqA3nC-J_y1}_F)0D zpEmwx_TGrY5-62YmKD`f_W$_n=HLPIf#WakA5fO3;n|nO753{>-ocYk$ejO39DDug zgn_svbodA=4C4-QQIJO_dFyO<3@InJ4lvMUclv{ZjMXxryVWc;zEh;+@sY|NDju< zY!d&JiTZx@L*0{$dvduYIAN5Of93NMm~xa(WY+)feyM$6o+K)3rRj<1G{J>y(}^Qx z60TT6{KE%J*>#so_}uhikCx|Nki?(wli1eX()`jJ55;dAuwjR1gB*lehZ8r zEB=u~B(|$c;ydxn`6nNvi7n9&cS_`gtrBl&mH3(s;)m#yW4+)c zeCu29>Qn9oQ-(|4sncxwzfS7!e^TPrjZ!rG40S)Jra$ZUm<3S(zU|m)ib&{)u@cBC zUE?P?de|U|@2=K;kms0L_j_?Qev_@y+@%=Q+?lMdl~gn-;mJoxU{Yp@2>;=u#Xss0 zO@Qf7xXX&A=-inSA`!1_B{b!T{oWQ)HD2o;oF}pEm6CVDM9EiUlH_VeTy*n?65YK= zCt)eg6q-IsQp#>Q^&hXSljw#mlGwhhqnw!wVvEl&iFia@1^HSHr~b)B5(BvIcgMQ2Ra>KFU19hSW%wU5o0wr!QV6i$JfXI%SGj@>~I z>tJ0|I(hESF_)sK+SIJ(c4dB!I#aifL;%No-G*xbupo<+V2@zq~|~S@c{& zY(lLgNmo*n%$nyf)}@K^PZ%%x7tE6QhdVSGg))iV*&yY(>i+(3Wrypv;z!B#v&A=I zOy+)#&*N$)Q_6NGOZk7^Al^~KHF2Zn_PCYn^k|4pGoQRh;g+Zdkex6-&LziTj^Q zN1oB;2?ySCT?d)Ra|k!yT3_P`C0W(ER>>)&k^64%-Fwo=nyHn zc$O}m1PQ8j^@enLEXv!xwMvu0xK8HZ=BJ)hW3#CXk*rHQsP77&I7R&UZoMdr>A=Cq z0f*q?;A2O2z>(k!T9;SiyK*U#^wwrUcXp0#7_}Db*kGQZ#yll~NK&FqLP;SW z2FT!Z;?k%(S(SQdBjz6~=>^+mT+zln7>_%4?9lf~5E^10b5nMo@xAnEPvtO7;>LEd zZofBve_zV{bVuw8b#r2k06qj8NK#gnDZso38IgGaA`GM=$`$Z1V7?~6-q%tIpG1%l zG^f~2`KD~eC{%VJe=&Y}K>lHDB1ca$J(pBICD%R;ZRp_B1xgB{^2FLn;v9nEv}x09 z-wR=mHG%oaPOZMi(HD8A-WrDXqV$XGqi?}ldm666dI$$Q;XPMgd8IRO z`WdlpJEiHhcf?y-D8Z2jT<3eceT_%JWrZlSs~G%{6+@-*O$`-9=(TEYeym`p5hWIy7=rg zxkYbcJyLM>CF-8GNW;QcCE47h6D?YfpSEaUb0}e8$SvBw&OB90s%m7{ZGV**2LRS> z>QDzrJ9jBv&c>7y>4*)eJy&4FArd3O9!&4;Q9x;UV!rJD*mPd>c%;kBXoaTfa%FZvUG!En6j_BS%X4%{O!@-;&(9 zM=F2u2Q{u=ll+s9lA_tOByakOlBCSm!k4AtnHQz{?@#FYs_ff0skSQUh*`M{^Cj}; zySfxgYz-=*dC z4`zc?sNk~~ zeMHUc>eIZ1`d0B5u1c>F5X@d$CXLU$pcO-Q{or;vMD5{1YF&gJO6e!%MTn;$tnIY< zl{X~O&@4m#`xb4Z5Qp4ewaz4ScLwEl8XkB;t;?@Stg1muE<9BVuedO?FCc6X16TGh zYHcn1+I5=TqQ6zG;U!b<@$1Iir;c4OpmO_I$nIpxmJ*WU}l z#O?Q`3BGTylBz%4E3pr2#1-!Tuv2_Xt&D_hHS7>g1d4sQOTv@Jr^irxE-ae6ozT+%8@NxeP=j~FS%H(u3IzQ{LW ztQ22zu2lc+-x62vk8Rtb`eQ@}u?BxH0EyD=(Mm`yiH?g98$jX5azggMbi(4+2am zBap~P!WyLmPXtgQS5Pw>O+OQUZayo&vw!VP6B#R+y7z+&hXOcBidv z9R<~%=Cj?Y(xmtK>0ls9slZ3Dq38D~RRc&EKxD9j@kh{{ASS_bGmZ#uLLT87ImwEe zMR)DioidA2@gO+bTQURcAS5v$h%sjDKym}Sf-r_;HUt++2{EoIGh@p8>?>$Ll8;E{ z?~8(qIdyMJ`{Wu+oO(32Y6Zz1Wbf%S6nU6WcrW)$B8Bo7v>RnHARw6FF+psk_et#7 zk(IbE+M2P!iDNT2K;l5Ph38TJA^Ad^)3$u(_rL$W4m9r#%pAl$_GB~rGWKov3#wg= zO+c`)EANG^Ac4+23(*I13vJEkxL!_xLy}prV1aFkq=N~}*M;qYGVBaOC1tIw;B+mI z>@|ucA-0oie%KqOEe8$`WZ;uQ_+s6IEQgO{S5m@&q@+pGLtZq*!)!nb)VjU?aw#f*9T1zGA|J37W)f z$eMix`y9Rlr4>~8@V(~Eo2Q@a4n{RG*Zn|jzz4(cLlF}{#v!;I+`xy$*JOW&A5WR% zTw|9pYt&2F53mO}>X}xshL}AF--T`1fpJTzB79!<+5A3aOmq0-zyJHc^}i5e`r{x$ zZ@@ao8~}-hSPC%?+6Lk$aTWYi9_+7k9gJ|$cW}y;q^(O*;vZNc;aOcviI6<<4k*_~WpPMId&LxxCX(@!K(RVR(}U(f^>PLTU5%5>S4@G*lVG$m7k z1R_f4xTDoQy`;;tBr2=b_YBshdnh&JDK8QK=&lN+{?Vg!VlY|Xs86J45L|M^y;39+ zIgQLZ7EiBbiETTj`GuwGH%lda)Oabq`NlNCfqOb_x_AZ;lD3WiE%BYz(xmR)j^Lt| zGS_a9=mvEisoaG*VIYt@>Sw3FI4Rtl=zkp)%!P!N6k5rwaRBjuEy_^whz`y z>+>&*XFx?dVbl?1$g$qK-1?+BNl*DS6RtTapXk5)PbE?viNnn26KRE|Pq6Y^eETlh z^NT-8;|p&|=*Yul;D3Et0+T0pd0*?2*QE8$_r*V~TuLrKzoSGBvqAColvGbiY|D0O zdVQtjFMmfTWxa((;w>$bczu)9Kej-k%5I7;oGy8%rB#08973S1NhqL8dDyo-rQFs_ zY-^YiK-ob^q*bkkxwu7q6BY$m+hs@Xt3)ZyJN0%f4bBc zUG1a^mztKsXV28@L**}iuh!dIXRr&B&+MY`g#h%Bgab1(l;fp`Y+j( zF296dfVxzoH6r<^PVFd<)ZrIRK2qF|%+o|Ctx`vxAd3`h)Tz8f2kDYfv}w(KPe^pj zE@@l6Ry?ZBJ*6d5di8}8Q+|uPCj}SPSCqDMc^wLYg98`N=yY&EgA=^w6fc2HB!GYO zo8Rb@NSsE5=#pLU-Kw}^1*#GxQV4KTll{+s{&Sc25Rl3yxDW(00WE?;Bs?H8WP{}7 z!i5X>`d$f&L2luGNR*Qd@9O_0dnCB@=rr}?M$NQ6!Q(}X7ReXB@CDoV8F^=tz6AS7 z;+h)ZrmT(~2r3esHi5d20uXf|LvW4R>MZ~w0|7$rh4F`Sh23{_M{q&mgT$I$xhQ~w zjGmy?HS|WY2EvSKN50dvZ8k^*pr``D#gtyyuwjFK4OIvv-1ilHr%@mpKYsi^B@~RJ z3f~9$%MREi{Q)47*nuPm4^(#mN*TA_daLeBNNEr+IPHx6oB4ykA?WlL1c{j&kQYay z99eL?v9q@X7i`VUJ7#>?fq8QC=FK`G%eB~%QThsgk2az&Np^JyN&(PUroSkQKwEPv zo9}^4WY;za8#uK~LY%qakw+fsLU6IegAYEa2`ms_vez{S4h}{zCtQB{<$4Zhe!K0q z+w|YvfpyH-2kK*}aAgxw0X_+(835%~tV&>}3z47_@4NEe0N_|j!cje^_S0n_OtTC zAO28&{_~&9mMvSfk3gB3>~bxA1%wBDI($i|Jkh}qquxSaL-arM%rm>)3!Cu;v5NJ= zj^JX{8I2!~DvSZ7Onh9%8NM&;jGe+BJ~{giqbieYud=_unrRLW0oFxSa*3m0 zVwyapJICh}H_6StAglH}Ag>eq%kn)Ek(k7rTf{SQd=o~ z@X6Kh_eEI{o3@Cz zG*6c>vK@NsH%rSqAL#L%f8yj!qE~;lgSw8&pZ!i6Usxf*iNj^!cm6{H#~!uchHbK? zMUAIOdeo?Xb%%l(h&*`kqH5x@m{x&zK?= zKm10=XRUAt{Nl+=E30VYsI5Da(sQM5)AltNH8%*q{-J}V^gB0oTPCUFTQ~siPU*6V z_!jOi(`Ps10UyFnxj&ig7+ZSn_X|gx~E>0>bsswukCFK@r^7O zpPCQd#raZo&l3`PXOoP6?#~jMb&6Jr(*&+$%APQ3c`n&L-hIP{riqto9daxC$o^Q` zN9?rI-tg4&&OJkucTs_h@2b{ozpJEB3UBzVBEZ%V!N6`V4> z=bn4?39M}51IYovY)&D2Kg))sD2r5##0OCO|GDv@e`=pc=C+{x4_~I_Fqa*}Sp|I;G#@=85 z`qv)&n!uu6dqFrs=2|-cKr&`VQ<0rno>&KlOcX(1L7WX z;}EaRHSH_-E#^Lg_jV z7-#jpsAc`MS%|=CoQc5US8lUe6 zKlnkn`%dgS7nvJC%EdP}3QrEf<=_UsCv!eNJ##ziE!`2i*k7<8f|!Dh@L8jtX$Af% zYXskg4{R+(%w7(H8N?CPTXKz8Vhdasdn`)veH4Ji!afGyGCL;1di(2N|5_9O?fh~F z`!Wzy5?jAfqFZ*0r?g1IM~~0>R!&Ll@>mTm65qNl<28~n(QUhQ;txrElFPQ=LE;0+ zeM1J=i|dWNy;>(yG?An|F-5Wr;)^R8msG2rqNKX+s%m}m*_yPX6cb6$cx{8a{vDYg ziN$pp19MN_cBM-asNSNmmfBD5?i#;K)YR%E5(zeUd8dMs%PpE{60fY$rIj*1Q(G^s zZ@-@|>(t&ZTqmR!5@1Q2{XK++xbhi!f38GaeB)MWdi8B_7ly@m*f3pgrpw%-ev|S? zB^S?*6 z31u@qwt-<(k=(cIPX-WU-0RV$vtnDfXEu!*3(<|+#2xha>%E~|RDbWIQuV7lr0SP{ zkmkj&^n3eJlA`L?+oj>TWs-O7SQ&83^;)GUXHzleRXb=KZ0Tz6skSyrMIy>>y&WV8 zcS)gmiV7qdQTEi(EG3tpCqc_tj_=s5Y`0k}GkJ^c=db9BmD2j|TJe_TOYrcKy(WV& zUm4F=a*$qES{KTZaG>p#-v)b`i(zpF|bRNq$r_J5`7*LO(EGtaA= zZ2Nd^slAkx%O(MytZ$I`?y7cMa&?&-$P^}HQAuXKl&G%N1eczaRVYD}YPZ3Z+h%=Y zETR6We500?t2J>WW4={uNNi8Fh_8Rok0X#ao2qD=m%0clFrZcuGzeZ4F36swzXg4S&)( zYm0U#2)W#;WC&bi+jlhy#2syzm$Da&< zR$I+e<;^#RK^!PWp{(Uz7Vu*f4t7)$E{tt_1L|_;ii85r$;+$kB5ks#08HBF;bQWs zQN(e+DhiP+p#za4%ma{;eS;RUXZKgnx`oZ6Q{Kk(6EG&_&74Z{1i47mvnkdL=hNpF z8Q*@4R__zfd-~Yc=i~n4kA`wYS3QfFK)ILX`P&|$E8B&YR{d*ld~8CwB6q#9-Gte6 zG+y4Tr7&}hd436WXYh&v^nCn==wV^v#{mm(yG&`22!X__u4mJzGSUX|D22(Y?5O#F z$)o6@@dH1ih|=wtB(^=Jbdw3UM5}TZWgjD@e2R}QzU=>t#2m+BvUq&*6d5$B>O}vd zz&;{Rio~EA`2I}w-WMZIzo9BHF*s_rk~$Ri5K0-Kp91%`mK!6`l%NeZC7X; zW3-f07Sa4b`JaSgXy3}@NZ<(VpRt= z3|1?wzX=6mmej6b>wLuKdgey)m$RP0unNzJiYc_UP5T~mG1bVp3l65<@Y%Do>Tvup zjh{+H5xL2DZ>aY+{!z)-XAP6`z4j)V2p?!d?3><~TbnE2zVp6S;FF@93nYZQ)@Sew zII{3I?9$R#2!rrQAS`@YSQCmi;WVLG(bCK69ToW~&^ zw*UqP>y*pu^H;EE9y8BLgu{>VG{s+Us;|8N&<6VEgn}k_k^T&(Il#YLh>M)Z;Ws)< zN4*MOCxqAgHr@q~*`#o{$A@Pg_MaI^S+6&ET7D9!{K}@9Y9Pe0+?3Y^k{erMf( zvfaj0s@s~g4s!J63~>=DtK6TWaf%S8>CT_|G5HtY2|C!jf_>9Q7BCf+r|wgZj%6yp zNU!+($o;(?4U!oHilW$-&CjOvXe?D-dCPT40VDY8=~(<8)FL~#<8p;7K4t4KesiNz z=2uy)O;dI`Y2sOJa?Ct(_X-`*QVUH+M|lhqZ`V))B2&4L`%H!1#ScO6bXZ?Jhwm(k z(YB4J$cmrS3Yz$~Ija^}Xfc)bQ#k(^NAjmXEl?*19m9x19)rqACPhbztwukXxt>h_ z*o@BCOHiF{f2)JUVXKPm18KZQOAZ-Xk>DU1%l&|XYQ>BByE}lH*0E3R>0QFNQH0HG z#*RY)Fuj?FeFq;am3_L}fRRkeb)J;*v84t)ec3#7%uu%;s_ec`I<5eLysrW;R5ISU zNh?-9irw(5dDj%HT;8ww4lJtQ&s2U5rlYtDz=>RH^I|HA2JckodbmchlBqrJh34Pa zc-{qM-TZlZCT)EG%1md1L;zwr!^FbILTIDp6=ATPoh6weL}20aO(xvsF;aAe5l6!00R74rUyAzU$e)E*X=2J@fZ)r3AqYOHbqwZm`w3)lzPgdp)7PeO|9-gh@ zS{DR?Uo)PB$ZeOuG<(Ep6**iP> zih(U>am_q0Ow5qwyz@LP%PLvDrTPbpC|ZOV1zgr|)pQyegL?*=#7^(pk)Tx8Eou22 zIX!b$b2o?BwuSq&)$81ZCp3q}NXlBRlod_ai(*%8pI&*Yc7)}ahElO5JCLQMiJ671 zWx}nyVZ2twdsNEW;Bm&#^VZtTeO<1KoJGZ=B;mCB@M@|dcmKR*jQ>7F{adeYPGZ(} zdQO&8|Ffbms}%g;nBFs@500hf-GF_(uhcF6m}B)@CT2P{O4HJbehPw;%rK|M>NTgl zyM8@DiCN^()Ss-oL<4|}mfhyvH$2gSjto-b6wj=yXRzGkaMNEO7ouKE6@%n0(u*zfCXu=%a&Sp5bGLM5~b77`;z#rKm3*(4|{U}#x)f?qN zh5I926C;5tyid>B5IBhl$TbcblVvyTg6eZa!P%Q#4TrcrlVCChyC@>)v4iqMW}?94 z#p6u^Y|b;22)gl351UD8lA&Egm*J)GecV+CY23v*U6`7KrQ)q-RRoA;_;SLyZ!(;% zk?FXePOo}o_F&g6R@h$NjfxxILS4k>H1jNL_1QX?B(uf&LYshny#AnT^Lo2RW%y2A zKmP^~l%eVpL~XYolWx7K=8&Oc-u3%8rm3pH5Md@&vF7d!0m`xj$Z7aDvPJ_kLM`hn zJh^$*0q+oZSVLAK(K>eq03{5r91!b7AGPB=YBEBL~TRuLP7sthbu21i~?@BC<;@S$@r41MJ4@6*kK;sa0X`S?pwLEOqYm% zV+W!|mnDI?0DVa*ey-o#F>^{Gn0Akm=wQL&;>c(eAXOK|vq*xkgO8Vw52+9O^1nn6 zDARB`0#K^Vn7h!?&x)+R%J-a~d(}Vjk?X*Se{UAO?}3Swya4H9s6eof*ap+B#cdbD z2Fb~^khzvK;57=zw>7kVOUw_syzBuE;WQ2gmHvX&=6XW=f@xl*!erO>@K&RN|z9=VK~d(xe<0W!}*!mBhcj9o{7SRhU`K z5WN*`54ffK8QAox0GR5Km+U$B%S);BW}VF&Sw7{IVwW+Cx#OKtjI#$)2u8p%hVunn z*B&x(sEf?Fknf(A#e%bV#LXRKbfSj_Qv~W0DO7HiZsvTR2#APO#yJ|Z8uqR5Xm)0j zjN+Sw?(TL0s2NIS$Po1>0oyLmEu$7)5g79JRMO=9@ABmf0kbVbu6@$ zWWvrO_|@3nQPZ)*F`FwH;JKf}YRQ`uoLl0(k{YIO(;uv>WH2B0s3Z&D4cs z1}h%Ke{6b%v-Ku)C0O8!p=`XE>E1;@!PPER2-q?i(>e0?$ej94(Lo-kiQ(aPab1Yf z_DnOh6mKywS(=fX3k>Dc9B=RfBRx33>?2atdIXylU%s`|VaD%^ z)ugcH1t4>XZD^*4VclA)bH;l%sMO4aRh*FUV-rl@C9igjbg|m5U`*&C2}onL!pN+= zI1NF$$n{|5za?TBUM%;FRb8};SWABYQTc_O^5vLVu=OI%LiuMb3J*s~0iq>0bru6ooc_`c7MJ9zF(Q z*C>!f?+Ana8aq2z;-|IgI3B6o(+h5_(f=z4&)Bp9xF=I`im2L2p)7O7h=Xjctu|cj z2lVp~w{>s+DotMz-so!X)TL2MUK=sz%p=Vi`mUc`SmJHjyaWH{ih&o|rE>_`r#b!T zNsdLvA&J&0x056LO{&1wwHLcxFPbf-)l)BfYc;@TNdyZgPtnMwW=xo0IGI$#sQw|n zZscgrB0qK3NG~tTi4(T9!#z^{<-0tfqvil6A@|+&q;;fv=ZRCq$C+yIoXUqj9(O-< zIttol##Mw_w@yO*v$`&qEhO&30Wl_Y-B^1a_J;5t%d$(QaHbI%>t)FByVW2o-@b+; z9`fLhb%37FZO$6ff12>}s&fw&QGb#DL9%Lw!W?Dk-kW8p6PddiRgDdLL+IhB^3nxm z??I=H??I0Nti1#Yyy|y^{Hy-yW}VWuzk31KhN15TZ!_eNJ`bMb4aRItY7}@eL?2bI z@^@LPS2kZ%zi+A1h6iC&IQY4~>mjV(y(?cgXH|p>r|I@PH2{kbI%6oJv)g+sLsUL% zRG~+_K_Z^y$F1hFiW@}rYP_dV6j%%fTlINaxjeLrsz^c!Cr*S$cg|J)ZWNfz0_KN_C&E@Z(^Ea&su+juV*Ylbk zbnd$DkVv<MV-}Z(&vj5vBuPle`UYQ ztM$zfpt8vLR7gpN1e}*^M?0NFh4!%OB@&ZIqvq`{a{r}hE!DnJJuThX!0}!(?`9EW z)ZDaYE_b7~6rD~!@>edwNVQwe*n+SE;nydfq{Vv;(mUh{a8{qM6_RF;a3%-;Pfmvn z*$qH;ufnzu)=?cFOQdCsXx->3Xddit=~FTj>A(z`yf38mIE%N=%vJ>U6uH$~d!)?OF3vJeUXEh3{ywG|-Ctrz zG_FM1*+S!C9RXmm0qp7aZ#3ZEUAop{$;=I~>;8lcB;=M+~ zMp1xm3<4t0M9a`x(NTwQ4;mDNaVW_|uqjK;xg!o zanK+4U7oxR!+MakZs1v}+2)B!>T)WnGwi@zV`qL1$Cq-if7M~3a4-J&Mj6v6wd~39 z3$$-9fx?O{-;TaK#a66*VMN#-gRFJgNm7zo+j{xAW}*#a9}OA1kWvc*7IG6jFLm)< z2~&7-0MBAt6o!)T*_@7iZmXda9srs;zs_U+~`p1hCi-T-!&dJ?Be zbNNiD(s>sMVdcO5+#)p+Ny!oc^{Ls1a172p<%qca0(Uo(GYlJ^nBYSx2cA}33t9G} zaE79$QVm;fxZU9TKHvXx-{Jl9siP+nl4-+6V&`jMEF?eE0tpVY&7|Evh z4K;I^8Lr?d-@ql^qs0_^y;3QvkZ;QHK?{rZ7egb*VRUH);A_99Z%f=g-xEyE!tp-6 zz9t}j1yp*%Cn7(~?+FGJb(eMbd7Jr!9wy5)6AWJ-Y;J^+O%yr*<~d|ce%bFZ@GGbH z!yRt59RU-7QR7WeQ0z2j{l6LEwcTEBJt{wKN$pjc6kWL!e7twcbM4) zk>;Vf&SrGlu3AaRQ)EU8i+nnhP0s@G3XL{<4T>*C{RNQi|6smnD~A z;EB{bIe;A<8_^18-a0!GugMIL6U&_a*+)87tGqhz6xI7{B{{`oqQG{6T3Kl}VT}_| z3}4Es2b0O5%|Vp0h3p(^MD3~g4Z7#r_x_Pa$5>#Z(N4wF6-EXmEW|}$QE>g^$W<%0 znQo;neQ_?|GAm~8VmIL;lD)Gw;z0WteahdNtu1gez^fLb?nTMMya11LnShK|?FaIY zoxAm(j;1!)SNq8ys^N4>iD&e zIT_YKJQKpzLF z6kUA;3<;EKwswZa_?`}Kfvcmo`h|B@&GeciwHNi7`)wN8!k^Dx4(U5V5&2C4FJL1U ztOwvb9RfWBvXGoTRtmc;+N$J%+RrpqLAv7|{$Py>nbt4DKW4-o=dH2i$Pt7lv(3i^ zj*N6ctUD=4Z5H^QgZysI2wLs~aApJ{saxi!u6hK6dEVV_2CrsqtyCax4mz{8i!Kol zb(27?x3NQ&9Lnscnr2Fa?UeSkTxe3tE{jIxr*M~$64x~Km1A6{5hlRYM9SiW4m@4@ zeRbE6u&0c)qyh87vN&Q-MgvlqFG;_z6Zfbzt&nK`y%b#%FIM7xc85KJ&f(l>Ne^%? zhg9vL?G6Z%2VGnW!g8&mB+}m)?HukjkgK$aD%U#nRa!03id#FmggFqQ^w`AH#Im@^ z%m!E~pH51R>%uPRsY2W^^2%IRBp91Lt6iD+$Fn?FJEhw-N@C}0?mud46vH<()Xm1} zU6d5>daPxN8%0`kWUFQ|rFY*lXKio00C}Bi(K~ake4o?FxSlMJ+)QAY%Ma#g>UG>}%s=qtT~DGNzalP} z6kjP~7`ksuh|M({4|&rapiXk#x4$Cf@eTb)N?LbJY|Ucko_n}<&Vss;X3?i7q3-BM-d$FaNJ zy2@4nZ7oB84!KX1IO6DTl-AZVdqsb1EGDb69w|z6i7KaP;d$_4z9Xf)^hydRs(hDi z6q}k1J~~yX7Rqq`XGU4rJ8vh#pKM)sbUy~RmJ;+A&0N$L3C@HJBQ|%VrTT4}b8b$p ztDbejit4Ho6b$#=9*>k>3AfUJ)bNyKS<{!pH6br0?pw$SdpDXkWURBYuW`QTOh29?!jH9cwE@$`wit zem`hUqpS7*K~A%7&`=!uM!!XFx97mf+$sX83Be+xZoB?b+Xwr^>QBWsU#QnFj8j!2 zncpPz(#s~qTbvPO$8(H?2vunDjX{LW>? z8?MonBD_$t`PoYx4r0RDT@+&}IqN7uR&ATJn;|2G{l)cmERRINgjf`W3HXr8Gu!pV z8c($o8ziN78G@vIaYi74gt71(LZ?XdLaZemDVe6g(QirB{pwG@ZHd|jiLm74fHMdS zfn9$N9o*;T^}g@YDvASMx1vhmKG;Cna=aMfzk_uFZ|TYcPo87hg7Lbv32~~J4}C&V z@WyB`2LOVST5Vmo30cn0WY)z#qcK4K29=(8K8I}3%kJ~2q|F=K4_^)B*<<{uz|XYk zEwxavRK;KUOc~Ml;@Abnz#~}|mAju^`k+0{Su96f@pV5tM)!ZJs)#&U8$tWB7xl|O47Te<$;R$1JDp%D z`;+tICDx^pd~!4}bDj#zQEG@1j8zug_PPyqRAG)8^1*nN%5ZoRlof= z!YJ(ce!ly=!_Dgv!pnG>;>25@calqS5_Hvlo@l{+Q^dy19X?T&HE6eKWMz!Llb(1` ziMKIb%M!N5w_gM^3w_7{M;lxLwSiD}dNJy*XQ$-VU!`}BNK{sEUZQrnNAA6*pAfmI z+e|6wL|JWTFkVM1$s~U|?YD+&_1nfa{O-eKT=Lfp7S@(K`*}8Crah`a+m}L#S4hD) zmAza6POR?F2Qj0Q**JKUZB@rmgWH+Odd~p2aJSHF7|@41N_Mg0z)(ieX69)IEf9SA z^I%LKmq=vqC$~i$9m?>BY}L0$C~wmiUsFuEu$I2sWYU3!FMyXa@!NGx(g!er2gQzl7PIE3UJwFn<^1hN) zU&lm3rrwJL87ufkphM>HHIIdkA~Z*}boKz7VKy-0>Dw}|ijvX_HBU9q7Z-GUqNM^8 z?047~7`YVF*W&Z2iR~^%k6q+Uw>L+KqjsfAzoAy{H^O0mFy~A!K)qK>S6X|_S`I}X zDi|1S@ioVGB&SzD4nTC?TJ%ADr8cWaAxgEzj{$=bsWbB~V!6MCJ8-81J7?BcNHX^> zr-)~+U8VpJ9L=w>*$Q>04I|9;*_fEh=LzwN4F{v{-_8;5yq{vHm7CUap!m}A4J|s> z@xYKG{pRh{C{$#=(US%b>GD!!-qtfqBUUySUp^*ZLOfj%bWXKUeHK{)LH9-?O)&kl z6rU%?LoPOv5=Jq#mY6#*6CXiBeh#w7l{2sHSYm0*TUJO_``PY{Mo7EU2I+>%a zVn5t5(`R!xP&3yh4kQuwUAL?39C-c@@9hD>dY?jAt+OsEaYtz%~JW&bj$J@-AWnGr(#cNdLxq??0DdJIf zC521uQdS?aewfuu$}sDnrDVJO?l_#}r<2upMPK6TlI}uFG@VAUU4@};bc!qbc^qr#017U5| z)|1@|(HYBmozhFC;)tL2FM6zwaCgsiC|?pKap(z}8_01^;Cfgb8ykOqF5js0N8N z2eu5GSWxM^H1tnTrKO&X^N;en_yEm!Mx+(<&ZaKOI5kh$_;bV=DOWG$L88yxJe42U z?k=tw5Nhd)DLpM$y0?5Gnsa_-oJ$xEK-V?iW3uszk~o(UJI*!J$Eee01~nq(59{U; zsmjVGzckonm^Icc1L?4mhrDTTRuVtRcw&72Z#Kx{{@&d$B&KqJG1SxDNr^lHrW z85x1P*z2q;k#mLebbYkU0Or|*!k4uCoB8&P4|gW!qvdBW zimuie_knGqZOqMUmPLEZSpN1ilugSukqLi6nfm{L%yjRhrGAo4u(Xt)yQ+n^<(rSc zCLOcc_hC{W-s2kMEg45x-euy>MuZ>6{7WDx&Hgx|`(EIBGnwunnmSme10$Nq4OI?i zyUhXPxp%d)aAv4o^E|$KGIF0+3B3^+|ZgR|GIP*KWzq>?B;Lszl@3@j8`HhnXH33LfhCd8wALu)b4O9aRufQdfW7 zkn?!h-!lDJb1N|E0ClUqJ!%x_T)gX5YCz3@Ja7s)e!xIwmKKkEO>bud_oK6eh{T?d z;=f=RTwRKJf)>rt9?AaQ(?rc=n@t3TIt~0Q`ml!P%h}6FGRmaLu5ZR;lM>?IzST58 z6-wdd+Raav#(cjwVfYEl7mM)%f8lix{BHh}I~e&D(_c*fJFo2!-nV#PxhU02mCP+H zU_Y`nqBk;yo#g}Mv3TA#a<3JQ@zz25ftOcvlE7i8wFO>&z5#rsqi@xAkw6oJy+my6O=BqmV54OLuBM`SvP3eY;n95yZU^nUotav(fg5$K{ z66kBT1k9D$1|ie(Dm6HpU@89x#6DKJiGgLvht3qetiz_J8a$#d293=$ z7scC}f^lIF%mT1BJ*&wzPweWU?x549rwzqO=w{o-qsOU@&7;kwOYx@rX@V18lLGon zdj9oaqHMny#nwVmdkA4mB4!;ZPBF9A4RSF$DD*gFp5-W_SiYE8oC0d`Ui!SZo~=W; zNtPeo-=tZe*hTArXH?YtbVJ3huh*V%(-ApPe&Pje++(O%cl$iSxW|YA&&{?qP*w4+ zy~0RU-Fs1HQR0h%Ti5RoDQ(sq^9<{ud?evm={eAFy9=p?9=&IyqvD6 z);+2uXp+Ya@!gm2Ct|K`G|+epR8tj$KDPhOJ#>~Cx{-SY{mS6UH2Y3Vh2CnnW^2T5 zAw#fR*h>2`Qiq7zrjg}Egis8f`#E)4kxZY2k+Sps%av459Uk^^lOTdJI>y8Th zz~EHwdi=Ra7PV}ta#Vhla~1{?ZBA4sN3m~1mVjS+;j-CXX8R>g)e*EX4$?-ZI)R4k4|spej6miw*epO_s?twwb#L!j%bobQA6&;^=_5LgoU{ zax6$a(V}wm;IK}Xg>o^*dgD0O=VJyz)^qQikb3k8bzM}0!3&tI^k&CA$n@E;Q?XK?X02_ym!>Gx63n)EGf|V3kOyG+ouX?`Pu*!{Q!UM-m)ia$|FAm>_OlsdXKb+kAz>;XGlUh>t~cbZT7*mn7%yE$ z*RQ?J*A$vo2`RVD%R;9Mv*Yjh*T8zZd(J}N+4JXLOuJ(`xk}oy=@-)A6n)Y z>r!@m|I7z&&htHN7&zu)Qaa0LSi6%q>VVjY%P@QI!7<@h_ zc!)^K=OVt?yvn)%djfy?j7?7V-d&%XbVX8eLT?;%ME~ammo6^Z*A=Tj?kVB*u%y9b z%kL6N2kU?K{m&}9dYl%(JfI?^gn_P;IC=FE1SO?$v0>|NR{K?F^ZZhzJvNLBIFQe|}9w`;y7lY!jxgF5?Et zQ}_FyPdjpe8SqEBx?1)r>pug+ARUwY3y~Z{0Etm_&i=2TKl>h?TNEcjogQ0;3S6&FAu zuZwigSL zB4g8{t2%9gqchGDqGEk9kv6`<$Ko~lX9!JBrD6&GGZ6o3+*!7*9y@!#;5LBL^xD+w z0Aj}h+iDC?k>Z%Yt#>7utDeKb*A_N1*I|PQ&w(0%j@F8#pMG*mJU=#N> zGwTP`wuPvJuVI&2pC^z&E=y$CR+Ih$D@zLKaK_#}??K%CT0m0FKUqllRZPgGaCFsR z3mxK64xW&~4Z!pVLPcDY2Z#S!)a5?Fo*u*%GHUvHLKn-g zm5v%>d7j{e26xr%S@bk`b$?9<*^OmOXT6T*bI(ObL(NNR0Z%l8)OtWaX_F%aWXq9a z446C#)cCkEwJJUmH%@ViId@Jbb^|0`-LS4WJ>VFXON_n?JI(y{y%<)OKQKOVw9qL3 zOMjHVlpfNSA1E2>aQT(&K7=c7#4-k)jZ<89)RPb)Pe%auk+C!6DXF)H4%hu+jO ztaV7$Z)u?JloJ0zU1r+^4BURkX1op^1fTm-WS#PP!|dq6_+fH92dx>G@V&qQI#K0J7$%htln1+sY>$ z7?Mk6H?fR>`7g}DmO_=?i!UTbWcjIMX7cDRDs(-*EmoIokc*GSmO*J|&9FuuIcgo8$Ru&Pc%u~=c<&BPuQR@!hivKVN;cztE;gA5l1__E)qg({tpD}P+W)n$LNY8-%ASTAw+lr;v=@s3 z+Y53`E%)gUF-{o~BJ2#?GyxEJ#SeJjz4!dqRo4*}U@wy9BM*r3xST2PZcD|$N9KIa z4WLusm&6d6QFr$B(DC1F@L z36=CX&*_dITU4$@z>7FTdFR#L{Y9zzyKUF*6y60!!_wvZ%HQ|2b5)`5>Xx*F;V`~Q zftKZpnL}d8^%)y&QX=iN#~yGxklb(qPhgXk_trSLh$*hhMmC0NQy*WBJ~DP&XG}W> z*COsE!GXwCp1Armqs{1H7E<^y*sBaWwScIq$~cDVM{`+Y z1hW}1`c$6xH~9F0*@dX9dNsNeZpmX;Obudp>Oz5$WKn%e;S)_V#Ln@K z(q(=ygNl+JfRf+dIjvNq^@U1eZ^IY|?%V%bF$aJqt*4gKNl0|>-mVK1}+BlUcBgcjHhjzhdTkrT9!Z?(q z^Fg;_K%%e1ZUAm><(r;FNf@A~J1$H~hsQI(@XPoU1qi!<-iW(Xj4x8lJ#5}Nx@Wrr zarMxNa9^N?_(dnj6G2eB-&FapQJm@o9|%h3FZ^UGAis-H_2M>|Xuiuf-se~MO@6Me zL2xJkjumNrkY-$C+jdGKSVI-O_0XBMhMZjU0~h6!KADl_vsIN;I;3rn$d)Pm%cpG0 z7=yhhP3@u*YJ=lr7)o>xr!P7i`ARbX=TLa}46y-RQ9rINX)%{Y zyYAovv_^44-b<#{|2n$tqX8rDCQ&fIlhoKx#ZScDpfjG4>*xv~zvWiFdr*5Adw@q$ zC9C}rJCw-j8d;nF>4Vwq|5r^y3yQ!1)_++NeX z`9ot2oTY%*Jy&#WXZHOW*wIiSPfHb8)f<<1`FW8A#*GvL|6M41>d_4z>j+b%gWg&J z`Rz654|xy$?Ky$aP@feLZ)7q{-R+N<^1Rfa28F8AIY_m~G4 z={FoSe(Xh;eq$B2sJwtneHKi-N@5`W7={5%u>y@!MK(%I@vY3TahTtfr!3p6$>jU(#J5z9E6 z$6WwF{PnU-f2#=~YyzszeJF5!yyp$pju>F+o(cGq|R{>y(6YvT)~wp3+x z(Qb!&jL`s4WryYWo%)kE*ZaH_^}AJlMyNx*1jbpUJUtoJ_H2atS+XJ=ty|!8hH9Sy zF$;|Ro}qMyR{NL2T_dLl zjyo(2K49z$J_6gg!q{SBIpzPHT<+Tb+nSS%z0;;f91cc;TT-GKm}5d}K#^B702&F# zR1PVzIxT=sgSvD|;yV(g|G!b!33B{O%9pjVdtJT~cZ)a)eHuMcqR5|Y4>R7Yl^a=n z|CuDhkS+=gPNRzxWKm{k@DXW!yti$WV1z`PcT#btr8>53IAWPd(yCz+Q`e$%j?fy7 zsqZe}pzm-#yS`JU+=B7FR&XD<+5u>JttOXmv>g7-I1N zSHvKkx3Poau`=45KagfS7u})4ZLfM1!m$5q1Bz4A9iO~GUMFbV6%?Y@YXn)MU%eNL0Ux44 zcBj=o7s!}QFCN5p{VE>WEiRz#r?t(y{}ff&xbDT6%C9rx?h-rTEyx5Riu5~O=SP)E z%a;VGsR4o{^(g3p`YI;qboyb%{_i1JEi0WsC4K9GMBC!0t@rMb-v*DhJ}+19yaZX5 z^%@rFk9W+mBC8n*TplQF?zGJE3LBSkweH7=a#GyEzsoRWE__y19+Yn`W)n2l!v<*; zl^A^*kxSz(_4r~Re7#1PY5ThepHt<)TyjunSXz#=TiIBj&XTU_A#4-x{2dH8hdk3t z_iv*!!_H*;ck>@}WcF;?S`V?*bq|bBt~-#EAU&>C^=<((HR~H@)UHu9MP%WT0e{Pr zy=_)+s06FeIYz)5x#cp%Z@@V!bdU}GhU-WC*4VFYSvPrF&C>a%P{v^nnztZ%)k*L; z{8TodnhoncTYB0U5wT2>O15ok$}UJphx#Q~GYo$_R4iS6QtH=rvZh_I>SHOGbKWGV z9brB&DL?Pm#~lB2_(-dipKzdpQAb(n*VM?U!g|qRLuv6IOC(Tj*i7f z&h+%OHY4)(qi?~c|GVBBL)Jab&x4BgC53Fv_+Sg|_7nGnEwr9kzvWzHv7IRXaj>7t*|;BA7_+;g@@O8OMnjO*JZq}t7Haf3Xw>hzw-l>M?laSwf} zC$(uRv|2Xd{kAD123jOiDkSyA{po_oVeD#zFv#rD^J+P8y?WLO#eN$Bx308b zg2i(f1*~msNFOdVAq-l)8$Lk);Qwbk> znm!k!05bCv!2CQQ{OC#3$9p;FV6xH{JoB0-a%4ogZaX`%FCN-KV%o)+lQfclN(H{@ zHF)?u(^@sD&+M^R7N~AdsH&mSE5p_Vbl4n-EidQ9diK3zDV+B!GW2=!7f*e}vo%C# zi)M^x;Fsq84@ox6KUV|aP@fo|Z4JM;G+$_R+nBriqM}IWCxbbRR3WB{0!!GWltVu0 z-fSe=81K(i0U|p4uY|u2QBHdtHuXDXGlCwjjNCSpUHXozDbDt1HE{X2D7(A6%}%Zk zTORfGy{=7YW}cvX2C-Z&dV4#Ne>CeI(x+EQd1v5x><@#%;#){+2zU-F20@a3Gurr_ zBML~OWoN*ptMhTvvt>;IU5nnZs=g zZL9yX-V^&}p!4|p`nr7ehd__>tW^%r7Ce9}RkTp~9tmf=b>bOTe$&ASVlJ=+l|;?F zY*(&uM8M>dX@c{$qe{7o+xb9r$I)*XdB1pm|3w>_%6v^vPBktQl64ouSH5@ZEz?*l z=3A!}jI*Z%57-Js0NB`UbcuR6yz{bbrgg*yPCp&{*C=7fl+(}A7;sABM9n?93C}cd|CTWzftp`;SglBSL94Grv1DnIBglJg3W!un-R(yJt{B2vd;0GnDza+ zln}MKUF!4W7p-K!7$a1oz{-mH`m8oB_tiwi#EH8~A4qquG9y6ICCxWIbAc1Bbt&Et zZiEmp&F=dbxG_@XZW0HLr}B$~cD_lTC*Ag2>481P4F@~7$rif(?0>;(`#mtb{sQ-`7M2Z&kbe95^JfQEkK2}oAkTGDIs2Er#?yh5t;`7N z68)yLXH1FcNj{Yd=viK*ZfjAJf=%ZWI`l%FNJBw!N`@ZgHCWJsBziN>9yJ^`Gyhd( z;<}ia`mMhA{dsx+huN)uy#BR@!B!j8cP2{g9rVsP$?r&f4z|y{`zs&rbX}Y6j`sltE`jUV#BOE zp3@|x?0YHbq*e0UsDki(P_J1{58D%El#cj)+_%2 zBiAXyx$#S$|A_{9+Gbutg2&EJDvbNZAEP8ps?ak&y+Q%(Pd@iA3EqeX+2>kB5k#JS z63;p%36x1t`C%(6)%}J`2f$q=`IT^BFlG>-wF0ZO5U-UjRASC%W|H! z&wH>7u4u-D%xQ&w`9V%KjcGP#0e^rZc2gr@B9irx?lpl6fk_gQ5zRsX>mHMyJfAW$ z+GM=LL{P$Q7Cz#B3ER8BfY~ZMZdLi5<*t!}hO<5}K~JA-`lwn_x1+a;Ze|TYNjMd$ zX#&ijsQ(>$boRy8^;$OEnsyizT1VCk;leFlyxZVm;XgnsQL%THsa$Ms1X6fKE+Sn^ zM^`A<(YGhKLvIT!6WChrM(&6M*#vsLSuvO8AB|0^pLyb3c8heeJ8a0VPRX1%ZTNPr zA=e`3%B$Tl$`xq`YB5Uw)pmJT(!+0D$$CF9*=(nb-fwV`0@atqcDT^l?mj%Ke<1b4 z+oSeZH7iQ!E!3*$^CmH>nRnJHS|Vz^n6a=QQ$k`%b`4z!9Tb8JzjFnAkawh$VC2;d zB3+(*^hy4m^!;{=xZ6MI9=9CZARrgT9Ld5Iabu_y^yNQCK<}T8HGqhzAWi2yUEYO7zTx1&@9` zk^E{xMNN)o+2OoLRJa<%58hEnZ?V=4q#UB|$uhaSI{qRraZAVlTB+6blfe~IA7N_C zb%s2Z%lsZ&>)l0?yIoGY~tb(p{NPix&)XKGk z&bpmP!!ojvktr1qr**jFB|vADh{1WvGjkqL?;M9q|LD~Oq7JS__oaH|fQnFTyUO>{ zgg$$YjNL_H1c#5pZ6_p|&Sru^3d{1-WJa4GH@`f(|NB_9t+`LiMx{>1yWz~4Rx$9-z?tmCm1 zrA#$F)FBDj`RN`p@{g3Tgn3-Mf;xV^HlpVI?5Fi3Bt7L-k)V}_6!(ZKUPxho36~=I zWE0%BEoz8kZMQT}6oZ0EW)LU=ya359>nh7@k>ZW91>Ggc7~Ov3%v$;3$hSXVt65}T z;x25;ujh$hamyPby-L3fizuWqQ5GUrJ0 zJ@C;Cv8NeZ=2F$-hQ`54l&uwg*uO%?=;W&ujjGov=gGI%>1wTD)$~|%XKkabJMJ#HEq9{4pIw97B+LVwAxXb@JGzcs zo+gs&JaR;zq^4$E12mJq@LDzhw3Th|J1nL}7yl3kC)8Ecd--eLN>;JDW6V2AHwcp&4}(4Q;g zBl^vMF=b|(QhT~mZ;3T#nimg(lF4V(K_F9!?Bi+Y`CK)0Os{Q)N+D8ZL841^xN&cG zCMKF;i@{1Cmnwiw+9nf6I(&QO?3Z@%V9^jg%yIk;>a{}`peC!_W%)!aB~abP=#wEh zZ+FHE{rat8%8}if1oEa<|s1{fACWk|{2=A#HrE=SXCCw_?-7{S7UiV8h~j z^-~6|YXEgPEFGZQ7YrH>{u{bYz$6d+rcj{8bNf#_T|fa?+GXMYQFcq~Rd=N?4;H(~ ztW(3%v;a~lZu$K%FGtcaP)BSFef+$sn0ocEgIgfuzZLqTIF%W| zW$R=SZ_z%JS(pERTkGh8S_;5mh2qj7bzcGFlLQRiAT%LKZ4#Pw6MQAl@PJKPG?qYmnb*{G)*+DlcEcbRtR%LfzFzb zZb193()tKm4$_PN9At7@??|bLAZw@D;8bB73Vj?ca0Ycs4x2-+jc6$&prVt3@%SE`ej*%OLf4|I)#j(Z;X0Xr+%!{2FzGMDS572j zouK}NAF}hBIiGX_{esJ0pun=Yh6JVSHPfPeXV5_3R{6I7->^R}#6WW;q5~Q*L){gO zK%2{a2uD+xsSjW|qE4CIVw-)RBaR=lGC2(soU8chiWRBlJ2&2Yoo;2UlrR7ti9KPG z_%}OR{?_B*E4orB1}E9^V?GyW7;T#*VFvNC7I@N59v#Z++n|&kOt^qc%0ckcX9>a z32u$&LOV47+S@)Y&?GY?h)Aa5am)|UNh@?jP`#?TMwwGPIASZDlhwS``>s{P5uksW3Ms zko<4_xV6Q9@SvkhgEwG_@GCj^ZfXhb3mm`PNMY%`bUkMCQ+!)bXF)!Jj6-ks!CEkxQRpm9&zH((GA^H{=vFv%Zg;P165_a30G}JWn?vtKnFO_hyubTxFdz z-ANmMwVRjSH;c1~9fc>02z5k2N2KE4{9o}@Cj}9vX;PKXA0aPn)x4ko1zFvtQog|&3IMYGl0!v_sQ$5-2VaMsa%pks8taQk69<}41p z3eXOo0lO2$Q5HSn8JGPr)XCzzMaeYn+kQ(QCN=kS8p_L`x&h<~&WXuMzj!<>j3`={ z*6Otz66s_4iBq59*E%|hja!)xq$bTD)UNOJv}Hu9tp}6Nhw2>XYI*_sV9r@1a9fL= z0Lsbyt z0qy9dt;FDIYU4r8@W>@Ho^fU8$NKtuFQCrY4yBbJ0PKyZtK6(%{tjR#_1(WFm5lXy z+?fnw>Wj`+uD92E6z9lx{>y=>CPqN2GFMvpagOLA5_^_?1B~oO9Jv8vr-|k9Y8O!l z$%^l(=KALl;{T>r-i>DdI&PCXY8AF=X#}*hkxRs~m+k2#kj&G&_ytsSj<4Uo(E|J4 zmBQHy#=qE~KBsdFJrbm*rj7!7^WMu#Kn%*>`StD1#ER5m?IbDC^BW&E?oO6+0&+}4 zQ9nJP2SrK1x5_;hU6*l5!*gyAm}t-8-9e! z5*s@^vEBxhH=p%6+dPx+Z49oRkGD>hNMxSvo&XAJ6d)))*}W?-D^vT|u@h}1&|Y80 zNukqgjmbDP1nw@~C_ZiVOw=a0?BxfX;ZfPR zdeo1P^#Le}?PsmpjBlIX7aMYVZVU2S0Oc|2_SP4E4@5hEorw&S$laP>7w1R`beL6J zDl6q#SM)7r$u=Pl=ZiYJ;3-W)R(;{+4k`8VCO7Ziy~{kWC~j?CtffZ#0I$L!#6WY% z#fL6zDz-a@eT8Z2TgtTq7=DhvQHM}+6=XGWvCM5%KHhI%4|f9(Ts!G0wCD z=JkvN_Vu&_uJ?=sp7*o^LGz3QQFGH7uF0MVUXHP3SlszM_BX2m_%3bva@QVXIYajz zYq@Fn9_L~ve#3NkMc473@a;3YvS*B=6R~V>%e2Qqe9=*`PLy{61~~sSdw;c5-jY0e zBQl{gP7y&+4Nstw8jpJ4jedhLuD(g-!Z`R+qeBpw<9%Stsf$(hBQi$~=4u|nq(d}& z2$PHm4#xPQly*c1s5b9xNg=RE(JtZ&Ao-fPLntbQzx|GiOrkc(LsFkHd*HnxcWGEPH^DMvMn>ygXXP_pf{m(At(2UT=PLU_1~sN;!M#dimI+C zQiJgPfwPe{7KNb%!$!dVP)jw>E@^v1QQO2JBknbb-4>FmD5&S_*7t83Fq6MXHo*qb-#(i(vqB#|7>Gqhn=hSmXlZ}hdil8cA zBO=JIdM!OZzn3Y^^Y<>i#z6BsB}mpK`l~Xp%jDWI`0IpoWyR7c za{jKTV)+WTiLwHfIR!+B?uL8+hvGvFDdyGq5!tycJ})Tv$v11L{()p(V#OA>>Si%U z5C$z6#k2w?<^?Xbz?ci}NUpk z0d6;43){Dh8-5!uI!u>xC3WgH-RticczP^dJx-Y1mDz*ZzM{|C z0!e|KL@7psqI?H3kun}yQ>6qorz#T$HCmfZy{EW7xQUKl)f}tT$R7yMwk!vV- zL-1o`*DmZWI)8(030EzcsPD?1ECy>_sjqk)WW@Y;&8qpDx7^*Co>gPX{i40@fsFjY zKOahzH1r=aSw&oF)-7AfHrMN2VZuhJi7ZeuW8m46&V0}gm(~*%R_CtS@IV~S4o$%x znXaAiAR;CD%Rc-^U>5^70v5J7xKwbHN-yW4@KAK(63uGk>;2UN;zk!xayePv84sO$ z6S#qiGM{MvGU(Px2p(4&3=sYuigMuBs)uTNJ+WS8N011hysGAifL{bqCniP-a{lIF_gLHa-S( zT%W*5brD{-7X~yJ;%%<+{O5Bo*Y>xnOG=Cz48rX{?;RgJ;xQwGpo|rE{X~cJ(MF9O zF-otCFhK4*H?{Udu|LNo5sp4x)Ed$3L$(W#@|bCgTy)bw*mqcbMOg*6XKy@iEJxBs z9A5YM0b#%!1{VLWxlmA~Xmb;R@t1)8r}=Vqz16eikm*DO8 zg4*X$;q(rJL}m=thN_R3P7i-dc-^cfhrHIV`WO2c@?KO$F(Km;(Qa>b=1E7~4aiOi zs{(`@igJV>EGvH|k;{xM9o`O?NNqL&n=i3LxipK#H0n}|Tvka zmQcBeftWxk!bRw%C`tNv;qCf*%q{dtd~$_FHE$JK<-pS7z&2LV$ku68;%?fZJgb5z zuzo(t_OSy`3)+HrOY8YT&I7A_SFS~$@R?NaanX0{_K4Lak$j2>q0)C~)OFgv{7YwS zK1XK@CzqMo@-nBl?B;ixepMG1lM(+bt&(yPiEo^uiLX@;JQshAqh(_x#P8fZ*9DM) zR$T^G9%^fzt{;samGY=?WLLpLTzk-O38kUxf+}8X!ZA58K69$d1wleslKi7iK2AE; zgZl2W;Lnf8AFV!Zy1(A1jWT)^A&4V{h%ClXdddRM{%H!R2R@9|BwEe|tBq?eEZ@Lo zKt!EpDcl66+&Z@H>_z}S5AyC|ih=g^Kvm4=nCG)}k+Q*6IGCkIDM~&iOL_Jul^f80t{_Ba(_cGnESotvcutcB@_QQcycu>yPyHE5n*(8O6?#=AY)k>EkS4hp6Hxl>-N4D2GL|4N{fC4yhlW59&^@^HGKxF7w*IVdjeC_{2HFQa zrO5NW;GHM0Z=Yu&L1=nLY9l+BgIX0(ui$ddFbKm9pZVwenN#4!?SvXbX?2`TUU>Kr zd$3_%H@KHGKl-4wpcL~wV9k{2{ruuu`@HO!@F+>HPvj-^vO={lZUfPJxqrFHxhxp^Xwr+3B5IhoAMvV7P@f&rNHZ zz8p9GdGqk-k3@ePCqdxgRUs@Y`hm1Z#{cx+-` z%Hli2n$Nmj992^uBXl>I)|(yK2>2JpU;?iNu%JthIq&6K*C`1gjsjn-JbMLpos@*o_x_KVi5GviEN5di@4XeR@jJ=uw~gNP(0ENx7;(-BzgHHN;bSR z%*TlcNcd1sF185oCfA!B*VsF>7T^$Ej?&i+F3dR2foDDYcqw(wm>YWx(8Mb)`x!MY zz(3}p>*QE`kzZTQe>XtBwpxLlQXLcFUcx~Ynys@Bi<t)$B`cymJDywfiJW*v?agBUdxEBx8FXA)Qvn)WFxwM zvTpdDwT+v>|E~p^d)Tw^Gk2_Y(N_*%|G4p{e6-~_RlA|9n?c<|AkQ3iJ6v9BKcWxIvhNn zEFAYa3t*K-7bWg_KdOGzvXvC{c>Yj-``&0xUZ{(770USs6DdJw>c3X#^c!?^KD)2U zvAE_tDE~p(o1XA|u)8w(N$AqIdis-fU}G$FU$4tqGE{1?3TcRrlA2e00%n?}504~h zeMwTQJx{4foK-RqzEyw8k`efg9UL~Oa&sKMv7B(ybL9OL>S{l^NW#PPm~aWuCmOvN zH$?ag2${bC3zKC4z~3VBJ)H;?>GXt9w#PgMk}>tF9_2Onj8cA&#XlKgal`KvT(8g@ zr~lJAdC6rj*ey^N&8h3)`9HS!lFQ=-kGUKXenoO2kXxhxpt zqak(D@(?{S?S*dI{{43&Ud$=oZ3AGb9Xky>3;r*ZC=#AaHD;sRQ2&e+GDeeoxV+;yf(9cAB<2v;h@Fnh9A{zLb(&foxc_`n@vZ(=^Y^xkOfTm5wz&mBA+SNNZsX zzYq!TQ}=c_knItZma=<3OC9-0spFsdGCEA;z&Tr zeOIw+@?+i|3|Evp5!$zuTKUk^Ocz8%%Mr;GGW$_du_$~X%r5#Y$~p`8e-0~ou?#Rl zvuWG!;Mn)~{ZZRxCf%NRs2AjMZ?{%ovX-MiOs zPd?%&5_;gr>mx;Isj+9n-o?)H+P{H5yv4@=E2^{p?R>Noe#)HC?Ycuz^O8h-B(qr? zI;TfH@8qL&V6KM{!M+O>I6wHq+8x1ofY^l7JrdP~5O)qHb7qY}*uW+wb*l&RSc+%4 z(+A*MjIa84aW{?&p)F27D+T_00D$tsiP~U0rtBZg$7|XF*U4(M*2=G)bsn>D#&kRP z2>Q*SQ)~Tl>|}1U5ZC`)c+it&pK#A0pZSzV-cM`UHHMHZDVdk*YU~GpR21I}yYK1i z`J*|x@fTh5ASSMP;I8BKo7Sh$zh$)Zt6RjxvirZS7Q5%xv^a5#h6_99sso!@Hz`mu zNN^Tvlt9O=HBLp@{z%}GnI01Siq55oN`oU)8IZ!qqPuisOF#j03( zA)AreGpf)#{`S9?L#kAW<^B>}k7%{aI@aG7rau4D5m!(QdL)?#K2`CZRloI?y0l!< z92QtZXuE*q=R5mS^f`u8`cVQJ(G`sSj;Mb-J6?inA1m~%talSF1PKELQG<07FJ|8E z#FuRy`TLP|agFJ3rIrtS=FSah$;+)t^)vXCi*o$W98$4K0R~mErs5Q#srZY*eXUSD z!aPR5vqT6*HlXGp?FXEJ)wI1d;*zdAWX#wREaS8S2Gu+SA^gOHfQ_wO*}V5vrGIU< ziUsex0Fr34T8Bpzi)ET=k(me-E}~0q(OK*Zo#SFud2;F84`i5WJ0dx0qeb4q55=#S zEb{e&5>cr=PL8K7ln$M}b~z)vErM&8j$auOhhEr>MZYB1Ldi6sA7VBaIT1Y;e~ajK zR1lvmRW)C^EW1uPJCc+1a;4-;{H%?We>4RR!OA3;u${-e{jOK zj(m?q5X&-LAL5YWw21DyfOfzh zjUF#pke_95S!f0QU(PJLWZg$s?~(-k4dEsTrlNI^mfV(|NOfu2OjWULOEo82FfNp; zSU@`849@c$61Z|*oh!k_Lgj6?2GqEUIy*BZAKcY#dmJz(%8&&jj2wk;+%LX#Q;wh$;cwql0o-d&srK@k2AyhS&!}Nh zVLf$}G>7A4iGff4Wly(cOkv^7eHs7DixmUB*joEpH(QUB^;uS|3qZ|snIMEHrYE#4 zyUwB`d7Nk4LX#k2Mls*dN z<0+lR+@fr{>Ozi7tdvZ}BpCE^0(@51Do=x1vnA_P?6Vm9Nn-vS94yanYGEVgVgjKD zgKyB-iDW?Fq0`VdXOmWozFHS3?)@7E>h(O+(Rg6Vt2!Hg5V*WC8qTp$9IfYix#S^+ zK}DENXIuEwoQ}g=*P$!OayWQ{<&}OyNfqSPms4w}kIf}!7)U!gu+4FSSr-s>weAkH zTHTao@?A6C=&aqqbzh5JPR0)<6gL9%R%Knq2i$IWuPE$PTTL*B$ndWU&wc zfDe1kJEKTD82xyqZm~Tk-4t-YV$=1fUjwm=nV5y57fkO_Tf|bEYE8kb5d!CG0 zG4e;CS5aPPSkogb%AWyI|9?rH=dky5Z6pg~e#HipVyr#Q+6oj%lkM{jb|*UhZaq#0 z`68GG6aT3XV-piqBs?wdA(k3}1-1P1cHZI#3Bs{MMJu}SL$Y2dm(kr3eRfE*AG^VeLM2q>oZpgNu7dg%73{I4o!be5k0~SSAz>jIg z#cufFcDP`tGhNLEK1{q7ss#S@^?wag+NWJSuD~efc4gRjxs;&K&x@^qiIWeQTZLUv zn=bhfW-8lo`_?Y=!leVz80m1X>}daO92jMGKSBRh)C++>XdnQvwXzcM&?eaJ&79fu z>5Zv9jE**1hO++*h(k9lZ$mR(ns-a`iiwzBGCzqBJ13S}2UED-6@{F93c38*j{tCjSYlqaAJoSDVI{fMB3Q+=At?8Ugops0XP!QDFwDl zT`yylLht8EgCZGUFDgxu9C?~sc)WLWt9CP(Us19Sfs<|UcJuJVs;kHI1kmfo*fE>6 z_JpfNYU-4{A*wHGZSMD-s1Bq#7MrLLVe>c5%wUeC5}fV?moPKa#&?Q!8(ak|&V;jT zQH9XL_Pm!H!1pc6t!$@mic1v?#p0Wm*s9RGFX_07otxq=kaMYJMgE5*Li-qn*~ubC zSllUsNA#Y2*lm>;>eJy|a8 zP0JqX-&r1+$H=#?=g6(TEaexx*igO1ggjd}k*_L&7z4p5#Tx>?#!m4m$UaBNg%c~r zwQ^|dUkhspc|3xU6SbiDwF^N1T zSoqzDz^;L-B-6p{6mza%DydD-4sJgke8d~cL6|z75oAFo7)eFD+vo7JS_&aZxY5{I z<4f@kG9G`p%EUgg5 zY0jgmgai#0sU`o8=Bc!^2C-rjpgu5>61Ydo_b5s-#vD)aBnp+E(kfuLEVx3~LOBaC zrK*=M!4cnMUxz46@UtLG%z+V)tq$0&y#8umJ?s3FtNEo}_-yPwU=15C0~Reu0PgrB zoLj)-tz47Yi@ee3z$9!KRof2!!Dz+NLR0SGZs zY(IcKhxOis7?rVZpwfu2mCtPudQ4aIBy9%Q=zpRyhx7w;1l`0jy+=TS-(wuR7TV;C zn7`ONGewFU4ZI*e$I!O^kwcCXSj*cco6ZPz!oa3a9YXCRUZT zfxdJ|^QIT5Zxg^_`P1d5 zXr_@W6n2tS9dSSG)y5yH8d*a%zk9SJ@&Gt{q&+*cuaZ{bZdAi_(mCan8R~QFSY%gt<$)zm?^sfE>qd3LfR`h zCXMyI~{%RWHHT=NDu)NJH#>8BjnYwkU`I_yYK^yo*7yA1!rvKafB z&(`LMQbs_t6aL6JWKnp#NRIuZYT^GITXv$?)G2~u#!*x@#`1~df%OdvIZ)5(kkg4- z2jcgm&QFeRoIO{L3=n@T*xG<&rD5j@qd2JTo9owli_kH&dZJ?JaZSk*l|UNi+LMw& ze+DB-7qAEx#M)S$1#D86#qe(Uo?kGAD8wKmHz zIcTz*iVKkO+;YjT7B7iP?Yisk(z?2wvtJ~arWEn+`EE`<{BZ*|^v zgW|tn>tLg>L!psmf%Q?$)3HY8@4kO*uF_J3Noa>iZ-{`pTJ}3UUMvf?Ul#H=50LzkF?Oke}3fvw!1=9CZ(s4zaxmFo}7+2o%MA8?~j`Non zvKu})X|>V$9(R>2!XDPVT^B7I-}x3T&4UER{l@@-JiL}3eJWZi*Vxe`ZXL#1bajkr zd&={@)shbM`Zv-O>F!3N`U^91evv!wi#E&JPmdk3TBZG3r9kWbOn(Wtbr?KP^-WkL zZa#g#uxP`p4QUK|v{bkJUN|BsA-EwK5jr=GH-nKQ}QtAPGRPMfyUHfE3RnB zx>B>l+!Q4oyj|*t5Vo~t_^tITB>gwQ(RDOfNqqei74}H**F8TP0@L9DKk?ZP2MP!GnBtAJm1*qH2qF+A%T2Yj zy;ie!@tuOVjw3cq!-63?GW}+BHug*CWkx?nx5~9f2;?c9==f`K+%eW(0T^vvKWkB` z3`-G~D3d^gdk+VAK0l{_Qp`ZgGtUM=)c=mU;M3g2PD7>o^qZv7&Bap*0(;xtv~mjY zuE5y4wjOBbbtuR-hQ7S1OitN8?NqJw5I0z%4QL8eE-bLj*T2scapg9(tI)hknFd7P zKB$Uocat)>lW74+HidWKjiXUrC^u2>Fr(U_S;gmlEvEZ6@| z-z!N7_}8!w6D5l9wH_;O9J4jw0=c0;1Z3^)NR$<5WDRz}ef-=Wa}vgm5|Q zzhWu^gh~f{#Trl)Sj-%YIm^gjJmcVVf>(5$gE8e(BHPHIF$n=_qYdFz@?uov zym`--*az$F_E{gQGedGce_9=k!mO2T#AS)tAudv!fQ7|H)@`Ch`u4a7*{S8H+u*z* zMCZMej})-$(+PwyaFT9rddAExFJ(e^#HU-Vh*_JR;LEjY7v8t?X|z6V=qVt$NB0MM z3*P-3R87B4je(Jk5sAN8W($7p$}3)Rh!*FcVr{Xvw+;2b3=h~gwVLgh*hbR4oQtv@ zQo{vPhdqan9@7b?kX6$`j9M*j?LTIxA$A#N9DP*mj{gkvXSod=M%JAx z!>B#<1A!?SXrX9-6Kk)5YrCbL%A?;DEwes@H)YuZwd&b##XpG4X+3rEb9I5_xH+M( z>vd#w!&n;p`j%{6rS;IVe%EZ85`CT{b*!_Bfl4r{qrVaIVS*DfI078P&Xbg1FdH^H zRo*;8x5e5i_R_~Gm~Y9HRCKjj#}sx<61%nDoO{T#^=la+rfw|sW(7-Dd)2V59P}`# z78sy%zfMYTrv&Po?Vs#XE0P03I+#YdUckkCWHVzoygEpN!s-X3_?ef#De&%ncW_?v z#oE_WHuHsR36~s|vqc@q2tV>Hekyga6&vh zZ$NkPAZY8##D}K{2K&A%w7+^DaNDiJ5;}e7QQR5)25z=BUs6ZB3@#ypaqzi;k3(Cy zPT2!NwFIF@(gdximc7d(3cLL1D_N%A=Lccnr0t}Y6KR6GyAdhm*ULv^nHPxwhF@^XgQ~ie~ z0OiD<_#%CEapk3dE*8NbKe@{55B0sTE8pW(J;PJ!MtMl7Hfn3*S=*G{UxjHcMD?*J zFnlr>d(h-_D-D>sU-cc+4&AB!2FwwKdS4!UREf{L5!qK)oBB?hZI)DpP2;bNWK_=YrbL}O#mjHQ_2sYt0K{(>Ziu1hZx)er+%f* zaCX0}3iid0_}<~+;=SYy-P2JFHTa&C)d2#vUgfScLfYq0WV!dD%&^vgr6=MAGR{3~ z>A!71ew!mL5hqT+eG5`*5sm)Pt;L3;fRt$NqfFV1>V-H`^e+=0cD!Gx^p{uTr6_T# zip_G(OvO-)EiQ?G1IP8T{VzXD!7nT0S`&nkes;l_@H;Qb-C&oeN?p&zZ5K< zva~wFw#ctT?zsjleJb91_teQ~((l7a4cdi8g>(CUX0$0BDn9F+Y~M0K1=WJ)|$ zOEfp581say(qY!RbkJ9b)7bIU zl4U!HS5%ls9-ewb>aSmzR)ONGRRKpkxG-qEfXm)uBuD%}=2=?w{)}&WYA!c#* zq>q?lgouJ2ieG%{tz*WrBxL>?!6>c{64R1ny_LO7^haJfJ*>+hG53~^#CCWN42ql# zF{|!kF1kF|a3RkBP@R(`PCg|j6S;GEvH1%}?KP)lIupQPp2K_%#f=3_r8Q6>E+^|u zumO_zUf_PhbP)qA2gP*bV1C!V3o|j$$%=iws!1j~t>+j9E zU&f1YJ%SB}QwF*eY0M0s_s+S+BM>k@OQaU|n9wyN%d4$7F#$0ipgl1Ae2P2J;jej( z!LwBDMx-hNKecyVM{E=C3(A2Lm?mt|3P#!-FPVd}_vKjX1>!ByJ;E^}AUG|{ClRst zAAx}WJFFpK5A}DwPtW`uKQk#3u2ft8*WQ2r$LvUQxa92`bPLD0#fa;hW4i#q%3|2; z$5_f*YDbKi&GHs|VVI2?&OX!D?a0{N=Pn#jF191c0zK&6=i)>(D|frqFle4@yC7v_ z&4)ZW!)u7`>!z9YM~l6&8tu$Xl-<>Oj4%E0CGB6#w><68J4l3ROa@6p5m1-=4_^3T z)QQwg?@3ZUs+NXHkp=D-vjfWb&oW5_k@7p|gMQ)02G1My!2r_~k>r)sA%03IM7hzb zzUX|9!|UdVyQ$;Stnkg~t>P0~RO*nS*^Aaz-H8a|lv}x+s(Y#pys~Ublh=z^UqVme z>_O0ycE<$QxY&z*Zfsiy{vhYr1*Or;kJ&YCZ0s%pY`<3ck^u5HmhdDyd;|bV%mQh(#vHLDG|PP~t#rpFa5?9%%c4^B?u# zMQH%Ht|@Ot-eA%xI#tV7!!fb57;#Thv$gy1V%LaK z{rr}Z-E{Zt;{oB|yhZwN^r*-oSAJy<4SIABH#g;v_B%BJv6k^R5gTNjDr`}NJ*n>0 zZrAhLO)WsIx*qm=={hha;36zkNQlkjL5A&S6|eHeNA;`c!q$V>4=H@xTL0B|7XLR* zRkPFk03VX+lt5b#s;t(u8bmYt&U>|Sd-Wf1gel>wfBA%wHv3gX_jUkYvp3#Qv>%pC zgT+UoMSFYld!K!lTdDc(+<>C-S@Pc4)0*Zd7OV)rv(+?DkV#5aa= zX4}3Tf4EaGFuF)R8#ije3sMJ=k=DC)B&yc~k0<-E#I4y zIp5M;?bHEE%vY;58KibjcGvQ!R@~Tc{~9v&t!Uo)DBbVhHLR=*E;|hJ%m!bEsNHXM zcy_diUmii6kXa10knpP2NPpKqK3!$%nWXI>9~G3DT)dz)vU~l876Q@n2hGGNxLSpn z2iIyq#qqLo9BsYS<*h@&q4oXFuRTE5c{HI^;(UTwthp!X6#aQB=vCBbSc_tn%_M@W z!ua>h^Kr%7Q~1Rj<+*Hgj}~`d7uAmLD6MCYZp@VJ<4+B)AC0B1a%i{(Mn3(*O`al( z3J<@n?;p?m5O;AJxJq74+TCJ3&bomA4-Xo~X~KnPJ32Lh*9pz|0?))LghaiWQC*g8 zQSAz|t;}jDH)Z9iY%`gbmQhxuhqG1q*hXFK^3^H#>0XR)Csi+{PV84NOxKMXR80Bb z<>>n!M?vCK#{Rzj2OH3#O+Kh*EneV#b4@P5;lSvplDc#p7%H_Txl-{-p6e$#mhJUh z=3S$+H0L+D>}&UaGoPH+NDUEvn!10so<*H;CF~^JC%v9k{@R|)N%3P_T|k({3m44} zAW3Jqh6u;CUK_iABbR%q=Qb*OP8D^=my&72Q+(Do#^w?4RCI$WCgNX`k~+B8^1#c( z==mDMo*B<$&|_$7jN7OwB|zvoOI!1cwb(ROYuATs??|=Xjj_Qb9(2NO&t)Pi?V;H4 z^6R@UMMM84xaQG_D{5}=DmI9e?`gsifBUB)iBnDT?6?T+1me>BWmrbkT_Y?y+kxB9 zr6lz9$F#DmV9$%6u+4lvht!HxVzPd2e>gGmP17elF73~! z+eKf!znC?Z%!9v}*pVG|-q!M2&354E;K%OQN(uh4&k~o~Cas)m>iYu#PZh0(DzSS^ zC`bm1^iv+A^$l;+zGcfM@h|a7sTVB7+I7Ik_&XAdsf;;+uhZaK)~(o@(Yq5__gvFo zFLlK;uXl*2Xuq#iZF+el{dj1I7M=7ezJn#BFkE%}hgQnKw33mSEpR8knpt56AZw=h zaammS+EOUc!jPG-Nwo7r+SF4+Zj%S^;NJ|1&9P}6f4@F$KcEywQ{3OtsV(UCO|xsa zaq&3&sIp*stEUlYrPT)c1>6h$lA{t17q@BNlUCbb_-51paAR-iHkM3EKlNPF%+vcL zFv?_rK!4J`Mt#`zMINzlui}wL-rw%W6_=XrjNFx|&k$&(WGh{WC6>>hd;iRk;+MVh zE&F@Mvz@7xnvHqk%%4%v9tUR1WC>breXhT%#VBlxqWh5ybt8BtmJ~jLFaVa_ zMnwjV`!6=SWt}w$WIGdXKVojeTOvMSxs@QQhSj*GDfjUnG8Qx>@Wp}z&|mmo><ay8JN(p8s^*K2Dfkm2Cw+an_l~q|F>#W++{!EH>P*Xh2OI-X?24$(8?7 z-HENEe&v&=dNuN$ZN8(_`sfGWf8404Bu=xGUjP~GAMDO*I4G%YhL3dVedH9MDaYKT z9GsFc_iA8Xm-~Jux#mw-8e7HlAZuq~gJ6j{T@jajETKuiVcUWM@ofcPGWuDg_m@kf zMGuMIwD0L2YnkHWxqB!-#Bdf_&J%L`ZR@Eq&c6|QPWXv9nKCL6lr%yFoC$`0ZuNv5zm0boGy$J^A;8anB^jsnzQ&p$6gxRvw zW*P%gE}uFs6Q6dRszqI(0ZekU`f{iYn_o*JshJVWC&tkvm{Y9UQSE(S-Kt9BwB6nZ zZoh!krjqh;Bei7+O5}W>`xB#9@~;O(rTvyMcb2H0kgW^nu2p^F%WbWRlO3g;_b#0I zMe&P5yV^7Umm%fe2iSNXs88mZ!j&HeKFK5AeO35^ zJ+t{W6y`fAdO_|V5vtb#sz}*VkSuei%6nJvI8o)RNqmr&kJkRUa)FUYnz_OR=NKsx(|Slb;z> zf%7Qtp>}w(_w9Qo-BQsTmU4l$V7$Uu0ZV{cwbfD-!9*W9(auCM+Uj+x5xK3&{*r|S z=jS^R=h9nHpH>n1L^hlH`Kg}5HP7|qGJ4TEdDSa>CL(az#16^-g07XZre|0yYH4QJve`mIrm4ud}i6J_)2(N+=g$H4DbAaIguH2x}&59 z{|A}G{I{2qz!rF{eLW$YgPKA(s}fMibuQrpykxzFkF1L(u6Ji2#lNQpvBRe(bH_s}v@EDgWA1QZvz9`wGB)&wsu@ zZ2qo4PBmR_|5qyZj8}&Cd0!j=JrgX|RDYXkFRYL^^}?5dhY!GVNtb>npKdt9FEgo~ zf-N$=(j0BYE{WF}3o3uAwu0C%lByp)VK3H|IE5$fWlBCaV0#Jxf7ugqHXrT`G}cjm zF`qt()z)Rs!HW@1a2F+e(q4Pns(5az9>HI~NIm9Xx0cNB8to%8bCN8jH)nZPh6HsR^iL%`}S^BaMyRQl3SCdu>McQwq zFAhz<>91NtQnNPX)nIz4&xf>uD(3x9@$KJEpxwqX<`+bF8Tklb)h26Jr?Bv9@PVBa^ZQG3++qN4UCunTDae87j zwr%s~{a%lI$JjsYKVU!4UTem<%o#u_j*6n3-8_9KYZONIl`R`fRwfGZHU+vK?w>| zqSoJKFX3ORxZG_R_yPmpOrUK+ZdM7>aM)zN7YBwJbIw=C>Cn9U(q2&!qGB|ZW+}Gr z302LUXZqRq2{z7t1&w3yyif`&5?BMR($8Fu&#r&kEI`#T80QP#UF~E#>UXR5Io47Y z47w6x1uOPhdYh-&EpBFYWh+J+68c`eB{h^1GD~6ErsV>8CoahZCH`>K?RTusd4uqv zZ@H|!a~&LZgC42>kXnL>d8Fpr6y-lNQquKlgAM`P~uKQ=$Q}5(sl09i8acpc%u8z2&f676oO5inEGcDCBx>lPXxWr{c= zIc(-nheA{L4ID<#;p)kH9E@j%kGnACa)K;hbB?g#5F4)3H>^m#&m39y7e_41QXuJ2 zm+o2Bs)=f)<#PC^BWa^MYNVTZs3Ezba9&3$F&Fl=F=t!>TnOngtZh$jgDJ;SChRuOl^?N;!6j&>x>M7INB>Sx-M_%heft4tO^bAgP}p z#`8Z%Jn>kK0><7=>$L11eW++a-oJTH44X?s1`H zq%{w*BKQCIhf~h-0pfd_T~M{}S7hG~^$%r!63NF^m=I>1zNreRQ?w0rYC9`<#CL6T zg%C3xqM;Sco(Da)sE*iz>8N+s9*S(iN1N++sOTnXLKcU}Hmc=`{sDw;i!q9&R>( z#DUKT4%swZRGEW;RNcHF-@Cm^W>qDUUVhbD{OI@44}Xd)>A%CW`5<<=Gu_cYTHs0B zwa}Rsf#9?I1Xe{Ngo6Wy;)vhtU$tZ44cnuxdwQa;+Y00l#IhJ+)5Gq?miyiNSiM@Y z=+#=vc<41!h(Q#(B6okjH5k)U$434o#ZFm}7ru2O(L+k>ZF1rW8fGCQi4n2l`onHV zcKR?Gy3y5>V~T>(P83XmLgY1mdlc!_8am7kS^>%9!y@Zi76Y5ydBye$rzmPQCCp?qcGZ+o|04d#Xk*9ieiQ7+~ApY;s=FLp7F5l zZwKTajA*~7`G377*^7R2k|KU_8P|neD6fJ)NQ?Yh2C_N|Fq;7`p68*+mk{($OF`#~ zGlbUYz^&}o)yrx94UY!!(AiAp2ZG$;iu~Uo@P=YbF~UNcFNCKz1OXQ(=r>;It}nZt z1u+uq@*PD}lqxFBLmqfU8(u(ZpcsVH1{lSmW(DzL9W$Z>QfWDMs&NA2y%uSPqz5kA=+FXnQ$X3Qw!BU%o|JC!0LvsH|1j!r+H6Pb;P!CbfGHGLA{Prw*xoi z%OvDBNfWUy#hZ15Q6@Jxod?s|{jPR$4+m~_(+Z$l2env(dUS-&l>o?f?B!eGzrvi{ z)%7LpoY)AD8$Pg0Qt5t4Myxs+p@V(YNl{zS6R};`w_-kPGmanla_H>w^)#gqUk8rM zmfbju&7jdL6>H?*P=`;>Wp4$b(5aeJ0R-PzrSs=%cR}Sj4BV!5zs}dXa3MxjBR2-Y zHA9k~d)Zb%n#G`XZrFo;zIQVCJqK`NBC!2liN=Ly?iPtg{MKIRSweyzAQA>REYTZXbf zHmsJ-BVGMCE8P_p?`x#sDWEF87N{*&*iSkR==oXl{^)l+pc0D;@voK~z(Mzh*m$3HiiqZ1t*-aM^Xlx zFtu!OVLz`(jNXMiMEeFs^P0}RdbH`CG z%8?=bwZ-WyUYPNJe+c0C5l&Vbkz`^KGjTFl=mHwwhclyiLsm<(*>Vkk~_qlEx zYMl!0_U&t>L1UT40*|)T_WKtK1vJLDcG1~x6i8h+3MXp8X*3-!PTLhB$)#^UTO<*l zpu0XEwObd?!n!rRwP=t-KSrb<-AKg`ogmnK{n8KQs_c>^7^-oF5Bsp8zg`6S&254q z6854^u<_y4j!@Dn$duvu+lafh;Ac1OSW(Ma`en(%>)K>6^r_N?#lH$4@8XZqB2@e{ zT`oy^5Ei1&SZ`0DPj=BSiTPkJn)|oCU`C#m@rJB0D=w%3B9{&jYD=h|h6tj{Wc1Hm z9<^V>gwGN0{>Box$i*ZPf(oA^+PePLgonoJ(Wl~j2r1StoI|mthW5N6W#`$3HH+d@ zs)mW?90h!AA|(4aOUG>B|M=LY!xy6jdWUxVGGKLmC7n)W&k!E@&P~2wz=&v8(;a>t zztH==G8*sZc#Imo1QVo+3*hl2*+ZHaPRfdF3@;&9(SzMsHwAj_QHqU@CftuL>?J*? zK)anv_I`LP`|NYxuIZAW1=7usbb7}{d8dc}iBz?`5)`Z^tab4Q@OdLZIChN?l2WQD z(FCuhB8dK&$DI5Pby>NBnuN#T8rN-783do!o?owB1Yq=O17vDs)JAz4@@7kFhd@dy zj*=C2SJa+e1p@#J&VJpn%8FlpgSw1PXR)i*d5bOSlXB(0QA2jWGj%9k_OSH!TvQ$w zHcMr(%0;cb&i%#}6y8ifbe{e#vjq(US@<+q@KK$=yGKG=yr4fk8P3-H~EAaGVw z>2`Qwy3eLMlVfI{o}hqsh*Yp81pha2z;FNHi;o( zMLVK{F`-JlBIOS*I1mT}S%*^vBANY*+)atNx*^9Y1KdQOhz-7?5|3dHTYR%@Pv|q* z!i*C(`$oAw1Lfg!H+~utoA+0AOtpVVoRGp~RRr$FjHWVK(kqmd!ClxC+tmA=zHi&l z^~|X#r>L`JR8#r!C2dQ)11U4rs&<@&0jf54+ik z8}6j&eI`zdOuT^ZBX9@kb!5sm^ke4(#&zY`mCUJ0sgV+`nAC^)v=RFER@bJ71ENp3 z;z%9P;~Zu8`{_(~MO>SMcH^)mgwM)##Zu`$+(2vrT<1Prfno&ZQ@bK9^3|Hw=L(IhTw@qlw`?wPd22?;oG}0Sq>4J@j*V3 zBKUf8fkq5hB3O$fleS3b{jW)KcfH=NmAw`XD)xh=u+}5XM<6E9;|l6gFX-muu&-nS^w_qrx#Xy{ z+-2oqc&Kv#=34EzA*+7fG{YP4Dz3n4jVL?M=)t0{@d?<3sjEglL>7&oFi~j#(bm`Z z;j3C*keup&ykT&z?M=*)&Y*shvtwuL$SvegmukNSn; zfEje@?vH8R&wb^GO60Ei%RA4(k&aLIo|4h0(D+u#GE;gJgU4Nau}_@MKL_~oqYVq1 zAlxOi&fh&`;Jw6W%WaXg6bB~p4Ez0EeJlPZ|0Egdg?MN0eYoZAi_H2f@_Uj+!p#aP zEyC~4Xw8Dh&=z!NN0E)fs@kPE_=u*O$Ji$&vn6y|P_l}$#fQ>!OUtHCm;9my-oA0y zpdTAtuj;{|R$h?(itw)3;EB6JO|Is)0C?jSdcusbXyh*^l_Rp*_rj*~$A6Q?89Z#o zf2fa<;Cl{m{dj>sn`U(rk47Ziz&c#nK=&>7Ex~ncZ*9c_d3~M;>umAACwWp^ln7Ac zg>a(e_n9f>!BbD8@T&gNT)=F}w^fv8?VVk}fcfE9!5+$cgenjrN9X#OKx`=Vuet!s zqy^fB9cZx)(Z`FCM-W1<-s1rqI>XMR~nMRkSB3Dv+XzoC9zU5NIMgDDYaYPDi{#4m+5_kwg z|JQw0xDg&lWADiT;nVGR1l!NDy6@>JbzqXF3i(kbfAwn7S9&iPcoOR8AgEFpP z3-rBFU8FSDrl)Y(hXms=hVw9>?AM9r6Hj#%$O|vw6fXrxIdaQ<+|$Uc8-{sU0a#VC zVpvhmBV+6Zq1PgWBTa!{w(e+x$O{ztMi>6HnIHvuGm9FliyF@fZ8Q+Gcl&(?tPcwt zv(tPl-?q}7tzCEEdkU}=HH4nGPkA`ubt9-QJ~1NVQWFSO=*8%-gl$$!r;Ny&+BCO?~| zn~HXf*~6x)KjdUJr_w3N2JS2SCP-w^z}^NKkJBV~^P|1@TZm=NiwN2nrAUdc6hqbf zKR|OXWhlAZq~Qs6V9y_6f~;~Vp{#1xJ;;=-8v4HaLLw8d^eGi~QR#r+|C+KdTH~d! zqSf=wh9hn2v=Q$+zJ+ulhiYew{-eizM_B<)7$8q(>R%%`$S+JNMZXl+Ir-d>hag35 z>X9wK?eiVBy9dj3YQE3YIxw#z_vb5&yuM>j#p7x9cQ>)GD2<(jcWd%~KhJ@QJ(d;C2snbJj5$Qj*vTXyx|yqtyKda@p6?SOgm*THm7+Yw`s!tFMd2t8 z+K9Mc-_N|2Z;xM;GUN*`Ze5?V*y(_BUQd3@rVk=3)znc29#Gvm;l}v9fFni0xRExb z&!QmE!GNu=ghgnjB^(Psx%(YLq@?B#jm;X5b)x00)(yG&`a_~jgTDaTl?0s+K{{;b(kO6v;J$Ga#i3h5X9 z_}!iq71*4Zl5@<1Xpw~~k;ej!UOqo)H3>@2GhN}7*#d)=;zX?E-hg_H5g{+%C5Xf9 zodNF9$*%~8%G_>hxpX@#57KNQApeWxZ~}Y6SUn7?@_(1rdhv-50!gNt8%;pdIQs*1 zHc1X+bb(=JpIY#bpyqLr?`c&@6zuJ2nVR3Cgcrr5^8^uZF5jn=Bg?bp#A*;pn}2Yv zn#4NUFCvX*j@R;exvMK>*u;l;hI|H>W+ce2RB*&p3}nALkVA$~k~7Xjg5Oo~^-5xd z8;2~HfBmwJv7GIi8Lns$Oj+_Wp<*njg+fh1DnJ%ut3&;@33fy?qbG#3J&3E{P3d+| zqYs2g;ik)Kk&6qj^VeLw$U&V=uB#u2x(SBa)-#!4UZPm$1*E=M(5Bq8P3AJbN|JIj zpFfR;Y#1`lGdg$e`GW=Dkpoq6L+rspw#y!iq-}6@Us8y&ksf~MM0iVI&hgRJj|IQT z2-;y;vyGdnYw%E{U2ozvZ!gtCo$sv}clpxF_0_1yVWzm#`Rx&hnC&-C)XEV-+?-+l zKp>>IHb4C&O@b1O67?E~lDqEMeBk0llkBkH#UA&#TaW}-q@xgH30wNsoC&eGLg;(X zynlohMBs_OWINW5wWEY3hyuo0WL7tx&wzOyIunLBF@M$fHhpy65p?f+`Pv0f-4!tf zya8B0V=omCj0hG9b?VIj;jk;+lVNBc@-#~E`x#Vtxq6U${y6*rFMiY4>-FxMd} z?E-oQ>K;^L?3XC0sX2NiE$QbLQgr7z$_B-h&RZPF;YphLPOKMfy01AMTFc#ainNP8 zZg9vZ^6;mEK{MY3k|DY2@Ty(;BJ;3Js%O(zEFJ>S0=1_Q^UgPFQHn2E0<`W1GCPpk zh2J1XQOniVidpO}R%>VnJ^KgQ!!rq`I!+B8`+a@4O%af=HBc^FOnxa(2{`T%Rad;I-PT0%Ly4I?L^@w z8cSiQ1VaC1?}9%E;>g?;mR?;PDdIn5hWz;vwcBL65O(#?6mJ;ro+n|~CpZX%Z!*9i9Xjg{7YKE`h{ZHi5R*>#vwm&PaJ;N+{=o3 zOc`vROANQk>qGF=gK7JGaUm?&T7w0t6rcc_9Vr>7%js@*#UYv;{}rhEv0ivd%oAFG zyOC;wbF;>g^rGA-ZHt-b|HwQo87c5pjtHg0W9_3skiw@4u%1F_Pt>`BCj5^AgWW7U|;51$9=keZ0A6+gVQwfM zfEo?B^Q+mKB3L<_{rk~f{i$RZ#I+G#rUw3$iw%@(i5u(fIeo*z51*0}WE~Ycgf0&j zo&7}Tz)Sm8W?5~e=Ez3c^H9HA)+e6OUsWa~N|nf8%QCprT`!j2aL8BO#g@Kk9RrJ}dHD;`-0&4wFjIDUPp-PJKk^QE>rD(I29;*sHF4(}$ zTfC_1Y|JtpBeh5-A<4GH_eGhm z)X{!@)<$67XA)WKrx`WK^}GCIpQRrHq7@Tk)ZBZ^pqeegNly@1rBN4@IK;DV@wqww) zlS)KsY`s6(jbx_b^>6X}NDof*RY})a>Kbbtk@f(B3FJE2LSm<(O+HkUIi9gTfjv$&RIpD_gWa4?_iFRb@}c&>WVwX)XIO$qU+wN~GX^pr5UX-wF2?Q$n-Rii}8rMdtk-eLJ++ z6~-3ZSDt!wX3$4P^HCkcR=G^Ze@VD*qmv${4{mqRck=z~{MRnek<)4ID9Rs% z+036RWKyw&3F04ibF#T3w-Dxia);f@u~q<|0~Qb1MF^klP_`=N=n#8b(D!0O>SG;q z>h7EwDk-x?Aa#$KqS)+`(SQkt`5Mn_CTkl71n-igL$O1M*2l`GTs_p|hH1jmLn~|M z(Q+DSwU33bRda0N4``pT1(D`5k`)LwRI4(CRO3*nC}ndpzsK@o?y0K%)EYtyqaUZ4 z@J9$NJV0l1rfmJFZEbnKGuH;G;JoX@q2GL}lgkQ-T*q<#bl{D=_|jRV;kA~2R_^KC z)_RIlmYO^rNWcyB4^|~!U>jpnv$usdD!EG&{8rz#t_g|Q&9zx1TvIjooyU`C`DlIX(niFt# zbnsM2Z*846m|;aNM+b1WkdoDSsDOz$%v&k8qkw^SO*Q#)7p)- zKr=$hK69c6d0C7Ws_~xZp{0ZHAjlILanU5r#|Q_JWOCbnq|iVa2x=MO!NE2&bJ$|Z z&fIj|txk%iZ^v>SSU11A=4~)j(3LF~0ZjC11yCsTFwBm|AAaeBJ{k)nVIteu`dJ$F zMNkMgz*&s0)HxhBxB4I2p>JQI&7kvNG@@SIYA^&;T;j{cku06+^GlU^%DLH4@dI!K zXTX1IX6%CLc~5>X`>x{V6DZtuD`s#}gqlUbgrMPb70Ikpyy#X0f)q7dHEm=n(Z;_- z5*B^g+f-&7nh@J(Xd;lwgz6)$07j!dZRrTG9AEePE&M3ep-rn*wI~ub!yU#+p{b`- z%9_v@N(N7dny|*==~3HB$F!k`+2wrdQKE<>$L@G+bcywAyu8xCl=+D<9&o7>k}s>4 zQ?;k=PEv01)!U)M4D`3wx=E+Eox}#;{?XDUi$uYOU?j}q{&1sN`aLb06cU4&h2LIH zytUL`v-OqBHM<%<&-1nDmOGN2o<0L6_%&69wz_7PDpvLIRa_hPR|xHpSAADmeWEOZ z@;(5gf($3r?7lHsK;|Ds!%*gKil4&s3^JV0Ny~`MPqsY8b)+YE3>i9k8tB1is)l-y z$R>Kk|l;w605I$RZJ>j_rLCi?CGoe-S{p#ETt)6{0%&K>5yhYUX@Vz+K~P7Em@}#9m2*$7W)RL^r_?5OQIO(frv&>ww7_HoD{|x| zLa&`(_F^hi0>4$tMY@k^p(Gle37A++`mYZ**~E^sowsiqb^|T18~9)-6OO+u(Dk#) z3XAhbbHwHw-6U~j?_vjLa@$|+78m{HNZ&>2Hp$lcyDYxWI^Jhv*x!V_n+}nNA_DA-q4>SUzBj;*~*9wfJ)@=#~LB)r-pV@+FPrT^+nw- z&gXgM>ByvY;au!;33qC{M6s9EPHb?tTN(eCW^r+^+k+aN9XXIyT3aosWU{}_qyafy z*+Cihpo|6RP^k2Wo`XH6tX;A{WZD5Mh2p}!hJ4$J(&bw2A2)SfD{|5NL~Fs!QNC?b z^wb`t_OZB|Cy+`O7W;L}_AuNv&~;2n>v!yDfFO(rTwK1-ImYyFeRzE)p?j8YsJ966 zvf=v}ytIG1pvFUx?Hb1MeN|GpM&oFg3kq0p1$w1%t9Dg2$5n#vTpU)rwB~qpR|Jxr zzPLd8or53dzOl;r)9-^W)^HykgDF;E7}elTtCYOj*cS%LHu93h2wN?P<`|1VIw4Sm zQh!!6a(Ga~ZKFWHH_TFE9Lsu+Pm7kMw1MN~sG}75wtO&KMr1LSew_S8}PK4v78J5mT@>G3}%k5iGGGeD>a;!=A z44N}f5q{FDl(cEl2`^ARP*qNf8YBM%{5>Bu4XH%hnqZP`YI>VfDE$tPG zwF6W^=)t;s6B zwkeWQjEQ8#w2)W+85$zbX@0dYt%|2sz`Q(ZL+L>*4wG37QL?T~U zkBa}?UB~C9E&2X@#+F~@CsD)!|xkzZ&AW52|1xr*_ALrj^ScC}(ysDK5v zk=X=6Q+a;8CDw}9#Va$EKMUtrr%)t~s2h9lRY$oRvW%i0i+k@h4T^CZ9%f!+T@lD4 zRjDHyyL%=3wjztekZPP2ODT#k%_#0$)=f5(A`eTH={tIHODj-5D2N5(8V>pC z=U>bi-0Gt?^0!C5DSi+>7^`*5FLnu!^)6G$w@Cn%QXJ_9<#6BsP(1ib>&sFMMwE8FM#N8vaBHbn7M3;zd$L{f25C#X31N92pY`@M zrqSYa+vBp1pvf;}F(v#0DFe3Eimx(((S0__5Xb4X@U}fRcrVmQKl5jW1@m#ixK*Na z7ist~b5+h}5-{}tgqMsPiC5;^BvDensL=mN%{biS%NN;Hd7A2^5El}GJ(4C95iW=- zaVt!#?rX3koU@%VI$nWt`jpd2RfHaR|QcIc!BYQPoO-LChMR_Z+0ZNxZE<(@(I%ArGyEwR(m!6zzLi6RXH@DvH zT#thDc%sGvQd2Or0~irKgr1V0{HGN#m)S<}7~#)iG1F;-T@qxd*UDUz>C8!@)Ee!g zSq3#?rAj_8Fs>^Qj4sn4of=<|@3whJ$F_k8;PZr7w+%1;CA2~gx76doL!SA9D-j28 zwmbDxrIK7YLt1DWS$X~P=mz+_V|{7Ek373s%__jB`lu5=MkEo$`q688X|tXO@D;bl z$9Y;aYE>Z9S%%^^x-#JVYY<}3VVPKOqdu9k*fa`Ol0dA$zOs%$9x)tvO&EBKOq!n% z6rmu%2oj4L9rW7ms6)l_73mvDcIKP+adi@bi!Z!vTln!E&_L*E@e)rclzf3%d{09H&#C(DW7s46qKKOZ9eFAj-GJ0zcq%y*q-w|D-T^b*^ z`sqRx3rH~47%ojLuN~JbaD0CId*@dp1P2MF3J!j6l<;`o$I#`rO-e^*4Rq+@? z4EpjG^I8oN`GX}DWrP_KLVY^o!2H=f--z3Ko&_33Uly|TE3Xt7KLh+-t8U;w06jyi zzm{x&HtD7=MJr3U{Yuwi1NO4Y|9=D~Va6J%)HEdm7bUZjQ77&ukP$BoqY2hPQ6+p+ zJ@yEk(UCvauM#{VKEK&>O;B04TPKB|2)?O^=b%b*f$eO4d$Q2pn?+GCU!|aopiU~h z8%2U~NC*oSAmzcpFzb*aIkbSnQbv(T79AR9DupgcuukmnXJmu4dOfAMC%iZnMc#Eu zv_|SvM0*$f0q*EEM5Y^4#Q;-EDX?K+(+`-{(Yb#6INfLB@y!nR4HQ(Zs*5*_T;a{T zRXdg|yiNV^+ZXuaQH7j11f^W6s|`9?hDGc^U9WmkzC3XMb<zb;_K0H|6cPd z=aF{%4lCaucSwCKx#xrBuAqB@zW~M!SFt_MvJK8_%biG3aD9YAlfveB0 zR4()Ev*l9J3!D0@3ZK&zaoHCAX$wUD`HSShtOsE`S#1(Cn>9>}v=SN3O~+wq`A=z? zQF_n3+hOD)N$D?fscNR|^FUOh@Rj-H%X;hzfX^8}On}&^#~+8$U0(71&&fsM>y120 zj3*Rr4c!n@I3~54Scgd&*k{W7Hp4obg#HAGijRjoadHsuL85%E z93DjfT%_y#72#zwdj(3hI!??z4v37?)|s%&d|>2v=$5K>X?i+b(}h-oNG*M+nMqER zCseJVm!O)h6X6<$x;cSO{6>8GWzClA0iZ}g&|kYUPZEGplhVnByOgsmn&A5Op0dwA z{x-EFYmz&cS)=wYS8U^g1H?nbwHn=Tk+L4kg z%^WY=TNj z>&NKS0&;!`<#rQ8`M-%!^jX;R8A+g{={C;^7APgJkb$o7Nj=NNKh!?2 zoZ$7`a0g{>#vM4}1rUl}Ma!QqM>NheoWA!n$zyYMz*ku}{LvaSNdeLziwW7nge5$B zum;^>q*o|ppmW-f-_cnK)MW-(Tmujbh*MlNewyTXg^6^#xFRJJlob2sPwW;dE!ziwHbYM}=uF*6IUn4O75Rv05D~)`+`VpzQi!sf*UjZe7eS zE;;>ke0?wQXBwOwPeMWO3Ha;LoJkivna@@Im_h1pp$xd_7y39Ed`!E31P_0$0zS&l z?rx>Mah)CPpwI8q?@i&-&$d_M`2Q@|D%w!z!*#|ObR>hQ6+#9bm(NjN%wVbt8)*T) zTPxmx-}p%wdoWohq_F-`EKo{3RXV-q_@3a%I!&5UlGICNkTkn6eJ$T=Jg%LRe#)@3|w{JBTP44dK z2y;aWG1jWZj3yz{GszsvjtpIIxqO7Sbv`yo0c*ZutHa`KxLr!y%kNy(QaQ?TVnK*? z@klwiZ%SIoW?rs>A&R-^w%2opVOOyC3)N^iWG+`SBG9Is6lZ1OgI$~=0~+4dC6-B1 z_aOQSLg$Kp%8~ztHvi{kEG@39)+OCWRgwl-ph<^`sccFKkE3+iv>dPK@AwJj^P(8x zjrmYghJ$ap(iBF+fdU$Ra+uJisL_`;x?upCVjs3h#@JN-w&$rR#{aj;5U1;se(sHi)|n}uTk zRlmK4@6yMP@*-(>$99=b&v(BsL>nJG$e5CvcNLwANhI&8xSIy8ozKf8@wFAM?CIsU zOOVgq{8_^Wg>2BMxk66|gdttFm~TDmuufS>`Yj5qsHdTqPmrx?mBNQ3S3G$LQ37}N z%eg-quu7SHpO`${NJ6`<34gq95*E~SL(G;6N3?f3FmFJAJXg8C7%Z}mL(z+4cd0Nr zT~)6mU&M(j;g@l0MVD_@R_jVyu9%ZMJaT4VjERaZ+McmJ*e}Lyo(GR#>k2 z4Rj7n&Y&YGs8@^W?yyv?V0;{C<=Myyw=^)mJ`fXpnYR@;+SoF;jYq~E+Ad&Glp$3k zrILcTS&ALWxN+T}f*?rIt-}M=6J(vOi&!xKY5IYr*SFx=axUK3__|*WwHv>;NFTx? zPab5wfI+bJAjP@4)QGe`sX_H5{c-=Mlyx`m!t&D*&FhF(bXY-sCGb*s!d)=*Pfj6*XA!!2qsbv(2jAO_vFp@bO_`ia zX3P`jNG)r?VmEGY(VJ*fPrj4jm6BX#%il9ZQhsuu^FSVvIk1g88(7D*LCWzIH`a5P zj4tGp_lGZ86ifhcE%iJPE;ouJaxydw<4dBTzmG9C1h)$6GB2daWIGE=rbAO??lvDj z-vbudqPszCI?Qh(wj<#)>&*M*IPeJ<)YCtAw^Oj9QS~WdoBlbBW?VW*H`JQPpO zomn(2wv2S;J?cHd<&k^Q)%2l)w|xA`Da;hEy33bdHX0mD7AtH*y~o{J2L!hy@y%3%Y=1O}qjhyVWRS%wAuAat;s0uiKhL_$^-FN1)7KU}EWK-+ z4YcCHFHA5CGbjG-nmIWLFQ+R?w_r(lBEHBO+>K-iA8`7%P94M+LnwQ`m`FtCz;*QI ztC2CqP86BPKBQX4*ASM2!rQ$Tv#E%nm?1|>(8+>mXKr}s$2%r6KW{&$6JRb`J+xkf zNC08s8YKdzPf0tbR)K_p!vg@u!T%2|Fd5bb4`eR5L}Q^m>s?|O!sl_v-;e7xM*bs2o-k8>xwW}bi9?@*dYrlhPsAU3t(Yb| z9bfINdl*I&0xVy((KhI9@DvOho&X&_u=KxgGU9h4js%1_I?0!fJ8rkTo2kjS42Y{)$lPc7ZOVECHOsk94$ysMrYD*Uw@#@4a*aWeRcbnR@%U)aT6wEDSYCrJ! z#cmV2-!Zu83>BeO@1UN0+09xH^9Bph7ATHydi9iL7;s``rnROS^8PqpP#wNJ{G4ms z;rd9}_QilGojHqu6LqLsXB3C}l+}M|1Hqkz#B(+DD+-UR)L5@u*rgn2weneCikZm2 zAk4HzJz+b;ccQGDZTtv0?fkq^W|AbdgpJFmG%rMNK3l`hnHVeh#RPR>w{fYM#ux<;tx#o&h z{!K7QJcgxeCpnVN;aKFKR>{|+A*6O7WvKDaSI3FyzM*d;F$7`4zQwIor-hSSf=)O; zv!p8-3M<${spls|9v?^&wKD^a&p@H4ka|p?ziag5o8dN;AYv!&?KP$3ugK-N}96g$AqW@^BUPa zj4fD>?KwfzXt^18t3v#fKGCUe`b5D)?4^IWF&Neoff!&c?@B&k>7RpSLbL~;6|{|g zcu_&XN1RjK8Y&rggimNE|27uJ@@?`1&Q*beGRAC(%9vw#V39=l?+Gb|jvmdcm576k z8wu7+WM7(~@JY`*lDS++i>%x(!?HgvMz1DM&W<@YEwL>CK^O>%wowkKJ%d7yZ}$g8FAO!>PxC8UJUfQ z!xTf5H6~g%M5G)^Q{AuJZowsc18LU^zTsiP*5P9LX{=OZ_oWSZJzS~KjZM3qMU4D| zWD}^^H6W{2Sy)>6ycPlt8yDOUIk#E5pt7_m)sC#LZIAsYe-k^@EXCeO8)CbqFLn$f zMk!yuXcld7#gj13yLDjA{~DR}-)(K(aN2q)5wcR8K*U?DQ#|Fa0YAy`UPw8%>7`kb z(jK&^P>+TmJ>LcCJYvZ|Ot7LJ(%qM54X#^tY3cTv*b+zldGB|qT7?W9{54}h_-}#j zn#Faa#5YN1O#b?F8(J820!oT1vdtP3NBiGXlRiHRwJ2qx9opWX;(zPXwJMO`yhr)N zstpy>pWUGLuP%&R*clz#2Cp7PFFpAFPqy^4mShUosR~*+>)NYtRWgT0Gn4r4g*}A6 zW<>C@bLoa$EDmJtH>-pl9gc=%*`pC^sso8tkPrO zi%N_zBz*Dsmz1Rdp#;p_aX57M@cf@v;%;7KU8S-dqwej9u%;}~!x)}c82Y|`;~3y!}R z|3g0McPIZGvU>dg}SC9OzGRjJX}Plg*!3-*O6kOp<_XT$;w>v>K2B%-@z) zDbahe9tN%swVeUt(WS=qW9z43#LmO>A4e5%} zAWr2BDq?z*~4i1HS?Aa zS4cAkqPS6mT&wE6LRO?OnuBi|d`-+3AR=^Q)hj7+*nG~cO9pqy?OeUA`%ip%5BM}( z@Y!g)NK^OC+)n+Y7sYn<1azwGtTr7Gq!f^4$txqq*5fRlXU1LbK|(9!NNyRfi&ip* zMAYCNDXvCl+x6wnHe&nQh0?4=T~9XuX>vfySN*$5w-nNNg#h(~Revd_Sh9eGCCCCP zR33l8)0I71)ft1w7s7M08-AlX$;2jBsi_{G)Jptv6?^yX*ghg941jHFO|%G6W%xpB zIZHf+h96K#DiB$awh{WV2;=d7q8NbFlRyc3JN5iDG@vKM z36;OPS20>(qYWE%n5u~+H@eV{?Ii6;v(>?dE9lE-#D+tzfuhCh8};}MeB*yd76KT6 zB7ZxOw)E=7^_;o3tAWU(D~Ng7RzB*4;6bB!xAS&S>x>;k1=zN|e zn)BzF4+N>sQ=Gqfb-M0(fgRdL?Y^DqS=1&ZOgJaAu*uymM2{(B!&p)z28aiEU+Xa*e1B`sQ@h&IkqFBJ3K z=sj*bD&{6-MZ2+RTdyuj-xXek z?w7vmNA<|AYlm2V(u}jMB9?DMibl3;Dt<$ci@tySKLY&GJ5v0^cbQw8*bWC+91$_y zq5sF2^?!*H&ZFd^Ow+6;b&FN5JKKJAqf+-Qc>%v|We>wpI^A?dX zp0%DEZD}0&U6}|mMM40(l5`4bs0{O%sIWGD>+wBFsbx&;azr|U5c)9kP73gBr*D+a zg)h_9{X0QuqXt*!^%ebaxjAUYIN1M@e97&<5%<<%QHEdFC^2+5D2;T3(w)+wgwh}a z(#_BvQYtN70+LD%Ie>(Obl1=+H8camdHmk)va~ zsaRbj!uGEB`v`+UjIABh`9gk|a0noH=VPSAVQqHkW!#Io&=5Dg0QrobbfQ*Mn+zp+ zN|$@qf4)sbyp#K*yCkEOjgO9q6OqPsE)&ts(!|D><*9cGT}=H<7+;6weYpHyc)>oH zB%FOzu3~EVC(d0>Zo%P9j&6N?{iXWJ$A-hO41)@S}W6F;SHzdtph z2%L?ap0mt;fr^{Uw{6FPj$%8lha*{f_8YmsIo{+-K+Ubrb-5pw4h3WOf8=@o?7jQ4 zq#`B(r=$YwS0Cq3XO)kUE=W>Pa;_S7NV(Rt`H6$xTVX3&gOzWPQd z9Qaz%=-;25&k0yP|4EmmlplAd7s(=k3nk{`2z|T(zxl|TMqQ$ISTTdP1nfC5g@m{E zd?**w=#;%>t{{$H#?!l1Gb`G8$#qX|gwu^&!+m~P$-GXXhD%DPFVVY@N2c~WJqfva5a+pAr`a?Tmrzwg$`^vPA2M^j_ni*5@^&&{v$Cr}P; zuH#@B@3CU@9%FnfQn5J+XVl-xSy4dIR`a6bf1iw+?_geR`PWX)#=V<(1NB#y* zK^;SzdZ=>bA@ba!JThCQO0V0dtQ49u5D(T`aJH}E7XENqAr`ZZ6d!LG3JaN&&)Qdi z-y5s=5p-!yH$F{TxfiKb;_HI7^0QGtA%z&sRe~KeOAJ3-eA`1dJgwG~VK@BOY?A-= z$6J{*efAs7>XZJ<5zsjvVk_;}*PL5v&+_?)<&1$S;-P*h@ zzIX^=d~3>l6;c|P@U{{3bVu^r$6#jy*wxC0u(C%Ir?sFsds^y|#>i8H_l+C|tbc#| zJZk<>iIvVZR%3taIpcoqMSbU`6I*mZa`FYzD_~tmPR(G*mmS`k8?#k2a;ZCW$DCDBYqE{I@tkW>MZqei7PJYHV z>s#d+-oHy^@cc|#8C}-m5H@$-aRq(#U*A1%W_ z6vxG2*+n#+&+Oy!vS|Xn^c}2tV#1zTpmb_=dU$;5OsHBC!*)6`WcKsV|W9mH8^Uj8)2dNThD3yTQks<67SD1yc_r9*-YJCMGLKs+y-Q}9yY`sd|&rJJH&!T zyV%3BSLsRLa=iY&<2*dOQp7u^IMWkGIfgVUid43JboeUJ)cuKEfy3nozCHmdsk44a z)Dk%%J4VFgiaT->oxJmuFG10t`7i^Pf_iK$Ur0Xq`>Vp7mlGf(FSGQu6|eh{PpgH^ z0u99teKzWF3^un2uvHQ!)xJ6Bw|>yP%sZuf5G+pswIh8Kv3c=y1Ufh>Jsl(@x^vnR04%X?tf2s&2h`JZpR zD7m@540QebUsIU~u8lTn7YxI-``<(g0D<*zMX3e<54Oe)E%8ibZ`4(RDV z_#dD7_wq*W;Mq@6CGPAjKegq;$(2rCyG7%u#xyQV?6}=X|9G|BFfV~YT`breuMwsm zrtu1)Q})1Y{b<3nSnHRKr0e7TjNQ&X%d+F4I9D$@ePl9NB^_pl0O(J$2_b%bX^CN; zC-P@+ZxQEYVMi)eBp2dCvuVicT6xhr9p3z^yPmH%QL!dmI~@%t{EV@%Pjy|*!FW=` zvrP2P_hNmDdhd{HIOT0V-@S96?zJ7B{Ydky<1D@AsyBZ=!&X!5aA~{j9`qBt6J52y zsU$Z2C-c5!W5m%!z&nRVep@Y;uw8F21>2q4Z@8W==@3@0El_w&l6-CohV#IcPzt^6 z8~5M~njWySenTnH(qhrIPe3Tdq7$C#Z`swC8s<*OQQFIJq(aUgoU(#ZrGMR-lr) z>}3m;L-O*V{K8>x$SH?uWs{<9>7>Hkr>sxNiEYJ(cG}qhJCEHJ#xOdB?&-a3;qwDP zTl^G&9Zwm=qSq?og@pC)HhmSADuU|GbeL+2hw2nF_Cu|fvES@ewBXdP^q>dC|LRQr zzu~t)6hJELaZm_o(?BlLQc$Q zA$EZ986xy|9R8xYSxYfgZX~5& zA@{wi6fN22bSysKb8U6GsX|`gRc~vkD*(MB6y>v8Yu+%w9Qi0G_g=Y`rqmg^GJd@u z)__&UmIL^1bFPFs)d%xyg-!oduDsjw{lh@E2$z5(HEOx z9W!&YPkG#xUVML&{aJ0I_nMsGKCn8(V(fbHQTx&}sP@IS#zN#=+U30_jMLXHof>*Q zpFs1Ub`QX4WSUTvO~q{wXRwHhQWdKv?+{v1f0MU%A?jft8!8)oaWQ=ZwOM$&lg{FC zhRd9BPJE3ZKEEkYZ&sB3K zxBIW??Shj^DeQ%ga8ng%CO;72-KGNInQBa1{fVpne!A{J@2l`-jQ{P9)qj5+F`@w) zE&cb$|Lu*1gYjC=|JQE=ORd82{%1=6Ki{9H{Xew;|NYNLjGp}e^3WH)sIT<(!;@w1 zu%9Gi0+tUd@szwzyiEaPCj-_X0Yy!Igg&JW@MB*8ylNdk0&XrxZi1VkkH1A)#Z64bnY3F9EO@6sF zd$J4v8!1mMdkertPWiUOb~wGxm}i;uzsC=FqnTnEHVhS?uqV$CL5k-E-#Of#e`ZlV z?ZM-Jeg`=TzHWo>+6*N9^PVL0`f z4lzQI=lR=XK&vgT&dX}o8A(}KFv9u%vNohIf=DLTEW zCc1?0aYB}`ortFMWBmo;t2 z3Ij=W;LyxkDJ&xT-h-LS?cm1A{>E$?O=U$Q$vm5j~`+;=PnHO4ML+LrEfp$f2toV7qaHem(FjI^oW2y{%Z9; zd`FpO@o-=?N3Jn0{kX~S_({I^>!&fsAH zb_6t!q$-NI7yq6Afev&pNE7*#mp4imNMPUDjyP`fJO3kk_%M>9BNGRFB1&P?Qoltq zJl?2sa+QWchqu3Ur%F7P5cIWwC}z|y?TV^FEWwaXqjsDKvN-cSDe{8CO>DU5#bPW8 z%e!ciuPMNc7f3&=epT@|1p*j%l|a0@LQyaCHXp8G8Tl=Nw;s9Iv$Yn#lcK`;uZ|#PrN<{MK&(y&o=u8?PS^M*Wf&hWs+no z#Ct&MwXlD8FiC^zd?xr}358$tk}6JiR>^Q3eMu?{T0E?U^3931RQ61=q-1m#r-eJ?`1wr zb77(53`e?YhJ>=Y<4JSsWEGS$X^!bs}U=*R{X}aPpmbCs{K{!p$vD5*rBJ>7|?B^@t4TA za-k$wDj6}oD3O-W>QYIf<$RF6&5#bbvOHdH5vp7Rq9aFsW-S4Z4yT_*i_BzRs#C6z zlrG~rFwrXV@?qrNC0tX@K?omC%;Fc(1)8r@#iM(Lp1CZvgX>N0IAik~b#M=8JXre{{Rz5l#O;nKG|qXc>EZEjE>`C2nU%+} z1~Y$GW)3hSOqKRoEvJ`vG7vEGcgcZ z#{1~?$=t{H{qbYqXs&R;wUDr6TfyI<>vO5|x{;9%&*P4=$Ijh=zfuA1Z~ z_6q%+_lZNB`R&vqbtKUM|t z3k@qUFak%x_h=Y*Yn>;ok;DqvOu$R5vm#nXE-l;r6)YsgZcMwb^=oLOY!byP?ZB2+ z<3L9WG0%WPwm}eXZ2S=_(4aP<2UrEBpZrwQ4M5DXRe~#W*vd~!7e(o4_-esW8urd zVC*b=j(Hc6Tee}FX57rlQZ4F6@;ae*cXV7#YUI`(eo`cK@Zf{>|4gJxq5v7ImRIKb{^n{(u%ELkg8+zI19o?}y*`z+WVyDIS-Sp+q5ONN@vZ)aE>FY=h0y5&RQ zL)_U;sL>H1*x3f9;blEMzd&;PqmU0^qS+$DiiS4%9nQE&8moDKl`;*x*JAiAL5sRz zU}Uxpmw7NoehW145dQc}B-4D^W7&P6CAfgff8DTK0gd(x2Y)KvBF)f-q>Q`OlHlD& zEG|SQXDjd#QxN^=81V4ij&#A^b_*yBu4uq0u!k`+eskUKK+ykqZe8nP>_m?&=*Ig2ofFo{bJ5^Gx+ISeZr{!bJnr- z=y6PyGD#+@hjDpvZiG?yuU%dFSK_y7ukw^V_dgupLlkZb zK&Ua!B>6u`ug>!y1KkmrXt5xQ`KE5HBkt} zIO}ah`wS@+Ssu=IWJB}Tb@sl!7*boa#>(T*l}MakiXKaEr9Ya3)ho?^|>zj`EdO28FVO?`iojbv51@VOG>P#u94anB#Iw79^1D{5Ek#to-GCbnI++UV3^Oc)lKpVuHF%r zLU2?G`f#H4nLUHRCYFApset@zC+nF~DMP)~=IbiTmh8@=9|}2>eTlf~*zv>?Ygsqa=ZVJL2>gQQLD5d!4Q784^f6PO9qP zc=x+n)sF?i>lX0?0@0*QCCT(klGoTwMtj*CAcT1s@^+(Rk6=uYU*-sNqUQJ8qYn^K zr`+yc%>$Caf9~wrjI}Cmy0|sDIKGBDi03wE?SL0LI(*7CJJ*}m_xdyIzYbvCRN-@R6x9kmf+A9n(jIxE|%$Cu}0vL};$o|tUrYE&kv zseq4fb+BKJl-)6B)2X|$yS7|XV3e&C@kkrsh-unV{5KWXlu)6=TrZA%+9gwBs&3MO9Jd~vWAiScz%lFGTGiiyxYUH*D?TWg z^EV!i2GAVzEY#bzLEk)RceQ_!OZlmM%K{s}0$O)@){G`?M%*po+IH`V--V<}0U^X)BC{>JZ73KPBh>llKN81FoFvpYd!p4$a2 zg;AONg< zGhk7tdE&rzJPYg(A3l7SIQE4i%oa}0?*6z2zq&vErj;FD8+7C-f3n&!9Qiji06Zz3t-*7aXl*gc+Z$J_+0!7DD_{RE!MUk zd@l&NKDG_nCCk5w)X+!;5}=ZsTk+i-vcG^^7i;pvL~=0sa?tfk_a`Pr_2A&yH+Ih6 z#~&b%NW@A#U&aoZwiuHiU~k_n;c~Xo*Ug$?s(%IXk~o?i35wfY$de9eJ)sS{nCSj7 zKyL!S;jV!&XA0V=2!P>RU-C~{cJsOcTtvhC6<-EkP3PT*>kc4g?i{oOigR3<>z1*W zi!==c74$~=x`V^w@osL#P6~DsbP~`#|HDRuUeaY5vKEF#KhLGryy{AdZ30oUyNDdD!(RnXblX$%F3j>Q>tDvLmOH=w#om-^P! zG&_S@3OOH@ToE6BSRIf>o~d6VOYE-K=5B&Tk=1AAth)&HXWefh?b7NQOXzA53N9e)?Y?tO4+Y zPkugd($^$$csl`5LIm)zWZQf@MMcH4`LW=u`o8Ob1G*uuExw&)D)(szj+p!m!lmTh1KKrI*e0$^)xRQ1@5H7%QyEOJ=gyowv?Ct4U( z?3^#@>#}fi)43UmLuT5s3%=dXh<6@u?!4rkGtAhyoU`zCmV&hbX=g-hYwLzxXR_C% z8aoC6eQ{?;SG+1~J)r{*0aiqm!e5R(Ea9dCp4;G86&|wyGRl~x*$O?s4K&yteP3S# z1FkEF7b?bJ9?n*C-%8*8zR;td8p)T19yCnBE`t2-_9ndaT=wS>Nc13CSjJ93aG;p; zV#CjUv^%#Pv51$nNK6EMY1gkTNKwX&( zWq%O2$n)WhKIiVYXBG?wQUC@G+uuP$Jvemzc!&tp%3sdRz$ zfcrI4h9p;^Hr%KCkh)d%g24P_?UKlxX#JAJoPYh2OixSswIj)lW$z_T>2un&=L`n> zD&fx4Wxu{}Mc}8VoFkz&gqF88xx^z>@%&=i|UknBj+Yp>AK9vp5~G zxzHt7=*okPiI^pL>;oqhH_srn>bqU7Usq}Pj7DG#%(jpG7$g=}H%UK7L&V)`yd6J< zZ5fulEjWr__0#%kcK-bqd*8|CEHP`V2ZLj9ms&)ckrP2r2NOZa!=Xj)j98semO&Qn zu$`EM6acr4`sdqS6*D}P4+_6irgZ4$qcv_B{H}3~w{Js1Wr!48uiH3!I0=E8O#Jp7 zSVt?vrR9e3J5}oe^;oE5f-jR*Da}|sZnVMs8~_nI@fqc->hG6Fdx?HMUE6MRxd=q0 z!(~Yb46$iZ4aS;wWHMshjj3wQs-&XO)&M zdHg^q*E*&;4IGT{+!=A_zI8LF5%<_K9H@uaOs5NNxt~1g?l?VuHt)O{tkBA#nE&wC zPD4g@`4gnM>ihL>R~8HIb;Z}T)@AmZUu9I~{B?~3bWwH#L;i*{0757kqB^E^S7G6n zi8eF{M8rL0zx)mWIeOe)14lz<+hY~mm9DwW-9&Qh?#lT=zx>s3IUXpF`>XwgL<;&_vdb(LiwInEzM2cn9V-?XM&tP%DGb(4IQVERyhd@kz!O!vh9n)%?} z5XUIrzcrAXt;$J7eXs_=r>$PMj_5gIem)S^wGUfkI+9(Dn^!-DyMwmCC`nRco3GJp zG~2n>&p#3$(a=t)w-kYmwRFtTA%aSX*B74l7AP?g4-?)s`|TyUQB_!|43%^ANs69K zMe^|aq51NZTj1FP6_d~NhT3*6d5am>{g>u7{TF@h?VRVo&-NYS7-i~dA}+)kGY zuo$HGMg6P-!+udbAJ^64KEJv5i~%b&{`_4FaDU>7DfeEAuuNPVH1?YC0=(}k$Y%Yw z$2dbq`oW;TGKtZe9t;o@BjnG@Q7^po)eFj}ir+Mie>Xk8J@S&#v&>i~Xq;Twxj6 zi*d!uQFJN(lMfLonB3gOb^b{PsmMk5jnlQ7br=lr8PCPjO8rMt^v%q5_+R1z?7;1Y zUDc`7&00kKoJL+;%?2AoimGO>J4-9t2>=iJ+{TUprCfeBt@Tx zHhxqJ$!_efG7%vkk|rzs6_G9D5OBht956o80`$t!h8>X2>BNKC4>mv$^7VHLS?d;$ z_h3URGq2B*H2`zeEefE|Yy<1GYepBFBkn+*E;4usak@Bx!K8ncZ-$QPta`6aztVC3 zV&VP-J}2%pU$?fC?aBw%ag&Oj6`T-4UAC*4BR34ZLxe@(%{ky6%R+kB^2oP;4)bwK zkoKLI4oJc^zdo;sn<7gRU2TklzZ6g2{gI1voalRgx5X~oVm7)@XX>WdV~aJ%Z%BJS z0)DuggZhB;JanYTX+7LXoGA=fr`}H?;XOV$3TfN<>S(%jmNgdGpQiQ7O{{9G z_w~o}h+!aEJzTYEAMl$f6JLFV2faC2`w8S=pnm|pS=+7!#Q4+uJMo-|PVEK@j@5uQ z&EERs>57!YfQ>HeA+dCU&RYP*X`c~y!;5QGy1Oc!uAIK<(3iPB=1rj5T;tlI6XDc> zK!x(I$CHyXMXpV^*O>pS zK=Er9@NoMa5l_6`MF1KgK_-SrfJW)W>~9QSb>XsIrC}QG{6G^OLdBxh_0q9qbs=B1 zG2o+l8j~QlN`Z=nZ79%ZB(uQ?KXMIOs&2BoWUh=d@oV9wDllIKK|SC)jigILY33T-FxfTZ*m8RYJhya zXz&M6pA>o~b+4e?#hrvaBD7>=_e)Yn5@>{TmeeX9{tkD47ouf)Io9AXm1Cn$Zm6=^ z|7*xDuhPPKa7f578MSg^o+{T%x%)C~=7W@Q9y>R@h)>)KK_+3l_Kno6FYyqQ`_yfn z=EaB9fEv94GQ-Lr>Ht{E?_Ig3Uj4y#n-(hH8QWTZ8f5z1k5DSbZ?#_#dydAi&s{2@ zWnjf>4Io5BfEvj;q$crA6$<$7Aj@>-a-tOjBPF%7TW{}Ddd-$BQEXCiX3S7_SCRT5>|g`*|fiRmOmskN@i^~plQ}TY{)RfsC zYLv2$c>d1$M8$$Hp7H!K5U#W*8p=yn$MPCEYRZUTZSI2Ur!L6}G;Y|N7I$yYcm4w~lSOia&sG0Cy!N;-QON|-FHeq3Wj!+R_GXLQaKZD9(x?~ zy1VVYOJJbG+k6sn$l@Y&&lVI&%P-xal@Q?;%#=GJj=I=H!EFeE7ANJ=_tRW#ieuFz z{udE|&7>5dghq9i)YEG##X+EXPi)Wna%3wdCXUOMD!D_zWWLUsfK1P+488Pk)Pwi~ z$l!UV-pJqmhU~~h?OwPv2wQU%&U{0pnQ*5j9QiD`l0w$O5I0g7bdK{SBf>I3YM!CP zClW``3NOV0WRqFW95nAcFty8MKMJB^E)b&~Q=&w}4xe(rNt~UJXW?Qrqm36UBiH0( zd9Sdw(d^l+zvx=}>$1O(m%a(P?muscMWRCfShaw}Jkux7tH|F|4DH!6uRxd)Mxts) zqJ{13`DT?XNf9@C?uaX&laPIt8B4>xu*nz|5!;4iZ;&d&+HX#emgR!LtBEj+;2NMQUV8d z3E&;FIu*_@{9N1xlVZG>sL|LUn;VowMZCuV!J?;^0UgVMzJ9YCtQ*4QcDA4J^8?V5 z{8^~JcWg)=cDv7eca6q63InN7Rq6it_TgF5ts^lhqXS`AM+RP55c0RDOfufYDiA22 zeq@$gT!n~H6nWcu7NzK4@(jG@HY^<5z~ED8z}jn@3@I7YT99`;KnU}O2~zh^k8Tdg zUIaM67Ve^WpQ4iBqb={H$MS|93DaoQeF~M~Kn-dttd6A0`9Z<#%oe0PsVoa%BCIvF zJpnx5ES*SKNcG#Bt+-z`?VK%T-66TbVHiRQmH*I(^K0niO5*N)W^%P-5TeUE5#oot z&T8#XIaQY?utaBY;P|=h&Aau1ZB<%#r9Q8e>&b-Xw?E0bgu*Nf`Uh_bp zMcp!4x=tfb>^sJfp?}m0Taa;SU;N-3b3lB;1y0Df{C?4gKnBcP*7HHMo|ElySZ;JMn@?_b!_vW0VtJG^eCw@h0CQV64~08OcY^)HXoHCRQJ zdm93UF$LIRc+9A9t!09!YYnqx=&DB#-IXbSOuiGlEWPK5AS+bZb4PR6uN${z&vWBe z#Vk%eOqfI=)Wh!#Eu{u2^8$+uQvd#sM~HCu(-_2Bu0OFIV~&+ax?OBJDsgUF+iH53 zw7io(A1`mUtlKgtRu4Y>`P^u4Jyzi;0OuHG_-6jziHgS!f7&aH{a#(X)UP}s&u=5H zhz#EwC1rg}lr8>2x{N+<$Jy{L=}p`Y9vn0_iT8R)9+}j-)O*ft{d7ottb%sBtklrv zP9nko`#Za?bncV7*Xs9u=UeozW;L{W0=`zld@##H{L+c3V9LWR;PJVo*tg}rkdStx zV==fuGDL;O%o)CQ)9Mx~nG9Oog#LglxS^;p^IqmP{9jBf@M5n6@F6~8XM?(tq)^1l$?~iUXaj6T@YgCl8prf+*f55pM)wwp zNnjntK>e7^(v~n=LFO8qn__eSJPG6;4`Yks%=HAfk{Mqng*+O66Aq&% z+7Vv384E#9RbwXLy}{N`$ry4z+pzl5G5K(na;jM*ay=qlWz53qxQ{qf zs?6CL((&4-kcl+HDxz=N%Pck008Rupqk}EC@S!ND?z51b?$d6IiZ1g88P?c+1Zk%< z)62bK8_yuz@a@1dQ)0c?CbXh$oxlyU9Y7r9@dyQAxRoo`>aZWNRL!Pt-553e6j4GS zi!so=?>=9E-6sEGfvq@17*SwXi`FNZ@cfcwH7*_m_e73vY3in$6v&%zNZc% z)vv23Jx}?l#pdh&7`<4dRq9H1&K+vmVAK>l>m@V0BM#7`udCnfqqHo`^FQ!uiCLEI zB?ghJJKMeDH8+liR7{@3ues@~O74m03!IqV7X~uRY`89e$_)J`!&DF+I`PO8%9VJ>~BX2b;z48TnOQ6VHB(((tdgUpnYw&P1P;Vq4RasFBh$TruY_V_JLo;N! zmdYC_`^_$F9g^Mfxv{n>2k<+S>#~HF^~3OzXfEEkn-#WC@Z0j}4OS5DMNC|Cvk$45 zYB3~qO6;b|9d+Prki)r{m0%3~SSD9DGJ(r~V%#}T3>K|ZFhB`u#LcN>5I6dM$^?_| z-mYMFtAHBMG3mKPJ>oAyhIXIPZRAY3z(1mBY!v^AK>n?wq7J68c>5`V?tOM~5~aFr z>?C}UiEI0r%6SxjV0WBskrEwUk-+Uov2GKRdR%V8uw_VBRGe^CFzRP~vO&2QkL#<6X(>c>a?%esuA`Sw~`}^R_S?9NxpB} z+0tfexSB&R_6eJmYNR%V!xBb|^%+FAvxN$`;FR=cBjUy}g;>Ov63eCzFMCR&8vhyV!+`|!r z59H1vYwB3)JdQof{Dh@I<1JTK1v4sc#tbZIB_dS(&ULF9r!1gc4;OX;K+r;2^(;eNe zm!VIW{#BP>wi7#1M(yPgx-OEqOg_&VXvAKv0y)O_NnDU%(+|X#ia{$kEI!nptt;}-!&H!qB zJr`O28jb2dOXY~fS%vp&6bh>RTDtLO6D3_=BvA z;9uT7@YvF%>e*7XKv*Am!;O~A)EzsA7D$5n0>T0`Y1v{kOR9Y&v-EG$dhX3DE=V9q zfMkLy!covD*a$aGs@B9p%R?KO#CjT82+16rIQu*|ThLNwWpuSq@A*S+H3ng}J@lyf zDRE01ph?n96jo?`(NV*cHa8;2c*5*J+`U5EX!ajZsJ_aN_Te9dwE_cCeaHFE zR4#9+#Mq-_nT|ez*>ns@Tz!+|WBZAH*6x2whoh7*6jE8o-dt((_QeO(4cWn4$(`&} zZdr8P2||BIcd=65O&tA^O0`4d?83D?pre)zZui`fzj<|hi*id5ruiJ^pFsmBKwZ+m z#z0kcv{J5zJ&83~6pKg=zauk2)&^fz^4Ygb7x1Yp$6$Z|Qm^nrS7-Bg)Vu&8n#_=S zdmhtErs@YF{MZ5RI&nKFpfYf!EK6!06zGPpv-%Rj3>V#ySG=l<_ zoL3-Fq8lt*lUr$(^1c9s%vN)vJM6KCbvZcG+e)H?=jDD5@0?h0eIkiLD6_#H|MzUt`tGEA|cuLr2on97g@d@ zk=R=46YoY6h1~oaUA_8VS>r#zn}@?zr+W2IsTC}Gd>p0`p6_G}=a7)!HX__8>H<+! zx)$H0g~sXz-)}Os#hDQ$Va*31P;62ZzG${S)RSNc;6(a`&3q||sx~I3H1%7L+5vPI zOWz!?xj*8hrgZK_l7}%)8aWi*=2`>fGM}*qy`{p4D;BzD5{V`j8|A-cC4yt>$uma! z166^NfpNnEZ5!m+Vt&lN#1AH>ya!-9K3so@=*cYodI`<^$0$4cfn63j6&fyo5{i=C zKgfP%E6{T-wp&CDbS#}JdRz#!y&7P!Xqc`6RTAMmCw_KeUFC5~7ap669?o2XeiliU zcG6)MTVbS+>4cSBrGf)F-=P`g9BM)D?qZP91Dx zlxF17blUyTtGqqryE zBuM<48>3Y;3q=rK^0;sup)PZ{ovnlQR6kLXsP;F%%a-)5Av5&&6TBpREZ@>aXRSCS z0b{i!3z`Tfb$V9LuVfN^_rF+znsQZ5^_8b%b22&uebLic7pM=0Y1n2`u_o9&KTAtx zeNERq;DhW`5dqWL?x;^L$%CZtQW~SK(@{@mIQYN5Xd_v;-)LwXxMXA~S zog?WG;}O9_mOafc_k0j z#Gc&%@@@XN9vw{uDuyy4`*6Q!oB^%vxO&_Cr<~uh)YN}i^DPbFbg6N*n zMs%+qlLUKD&_9Z3MGD;^7vL0y{-dLcy%OgyFk#F*z38Ek9mK9uVh%mXMZ+#4JH1R% z*iPDXb;Y9#lEpniq=6?+>X>njaM)t8d06r+nQ`YR(CA_r??1?g=T1<7W6iLw>&BjQ z``-o*rE>B?xE02P35C9l1OOTPB!L=C>*C=*bDVf+E>eqr%SMz<)EJ zEJw8fO^ic;Mq46`VqEjn=6qNv1{E3`ah9eEelG%02;?C6tg+aZq?QAakJYY0!)Dyv zr`T@iRd2wQ6s*LwNfKFZL=W!*G-}I8V`b<=?%l6_TX1A26K|rPlTs_%%Ojb^LW{8; zYcVHv=&ecN^ES!e+{oWB8I+{*k3Wf7xdhJV`Z`W~a3(1zg3`i6CC8FO9&Uk)0h{of zrfI6P24Zp^_UJXpP9EOw$6zcb6nQl?u2>Y}f}5kt-!Yozh&9~DFFF-%*t(?nrGYH( z*JW6$PPZRoS(4nY2{QM#+aR5~u(Lqyt}nh|bJJ|9ZYJE1HKWhQSe%#&dJv#D98-|b zZh7iO5%y-rHNhwc3QfP63zWe&jl#B=f}oA>AwXz44oGD}Gc#W!?SRds#_aiWWXo`@ zHOF(OA@wi8v}mr=&NAg%0`ZP$k>SDH;@5dyC}ZI^e)*O;A+y10z9v{!jJK#(c&MZY z5=w8`bKJrmxv~FFT-`WsN_Q&C@M8_IcogFIq9<)x1jn?dhN^gOS1$hK=)H=(S6P!d zm{f)0Ok~5Ju;!K3w(NXm>sGk)X}|z6?>}8P4fCW75;|}=ppOxo4+`W%N zdtOca8HalA$Gs@{c5`?MpYrpULBQS(N51#se$|hXigR#vBNjSlFS-!ihbL`sqBvyMRtjXtxADR&4M`Q@Or96ND4B3a83hj3=l;vwNATo105^f|&2}y4srSqMTo(KAB77 z=H9;Zm_X*l2o1J_Y%nR;#zzIQ6lBTVspo!)Y6-B8H zlwetre}fpw3MQhO0&lAJ)VXSPgGYqoKcHsHl#7h7C3KwAEu z^fMwX1v_Og*gGd?P#jGcR9++ycYK}$t+~0pnep9*7eLLS7^rnmQq$HnZ_e5^MJ^MKiqd!X4su`XgS;hv%c7QB?d z_kCKdvr1_gKV>s^x*TiBSzP(e)po_}2U0DpFl?pRP?X<_a*5||Qp~&|uHu+yX;fiK z$qt9QRIha0q{T4L?l}+7;Dk-DCD!BJl>sQDi!P55nJCf`Iv^Wa6P`saibV48l#Qd2J)D*v(~ z`#07j7YNwnY9gzH>qE{<@<}itX`?XX`H$p0_9`00*Mp;IOs7%6Eiu>)VhVFbYtrO^ zi&o}HVXI)HvAkXY?g7M~kOi`Ksk`M_x^vzTqFS&SXN@HEfPakky@-r6P+~8MihIMx znPvQu0Uab^OarU8)A>JWd(Wt*+O2I=5d@SDg7hjyr1uU=l@1CbMT#^bw9oSWPdPjPGKPe?zat#{nlhlp$zG?3yIq-d)5_XW!^B06 z6DRpT`E_d~3s(}bApY}LUFHFn?>M{BCJn+*p90blT+N9QmW`uuExdC zWkdK;1lM0Cxe1irf~@=*k4zZC-mP8?w8HwVYBKG6&U`nhdvG~dr0jq25xSkS#Mewt z<3}|c9X*)aH~vfs5vb2kQM`vqzUtd|>p(pqH4`Wua&mHNlqMm+=Lo-S|BE+3g9F!^ z-^4W}UN#+;wT;ox>kI;m{gK&L;!NCPqdsEJXC5$m-8SkLN6?Hq>0I_7V zbsBzf3lun2`qNz?t`sAQ#aVcxgsT`ZlwG%&lJVhaNHM<2vAWdh#X_3ON$r{+CrJ`w zn~O7LXk?pkn5vYs*#g%ey9EfC`F*EcAOJuhoSn*mDNUuD^DI=rfD|EX|M!aHeDOFg zz|G~ElLt{SZy#kc(qoQ@z^7P*2f=hC(b-*lZtB;^I&Kh0PHiNua3+8D^o-XrpEzo^ ze43fy(_iq13aJRh?tyGYWxGH27ZzGt~KRmf;7ETV|v@_l3zF^u>V3%cOg_Mpo zpS$ldEX9D>s|WeI{qJL#$!q%`TwQbSkWbvpH(OJH`~T zfBbv$<&x%&oGz71b~tT27JJ4ip4_f2ua#d&-1?Nn zG$nQoM9{a4g&bTA&akouzGj1OR*y4^o~H# z!oQ@;I@iw@6|lm;$|Zw?7?CkS^A^tu;{P=L-(aFla-X=1d)S#%{c2@2bzo}opF8-i z3#{|FQ}d>C*`E*e%=AxS&FCH0+mGaO0pU|ybKE+DRkd2#jY6y%oEJ9B{?OCWWrjW+ z<7;Xo&?h+=%~$zq7TCR~Y|8qd7WZSFgJ=1;t-FUCk$DN~Z{Fgs*+N<3Ib?yg{36r8Vg1vfzvv2BiOh{1OI|KUzPHXO#+e?(>f;Aj7O&|wM-*#En? z{?{KDMJby84=;KdB_8|#tqAMLZ(5(e82tMk%IE^G$BPnY3z4JmUlC@&`|ElmJWBQxnf>7;q0YbBXs{KY4C(V0o&2BcM zh0kQ=zbZX(t6rcjZEP?7(UbRoKOB#Go#FiIwZwllxlX2G+tBVErl8r=AQ$>ik@;*C zO?ALa9|=z02mb*cUlL4^l#JsQ8q?UEOg8>gphHA~OYr}(k4OG*_3?kI|9@{7|9=+I z^9_bqn8)fn7f1QB4##ww+cmjW`DNoj2E6;Kbo&ger;-rTDgP;FTA0FycveLFj5}TVza;by|6|7y5tLni3IO0vs(Fi>NuxV zDlZks?>jSAHLpTG_B3t;muPco;X_?P0&5{2CiZCXvD6aglQXTu5GZWkNN-`PA(4jO zBle;;sXTJBWPg!xta@Vh!IqrO>3*W%fKHi^`KMTr z4QN&NswKXs-G7hekJ`QUT|!zBD~I7}`v*YO6fwNS7+7dOr<}yX5`4hV7?Upi+{XJL zN%X5R9((~$s+OF5K-|}xHKe$T`^g|6PlxF#Pibtw^!Y zb|3hqi>J1i+Wf$ zrT_KjTM&A2GE+{i$FrQJ3m772%4rN3gfgA`f5-npx8!`aG%^c^@t(`_T>UyaM=J|! zQFeBE8$L~Nc5kN%>#5dZq@?KjQhu_vf7bL3&u+ScXR20nK9%K7`iX&j$lC_z zzaG`I9sQ&l>47VQHiSMM2xpmBfk!j-0ShM~)lUx4c4ap=N)7Fvu#g+eiQ!BT*u-*a zGOVOTXt*_BJF%A5yS#kd-&=DrP;1!pC-K^vnf;Z>~FX!Q6MXbapkaU5}~NJn|J z*QbX$`Ez7CwgSnv%UeRK5`^x9>fhRgvK#_!(ZT5sXdatfXZ{UbldncQqx9mHi9RyZ zE?Kl>;pNq!VZs-butt;9tOg42CxHrSwSWc1rPPU|-)l7&o_iUY>7A0OemC=J(*I!V z4ZIXhhkaxOT)ubJHcqgL_Fl|6eU|X!R0M2NOlg5opEJSFM?2%|p?mA;qcy0kup{-0 zk&Gu!qvxhV^Di5w!-Gk76Eq-9=Az#?8e(B*!H>Cv?A{mq`fkLwf%fY&HMV1ctf09` zEA)9&H&0sJo4f$zs(@9;-$=eOtB9_KNS4#xU>@LwV|`%~(Du=&gey#Dqo*N?I<@j~ zXgGq&$VS?SV9m5i*wqd;P75#6oS`{5II$aF5r(6SW|}N}Yi2;`v(9NK$aRPJ>+Wjo zWskfmP6iEAinz_gaEY^lsaTMse%4;r0>~T1u9u?2HCo3*3*0QIyXY(e!fz4#unI(4NjB6_mCKD(MEhUbIzSMU2)}qmLeB06a zZt>2eR6*!|?>z+^TAX8nCE>I6%!kk*V4>+i0cD5sQs+luDoPeJsX*&~Erx7in}=NH zRS}iPD=Mz|@Mr$n18{ieJk~134I?YircD?Bj-S$*ZQvGb)(fmejJBzOl3w%9a=#pS zV$>v1e{tD0K?_`mBriB&3ihV>r~orN6n3*CJZVLDHvyp|2kyaCAm;mzy)Xsjj=G-W{Tu`6G{E7Tm@RGuLkeKnT;_8Suxi0*lzAe574!LnSnQ&%!_Fi7BXGm2XPHKZ z*5j+PcB9%2;iosf zfoFydne85?tImUXut)Aq5u^+TPA%SLze%3;+^#@J9*6*4W>=E5RQYsGajZ6|p^n~D8WdC?)nejy`3sB$Wvy%Qo-r}IC`rcOF&zAJ$4QA>pqWDo$mtMLMiBvq7@Rmrz#lV$Bon;)}*$C74AEtT6 ze@xi{^O+Lt4+}=|NlS$Wj;4I`X=vauO0}bvhMqW z8CjE_YZry7kG|{l;m4M^mdiF;2~itPB0_-x%~zHo1;cj@qU!IqnLCUZGpk(D>5gap zU9yrg_P3`fzglba)o3+fIE!2lh0%THR^9$gFSl4)g@S7RBStATR0W|3NO|(m=0i}> z3nwNp>kWU2m!w-PtJRxaRzZo=I5!Cxumu)L<75OxuG zn1-o@MSE-EXa~DN!zjn-II1FTP^FHCU>{Ql?wTSk!)p5yJaGCYqYP@AlX*WR-@mNm zD+wb1&B7@a^r?kA)6qcnigT2F>l3VCLkid%dS-XL6kKwCn*N4c6%Er%D6X)aSGyS5eykZj860lfg9S(oana-&l@x= zY5_xeHdF9kwHe6DrE)yc9n-RmElCYHW8m=JPW+vVpn$;G6UNAQyHmBbLNv@vqKqj` z74lZpl@&h71j;vyZ7M;iS85+eU2Yoq?}z&R7){pa5y6zVVeh>A&`}Mw@}G6 z(sD-jexIB-;CiLmb!QX@ni|}0AQRw`wuYMG+r#1evk46bc?5>;O*$f?yMRCF4`LU7 zsP(|(tx0v=a{*!Zq)U@Z^Xw5}Qd^(v_H6HN_7o15Q+Xx%HkNzLZbePcgeG~CJ;fG&q z9Nw}Y6+gvV( z0|L(Jzj@nyDG};^!LPWGx{XIUyOk7KI9gOVBRLUN$2afHe9>hQi$W?$+qQVUhE%TA z`~t%l+5H2!WFkIkU^tJsg`F)Y15WxfIKe^{XyjS{j$!A#CFzpF)##8I{HFputG4jO zTI?n~3=jmg8#;O0a5FXxQ~4hov3g~Ifl=CPGS&g1zFtEaN{?G=5abio4g%>9Pa}Ge z6#M%jU&go?)X0t^uJ&QF{${UcA#=vtW`Z#@UKc%&ywkc9^TcF>#Th8CIVhBfIl;q( zdXRH#)FE-WTsb-%BkbsJ7O9*>_@1+mP8^Z7({7I}bUTw-V|SpbFTx<~c(I(Pl92Ys ztg1Wjm8987|K*>if>vfT&7NrgCZEGCSo5{F;A&jZgFP$ZayQt4b4G1A@K0-?mzxmy zkjtXUJEtQ~Y{LSh-H^?lnIn3C{PR_vyoc;SVn5xLbsh)8UX!Sy@fec|OoGpjGP}!; zgTJ@;Uq!`SCPbora0^>_4(MuC8aT zW|i#RRTW=t=i@t|y zbxF^c#6>1C*R!Q5?pG-e@FuJ5cBFOvocAj*BFodw_fIG6`PoLOpqxENK4*fguy4*G>7Oy%T-3ZB~~vb`nvGB*}A9EkPs;6xdp#K2A(LxSuww?jmzBc$3}EvON41 z`NWrGny>Zrbw+Rhk1yS%4eB6U$NuHNmD0wm#x8?UN>1BRwfLWoo4%)~P9QW&YN2Yi z8dOjUkRV}B6HkhW1f{q6bWhirR7<-a`AIwZE!5P`!nwkP)#6-b$xD&UeysLzf#K%s zfz-gOIGywd72N=4Klo_AEB_mo^arwi>I;QoQySW)P83f38ur`IcH13dx(#b?LP%_P1z*+4|;3T3;By zln1$gk@U;y4_?GsYV@=8o^AVUw>v8lU^$tZS4XMWbD{Rp?9Quuc%KS4=Ki=${_*vT z2*|B+X!#ntg81pDt6y9?I#B%wz25en`aHGc3CW=A8M9*9V(Zc0%VI8NP7FB{AI={O zT<^-*PvG^FH#}+_8N8PR0-Y&*EsdT(2}dU=Cso`ZvklRX!$+N$NZ(gyyQ}tSRfB)_ z_D4(surmizOHv}FaI0pnue|V^%w=vH&f*-zc)Zx(^R9c`pG8mnTfq3!;Dh)$6ffUy zH1k$NqZZdfJ1|Ipb^F>K&;2oC8R+(tJB(GbpK0m4k9O<2IGJS^j~y(c z3vV`mlX7f>lPxKDA?Qv2>F(<;v5k=RkvUf3!4{NYo(frJbjC!e0e{sYYq4s=cQr(q zNh6OS?`)*0oZIq}Rs<)Gi2J+#Q)DXldvkVCmh#6&+sLaSP9-AdTnpE!cHZEjmEO-m zW7%#nRT~RmUi(>Bj@%qka~V$9B_F8PO-kIDu+byYP@5s!8z;m#4X$NA3+WxO)v~_= ztp+yv+O86kFB?(Nlf&mviN_)G=JZpM5zrr*S9uOQzhb#;&X_Vz@1jId7ZFQu@4rBBIBLkL~i^z8Xx^Ob|$09 zBMWA^%RbL0-OKSDe@rGdT8~LK?yMN%WW(dyt=a=G6+Thw+3*j?uyf;XrB#xQ0w32L zb)d_@>)AF0kKz}9l?X1M%V66*`gg^^&aJcHafW*ig8vbtj-OY}cyD2Rxr6GW@uD4W zh{NMUG^jtj(+N4-!{l5!^s4m?Q0Eym0{@yu4R;RIZW%Xr8I_snPX6YYHhzs6bQM^< z?n;%Ag!}~=oG7XJqXv+vq6dey0lo6B*?W>#%Mje1%TLJA0Ivle$gI++tY;zA< zargIHAt<`N2z@BVAkjRV39_^aS6to9t{DIW^~Bwi7JgKPoM=O-&vOw>1&=_92aERa z76J9iyisQGg%*c%dJ~$0r;ReRSA?~m+GB-MZl;VELngR7QQ?rTRhzlwB{m*?vb|9d zJL<@$xlQYqxzoR2i;2kszf^9`jA{PLoZAWdvU}L#9D}cqP1k*^fzFgb)`DdM8m4&& z-ab6nfE+RQB3=h>FDR?{Ho22cGcF43aptEjq4c;|Umwg$?KNbx5(8->c9Lq=x$5W- zeX>mwBwSxK&P|CdD3@&>{CMWn)NuxsrX=KRmwt2%f zR9p(V&pO^Kuni-eUKE_be> z7iTekP~8VKqpd;St7kk49-gs#vqDtLDC?y`grSv8i<4_#bS&Wa^)nD~h0!!q9Z&zT zS3rC|(7}>lvZnv+30ZLL0w3Uta6_CgliocYWy<>W1{w1ZjiRA5Q}CF*ZabI*Ux39_ zz7Z=;ra9-}V0vOyb*%AULKVDFT1kM=K(K53#TVR(S#;`z;u`1jKfcVaU3fgWmEjOZNzv#b?UI=!UT zoELMc*TucK23v$cd>9VRrSL?+?d+GXYv0S%&4!=H%sW?6FZM9(vxm-C2a$)gfUh{{ z(9XGqx-h`PmH<9H+Sr*6pJku0v(^-)+#St9<>c9boMH+!)R_)hZ;E7;(56ix$+A6E z;j0JT@tCeU3_L{(ssaDZS6z$D+6j#~%kcAv<%B@|QW#6w5*4PIrb^t1Y#s9$nPp=g zrsI@a>h$v-V|Y?tL$l>tpbw1AmyU1-sko|JW*=-x{kOAot8^XR(iWa-&oY_2V2x=#;nz3HZqfV&t;K26S~= z3H#&1(KVY#CC2D6@oa#SpSO0)(33toEh0uqP5@_|dU|g^XBNRTeX=G?tGoFTNA%wj z6D+p9!3lkCE@KkK993xYwL7!(y24p@Yb){K zvuX#U2bvFPh_ZyGspP5*h=U)8d~eNmaMOA47G<16VE&nmKMVXWcF8_qyDJR(4wpd% zK7Z9yuw_`eGrDwu{?*kEG#sMmN|khokC6&68^%*gPuaqx&9{j-1r9IU=L}F*ibKr( zf0!|Cn8eU$iswkmZ@s~l6)_sg^0r(gqEB$^HqR8cTf(>oR&^6njLEe1o1>UQDUO=m znL?~E3Td9>bgjF^gW>kEyVlpg1%U}V+0Tw-w_o8th(x9f86Ju(2EAE4J)*0?!R4e~ z*gweTsG(fZ&;i?c z=M`(4W{JOD^@3Qmq;LMji~#+S*)LXuvTu^YTXsr}Yh3)lHhm`aN$zMk#OyNM-qqU% zgB-0^qcvw25p$hfBoFHCCac0|CoA>WYwQfy&7L!5W{Hh2O2;2aI#<>;uNTuvEQ~%! zDBQNLUSEN(oLfa#KX5K_#aC3%LA}{Bj8nr%-f7O!0?)gxR)awLWAI-Ev?7u_A(ih+ zxXh%4;L#T#U=be_xH_1@^5jd&?_3s^k2P0KVBxV}Te(6!X_3V=ki#G^$JJ==!ttLz zLABa%-)z6ENJ_)rg{dj0)eUexVoOf;zr`$ih!h0%L{GVyzc(d=dhbD;Yra5a zRps|qh5WKKjCH39`x>R*SnB_6sP~b8qFO{dFgeXqX?cD=y3`DA%}L4hk&p#_PJm5QKMTId^mb>_QKW59LHhYo}u+yI7c@qOt(* zgC&R(bKOl6jq{D>dLmyt7CA`AM@&O)&NXNnPcyJw#fZUVbeM=E;k{oZnW5DtKCwvu z7p7T0psZVt80)@| zzG2OP8KLzWtB!Mq)Mr^*Q@)(PlWo&3zHxgbLR3=71kk-F;>k4JdJM0?)3+C&lhoP&bfs(0XttHf zZ@d_|tYB}OWoegq6NGrb1-D&&{{$jq|KrfNzWY#t!QTMT8;fq(f}1xu3arFl5}qln#QQQz;?vf`BG$-DTEDg@3u!nZGiG#N z^-(&B@4$u(C;1hbw1E=P2p7Do%Ur?q-aY}P+Y#OICPh~UqjV8>Q7lw_eR>qu47Lm1 zTanv1Y-(OLBpHOnGyK}G?O)R<>}@~NT@(PsEpWLdXRh4nb%Et^gOYZhFqD?G#42yeB#y)m8_6lNFiu+vtqlM zr2GW?=I_eqXDKFzgKIIBGnl?6r-$fcIs(~Iz;}-wfk)F?6RPdU{d6M5x;-6}c0E-E z7eiTu=xJW!LbXOgZMjxa3zQ4k0KVH!Z*22`^4nFcvSgwtmQx07zT8Z72_kVi(|_QU z=|8M{D5j<&C;0+<07ysOquiCuVA-}(VaTr<(J8M7*&QrRj=-1L`+tne_Zq6QwJq`#yoz&vubw^%mroogOufC%IfM5H z%}E`14fZs9S7QJn?eMD{V)H_+ZpIR)q5>>?|M7<-ljaE)gr$F!StWs55korPI$3uc z;_^n$U)9C8b1D376(Sua!3%~Wfxj%S|3yoVZR~NLQFKC|!;cF}F=UF^6BlLVeiiM1 zgvZttSHE$G=y=k^CoMfQI2h#r@=E=NqJVzsw-}nU@H&msDTw6lzr$v&~DTv z?|aI4FD{-0`!w?RUnVfceoyE*(N$#>{w`&^^@tjfEOYgDS3(%aAfGMT4 zKq?yNyEt<>hQ{GE2Cs~tFq~3PJ zMoUOY0<-%Fmu@jnN2kNvrWNkD+{7tt+Q$lHK`fwN#O?!o>N zx90N7yHmH&gDF9U-|q($;q(#21R`=b$RZ0^v-BP0m{!7jz%~VssdRP+>07wEe4*TP z=C#^@)K*xU8=@J0S!mf9_4MP=r!DH-m^Hb*{>qAFNyJQBdLy^}<$QJM+NW>cc!;^X z_M)+9WAT|C*vL7?DWLW3yj?oL>mf#4R6_z2dJ?WVGT~p8^*daCEz11mT+OE5e4vlR zUD(BGT@|xJcihz0mTEugXwiBTrrh+zt^~kKdEpiV-d?3eWF*C`SSw5VFM7L;uY6i* zNK3{KMBKGFcW5<@K{L$9;viTV0 z!3O0QCom{X;T9?u8K*4+UDGS3Jo+w&DsMBbzuoL^h8C0O|2alzESJeCfzkB|Pg-aJ0yHI{wGe(KNb4 zG@vC`n}LDAjjMTmuyB*Q;vgC%B@rB<&hi!_Bm?S92Kj^gug^QAi{df`IRO09{98wj z_>GLpw3LxQGQ04|9#y~XN(mZ-8YArs>R9dG9vO`<_OYD(~EJQE63 zss*cwS_pX0#E*|dP0(~&MRBo4bK6-iSv{!r)eue6M(T}zyz^VNUwj4rx7N7agd#4O zKMYNw*oKu;5|_P8^Vtb0SGx2f9f`;(_&Dy(@EY<*ma~TLn}3U)P5H&dDa_@GKO+en z{Yt;}5%93=`&Hl8>Qs@_qGE(|a75pPOqaV;B_@rnMF`IJB~0ik+CVXrUsy#?!x+KYP6zUCz09t&{qS z44B7P>pbDH6m*dFJLWR%-XO%>aBKsI?4dg#v-Nv<>6kS4l=5;mV`jAsm zlDHF(x%AXrK-t2kDnE|q`G*gjA6RAT+3vJt0_~59st|X@03ULEw&m|*U|YvAyvIXp zr2w!Bs}|?WZ*0iVVZ7Ga4e@u?^}c9cxj!rz}glhim1>lKWGz zhKdRei4``2$Of+laB*zg0BHVET)>AM?dHpjT-G%uve}8k?twSPWsgT+n|{E4@~R`~ zN6;0_+gDXsKOi?~o8o1Olx!?nx-KT>h=LenSNG>z~K(sG|URbARt!4LI{EU?jn2 zb#_3@+ckv)7@N$I?Q-m3A5wBEqeF#lnW!Jl1aiKnZMGsQa@mmP4TY zo3zxCz7s>$SE6iyQBePyNd64{w)d2m!)WmGSZzk_Gd6HSpH)fx@53>_5%bQ4itmm zL>9uTZa2cla#uC%%}1ZFGG!UsjVlGtBn$bB4QF)1%0#fj0I1wUyHTmgAER|QJ)e)( z1M|>beDUHCt`D&ESLa$Zq3s0L9iRhhE;}W~E@i_;ome(<-`$JMi{8$CSSFqc;t}wK z3R)3r;6jly^JYNjb!&=A0qXBidVbT7ieS&3QO5WgX!F+^c$W}uqe^09jetskN5oKj z=lEy_7BvO8d@#)rd3AX6XOo~y{H`DW0QT6`ZpBETh*{5ROqOM*W4sUPel-pGFgCy0 z5Eq5cXb;SMmkr``B4J7rE@FPSmFXz^I29jGgPF#vzmC9(@XTH(*!1xRHoAW7k{p03 zBS~!Ukr=*?(Zs^jxs>wo|$hMqWA}2Ze}pE%`S(v8o4Uw(DYKS1k8y zHg2#d7_n(gtz9;jGy(xk#tubf0Xp^LTM$C43^L7tb-^$_Xci0i*k39T7SVm(XqhDOLvK zXV!#O_?7qK$nS;p%ApS%t_?|9Hv@$TmBtcPeF}P>+ zkNm^A2T^wAR#4UR;~Fft#P~yeM$BYejL7KGOKBF#?+2!FVfnc;W5f+)*Givp5+5M*M#jG+nJVu4>&|aFjj(HlN!v%I zxj^7nd%*R~JZWtjB>CJ?c8Q_WU}5beSyBGiZH|N#_)Kl`PnzWxs+?&*PrpdFeyrHS zTR`~WVhC?gO7a>Z`+hF3k!3|A$ zac^G0S&B-?0a(ou7V_J~!f8TUD4XqbMmp=%o8tA5o*^7(LSX2!_zjV~TIZv;U(gXY zF;U~B;zz(Rz#^4k?mP=zq2w5yD~yX*(_q71@pk3V?TfUJR-c^Kz{c(P4H4Q9hRr}= zrg*>P<#MeQHUm#nqm7SbGB5YFJq;?qbNp2OtvvU(HuILvnN%c#P+FUbEv4-qcWzq~ z_e-&Sx!wMW#wi4~@~)kbG1Ic)_iN{Tl*Qf;%<{Kv$!W>hTs}Fac>@4)z3lE;_8CeV9i2wab5d`9@(o5 zBMC;*=?=e-j{5$S4q6JBeRs>Udm0Q-+}ytx`;+REp_YJDRS$54_B}n5UxvXSL%bSW zgK_0!pPBMikEJ-Wue?!-M)Q&#t^FOOKG+bfT(HwgM*ltKKE_=eH+6M?B+ng#By(DU z3jF!vRdUUAV3;7;E}zc7s4em6N9{l#9cY7df;8$NTV`7G0|mnB0nz8PR0Bx^z5lu- zDf0;U9~Ds%yc;)X&g+B`*KGapkI-R`>Z}H0g6Th65N#KYjZFI%Ip1r|7u~B0Q6I>D z4fVl$`99FTStBSNpl@FKM!MLs=Hha`DO=ge zXT{ZPUADT;MQatp!>*qY%7Tq{L&qM)^jE7Z$gg$8Ne>573cI1 z*@ylSLj-Xzuk5kkx>@9glElJHV)1rm-ghE=F z!(tT`KNs%8MwARgI?gAW^gU?=p^rX$_FW|^93nZvJCZw_`|9o;Rbh*2ersjQYd*d4 zd+CHSS^`XrX{i>?u>3nP?_ivIvPAN`FT7Qye2Pht%8YL6jguqmiq34g%O}GpQNBfF zXM0C^_5Ls1VS?s@!r?On>#}AoGx>aPP$B9pRZoD9B4+z7CAu!`YL^%@o>{lc2uiDdcl-+ z+nDnkXCq1~eO=lEF;XsA^ngLocfQ4ZrT2n@hU@qr%g0*(U}LyqPN zns=2d6is?aLJr7}eJzp{rMtFU?gHa1tLA z81w6YDspID($u!Y5pr>5?)+Z%Nnc7U$%{%J^7QL zNGbIul||??1!k<-tV({06tDzplYtdw54e#dUyvj>aP9feFvn!0C_n7-Af~h>oMap% zSJ%WHz%<=vKV>DsWS|KRMsTIveyhl$@bkfQ(ejmuG=pM$@#-wD=eM6fK0L9A=RUSm zOV^em`FW~b^fBL7QtNMzi;c))f-05Y?$2nZ3Ef{K{v-Dzy}wiweEJx@MeDu${k?NJ zdOpuaX+;wOv;p)dDpWb)65jnWf*iFi(;RU9UCfWonqgKrsr~5}zw27CPdRNaIL5;A zLmj(BDR$%X`tISZ$<+pE_2DLb+F}0M`^JnfbQxAY6hV+!TNKJavV|u!Lw?gR#gAv5 zPm!~xenew~_$tLob)ODOxd>rj%FVy`JX1&U?mDX!EQ{GCX#JJ3l_h3nWUu%-`TO3; z1k)Nh(6m6CAz5JOxnK^X(eI9GhEH{SXFFEeh|SA^N8Ea28HYcX>>1>mRVo<8S~kmi zTZIHan0AtuNHbdS{_MZv!71^c(jB{|;PFjpAuo7EmZkWVHbJdgZ0UV9KmPHj!+Yjs zmD_UFs;&O1AId2E7RwEEsxpfgZA>iCD}TM%Z1ON+Kc9P(PB{(E>=-aWou4TTeYFGa|5q2u_@$6rnGaqtEJmy(V)O6 zFy%u23q<)>x5Y*1SQ>^%#ZccG`LM?{pabQ0$?^BKVya1l*yw)t{JhNLh$Jwf*g{ z?watFXp$8qK%%bsjPt`ihD`BiO80g2=kCwaalEf*9Hu7uq4Hpw1!-ygM}}Didy3qV zk8CTZz-lhRE%ZWaB1fSsDe)c51%Af?dQ`!~4{^}G@@?!rC;aSa`n?u)H1 zq%6H1R$yYRV5Tyw~~?>Q099 z<`I?~Zp!NpXD(lFud|7il{9t~!&M%r9aQI1MQJl56H7uT4LLTrBn)ZJY^O|l**(Wt zf?^87rr+Ap7pj;i_2PcFSa>LN)>7#30z-82kbr-_IRf>##j))>{|qU8vP`GHePfVB z!QLPd3qZH7?UM=!*|4Bfom81WmUjm(4S(ND7t15MTc*S`to5x1)e2b)&Fy51QT&LpKce03P!lGoI=VhPUJN3tHW zI;}UI_ZOV9s(uB7BAh!niy|H7uKJE;UNh2VCCm=gaA>d`2TaRl&iTNI{uKHpi>Nc2 z?De%~fTaui7>$V5PnF3xJM7+kxae@BKvmX24!`ZpmDJo<7KX;(SL}K8*U)jx;;Z4y zZlRk-P?> zkKIb4TAXWn+5qKO5XcO^l~=k{v~2lkdi6(yMwxtkj{#GbIzQ4^uVh<;@70+ z6mPJZ!9-gSE%)SV1^W)tY_g=N;h#Kj2Yo#m9jSB7pBBnRvNkq#F_0Xn#3mYUwLCQ} zo&e8X>|qtz&npeFzII`8aB01;YeXdZ`xd^JGuHfGW0nHi%!oW*uEA!|&v(6GBpd0? z^|P-756fcl;RA?nmMGa;!I$)X8LnIRlOoQAcYE}ij2?Ns?X1YLi)v2pckDD<+MaIi zX**9{Xw&Fh3ZCSK|B=W%*b+P3&$8}VwL1#0whQ{vizGhqxF)WzDNOy_!VJX|j0|Jr zyY0U&FRX4if3=5)t4;Gx=I$?AKBHB~Ug6mLhaad<+@BWpa~M#9@-HCrvYwF?$%e2G z%0J3^c65IRlD$H78I;r}>ixM}XMw6yH88$c=Dy4;>(98saK2ySKb}b!ik7_BH#(?7 zONhDswO2}L(R_Wv|C);~hUYMD`It$^H274UAj&WPPXLlmY)~RFHu_=31HHK|iO}~N zV3B7UC*K)jZBAc1QTYgl1n3#;a9rf+^A#i13BK@HRd6L(Jy2DXh-KJJYj3k|(&ypt}G$ z?|@_0$S=cX5VQdIzN3Sy064HFjZmJTKe%q^?Ej(a9iuCYm*~ORcE{=1w$-uOF+04m zt?t-%a^rMt+v(uOwrykb{xkFDO?^1)d^>C1^Q*dbYVTc}kJV%x1a^sh6N%19uSbBQ zzNf!Qb>^+C2Jwv@ zK|v%FbV#oOgzI8GVws;;8&OfbEEVU3I5uj-4z0tN=BS5p)lzxq;QEp$_;Vc%d14PM zxvkc~jz@p!{wSw^BaOzHAv;Z0*64a=0$JP#Ieq8PcK?TH; zU`9+;{<5*8f?~8&S{dCzuQar$MG#Q-cUlSK8pXjk6O@qJLfvAjA=F^CW+NikQEl-G zMxVQXK`hmwF_c7TSl1Ybp4HV+(vUFk4dNa~yU%os^8=brtv47sO@0o^G?}~VQ?yeeZb`0p$dTWXQn`flM;L=S))R5tA zy1N8tgXKy#5|qD-!L#@idCBsr-!uqJO%3(vN+e(KA@#kaMXe_RJ7ENq-s|`BJnHvi z?~1|sTrv6Aa{y+06o8NLx6LD;0Wu+KlEC~2Hiqvdo$&k9vnHr`rMgUX@9t!jWUR4V z?{J<=MzWj2Kce~l3dVIc+GHIX8$YV7=2_H4pP$CC3J}+1YXgs^2QaWXXW&d`rTw3d zhbAlj|J0Hg@}W1PudTjhXrWsl&WPlDVV_LI`{Da4uz4Q=9XC(3Rc^Q;M~ZKyuQ;OQ_@O(pbYD(jmW4*IL3bQkk|4U#CKXG5)hIQ<8nr4hfe>Q!H{NggA=V)XUT<2|L8>r%jTFD!OAie5t?%SzLm^xAR!-44j&^{^Lt)#vPh&EG2 zJwuR)Vxbm~rQ7ysBrlE>6M7Ep+-YpBMkuG{GPfABK!OUx*2l5uD)Y~|`y=MX-yEs9 zZ1t7o(ybvJa_O|g&55z@ggZaIs08GSD8J;8NmA177_!oas1^XVrD6ubs$YeO`~i#_ zoDH?y3dK{h0*03qs$?=OIu%j*M?n^|4ByfmH*rI9Ct%O;(BTGZI3;mP*xDVE;<0Q8 zc}dr{EQUN#JL?$4E-RxQ_?T&6^3O!%@xL~*Vcn0<(`YTd=jB{mNVIXrnXvbrpr;9vDn)_U4J4 z`dOc>EG5V2GB-Y#_SD^#d1dcq=gVF~)EPSK_EB`9XneC>R^X~c=8<~kaidKHB&}f@ z67y=BNfU`Vsq{G;zia5H!9%oANgJBJ61dDS8_=CGRfBV;*25B1!2Lj>#m4=eD8yZX z&9yEbr6!zqTmpipCC0U_JHCGGm#3MKCWR8$fTlxd${QLo>*87*a$INI?;yMO3qvNh zuAwDl)y8JpivIgRna#{M_EvT6;sG`?lwl2tPy#NpHuOgDE0gMg3Qsr%;A*nVt$xgP zem&D%eWzj%%I&um=AIX)cTZE-zr5<`n02Ea3MQa>HSrG)cwTx%&*&EFyJeBT&5vub z{VTeOdG3~F*{rRm=awSsEQIcyFaF>-8Ae$pI6Ph+nST|3kcq;$WaMNmDaa?~a+t3y z-R}D*w-{x%)jy3xy}&Ngm9AQaJ!@*_Y1{4}Sh|^W?L=9)9#A--5&hrJL^3+Q%GRN? z5xBDZeFKmD1I#rovzlFwCDwVlg`$rj1RLTTtn)&;ZK^U8L zk0+QJS6)XA+$b{hM!z=WjL_IoOq-E!yPbFcI<8n7F$k@Wq?+w|eqqoY1zkC>V=-rQ zf3E_LJC6}Y&-06J7}@ZKH#o+wx&H1U zo}s-vE*^HH6ZM6TnFrozDmprA1OJd?qfw#WQ^f0THRyNE0}pD};KM|oLcqOLl?kMy z^2wz)g_TMeU(YEtpoinzOW9^))_I|Zv$jD;Yv?%?PI4N-K0>8wJ@Mz*i&878;DU;_ z)bFDR(_4IYV-#odkl?g%W$?IBDAb%sGOO^Kl$jRT6%Rm$g<{? z8w2}L^t>lTqsPhtRGnGn?l3a&P|?Pqtkar!g;!hI;S0y5FprDzq347V#u5E4r}ha^ zTg}XCOoeY1!!v6xFf@@+1$6v&p4-G9U|HqxRvr?|fk>c&ME8I~u9=6ZQ|2jfcqlU* zYSCq)$8tn5+TmXqs9Cv!&Mq0OlXCBvXGHDqO)1(HJx&5}e~9qES8;P?FcUwnXqmT8 z#0e0~j@{;@SJes{SqM==QM3J4=z-6giy}I1Kz`am*#Hc3F|OFEx@F`@{4*M6yZq<$^=tb}51UKbc?k@X(-A4|7@LS_7Ejt;cu%R(FPd?ry8_138m2@rV$41CgJ&`eH;%KbXR@b*M>C598h52m)p)efEPRfW`I zzjt!;`NKup7|Vk#|D`l@-a;pPTa)MAXdrJ{N>I<{F_`BZZ%tFG%)$~<;7Q1fatXp) zbWdJZk>qByLTRwglu`Th&7_JN@>IKkPyrX^cUV>wPl01EOs3{J%TH|bcsw-&8)xf< z?auck>w(dM!TI50Hz>BB*JMCH!M!Iq$=)$9lK1^iG<&=wd1RPjH_TnCnf4}V)trgv zr9${%AAv{6Z&Y%3ocoPqK0=5!oUL7!C|2@(qMyj-GYv^x1eDT~!K~GefzQk@jurBG z86M9bB-Mh!JM8~Uo2Xx3!~nj7f1Rd zxA}DR#!OUMNuxL8DN}4b7)_KqUO*g$KvlJNCQlWMN#U+i!CuDOC4- zvMD>yp*0)gt`=8;nXGsw(E0g6+%xGRE->BNFE~u;i%jbSg-MMP!#(_t%_Vqam!@eO zS###*yj0vFAN=P*{yBERUpEK=3x;iLFNQ9?3BLihuo{i%#0!?ZtZeQmvy1M z24)4#HPhU#xC=Ybc`hw?ThdJ4P)yS|21m+_H1Rmy(iKR)0SgtwM9YV1T2mhb=_i^w z8y0m*(yY<(xvitGEuf`|AEs1igtCAJ*syTcDUje-yggM{v7h~My&e(>Gu~pz##EI6 zMTt?k3E^_Slq_&}RBu*t$~yX-U=6H%wWZP^^@wenOHlse%5a`6ikH;kQx~(%P>j_W z<|tyqQg(B?ZICN(Ce?U%*G=Y^9Kej$nP<>YTSqqT;QOg4__lkN0(%c0!Q;#AQG+K> zm{)&BdTb_$=;7$na z{2>oLSkBB#c-^E7*fa||Y@dnS#{nxf!+ULfAc4mw4?~_ueWa)a+$Iu^GNl*_@}4sL zFrn9=Km)4%K#E4!ZUtQw?Kxe6)wm7E*CjP8l}5{5Xxbro;Y=~_v%fBBaKAq=`PVtQ zqm#&1&0`sO{aVZU;dC??mTR%JrL9~qq=OgEBEp1*wuQzhTYKzIbqP`03|VFpCF&R| zYs-p9i_xK-xcODf1JNFvpV7T+l4}6=93$TqWw6f+lkJ)*T`SY$rs#dXtK^c zC0WX!+*XSW+ALjs{*?`&O0rLB@{VjOBFGtJk zD}hC8v=f*brqyE66lf>yJMn44%q1x>4E0hmMZ1OOr4AL7G;tOqu#KRjGqK&d*B2YZ z#??Rud8%eM!8x%FVbcHEVK0b5b|Vy3NJjj;O$s*_o=ws(NptlGcJON>KP zJwBSDP}mQ2iu&km(QK@}@r4?SVY%+UGR_|Y7<`Vt{Spy}CL{1=dMTtJy= zPDcrK+3k^&TE#o;oHcmH5}t1pg!NIy7HXh_Q*8VUb1885Dj}G)TcG0m=^R7N4F?Sz zn81B{`bs3O%5?xb8zzyp%h9erRrD#fV4%3yvCFv`b7uq3faoe**2xb3V%SuTI6(lr zkJ4{R^F}Vt&@i>uLKx|}GEuoEe3u%0Spt06=0EpbN4JMVol(-rzrC)$l^poyZ_NDt z+aQVyODB3&M=LnEMGB6^j4}HQuy#8A_irCZd5=-3`BW9(M8*!F1Y!<7?&MbrO(rhR zABkmIbLgb&s9K>7BDeq_4V6O&(vEsJNGZlSZ6B2qCR=a0+Ciuki6`HsLCe|l^Moyk zOcH&|0SH)r)RhL4Ov;VRCpVlGkVT+VH1`98a!75N96kg({yfK0L%YDm(s}M*(4C{f z%WOLt)l0xYNRtByj|BOj5|g;Nk6$V1z$h#-JQ(?9=njm&>ZzbCD?^M+fq1WIO6fj= z%f`X0uvrM9e*GZw<$PX2h(Owm)Vok}7PI#!ipfMWkmQK=1u^NBV4S?cu3Lt(k4fvI z&N7`QSBRIERjQd8O(fxHg{e}XsSB}(#MuD zwWVG@(~ejnoJ(yz)B5_ZiXot!1n-7#B{NQ;uU)*1Gk1v9iUVr&IrS@jDONI((-R>! z7$2vIGP&Vg`+KnJpaWvp*(zIsTmE`5X(>Ph$f&-+FF&o{)L%$Iw@W9P z8vW>GE%c8){sJ0+aNNeC*tWa-#}|bYMrr*`Ty(p15y_+uTFj=|lCSM&VnH>f|Cnp)-qNzaGHW9~HALa&XOWoj5&0u{a^>@ewzSb81Hchp3`4ZLW_t z0!W9a7V1eeNS~fg+9l4&BoI0iEN10>T9dBGO2#Rqh5{*+xeQk=DuWk6t@B5+rl=A^mnJEllAKqktNT_Fb~ z#ojMsTfCayT1v_HJZi4&p}YO|bdEjpLe4Z}!ntj*I0)qd&`wJ6_dao&mrDIR-E*wj zRkI2gFo@t1)UTkVMjD_(z<3XqWM)JSzm~&2hds zO4@XOV77;Y+nUQ)Ny#FeC@kMF{vCV{TSWLU>Jq{O($`dWZn1P(BS0LUImyN;L2fk) zNgYDvFqvElD*_!@mXlUaTy%7;*Rn4S_uh%$bImtPFP|Ah-@F<_(Mt6crY6o5!uTeh%lnH>&8A_uvNeJ|(x3 z-7z$G@Q>5)39G+#1yeyQA!9Ot`cU`7;3TeFTU36d_)j8=G)Ev(wNSh7H)|F1$nTDR z=E0#(?IVYuYi7)eYc=#Fo8nEMC*cP8AgL8a(JE0AAE2WVM*BDYNU=?2ikG@Gnx93i zM`3ft%MrOsO69t)E!5;2<-DlCO2f`563LxTI2Wu6 zJ;I0^{V-i*noup|o;~RFEGVI0&BSK4PF&cNI2;i5^ltNZxBV;8I)gG0IxwSyF#BuD zfl0muK8TG13&XDZpRoW%1GMgkp74YmxBTtEi|Ji_TI?6QW*-YR+>{972roBI2l3o8 z6)*KslZUma<{HxVz^Hn9yT14?%0B>Y&xc`NZTftE(!Jzv$lQr;9r^+YqH&U64 zv2hG%TvkIL(^fpg0c`>KC`fm`3+!E=wS!b!)^w4AIbAFv0I9-Z+j>fkKd+Xkb*}F3 z_v#J1I#t4h3*P}fSSuxJqzHN~Tjtt9fki4QJi&iY#kZXTQ*MXtkDX{ct^7$(EN)nC zsk?(=LO?;igM#E$`4#%E;WZT6`#cwJcH?ukRXA75vIh@_<1+}Luehk~yrNnK^A}dc z$9rI${mckLvB3wdXxKS=)k+vm{^p3=g|(J}N>$G#KiDBgxo8J#MW+3wj*`M|RTFo- zC4!&MH`l*A6cdah*v&KW&b2T>-z<4FWXc-v-IBqmRRSY&%3JeuAuWy z@(0K*6M${af`=*M5*j`3*+6zM>i1&Se8*o1?E?CP^s>`>?F#Ng#xJ|iKwRiunBkIq zYuDN{9Fai!s5L*13`suta<&pKBpZoPlK~9usov(5aa(fJ59=1K=ys`4>_^=5Rv=

(&?R^}yBIffC2`xXdbyGJE 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

XJ6LrI3qdqe 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 { + // res contains client response +}); +``` + +This function return as promise so that you can await a potential response from the client. If you are calling a method on the client but don't expect a response then you should instead opt for using the `send()` function. + +```javascript +this.client.send('methodName', DATA); +``` + +## Subscriptions + +A client is not only able to respond to method calls but also push data directly to the Sonar desktop app. With the subscribe API your plugin can subscribe to there pushes from the client. Pass the name of the method and the API it is part of as well as a callback function to start a subscription. Any time the client sends a push matching this method the callback will be called with any attached data as a javascript object. + +```javascript +this.client.subscribe('methodName', data => { + // data contains any payload sent by the client +}); +``` diff --git a/docs/create-plugin.md b/docs/create-plugin.md new file mode 100644 index 000000000..5fd61115f --- /dev/null +++ b/docs/create-plugin.md @@ -0,0 +1,140 @@ +--- +id: create-plugin +title: Mobile Setup +sidebar_label: Mobile Setup +--- + +## Implement SonarPlugin + +Create a class implementing `SonarPlugin`. + +### Android + +```java +public class MySonarPlugin implements SonarPlugin { + private SonarConnection mConnection; + + @Override + public String getId() { + return "MySonarPlugin"; + } + + @Override + public void onConnect(SonarConnection connection) throws Exception { + mConnection = connection; + } + + @Override + public void onDisconnect() throws Exception { + mConnection = null; + } +} +``` + +### iOS + +```objective-c +@interface MySonarPlugin : NSObject +@end + +@implementation MySonarPlugin + +- (NSString*)identifier { return @"MySonarPlugin"; } +- (void)didConnect:(SonarConnection*)connection {} +- (void)didDisonnect {} + +@end +``` + +### C++ + +```c++ +class MySonarPlugin : public SonarPlugin { +public: + std::string identifier() const override { return "MySonarPlugin"; } + void didConnect(std::shared_ptr conn) override; + void didDisconnect() override; +}; +``` + +## Using SonarConnection + +Using the `SonarConnection` object you can register a receiver of a desktop method call and respond with data. + +### Android + +```java +connection.receive("getData", new SonarReceiver() { + @Override + public void onReceive(SonarObject params, SonarResponder responder) throws Exception { + responder.success( + new SonarObject.Builder() + .put("data", MyData.get()) + .build()); + } +}); +``` + +### iOS + +```objective-c +@interface MySonarPlugin : NSObject +@end + +@implementation MySonarPlugin + +- (NSString*)identifier { return @"MySonarPlugin"; } + +- (void)didConnect:(SonarConnection*)connection +{ + [connection receive:@"getData" withBlock:^(NSDictionary *params, SonarResponder *responder) { + [responder success:@{ + @"data":[MyData get], + }]; + }]; +} + +- (void)didDisonnect {} + +@end +``` + +### C++ + +```c++ +void MySonarPlugin::didConnect(std::shared_ptr conn) { + conn->receive("getData", [](const folly::dynamic ¶ms, + std::unique_ptr responder) { + dynamic response = folly::dynamic::object("data", getMyData()); + responder->success(response); + }); +} +``` + +## Push data to the desktop + +You don't have to wait for the desktop to request data though, you can also push data directly to the desktop. + +### Android + +```java +connection.send("MyMessage", + new SonarObject.Builder() + .put("message", "Hello") + .build() +``` + +### iOS + +```objective-c +[connection send:@"getData" withParams:@{@"message":@"hello"}]; +``` + +### C++ + +```c++ +void MySonarPlugin::didConnect(std::shared_ptr conn) { + dynamic message = folly::dynamic::object("message", "hello"); + conn->send("getData", message); +} +``` diff --git a/docs/create-table-plugin.md b/docs/create-table-plugin.md new file mode 100644 index 000000000..323955e09 --- /dev/null +++ b/docs/create-table-plugin.md @@ -0,0 +1,86 @@ +--- +id: create-table-plugin +title: Create Table Plugin +sidebar_label: Create Table Plugin +--- + +A very common kind of Sonar plugin is a plugin which fetches some structured data from the device and presents it in a table. + +To make building these kinds of plugins as easy as possible we have created an abstraction we call `createTablePlugin`. This is a function which manages the complexities of building a table plugin but still allows you to customize many things to suite your needs. + +Below is a sample implementation of a desktop plugin based on `createTablePlugin`. It subscribes to updates from a client plugin with id `myplugin` sending rows to with the `newRow` method. A row can have any structure you want as long as it has a unique field `id` of type `string`. + +See "[Create Plugin](create-plugin.md)" for how to create the native counterpart for your plugin. + +```javascript +import {ManagedDataInspector, Panel, Text, createTablePlugin} from 'sonar'; + +type Id = string; + +type Row = { + id: Id, + column1: string, + column2: string, + column3: string, + extras: Object, +}; + +function buildRow(row: Row) { + return { + columns: { + column1: { + value: {row.column1}, + filterValue: row.column1, + }, + column2: { + value: {row.column2}, + filterValue: row.column2, + }, + column3: { + value: {row.column3}, + filterValue: row.column3, + }, + }, + key: row.id, + copyText: JSON.stringify(row), + filterValue: `${row.column1} ${row.column2} ${row.column3}`, + }; +} + +function renderSidebar(row: Row) { + return ( + + + + ); +} + +const columns = { + time: { + value: 'Column1', + }, + module: { + value: 'Column2', + }, + name: { + value: 'Column3', + }, +}; + +const columnSizes = { + time: '15%', + module: '20%', + name: 'flex', +}; + +export default createTablePlugin({ + title: 'My Plugin', // Title of plugin + id: 'myplugin', // ID of plugin + method: 'newRow', // Method which should be subscribed to to get new rows with share Row (from above), + icon: 'washing-machine', + columns, + columnSizes, + renderSidebar, + buildRow, +}); +``` diff --git a/docs/error-handling.md b/docs/error-handling.md new file mode 100644 index 000000000..12a5f9725 --- /dev/null +++ b/docs/error-handling.md @@ -0,0 +1,32 @@ +--- +id: error-handling +title: Error Handling +sidebar_label: Error Handling +--- + +Errors in Sonar plugins should be hidden from the user while providing actionable data to the plugin developer. + +## Android + +To gracefully handle errors in Sonar we provide the `ErrorReportingRunnable` class. This is a custom runnable which catches all exceptions, stopping them from crashing the application and reporting them to the plugin developer. + +```java +new ErrorReportingRunnable(mConnection) { + @Override + public void runOrThrow() throws Exception { + mightThrowException(); + } +}.run(); +``` + +Executing this block of code will always finish without error but may transfer any silences error to the Sonar desktop app. During plugin development these java stack traces are surfaced in the chrome dev console. In production the errors are instead sent to and a task is assigned so that you can quickly deploy a fix. + +Always use `ErrorReportingRunnable` for error handling instead of `try`/`catch` or even worse letting errors crash the app. With ErrorReportingRunnable you won't block anyone and you won't hide any stack traces. + +## C++ + +To gracefully handle errors in Sonar we perform all transactions inside of a try block which catches all exceptions, stopping them from crashing the application and reporting them to the plugin developer. This includes your own customs implementations of `SonarPlugin::didConnect()` and `SonarConnection::send()` and `::receive()`! + +That means you can safely throw exceptions in your plugin code. The exception messages will be sent to the Sonar desktop app. During plugin development the exception messages are surfaced in the Chrome dev console. + +If your plugin performs asynchronous work in which exceptions are thrown, these exceptions will not be caught by the Sonar infrastructure. You should handle them appropriately. diff --git a/docs/getting-started.md b/docs/getting-started.md new file mode 100644 index 000000000..53fc98a95 --- /dev/null +++ b/docs/getting-started.md @@ -0,0 +1,82 @@ +--- +id: getting-started +title: Getting Started +sidebar_label: Getting Started +--- + +Sonar helps you debug Android and iOS apps running in an emulator/simulator or connected physical development devices. Sonar consists of two parts: + +* The desktop app for macOS +* The native mobile SDKs for Android and iOS + +To use Sonar, you need to add the mobile SDK to your app. + +## Setup + +### Desktop app + +The desktop part of Sonar doesn't need any particular setup. Simply [download the latest build](https://www.facebook.com/sonar/public/mac) of our app and launch it. The desktop app is available for macOS and requires a working installation of the Android/iOS development tools on your system. + +Once you start Sonar and launch an emulator/simulator or connect a device, you will already be able to see the device logs in Sonar. To see app specific data, you need to integrate our native SDKs with your app. + +![Logs plugin](/docs/assets/initial.png) + +### Setup your Android app + +TODO: Install dependencies + +TODO: Add dependencies to your `build.gradle` file. + +Now you can initialize Sonar in your Application's `onCreate`-method like this: + +```java +public class MyApplication extends Application { + + @Override + public void onCreate() { + super.onCreate(); + + if (BuildConfig.DEBUG && SonarUtils.isMainProcess(mApplicationContext)) { + final SonarClient client = AndroidSonarClient.getInstance(this); + client.addPlugin(new MySonarPlugin()); + client.start(); + } + } +} +``` + +### Setup your iOS app + +To integrate with our iOS app, you can use [CocoaPods](https://cocoapods.org). Add the mobile Sonar SDK to your `Podfile`: + +```ruby +platform :ios, '8.0' +use_frameworks! + +target 'MyApp' do + pod 'Sonar', '~> 1.0' +end +``` + +and install the dependencies by running `pod install`. When you open the Xcode workspace file for your app, you now can import and initialize Sonar in your AppDelegate. + +```objective-c +#import + +@implementation AppDelegate + +- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions +{ +#if DEBUG + SonarClient *client = [SonarClient sharedClient]; + [client addPlugin:[MySonarPlugin new]]; + [client start]; +#endif + ... +} +@end +``` + +## Ready for takeoff + +Finally you need to add plugins to your Sonar client. See [Network Plugin](network-plugin.md) and [Layout Inspector Plugin](layout-plugin.md) on how to add them. diff --git a/docs/jssetup.md b/docs/jssetup.md new file mode 100644 index 000000000..83f76ca1f --- /dev/null +++ b/docs/jssetup.md @@ -0,0 +1,58 @@ +--- +id: js-setup +title: JavaScript Setup +sidebar_label: JavaScript Setup +--- + +## Creating the plugin UI + +To create the desktop part of your plugin, initiate a new JavaScript project using `yarn init` and make sure your package name starts with `sonar-plugin-` and a file called `index.js`, which is the entry point to your plugin. A sample `package.json`-file could look like this: + +``` +{ + "name": "sonar-plugin-myplugin", + "version": "1.0.0", + "main": "index.js", + "license": "MIT", + "dependencies": {} +} +``` + +In `index.js` you can now create your plugin. We expect this file to have a default export of type `SonarPlugin`. A hello-world-plugin could look like this: + +```js +import {SonarPlugin} from 'sonar'; + +export default class extends SonarPlugin { + render() { + return 'hello world'; + } +} +``` + +Learn more on how to use [Sonar's UI components](ui-components.md). + +### Dynamically loading plugins + +Once a plugin is created, Sonar can load it from it's folder. The path from where the plugins are loaded is specified in `~/.sonar/config.json`. Add the parent folder of your plugin to `pluginPaths` and start Sonar. + +### npm dependencies + +If you need any dependencies in your plugin, you can install them using `yarn add`. The Sonar UI components exported from `sonar`, as well as `react` and `react-dom` don't need to be installed as dependencies. Our plugin-loader makes these dependencies available to your plugin. + +### ES6, babel-transforms and bundling + +Our plugin-loader is capable of all ES6 goodness, flow annotations and JSX and applies the required babel-transforms without you having to care about this. Also you don't need to bundle your plugin, you can simply use ES6 imports and it will work out of the box. + +## Working on the core + +If you only want to work on a plugin, you don't need to run the development build of Sonar, but you can use the production release. However, if you want to contribute to Sonar's core, add additional UI components, or do anything outside the scope of a single plugins this is how you run the development version of Sonar. + +Make sure you have a recent version of node.js and yarn installed on your system (node ≥ 8, yarn ≥ 1.5). Then run the following commands: + +``` +git clone https://github.com/facebook/Sonar.git +cd Sonar +yarn +yarn start +``` diff --git a/docs/layout-plugin.md b/docs/layout-plugin.md new file mode 100644 index 000000000..58d847bc8 --- /dev/null +++ b/docs/layout-plugin.md @@ -0,0 +1,54 @@ +--- +id: layout-plugin +title: Layout Inspector +--- + +The Layout Inspector in Sonar is useful for a ton of different debugging scenarios. First of all you can inspect what views the hierarchy is made up of as well as what properties each view has. This is incredibly useful when debugging issues with your product. + +The Layout tab supports [Litho](https://fblitho.com) and [ComponentKit](https://componentkit.org) components as well! We integrate with these frameworks to present components in the hierarchy just as if they were native views. We show you all the layout properties, props, and state of the components. The layout inspector is further extensible to support other UI frameworks. + +If you hover over a view or component in Sonar we will highlight the corresponding item in your app! This is perfect for debugging the bounds of your views and making sure you have the correct visual padding. + +![Layout plugin](/docs/assets/layout.png) + +## Setup + +To use the layout inspector plugin, you need to add the plugin to your Sonar client instance. + +### Android + +```java +import com.facebook.sonar.plugins.inspector.DescriptorMapping; +import com.facebook.sonar.plugins.inspector.InspectorSonarPlugin; + +final DescriptorMapping descriptorMapping = DescriptorMapping.withDefaults(); +client.addPlugin(new InspectorSonarPlugin(mApplicationContext, descriptorMapping)); +``` + +### iOS + +```objective-c +#import +#import + +SKDescriptorMapper *mapper = [[SKDescriptorMapper alloc] initWithDefaults]; +[client addPlugin:[[SonarKitLayoutPlugin alloc] initWithRootNode:context.application withDescriptorMapper:mapper]] +``` + +## Quick edits + +The Layout Inspector not only allows you to view the hierarchy and inspect each item's properties, but it also allows you to edit things such as layout attributes, background colors, props, and state. Most things actually! This allows you to quickly tweak paddings, margins, and colors until you are happy with them, all without re-compiling. This can save you many hours implementing a new design. + +## Target mode + +Enable target mode by clicking on the crosshairs icon. Now, you can touch any view on the device and Layout Inspector will jump to the correct position within your layout hierarchy. + +### Blocking fullscreen views (Android only) + +The issue is that if you have some view that occupies big part of the screen but draws nothing and its Z-position is higher than your main content, then selecting view/component through Layout Inspector doesn't work as you intended, as it will always hit that transparent view and you need to manually navigate to the view you need which is time-consuming and should not be necessary. + +Add the following tag to your view to skip it from Sonar's view picker. The view will still be shown in the layout hierarchy, but it will not be selected while using the view picker. + +```java +view.setTag("sonar_skip_view_traversal", true); +``` diff --git a/docs/logs-plugin.md b/docs/logs-plugin.md new file mode 100644 index 000000000..0a1460c49 --- /dev/null +++ b/docs/logs-plugin.md @@ -0,0 +1,18 @@ +--- +id: logs-plugin +title: Logs +--- + +The Logs plugin shows device logs, without any additional setup. This is a device plugin, meaning that it is not tied to any specific app and there is no additional setup needed to see the logs. + +![Logs plugin](/docs/assets/logs.png) + +## Filtering + +The search bar can be used to search for logs and filter for certain types. From the context menu on the table headers you can show more infos like timestamp, PID or TID. Click on a tag, PID or TID in the table to filter only for logs with the same value. + +## Expression watcher + +The expression watcher in the sidebar can be used to watch for certain logs to happen and count how often the occur. An expression can be a simple string, or a regular expression which is matched against the logs. + +When the notify checkbox is enabled, Sonar will send notifications once the log is happening. This let's you know when the watcher triggered, even if Sonar is in the background. diff --git a/docs/network-plugin.md b/docs/network-plugin.md new file mode 100644 index 000000000..90d479a27 --- /dev/null +++ b/docs/network-plugin.md @@ -0,0 +1,32 @@ +--- +id: network-plugin +title: Network +--- + +Use the Network inspector to inspect outgoing network traffic our apps. You can easily browse all requests being made and their responses. The plugin also supports gzipped responses. + +![Netowrk plugin](/docs/assets/network.png) + +## Setup + +To use the network plugin, you need to add the plugin to your Sonar client instance. + +### Android + +```java +import com.facebook.sonar.plugins.network.NetworkSonarPlugin; + +client.addPlugin(new NetworkSonarPlugin()); +``` + +### iOS + +```objective-c +#import + +[client addPlugin: [SonarKitNetworkPlugin new]] +``` + +## Usage + +All request sent from the device will be listed in the plugin. Click on a request to see details like headers and body. You can filter the table for domain, method or status by clicking on the corresponding value in the table. diff --git a/docs/send-data.md b/docs/send-data.md new file mode 100644 index 000000000..5308dfcd9 --- /dev/null +++ b/docs/send-data.md @@ -0,0 +1,50 @@ +--- +id: send-data +title: Sending Data to Plugins +sidebar_label: Send Data +--- + +It is often useful to get an instance of a sonar plugin to send data to it. Sonar makes this simple with built in support. + +Plugins should be treated as singleton instances as there can only be one `SonarClient` and each `SonarClient` can only have one instance of a certain plugin. The Sonar API makes this simple by offering a way to get the current client and query it for plugins. + +Plugins are identified by the string that their identifier method returns, in this example, "MySonarPlugin": + +### Android + +```java +final SonarClient client = AndroidSonarClient.getInstance(context); +// Client may be null if AndroidSonarClient.createInstance() was never called +// which is the case in production builds. +if (client != null) { + final MySonarPlugin plugin = client.getPlugin("MySonarPlugin"); + plugin.sendData(myData); +} +``` + +### iOS + +```objective-c +SonarClient *client = [SonarClient sharedClient]; +MySonarPlugin *myPlugin = [client pluginWithIdentifier:@"MySonarPlugin"]; +[myPlugin sendData:myData]; +``` + +### C++ + +```c++ +auto &client = SonarClient::instance(); + +// "MySonarPlugin is the return value of MySonarPlugin::identifier() +auto aPlugin = client.getPlugin("MySonarPlugin"); + +// aPlugin is a std::shared_ptr. Downcast to expected type. +auto myPlugin = std::static_pointer_cast(aPlugin); + +// Alternatively, use the templated version +myPlugin = client.getPlugin("MySonarPlugin"); + +myPlugin->sendData(myData); +``` + +Here, `sendData` is an example of a method that might be implemented by the sonar plugin. diff --git a/docs/stetho.md b/docs/stetho.md new file mode 100644 index 000000000..2ff631642 --- /dev/null +++ b/docs/stetho.md @@ -0,0 +1,11 @@ +--- +id: stetho +title: Stetho Guidance +sidebar_label: Stetho Guidance +--- + +In 2015, we introduced [Stetho](http://facebook.github.io/stetho/), an Android debugging bridge built on top of Chrome dev tools. While it was a valuable tool to us and many members of the community, we felt that it limited us in what we could do with it. Stetho is Android-only and while Chrome dev tools gave us a nice foundation to build upon, they also limited us in what we could build. Stetho is an Android tool and Chrome dev tools is built for web developers. This means we can only provide a good experience for the intersection of those two development environments, which was very limiting. With Sonar being built as a standalone app, we can do more things, like handling adb connections and supporting iOS, which wouldn't easily achievable with stetho. + +This is why we built Sonar. We wanted to create a platform that gives us all the flexibility we need to build more advanced features and support for iOS. One of Sonar's core concept is it's extensibility using [plugins](create-plugin.md). Plugins are written in react and we provide a set of ready-to-use UI components that allows developers to build great plugin UIs with a few lines of code. + +While offering many new features, Sonar also already covers most of the features provided by Stetho. This includes network and layout inspection, and an advanced log viewer. We are committed to continuously improving Sonar with new features and plugins, however we are aware that not all stetho features are currently supported by Sonar. If you are using a particular feature of Stetho which isn't supported by Sonar, we are more than happy to hear about your use-case. Stetho will continue to work and we are not abandoning it so you can choose the tool that fits your needs best. We are confident that Sonar will work well for most use-cases and are more than happy to accept contributions from the open-source community adding new features. diff --git a/docs/styling-components.md b/docs/styling-components.md new file mode 100644 index 000000000..462c08b32 --- /dev/null +++ b/docs/styling-components.md @@ -0,0 +1,75 @@ +--- +id: styling-components +title: Styling Components +sidebar_label: Styling Components +--- + +We use a styled-component based approach to styling our views. This means styles are defined in JavaScript and are written as CSS-stylesheets to the DOM. A component and it's styles are coupled. Styled components can extend another to inherit their styles. + +## Basic tags + +For basic building blocks (views, texts, ...) you can use the styled object. + +```javascript +import {styled} from 'sonar'; + +const MyView = styled.view({ + fontSize: 10, + color: colors.red +}); +const MyText = styled.text({ ... }); +const MyImage = styled.image({ ... }); +const MyInput = styled.input({ ... }); +``` + +But you can use any other HTML-tags like this: + +```javascript +styled.customHTMLTag('canvas', { ... }); +``` + +## Extending Sonar Components + +It's very common for components to require customizing Sonar's components in some way. For example changing colors, alignment, or wrapping behavior. There is a `extends` method on all styled components which allows adding or overwriting existing style rules. + +For these use cases when a styled component is only used within the context of a single component we encourage declaring it as a inner static instance. This makes it clear where the component is used and avoids polluting the global namespace. + +```javascript +class MyComponent extends Component { + static Container = FlexRow.extends({ + alignItems: 'center', + }); + + render() { + return ...; + } +} +``` + +## CSS + +The CSS-in-JS object passed to the styled components takes just any CSS rule, with the difference that it uses camel cased keys for the properties. Pixel-values can be numbers, any other values need to be strings. + +Dynamic values also can be functions, receiving the react props as argument. (Make sure to add properties passed to a component to the `ignoredAttributes` array to not be written to the DOM as an attribute.) + +```javascript +const MyView = styled.view( + { + fontSize: 10, + color: props => (props.disabled ? colors.red : colors.black), + }, + { + ignoredAttributes: ['disabled'], + } +); +``` + +Pseudo-classes can be used like this: + +```javascript +'&:hover': {color: colors.red}` +``` + +## Colors + +The colors module contains all standard colors used by Sonar. All the available colors are defined in `src/ui/components/colors.js` with comments about suggested usage of them. And we strongly encourage to use them. diff --git a/docs/testing.md b/docs/testing.md new file mode 100644 index 000000000..3817d32b9 --- /dev/null +++ b/docs/testing.md @@ -0,0 +1,96 @@ +--- +id: testing +title: Testing +sidebar_label: Testing +--- + +Developer tools are only used if they work. We have built APIs to test plugins. + +## Android + +Start by creating your first test file in this directory `MySonarPluginTest.java`. In the test method body we create our plugin which we want to test as well as a `SonarConnectionMock`. In this contrived example we simply assert that our plugin's connected status is what we expect. + +```java +@RunWith(WithTestDefaultsRunner.class) +public class MySonarPluginTest { + + @Test + public void myTest() { + final MySonarPlugin plugin = new MySonarPlugin(); + final SonarConnectionMock connection = new SonarConnectionMock(); + + plugin.onConnect(connection); + assertThat(plugin.connected(), equalTo(true)); + } +} +``` + +There are two mock classes that are used to construct tests `SonarConnectionMock` and `SonarResponderMock`. Together these can be used to write very powerful tests to verify the end to end behavior of your plugin. For example we can test if for a given incoming message our plugin responds as we expect. + +```java +@Test +public void myTest() { + final MySonarPlugin plugin = new MySonarPlugin(); + final SonarConnectionMock connection = new SonarConnectionMock(); + final SonarResponderMock responder = new SonarResponderMock(); + + plugin.onConnect(connection); + + final SonarObject params = new SonarObject.Builder() + .put("phrase", "sonar") + .build(); + connection.receivers.get("myMethod").onReceive(params, responder); + + assertThat(responder.successes, hasItem( + new SonarObject.Builder() + .put("phrase", "ranos") + .build())); +} +``` + +## C++ + +Start by creating your first test file in this directory `MySonarPluginTests.cpp` and import the testing utilities from `//xplat/sonar-client:SonarTestLib`. These utilities mock out core pieces of the communication channel so that you can test your plugin in isolation. + +``` +#include +#include +#include + +#include +#include + +namespace facebook { +namespace sonar { +namespace test { + +TEST(MySonarPluginTests, testDummy) { + EXPECT_EQ(1 + 1, 2); +} + +} // namespace test +} // namespace sonar +} // namespace facebook +``` + +Here is a simple test using these mock utilities to create a plugin, send some data, and assert that the result is as expected. + +``` +TEST(MySonarPluginTests, testDummy) { + std::vector successfulResponses; + auto responder = std::make_unique(&successfulResponses); + auto conn = std::make_shared(); + + MySonarPlugin plugin; + plugin.didConnect(conn); + + folly::dynamic message = folly::dynamic::object("param1", "hello"); + folly::dynamic expectedResponse = folly::dynamic::object("response", "Hi there"); + + auto receiver = conn->receivers_["someMethod"]; + receiver(message, std::move(responder)); + + EXPECT_EQ(successfulResponses.size(), 1); + EXPECT_EQ(successfulResponses.back(), expectedResponse); +} +``` diff --git a/docs/ui-components.md b/docs/ui-components.md new file mode 100644 index 000000000..2e4150ccf --- /dev/null +++ b/docs/ui-components.md @@ -0,0 +1,254 @@ +--- +id: ui-components +title: UI Components +sidebar_label: UI Components +--- + +Sonar has a lot of built in React components to build UIs. You can find all of these in [`src/ui/components`](https://github.com/facebook/Sonar/tree/master/src/ui/components) and can import them directly using `import {Buttom} from 'sonar'`. + +## FlexBox + +In Sonar we make heavy use of flexbox for layout. FlexBox is layout system on the web which has been specifically design for building application like UIs. Sonar provides two flexbox components `FlexRow` and `FlexColumn`. These are flexbox components with some sane defaults such as automatically scrolling content that overflows. + +```javascript +import { FlexRow, FlexColumn } from 'sonar'; + +// Align children horizontally + + {children} + + +// Align children vertically + + {children} + +``` + +To control other flexbox properties than the direction you can extend existing components, detailed in [Styling Components](styling-components.md). + +```javascript +import {FlexRow, styled} from 'sonar'; + +const CenterFlexRow = FlexRow.extends({ + justifyContent: 'center', +}); + +// Align children horizontally in the center +{children}; +``` + +## Text + +The `Text` component is available to render any text in your plugin. To render headers and subtitle differently for example, we used the styled module. With this we can also change the color, text alignment, and any other properties typically found on a `span`. + +```javascript +import {Text, styled, colors} from 'sonar'; + +const Title = Text.extends({ + color: colors.red, +}); + +Sonar Subtitle; +``` + +## Buttons + +Sonar comes with a couple of button styles built in! As always you can style then further using the styled module but we expect the pre-defined buttons to fit most UIs. + +```javascript +import {Button} from 'sonar'; + +; +``` + +You can create a group of buttons by surrounding it with ``. + +## Sidebar + +The `Sidebar` component provides a nice abstraction around some common but complex behavior. The `Sidebar` is used by all major Sonar plugins and using it in your plugin will ensure your plugin behaves similarly, such as allowing for resizing. + +```javascript +import {FlexRow, Sidebar, colors, styled} from 'infinity-ui'; +import {SonarPlugin} from 'sonar'; + +type State = {}; + +export default class MySonarPlugin extends SonarPlugin { + static title = 'My Plugin'; + static id = 'my-plugin'; + + static Red = styled.view({ + backgroundColor: colors.red, + }); + + static Blue = styled.view({ + backgroundColor: colors.blue, + }); + + render() { + return ( + + + + + + + + ); + } +} +``` + +## Panel + +Panels are a way to section data, and make it collapsible. They are often used in sidebars. Just give the Panel a heading and some content and it makes sure that it displays in the same style as the rest of Sonar. + +```javascript +import { + FlexColumn, + FlexRow, + Sidebar, + Panel, + colors, + styled, + SonarPlugin, +} from 'sonar'; + +type State = {}; + +export default class MySonarPlugin extends SonarPlugin { + static title = 'My Plugin'; + static id = 'my-plugin'; + + static Red = styled.view({ + backgroundColor: colors.red, + }); + + static Blue = styled.view({ + backgroundColor: colors.blue, + height: 200, + }); + + static Green = styled.view({ + backgroundColor: colors.green, + height: 200, + }); + + render() { + return ( + + + + + + + + + + + + + + + + ); + } +} +``` + +## DataInspector + +The `DataInspector` component is used to unpack and display a javascript object. It is used to show View properties in the layout inspector, and to show event data in the analytics plugins. + +```javascript +import {FlexColumn, DataInspector, SonarPlugin} from 'sonar'; + +type State = {}; + +export default class MySonarPlugin extends SonarPlugin { + static title = 'My Plugin'; + static id = 'my-plugin'; + + static data = { + one: 1, + two: '2', + three: [1, 2, 3], + }; + + render() { + return ( + + + + ); + } +} +``` + +## Toolbar + +The `Toolbar` component can display a toolbar with buttons, inputs, etc. A `` can be used to fill the space between items. + +```javascript +import {Toolbar, Spacer, Button, SonarPlugin} from 'sonar'; + +export default class MySonarPlugin extends SonarPlugin { + render() { + return ( + + + + + + ); + } +} +``` + +## Popover + +Used to display content in an overlay. + +```javascript +import {Popover, SonarPlugin} from 'sonar'; + +export default class MySonarPlugin extends SonarPlugin { + render() { + return ( + {this.state.popoverVisible && this.setState({popoverVisible: false})}> + ... + } + ); + } +} +``` + +## ContextMenu + +Add a native context menu to a component by wrapping it with the ContextMenu component. + +```javascript +import {ContextMenu, SonarPlugin} from 'sonar'; + +export default class MySonarPlugin extends SonarPlugin { + contextMenuItems = [ + { + label: 'Copy', + click: this.copy, + }, + { + type: 'separator', + }, + { + label: 'Clear All', + click: this.clear, + }, + ]; + + render() { + return ...; + } +} +``` diff --git a/docs/unterstanding-sonar.md b/docs/unterstanding-sonar.md new file mode 100644 index 000000000..36af832b4 --- /dev/null +++ b/docs/unterstanding-sonar.md @@ -0,0 +1,13 @@ +--- +id: understand +title: Understanding Sonar +sidebar_label: Understanding Sonar +--- + +The Sonar desktop app and the mobile native SDK establish an [rsocket](http://rsocket.io) connection which is used to send data to and from the device. Sonar does not make any restrictions on what kind of data is being sent. This enables a lot of different use-cases where you want to better understand what is going inside your app. For example you can visualize the state of local caches, events happening or trigger actions on your app from the desktop. + +## Plugins + +Sonar itself only provides the architectural platform. What makes it useful are the plugins built on top of it: [Logs](logs-plugin.md), [Layout Inspector](layout-plugin.md) and [Network Inspector](network-plugin.md) are all plugins. Plugins can be built very specific to your business logic and the use-cases you have in your app. We are shipping Sonar with a couple of built-in all-purpose plugins, but we encourage you to build your own. + +A plugin always consists of the native implementation sending and receiving data and the desktop plugin visualizing data. Learn more on how to [create a plugin](create-plugin.md). The native implementations are written in Java, Objective-C, or C++, the desktop UI is written in React. diff --git a/flow-typed/electron-menu.js b/flow-typed/electron-menu.js new file mode 100644 index 000000000..c18519784 --- /dev/null +++ b/flow-typed/electron-menu.js @@ -0,0 +1,78 @@ +/** + * Copyright 2018-present Facebook. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * @format + */ + +type Electron$BrowserWindow = any; +type Electron$NativeImage = any; + +type Electron$MenuRoles = + | 'undo' + | 'redo' + | 'cut' + | 'copy' + | 'paste' + | 'pasteandmatchstyle' + | 'selectall' + | 'delete' + | 'minimize' + | 'close' + | 'quit' + | 'togglefullscreen' // macOS-only + | 'about' + | 'hide' + | 'hideothers' + | 'unhide' + | 'front' + | 'zoom' + | 'window' + | 'help' + | 'services'; + +type Electron$MenuType = 'normal' | 'separator' | 'submenu' | 'checkbox' | 'radio'; + +type Electron$MenuItemOptions = { + click?: ( + menuItem: Electron$MenuItem, + browserWindow: Object, + event: Object, + ) => void, + role?: Electron$MenuRoles, + type?: Electron$MenuType, + label?: string, + sublabel?: string, + accelerator?: string, + icon?: Object, + enabled?: boolean, + visible?: boolean, + checked?: boolean, + submenu?: Electron$MenuItem | Electron$MenuItemOptions, + id?: string, + position?: string, +}; + +declare class Electron$MenuItem { + constructor: (options: Electron$MenuItemOptions) => void, + enabled: boolean, + visible: boolean, + checked: boolean, +} + +declare class Electron$Menu { + static setApplicationMenu: (menu: Electron$Menu) => void, + static getApplicationMenu: () => ?Electron$Menu, + static sendActionToFirstResponder: (action: string) => void, + static buildFromTemplate: (templates: Array) => Electron$Menu, + popup: ( + browserWindow: Object, + x?: number, + y?: number, + positioningItem?: number, + ) => void, + popup: (x?: number, y?: number, positioningItem?: number) => void, + append: (menuItem: Electron$MenuItem) => void, + insert: (pos: number, menuItem: Electron$MenuItem) => void, + items: Array, +} diff --git a/flow-typed/npm/JSONStream_vx.x.x.js b/flow-typed/npm/JSONStream_vx.x.x.js new file mode 100644 index 000000000..acc5481b3 --- /dev/null +++ b/flow-typed/npm/JSONStream_vx.x.x.js @@ -0,0 +1,192 @@ +// flow-typed signature: 2e82c8be2483588f05be3476cd2af900 +// flow-typed version: <>/JSONStream_v^1.3.1/flow_v0.59.0 + +/** + * This is an autogenerated libdef stub for: + * + * 'JSONStream' + * + * Fill this stub out by replacing all the `any` types. + * + * Once filled out, we encourage you to share your work with the + * community by sending a pull request to: + * https://github.com/flowtype/flow-typed + */ + +declare module 'JSONStream' { + declare module.exports: any; +} + +/** + * We include stubs for each file inside this npm package in case you need to + * require those files directly. Feel free to delete any files that aren't + * needed. + */ +declare module 'JSONStream/examples/all_docs' { + declare module.exports: any; +} + +declare module 'JSONStream/test/bool' { + declare module.exports: any; +} + +declare module 'JSONStream/test/browser' { + declare module.exports: any; +} + +declare module 'JSONStream/test/destroy_missing' { + declare module.exports: any; +} + +declare module 'JSONStream/test/disabled/doubledot1' { + declare module.exports: any; +} + +declare module 'JSONStream/test/disabled/doubledot2' { + declare module.exports: any; +} + +declare module 'JSONStream/test/empty' { + declare module.exports: any; +} + +declare module 'JSONStream/test/error_contents' { + declare module.exports: any; +} + +declare module 'JSONStream/test/fn' { + declare module.exports: any; +} + +declare module 'JSONStream/test/gen' { + declare module.exports: any; +} + +declare module 'JSONStream/test/header_footer' { + declare module.exports: any; +} + +declare module 'JSONStream/test/issues' { + declare module.exports: any; +} + +declare module 'JSONStream/test/keys' { + declare module.exports: any; +} + +declare module 'JSONStream/test/map' { + declare module.exports: any; +} + +declare module 'JSONStream/test/multiple_objects_error' { + declare module.exports: any; +} + +declare module 'JSONStream/test/multiple_objects' { + declare module.exports: any; +} + +declare module 'JSONStream/test/null' { + declare module.exports: any; +} + +declare module 'JSONStream/test/parsejson' { + declare module.exports: any; +} + +declare module 'JSONStream/test/stringify_object' { + declare module.exports: any; +} + +declare module 'JSONStream/test/stringify' { + declare module.exports: any; +} + +declare module 'JSONStream/test/test' { + declare module.exports: any; +} + +declare module 'JSONStream/test/test2' { + declare module.exports: any; +} + +declare module 'JSONStream/test/two-ways' { + declare module.exports: any; +} + +// Filename aliases +declare module 'JSONStream/examples/all_docs.js' { + declare module.exports: $Exports<'JSONStream/examples/all_docs'>; +} +declare module 'JSONStream/index' { + declare module.exports: $Exports<'JSONStream'>; +} +declare module 'JSONStream/index.js' { + declare module.exports: $Exports<'JSONStream'>; +} +declare module 'JSONStream/test/bool.js' { + declare module.exports: $Exports<'JSONStream/test/bool'>; +} +declare module 'JSONStream/test/browser.js' { + declare module.exports: $Exports<'JSONStream/test/browser'>; +} +declare module 'JSONStream/test/destroy_missing.js' { + declare module.exports: $Exports<'JSONStream/test/destroy_missing'>; +} +declare module 'JSONStream/test/disabled/doubledot1.js' { + declare module.exports: $Exports<'JSONStream/test/disabled/doubledot1'>; +} +declare module 'JSONStream/test/disabled/doubledot2.js' { + declare module.exports: $Exports<'JSONStream/test/disabled/doubledot2'>; +} +declare module 'JSONStream/test/empty.js' { + declare module.exports: $Exports<'JSONStream/test/empty'>; +} +declare module 'JSONStream/test/error_contents.js' { + declare module.exports: $Exports<'JSONStream/test/error_contents'>; +} +declare module 'JSONStream/test/fn.js' { + declare module.exports: $Exports<'JSONStream/test/fn'>; +} +declare module 'JSONStream/test/gen.js' { + declare module.exports: $Exports<'JSONStream/test/gen'>; +} +declare module 'JSONStream/test/header_footer.js' { + declare module.exports: $Exports<'JSONStream/test/header_footer'>; +} +declare module 'JSONStream/test/issues.js' { + declare module.exports: $Exports<'JSONStream/test/issues'>; +} +declare module 'JSONStream/test/keys.js' { + declare module.exports: $Exports<'JSONStream/test/keys'>; +} +declare module 'JSONStream/test/map.js' { + declare module.exports: $Exports<'JSONStream/test/map'>; +} +declare module 'JSONStream/test/multiple_objects_error.js' { + declare module.exports: $Exports<'JSONStream/test/multiple_objects_error'>; +} +declare module 'JSONStream/test/multiple_objects.js' { + declare module.exports: $Exports<'JSONStream/test/multiple_objects'>; +} +declare module 'JSONStream/test/null.js' { + declare module.exports: $Exports<'JSONStream/test/null'>; +} +declare module 'JSONStream/test/parsejson.js' { + declare module.exports: $Exports<'JSONStream/test/parsejson'>; +} +declare module 'JSONStream/test/stringify_object.js' { + declare module.exports: $Exports<'JSONStream/test/stringify_object'>; +} +declare module 'JSONStream/test/stringify.js' { + declare module.exports: $Exports<'JSONStream/test/stringify'>; +} +declare module 'JSONStream/test/test.js' { + declare module.exports: $Exports<'JSONStream/test/test'>; +} +declare module 'JSONStream/test/test2.js' { + declare module.exports: $Exports<'JSONStream/test/test2'>; +} +declare module 'JSONStream/test/two-ways.js' { + declare module.exports: $Exports<'JSONStream/test/two-ways'>; +} diff --git a/flow-typed/npm/adbkit-fb_vx.x.x.js b/flow-typed/npm/adbkit-fb_vx.x.x.js new file mode 100644 index 000000000..c1368acfb --- /dev/null +++ b/flow-typed/npm/adbkit-fb_vx.x.x.js @@ -0,0 +1,507 @@ +// flow-typed signature: 7849d9ce4b390afcfc917a08445a20eb +// flow-typed version: <>/adbkit-fb_v2.10.1/flow_v0.59.0 + +/** + * This is an autogenerated libdef stub for: + * + * 'adbkit-fb' + * + * Fill this stub out by replacing all the `any` types. + * + * Once filled out, we encourage you to share your work with the + * community by sending a pull request to: + * https://github.com/flowtype/flow-typed + */ + +declare module 'adbkit-fb' { + declare module.exports: any; +} + +/** + * We include stubs for each file inside this npm package in case you need to + * require those files directly. Feel free to delete any files that aren't + * needed. + */ +declare module 'adbkit-fb/lib/adb' { + declare module.exports: any; +} + +declare module 'adbkit-fb/lib/adb/auth' { + declare module.exports: any; +} + +declare module 'adbkit-fb/lib/adb/client' { + declare module.exports: any; +} + +declare module 'adbkit-fb/lib/adb/command' { + declare module.exports: any; +} + +declare module 'adbkit-fb/lib/adb/command/host-serial/forward' { + declare module.exports: any; +} + +declare module 'adbkit-fb/lib/adb/command/host-serial/getdevicepath' { + declare module.exports: any; +} + +declare module 'adbkit-fb/lib/adb/command/host-serial/getserialno' { + declare module.exports: any; +} + +declare module 'adbkit-fb/lib/adb/command/host-serial/getstate' { + declare module.exports: any; +} + +declare module 'adbkit-fb/lib/adb/command/host-serial/listforwards' { + declare module.exports: any; +} + +declare module 'adbkit-fb/lib/adb/command/host-serial/waitfordevice' { + declare module.exports: any; +} + +declare module 'adbkit-fb/lib/adb/command/host-transport/clear' { + declare module.exports: any; +} + +declare module 'adbkit-fb/lib/adb/command/host-transport/framebuffer' { + declare module.exports: any; +} + +declare module 'adbkit-fb/lib/adb/command/host-transport/getfeatures' { + declare module.exports: any; +} + +declare module 'adbkit-fb/lib/adb/command/host-transport/getpackages' { + declare module.exports: any; +} + +declare module 'adbkit-fb/lib/adb/command/host-transport/getproperties' { + declare module.exports: any; +} + +declare module 'adbkit-fb/lib/adb/command/host-transport/install' { + declare module.exports: any; +} + +declare module 'adbkit-fb/lib/adb/command/host-transport/isinstalled' { + declare module.exports: any; +} + +declare module 'adbkit-fb/lib/adb/command/host-transport/listreverses' { + declare module.exports: any; +} + +declare module 'adbkit-fb/lib/adb/command/host-transport/local' { + declare module.exports: any; +} + +declare module 'adbkit-fb/lib/adb/command/host-transport/log' { + declare module.exports: any; +} + +declare module 'adbkit-fb/lib/adb/command/host-transport/logcat' { + declare module.exports: any; +} + +declare module 'adbkit-fb/lib/adb/command/host-transport/monkey' { + declare module.exports: any; +} + +declare module 'adbkit-fb/lib/adb/command/host-transport/reboot' { + declare module.exports: any; +} + +declare module 'adbkit-fb/lib/adb/command/host-transport/remount' { + declare module.exports: any; +} + +declare module 'adbkit-fb/lib/adb/command/host-transport/reverse' { + declare module.exports: any; +} + +declare module 'adbkit-fb/lib/adb/command/host-transport/root' { + declare module.exports: any; +} + +declare module 'adbkit-fb/lib/adb/command/host-transport/screencap' { + declare module.exports: any; +} + +declare module 'adbkit-fb/lib/adb/command/host-transport/shell' { + declare module.exports: any; +} + +declare module 'adbkit-fb/lib/adb/command/host-transport/startactivity' { + declare module.exports: any; +} + +declare module 'adbkit-fb/lib/adb/command/host-transport/startservice' { + declare module.exports: any; +} + +declare module 'adbkit-fb/lib/adb/command/host-transport/sync' { + declare module.exports: any; +} + +declare module 'adbkit-fb/lib/adb/command/host-transport/tcp' { + declare module.exports: any; +} + +declare module 'adbkit-fb/lib/adb/command/host-transport/tcpip' { + declare module.exports: any; +} + +declare module 'adbkit-fb/lib/adb/command/host-transport/trackjdwp' { + declare module.exports: any; +} + +declare module 'adbkit-fb/lib/adb/command/host-transport/uninstall' { + declare module.exports: any; +} + +declare module 'adbkit-fb/lib/adb/command/host-transport/usb' { + declare module.exports: any; +} + +declare module 'adbkit-fb/lib/adb/command/host-transport/waitbootcomplete' { + declare module.exports: any; +} + +declare module 'adbkit-fb/lib/adb/command/host/connect' { + declare module.exports: any; +} + +declare module 'adbkit-fb/lib/adb/command/host/devices' { + declare module.exports: any; +} + +declare module 'adbkit-fb/lib/adb/command/host/deviceswithpaths' { + declare module.exports: any; +} + +declare module 'adbkit-fb/lib/adb/command/host/disconnect' { + declare module.exports: any; +} + +declare module 'adbkit-fb/lib/adb/command/host/kill' { + declare module.exports: any; +} + +declare module 'adbkit-fb/lib/adb/command/host/trackdevices' { + declare module.exports: any; +} + +declare module 'adbkit-fb/lib/adb/command/host/transport' { + declare module.exports: any; +} + +declare module 'adbkit-fb/lib/adb/command/host/version' { + declare module.exports: any; +} + +declare module 'adbkit-fb/lib/adb/connection' { + declare module.exports: any; +} + +declare module 'adbkit-fb/lib/adb/dump' { + declare module.exports: any; +} + +declare module 'adbkit-fb/lib/adb/framebuffer/rgbtransform' { + declare module.exports: any; +} + +declare module 'adbkit-fb/lib/adb/keycode' { + declare module.exports: any; +} + +declare module 'adbkit-fb/lib/adb/linetransform' { + declare module.exports: any; +} + +declare module 'adbkit-fb/lib/adb/parser' { + declare module.exports: any; +} + +declare module 'adbkit-fb/lib/adb/proc/stat' { + declare module.exports: any; +} + +declare module 'adbkit-fb/lib/adb/protocol' { + declare module.exports: any; +} + +declare module 'adbkit-fb/lib/adb/sync' { + declare module.exports: any; +} + +declare module 'adbkit-fb/lib/adb/sync/entry' { + declare module.exports: any; +} + +declare module 'adbkit-fb/lib/adb/sync/pulltransfer' { + declare module.exports: any; +} + +declare module 'adbkit-fb/lib/adb/sync/pushtransfer' { + declare module.exports: any; +} + +declare module 'adbkit-fb/lib/adb/sync/stats' { + declare module.exports: any; +} + +declare module 'adbkit-fb/lib/adb/tcpusb/packet' { + declare module.exports: any; +} + +declare module 'adbkit-fb/lib/adb/tcpusb/packetreader' { + declare module.exports: any; +} + +declare module 'adbkit-fb/lib/adb/tcpusb/rollingcounter' { + declare module.exports: any; +} + +declare module 'adbkit-fb/lib/adb/tcpusb/server' { + declare module.exports: any; +} + +declare module 'adbkit-fb/lib/adb/tcpusb/service' { + declare module.exports: any; +} + +declare module 'adbkit-fb/lib/adb/tcpusb/servicemap' { + declare module.exports: any; +} + +declare module 'adbkit-fb/lib/adb/tcpusb/socket' { + declare module.exports: any; +} + +declare module 'adbkit-fb/lib/adb/tracker' { + declare module.exports: any; +} + +declare module 'adbkit-fb/lib/adb/util' { + declare module.exports: any; +} + +declare module 'adbkit-fb/lib/cli' { + declare module.exports: any; +} + +// Filename aliases +declare module 'adbkit-fb/index' { + declare module.exports: $Exports<'adbkit-fb'>; +} +declare module 'adbkit-fb/index.js' { + declare module.exports: $Exports<'adbkit-fb'>; +} +declare module 'adbkit-fb/lib/adb.js' { + declare module.exports: $Exports<'adbkit-fb/lib/adb'>; +} +declare module 'adbkit-fb/lib/adb/auth.js' { + declare module.exports: $Exports<'adbkit-fb/lib/adb/auth'>; +} +declare module 'adbkit-fb/lib/adb/client.js' { + declare module.exports: $Exports<'adbkit-fb/lib/adb/client'>; +} +declare module 'adbkit-fb/lib/adb/command.js' { + declare module.exports: $Exports<'adbkit-fb/lib/adb/command'>; +} +declare module 'adbkit-fb/lib/adb/command/host-serial/forward.js' { + declare module.exports: $Exports<'adbkit-fb/lib/adb/command/host-serial/forward'>; +} +declare module 'adbkit-fb/lib/adb/command/host-serial/getdevicepath.js' { + declare module.exports: $Exports<'adbkit-fb/lib/adb/command/host-serial/getdevicepath'>; +} +declare module 'adbkit-fb/lib/adb/command/host-serial/getserialno.js' { + declare module.exports: $Exports<'adbkit-fb/lib/adb/command/host-serial/getserialno'>; +} +declare module 'adbkit-fb/lib/adb/command/host-serial/getstate.js' { + declare module.exports: $Exports<'adbkit-fb/lib/adb/command/host-serial/getstate'>; +} +declare module 'adbkit-fb/lib/adb/command/host-serial/listforwards.js' { + declare module.exports: $Exports<'adbkit-fb/lib/adb/command/host-serial/listforwards'>; +} +declare module 'adbkit-fb/lib/adb/command/host-serial/waitfordevice.js' { + declare module.exports: $Exports<'adbkit-fb/lib/adb/command/host-serial/waitfordevice'>; +} +declare module 'adbkit-fb/lib/adb/command/host-transport/clear.js' { + declare module.exports: $Exports<'adbkit-fb/lib/adb/command/host-transport/clear'>; +} +declare module 'adbkit-fb/lib/adb/command/host-transport/framebuffer.js' { + declare module.exports: $Exports<'adbkit-fb/lib/adb/command/host-transport/framebuffer'>; +} +declare module 'adbkit-fb/lib/adb/command/host-transport/getfeatures.js' { + declare module.exports: $Exports<'adbkit-fb/lib/adb/command/host-transport/getfeatures'>; +} +declare module 'adbkit-fb/lib/adb/command/host-transport/getpackages.js' { + declare module.exports: $Exports<'adbkit-fb/lib/adb/command/host-transport/getpackages'>; +} +declare module 'adbkit-fb/lib/adb/command/host-transport/getproperties.js' { + declare module.exports: $Exports<'adbkit-fb/lib/adb/command/host-transport/getproperties'>; +} +declare module 'adbkit-fb/lib/adb/command/host-transport/install.js' { + declare module.exports: $Exports<'adbkit-fb/lib/adb/command/host-transport/install'>; +} +declare module 'adbkit-fb/lib/adb/command/host-transport/isinstalled.js' { + declare module.exports: $Exports<'adbkit-fb/lib/adb/command/host-transport/isinstalled'>; +} +declare module 'adbkit-fb/lib/adb/command/host-transport/listreverses.js' { + declare module.exports: $Exports<'adbkit-fb/lib/adb/command/host-transport/listreverses'>; +} +declare module 'adbkit-fb/lib/adb/command/host-transport/local.js' { + declare module.exports: $Exports<'adbkit-fb/lib/adb/command/host-transport/local'>; +} +declare module 'adbkit-fb/lib/adb/command/host-transport/log.js' { + declare module.exports: $Exports<'adbkit-fb/lib/adb/command/host-transport/log'>; +} +declare module 'adbkit-fb/lib/adb/command/host-transport/logcat.js' { + declare module.exports: $Exports<'adbkit-fb/lib/adb/command/host-transport/logcat'>; +} +declare module 'adbkit-fb/lib/adb/command/host-transport/monkey.js' { + declare module.exports: $Exports<'adbkit-fb/lib/adb/command/host-transport/monkey'>; +} +declare module 'adbkit-fb/lib/adb/command/host-transport/reboot.js' { + declare module.exports: $Exports<'adbkit-fb/lib/adb/command/host-transport/reboot'>; +} +declare module 'adbkit-fb/lib/adb/command/host-transport/remount.js' { + declare module.exports: $Exports<'adbkit-fb/lib/adb/command/host-transport/remount'>; +} +declare module 'adbkit-fb/lib/adb/command/host-transport/reverse.js' { + declare module.exports: $Exports<'adbkit-fb/lib/adb/command/host-transport/reverse'>; +} +declare module 'adbkit-fb/lib/adb/command/host-transport/root.js' { + declare module.exports: $Exports<'adbkit-fb/lib/adb/command/host-transport/root'>; +} +declare module 'adbkit-fb/lib/adb/command/host-transport/screencap.js' { + declare module.exports: $Exports<'adbkit-fb/lib/adb/command/host-transport/screencap'>; +} +declare module 'adbkit-fb/lib/adb/command/host-transport/shell.js' { + declare module.exports: $Exports<'adbkit-fb/lib/adb/command/host-transport/shell'>; +} +declare module 'adbkit-fb/lib/adb/command/host-transport/startactivity.js' { + declare module.exports: $Exports<'adbkit-fb/lib/adb/command/host-transport/startactivity'>; +} +declare module 'adbkit-fb/lib/adb/command/host-transport/startservice.js' { + declare module.exports: $Exports<'adbkit-fb/lib/adb/command/host-transport/startservice'>; +} +declare module 'adbkit-fb/lib/adb/command/host-transport/sync.js' { + declare module.exports: $Exports<'adbkit-fb/lib/adb/command/host-transport/sync'>; +} +declare module 'adbkit-fb/lib/adb/command/host-transport/tcp.js' { + declare module.exports: $Exports<'adbkit-fb/lib/adb/command/host-transport/tcp'>; +} +declare module 'adbkit-fb/lib/adb/command/host-transport/tcpip.js' { + declare module.exports: $Exports<'adbkit-fb/lib/adb/command/host-transport/tcpip'>; +} +declare module 'adbkit-fb/lib/adb/command/host-transport/trackjdwp.js' { + declare module.exports: $Exports<'adbkit-fb/lib/adb/command/host-transport/trackjdwp'>; +} +declare module 'adbkit-fb/lib/adb/command/host-transport/uninstall.js' { + declare module.exports: $Exports<'adbkit-fb/lib/adb/command/host-transport/uninstall'>; +} +declare module 'adbkit-fb/lib/adb/command/host-transport/usb.js' { + declare module.exports: $Exports<'adbkit-fb/lib/adb/command/host-transport/usb'>; +} +declare module 'adbkit-fb/lib/adb/command/host-transport/waitbootcomplete.js' { + declare module.exports: $Exports<'adbkit-fb/lib/adb/command/host-transport/waitbootcomplete'>; +} +declare module 'adbkit-fb/lib/adb/command/host/connect.js' { + declare module.exports: $Exports<'adbkit-fb/lib/adb/command/host/connect'>; +} +declare module 'adbkit-fb/lib/adb/command/host/devices.js' { + declare module.exports: $Exports<'adbkit-fb/lib/adb/command/host/devices'>; +} +declare module 'adbkit-fb/lib/adb/command/host/deviceswithpaths.js' { + declare module.exports: $Exports<'adbkit-fb/lib/adb/command/host/deviceswithpaths'>; +} +declare module 'adbkit-fb/lib/adb/command/host/disconnect.js' { + declare module.exports: $Exports<'adbkit-fb/lib/adb/command/host/disconnect'>; +} +declare module 'adbkit-fb/lib/adb/command/host/kill.js' { + declare module.exports: $Exports<'adbkit-fb/lib/adb/command/host/kill'>; +} +declare module 'adbkit-fb/lib/adb/command/host/trackdevices.js' { + declare module.exports: $Exports<'adbkit-fb/lib/adb/command/host/trackdevices'>; +} +declare module 'adbkit-fb/lib/adb/command/host/transport.js' { + declare module.exports: $Exports<'adbkit-fb/lib/adb/command/host/transport'>; +} +declare module 'adbkit-fb/lib/adb/command/host/version.js' { + declare module.exports: $Exports<'adbkit-fb/lib/adb/command/host/version'>; +} +declare module 'adbkit-fb/lib/adb/connection.js' { + declare module.exports: $Exports<'adbkit-fb/lib/adb/connection'>; +} +declare module 'adbkit-fb/lib/adb/dump.js' { + declare module.exports: $Exports<'adbkit-fb/lib/adb/dump'>; +} +declare module 'adbkit-fb/lib/adb/framebuffer/rgbtransform.js' { + declare module.exports: $Exports<'adbkit-fb/lib/adb/framebuffer/rgbtransform'>; +} +declare module 'adbkit-fb/lib/adb/keycode.js' { + declare module.exports: $Exports<'adbkit-fb/lib/adb/keycode'>; +} +declare module 'adbkit-fb/lib/adb/linetransform.js' { + declare module.exports: $Exports<'adbkit-fb/lib/adb/linetransform'>; +} +declare module 'adbkit-fb/lib/adb/parser.js' { + declare module.exports: $Exports<'adbkit-fb/lib/adb/parser'>; +} +declare module 'adbkit-fb/lib/adb/proc/stat.js' { + declare module.exports: $Exports<'adbkit-fb/lib/adb/proc/stat'>; +} +declare module 'adbkit-fb/lib/adb/protocol.js' { + declare module.exports: $Exports<'adbkit-fb/lib/adb/protocol'>; +} +declare module 'adbkit-fb/lib/adb/sync.js' { + declare module.exports: $Exports<'adbkit-fb/lib/adb/sync'>; +} +declare module 'adbkit-fb/lib/adb/sync/entry.js' { + declare module.exports: $Exports<'adbkit-fb/lib/adb/sync/entry'>; +} +declare module 'adbkit-fb/lib/adb/sync/pulltransfer.js' { + declare module.exports: $Exports<'adbkit-fb/lib/adb/sync/pulltransfer'>; +} +declare module 'adbkit-fb/lib/adb/sync/pushtransfer.js' { + declare module.exports: $Exports<'adbkit-fb/lib/adb/sync/pushtransfer'>; +} +declare module 'adbkit-fb/lib/adb/sync/stats.js' { + declare module.exports: $Exports<'adbkit-fb/lib/adb/sync/stats'>; +} +declare module 'adbkit-fb/lib/adb/tcpusb/packet.js' { + declare module.exports: $Exports<'adbkit-fb/lib/adb/tcpusb/packet'>; +} +declare module 'adbkit-fb/lib/adb/tcpusb/packetreader.js' { + declare module.exports: $Exports<'adbkit-fb/lib/adb/tcpusb/packetreader'>; +} +declare module 'adbkit-fb/lib/adb/tcpusb/rollingcounter.js' { + declare module.exports: $Exports<'adbkit-fb/lib/adb/tcpusb/rollingcounter'>; +} +declare module 'adbkit-fb/lib/adb/tcpusb/server.js' { + declare module.exports: $Exports<'adbkit-fb/lib/adb/tcpusb/server'>; +} +declare module 'adbkit-fb/lib/adb/tcpusb/service.js' { + declare module.exports: $Exports<'adbkit-fb/lib/adb/tcpusb/service'>; +} +declare module 'adbkit-fb/lib/adb/tcpusb/servicemap.js' { + declare module.exports: $Exports<'adbkit-fb/lib/adb/tcpusb/servicemap'>; +} +declare module 'adbkit-fb/lib/adb/tcpusb/socket.js' { + declare module.exports: $Exports<'adbkit-fb/lib/adb/tcpusb/socket'>; +} +declare module 'adbkit-fb/lib/adb/tracker.js' { + declare module.exports: $Exports<'adbkit-fb/lib/adb/tracker'>; +} +declare module 'adbkit-fb/lib/adb/util.js' { + declare module.exports: $Exports<'adbkit-fb/lib/adb/util'>; +} +declare module 'adbkit-fb/lib/cli.js' { + declare module.exports: $Exports<'adbkit-fb/lib/cli'>; +} diff --git a/flow-typed/npm/adbkit-logcat-fb_vx.x.x.js b/flow-typed/npm/adbkit-logcat-fb_vx.x.x.js new file mode 100644 index 000000000..ee6b08588 --- /dev/null +++ b/flow-typed/npm/adbkit-logcat-fb_vx.x.x.js @@ -0,0 +1,80 @@ +// flow-typed signature: 4c4fcc7d39703336b04af263e250bdd1 +// flow-typed version: <>/adbkit-logcat-fb_v1.1.0/flow_v0.59.0 + +/** + * This is an autogenerated libdef stub for: + * + * 'adbkit-logcat-fb' + * + * Fill this stub out by replacing all the `any` types. + * + * Once filled out, we encourage you to share your work with the + * community by sending a pull request to: + * https://github.com/flowtype/flow-typed + */ + +declare module 'adbkit-logcat-fb' { + declare module.exports: any; +} + +/** + * We include stubs for each file inside this npm package in case you need to + * require those files directly. Feel free to delete any files that aren't + * needed. + */ +declare module 'adbkit-logcat-fb/lib/logcat' { + declare module.exports: any; +} + +declare module 'adbkit-logcat-fb/lib/logcat/entry' { + declare module.exports: any; +} + +declare module 'adbkit-logcat-fb/lib/logcat/parser' { + declare module.exports: any; +} + +declare module 'adbkit-logcat-fb/lib/logcat/parser/binary' { + declare module.exports: any; +} + +declare module 'adbkit-logcat-fb/lib/logcat/priority' { + declare module.exports: any; +} + +declare module 'adbkit-logcat-fb/lib/logcat/reader' { + declare module.exports: any; +} + +declare module 'adbkit-logcat-fb/lib/logcat/transform' { + declare module.exports: any; +} + +// Filename aliases +declare module 'adbkit-logcat-fb/index' { + declare module.exports: $Exports<'adbkit-logcat-fb'>; +} +declare module 'adbkit-logcat-fb/index.js' { + declare module.exports: $Exports<'adbkit-logcat-fb'>; +} +declare module 'adbkit-logcat-fb/lib/logcat.js' { + declare module.exports: $Exports<'adbkit-logcat-fb/lib/logcat'>; +} +declare module 'adbkit-logcat-fb/lib/logcat/entry.js' { + declare module.exports: $Exports<'adbkit-logcat-fb/lib/logcat/entry'>; +} +declare module 'adbkit-logcat-fb/lib/logcat/parser.js' { + declare module.exports: $Exports<'adbkit-logcat-fb/lib/logcat/parser'>; +} +declare module 'adbkit-logcat-fb/lib/logcat/parser/binary.js' { + declare module.exports: $Exports<'adbkit-logcat-fb/lib/logcat/parser/binary'>; +} +declare module 'adbkit-logcat-fb/lib/logcat/priority.js' { + declare module.exports: $Exports<'adbkit-logcat-fb/lib/logcat/priority'>; +} +declare module 'adbkit-logcat-fb/lib/logcat/reader.js' { + declare module.exports: $Exports<'adbkit-logcat-fb/lib/logcat/reader'>; +} +declare module 'adbkit-logcat-fb/lib/logcat/transform.js' { + declare module.exports: $Exports<'adbkit-logcat-fb/lib/logcat/transform'>; +} diff --git a/flow-typed/npm/babel-cli_vx.x.x.js b/flow-typed/npm/babel-cli_vx.x.x.js new file mode 100644 index 000000000..42c472acb --- /dev/null +++ b/flow-typed/npm/babel-cli_vx.x.x.js @@ -0,0 +1,108 @@ +// flow-typed signature: 0f7f1ee584ef43d0f9403cfe273cc39d +// flow-typed version: <>/babel-cli_v7.0.0-alpha.12/flow_v0.59.0 + +/** + * This is an autogenerated libdef stub for: + * + * 'babel-cli' + * + * Fill this stub out by replacing all the `any` types. + * + * Once filled out, we encourage you to share your work with the + * community by sending a pull request to: + * https://github.com/flowtype/flow-typed + */ + +declare module 'babel-cli' { + declare module.exports: any; +} + +/** + * We include stubs for each file inside this npm package in case you need to + * require those files directly. Feel free to delete any files that aren't + * needed. + */ +declare module 'babel-cli/bin/babel-doctor' { + declare module.exports: any; +} + +declare module 'babel-cli/bin/babel-external-helpers' { + declare module.exports: any; +} + +declare module 'babel-cli/bin/babel-node' { + declare module.exports: any; +} + +declare module 'babel-cli/bin/babel' { + declare module.exports: any; +} + +declare module 'babel-cli/lib/_babel-node' { + declare module.exports: any; +} + +declare module 'babel-cli/lib/babel-external-helpers' { + declare module.exports: any; +} + +declare module 'babel-cli/lib/babel-node' { + declare module.exports: any; +} + +declare module 'babel-cli/lib/babel/dir' { + declare module.exports: any; +} + +declare module 'babel-cli/lib/babel/file' { + declare module.exports: any; +} + +declare module 'babel-cli/lib/babel/index' { + declare module.exports: any; +} + +declare module 'babel-cli/lib/babel/util' { + declare module.exports: any; +} + +// Filename aliases +declare module 'babel-cli/bin/babel-doctor.js' { + declare module.exports: $Exports<'babel-cli/bin/babel-doctor'>; +} +declare module 'babel-cli/bin/babel-external-helpers.js' { + declare module.exports: $Exports<'babel-cli/bin/babel-external-helpers'>; +} +declare module 'babel-cli/bin/babel-node.js' { + declare module.exports: $Exports<'babel-cli/bin/babel-node'>; +} +declare module 'babel-cli/bin/babel.js' { + declare module.exports: $Exports<'babel-cli/bin/babel'>; +} +declare module 'babel-cli/index' { + declare module.exports: $Exports<'babel-cli'>; +} +declare module 'babel-cli/index.js' { + declare module.exports: $Exports<'babel-cli'>; +} +declare module 'babel-cli/lib/_babel-node.js' { + declare module.exports: $Exports<'babel-cli/lib/_babel-node'>; +} +declare module 'babel-cli/lib/babel-external-helpers.js' { + declare module.exports: $Exports<'babel-cli/lib/babel-external-helpers'>; +} +declare module 'babel-cli/lib/babel-node.js' { + declare module.exports: $Exports<'babel-cli/lib/babel-node'>; +} +declare module 'babel-cli/lib/babel/dir.js' { + declare module.exports: $Exports<'babel-cli/lib/babel/dir'>; +} +declare module 'babel-cli/lib/babel/file.js' { + declare module.exports: $Exports<'babel-cli/lib/babel/file'>; +} +declare module 'babel-cli/lib/babel/index.js' { + declare module.exports: $Exports<'babel-cli/lib/babel/index'>; +} +declare module 'babel-cli/lib/babel/util.js' { + declare module.exports: $Exports<'babel-cli/lib/babel/util'>; +} diff --git a/flow-typed/npm/babel-code-frame_vx.x.x.js b/flow-typed/npm/babel-code-frame_vx.x.x.js new file mode 100644 index 000000000..1f6832cf1 --- /dev/null +++ b/flow-typed/npm/babel-code-frame_vx.x.x.js @@ -0,0 +1,32 @@ +// flow-typed signature: d1d2d301b3f753cb6d40f8ac6d8df8c8 +// flow-typed version: <>/babel-code-frame_v^6.22.0/flow_v0.59.0 + +/** + * This is an autogenerated libdef stub for: + * + * 'babel-code-frame' + * + * Fill this stub out by replacing all the `any` types. + * + * Once filled out, we encourage you to share your work with the + * community by sending a pull request to: + * https://github.com/flowtype/flow-typed + */ + +declare module 'babel-code-frame' { + declare module.exports: any; +} + +/** + * We include stubs for each file inside this npm package in case you need to + * require those files directly. Feel free to delete any files that aren't + * needed. + */ +declare module 'babel-code-frame/lib/index' { + declare module.exports: any; +} + +// Filename aliases +declare module 'babel-code-frame/lib/index.js' { + declare module.exports: $Exports<'babel-code-frame/lib/index'>; +} diff --git a/flow-typed/npm/babel-core_vx.x.x.js b/flow-typed/npm/babel-core_vx.x.x.js new file mode 100644 index 000000000..6a02a9515 --- /dev/null +++ b/flow-typed/npm/babel-core_vx.x.x.js @@ -0,0 +1,171 @@ +// flow-typed signature: 8f20b8fc8e610a76416674f109b1d8bc +// flow-typed version: <>/babel-core_v7.0.0-alpha.12/flow_v0.59.0 + +/** + * This is an autogenerated libdef stub for: + * + * 'babel-core' + * + * Fill this stub out by replacing all the `any` types. + * + * Once filled out, we encourage you to share your work with the + * community by sending a pull request to: + * https://github.com/flowtype/flow-typed + */ + +declare module 'babel-core' { + declare module.exports: any; +} + +/** + * We include stubs for each file inside this npm package in case you need to + * require those files directly. Feel free to delete any files that aren't + * needed. + */ +declare module 'babel-core/lib/config/build-config-chain' { + declare module.exports: any; +} + +declare module 'babel-core/lib/config/caching' { + declare module.exports: any; +} + +declare module 'babel-core/lib/config/helpers/environment' { + declare module.exports: any; +} + +declare module 'babel-core/lib/config/index' { + declare module.exports: any; +} + +declare module 'babel-core/lib/config/loading/files/configuration' { + declare module.exports: any; +} + +declare module 'babel-core/lib/config/loading/files/index-browser' { + declare module.exports: any; +} + +declare module 'babel-core/lib/config/loading/files/index' { + declare module.exports: any; +} + +declare module 'babel-core/lib/config/loading/files/plugins' { + declare module.exports: any; +} + +declare module 'babel-core/lib/config/option-manager' { + declare module.exports: any; +} + +declare module 'babel-core/lib/config/plugin' { + declare module.exports: any; +} + +declare module 'babel-core/lib/config/removed' { + declare module.exports: any; +} + +declare module 'babel-core/lib/index' { + declare module.exports: any; +} + +declare module 'babel-core/lib/tools/build-external-helpers' { + declare module.exports: any; +} + +declare module 'babel-core/lib/transformation/file/index' { + declare module.exports: any; +} + +declare module 'babel-core/lib/transformation/file/metadata' { + declare module.exports: any; +} + +declare module 'babel-core/lib/transformation/internal-plugins/block-hoist' { + declare module.exports: any; +} + +declare module 'babel-core/lib/transformation/pipeline' { + declare module.exports: any; +} + +declare module 'babel-core/lib/transformation/plugin-pass' { + declare module.exports: any; +} + +declare module 'babel-core/lib/transformation/store' { + declare module.exports: any; +} + +declare module 'babel-core/register' { + declare module.exports: any; +} + +// Filename aliases +declare module 'babel-core/index' { + declare module.exports: $Exports<'babel-core'>; +} +declare module 'babel-core/index.js' { + declare module.exports: $Exports<'babel-core'>; +} +declare module 'babel-core/lib/config/build-config-chain.js' { + declare module.exports: $Exports<'babel-core/lib/config/build-config-chain'>; +} +declare module 'babel-core/lib/config/caching.js' { + declare module.exports: $Exports<'babel-core/lib/config/caching'>; +} +declare module 'babel-core/lib/config/helpers/environment.js' { + declare module.exports: $Exports<'babel-core/lib/config/helpers/environment'>; +} +declare module 'babel-core/lib/config/index.js' { + declare module.exports: $Exports<'babel-core/lib/config/index'>; +} +declare module 'babel-core/lib/config/loading/files/configuration.js' { + declare module.exports: $Exports<'babel-core/lib/config/loading/files/configuration'>; +} +declare module 'babel-core/lib/config/loading/files/index-browser.js' { + declare module.exports: $Exports<'babel-core/lib/config/loading/files/index-browser'>; +} +declare module 'babel-core/lib/config/loading/files/index.js' { + declare module.exports: $Exports<'babel-core/lib/config/loading/files/index'>; +} +declare module 'babel-core/lib/config/loading/files/plugins.js' { + declare module.exports: $Exports<'babel-core/lib/config/loading/files/plugins'>; +} +declare module 'babel-core/lib/config/option-manager.js' { + declare module.exports: $Exports<'babel-core/lib/config/option-manager'>; +} +declare module 'babel-core/lib/config/plugin.js' { + declare module.exports: $Exports<'babel-core/lib/config/plugin'>; +} +declare module 'babel-core/lib/config/removed.js' { + declare module.exports: $Exports<'babel-core/lib/config/removed'>; +} +declare module 'babel-core/lib/index.js' { + declare module.exports: $Exports<'babel-core/lib/index'>; +} +declare module 'babel-core/lib/tools/build-external-helpers.js' { + declare module.exports: $Exports<'babel-core/lib/tools/build-external-helpers'>; +} +declare module 'babel-core/lib/transformation/file/index.js' { + declare module.exports: $Exports<'babel-core/lib/transformation/file/index'>; +} +declare module 'babel-core/lib/transformation/file/metadata.js' { + declare module.exports: $Exports<'babel-core/lib/transformation/file/metadata'>; +} +declare module 'babel-core/lib/transformation/internal-plugins/block-hoist.js' { + declare module.exports: $Exports<'babel-core/lib/transformation/internal-plugins/block-hoist'>; +} +declare module 'babel-core/lib/transformation/pipeline.js' { + declare module.exports: $Exports<'babel-core/lib/transformation/pipeline'>; +} +declare module 'babel-core/lib/transformation/plugin-pass.js' { + declare module.exports: $Exports<'babel-core/lib/transformation/plugin-pass'>; +} +declare module 'babel-core/lib/transformation/store.js' { + declare module.exports: $Exports<'babel-core/lib/transformation/store'>; +} +declare module 'babel-core/register.js' { + declare module.exports: $Exports<'babel-core/register'>; +} diff --git a/flow-typed/npm/babel-eslint_vx.x.x.js b/flow-typed/npm/babel-eslint_vx.x.x.js new file mode 100644 index 000000000..5d5691246 --- /dev/null +++ b/flow-typed/npm/babel-eslint_vx.x.x.js @@ -0,0 +1,80 @@ +// flow-typed signature: 1fb22ed9a932c432e0fdd6cf6450c58e +// flow-typed version: <>/babel-eslint_v7.2.3/flow_v0.59.0 + +/** + * This is an autogenerated libdef stub for: + * + * 'babel-eslint' + * + * Fill this stub out by replacing all the `any` types. + * + * Once filled out, we encourage you to share your work with the + * community by sending a pull request to: + * https://github.com/flowtype/flow-typed + */ + +declare module 'babel-eslint' { + declare module.exports: any; +} + +/** + * We include stubs for each file inside this npm package in case you need to + * require those files directly. Feel free to delete any files that aren't + * needed. + */ +declare module 'babel-eslint/babylon-to-espree/attachComments' { + declare module.exports: any; +} + +declare module 'babel-eslint/babylon-to-espree/convertComments' { + declare module.exports: any; +} + +declare module 'babel-eslint/babylon-to-espree/convertTemplateType' { + declare module.exports: any; +} + +declare module 'babel-eslint/babylon-to-espree/index' { + declare module.exports: any; +} + +declare module 'babel-eslint/babylon-to-espree/toAST' { + declare module.exports: any; +} + +declare module 'babel-eslint/babylon-to-espree/toToken' { + declare module.exports: any; +} + +declare module 'babel-eslint/babylon-to-espree/toTokens' { + declare module.exports: any; +} + +// Filename aliases +declare module 'babel-eslint/babylon-to-espree/attachComments.js' { + declare module.exports: $Exports<'babel-eslint/babylon-to-espree/attachComments'>; +} +declare module 'babel-eslint/babylon-to-espree/convertComments.js' { + declare module.exports: $Exports<'babel-eslint/babylon-to-espree/convertComments'>; +} +declare module 'babel-eslint/babylon-to-espree/convertTemplateType.js' { + declare module.exports: $Exports<'babel-eslint/babylon-to-espree/convertTemplateType'>; +} +declare module 'babel-eslint/babylon-to-espree/index.js' { + declare module.exports: $Exports<'babel-eslint/babylon-to-espree/index'>; +} +declare module 'babel-eslint/babylon-to-espree/toAST.js' { + declare module.exports: $Exports<'babel-eslint/babylon-to-espree/toAST'>; +} +declare module 'babel-eslint/babylon-to-espree/toToken.js' { + declare module.exports: $Exports<'babel-eslint/babylon-to-espree/toToken'>; +} +declare module 'babel-eslint/babylon-to-espree/toTokens.js' { + declare module.exports: $Exports<'babel-eslint/babylon-to-espree/toTokens'>; +} +declare module 'babel-eslint/index' { + declare module.exports: $Exports<'babel-eslint'>; +} +declare module 'babel-eslint/index.js' { + declare module.exports: $Exports<'babel-eslint'>; +} diff --git a/flow-typed/npm/babel-generator_vx.x.x.js b/flow-typed/npm/babel-generator_vx.x.x.js new file mode 100644 index 000000000..ac06bae27 --- /dev/null +++ b/flow-typed/npm/babel-generator_vx.x.x.js @@ -0,0 +1,151 @@ +// flow-typed signature: 0b1639e0bffdd43bd3a51636725d6b05 +// flow-typed version: <>/babel-generator_v^6.24.1/flow_v0.59.0 + +/** + * This is an autogenerated libdef stub for: + * + * 'babel-generator' + * + * Fill this stub out by replacing all the `any` types. + * + * Once filled out, we encourage you to share your work with the + * community by sending a pull request to: + * https://github.com/flowtype/flow-typed + */ + +declare module 'babel-generator' { + declare module.exports: any; +} + +/** + * We include stubs for each file inside this npm package in case you need to + * require those files directly. Feel free to delete any files that aren't + * needed. + */ +declare module 'babel-generator/lib/buffer' { + declare module.exports: any; +} + +declare module 'babel-generator/lib/generators/base' { + declare module.exports: any; +} + +declare module 'babel-generator/lib/generators/classes' { + declare module.exports: any; +} + +declare module 'babel-generator/lib/generators/expressions' { + declare module.exports: any; +} + +declare module 'babel-generator/lib/generators/flow' { + declare module.exports: any; +} + +declare module 'babel-generator/lib/generators/jsx' { + declare module.exports: any; +} + +declare module 'babel-generator/lib/generators/methods' { + declare module.exports: any; +} + +declare module 'babel-generator/lib/generators/modules' { + declare module.exports: any; +} + +declare module 'babel-generator/lib/generators/statements' { + declare module.exports: any; +} + +declare module 'babel-generator/lib/generators/template-literals' { + declare module.exports: any; +} + +declare module 'babel-generator/lib/generators/types' { + declare module.exports: any; +} + +declare module 'babel-generator/lib/index' { + declare module.exports: any; +} + +declare module 'babel-generator/lib/node/index' { + declare module.exports: any; +} + +declare module 'babel-generator/lib/node/parentheses' { + declare module.exports: any; +} + +declare module 'babel-generator/lib/node/whitespace' { + declare module.exports: any; +} + +declare module 'babel-generator/lib/printer' { + declare module.exports: any; +} + +declare module 'babel-generator/lib/source-map' { + declare module.exports: any; +} + +declare module 'babel-generator/lib/whitespace' { + declare module.exports: any; +} + +// Filename aliases +declare module 'babel-generator/lib/buffer.js' { + declare module.exports: $Exports<'babel-generator/lib/buffer'>; +} +declare module 'babel-generator/lib/generators/base.js' { + declare module.exports: $Exports<'babel-generator/lib/generators/base'>; +} +declare module 'babel-generator/lib/generators/classes.js' { + declare module.exports: $Exports<'babel-generator/lib/generators/classes'>; +} +declare module 'babel-generator/lib/generators/expressions.js' { + declare module.exports: $Exports<'babel-generator/lib/generators/expressions'>; +} +declare module 'babel-generator/lib/generators/flow.js' { + declare module.exports: $Exports<'babel-generator/lib/generators/flow'>; +} +declare module 'babel-generator/lib/generators/jsx.js' { + declare module.exports: $Exports<'babel-generator/lib/generators/jsx'>; +} +declare module 'babel-generator/lib/generators/methods.js' { + declare module.exports: $Exports<'babel-generator/lib/generators/methods'>; +} +declare module 'babel-generator/lib/generators/modules.js' { + declare module.exports: $Exports<'babel-generator/lib/generators/modules'>; +} +declare module 'babel-generator/lib/generators/statements.js' { + declare module.exports: $Exports<'babel-generator/lib/generators/statements'>; +} +declare module 'babel-generator/lib/generators/template-literals.js' { + declare module.exports: $Exports<'babel-generator/lib/generators/template-literals'>; +} +declare module 'babel-generator/lib/generators/types.js' { + declare module.exports: $Exports<'babel-generator/lib/generators/types'>; +} +declare module 'babel-generator/lib/index.js' { + declare module.exports: $Exports<'babel-generator/lib/index'>; +} +declare module 'babel-generator/lib/node/index.js' { + declare module.exports: $Exports<'babel-generator/lib/node/index'>; +} +declare module 'babel-generator/lib/node/parentheses.js' { + declare module.exports: $Exports<'babel-generator/lib/node/parentheses'>; +} +declare module 'babel-generator/lib/node/whitespace.js' { + declare module.exports: $Exports<'babel-generator/lib/node/whitespace'>; +} +declare module 'babel-generator/lib/printer.js' { + declare module.exports: $Exports<'babel-generator/lib/printer'>; +} +declare module 'babel-generator/lib/source-map.js' { + declare module.exports: $Exports<'babel-generator/lib/source-map'>; +} +declare module 'babel-generator/lib/whitespace.js' { + declare module.exports: $Exports<'babel-generator/lib/whitespace'>; +} diff --git a/flow-typed/npm/babel-plugin-transform-class-properties_vx.x.x.js b/flow-typed/npm/babel-plugin-transform-class-properties_vx.x.x.js new file mode 100644 index 000000000..e28205880 --- /dev/null +++ b/flow-typed/npm/babel-plugin-transform-class-properties_vx.x.x.js @@ -0,0 +1,32 @@ +// flow-typed signature: b952c89ce390b876119ae568acff43b6 +// flow-typed version: <>/babel-plugin-transform-class-properties_v7.0.0-alpha.12/flow_v0.59.0 + +/** + * This is an autogenerated libdef stub for: + * + * 'babel-plugin-transform-class-properties' + * + * Fill this stub out by replacing all the `any` types. + * + * Once filled out, we encourage you to share your work with the + * community by sending a pull request to: + * https://github.com/flowtype/flow-typed + */ + +declare module 'babel-plugin-transform-class-properties' { + declare module.exports: any; +} + +/** + * We include stubs for each file inside this npm package in case you need to + * require those files directly. Feel free to delete any files that aren't + * needed. + */ +declare module 'babel-plugin-transform-class-properties/lib/index' { + declare module.exports: any; +} + +// Filename aliases +declare module 'babel-plugin-transform-class-properties/lib/index.js' { + declare module.exports: $Exports<'babel-plugin-transform-class-properties/lib/index'>; +} diff --git a/flow-typed/npm/babel-plugin-transform-es2015-destructuring_vx.x.x.js b/flow-typed/npm/babel-plugin-transform-es2015-destructuring_vx.x.x.js new file mode 100644 index 000000000..c9f302562 --- /dev/null +++ b/flow-typed/npm/babel-plugin-transform-es2015-destructuring_vx.x.x.js @@ -0,0 +1,32 @@ +// flow-typed signature: 1bad2e410546918dc0e7272dc87e0a34 +// flow-typed version: <>/babel-plugin-transform-es2015-destructuring_v7.0.0-alpha.12/flow_v0.59.0 + +/** + * This is an autogenerated libdef stub for: + * + * 'babel-plugin-transform-es2015-destructuring' + * + * Fill this stub out by replacing all the `any` types. + * + * Once filled out, we encourage you to share your work with the + * community by sending a pull request to: + * https://github.com/flowtype/flow-typed + */ + +declare module 'babel-plugin-transform-es2015-destructuring' { + declare module.exports: any; +} + +/** + * We include stubs for each file inside this npm package in case you need to + * require those files directly. Feel free to delete any files that aren't + * needed. + */ +declare module 'babel-plugin-transform-es2015-destructuring/lib/index' { + declare module.exports: any; +} + +// Filename aliases +declare module 'babel-plugin-transform-es2015-destructuring/lib/index.js' { + declare module.exports: $Exports<'babel-plugin-transform-es2015-destructuring/lib/index'>; +} diff --git a/flow-typed/npm/babel-plugin-transform-es2015-modules-commonjs_vx.x.x.js b/flow-typed/npm/babel-plugin-transform-es2015-modules-commonjs_vx.x.x.js new file mode 100644 index 000000000..b8bde563e --- /dev/null +++ b/flow-typed/npm/babel-plugin-transform-es2015-modules-commonjs_vx.x.x.js @@ -0,0 +1,32 @@ +// flow-typed signature: bc928daf5d3cf67f45a4ae5920314b13 +// flow-typed version: <>/babel-plugin-transform-es2015-modules-commonjs_v7.0.0-alpha.12/flow_v0.59.0 + +/** + * This is an autogenerated libdef stub for: + * + * 'babel-plugin-transform-es2015-modules-commonjs' + * + * Fill this stub out by replacing all the `any` types. + * + * Once filled out, we encourage you to share your work with the + * community by sending a pull request to: + * https://github.com/flowtype/flow-typed + */ + +declare module 'babel-plugin-transform-es2015-modules-commonjs' { + declare module.exports: any; +} + +/** + * We include stubs for each file inside this npm package in case you need to + * require those files directly. Feel free to delete any files that aren't + * needed. + */ +declare module 'babel-plugin-transform-es2015-modules-commonjs/lib/index' { + declare module.exports: any; +} + +// Filename aliases +declare module 'babel-plugin-transform-es2015-modules-commonjs/lib/index.js' { + declare module.exports: $Exports<'babel-plugin-transform-es2015-modules-commonjs/lib/index'>; +} diff --git a/flow-typed/npm/babel-plugin-transform-flow-strip-types_vx.x.x.js b/flow-typed/npm/babel-plugin-transform-flow-strip-types_vx.x.x.js new file mode 100644 index 000000000..8caeef16d --- /dev/null +++ b/flow-typed/npm/babel-plugin-transform-flow-strip-types_vx.x.x.js @@ -0,0 +1,32 @@ +// flow-typed signature: 8f14e19a39c2bd3974954eea41f59410 +// flow-typed version: <>/babel-plugin-transform-flow-strip-types_v7.0.0-alpha.12/flow_v0.59.0 + +/** + * This is an autogenerated libdef stub for: + * + * 'babel-plugin-transform-flow-strip-types' + * + * Fill this stub out by replacing all the `any` types. + * + * Once filled out, we encourage you to share your work with the + * community by sending a pull request to: + * https://github.com/flowtype/flow-typed + */ + +declare module 'babel-plugin-transform-flow-strip-types' { + declare module.exports: any; +} + +/** + * We include stubs for each file inside this npm package in case you need to + * require those files directly. Feel free to delete any files that aren't + * needed. + */ +declare module 'babel-plugin-transform-flow-strip-types/lib/index' { + declare module.exports: any; +} + +// Filename aliases +declare module 'babel-plugin-transform-flow-strip-types/lib/index.js' { + declare module.exports: $Exports<'babel-plugin-transform-flow-strip-types/lib/index'>; +} diff --git a/flow-typed/npm/babel-plugin-transform-object-rest-spread_vx.x.x.js b/flow-typed/npm/babel-plugin-transform-object-rest-spread_vx.x.x.js new file mode 100644 index 000000000..1788c5ba0 --- /dev/null +++ b/flow-typed/npm/babel-plugin-transform-object-rest-spread_vx.x.x.js @@ -0,0 +1,32 @@ +// flow-typed signature: 529d59fc1e249a090e2a76a3835db876 +// flow-typed version: <>/babel-plugin-transform-object-rest-spread_v7.0.0-alpha.12/flow_v0.59.0 + +/** + * This is an autogenerated libdef stub for: + * + * 'babel-plugin-transform-object-rest-spread' + * + * Fill this stub out by replacing all the `any` types. + * + * Once filled out, we encourage you to share your work with the + * community by sending a pull request to: + * https://github.com/flowtype/flow-typed + */ + +declare module 'babel-plugin-transform-object-rest-spread' { + declare module.exports: any; +} + +/** + * We include stubs for each file inside this npm package in case you need to + * require those files directly. Feel free to delete any files that aren't + * needed. + */ +declare module 'babel-plugin-transform-object-rest-spread/lib/index' { + declare module.exports: any; +} + +// Filename aliases +declare module 'babel-plugin-transform-object-rest-spread/lib/index.js' { + declare module.exports: $Exports<'babel-plugin-transform-object-rest-spread/lib/index'>; +} diff --git a/flow-typed/npm/babel-preset-react_vx.x.x.js b/flow-typed/npm/babel-preset-react_vx.x.x.js new file mode 100644 index 000000000..5d64556c3 --- /dev/null +++ b/flow-typed/npm/babel-preset-react_vx.x.x.js @@ -0,0 +1,32 @@ +// flow-typed signature: 1daf2e279938e1a1932c392cf775b7dc +// flow-typed version: <>/babel-preset-react_v7.0.0-alpha.12/flow_v0.59.0 + +/** + * This is an autogenerated libdef stub for: + * + * 'babel-preset-react' + * + * Fill this stub out by replacing all the `any` types. + * + * Once filled out, we encourage you to share your work with the + * community by sending a pull request to: + * https://github.com/flowtype/flow-typed + */ + +declare module 'babel-preset-react' { + declare module.exports: any; +} + +/** + * We include stubs for each file inside this npm package in case you need to + * require those files directly. Feel free to delete any files that aren't + * needed. + */ +declare module 'babel-preset-react/lib/index' { + declare module.exports: any; +} + +// Filename aliases +declare module 'babel-preset-react/lib/index.js' { + declare module.exports: $Exports<'babel-preset-react/lib/index'>; +} diff --git a/flow-typed/npm/babel-register_vx.x.x.js b/flow-typed/npm/babel-register_vx.x.x.js new file mode 100644 index 000000000..66bd624c1 --- /dev/null +++ b/flow-typed/npm/babel-register_vx.x.x.js @@ -0,0 +1,46 @@ +// flow-typed signature: d1ce10c85f971481323ed89a9b5029e0 +// flow-typed version: <>/babel-register_v7.0.0-alpha.12/flow_v0.59.0 + +/** + * This is an autogenerated libdef stub for: + * + * 'babel-register' + * + * Fill this stub out by replacing all the `any` types. + * + * Once filled out, we encourage you to share your work with the + * community by sending a pull request to: + * https://github.com/flowtype/flow-typed + */ + +declare module 'babel-register' { + declare module.exports: any; +} + +/** + * We include stubs for each file inside this npm package in case you need to + * require those files directly. Feel free to delete any files that aren't + * needed. + */ +declare module 'babel-register/lib/browser' { + declare module.exports: any; +} + +declare module 'babel-register/lib/cache' { + declare module.exports: any; +} + +declare module 'babel-register/lib/node' { + declare module.exports: any; +} + +// Filename aliases +declare module 'babel-register/lib/browser.js' { + declare module.exports: $Exports<'babel-register/lib/browser'>; +} +declare module 'babel-register/lib/cache.js' { + declare module.exports: $Exports<'babel-register/lib/cache'>; +} +declare module 'babel-register/lib/node.js' { + declare module.exports: $Exports<'babel-register/lib/node'>; +} diff --git a/flow-typed/npm/babel-traverse_vx.x.x.js b/flow-typed/npm/babel-traverse_vx.x.x.js new file mode 100644 index 000000000..ed78f5990 --- /dev/null +++ b/flow-typed/npm/babel-traverse_vx.x.x.js @@ -0,0 +1,200 @@ +// flow-typed signature: b39ccdff10eaf6fe22d8bbd6a6415324 +// flow-typed version: <>/babel-traverse_v7.0.0-alpha.12/flow_v0.59.0 + +/** + * This is an autogenerated libdef stub for: + * + * 'babel-traverse' + * + * Fill this stub out by replacing all the `any` types. + * + * Once filled out, we encourage you to share your work with the + * community by sending a pull request to: + * https://github.com/flowtype/flow-typed + */ + +declare module 'babel-traverse' { + declare module.exports: any; +} + +/** + * We include stubs for each file inside this npm package in case you need to + * require those files directly. Feel free to delete any files that aren't + * needed. + */ +declare module 'babel-traverse/lib/cache' { + declare module.exports: any; +} + +declare module 'babel-traverse/lib/context' { + declare module.exports: any; +} + +declare module 'babel-traverse/lib/hub' { + declare module.exports: any; +} + +declare module 'babel-traverse/lib/index' { + declare module.exports: any; +} + +declare module 'babel-traverse/lib/path/ancestry' { + declare module.exports: any; +} + +declare module 'babel-traverse/lib/path/comments' { + declare module.exports: any; +} + +declare module 'babel-traverse/lib/path/context' { + declare module.exports: any; +} + +declare module 'babel-traverse/lib/path/conversion' { + declare module.exports: any; +} + +declare module 'babel-traverse/lib/path/evaluation' { + declare module.exports: any; +} + +declare module 'babel-traverse/lib/path/family' { + declare module.exports: any; +} + +declare module 'babel-traverse/lib/path/index' { + declare module.exports: any; +} + +declare module 'babel-traverse/lib/path/inference/index' { + declare module.exports: any; +} + +declare module 'babel-traverse/lib/path/inference/inferer-reference' { + declare module.exports: any; +} + +declare module 'babel-traverse/lib/path/inference/inferers' { + declare module.exports: any; +} + +declare module 'babel-traverse/lib/path/introspection' { + declare module.exports: any; +} + +declare module 'babel-traverse/lib/path/lib/hoister' { + declare module.exports: any; +} + +declare module 'babel-traverse/lib/path/lib/removal-hooks' { + declare module.exports: any; +} + +declare module 'babel-traverse/lib/path/lib/virtual-types' { + declare module.exports: any; +} + +declare module 'babel-traverse/lib/path/modification' { + declare module.exports: any; +} + +declare module 'babel-traverse/lib/path/removal' { + declare module.exports: any; +} + +declare module 'babel-traverse/lib/path/replacement' { + declare module.exports: any; +} + +declare module 'babel-traverse/lib/scope/binding' { + declare module.exports: any; +} + +declare module 'babel-traverse/lib/scope/index' { + declare module.exports: any; +} + +declare module 'babel-traverse/lib/scope/lib/renamer' { + declare module.exports: any; +} + +declare module 'babel-traverse/lib/visitors' { + declare module.exports: any; +} + +// Filename aliases +declare module 'babel-traverse/lib/cache.js' { + declare module.exports: $Exports<'babel-traverse/lib/cache'>; +} +declare module 'babel-traverse/lib/context.js' { + declare module.exports: $Exports<'babel-traverse/lib/context'>; +} +declare module 'babel-traverse/lib/hub.js' { + declare module.exports: $Exports<'babel-traverse/lib/hub'>; +} +declare module 'babel-traverse/lib/index.js' { + declare module.exports: $Exports<'babel-traverse/lib/index'>; +} +declare module 'babel-traverse/lib/path/ancestry.js' { + declare module.exports: $Exports<'babel-traverse/lib/path/ancestry'>; +} +declare module 'babel-traverse/lib/path/comments.js' { + declare module.exports: $Exports<'babel-traverse/lib/path/comments'>; +} +declare module 'babel-traverse/lib/path/context.js' { + declare module.exports: $Exports<'babel-traverse/lib/path/context'>; +} +declare module 'babel-traverse/lib/path/conversion.js' { + declare module.exports: $Exports<'babel-traverse/lib/path/conversion'>; +} +declare module 'babel-traverse/lib/path/evaluation.js' { + declare module.exports: $Exports<'babel-traverse/lib/path/evaluation'>; +} +declare module 'babel-traverse/lib/path/family.js' { + declare module.exports: $Exports<'babel-traverse/lib/path/family'>; +} +declare module 'babel-traverse/lib/path/index.js' { + declare module.exports: $Exports<'babel-traverse/lib/path/index'>; +} +declare module 'babel-traverse/lib/path/inference/index.js' { + declare module.exports: $Exports<'babel-traverse/lib/path/inference/index'>; +} +declare module 'babel-traverse/lib/path/inference/inferer-reference.js' { + declare module.exports: $Exports<'babel-traverse/lib/path/inference/inferer-reference'>; +} +declare module 'babel-traverse/lib/path/inference/inferers.js' { + declare module.exports: $Exports<'babel-traverse/lib/path/inference/inferers'>; +} +declare module 'babel-traverse/lib/path/introspection.js' { + declare module.exports: $Exports<'babel-traverse/lib/path/introspection'>; +} +declare module 'babel-traverse/lib/path/lib/hoister.js' { + declare module.exports: $Exports<'babel-traverse/lib/path/lib/hoister'>; +} +declare module 'babel-traverse/lib/path/lib/removal-hooks.js' { + declare module.exports: $Exports<'babel-traverse/lib/path/lib/removal-hooks'>; +} +declare module 'babel-traverse/lib/path/lib/virtual-types.js' { + declare module.exports: $Exports<'babel-traverse/lib/path/lib/virtual-types'>; +} +declare module 'babel-traverse/lib/path/modification.js' { + declare module.exports: $Exports<'babel-traverse/lib/path/modification'>; +} +declare module 'babel-traverse/lib/path/removal.js' { + declare module.exports: $Exports<'babel-traverse/lib/path/removal'>; +} +declare module 'babel-traverse/lib/path/replacement.js' { + declare module.exports: $Exports<'babel-traverse/lib/path/replacement'>; +} +declare module 'babel-traverse/lib/scope/binding.js' { + declare module.exports: $Exports<'babel-traverse/lib/scope/binding'>; +} +declare module 'babel-traverse/lib/scope/index.js' { + declare module.exports: $Exports<'babel-traverse/lib/scope/index'>; +} +declare module 'babel-traverse/lib/scope/lib/renamer.js' { + declare module.exports: $Exports<'babel-traverse/lib/scope/lib/renamer'>; +} +declare module 'babel-traverse/lib/visitors.js' { + declare module.exports: $Exports<'babel-traverse/lib/visitors'>; +} diff --git a/flow-typed/npm/babylon_vx.x.x.js b/flow-typed/npm/babylon_vx.x.x.js new file mode 100644 index 000000000..06d23c2be --- /dev/null +++ b/flow-typed/npm/babylon_vx.x.x.js @@ -0,0 +1,46 @@ +// flow-typed signature: f472557a9bcea4a046c88cdcdd21ff40 +// flow-typed version: <>/babylon_v7.0.0-beta.14/flow_v0.59.0 + +/** + * This is an autogenerated libdef stub for: + * + * 'babylon' + * + * Fill this stub out by replacing all the `any` types. + * + * Once filled out, we encourage you to share your work with the + * community by sending a pull request to: + * https://github.com/flowtype/flow-typed + */ + +declare module 'babylon' { + declare module.exports: any; +} + +/** + * We include stubs for each file inside this npm package in case you need to + * require those files directly. Feel free to delete any files that aren't + * needed. + */ +declare module 'babylon/bin/babylon' { + declare module.exports: any; +} + +declare module 'babylon/bin/generate-identifier-regex' { + declare module.exports: any; +} + +declare module 'babylon/lib/index' { + declare module.exports: any; +} + +// Filename aliases +declare module 'babylon/bin/babylon.js' { + declare module.exports: $Exports<'babylon/bin/babylon'>; +} +declare module 'babylon/bin/generate-identifier-regex.js' { + declare module.exports: $Exports<'babylon/bin/generate-identifier-regex'>; +} +declare module 'babylon/lib/index.js' { + declare module.exports: $Exports<'babylon/lib/index'>; +} diff --git a/flow-typed/npm/chalk_v1.x.x.js b/flow-typed/npm/chalk_v1.x.x.js new file mode 100644 index 000000000..9cabf16bc --- /dev/null +++ b/flow-typed/npm/chalk_v1.x.x.js @@ -0,0 +1,114 @@ +// flow-typed signature: b1a2d646047879188d7e44cb218212b5 +// flow-typed version: b43dff3e0e/chalk_v1.x.x/flow_>=v0.19.x + +type $npm$chalk$StyleElement = { + open: string; + close: string; +}; + +type $npm$chalk$Chain = $npm$chalk$Style & (...text: any[]) => string; + +type $npm$chalk$Style = { + // General + reset: $npm$chalk$Chain; + bold: $npm$chalk$Chain; + dim: $npm$chalk$Chain; + italic: $npm$chalk$Chain; + underline: $npm$chalk$Chain; + inverse: $npm$chalk$Chain; + strikethrough: $npm$chalk$Chain; + + // Text colors + black: $npm$chalk$Chain; + red: $npm$chalk$Chain; + green: $npm$chalk$Chain; + yellow: $npm$chalk$Chain; + blue: $npm$chalk$Chain; + magenta: $npm$chalk$Chain; + cyan: $npm$chalk$Chain; + white: $npm$chalk$Chain; + gray: $npm$chalk$Chain; + grey: $npm$chalk$Chain; + + // Background colors + bgBlack: $npm$chalk$Chain; + bgRed: $npm$chalk$Chain; + bgGreen: $npm$chalk$Chain; + bgYellow: $npm$chalk$Chain; + bgBlue: $npm$chalk$Chain; + bgMagenta: $npm$chalk$Chain; + bgCyan: $npm$chalk$Chain; + bgWhite: $npm$chalk$Chain; +}; + +type $npm$chalk$StyleMap = { + // General + reset: $npm$chalk$StyleElement; + bold: $npm$chalk$StyleElement; + dim: $npm$chalk$StyleElement; + italic: $npm$chalk$StyleElement; + underline: $npm$chalk$StyleElement; + inverse: $npm$chalk$StyleElement; + strikethrough: $npm$chalk$StyleElement; + + // Text colors + black: $npm$chalk$StyleElement; + red: $npm$chalk$StyleElement; + green: $npm$chalk$StyleElement; + yellow: $npm$chalk$StyleElement; + blue: $npm$chalk$StyleElement; + magenta: $npm$chalk$StyleElement; + cyan: $npm$chalk$StyleElement; + white: $npm$chalk$StyleElement; + gray: $npm$chalk$StyleElement; + + // Background colors + bgBlack: $npm$chalk$StyleElement; + bgRed: $npm$chalk$StyleElement; + bgGreen: $npm$chalk$StyleElement; + bgYellow: $npm$chalk$StyleElement; + bgBlue: $npm$chalk$StyleElement; + bgMagenta: $npm$chalk$StyleElement; + bgCyan: $npm$chalk$StyleElement; + bgWhite: $npm$chalk$StyleElement; +}; + +declare module "chalk" { + declare var enabled: boolean; + declare var supportsColor: boolean; + declare var styles: $npm$chalk$StyleMap; + + declare function stripColor(value: string): any; + declare function hasColor(str: string): boolean; + + // General + declare var reset: $npm$chalk$Chain; + declare var bold: $npm$chalk$Chain; + declare var dim: $npm$chalk$Chain; + declare var italic: $npm$chalk$Chain; + declare var underline: $npm$chalk$Chain; + declare var inverse: $npm$chalk$Chain; + declare var strikethrough: $npm$chalk$Chain; + + // Text colors + declare var black: $npm$chalk$Chain; + declare var red: $npm$chalk$Chain; + declare var green: $npm$chalk$Chain; + declare var yellow: $npm$chalk$Chain; + declare var blue: $npm$chalk$Chain; + declare var magenta: $npm$chalk$Chain; + declare var cyan: $npm$chalk$Chain; + declare var white: $npm$chalk$Chain; + declare var gray: $npm$chalk$Chain; + declare var grey: $npm$chalk$Chain; + + // Background colors + declare var bgBlack: $npm$chalk$Chain; + declare var bgRed: $npm$chalk$Chain; + declare var bgGreen: $npm$chalk$Chain; + declare var bgYellow: $npm$chalk$Chain; + declare var bgBlue: $npm$chalk$Chain; + declare var bgMagenta: $npm$chalk$Chain; + declare var bgCyan: $npm$chalk$Chain; + declare var bgWhite: $npm$chalk$Chain; +} diff --git a/flow-typed/npm/codemirror_vx.x.x.js b/flow-typed/npm/codemirror_vx.x.x.js new file mode 100644 index 000000000..3898aefd4 --- /dev/null +++ b/flow-typed/npm/codemirror_vx.x.x.js @@ -0,0 +1,1761 @@ +// flow-typed signature: 56334b937a6991fded5d2f2312821ccd +// flow-typed version: <>/codemirror_v^5.25.0/flow_v0.59.0 + +/** + * This is an autogenerated libdef stub for: + * + * 'codemirror' + * + * Fill this stub out by replacing all the `any` types. + * + * Once filled out, we encourage you to share your work with the + * community by sending a pull request to: + * https://github.com/flowtype/flow-typed + */ + +declare module 'codemirror' { + declare module.exports: any; +} + +/** + * We include stubs for each file inside this npm package in case you need to + * require those files directly. Feel free to delete any files that aren't + * needed. + */ +declare module 'codemirror/addon/comment/comment' { + declare module.exports: any; +} + +declare module 'codemirror/addon/comment/continuecomment' { + declare module.exports: any; +} + +declare module 'codemirror/addon/dialog/dialog' { + declare module.exports: any; +} + +declare module 'codemirror/addon/display/autorefresh' { + declare module.exports: any; +} + +declare module 'codemirror/addon/display/fullscreen' { + declare module.exports: any; +} + +declare module 'codemirror/addon/display/panel' { + declare module.exports: any; +} + +declare module 'codemirror/addon/display/placeholder' { + declare module.exports: any; +} + +declare module 'codemirror/addon/display/rulers' { + declare module.exports: any; +} + +declare module 'codemirror/addon/edit/closebrackets' { + declare module.exports: any; +} + +declare module 'codemirror/addon/edit/closetag' { + declare module.exports: any; +} + +declare module 'codemirror/addon/edit/continuelist' { + declare module.exports: any; +} + +declare module 'codemirror/addon/edit/matchbrackets' { + declare module.exports: any; +} + +declare module 'codemirror/addon/edit/matchtags' { + declare module.exports: any; +} + +declare module 'codemirror/addon/edit/trailingspace' { + declare module.exports: any; +} + +declare module 'codemirror/addon/fold/brace-fold' { + declare module.exports: any; +} + +declare module 'codemirror/addon/fold/comment-fold' { + declare module.exports: any; +} + +declare module 'codemirror/addon/fold/foldcode' { + declare module.exports: any; +} + +declare module 'codemirror/addon/fold/foldgutter' { + declare module.exports: any; +} + +declare module 'codemirror/addon/fold/indent-fold' { + declare module.exports: any; +} + +declare module 'codemirror/addon/fold/markdown-fold' { + declare module.exports: any; +} + +declare module 'codemirror/addon/fold/xml-fold' { + declare module.exports: any; +} + +declare module 'codemirror/addon/hint/anyword-hint' { + declare module.exports: any; +} + +declare module 'codemirror/addon/hint/css-hint' { + declare module.exports: any; +} + +declare module 'codemirror/addon/hint/html-hint' { + declare module.exports: any; +} + +declare module 'codemirror/addon/hint/javascript-hint' { + declare module.exports: any; +} + +declare module 'codemirror/addon/hint/show-hint' { + declare module.exports: any; +} + +declare module 'codemirror/addon/hint/sql-hint' { + declare module.exports: any; +} + +declare module 'codemirror/addon/hint/xml-hint' { + declare module.exports: any; +} + +declare module 'codemirror/addon/lint/coffeescript-lint' { + declare module.exports: any; +} + +declare module 'codemirror/addon/lint/css-lint' { + declare module.exports: any; +} + +declare module 'codemirror/addon/lint/html-lint' { + declare module.exports: any; +} + +declare module 'codemirror/addon/lint/javascript-lint' { + declare module.exports: any; +} + +declare module 'codemirror/addon/lint/json-lint' { + declare module.exports: any; +} + +declare module 'codemirror/addon/lint/lint' { + declare module.exports: any; +} + +declare module 'codemirror/addon/lint/yaml-lint' { + declare module.exports: any; +} + +declare module 'codemirror/addon/merge/merge' { + declare module.exports: any; +} + +declare module 'codemirror/addon/mode/loadmode' { + declare module.exports: any; +} + +declare module 'codemirror/addon/mode/multiplex_test' { + declare module.exports: any; +} + +declare module 'codemirror/addon/mode/multiplex' { + declare module.exports: any; +} + +declare module 'codemirror/addon/mode/overlay' { + declare module.exports: any; +} + +declare module 'codemirror/addon/mode/simple' { + declare module.exports: any; +} + +declare module 'codemirror/addon/runmode/colorize' { + declare module.exports: any; +} + +declare module 'codemirror/addon/runmode/runmode-standalone' { + declare module.exports: any; +} + +declare module 'codemirror/addon/runmode/runmode' { + declare module.exports: any; +} + +declare module 'codemirror/addon/runmode/runmode.node' { + declare module.exports: any; +} + +declare module 'codemirror/addon/scroll/annotatescrollbar' { + declare module.exports: any; +} + +declare module 'codemirror/addon/scroll/scrollpastend' { + declare module.exports: any; +} + +declare module 'codemirror/addon/scroll/simplescrollbars' { + declare module.exports: any; +} + +declare module 'codemirror/addon/search/jump-to-line' { + declare module.exports: any; +} + +declare module 'codemirror/addon/search/match-highlighter' { + declare module.exports: any; +} + +declare module 'codemirror/addon/search/matchesonscrollbar' { + declare module.exports: any; +} + +declare module 'codemirror/addon/search/search' { + declare module.exports: any; +} + +declare module 'codemirror/addon/search/searchcursor' { + declare module.exports: any; +} + +declare module 'codemirror/addon/selection/active-line' { + declare module.exports: any; +} + +declare module 'codemirror/addon/selection/mark-selection' { + declare module.exports: any; +} + +declare module 'codemirror/addon/selection/selection-pointer' { + declare module.exports: any; +} + +declare module 'codemirror/addon/tern/tern' { + declare module.exports: any; +} + +declare module 'codemirror/addon/tern/worker' { + declare module.exports: any; +} + +declare module 'codemirror/addon/wrap/hardwrap' { + declare module.exports: any; +} + +declare module 'codemirror/keymap/emacs' { + declare module.exports: any; +} + +declare module 'codemirror/keymap/sublime' { + declare module.exports: any; +} + +declare module 'codemirror/keymap/vim' { + declare module.exports: any; +} + +declare module 'codemirror/lib/codemirror' { + declare module.exports: any; +} + +declare module 'codemirror/mode/apl/apl' { + declare module.exports: any; +} + +declare module 'codemirror/mode/asciiarmor/asciiarmor' { + declare module.exports: any; +} + +declare module 'codemirror/mode/asn.1/asn.1' { + declare module.exports: any; +} + +declare module 'codemirror/mode/asterisk/asterisk' { + declare module.exports: any; +} + +declare module 'codemirror/mode/brainfuck/brainfuck' { + declare module.exports: any; +} + +declare module 'codemirror/mode/clike/clike' { + declare module.exports: any; +} + +declare module 'codemirror/mode/clojure/clojure' { + declare module.exports: any; +} + +declare module 'codemirror/mode/cmake/cmake' { + declare module.exports: any; +} + +declare module 'codemirror/mode/cobol/cobol' { + declare module.exports: any; +} + +declare module 'codemirror/mode/coffeescript/coffeescript' { + declare module.exports: any; +} + +declare module 'codemirror/mode/commonlisp/commonlisp' { + declare module.exports: any; +} + +declare module 'codemirror/mode/crystal/crystal' { + declare module.exports: any; +} + +declare module 'codemirror/mode/css/css' { + declare module.exports: any; +} + +declare module 'codemirror/mode/cypher/cypher' { + declare module.exports: any; +} + +declare module 'codemirror/mode/d/d' { + declare module.exports: any; +} + +declare module 'codemirror/mode/dart/dart' { + declare module.exports: any; +} + +declare module 'codemirror/mode/diff/diff' { + declare module.exports: any; +} + +declare module 'codemirror/mode/django/django' { + declare module.exports: any; +} + +declare module 'codemirror/mode/dockerfile/dockerfile' { + declare module.exports: any; +} + +declare module 'codemirror/mode/dtd/dtd' { + declare module.exports: any; +} + +declare module 'codemirror/mode/dylan/dylan' { + declare module.exports: any; +} + +declare module 'codemirror/mode/ebnf/ebnf' { + declare module.exports: any; +} + +declare module 'codemirror/mode/ecl/ecl' { + declare module.exports: any; +} + +declare module 'codemirror/mode/eiffel/eiffel' { + declare module.exports: any; +} + +declare module 'codemirror/mode/elm/elm' { + declare module.exports: any; +} + +declare module 'codemirror/mode/erlang/erlang' { + declare module.exports: any; +} + +declare module 'codemirror/mode/factor/factor' { + declare module.exports: any; +} + +declare module 'codemirror/mode/fcl/fcl' { + declare module.exports: any; +} + +declare module 'codemirror/mode/forth/forth' { + declare module.exports: any; +} + +declare module 'codemirror/mode/fortran/fortran' { + declare module.exports: any; +} + +declare module 'codemirror/mode/gas/gas' { + declare module.exports: any; +} + +declare module 'codemirror/mode/gfm/gfm' { + declare module.exports: any; +} + +declare module 'codemirror/mode/gherkin/gherkin' { + declare module.exports: any; +} + +declare module 'codemirror/mode/go/go' { + declare module.exports: any; +} + +declare module 'codemirror/mode/groovy/groovy' { + declare module.exports: any; +} + +declare module 'codemirror/mode/haml/haml' { + declare module.exports: any; +} + +declare module 'codemirror/mode/handlebars/handlebars' { + declare module.exports: any; +} + +declare module 'codemirror/mode/haskell-literate/haskell-literate' { + declare module.exports: any; +} + +declare module 'codemirror/mode/haskell/haskell' { + declare module.exports: any; +} + +declare module 'codemirror/mode/haxe/haxe' { + declare module.exports: any; +} + +declare module 'codemirror/mode/htmlembedded/htmlembedded' { + declare module.exports: any; +} + +declare module 'codemirror/mode/htmlmixed/htmlmixed' { + declare module.exports: any; +} + +declare module 'codemirror/mode/http/http' { + declare module.exports: any; +} + +declare module 'codemirror/mode/idl/idl' { + declare module.exports: any; +} + +declare module 'codemirror/mode/javascript/javascript' { + declare module.exports: any; +} + +declare module 'codemirror/mode/jinja2/jinja2' { + declare module.exports: any; +} + +declare module 'codemirror/mode/jsx/jsx' { + declare module.exports: any; +} + +declare module 'codemirror/mode/julia/julia' { + declare module.exports: any; +} + +declare module 'codemirror/mode/livescript/livescript' { + declare module.exports: any; +} + +declare module 'codemirror/mode/lua/lua' { + declare module.exports: any; +} + +declare module 'codemirror/mode/markdown/markdown' { + declare module.exports: any; +} + +declare module 'codemirror/mode/mathematica/mathematica' { + declare module.exports: any; +} + +declare module 'codemirror/mode/mbox/mbox' { + declare module.exports: any; +} + +declare module 'codemirror/mode/meta' { + declare module.exports: any; +} + +declare module 'codemirror/mode/mirc/mirc' { + declare module.exports: any; +} + +declare module 'codemirror/mode/mllike/mllike' { + declare module.exports: any; +} + +declare module 'codemirror/mode/modelica/modelica' { + declare module.exports: any; +} + +declare module 'codemirror/mode/mscgen/mscgen' { + declare module.exports: any; +} + +declare module 'codemirror/mode/mumps/mumps' { + declare module.exports: any; +} + +declare module 'codemirror/mode/nginx/nginx' { + declare module.exports: any; +} + +declare module 'codemirror/mode/nsis/nsis' { + declare module.exports: any; +} + +declare module 'codemirror/mode/ntriples/ntriples' { + declare module.exports: any; +} + +declare module 'codemirror/mode/octave/octave' { + declare module.exports: any; +} + +declare module 'codemirror/mode/oz/oz' { + declare module.exports: any; +} + +declare module 'codemirror/mode/pascal/pascal' { + declare module.exports: any; +} + +declare module 'codemirror/mode/pegjs/pegjs' { + declare module.exports: any; +} + +declare module 'codemirror/mode/perl/perl' { + declare module.exports: any; +} + +declare module 'codemirror/mode/php/php' { + declare module.exports: any; +} + +declare module 'codemirror/mode/pig/pig' { + declare module.exports: any; +} + +declare module 'codemirror/mode/powershell/powershell' { + declare module.exports: any; +} + +declare module 'codemirror/mode/properties/properties' { + declare module.exports: any; +} + +declare module 'codemirror/mode/protobuf/protobuf' { + declare module.exports: any; +} + +declare module 'codemirror/mode/pug/pug' { + declare module.exports: any; +} + +declare module 'codemirror/mode/puppet/puppet' { + declare module.exports: any; +} + +declare module 'codemirror/mode/python/python' { + declare module.exports: any; +} + +declare module 'codemirror/mode/q/q' { + declare module.exports: any; +} + +declare module 'codemirror/mode/r/r' { + declare module.exports: any; +} + +declare module 'codemirror/mode/rpm/rpm' { + declare module.exports: any; +} + +declare module 'codemirror/mode/rst/rst' { + declare module.exports: any; +} + +declare module 'codemirror/mode/ruby/ruby' { + declare module.exports: any; +} + +declare module 'codemirror/mode/rust/rust' { + declare module.exports: any; +} + +declare module 'codemirror/mode/sas/sas' { + declare module.exports: any; +} + +declare module 'codemirror/mode/sass/sass' { + declare module.exports: any; +} + +declare module 'codemirror/mode/scheme/scheme' { + declare module.exports: any; +} + +declare module 'codemirror/mode/shell/shell' { + declare module.exports: any; +} + +declare module 'codemirror/mode/sieve/sieve' { + declare module.exports: any; +} + +declare module 'codemirror/mode/slim/slim' { + declare module.exports: any; +} + +declare module 'codemirror/mode/smalltalk/smalltalk' { + declare module.exports: any; +} + +declare module 'codemirror/mode/smarty/smarty' { + declare module.exports: any; +} + +declare module 'codemirror/mode/solr/solr' { + declare module.exports: any; +} + +declare module 'codemirror/mode/soy/soy' { + declare module.exports: any; +} + +declare module 'codemirror/mode/sparql/sparql' { + declare module.exports: any; +} + +declare module 'codemirror/mode/spreadsheet/spreadsheet' { + declare module.exports: any; +} + +declare module 'codemirror/mode/sql/sql' { + declare module.exports: any; +} + +declare module 'codemirror/mode/stex/stex' { + declare module.exports: any; +} + +declare module 'codemirror/mode/stylus/stylus' { + declare module.exports: any; +} + +declare module 'codemirror/mode/swift/swift' { + declare module.exports: any; +} + +declare module 'codemirror/mode/tcl/tcl' { + declare module.exports: any; +} + +declare module 'codemirror/mode/textile/textile' { + declare module.exports: any; +} + +declare module 'codemirror/mode/tiddlywiki/tiddlywiki' { + declare module.exports: any; +} + +declare module 'codemirror/mode/tiki/tiki' { + declare module.exports: any; +} + +declare module 'codemirror/mode/toml/toml' { + declare module.exports: any; +} + +declare module 'codemirror/mode/tornado/tornado' { + declare module.exports: any; +} + +declare module 'codemirror/mode/troff/troff' { + declare module.exports: any; +} + +declare module 'codemirror/mode/ttcn-cfg/ttcn-cfg' { + declare module.exports: any; +} + +declare module 'codemirror/mode/ttcn/ttcn' { + declare module.exports: any; +} + +declare module 'codemirror/mode/turtle/turtle' { + declare module.exports: any; +} + +declare module 'codemirror/mode/twig/twig' { + declare module.exports: any; +} + +declare module 'codemirror/mode/vb/vb' { + declare module.exports: any; +} + +declare module 'codemirror/mode/vbscript/vbscript' { + declare module.exports: any; +} + +declare module 'codemirror/mode/velocity/velocity' { + declare module.exports: any; +} + +declare module 'codemirror/mode/verilog/verilog' { + declare module.exports: any; +} + +declare module 'codemirror/mode/vhdl/vhdl' { + declare module.exports: any; +} + +declare module 'codemirror/mode/vue/vue' { + declare module.exports: any; +} + +declare module 'codemirror/mode/webidl/webidl' { + declare module.exports: any; +} + +declare module 'codemirror/mode/xml/xml' { + declare module.exports: any; +} + +declare module 'codemirror/mode/xquery/xquery' { + declare module.exports: any; +} + +declare module 'codemirror/mode/yacas/yacas' { + declare module.exports: any; +} + +declare module 'codemirror/mode/yaml-frontmatter/yaml-frontmatter' { + declare module.exports: any; +} + +declare module 'codemirror/mode/yaml/yaml' { + declare module.exports: any; +} + +declare module 'codemirror/mode/z80/z80' { + declare module.exports: any; +} + +declare module 'codemirror/rollup.config' { + declare module.exports: any; +} + +declare module 'codemirror/src/codemirror' { + declare module.exports: any; +} + +declare module 'codemirror/src/display/Display' { + declare module.exports: any; +} + +declare module 'codemirror/src/display/focus' { + declare module.exports: any; +} + +declare module 'codemirror/src/display/gutters' { + declare module.exports: any; +} + +declare module 'codemirror/src/display/highlight_worker' { + declare module.exports: any; +} + +declare module 'codemirror/src/display/line_numbers' { + declare module.exports: any; +} + +declare module 'codemirror/src/display/mode_state' { + declare module.exports: any; +} + +declare module 'codemirror/src/display/operations' { + declare module.exports: any; +} + +declare module 'codemirror/src/display/scroll_events' { + declare module.exports: any; +} + +declare module 'codemirror/src/display/scrollbars' { + declare module.exports: any; +} + +declare module 'codemirror/src/display/scrolling' { + declare module.exports: any; +} + +declare module 'codemirror/src/display/selection' { + declare module.exports: any; +} + +declare module 'codemirror/src/display/update_display' { + declare module.exports: any; +} + +declare module 'codemirror/src/display/update_line' { + declare module.exports: any; +} + +declare module 'codemirror/src/display/update_lines' { + declare module.exports: any; +} + +declare module 'codemirror/src/display/view_tracking' { + declare module.exports: any; +} + +declare module 'codemirror/src/edit/CodeMirror' { + declare module.exports: any; +} + +declare module 'codemirror/src/edit/commands' { + declare module.exports: any; +} + +declare module 'codemirror/src/edit/deleteNearSelection' { + declare module.exports: any; +} + +declare module 'codemirror/src/edit/drop_events' { + declare module.exports: any; +} + +declare module 'codemirror/src/edit/fromTextArea' { + declare module.exports: any; +} + +declare module 'codemirror/src/edit/global_events' { + declare module.exports: any; +} + +declare module 'codemirror/src/edit/key_events' { + declare module.exports: any; +} + +declare module 'codemirror/src/edit/legacy' { + declare module.exports: any; +} + +declare module 'codemirror/src/edit/main' { + declare module.exports: any; +} + +declare module 'codemirror/src/edit/methods' { + declare module.exports: any; +} + +declare module 'codemirror/src/edit/mouse_events' { + declare module.exports: any; +} + +declare module 'codemirror/src/edit/options' { + declare module.exports: any; +} + +declare module 'codemirror/src/edit/utils' { + declare module.exports: any; +} + +declare module 'codemirror/src/input/ContentEditableInput' { + declare module.exports: any; +} + +declare module 'codemirror/src/input/indent' { + declare module.exports: any; +} + +declare module 'codemirror/src/input/input' { + declare module.exports: any; +} + +declare module 'codemirror/src/input/keymap' { + declare module.exports: any; +} + +declare module 'codemirror/src/input/keynames' { + declare module.exports: any; +} + +declare module 'codemirror/src/input/movement' { + declare module.exports: any; +} + +declare module 'codemirror/src/input/TextareaInput' { + declare module.exports: any; +} + +declare module 'codemirror/src/line/highlight' { + declare module.exports: any; +} + +declare module 'codemirror/src/line/line_data' { + declare module.exports: any; +} + +declare module 'codemirror/src/line/pos' { + declare module.exports: any; +} + +declare module 'codemirror/src/line/saw_special_spans' { + declare module.exports: any; +} + +declare module 'codemirror/src/line/spans' { + declare module.exports: any; +} + +declare module 'codemirror/src/line/utils_line' { + declare module.exports: any; +} + +declare module 'codemirror/src/measurement/position_measurement' { + declare module.exports: any; +} + +declare module 'codemirror/src/measurement/widgets' { + declare module.exports: any; +} + +declare module 'codemirror/src/model/change_measurement' { + declare module.exports: any; +} + +declare module 'codemirror/src/model/changes' { + declare module.exports: any; +} + +declare module 'codemirror/src/model/chunk' { + declare module.exports: any; +} + +declare module 'codemirror/src/model/Doc' { + declare module.exports: any; +} + +declare module 'codemirror/src/model/document_data' { + declare module.exports: any; +} + +declare module 'codemirror/src/model/history' { + declare module.exports: any; +} + +declare module 'codemirror/src/model/line_widget' { + declare module.exports: any; +} + +declare module 'codemirror/src/model/mark_text' { + declare module.exports: any; +} + +declare module 'codemirror/src/model/selection_updates' { + declare module.exports: any; +} + +declare module 'codemirror/src/model/selection' { + declare module.exports: any; +} + +declare module 'codemirror/src/modes' { + declare module.exports: any; +} + +declare module 'codemirror/src/util/bidi' { + declare module.exports: any; +} + +declare module 'codemirror/src/util/browser' { + declare module.exports: any; +} + +declare module 'codemirror/src/util/dom' { + declare module.exports: any; +} + +declare module 'codemirror/src/util/event' { + declare module.exports: any; +} + +declare module 'codemirror/src/util/feature_detection' { + declare module.exports: any; +} + +declare module 'codemirror/src/util/misc' { + declare module.exports: any; +} + +declare module 'codemirror/src/util/operation_group' { + declare module.exports: any; +} + +declare module 'codemirror/src/util/StringStream' { + declare module.exports: any; +} + +// Filename aliases +declare module 'codemirror/addon/comment/comment.js' { + declare module.exports: $Exports<'codemirror/addon/comment/comment'>; +} +declare module 'codemirror/addon/comment/continuecomment.js' { + declare module.exports: $Exports<'codemirror/addon/comment/continuecomment'>; +} +declare module 'codemirror/addon/dialog/dialog.js' { + declare module.exports: $Exports<'codemirror/addon/dialog/dialog'>; +} +declare module 'codemirror/addon/display/autorefresh.js' { + declare module.exports: $Exports<'codemirror/addon/display/autorefresh'>; +} +declare module 'codemirror/addon/display/fullscreen.js' { + declare module.exports: $Exports<'codemirror/addon/display/fullscreen'>; +} +declare module 'codemirror/addon/display/panel.js' { + declare module.exports: $Exports<'codemirror/addon/display/panel'>; +} +declare module 'codemirror/addon/display/placeholder.js' { + declare module.exports: $Exports<'codemirror/addon/display/placeholder'>; +} +declare module 'codemirror/addon/display/rulers.js' { + declare module.exports: $Exports<'codemirror/addon/display/rulers'>; +} +declare module 'codemirror/addon/edit/closebrackets.js' { + declare module.exports: $Exports<'codemirror/addon/edit/closebrackets'>; +} +declare module 'codemirror/addon/edit/closetag.js' { + declare module.exports: $Exports<'codemirror/addon/edit/closetag'>; +} +declare module 'codemirror/addon/edit/continuelist.js' { + declare module.exports: $Exports<'codemirror/addon/edit/continuelist'>; +} +declare module 'codemirror/addon/edit/matchbrackets.js' { + declare module.exports: $Exports<'codemirror/addon/edit/matchbrackets'>; +} +declare module 'codemirror/addon/edit/matchtags.js' { + declare module.exports: $Exports<'codemirror/addon/edit/matchtags'>; +} +declare module 'codemirror/addon/edit/trailingspace.js' { + declare module.exports: $Exports<'codemirror/addon/edit/trailingspace'>; +} +declare module 'codemirror/addon/fold/brace-fold.js' { + declare module.exports: $Exports<'codemirror/addon/fold/brace-fold'>; +} +declare module 'codemirror/addon/fold/comment-fold.js' { + declare module.exports: $Exports<'codemirror/addon/fold/comment-fold'>; +} +declare module 'codemirror/addon/fold/foldcode.js' { + declare module.exports: $Exports<'codemirror/addon/fold/foldcode'>; +} +declare module 'codemirror/addon/fold/foldgutter.js' { + declare module.exports: $Exports<'codemirror/addon/fold/foldgutter'>; +} +declare module 'codemirror/addon/fold/indent-fold.js' { + declare module.exports: $Exports<'codemirror/addon/fold/indent-fold'>; +} +declare module 'codemirror/addon/fold/markdown-fold.js' { + declare module.exports: $Exports<'codemirror/addon/fold/markdown-fold'>; +} +declare module 'codemirror/addon/fold/xml-fold.js' { + declare module.exports: $Exports<'codemirror/addon/fold/xml-fold'>; +} +declare module 'codemirror/addon/hint/anyword-hint.js' { + declare module.exports: $Exports<'codemirror/addon/hint/anyword-hint'>; +} +declare module 'codemirror/addon/hint/css-hint.js' { + declare module.exports: $Exports<'codemirror/addon/hint/css-hint'>; +} +declare module 'codemirror/addon/hint/html-hint.js' { + declare module.exports: $Exports<'codemirror/addon/hint/html-hint'>; +} +declare module 'codemirror/addon/hint/javascript-hint.js' { + declare module.exports: $Exports<'codemirror/addon/hint/javascript-hint'>; +} +declare module 'codemirror/addon/hint/show-hint.js' { + declare module.exports: $Exports<'codemirror/addon/hint/show-hint'>; +} +declare module 'codemirror/addon/hint/sql-hint.js' { + declare module.exports: $Exports<'codemirror/addon/hint/sql-hint'>; +} +declare module 'codemirror/addon/hint/xml-hint.js' { + declare module.exports: $Exports<'codemirror/addon/hint/xml-hint'>; +} +declare module 'codemirror/addon/lint/coffeescript-lint.js' { + declare module.exports: $Exports<'codemirror/addon/lint/coffeescript-lint'>; +} +declare module 'codemirror/addon/lint/css-lint.js' { + declare module.exports: $Exports<'codemirror/addon/lint/css-lint'>; +} +declare module 'codemirror/addon/lint/html-lint.js' { + declare module.exports: $Exports<'codemirror/addon/lint/html-lint'>; +} +declare module 'codemirror/addon/lint/javascript-lint.js' { + declare module.exports: $Exports<'codemirror/addon/lint/javascript-lint'>; +} +declare module 'codemirror/addon/lint/json-lint.js' { + declare module.exports: $Exports<'codemirror/addon/lint/json-lint'>; +} +declare module 'codemirror/addon/lint/lint.js' { + declare module.exports: $Exports<'codemirror/addon/lint/lint'>; +} +declare module 'codemirror/addon/lint/yaml-lint.js' { + declare module.exports: $Exports<'codemirror/addon/lint/yaml-lint'>; +} +declare module 'codemirror/addon/merge/merge.js' { + declare module.exports: $Exports<'codemirror/addon/merge/merge'>; +} +declare module 'codemirror/addon/mode/loadmode.js' { + declare module.exports: $Exports<'codemirror/addon/mode/loadmode'>; +} +declare module 'codemirror/addon/mode/multiplex_test.js' { + declare module.exports: $Exports<'codemirror/addon/mode/multiplex_test'>; +} +declare module 'codemirror/addon/mode/multiplex.js' { + declare module.exports: $Exports<'codemirror/addon/mode/multiplex'>; +} +declare module 'codemirror/addon/mode/overlay.js' { + declare module.exports: $Exports<'codemirror/addon/mode/overlay'>; +} +declare module 'codemirror/addon/mode/simple.js' { + declare module.exports: $Exports<'codemirror/addon/mode/simple'>; +} +declare module 'codemirror/addon/runmode/colorize.js' { + declare module.exports: $Exports<'codemirror/addon/runmode/colorize'>; +} +declare module 'codemirror/addon/runmode/runmode-standalone.js' { + declare module.exports: $Exports<'codemirror/addon/runmode/runmode-standalone'>; +} +declare module 'codemirror/addon/runmode/runmode.js' { + declare module.exports: $Exports<'codemirror/addon/runmode/runmode'>; +} +declare module 'codemirror/addon/runmode/runmode.node.js' { + declare module.exports: $Exports<'codemirror/addon/runmode/runmode.node'>; +} +declare module 'codemirror/addon/scroll/annotatescrollbar.js' { + declare module.exports: $Exports<'codemirror/addon/scroll/annotatescrollbar'>; +} +declare module 'codemirror/addon/scroll/scrollpastend.js' { + declare module.exports: $Exports<'codemirror/addon/scroll/scrollpastend'>; +} +declare module 'codemirror/addon/scroll/simplescrollbars.js' { + declare module.exports: $Exports<'codemirror/addon/scroll/simplescrollbars'>; +} +declare module 'codemirror/addon/search/jump-to-line.js' { + declare module.exports: $Exports<'codemirror/addon/search/jump-to-line'>; +} +declare module 'codemirror/addon/search/match-highlighter.js' { + declare module.exports: $Exports<'codemirror/addon/search/match-highlighter'>; +} +declare module 'codemirror/addon/search/matchesonscrollbar.js' { + declare module.exports: $Exports<'codemirror/addon/search/matchesonscrollbar'>; +} +declare module 'codemirror/addon/search/search.js' { + declare module.exports: $Exports<'codemirror/addon/search/search'>; +} +declare module 'codemirror/addon/search/searchcursor.js' { + declare module.exports: $Exports<'codemirror/addon/search/searchcursor'>; +} +declare module 'codemirror/addon/selection/active-line.js' { + declare module.exports: $Exports<'codemirror/addon/selection/active-line'>; +} +declare module 'codemirror/addon/selection/mark-selection.js' { + declare module.exports: $Exports<'codemirror/addon/selection/mark-selection'>; +} +declare module 'codemirror/addon/selection/selection-pointer.js' { + declare module.exports: $Exports<'codemirror/addon/selection/selection-pointer'>; +} +declare module 'codemirror/addon/tern/tern.js' { + declare module.exports: $Exports<'codemirror/addon/tern/tern'>; +} +declare module 'codemirror/addon/tern/worker.js' { + declare module.exports: $Exports<'codemirror/addon/tern/worker'>; +} +declare module 'codemirror/addon/wrap/hardwrap.js' { + declare module.exports: $Exports<'codemirror/addon/wrap/hardwrap'>; +} +declare module 'codemirror/keymap/emacs.js' { + declare module.exports: $Exports<'codemirror/keymap/emacs'>; +} +declare module 'codemirror/keymap/sublime.js' { + declare module.exports: $Exports<'codemirror/keymap/sublime'>; +} +declare module 'codemirror/keymap/vim.js' { + declare module.exports: $Exports<'codemirror/keymap/vim'>; +} +declare module 'codemirror/lib/codemirror.js' { + declare module.exports: $Exports<'codemirror/lib/codemirror'>; +} +declare module 'codemirror/mode/apl/apl.js' { + declare module.exports: $Exports<'codemirror/mode/apl/apl'>; +} +declare module 'codemirror/mode/asciiarmor/asciiarmor.js' { + declare module.exports: $Exports<'codemirror/mode/asciiarmor/asciiarmor'>; +} +declare module 'codemirror/mode/asn.1/asn.1.js' { + declare module.exports: $Exports<'codemirror/mode/asn.1/asn.1'>; +} +declare module 'codemirror/mode/asterisk/asterisk.js' { + declare module.exports: $Exports<'codemirror/mode/asterisk/asterisk'>; +} +declare module 'codemirror/mode/brainfuck/brainfuck.js' { + declare module.exports: $Exports<'codemirror/mode/brainfuck/brainfuck'>; +} +declare module 'codemirror/mode/clike/clike.js' { + declare module.exports: $Exports<'codemirror/mode/clike/clike'>; +} +declare module 'codemirror/mode/clojure/clojure.js' { + declare module.exports: $Exports<'codemirror/mode/clojure/clojure'>; +} +declare module 'codemirror/mode/cmake/cmake.js' { + declare module.exports: $Exports<'codemirror/mode/cmake/cmake'>; +} +declare module 'codemirror/mode/cobol/cobol.js' { + declare module.exports: $Exports<'codemirror/mode/cobol/cobol'>; +} +declare module 'codemirror/mode/coffeescript/coffeescript.js' { + declare module.exports: $Exports<'codemirror/mode/coffeescript/coffeescript'>; +} +declare module 'codemirror/mode/commonlisp/commonlisp.js' { + declare module.exports: $Exports<'codemirror/mode/commonlisp/commonlisp'>; +} +declare module 'codemirror/mode/crystal/crystal.js' { + declare module.exports: $Exports<'codemirror/mode/crystal/crystal'>; +} +declare module 'codemirror/mode/css/css.js' { + declare module.exports: $Exports<'codemirror/mode/css/css'>; +} +declare module 'codemirror/mode/cypher/cypher.js' { + declare module.exports: $Exports<'codemirror/mode/cypher/cypher'>; +} +declare module 'codemirror/mode/d/d.js' { + declare module.exports: $Exports<'codemirror/mode/d/d'>; +} +declare module 'codemirror/mode/dart/dart.js' { + declare module.exports: $Exports<'codemirror/mode/dart/dart'>; +} +declare module 'codemirror/mode/diff/diff.js' { + declare module.exports: $Exports<'codemirror/mode/diff/diff'>; +} +declare module 'codemirror/mode/django/django.js' { + declare module.exports: $Exports<'codemirror/mode/django/django'>; +} +declare module 'codemirror/mode/dockerfile/dockerfile.js' { + declare module.exports: $Exports<'codemirror/mode/dockerfile/dockerfile'>; +} +declare module 'codemirror/mode/dtd/dtd.js' { + declare module.exports: $Exports<'codemirror/mode/dtd/dtd'>; +} +declare module 'codemirror/mode/dylan/dylan.js' { + declare module.exports: $Exports<'codemirror/mode/dylan/dylan'>; +} +declare module 'codemirror/mode/ebnf/ebnf.js' { + declare module.exports: $Exports<'codemirror/mode/ebnf/ebnf'>; +} +declare module 'codemirror/mode/ecl/ecl.js' { + declare module.exports: $Exports<'codemirror/mode/ecl/ecl'>; +} +declare module 'codemirror/mode/eiffel/eiffel.js' { + declare module.exports: $Exports<'codemirror/mode/eiffel/eiffel'>; +} +declare module 'codemirror/mode/elm/elm.js' { + declare module.exports: $Exports<'codemirror/mode/elm/elm'>; +} +declare module 'codemirror/mode/erlang/erlang.js' { + declare module.exports: $Exports<'codemirror/mode/erlang/erlang'>; +} +declare module 'codemirror/mode/factor/factor.js' { + declare module.exports: $Exports<'codemirror/mode/factor/factor'>; +} +declare module 'codemirror/mode/fcl/fcl.js' { + declare module.exports: $Exports<'codemirror/mode/fcl/fcl'>; +} +declare module 'codemirror/mode/forth/forth.js' { + declare module.exports: $Exports<'codemirror/mode/forth/forth'>; +} +declare module 'codemirror/mode/fortran/fortran.js' { + declare module.exports: $Exports<'codemirror/mode/fortran/fortran'>; +} +declare module 'codemirror/mode/gas/gas.js' { + declare module.exports: $Exports<'codemirror/mode/gas/gas'>; +} +declare module 'codemirror/mode/gfm/gfm.js' { + declare module.exports: $Exports<'codemirror/mode/gfm/gfm'>; +} +declare module 'codemirror/mode/gherkin/gherkin.js' { + declare module.exports: $Exports<'codemirror/mode/gherkin/gherkin'>; +} +declare module 'codemirror/mode/go/go.js' { + declare module.exports: $Exports<'codemirror/mode/go/go'>; +} +declare module 'codemirror/mode/groovy/groovy.js' { + declare module.exports: $Exports<'codemirror/mode/groovy/groovy'>; +} +declare module 'codemirror/mode/haml/haml.js' { + declare module.exports: $Exports<'codemirror/mode/haml/haml'>; +} +declare module 'codemirror/mode/handlebars/handlebars.js' { + declare module.exports: $Exports<'codemirror/mode/handlebars/handlebars'>; +} +declare module 'codemirror/mode/haskell-literate/haskell-literate.js' { + declare module.exports: $Exports<'codemirror/mode/haskell-literate/haskell-literate'>; +} +declare module 'codemirror/mode/haskell/haskell.js' { + declare module.exports: $Exports<'codemirror/mode/haskell/haskell'>; +} +declare module 'codemirror/mode/haxe/haxe.js' { + declare module.exports: $Exports<'codemirror/mode/haxe/haxe'>; +} +declare module 'codemirror/mode/htmlembedded/htmlembedded.js' { + declare module.exports: $Exports<'codemirror/mode/htmlembedded/htmlembedded'>; +} +declare module 'codemirror/mode/htmlmixed/htmlmixed.js' { + declare module.exports: $Exports<'codemirror/mode/htmlmixed/htmlmixed'>; +} +declare module 'codemirror/mode/http/http.js' { + declare module.exports: $Exports<'codemirror/mode/http/http'>; +} +declare module 'codemirror/mode/idl/idl.js' { + declare module.exports: $Exports<'codemirror/mode/idl/idl'>; +} +declare module 'codemirror/mode/javascript/javascript.js' { + declare module.exports: $Exports<'codemirror/mode/javascript/javascript'>; +} +declare module 'codemirror/mode/jinja2/jinja2.js' { + declare module.exports: $Exports<'codemirror/mode/jinja2/jinja2'>; +} +declare module 'codemirror/mode/jsx/jsx.js' { + declare module.exports: $Exports<'codemirror/mode/jsx/jsx'>; +} +declare module 'codemirror/mode/julia/julia.js' { + declare module.exports: $Exports<'codemirror/mode/julia/julia'>; +} +declare module 'codemirror/mode/livescript/livescript.js' { + declare module.exports: $Exports<'codemirror/mode/livescript/livescript'>; +} +declare module 'codemirror/mode/lua/lua.js' { + declare module.exports: $Exports<'codemirror/mode/lua/lua'>; +} +declare module 'codemirror/mode/markdown/markdown.js' { + declare module.exports: $Exports<'codemirror/mode/markdown/markdown'>; +} +declare module 'codemirror/mode/mathematica/mathematica.js' { + declare module.exports: $Exports<'codemirror/mode/mathematica/mathematica'>; +} +declare module 'codemirror/mode/mbox/mbox.js' { + declare module.exports: $Exports<'codemirror/mode/mbox/mbox'>; +} +declare module 'codemirror/mode/meta.js' { + declare module.exports: $Exports<'codemirror/mode/meta'>; +} +declare module 'codemirror/mode/mirc/mirc.js' { + declare module.exports: $Exports<'codemirror/mode/mirc/mirc'>; +} +declare module 'codemirror/mode/mllike/mllike.js' { + declare module.exports: $Exports<'codemirror/mode/mllike/mllike'>; +} +declare module 'codemirror/mode/modelica/modelica.js' { + declare module.exports: $Exports<'codemirror/mode/modelica/modelica'>; +} +declare module 'codemirror/mode/mscgen/mscgen.js' { + declare module.exports: $Exports<'codemirror/mode/mscgen/mscgen'>; +} +declare module 'codemirror/mode/mumps/mumps.js' { + declare module.exports: $Exports<'codemirror/mode/mumps/mumps'>; +} +declare module 'codemirror/mode/nginx/nginx.js' { + declare module.exports: $Exports<'codemirror/mode/nginx/nginx'>; +} +declare module 'codemirror/mode/nsis/nsis.js' { + declare module.exports: $Exports<'codemirror/mode/nsis/nsis'>; +} +declare module 'codemirror/mode/ntriples/ntriples.js' { + declare module.exports: $Exports<'codemirror/mode/ntriples/ntriples'>; +} +declare module 'codemirror/mode/octave/octave.js' { + declare module.exports: $Exports<'codemirror/mode/octave/octave'>; +} +declare module 'codemirror/mode/oz/oz.js' { + declare module.exports: $Exports<'codemirror/mode/oz/oz'>; +} +declare module 'codemirror/mode/pascal/pascal.js' { + declare module.exports: $Exports<'codemirror/mode/pascal/pascal'>; +} +declare module 'codemirror/mode/pegjs/pegjs.js' { + declare module.exports: $Exports<'codemirror/mode/pegjs/pegjs'>; +} +declare module 'codemirror/mode/perl/perl.js' { + declare module.exports: $Exports<'codemirror/mode/perl/perl'>; +} +declare module 'codemirror/mode/php/php.js' { + declare module.exports: $Exports<'codemirror/mode/php/php'>; +} +declare module 'codemirror/mode/pig/pig.js' { + declare module.exports: $Exports<'codemirror/mode/pig/pig'>; +} +declare module 'codemirror/mode/powershell/powershell.js' { + declare module.exports: $Exports<'codemirror/mode/powershell/powershell'>; +} +declare module 'codemirror/mode/properties/properties.js' { + declare module.exports: $Exports<'codemirror/mode/properties/properties'>; +} +declare module 'codemirror/mode/protobuf/protobuf.js' { + declare module.exports: $Exports<'codemirror/mode/protobuf/protobuf'>; +} +declare module 'codemirror/mode/pug/pug.js' { + declare module.exports: $Exports<'codemirror/mode/pug/pug'>; +} +declare module 'codemirror/mode/puppet/puppet.js' { + declare module.exports: $Exports<'codemirror/mode/puppet/puppet'>; +} +declare module 'codemirror/mode/python/python.js' { + declare module.exports: $Exports<'codemirror/mode/python/python'>; +} +declare module 'codemirror/mode/q/q.js' { + declare module.exports: $Exports<'codemirror/mode/q/q'>; +} +declare module 'codemirror/mode/r/r.js' { + declare module.exports: $Exports<'codemirror/mode/r/r'>; +} +declare module 'codemirror/mode/rpm/rpm.js' { + declare module.exports: $Exports<'codemirror/mode/rpm/rpm'>; +} +declare module 'codemirror/mode/rst/rst.js' { + declare module.exports: $Exports<'codemirror/mode/rst/rst'>; +} +declare module 'codemirror/mode/ruby/ruby.js' { + declare module.exports: $Exports<'codemirror/mode/ruby/ruby'>; +} +declare module 'codemirror/mode/rust/rust.js' { + declare module.exports: $Exports<'codemirror/mode/rust/rust'>; +} +declare module 'codemirror/mode/sas/sas.js' { + declare module.exports: $Exports<'codemirror/mode/sas/sas'>; +} +declare module 'codemirror/mode/sass/sass.js' { + declare module.exports: $Exports<'codemirror/mode/sass/sass'>; +} +declare module 'codemirror/mode/scheme/scheme.js' { + declare module.exports: $Exports<'codemirror/mode/scheme/scheme'>; +} +declare module 'codemirror/mode/shell/shell.js' { + declare module.exports: $Exports<'codemirror/mode/shell/shell'>; +} +declare module 'codemirror/mode/sieve/sieve.js' { + declare module.exports: $Exports<'codemirror/mode/sieve/sieve'>; +} +declare module 'codemirror/mode/slim/slim.js' { + declare module.exports: $Exports<'codemirror/mode/slim/slim'>; +} +declare module 'codemirror/mode/smalltalk/smalltalk.js' { + declare module.exports: $Exports<'codemirror/mode/smalltalk/smalltalk'>; +} +declare module 'codemirror/mode/smarty/smarty.js' { + declare module.exports: $Exports<'codemirror/mode/smarty/smarty'>; +} +declare module 'codemirror/mode/solr/solr.js' { + declare module.exports: $Exports<'codemirror/mode/solr/solr'>; +} +declare module 'codemirror/mode/soy/soy.js' { + declare module.exports: $Exports<'codemirror/mode/soy/soy'>; +} +declare module 'codemirror/mode/sparql/sparql.js' { + declare module.exports: $Exports<'codemirror/mode/sparql/sparql'>; +} +declare module 'codemirror/mode/spreadsheet/spreadsheet.js' { + declare module.exports: $Exports<'codemirror/mode/spreadsheet/spreadsheet'>; +} +declare module 'codemirror/mode/sql/sql.js' { + declare module.exports: $Exports<'codemirror/mode/sql/sql'>; +} +declare module 'codemirror/mode/stex/stex.js' { + declare module.exports: $Exports<'codemirror/mode/stex/stex'>; +} +declare module 'codemirror/mode/stylus/stylus.js' { + declare module.exports: $Exports<'codemirror/mode/stylus/stylus'>; +} +declare module 'codemirror/mode/swift/swift.js' { + declare module.exports: $Exports<'codemirror/mode/swift/swift'>; +} +declare module 'codemirror/mode/tcl/tcl.js' { + declare module.exports: $Exports<'codemirror/mode/tcl/tcl'>; +} +declare module 'codemirror/mode/textile/textile.js' { + declare module.exports: $Exports<'codemirror/mode/textile/textile'>; +} +declare module 'codemirror/mode/tiddlywiki/tiddlywiki.js' { + declare module.exports: $Exports<'codemirror/mode/tiddlywiki/tiddlywiki'>; +} +declare module 'codemirror/mode/tiki/tiki.js' { + declare module.exports: $Exports<'codemirror/mode/tiki/tiki'>; +} +declare module 'codemirror/mode/toml/toml.js' { + declare module.exports: $Exports<'codemirror/mode/toml/toml'>; +} +declare module 'codemirror/mode/tornado/tornado.js' { + declare module.exports: $Exports<'codemirror/mode/tornado/tornado'>; +} +declare module 'codemirror/mode/troff/troff.js' { + declare module.exports: $Exports<'codemirror/mode/troff/troff'>; +} +declare module 'codemirror/mode/ttcn-cfg/ttcn-cfg.js' { + declare module.exports: $Exports<'codemirror/mode/ttcn-cfg/ttcn-cfg'>; +} +declare module 'codemirror/mode/ttcn/ttcn.js' { + declare module.exports: $Exports<'codemirror/mode/ttcn/ttcn'>; +} +declare module 'codemirror/mode/turtle/turtle.js' { + declare module.exports: $Exports<'codemirror/mode/turtle/turtle'>; +} +declare module 'codemirror/mode/twig/twig.js' { + declare module.exports: $Exports<'codemirror/mode/twig/twig'>; +} +declare module 'codemirror/mode/vb/vb.js' { + declare module.exports: $Exports<'codemirror/mode/vb/vb'>; +} +declare module 'codemirror/mode/vbscript/vbscript.js' { + declare module.exports: $Exports<'codemirror/mode/vbscript/vbscript'>; +} +declare module 'codemirror/mode/velocity/velocity.js' { + declare module.exports: $Exports<'codemirror/mode/velocity/velocity'>; +} +declare module 'codemirror/mode/verilog/verilog.js' { + declare module.exports: $Exports<'codemirror/mode/verilog/verilog'>; +} +declare module 'codemirror/mode/vhdl/vhdl.js' { + declare module.exports: $Exports<'codemirror/mode/vhdl/vhdl'>; +} +declare module 'codemirror/mode/vue/vue.js' { + declare module.exports: $Exports<'codemirror/mode/vue/vue'>; +} +declare module 'codemirror/mode/webidl/webidl.js' { + declare module.exports: $Exports<'codemirror/mode/webidl/webidl'>; +} +declare module 'codemirror/mode/xml/xml.js' { + declare module.exports: $Exports<'codemirror/mode/xml/xml'>; +} +declare module 'codemirror/mode/xquery/xquery.js' { + declare module.exports: $Exports<'codemirror/mode/xquery/xquery'>; +} +declare module 'codemirror/mode/yacas/yacas.js' { + declare module.exports: $Exports<'codemirror/mode/yacas/yacas'>; +} +declare module 'codemirror/mode/yaml-frontmatter/yaml-frontmatter.js' { + declare module.exports: $Exports<'codemirror/mode/yaml-frontmatter/yaml-frontmatter'>; +} +declare module 'codemirror/mode/yaml/yaml.js' { + declare module.exports: $Exports<'codemirror/mode/yaml/yaml'>; +} +declare module 'codemirror/mode/z80/z80.js' { + declare module.exports: $Exports<'codemirror/mode/z80/z80'>; +} +declare module 'codemirror/rollup.config.js' { + declare module.exports: $Exports<'codemirror/rollup.config'>; +} +declare module 'codemirror/src/codemirror.js' { + declare module.exports: $Exports<'codemirror/src/codemirror'>; +} +declare module 'codemirror/src/display/Display.js' { + declare module.exports: $Exports<'codemirror/src/display/Display'>; +} +declare module 'codemirror/src/display/focus.js' { + declare module.exports: $Exports<'codemirror/src/display/focus'>; +} +declare module 'codemirror/src/display/gutters.js' { + declare module.exports: $Exports<'codemirror/src/display/gutters'>; +} +declare module 'codemirror/src/display/highlight_worker.js' { + declare module.exports: $Exports<'codemirror/src/display/highlight_worker'>; +} +declare module 'codemirror/src/display/line_numbers.js' { + declare module.exports: $Exports<'codemirror/src/display/line_numbers'>; +} +declare module 'codemirror/src/display/mode_state.js' { + declare module.exports: $Exports<'codemirror/src/display/mode_state'>; +} +declare module 'codemirror/src/display/operations.js' { + declare module.exports: $Exports<'codemirror/src/display/operations'>; +} +declare module 'codemirror/src/display/scroll_events.js' { + declare module.exports: $Exports<'codemirror/src/display/scroll_events'>; +} +declare module 'codemirror/src/display/scrollbars.js' { + declare module.exports: $Exports<'codemirror/src/display/scrollbars'>; +} +declare module 'codemirror/src/display/scrolling.js' { + declare module.exports: $Exports<'codemirror/src/display/scrolling'>; +} +declare module 'codemirror/src/display/selection.js' { + declare module.exports: $Exports<'codemirror/src/display/selection'>; +} +declare module 'codemirror/src/display/update_display.js' { + declare module.exports: $Exports<'codemirror/src/display/update_display'>; +} +declare module 'codemirror/src/display/update_line.js' { + declare module.exports: $Exports<'codemirror/src/display/update_line'>; +} +declare module 'codemirror/src/display/update_lines.js' { + declare module.exports: $Exports<'codemirror/src/display/update_lines'>; +} +declare module 'codemirror/src/display/view_tracking.js' { + declare module.exports: $Exports<'codemirror/src/display/view_tracking'>; +} +declare module 'codemirror/src/edit/CodeMirror.js' { + declare module.exports: $Exports<'codemirror/src/edit/CodeMirror'>; +} +declare module 'codemirror/src/edit/commands.js' { + declare module.exports: $Exports<'codemirror/src/edit/commands'>; +} +declare module 'codemirror/src/edit/deleteNearSelection.js' { + declare module.exports: $Exports<'codemirror/src/edit/deleteNearSelection'>; +} +declare module 'codemirror/src/edit/drop_events.js' { + declare module.exports: $Exports<'codemirror/src/edit/drop_events'>; +} +declare module 'codemirror/src/edit/fromTextArea.js' { + declare module.exports: $Exports<'codemirror/src/edit/fromTextArea'>; +} +declare module 'codemirror/src/edit/global_events.js' { + declare module.exports: $Exports<'codemirror/src/edit/global_events'>; +} +declare module 'codemirror/src/edit/key_events.js' { + declare module.exports: $Exports<'codemirror/src/edit/key_events'>; +} +declare module 'codemirror/src/edit/legacy.js' { + declare module.exports: $Exports<'codemirror/src/edit/legacy'>; +} +declare module 'codemirror/src/edit/main.js' { + declare module.exports: $Exports<'codemirror/src/edit/main'>; +} +declare module 'codemirror/src/edit/methods.js' { + declare module.exports: $Exports<'codemirror/src/edit/methods'>; +} +declare module 'codemirror/src/edit/mouse_events.js' { + declare module.exports: $Exports<'codemirror/src/edit/mouse_events'>; +} +declare module 'codemirror/src/edit/options.js' { + declare module.exports: $Exports<'codemirror/src/edit/options'>; +} +declare module 'codemirror/src/edit/utils.js' { + declare module.exports: $Exports<'codemirror/src/edit/utils'>; +} +declare module 'codemirror/src/input/ContentEditableInput.js' { + declare module.exports: $Exports<'codemirror/src/input/ContentEditableInput'>; +} +declare module 'codemirror/src/input/indent.js' { + declare module.exports: $Exports<'codemirror/src/input/indent'>; +} +declare module 'codemirror/src/input/input.js' { + declare module.exports: $Exports<'codemirror/src/input/input'>; +} +declare module 'codemirror/src/input/keymap.js' { + declare module.exports: $Exports<'codemirror/src/input/keymap'>; +} +declare module 'codemirror/src/input/keynames.js' { + declare module.exports: $Exports<'codemirror/src/input/keynames'>; +} +declare module 'codemirror/src/input/movement.js' { + declare module.exports: $Exports<'codemirror/src/input/movement'>; +} +declare module 'codemirror/src/input/TextareaInput.js' { + declare module.exports: $Exports<'codemirror/src/input/TextareaInput'>; +} +declare module 'codemirror/src/line/highlight.js' { + declare module.exports: $Exports<'codemirror/src/line/highlight'>; +} +declare module 'codemirror/src/line/line_data.js' { + declare module.exports: $Exports<'codemirror/src/line/line_data'>; +} +declare module 'codemirror/src/line/pos.js' { + declare module.exports: $Exports<'codemirror/src/line/pos'>; +} +declare module 'codemirror/src/line/saw_special_spans.js' { + declare module.exports: $Exports<'codemirror/src/line/saw_special_spans'>; +} +declare module 'codemirror/src/line/spans.js' { + declare module.exports: $Exports<'codemirror/src/line/spans'>; +} +declare module 'codemirror/src/line/utils_line.js' { + declare module.exports: $Exports<'codemirror/src/line/utils_line'>; +} +declare module 'codemirror/src/measurement/position_measurement.js' { + declare module.exports: $Exports<'codemirror/src/measurement/position_measurement'>; +} +declare module 'codemirror/src/measurement/widgets.js' { + declare module.exports: $Exports<'codemirror/src/measurement/widgets'>; +} +declare module 'codemirror/src/model/change_measurement.js' { + declare module.exports: $Exports<'codemirror/src/model/change_measurement'>; +} +declare module 'codemirror/src/model/changes.js' { + declare module.exports: $Exports<'codemirror/src/model/changes'>; +} +declare module 'codemirror/src/model/chunk.js' { + declare module.exports: $Exports<'codemirror/src/model/chunk'>; +} +declare module 'codemirror/src/model/Doc.js' { + declare module.exports: $Exports<'codemirror/src/model/Doc'>; +} +declare module 'codemirror/src/model/document_data.js' { + declare module.exports: $Exports<'codemirror/src/model/document_data'>; +} +declare module 'codemirror/src/model/history.js' { + declare module.exports: $Exports<'codemirror/src/model/history'>; +} +declare module 'codemirror/src/model/line_widget.js' { + declare module.exports: $Exports<'codemirror/src/model/line_widget'>; +} +declare module 'codemirror/src/model/mark_text.js' { + declare module.exports: $Exports<'codemirror/src/model/mark_text'>; +} +declare module 'codemirror/src/model/selection_updates.js' { + declare module.exports: $Exports<'codemirror/src/model/selection_updates'>; +} +declare module 'codemirror/src/model/selection.js' { + declare module.exports: $Exports<'codemirror/src/model/selection'>; +} +declare module 'codemirror/src/modes.js' { + declare module.exports: $Exports<'codemirror/src/modes'>; +} +declare module 'codemirror/src/util/bidi.js' { + declare module.exports: $Exports<'codemirror/src/util/bidi'>; +} +declare module 'codemirror/src/util/browser.js' { + declare module.exports: $Exports<'codemirror/src/util/browser'>; +} +declare module 'codemirror/src/util/dom.js' { + declare module.exports: $Exports<'codemirror/src/util/dom'>; +} +declare module 'codemirror/src/util/event.js' { + declare module.exports: $Exports<'codemirror/src/util/event'>; +} +declare module 'codemirror/src/util/feature_detection.js' { + declare module.exports: $Exports<'codemirror/src/util/feature_detection'>; +} +declare module 'codemirror/src/util/misc.js' { + declare module.exports: $Exports<'codemirror/src/util/misc'>; +} +declare module 'codemirror/src/util/operation_group.js' { + declare module.exports: $Exports<'codemirror/src/util/operation_group'>; +} +declare module 'codemirror/src/util/StringStream.js' { + declare module.exports: $Exports<'codemirror/src/util/StringStream'>; +} diff --git a/flow-typed/npm/dashify_vx.x.x.js b/flow-typed/npm/dashify_vx.x.x.js new file mode 100644 index 000000000..4222c2939 --- /dev/null +++ b/flow-typed/npm/dashify_vx.x.x.js @@ -0,0 +1,33 @@ +// flow-typed signature: b26465a763805506e2f1120d04ab58eb +// flow-typed version: <>/dashify_v^0.2.2/flow_v0.59.0 + +/** + * This is an autogenerated libdef stub for: + * + * 'dashify' + * + * Fill this stub out by replacing all the `any` types. + * + * Once filled out, we encourage you to share your work with the + * community by sending a pull request to: + * https://github.com/flowtype/flow-typed + */ + +declare module 'dashify' { + declare module.exports: any; +} + +/** + * We include stubs for each file inside this npm package in case you need to + * require those files directly. Feel free to delete any files that aren't + * needed. + */ + + +// Filename aliases +declare module 'dashify/index' { + declare module.exports: $Exports<'dashify'>; +} +declare module 'dashify/index.js' { + declare module.exports: $Exports<'dashify'>; +} diff --git a/flow-typed/npm/deep-equal_vx.x.x.js b/flow-typed/npm/deep-equal_vx.x.x.js new file mode 100644 index 000000000..970019151 --- /dev/null +++ b/flow-typed/npm/deep-equal_vx.x.x.js @@ -0,0 +1,59 @@ +// flow-typed signature: ac858859a846498c06179ada0c8b78a1 +// flow-typed version: <>/deep-equal_v^1.0.1/flow_v0.59.0 + +/** + * This is an autogenerated libdef stub for: + * + * 'deep-equal' + * + * Fill this stub out by replacing all the `any` types. + * + * Once filled out, we encourage you to share your work with the + * community by sending a pull request to: + * https://github.com/flowtype/flow-typed + */ + +declare module 'deep-equal' { + declare module.exports: any; +} + +/** + * We include stubs for each file inside this npm package in case you need to + * require those files directly. Feel free to delete any files that aren't + * needed. + */ +declare module 'deep-equal/example/cmp' { + declare module.exports: any; +} + +declare module 'deep-equal/lib/is_arguments' { + declare module.exports: any; +} + +declare module 'deep-equal/lib/keys' { + declare module.exports: any; +} + +declare module 'deep-equal/test/cmp' { + declare module.exports: any; +} + +// Filename aliases +declare module 'deep-equal/example/cmp.js' { + declare module.exports: $Exports<'deep-equal/example/cmp'>; +} +declare module 'deep-equal/index' { + declare module.exports: $Exports<'deep-equal'>; +} +declare module 'deep-equal/index.js' { + declare module.exports: $Exports<'deep-equal'>; +} +declare module 'deep-equal/lib/is_arguments.js' { + declare module.exports: $Exports<'deep-equal/lib/is_arguments'>; +} +declare module 'deep-equal/lib/keys.js' { + declare module.exports: $Exports<'deep-equal/lib/keys'>; +} +declare module 'deep-equal/test/cmp.js' { + declare module.exports: $Exports<'deep-equal/test/cmp'>; +} diff --git a/flow-typed/npm/detect-port_vx.x.x.js b/flow-typed/npm/detect-port_vx.x.x.js new file mode 100644 index 000000000..aaea225a1 --- /dev/null +++ b/flow-typed/npm/detect-port_vx.x.x.js @@ -0,0 +1,38 @@ +// flow-typed signature: ca3761607eebb8eefa0b0b2cd828537f +// flow-typed version: <>/detect-port_v^1.1.1/flow_v0.59.0 + +/** + * This is an autogenerated libdef stub for: + * + * 'detect-port' + * + * Fill this stub out by replacing all the `any` types. + * + * Once filled out, we encourage you to share your work with the + * community by sending a pull request to: + * https://github.com/flowtype/flow-typed + */ + +declare module 'detect-port' { + declare module.exports: any; +} + +/** + * We include stubs for each file inside this npm package in case you need to + * require those files directly. Feel free to delete any files that aren't + * needed. + */ +declare module 'detect-port/lib/detect-port' { + declare module.exports: any; +} + +// Filename aliases +declare module 'detect-port/index' { + declare module.exports: $Exports<'detect-port'>; +} +declare module 'detect-port/index.js' { + declare module.exports: $Exports<'detect-port'>; +} +declare module 'detect-port/lib/detect-port.js' { + declare module.exports: $Exports<'detect-port/lib/detect-port'>; +} diff --git a/flow-typed/npm/electron-builder_vx.x.x.js b/flow-typed/npm/electron-builder_vx.x.x.js new file mode 100644 index 000000000..39edd17fd --- /dev/null +++ b/flow-typed/npm/electron-builder_vx.x.x.js @@ -0,0 +1,347 @@ +// flow-typed signature: 0782c9570706be2268d543150a4f38dc +// flow-typed version: <>/electron-builder_v^16.8.3/flow_v0.59.0 + +/** + * This is an autogenerated libdef stub for: + * + * 'electron-builder' + * + * Fill this stub out by replacing all the `any` types. + * + * Once filled out, we encourage you to share your work with the + * community by sending a pull request to: + * https://github.com/flowtype/flow-typed + */ + +declare module 'electron-builder' { + declare module.exports: any; +} + +/** + * We include stubs for each file inside this npm package in case you need to + * require those files directly. Feel free to delete any files that aren't + * needed. + */ +declare module 'electron-builder/out/appInfo' { + declare module.exports: any; +} + +declare module 'electron-builder/out/asar' { + declare module.exports: any; +} + +declare module 'electron-builder/out/asarUtil' { + declare module.exports: any; +} + +declare module 'electron-builder/out/builder' { + declare module.exports: any; +} + +declare module 'electron-builder/out/cli/build-cli' { + declare module.exports: any; +} + +declare module 'electron-builder/out/cli/cliOptions' { + declare module.exports: any; +} + +declare module 'electron-builder/out/cli/create-self-signed-cert' { + declare module.exports: any; +} + +declare module 'electron-builder/out/cli/install-app-deps' { + declare module.exports: any; +} + +declare module 'electron-builder/out/cli/node-gyp-rebuild' { + declare module.exports: any; +} + +declare module 'electron-builder/out/codeSign' { + declare module.exports: any; +} + +declare module 'electron-builder/out/errorMessages' { + declare module.exports: any; +} + +declare module 'electron-builder/out/fileMatcher' { + declare module.exports: any; +} + +declare module 'electron-builder/out/fileTransformer' { + declare module.exports: any; +} + +declare module 'electron-builder/out/forge/forge-maker' { + declare module.exports: any; +} + +declare module 'electron-builder/out/index' { + declare module.exports: any; +} + +declare module 'electron-builder/out/linuxPackager' { + declare module.exports: any; +} + +declare module 'electron-builder/out/macPackager' { + declare module.exports: any; +} + +declare module 'electron-builder/out/metadata' { + declare module.exports: any; +} + +declare module 'electron-builder/out/options/linuxOptions' { + declare module.exports: any; +} + +declare module 'electron-builder/out/options/macOptions' { + declare module.exports: any; +} + +declare module 'electron-builder/out/options/winOptions' { + declare module.exports: any; +} + +declare module 'electron-builder/out/packager' { + declare module.exports: any; +} + +declare module 'electron-builder/out/packager/dirPackager' { + declare module.exports: any; +} + +declare module 'electron-builder/out/packager/mac' { + declare module.exports: any; +} + +declare module 'electron-builder/out/packagerApi' { + declare module.exports: any; +} + +declare module 'electron-builder/out/platformPackager' { + declare module.exports: any; +} + +declare module 'electron-builder/out/publish/PublishManager' { + declare module.exports: any; +} + +declare module 'electron-builder/out/readInstalled' { + declare module.exports: any; +} + +declare module 'electron-builder/out/repositoryInfo' { + declare module.exports: any; +} + +declare module 'electron-builder/out/targets/appImage' { + declare module.exports: any; +} + +declare module 'electron-builder/out/targets/appx' { + declare module.exports: any; +} + +declare module 'electron-builder/out/targets/archive' { + declare module.exports: any; +} + +declare module 'electron-builder/out/targets/ArchiveTarget' { + declare module.exports: any; +} + +declare module 'electron-builder/out/targets/dmg' { + declare module.exports: any; +} + +declare module 'electron-builder/out/targets/fpm' { + declare module.exports: any; +} + +declare module 'electron-builder/out/targets/LinuxTargetHelper' { + declare module.exports: any; +} + +declare module 'electron-builder/out/targets/nsis' { + declare module.exports: any; +} + +declare module 'electron-builder/out/targets/pkg' { + declare module.exports: any; +} + +declare module 'electron-builder/out/targets/snap' { + declare module.exports: any; +} + +declare module 'electron-builder/out/targets/targetFactory' { + declare module.exports: any; +} + +declare module 'electron-builder/out/targets/WebInstallerTarget' { + declare module.exports: any; +} + +declare module 'electron-builder/out/util/filter' { + declare module.exports: any; +} + +declare module 'electron-builder/out/util/readPackageJson' { + declare module.exports: any; +} + +declare module 'electron-builder/out/windowsCodeSign' { + declare module.exports: any; +} + +declare module 'electron-builder/out/winPackager' { + declare module.exports: any; +} + +declare module 'electron-builder/out/yarn' { + declare module.exports: any; +} + +// Filename aliases +declare module 'electron-builder/out/appInfo.js' { + declare module.exports: $Exports<'electron-builder/out/appInfo'>; +} +declare module 'electron-builder/out/asar.js' { + declare module.exports: $Exports<'electron-builder/out/asar'>; +} +declare module 'electron-builder/out/asarUtil.js' { + declare module.exports: $Exports<'electron-builder/out/asarUtil'>; +} +declare module 'electron-builder/out/builder.js' { + declare module.exports: $Exports<'electron-builder/out/builder'>; +} +declare module 'electron-builder/out/cli/build-cli.js' { + declare module.exports: $Exports<'electron-builder/out/cli/build-cli'>; +} +declare module 'electron-builder/out/cli/cliOptions.js' { + declare module.exports: $Exports<'electron-builder/out/cli/cliOptions'>; +} +declare module 'electron-builder/out/cli/create-self-signed-cert.js' { + declare module.exports: $Exports<'electron-builder/out/cli/create-self-signed-cert'>; +} +declare module 'electron-builder/out/cli/install-app-deps.js' { + declare module.exports: $Exports<'electron-builder/out/cli/install-app-deps'>; +} +declare module 'electron-builder/out/cli/node-gyp-rebuild.js' { + declare module.exports: $Exports<'electron-builder/out/cli/node-gyp-rebuild'>; +} +declare module 'electron-builder/out/codeSign.js' { + declare module.exports: $Exports<'electron-builder/out/codeSign'>; +} +declare module 'electron-builder/out/errorMessages.js' { + declare module.exports: $Exports<'electron-builder/out/errorMessages'>; +} +declare module 'electron-builder/out/fileMatcher.js' { + declare module.exports: $Exports<'electron-builder/out/fileMatcher'>; +} +declare module 'electron-builder/out/fileTransformer.js' { + declare module.exports: $Exports<'electron-builder/out/fileTransformer'>; +} +declare module 'electron-builder/out/forge/forge-maker.js' { + declare module.exports: $Exports<'electron-builder/out/forge/forge-maker'>; +} +declare module 'electron-builder/out/index.js' { + declare module.exports: $Exports<'electron-builder/out/index'>; +} +declare module 'electron-builder/out/linuxPackager.js' { + declare module.exports: $Exports<'electron-builder/out/linuxPackager'>; +} +declare module 'electron-builder/out/macPackager.js' { + declare module.exports: $Exports<'electron-builder/out/macPackager'>; +} +declare module 'electron-builder/out/metadata.js' { + declare module.exports: $Exports<'electron-builder/out/metadata'>; +} +declare module 'electron-builder/out/options/linuxOptions.js' { + declare module.exports: $Exports<'electron-builder/out/options/linuxOptions'>; +} +declare module 'electron-builder/out/options/macOptions.js' { + declare module.exports: $Exports<'electron-builder/out/options/macOptions'>; +} +declare module 'electron-builder/out/options/winOptions.js' { + declare module.exports: $Exports<'electron-builder/out/options/winOptions'>; +} +declare module 'electron-builder/out/packager.js' { + declare module.exports: $Exports<'electron-builder/out/packager'>; +} +declare module 'electron-builder/out/packager/dirPackager.js' { + declare module.exports: $Exports<'electron-builder/out/packager/dirPackager'>; +} +declare module 'electron-builder/out/packager/mac.js' { + declare module.exports: $Exports<'electron-builder/out/packager/mac'>; +} +declare module 'electron-builder/out/packagerApi.js' { + declare module.exports: $Exports<'electron-builder/out/packagerApi'>; +} +declare module 'electron-builder/out/platformPackager.js' { + declare module.exports: $Exports<'electron-builder/out/platformPackager'>; +} +declare module 'electron-builder/out/publish/PublishManager.js' { + declare module.exports: $Exports<'electron-builder/out/publish/PublishManager'>; +} +declare module 'electron-builder/out/readInstalled.js' { + declare module.exports: $Exports<'electron-builder/out/readInstalled'>; +} +declare module 'electron-builder/out/repositoryInfo.js' { + declare module.exports: $Exports<'electron-builder/out/repositoryInfo'>; +} +declare module 'electron-builder/out/targets/appImage.js' { + declare module.exports: $Exports<'electron-builder/out/targets/appImage'>; +} +declare module 'electron-builder/out/targets/appx.js' { + declare module.exports: $Exports<'electron-builder/out/targets/appx'>; +} +declare module 'electron-builder/out/targets/archive.js' { + declare module.exports: $Exports<'electron-builder/out/targets/archive'>; +} +declare module 'electron-builder/out/targets/ArchiveTarget.js' { + declare module.exports: $Exports<'electron-builder/out/targets/ArchiveTarget'>; +} +declare module 'electron-builder/out/targets/dmg.js' { + declare module.exports: $Exports<'electron-builder/out/targets/dmg'>; +} +declare module 'electron-builder/out/targets/fpm.js' { + declare module.exports: $Exports<'electron-builder/out/targets/fpm'>; +} +declare module 'electron-builder/out/targets/LinuxTargetHelper.js' { + declare module.exports: $Exports<'electron-builder/out/targets/LinuxTargetHelper'>; +} +declare module 'electron-builder/out/targets/nsis.js' { + declare module.exports: $Exports<'electron-builder/out/targets/nsis'>; +} +declare module 'electron-builder/out/targets/pkg.js' { + declare module.exports: $Exports<'electron-builder/out/targets/pkg'>; +} +declare module 'electron-builder/out/targets/snap.js' { + declare module.exports: $Exports<'electron-builder/out/targets/snap'>; +} +declare module 'electron-builder/out/targets/targetFactory.js' { + declare module.exports: $Exports<'electron-builder/out/targets/targetFactory'>; +} +declare module 'electron-builder/out/targets/WebInstallerTarget.js' { + declare module.exports: $Exports<'electron-builder/out/targets/WebInstallerTarget'>; +} +declare module 'electron-builder/out/util/filter.js' { + declare module.exports: $Exports<'electron-builder/out/util/filter'>; +} +declare module 'electron-builder/out/util/readPackageJson.js' { + declare module.exports: $Exports<'electron-builder/out/util/readPackageJson'>; +} +declare module 'electron-builder/out/windowsCodeSign.js' { + declare module.exports: $Exports<'electron-builder/out/windowsCodeSign'>; +} +declare module 'electron-builder/out/winPackager.js' { + declare module.exports: $Exports<'electron-builder/out/winPackager'>; +} +declare module 'electron-builder/out/yarn.js' { + declare module.exports: $Exports<'electron-builder/out/yarn'>; +} diff --git a/flow-typed/npm/electron-devtools-installer_vx.x.x.js b/flow-typed/npm/electron-devtools-installer_vx.x.x.js new file mode 100644 index 000000000..6bab03346 --- /dev/null +++ b/flow-typed/npm/electron-devtools-installer_vx.x.x.js @@ -0,0 +1,67 @@ +// flow-typed signature: fce58527cae3f8649ab3ffb72e58090c +// flow-typed version: <>/electron-devtools-installer_v^2.2.0/flow_v0.59.0 + +/** + * This is an autogenerated libdef stub for: + * + * 'electron-devtools-installer' + * + * Fill this stub out by replacing all the `any` types. + * + * Once filled out, we encourage you to share your work with the + * community by sending a pull request to: + * https://github.com/flowtype/flow-typed + */ + +declare module 'electron-devtools-installer' { + declare module.exports: any; +} + +/** + * We include stubs for each file inside this npm package in case you need to + * require those files directly. Feel free to delete any files that aren't + * needed. + */ +declare module 'electron-devtools-installer/dist/downloadChromeExtension' { + declare module.exports: any; +} + +declare module 'electron-devtools-installer/dist/index' { + declare module.exports: any; +} + +declare module 'electron-devtools-installer/dist/utils' { + declare module.exports: any; +} + +declare module 'electron-devtools-installer/src/downloadChromeExtension' { + declare module.exports: any; +} + +declare module 'electron-devtools-installer/src/index' { + declare module.exports: any; +} + +declare module 'electron-devtools-installer/src/utils' { + declare module.exports: any; +} + +// Filename aliases +declare module 'electron-devtools-installer/dist/downloadChromeExtension.js' { + declare module.exports: $Exports<'electron-devtools-installer/dist/downloadChromeExtension'>; +} +declare module 'electron-devtools-installer/dist/index.js' { + declare module.exports: $Exports<'electron-devtools-installer/dist/index'>; +} +declare module 'electron-devtools-installer/dist/utils.js' { + declare module.exports: $Exports<'electron-devtools-installer/dist/utils'>; +} +declare module 'electron-devtools-installer/src/downloadChromeExtension.js' { + declare module.exports: $Exports<'electron-devtools-installer/src/downloadChromeExtension'>; +} +declare module 'electron-devtools-installer/src/index.js' { + declare module.exports: $Exports<'electron-devtools-installer/src/index'>; +} +declare module 'electron-devtools-installer/src/utils.js' { + declare module.exports: $Exports<'electron-devtools-installer/src/utils'>; +} diff --git a/flow-typed/npm/electron_vx.x.x.js b/flow-typed/npm/electron_vx.x.x.js new file mode 100644 index 000000000..cbb81fb59 --- /dev/null +++ b/flow-typed/npm/electron_vx.x.x.js @@ -0,0 +1,59 @@ +// flow-typed signature: 451c88326bb7cc6aa79491d34e1c60b0 +// flow-typed version: <>/electron_v1.7.3/flow_v0.59.0 + +/** + * This is an autogenerated libdef stub for: + * + * 'electron' + * + * Fill this stub out by replacing all the `any` types. + * + * Once filled out, we encourage you to share your work with the + * community by sending a pull request to: + * https://github.com/flowtype/flow-typed + */ + +declare module 'electron' { + declare module.exports: any; +} + +/** + * We include stubs for each file inside this npm package in case you need to + * require those files directly. Feel free to delete any files that aren't + * needed. + */ +declare module 'electron/cli' { + declare module.exports: any; +} + +declare module 'electron/install' { + declare module.exports: any; +} + +declare module 'electron/test/errors' { + declare module.exports: any; +} + +declare module 'electron/test/index' { + declare module.exports: any; +} + +// Filename aliases +declare module 'electron/cli.js' { + declare module.exports: $Exports<'electron/cli'>; +} +declare module 'electron/index' { + declare module.exports: $Exports<'electron'>; +} +declare module 'electron/index.js' { + declare module.exports: $Exports<'electron'>; +} +declare module 'electron/install.js' { + declare module.exports: $Exports<'electron/install'>; +} +declare module 'electron/test/errors.js' { + declare module.exports: $Exports<'electron/test/errors'>; +} +declare module 'electron/test/index.js' { + declare module.exports: $Exports<'electron/test/index'>; +} diff --git a/flow-typed/npm/eslint-config-react-app_vx.x.x.js b/flow-typed/npm/eslint-config-react-app_vx.x.x.js new file mode 100644 index 000000000..10d3abccf --- /dev/null +++ b/flow-typed/npm/eslint-config-react-app_vx.x.x.js @@ -0,0 +1,33 @@ +// flow-typed signature: 44d1e6a2fb005812ddc1cec21c490caf +// flow-typed version: <>/eslint-config-react-app_v^0.6.2/flow_v0.59.0 + +/** + * This is an autogenerated libdef stub for: + * + * 'eslint-config-react-app' + * + * Fill this stub out by replacing all the `any` types. + * + * Once filled out, we encourage you to share your work with the + * community by sending a pull request to: + * https://github.com/flowtype/flow-typed + */ + +declare module 'eslint-config-react-app' { + declare module.exports: any; +} + +/** + * We include stubs for each file inside this npm package in case you need to + * require those files directly. Feel free to delete any files that aren't + * needed. + */ + + +// Filename aliases +declare module 'eslint-config-react-app/index' { + declare module.exports: $Exports<'eslint-config-react-app'>; +} +declare module 'eslint-config-react-app/index.js' { + declare module.exports: $Exports<'eslint-config-react-app'>; +} diff --git a/flow-typed/npm/eslint-plugin-flowtype_vx.x.x.js b/flow-typed/npm/eslint-plugin-flowtype_vx.x.x.js new file mode 100644 index 000000000..f58acf6ce --- /dev/null +++ b/flow-typed/npm/eslint-plugin-flowtype_vx.x.x.js @@ -0,0 +1,340 @@ +// flow-typed signature: 01f86fa0dc19e1126195f0bded4a75de +// flow-typed version: <>/eslint-plugin-flowtype_v^2.30.4/flow_v0.59.0 + +/** + * This is an autogenerated libdef stub for: + * + * 'eslint-plugin-flowtype' + * + * Fill this stub out by replacing all the `any` types. + * + * Once filled out, we encourage you to share your work with the + * community by sending a pull request to: + * https://github.com/flowtype/flow-typed + */ + +declare module 'eslint-plugin-flowtype' { + declare module.exports: any; +} + +/** + * We include stubs for each file inside this npm package in case you need to + * require those files directly. Feel free to delete any files that aren't + * needed. + */ +declare module 'eslint-plugin-flowtype/bin/readmeAssertions' { + declare module.exports: any; +} + +declare module 'eslint-plugin-flowtype/dist/index' { + declare module.exports: any; +} + +declare module 'eslint-plugin-flowtype/dist/rules/booleanStyle' { + declare module.exports: any; +} + +declare module 'eslint-plugin-flowtype/dist/rules/defineFlowType' { + declare module.exports: any; +} + +declare module 'eslint-plugin-flowtype/dist/rules/delimiterDangle' { + declare module.exports: any; +} + +declare module 'eslint-plugin-flowtype/dist/rules/genericSpacing' { + declare module.exports: any; +} + +declare module 'eslint-plugin-flowtype/dist/rules/noDupeKeys' { + declare module.exports: any; +} + +declare module 'eslint-plugin-flowtype/dist/rules/noMutableArray' { + declare module.exports: any; +} + +declare module 'eslint-plugin-flowtype/dist/rules/noPrimitiveConstructorTypes' { + declare module.exports: any; +} + +declare module 'eslint-plugin-flowtype/dist/rules/noTypesMissingFileAnnotation' { + declare module.exports: any; +} + +declare module 'eslint-plugin-flowtype/dist/rules/noUnusedExpressions' { + declare module.exports: any; +} + +declare module 'eslint-plugin-flowtype/dist/rules/noWeakTypes' { + declare module.exports: any; +} + +declare module 'eslint-plugin-flowtype/dist/rules/objectTypeDelimiter' { + declare module.exports: any; +} + +declare module 'eslint-plugin-flowtype/dist/rules/requireParameterType' { + declare module.exports: any; +} + +declare module 'eslint-plugin-flowtype/dist/rules/requireReturnType' { + declare module.exports: any; +} + +declare module 'eslint-plugin-flowtype/dist/rules/requireValidFileAnnotation' { + declare module.exports: any; +} + +declare module 'eslint-plugin-flowtype/dist/rules/requireVariableType' { + declare module.exports: any; +} + +declare module 'eslint-plugin-flowtype/dist/rules/semi' { + declare module.exports: any; +} + +declare module 'eslint-plugin-flowtype/dist/rules/sortKeys' { + declare module.exports: any; +} + +declare module 'eslint-plugin-flowtype/dist/rules/spaceAfterTypeColon' { + declare module.exports: any; +} + +declare module 'eslint-plugin-flowtype/dist/rules/spaceBeforeGenericBracket' { + declare module.exports: any; +} + +declare module 'eslint-plugin-flowtype/dist/rules/spaceBeforeTypeColon' { + declare module.exports: any; +} + +declare module 'eslint-plugin-flowtype/dist/rules/typeColonSpacing/evaluateFunctions' { + declare module.exports: any; +} + +declare module 'eslint-plugin-flowtype/dist/rules/typeColonSpacing/evaluateObjectTypeIndexer' { + declare module.exports: any; +} + +declare module 'eslint-plugin-flowtype/dist/rules/typeColonSpacing/evaluateObjectTypeProperty' { + declare module.exports: any; +} + +declare module 'eslint-plugin-flowtype/dist/rules/typeColonSpacing/evaluateReturnType' { + declare module.exports: any; +} + +declare module 'eslint-plugin-flowtype/dist/rules/typeColonSpacing/evaluateTypeCastExpression' { + declare module.exports: any; +} + +declare module 'eslint-plugin-flowtype/dist/rules/typeColonSpacing/evaluateTypical' { + declare module.exports: any; +} + +declare module 'eslint-plugin-flowtype/dist/rules/typeColonSpacing/index' { + declare module.exports: any; +} + +declare module 'eslint-plugin-flowtype/dist/rules/typeColonSpacing/reporter' { + declare module.exports: any; +} + +declare module 'eslint-plugin-flowtype/dist/rules/typeIdMatch' { + declare module.exports: any; +} + +declare module 'eslint-plugin-flowtype/dist/rules/unionIntersectionSpacing' { + declare module.exports: any; +} + +declare module 'eslint-plugin-flowtype/dist/rules/useFlowType' { + declare module.exports: any; +} + +declare module 'eslint-plugin-flowtype/dist/rules/validSyntax' { + declare module.exports: any; +} + +declare module 'eslint-plugin-flowtype/dist/utilities/checkFlowFileAnnotation' { + declare module.exports: any; +} + +declare module 'eslint-plugin-flowtype/dist/utilities/fuzzyStringMatch' { + declare module.exports: any; +} + +declare module 'eslint-plugin-flowtype/dist/utilities/getParameterName' { + declare module.exports: any; +} + +declare module 'eslint-plugin-flowtype/dist/utilities/getTokenAfterParens' { + declare module.exports: any; +} + +declare module 'eslint-plugin-flowtype/dist/utilities/getTokenBeforeParens' { + declare module.exports: any; +} + +declare module 'eslint-plugin-flowtype/dist/utilities/index' { + declare module.exports: any; +} + +declare module 'eslint-plugin-flowtype/dist/utilities/isFlowFile' { + declare module.exports: any; +} + +declare module 'eslint-plugin-flowtype/dist/utilities/isFlowFileAnnotation' { + declare module.exports: any; +} + +declare module 'eslint-plugin-flowtype/dist/utilities/iterateFunctionNodes' { + declare module.exports: any; +} + +declare module 'eslint-plugin-flowtype/dist/utilities/quoteName' { + declare module.exports: any; +} + +declare module 'eslint-plugin-flowtype/dist/utilities/spacingFixers' { + declare module.exports: any; +} + +// Filename aliases +declare module 'eslint-plugin-flowtype/bin/readmeAssertions.js' { + declare module.exports: $Exports<'eslint-plugin-flowtype/bin/readmeAssertions'>; +} +declare module 'eslint-plugin-flowtype/dist/index.js' { + declare module.exports: $Exports<'eslint-plugin-flowtype/dist/index'>; +} +declare module 'eslint-plugin-flowtype/dist/rules/booleanStyle.js' { + declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/booleanStyle'>; +} +declare module 'eslint-plugin-flowtype/dist/rules/defineFlowType.js' { + declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/defineFlowType'>; +} +declare module 'eslint-plugin-flowtype/dist/rules/delimiterDangle.js' { + declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/delimiterDangle'>; +} +declare module 'eslint-plugin-flowtype/dist/rules/genericSpacing.js' { + declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/genericSpacing'>; +} +declare module 'eslint-plugin-flowtype/dist/rules/noDupeKeys.js' { + declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/noDupeKeys'>; +} +declare module 'eslint-plugin-flowtype/dist/rules/noMutableArray.js' { + declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/noMutableArray'>; +} +declare module 'eslint-plugin-flowtype/dist/rules/noPrimitiveConstructorTypes.js' { + declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/noPrimitiveConstructorTypes'>; +} +declare module 'eslint-plugin-flowtype/dist/rules/noTypesMissingFileAnnotation.js' { + declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/noTypesMissingFileAnnotation'>; +} +declare module 'eslint-plugin-flowtype/dist/rules/noUnusedExpressions.js' { + declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/noUnusedExpressions'>; +} +declare module 'eslint-plugin-flowtype/dist/rules/noWeakTypes.js' { + declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/noWeakTypes'>; +} +declare module 'eslint-plugin-flowtype/dist/rules/objectTypeDelimiter.js' { + declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/objectTypeDelimiter'>; +} +declare module 'eslint-plugin-flowtype/dist/rules/requireParameterType.js' { + declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/requireParameterType'>; +} +declare module 'eslint-plugin-flowtype/dist/rules/requireReturnType.js' { + declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/requireReturnType'>; +} +declare module 'eslint-plugin-flowtype/dist/rules/requireValidFileAnnotation.js' { + declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/requireValidFileAnnotation'>; +} +declare module 'eslint-plugin-flowtype/dist/rules/requireVariableType.js' { + declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/requireVariableType'>; +} +declare module 'eslint-plugin-flowtype/dist/rules/semi.js' { + declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/semi'>; +} +declare module 'eslint-plugin-flowtype/dist/rules/sortKeys.js' { + declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/sortKeys'>; +} +declare module 'eslint-plugin-flowtype/dist/rules/spaceAfterTypeColon.js' { + declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/spaceAfterTypeColon'>; +} +declare module 'eslint-plugin-flowtype/dist/rules/spaceBeforeGenericBracket.js' { + declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/spaceBeforeGenericBracket'>; +} +declare module 'eslint-plugin-flowtype/dist/rules/spaceBeforeTypeColon.js' { + declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/spaceBeforeTypeColon'>; +} +declare module 'eslint-plugin-flowtype/dist/rules/typeColonSpacing/evaluateFunctions.js' { + declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/typeColonSpacing/evaluateFunctions'>; +} +declare module 'eslint-plugin-flowtype/dist/rules/typeColonSpacing/evaluateObjectTypeIndexer.js' { + declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/typeColonSpacing/evaluateObjectTypeIndexer'>; +} +declare module 'eslint-plugin-flowtype/dist/rules/typeColonSpacing/evaluateObjectTypeProperty.js' { + declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/typeColonSpacing/evaluateObjectTypeProperty'>; +} +declare module 'eslint-plugin-flowtype/dist/rules/typeColonSpacing/evaluateReturnType.js' { + declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/typeColonSpacing/evaluateReturnType'>; +} +declare module 'eslint-plugin-flowtype/dist/rules/typeColonSpacing/evaluateTypeCastExpression.js' { + declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/typeColonSpacing/evaluateTypeCastExpression'>; +} +declare module 'eslint-plugin-flowtype/dist/rules/typeColonSpacing/evaluateTypical.js' { + declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/typeColonSpacing/evaluateTypical'>; +} +declare module 'eslint-plugin-flowtype/dist/rules/typeColonSpacing/index.js' { + declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/typeColonSpacing/index'>; +} +declare module 'eslint-plugin-flowtype/dist/rules/typeColonSpacing/reporter.js' { + declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/typeColonSpacing/reporter'>; +} +declare module 'eslint-plugin-flowtype/dist/rules/typeIdMatch.js' { + declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/typeIdMatch'>; +} +declare module 'eslint-plugin-flowtype/dist/rules/unionIntersectionSpacing.js' { + declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/unionIntersectionSpacing'>; +} +declare module 'eslint-plugin-flowtype/dist/rules/useFlowType.js' { + declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/useFlowType'>; +} +declare module 'eslint-plugin-flowtype/dist/rules/validSyntax.js' { + declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/validSyntax'>; +} +declare module 'eslint-plugin-flowtype/dist/utilities/checkFlowFileAnnotation.js' { + declare module.exports: $Exports<'eslint-plugin-flowtype/dist/utilities/checkFlowFileAnnotation'>; +} +declare module 'eslint-plugin-flowtype/dist/utilities/fuzzyStringMatch.js' { + declare module.exports: $Exports<'eslint-plugin-flowtype/dist/utilities/fuzzyStringMatch'>; +} +declare module 'eslint-plugin-flowtype/dist/utilities/getParameterName.js' { + declare module.exports: $Exports<'eslint-plugin-flowtype/dist/utilities/getParameterName'>; +} +declare module 'eslint-plugin-flowtype/dist/utilities/getTokenAfterParens.js' { + declare module.exports: $Exports<'eslint-plugin-flowtype/dist/utilities/getTokenAfterParens'>; +} +declare module 'eslint-plugin-flowtype/dist/utilities/getTokenBeforeParens.js' { + declare module.exports: $Exports<'eslint-plugin-flowtype/dist/utilities/getTokenBeforeParens'>; +} +declare module 'eslint-plugin-flowtype/dist/utilities/index.js' { + declare module.exports: $Exports<'eslint-plugin-flowtype/dist/utilities/index'>; +} +declare module 'eslint-plugin-flowtype/dist/utilities/isFlowFile.js' { + declare module.exports: $Exports<'eslint-plugin-flowtype/dist/utilities/isFlowFile'>; +} +declare module 'eslint-plugin-flowtype/dist/utilities/isFlowFileAnnotation.js' { + declare module.exports: $Exports<'eslint-plugin-flowtype/dist/utilities/isFlowFileAnnotation'>; +} +declare module 'eslint-plugin-flowtype/dist/utilities/iterateFunctionNodes.js' { + declare module.exports: $Exports<'eslint-plugin-flowtype/dist/utilities/iterateFunctionNodes'>; +} +declare module 'eslint-plugin-flowtype/dist/utilities/quoteName.js' { + declare module.exports: $Exports<'eslint-plugin-flowtype/dist/utilities/quoteName'>; +} +declare module 'eslint-plugin-flowtype/dist/utilities/spacingFixers.js' { + declare module.exports: $Exports<'eslint-plugin-flowtype/dist/utilities/spacingFixers'>; +} diff --git a/flow-typed/npm/eslint-plugin-import_vx.x.x.js b/flow-typed/npm/eslint-plugin-import_vx.x.x.js new file mode 100644 index 000000000..328442c4f --- /dev/null +++ b/flow-typed/npm/eslint-plugin-import_vx.x.x.js @@ -0,0 +1,340 @@ +// flow-typed signature: e6182e793944459234f882bb47d2ba01 +// flow-typed version: <>/eslint-plugin-import_v^2.2.0/flow_v0.59.0 + +/** + * This is an autogenerated libdef stub for: + * + * 'eslint-plugin-import' + * + * Fill this stub out by replacing all the `any` types. + * + * Once filled out, we encourage you to share your work with the + * community by sending a pull request to: + * https://github.com/flowtype/flow-typed + */ + +declare module 'eslint-plugin-import' { + declare module.exports: any; +} + +/** + * We include stubs for each file inside this npm package in case you need to + * require those files directly. Feel free to delete any files that aren't + * needed. + */ +declare module 'eslint-plugin-import/config/electron' { + declare module.exports: any; +} + +declare module 'eslint-plugin-import/config/errors' { + declare module.exports: any; +} + +declare module 'eslint-plugin-import/config/react-native' { + declare module.exports: any; +} + +declare module 'eslint-plugin-import/config/react' { + declare module.exports: any; +} + +declare module 'eslint-plugin-import/config/recommended' { + declare module.exports: any; +} + +declare module 'eslint-plugin-import/config/stage-0' { + declare module.exports: any; +} + +declare module 'eslint-plugin-import/config/warnings' { + declare module.exports: any; +} + +declare module 'eslint-plugin-import/lib/core/importType' { + declare module.exports: any; +} + +declare module 'eslint-plugin-import/lib/core/staticRequire' { + declare module.exports: any; +} + +declare module 'eslint-plugin-import/lib/ExportMap' { + declare module.exports: any; +} + +declare module 'eslint-plugin-import/lib/importDeclaration' { + declare module.exports: any; +} + +declare module 'eslint-plugin-import/lib/index' { + declare module.exports: any; +} + +declare module 'eslint-plugin-import/lib/rules/default' { + declare module.exports: any; +} + +declare module 'eslint-plugin-import/lib/rules/export' { + declare module.exports: any; +} + +declare module 'eslint-plugin-import/lib/rules/exports-last' { + declare module.exports: any; +} + +declare module 'eslint-plugin-import/lib/rules/extensions' { + declare module.exports: any; +} + +declare module 'eslint-plugin-import/lib/rules/first' { + declare module.exports: any; +} + +declare module 'eslint-plugin-import/lib/rules/imports-first' { + declare module.exports: any; +} + +declare module 'eslint-plugin-import/lib/rules/max-dependencies' { + declare module.exports: any; +} + +declare module 'eslint-plugin-import/lib/rules/named' { + declare module.exports: any; +} + +declare module 'eslint-plugin-import/lib/rules/namespace' { + declare module.exports: any; +} + +declare module 'eslint-plugin-import/lib/rules/newline-after-import' { + declare module.exports: any; +} + +declare module 'eslint-plugin-import/lib/rules/no-absolute-path' { + declare module.exports: any; +} + +declare module 'eslint-plugin-import/lib/rules/no-amd' { + declare module.exports: any; +} + +declare module 'eslint-plugin-import/lib/rules/no-anonymous-default-export' { + declare module.exports: any; +} + +declare module 'eslint-plugin-import/lib/rules/no-commonjs' { + declare module.exports: any; +} + +declare module 'eslint-plugin-import/lib/rules/no-deprecated' { + declare module.exports: any; +} + +declare module 'eslint-plugin-import/lib/rules/no-duplicates' { + declare module.exports: any; +} + +declare module 'eslint-plugin-import/lib/rules/no-dynamic-require' { + declare module.exports: any; +} + +declare module 'eslint-plugin-import/lib/rules/no-extraneous-dependencies' { + declare module.exports: any; +} + +declare module 'eslint-plugin-import/lib/rules/no-internal-modules' { + declare module.exports: any; +} + +declare module 'eslint-plugin-import/lib/rules/no-mutable-exports' { + declare module.exports: any; +} + +declare module 'eslint-plugin-import/lib/rules/no-named-as-default-member' { + declare module.exports: any; +} + +declare module 'eslint-plugin-import/lib/rules/no-named-as-default' { + declare module.exports: any; +} + +declare module 'eslint-plugin-import/lib/rules/no-named-default' { + declare module.exports: any; +} + +declare module 'eslint-plugin-import/lib/rules/no-namespace' { + declare module.exports: any; +} + +declare module 'eslint-plugin-import/lib/rules/no-nodejs-modules' { + declare module.exports: any; +} + +declare module 'eslint-plugin-import/lib/rules/no-restricted-paths' { + declare module.exports: any; +} + +declare module 'eslint-plugin-import/lib/rules/no-unassigned-import' { + declare module.exports: any; +} + +declare module 'eslint-plugin-import/lib/rules/no-unresolved' { + declare module.exports: any; +} + +declare module 'eslint-plugin-import/lib/rules/no-webpack-loader-syntax' { + declare module.exports: any; +} + +declare module 'eslint-plugin-import/lib/rules/order' { + declare module.exports: any; +} + +declare module 'eslint-plugin-import/lib/rules/prefer-default-export' { + declare module.exports: any; +} + +declare module 'eslint-plugin-import/lib/rules/unambiguous' { + declare module.exports: any; +} + +declare module 'eslint-plugin-import/memo-parser/index' { + declare module.exports: any; +} + +// Filename aliases +declare module 'eslint-plugin-import/config/electron.js' { + declare module.exports: $Exports<'eslint-plugin-import/config/electron'>; +} +declare module 'eslint-plugin-import/config/errors.js' { + declare module.exports: $Exports<'eslint-plugin-import/config/errors'>; +} +declare module 'eslint-plugin-import/config/react-native.js' { + declare module.exports: $Exports<'eslint-plugin-import/config/react-native'>; +} +declare module 'eslint-plugin-import/config/react.js' { + declare module.exports: $Exports<'eslint-plugin-import/config/react'>; +} +declare module 'eslint-plugin-import/config/recommended.js' { + declare module.exports: $Exports<'eslint-plugin-import/config/recommended'>; +} +declare module 'eslint-plugin-import/config/stage-0.js' { + declare module.exports: $Exports<'eslint-plugin-import/config/stage-0'>; +} +declare module 'eslint-plugin-import/config/warnings.js' { + declare module.exports: $Exports<'eslint-plugin-import/config/warnings'>; +} +declare module 'eslint-plugin-import/lib/core/importType.js' { + declare module.exports: $Exports<'eslint-plugin-import/lib/core/importType'>; +} +declare module 'eslint-plugin-import/lib/core/staticRequire.js' { + declare module.exports: $Exports<'eslint-plugin-import/lib/core/staticRequire'>; +} +declare module 'eslint-plugin-import/lib/ExportMap.js' { + declare module.exports: $Exports<'eslint-plugin-import/lib/ExportMap'>; +} +declare module 'eslint-plugin-import/lib/importDeclaration.js' { + declare module.exports: $Exports<'eslint-plugin-import/lib/importDeclaration'>; +} +declare module 'eslint-plugin-import/lib/index.js' { + declare module.exports: $Exports<'eslint-plugin-import/lib/index'>; +} +declare module 'eslint-plugin-import/lib/rules/default.js' { + declare module.exports: $Exports<'eslint-plugin-import/lib/rules/default'>; +} +declare module 'eslint-plugin-import/lib/rules/export.js' { + declare module.exports: $Exports<'eslint-plugin-import/lib/rules/export'>; +} +declare module 'eslint-plugin-import/lib/rules/exports-last.js' { + declare module.exports: $Exports<'eslint-plugin-import/lib/rules/exports-last'>; +} +declare module 'eslint-plugin-import/lib/rules/extensions.js' { + declare module.exports: $Exports<'eslint-plugin-import/lib/rules/extensions'>; +} +declare module 'eslint-plugin-import/lib/rules/first.js' { + declare module.exports: $Exports<'eslint-plugin-import/lib/rules/first'>; +} +declare module 'eslint-plugin-import/lib/rules/imports-first.js' { + declare module.exports: $Exports<'eslint-plugin-import/lib/rules/imports-first'>; +} +declare module 'eslint-plugin-import/lib/rules/max-dependencies.js' { + declare module.exports: $Exports<'eslint-plugin-import/lib/rules/max-dependencies'>; +} +declare module 'eslint-plugin-import/lib/rules/named.js' { + declare module.exports: $Exports<'eslint-plugin-import/lib/rules/named'>; +} +declare module 'eslint-plugin-import/lib/rules/namespace.js' { + declare module.exports: $Exports<'eslint-plugin-import/lib/rules/namespace'>; +} +declare module 'eslint-plugin-import/lib/rules/newline-after-import.js' { + declare module.exports: $Exports<'eslint-plugin-import/lib/rules/newline-after-import'>; +} +declare module 'eslint-plugin-import/lib/rules/no-absolute-path.js' { + declare module.exports: $Exports<'eslint-plugin-import/lib/rules/no-absolute-path'>; +} +declare module 'eslint-plugin-import/lib/rules/no-amd.js' { + declare module.exports: $Exports<'eslint-plugin-import/lib/rules/no-amd'>; +} +declare module 'eslint-plugin-import/lib/rules/no-anonymous-default-export.js' { + declare module.exports: $Exports<'eslint-plugin-import/lib/rules/no-anonymous-default-export'>; +} +declare module 'eslint-plugin-import/lib/rules/no-commonjs.js' { + declare module.exports: $Exports<'eslint-plugin-import/lib/rules/no-commonjs'>; +} +declare module 'eslint-plugin-import/lib/rules/no-deprecated.js' { + declare module.exports: $Exports<'eslint-plugin-import/lib/rules/no-deprecated'>; +} +declare module 'eslint-plugin-import/lib/rules/no-duplicates.js' { + declare module.exports: $Exports<'eslint-plugin-import/lib/rules/no-duplicates'>; +} +declare module 'eslint-plugin-import/lib/rules/no-dynamic-require.js' { + declare module.exports: $Exports<'eslint-plugin-import/lib/rules/no-dynamic-require'>; +} +declare module 'eslint-plugin-import/lib/rules/no-extraneous-dependencies.js' { + declare module.exports: $Exports<'eslint-plugin-import/lib/rules/no-extraneous-dependencies'>; +} +declare module 'eslint-plugin-import/lib/rules/no-internal-modules.js' { + declare module.exports: $Exports<'eslint-plugin-import/lib/rules/no-internal-modules'>; +} +declare module 'eslint-plugin-import/lib/rules/no-mutable-exports.js' { + declare module.exports: $Exports<'eslint-plugin-import/lib/rules/no-mutable-exports'>; +} +declare module 'eslint-plugin-import/lib/rules/no-named-as-default-member.js' { + declare module.exports: $Exports<'eslint-plugin-import/lib/rules/no-named-as-default-member'>; +} +declare module 'eslint-plugin-import/lib/rules/no-named-as-default.js' { + declare module.exports: $Exports<'eslint-plugin-import/lib/rules/no-named-as-default'>; +} +declare module 'eslint-plugin-import/lib/rules/no-named-default.js' { + declare module.exports: $Exports<'eslint-plugin-import/lib/rules/no-named-default'>; +} +declare module 'eslint-plugin-import/lib/rules/no-namespace.js' { + declare module.exports: $Exports<'eslint-plugin-import/lib/rules/no-namespace'>; +} +declare module 'eslint-plugin-import/lib/rules/no-nodejs-modules.js' { + declare module.exports: $Exports<'eslint-plugin-import/lib/rules/no-nodejs-modules'>; +} +declare module 'eslint-plugin-import/lib/rules/no-restricted-paths.js' { + declare module.exports: $Exports<'eslint-plugin-import/lib/rules/no-restricted-paths'>; +} +declare module 'eslint-plugin-import/lib/rules/no-unassigned-import.js' { + declare module.exports: $Exports<'eslint-plugin-import/lib/rules/no-unassigned-import'>; +} +declare module 'eslint-plugin-import/lib/rules/no-unresolved.js' { + declare module.exports: $Exports<'eslint-plugin-import/lib/rules/no-unresolved'>; +} +declare module 'eslint-plugin-import/lib/rules/no-webpack-loader-syntax.js' { + declare module.exports: $Exports<'eslint-plugin-import/lib/rules/no-webpack-loader-syntax'>; +} +declare module 'eslint-plugin-import/lib/rules/order.js' { + declare module.exports: $Exports<'eslint-plugin-import/lib/rules/order'>; +} +declare module 'eslint-plugin-import/lib/rules/prefer-default-export.js' { + declare module.exports: $Exports<'eslint-plugin-import/lib/rules/prefer-default-export'>; +} +declare module 'eslint-plugin-import/lib/rules/unambiguous.js' { + declare module.exports: $Exports<'eslint-plugin-import/lib/rules/unambiguous'>; +} +declare module 'eslint-plugin-import/memo-parser/index.js' { + declare module.exports: $Exports<'eslint-plugin-import/memo-parser/index'>; +} diff --git a/flow-typed/npm/eslint-plugin-jest_vx.x.x.js b/flow-typed/npm/eslint-plugin-jest_vx.x.x.js new file mode 100644 index 000000000..691b5fc55 --- /dev/null +++ b/flow-typed/npm/eslint-plugin-jest_vx.x.x.js @@ -0,0 +1,67 @@ +// flow-typed signature: 8a40d0f5dc4e849acdc08684ab7c532f +// flow-typed version: <>/eslint-plugin-jest_v^20.0.1/flow_v0.59.0 + +/** + * This is an autogenerated libdef stub for: + * + * 'eslint-plugin-jest' + * + * Fill this stub out by replacing all the `any` types. + * + * Once filled out, we encourage you to share your work with the + * community by sending a pull request to: + * https://github.com/flowtype/flow-typed + */ + +declare module 'eslint-plugin-jest' { + declare module.exports: any; +} + +/** + * We include stubs for each file inside this npm package in case you need to + * require those files directly. Feel free to delete any files that aren't + * needed. + */ +declare module 'eslint-plugin-jest/build/index' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jest/build/rules/no-disabled-tests' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jest/build/rules/no-focused-tests' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jest/build/rules/no-identical-title' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jest/build/rules/types' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jest/build/rules/valid-expect' { + declare module.exports: any; +} + +// Filename aliases +declare module 'eslint-plugin-jest/build/index.js' { + declare module.exports: $Exports<'eslint-plugin-jest/build/index'>; +} +declare module 'eslint-plugin-jest/build/rules/no-disabled-tests.js' { + declare module.exports: $Exports<'eslint-plugin-jest/build/rules/no-disabled-tests'>; +} +declare module 'eslint-plugin-jest/build/rules/no-focused-tests.js' { + declare module.exports: $Exports<'eslint-plugin-jest/build/rules/no-focused-tests'>; +} +declare module 'eslint-plugin-jest/build/rules/no-identical-title.js' { + declare module.exports: $Exports<'eslint-plugin-jest/build/rules/no-identical-title'>; +} +declare module 'eslint-plugin-jest/build/rules/types.js' { + declare module.exports: $Exports<'eslint-plugin-jest/build/rules/types'>; +} +declare module 'eslint-plugin-jest/build/rules/valid-expect.js' { + declare module.exports: $Exports<'eslint-plugin-jest/build/rules/valid-expect'>; +} diff --git a/flow-typed/npm/eslint-plugin-jsx-a11y_vx.x.x.js b/flow-typed/npm/eslint-plugin-jsx-a11y_vx.x.x.js new file mode 100644 index 000000000..fbaf71646 --- /dev/null +++ b/flow-typed/npm/eslint-plugin-jsx-a11y_vx.x.x.js @@ -0,0 +1,1411 @@ +// flow-typed signature: 6b61f7970cc96dba334588a5e4980afa +// flow-typed version: <>/eslint-plugin-jsx-a11y_v^4.0.0/flow_v0.59.0 + +/** + * This is an autogenerated libdef stub for: + * + * 'eslint-plugin-jsx-a11y' + * + * Fill this stub out by replacing all the `any` types. + * + * Once filled out, we encourage you to share your work with the + * community by sending a pull request to: + * https://github.com/flowtype/flow-typed + */ + +declare module 'eslint-plugin-jsx-a11y' { + declare module.exports: any; +} + +/** + * We include stubs for each file inside this npm package in case you need to + * require those files directly. Feel free to delete any files that aren't + * needed. + */ +declare module 'eslint-plugin-jsx-a11y/__mocks__/genInteractives' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/__mocks__/IdentifierMock' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/__mocks__/JSXAttributeMock' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/__mocks__/JSXElementMock' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/__mocks__/JSXExpressionContainerMock' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/__tests__/__util__/parserOptionsMapper' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/__tests__/index-test' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/__tests__/src/rules/accessible-emoji-test' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/__tests__/src/rules/anchor-has-content-test' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/__tests__/src/rules/aria-activedescendant-has-tabindex-test' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/__tests__/src/rules/aria-props-test' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/__tests__/src/rules/aria-proptypes-test' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/__tests__/src/rules/aria-role-test' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/__tests__/src/rules/aria-unsupported-elements-test' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/__tests__/src/rules/click-events-have-key-events-test' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/__tests__/src/rules/heading-has-content-test' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/__tests__/src/rules/href-no-hash-test' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/__tests__/src/rules/html-has-lang-test' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/__tests__/src/rules/iframe-has-title-test' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/__tests__/src/rules/img-has-alt-test' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/__tests__/src/rules/img-redundant-alt-test' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/__tests__/src/rules/label-has-for-test' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/__tests__/src/rules/lang-test' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/__tests__/src/rules/mouse-events-have-key-events-test' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/__tests__/src/rules/no-access-key-test' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/__tests__/src/rules/no-autofocus-test' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/__tests__/src/rules/no-distracting-elements-test' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/__tests__/src/rules/no-onchange-test' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/__tests__/src/rules/no-redundant-roles-test' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/__tests__/src/rules/no-static-element-interactions-test' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/__tests__/src/rules/onclick-has-focus-test' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/__tests__/src/rules/onclick-has-role-test' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/__tests__/src/rules/role-has-required-aria-props-test' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/__tests__/src/rules/role-supports-aria-props-test' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/__tests__/src/rules/scope-test' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/__tests__/src/rules/tabindex-no-positive-test' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/__tests__/src/util/getSuggestion-test' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/__tests__/src/util/getTabIndex-test' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/__tests__/src/util/isInteractiveElement-test' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/__tests__/src/util/isInteractiveRole-test' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/__tests__/src/util/parserOptionsMapper-test' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/__tests__/src/util/schemas-test' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/flow/eslint' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/lib/index' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/lib/rules/accessible-emoji' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/lib/rules/anchor-has-content' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/lib/rules/aria-activedescendant-has-tabindex' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/lib/rules/aria-props' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/lib/rules/aria-proptypes' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/lib/rules/aria-role' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/lib/rules/aria-unsupported-elements' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/lib/rules/click-events-have-key-events' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/lib/rules/heading-has-content' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/lib/rules/href-no-hash' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/lib/rules/html-has-lang' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/lib/rules/iframe-has-title' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/lib/rules/img-has-alt' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/lib/rules/img-redundant-alt' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/lib/rules/label-has-for' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/lib/rules/lang' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/lib/rules/mouse-events-have-key-events' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/lib/rules/no-access-key' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/lib/rules/no-autofocus' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/lib/rules/no-distracting-elements' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/lib/rules/no-onchange' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/lib/rules/no-redundant-roles' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/lib/rules/no-static-element-interactions' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/lib/rules/onclick-has-focus' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/lib/rules/onclick-has-role' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/lib/rules/role-has-required-aria-props' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/lib/rules/role-supports-aria-props' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/lib/rules/scope' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/lib/rules/tabindex-no-positive' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/lib/util/getImplicitRole' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/lib/util/getSuggestion' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/lib/util/getTabIndex' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/a' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/area' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/article' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/aside' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/body' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/button' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/datalist' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/details' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/dialog' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/dl' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/form' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/h1' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/h2' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/h3' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/h4' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/h5' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/h6' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/hr' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/img' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/index' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/input' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/li' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/link' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/menu' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/menuitem' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/meter' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/nav' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/ol' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/option' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/output' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/progress' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/section' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/select' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/tbody' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/textarea' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/tfoot' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/thead' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/ul' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/lib/util/isHiddenFromScreenReader' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/lib/util/isInteractiveElement' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/lib/util/isInteractiveRole' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/lib/util/schemas' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/scripts/addRuleToIndex' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/scripts/boilerplate/doc' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/scripts/boilerplate/rule' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/scripts/boilerplate/test' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/scripts/create-rule' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/src/index' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/src/rules/accessible-emoji' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/src/rules/anchor-has-content' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/src/rules/aria-activedescendant-has-tabindex' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/src/rules/aria-props' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/src/rules/aria-proptypes' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/src/rules/aria-role' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/src/rules/aria-unsupported-elements' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/src/rules/click-events-have-key-events' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/src/rules/heading-has-content' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/src/rules/href-no-hash' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/src/rules/html-has-lang' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/src/rules/iframe-has-title' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/src/rules/img-has-alt' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/src/rules/img-redundant-alt' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/src/rules/label-has-for' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/src/rules/lang' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/src/rules/mouse-events-have-key-events' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/src/rules/no-access-key' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/src/rules/no-autofocus' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/src/rules/no-distracting-elements' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/src/rules/no-onchange' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/src/rules/no-redundant-roles' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/src/rules/no-static-element-interactions' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/src/rules/onclick-has-focus' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/src/rules/onclick-has-role' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/src/rules/role-has-required-aria-props' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/src/rules/role-supports-aria-props' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/src/rules/scope' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/src/rules/tabindex-no-positive' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/src/util/getImplicitRole' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/src/util/getSuggestion' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/src/util/getTabIndex' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/src/util/implicitRoles/a' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/src/util/implicitRoles/area' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/src/util/implicitRoles/article' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/src/util/implicitRoles/aside' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/src/util/implicitRoles/body' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/src/util/implicitRoles/button' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/src/util/implicitRoles/datalist' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/src/util/implicitRoles/details' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/src/util/implicitRoles/dialog' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/src/util/implicitRoles/dl' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/src/util/implicitRoles/form' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/src/util/implicitRoles/h1' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/src/util/implicitRoles/h2' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/src/util/implicitRoles/h3' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/src/util/implicitRoles/h4' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/src/util/implicitRoles/h5' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/src/util/implicitRoles/h6' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/src/util/implicitRoles/hr' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/src/util/implicitRoles/img' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/src/util/implicitRoles/index' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/src/util/implicitRoles/input' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/src/util/implicitRoles/li' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/src/util/implicitRoles/link' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/src/util/implicitRoles/menu' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/src/util/implicitRoles/menuitem' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/src/util/implicitRoles/meter' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/src/util/implicitRoles/nav' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/src/util/implicitRoles/ol' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/src/util/implicitRoles/option' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/src/util/implicitRoles/output' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/src/util/implicitRoles/progress' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/src/util/implicitRoles/section' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/src/util/implicitRoles/select' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/src/util/implicitRoles/tbody' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/src/util/implicitRoles/textarea' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/src/util/implicitRoles/tfoot' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/src/util/implicitRoles/thead' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/src/util/implicitRoles/ul' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/src/util/isHiddenFromScreenReader' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/src/util/isInteractiveElement' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/src/util/isInteractiveRole' { + declare module.exports: any; +} + +declare module 'eslint-plugin-jsx-a11y/src/util/schemas' { + declare module.exports: any; +} + +// Filename aliases +declare module 'eslint-plugin-jsx-a11y/__mocks__/genInteractives.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/__mocks__/genInteractives'>; +} +declare module 'eslint-plugin-jsx-a11y/__mocks__/IdentifierMock.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/__mocks__/IdentifierMock'>; +} +declare module 'eslint-plugin-jsx-a11y/__mocks__/JSXAttributeMock.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/__mocks__/JSXAttributeMock'>; +} +declare module 'eslint-plugin-jsx-a11y/__mocks__/JSXElementMock.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/__mocks__/JSXElementMock'>; +} +declare module 'eslint-plugin-jsx-a11y/__mocks__/JSXExpressionContainerMock.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/__mocks__/JSXExpressionContainerMock'>; +} +declare module 'eslint-plugin-jsx-a11y/__tests__/__util__/parserOptionsMapper.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/__tests__/__util__/parserOptionsMapper'>; +} +declare module 'eslint-plugin-jsx-a11y/__tests__/index-test.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/__tests__/index-test'>; +} +declare module 'eslint-plugin-jsx-a11y/__tests__/src/rules/accessible-emoji-test.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/__tests__/src/rules/accessible-emoji-test'>; +} +declare module 'eslint-plugin-jsx-a11y/__tests__/src/rules/anchor-has-content-test.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/__tests__/src/rules/anchor-has-content-test'>; +} +declare module 'eslint-plugin-jsx-a11y/__tests__/src/rules/aria-activedescendant-has-tabindex-test.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/__tests__/src/rules/aria-activedescendant-has-tabindex-test'>; +} +declare module 'eslint-plugin-jsx-a11y/__tests__/src/rules/aria-props-test.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/__tests__/src/rules/aria-props-test'>; +} +declare module 'eslint-plugin-jsx-a11y/__tests__/src/rules/aria-proptypes-test.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/__tests__/src/rules/aria-proptypes-test'>; +} +declare module 'eslint-plugin-jsx-a11y/__tests__/src/rules/aria-role-test.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/__tests__/src/rules/aria-role-test'>; +} +declare module 'eslint-plugin-jsx-a11y/__tests__/src/rules/aria-unsupported-elements-test.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/__tests__/src/rules/aria-unsupported-elements-test'>; +} +declare module 'eslint-plugin-jsx-a11y/__tests__/src/rules/click-events-have-key-events-test.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/__tests__/src/rules/click-events-have-key-events-test'>; +} +declare module 'eslint-plugin-jsx-a11y/__tests__/src/rules/heading-has-content-test.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/__tests__/src/rules/heading-has-content-test'>; +} +declare module 'eslint-plugin-jsx-a11y/__tests__/src/rules/href-no-hash-test.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/__tests__/src/rules/href-no-hash-test'>; +} +declare module 'eslint-plugin-jsx-a11y/__tests__/src/rules/html-has-lang-test.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/__tests__/src/rules/html-has-lang-test'>; +} +declare module 'eslint-plugin-jsx-a11y/__tests__/src/rules/iframe-has-title-test.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/__tests__/src/rules/iframe-has-title-test'>; +} +declare module 'eslint-plugin-jsx-a11y/__tests__/src/rules/img-has-alt-test.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/__tests__/src/rules/img-has-alt-test'>; +} +declare module 'eslint-plugin-jsx-a11y/__tests__/src/rules/img-redundant-alt-test.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/__tests__/src/rules/img-redundant-alt-test'>; +} +declare module 'eslint-plugin-jsx-a11y/__tests__/src/rules/label-has-for-test.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/__tests__/src/rules/label-has-for-test'>; +} +declare module 'eslint-plugin-jsx-a11y/__tests__/src/rules/lang-test.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/__tests__/src/rules/lang-test'>; +} +declare module 'eslint-plugin-jsx-a11y/__tests__/src/rules/mouse-events-have-key-events-test.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/__tests__/src/rules/mouse-events-have-key-events-test'>; +} +declare module 'eslint-plugin-jsx-a11y/__tests__/src/rules/no-access-key-test.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/__tests__/src/rules/no-access-key-test'>; +} +declare module 'eslint-plugin-jsx-a11y/__tests__/src/rules/no-autofocus-test.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/__tests__/src/rules/no-autofocus-test'>; +} +declare module 'eslint-plugin-jsx-a11y/__tests__/src/rules/no-distracting-elements-test.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/__tests__/src/rules/no-distracting-elements-test'>; +} +declare module 'eslint-plugin-jsx-a11y/__tests__/src/rules/no-onchange-test.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/__tests__/src/rules/no-onchange-test'>; +} +declare module 'eslint-plugin-jsx-a11y/__tests__/src/rules/no-redundant-roles-test.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/__tests__/src/rules/no-redundant-roles-test'>; +} +declare module 'eslint-plugin-jsx-a11y/__tests__/src/rules/no-static-element-interactions-test.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/__tests__/src/rules/no-static-element-interactions-test'>; +} +declare module 'eslint-plugin-jsx-a11y/__tests__/src/rules/onclick-has-focus-test.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/__tests__/src/rules/onclick-has-focus-test'>; +} +declare module 'eslint-plugin-jsx-a11y/__tests__/src/rules/onclick-has-role-test.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/__tests__/src/rules/onclick-has-role-test'>; +} +declare module 'eslint-plugin-jsx-a11y/__tests__/src/rules/role-has-required-aria-props-test.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/__tests__/src/rules/role-has-required-aria-props-test'>; +} +declare module 'eslint-plugin-jsx-a11y/__tests__/src/rules/role-supports-aria-props-test.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/__tests__/src/rules/role-supports-aria-props-test'>; +} +declare module 'eslint-plugin-jsx-a11y/__tests__/src/rules/scope-test.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/__tests__/src/rules/scope-test'>; +} +declare module 'eslint-plugin-jsx-a11y/__tests__/src/rules/tabindex-no-positive-test.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/__tests__/src/rules/tabindex-no-positive-test'>; +} +declare module 'eslint-plugin-jsx-a11y/__tests__/src/util/getSuggestion-test.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/__tests__/src/util/getSuggestion-test'>; +} +declare module 'eslint-plugin-jsx-a11y/__tests__/src/util/getTabIndex-test.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/__tests__/src/util/getTabIndex-test'>; +} +declare module 'eslint-plugin-jsx-a11y/__tests__/src/util/isInteractiveElement-test.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/__tests__/src/util/isInteractiveElement-test'>; +} +declare module 'eslint-plugin-jsx-a11y/__tests__/src/util/isInteractiveRole-test.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/__tests__/src/util/isInteractiveRole-test'>; +} +declare module 'eslint-plugin-jsx-a11y/__tests__/src/util/parserOptionsMapper-test.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/__tests__/src/util/parserOptionsMapper-test'>; +} +declare module 'eslint-plugin-jsx-a11y/__tests__/src/util/schemas-test.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/__tests__/src/util/schemas-test'>; +} +declare module 'eslint-plugin-jsx-a11y/flow/eslint.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/flow/eslint'>; +} +declare module 'eslint-plugin-jsx-a11y/lib/index.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/index'>; +} +declare module 'eslint-plugin-jsx-a11y/lib/rules/accessible-emoji.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/rules/accessible-emoji'>; +} +declare module 'eslint-plugin-jsx-a11y/lib/rules/anchor-has-content.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/rules/anchor-has-content'>; +} +declare module 'eslint-plugin-jsx-a11y/lib/rules/aria-activedescendant-has-tabindex.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/rules/aria-activedescendant-has-tabindex'>; +} +declare module 'eslint-plugin-jsx-a11y/lib/rules/aria-props.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/rules/aria-props'>; +} +declare module 'eslint-plugin-jsx-a11y/lib/rules/aria-proptypes.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/rules/aria-proptypes'>; +} +declare module 'eslint-plugin-jsx-a11y/lib/rules/aria-role.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/rules/aria-role'>; +} +declare module 'eslint-plugin-jsx-a11y/lib/rules/aria-unsupported-elements.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/rules/aria-unsupported-elements'>; +} +declare module 'eslint-plugin-jsx-a11y/lib/rules/click-events-have-key-events.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/rules/click-events-have-key-events'>; +} +declare module 'eslint-plugin-jsx-a11y/lib/rules/heading-has-content.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/rules/heading-has-content'>; +} +declare module 'eslint-plugin-jsx-a11y/lib/rules/href-no-hash.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/rules/href-no-hash'>; +} +declare module 'eslint-plugin-jsx-a11y/lib/rules/html-has-lang.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/rules/html-has-lang'>; +} +declare module 'eslint-plugin-jsx-a11y/lib/rules/iframe-has-title.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/rules/iframe-has-title'>; +} +declare module 'eslint-plugin-jsx-a11y/lib/rules/img-has-alt.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/rules/img-has-alt'>; +} +declare module 'eslint-plugin-jsx-a11y/lib/rules/img-redundant-alt.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/rules/img-redundant-alt'>; +} +declare module 'eslint-plugin-jsx-a11y/lib/rules/label-has-for.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/rules/label-has-for'>; +} +declare module 'eslint-plugin-jsx-a11y/lib/rules/lang.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/rules/lang'>; +} +declare module 'eslint-plugin-jsx-a11y/lib/rules/mouse-events-have-key-events.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/rules/mouse-events-have-key-events'>; +} +declare module 'eslint-plugin-jsx-a11y/lib/rules/no-access-key.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/rules/no-access-key'>; +} +declare module 'eslint-plugin-jsx-a11y/lib/rules/no-autofocus.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/rules/no-autofocus'>; +} +declare module 'eslint-plugin-jsx-a11y/lib/rules/no-distracting-elements.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/rules/no-distracting-elements'>; +} +declare module 'eslint-plugin-jsx-a11y/lib/rules/no-onchange.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/rules/no-onchange'>; +} +declare module 'eslint-plugin-jsx-a11y/lib/rules/no-redundant-roles.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/rules/no-redundant-roles'>; +} +declare module 'eslint-plugin-jsx-a11y/lib/rules/no-static-element-interactions.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/rules/no-static-element-interactions'>; +} +declare module 'eslint-plugin-jsx-a11y/lib/rules/onclick-has-focus.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/rules/onclick-has-focus'>; +} +declare module 'eslint-plugin-jsx-a11y/lib/rules/onclick-has-role.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/rules/onclick-has-role'>; +} +declare module 'eslint-plugin-jsx-a11y/lib/rules/role-has-required-aria-props.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/rules/role-has-required-aria-props'>; +} +declare module 'eslint-plugin-jsx-a11y/lib/rules/role-supports-aria-props.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/rules/role-supports-aria-props'>; +} +declare module 'eslint-plugin-jsx-a11y/lib/rules/scope.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/rules/scope'>; +} +declare module 'eslint-plugin-jsx-a11y/lib/rules/tabindex-no-positive.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/rules/tabindex-no-positive'>; +} +declare module 'eslint-plugin-jsx-a11y/lib/util/getImplicitRole.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/util/getImplicitRole'>; +} +declare module 'eslint-plugin-jsx-a11y/lib/util/getSuggestion.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/util/getSuggestion'>; +} +declare module 'eslint-plugin-jsx-a11y/lib/util/getTabIndex.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/util/getTabIndex'>; +} +declare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/a.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/util/implicitRoles/a'>; +} +declare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/area.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/util/implicitRoles/area'>; +} +declare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/article.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/util/implicitRoles/article'>; +} +declare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/aside.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/util/implicitRoles/aside'>; +} +declare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/body.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/util/implicitRoles/body'>; +} +declare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/button.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/util/implicitRoles/button'>; +} +declare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/datalist.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/util/implicitRoles/datalist'>; +} +declare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/details.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/util/implicitRoles/details'>; +} +declare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/dialog.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/util/implicitRoles/dialog'>; +} +declare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/dl.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/util/implicitRoles/dl'>; +} +declare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/form.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/util/implicitRoles/form'>; +} +declare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/h1.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/util/implicitRoles/h1'>; +} +declare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/h2.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/util/implicitRoles/h2'>; +} +declare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/h3.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/util/implicitRoles/h3'>; +} +declare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/h4.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/util/implicitRoles/h4'>; +} +declare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/h5.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/util/implicitRoles/h5'>; +} +declare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/h6.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/util/implicitRoles/h6'>; +} +declare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/hr.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/util/implicitRoles/hr'>; +} +declare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/img.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/util/implicitRoles/img'>; +} +declare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/index.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/util/implicitRoles/index'>; +} +declare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/input.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/util/implicitRoles/input'>; +} +declare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/li.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/util/implicitRoles/li'>; +} +declare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/link.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/util/implicitRoles/link'>; +} +declare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/menu.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/util/implicitRoles/menu'>; +} +declare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/menuitem.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/util/implicitRoles/menuitem'>; +} +declare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/meter.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/util/implicitRoles/meter'>; +} +declare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/nav.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/util/implicitRoles/nav'>; +} +declare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/ol.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/util/implicitRoles/ol'>; +} +declare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/option.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/util/implicitRoles/option'>; +} +declare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/output.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/util/implicitRoles/output'>; +} +declare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/progress.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/util/implicitRoles/progress'>; +} +declare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/section.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/util/implicitRoles/section'>; +} +declare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/select.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/util/implicitRoles/select'>; +} +declare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/tbody.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/util/implicitRoles/tbody'>; +} +declare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/textarea.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/util/implicitRoles/textarea'>; +} +declare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/tfoot.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/util/implicitRoles/tfoot'>; +} +declare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/thead.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/util/implicitRoles/thead'>; +} +declare module 'eslint-plugin-jsx-a11y/lib/util/implicitRoles/ul.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/util/implicitRoles/ul'>; +} +declare module 'eslint-plugin-jsx-a11y/lib/util/isHiddenFromScreenReader.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/util/isHiddenFromScreenReader'>; +} +declare module 'eslint-plugin-jsx-a11y/lib/util/isInteractiveElement.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/util/isInteractiveElement'>; +} +declare module 'eslint-plugin-jsx-a11y/lib/util/isInteractiveRole.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/util/isInteractiveRole'>; +} +declare module 'eslint-plugin-jsx-a11y/lib/util/schemas.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/lib/util/schemas'>; +} +declare module 'eslint-plugin-jsx-a11y/scripts/addRuleToIndex.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/scripts/addRuleToIndex'>; +} +declare module 'eslint-plugin-jsx-a11y/scripts/boilerplate/doc.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/scripts/boilerplate/doc'>; +} +declare module 'eslint-plugin-jsx-a11y/scripts/boilerplate/rule.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/scripts/boilerplate/rule'>; +} +declare module 'eslint-plugin-jsx-a11y/scripts/boilerplate/test.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/scripts/boilerplate/test'>; +} +declare module 'eslint-plugin-jsx-a11y/scripts/create-rule.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/scripts/create-rule'>; +} +declare module 'eslint-plugin-jsx-a11y/src/index.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/src/index'>; +} +declare module 'eslint-plugin-jsx-a11y/src/rules/accessible-emoji.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/src/rules/accessible-emoji'>; +} +declare module 'eslint-plugin-jsx-a11y/src/rules/anchor-has-content.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/src/rules/anchor-has-content'>; +} +declare module 'eslint-plugin-jsx-a11y/src/rules/aria-activedescendant-has-tabindex.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/src/rules/aria-activedescendant-has-tabindex'>; +} +declare module 'eslint-plugin-jsx-a11y/src/rules/aria-props.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/src/rules/aria-props'>; +} +declare module 'eslint-plugin-jsx-a11y/src/rules/aria-proptypes.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/src/rules/aria-proptypes'>; +} +declare module 'eslint-plugin-jsx-a11y/src/rules/aria-role.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/src/rules/aria-role'>; +} +declare module 'eslint-plugin-jsx-a11y/src/rules/aria-unsupported-elements.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/src/rules/aria-unsupported-elements'>; +} +declare module 'eslint-plugin-jsx-a11y/src/rules/click-events-have-key-events.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/src/rules/click-events-have-key-events'>; +} +declare module 'eslint-plugin-jsx-a11y/src/rules/heading-has-content.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/src/rules/heading-has-content'>; +} +declare module 'eslint-plugin-jsx-a11y/src/rules/href-no-hash.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/src/rules/href-no-hash'>; +} +declare module 'eslint-plugin-jsx-a11y/src/rules/html-has-lang.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/src/rules/html-has-lang'>; +} +declare module 'eslint-plugin-jsx-a11y/src/rules/iframe-has-title.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/src/rules/iframe-has-title'>; +} +declare module 'eslint-plugin-jsx-a11y/src/rules/img-has-alt.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/src/rules/img-has-alt'>; +} +declare module 'eslint-plugin-jsx-a11y/src/rules/img-redundant-alt.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/src/rules/img-redundant-alt'>; +} +declare module 'eslint-plugin-jsx-a11y/src/rules/label-has-for.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/src/rules/label-has-for'>; +} +declare module 'eslint-plugin-jsx-a11y/src/rules/lang.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/src/rules/lang'>; +} +declare module 'eslint-plugin-jsx-a11y/src/rules/mouse-events-have-key-events.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/src/rules/mouse-events-have-key-events'>; +} +declare module 'eslint-plugin-jsx-a11y/src/rules/no-access-key.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/src/rules/no-access-key'>; +} +declare module 'eslint-plugin-jsx-a11y/src/rules/no-autofocus.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/src/rules/no-autofocus'>; +} +declare module 'eslint-plugin-jsx-a11y/src/rules/no-distracting-elements.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/src/rules/no-distracting-elements'>; +} +declare module 'eslint-plugin-jsx-a11y/src/rules/no-onchange.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/src/rules/no-onchange'>; +} +declare module 'eslint-plugin-jsx-a11y/src/rules/no-redundant-roles.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/src/rules/no-redundant-roles'>; +} +declare module 'eslint-plugin-jsx-a11y/src/rules/no-static-element-interactions.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/src/rules/no-static-element-interactions'>; +} +declare module 'eslint-plugin-jsx-a11y/src/rules/onclick-has-focus.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/src/rules/onclick-has-focus'>; +} +declare module 'eslint-plugin-jsx-a11y/src/rules/onclick-has-role.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/src/rules/onclick-has-role'>; +} +declare module 'eslint-plugin-jsx-a11y/src/rules/role-has-required-aria-props.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/src/rules/role-has-required-aria-props'>; +} +declare module 'eslint-plugin-jsx-a11y/src/rules/role-supports-aria-props.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/src/rules/role-supports-aria-props'>; +} +declare module 'eslint-plugin-jsx-a11y/src/rules/scope.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/src/rules/scope'>; +} +declare module 'eslint-plugin-jsx-a11y/src/rules/tabindex-no-positive.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/src/rules/tabindex-no-positive'>; +} +declare module 'eslint-plugin-jsx-a11y/src/util/getImplicitRole.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/src/util/getImplicitRole'>; +} +declare module 'eslint-plugin-jsx-a11y/src/util/getSuggestion.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/src/util/getSuggestion'>; +} +declare module 'eslint-plugin-jsx-a11y/src/util/getTabIndex.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/src/util/getTabIndex'>; +} +declare module 'eslint-plugin-jsx-a11y/src/util/implicitRoles/a.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/src/util/implicitRoles/a'>; +} +declare module 'eslint-plugin-jsx-a11y/src/util/implicitRoles/area.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/src/util/implicitRoles/area'>; +} +declare module 'eslint-plugin-jsx-a11y/src/util/implicitRoles/article.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/src/util/implicitRoles/article'>; +} +declare module 'eslint-plugin-jsx-a11y/src/util/implicitRoles/aside.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/src/util/implicitRoles/aside'>; +} +declare module 'eslint-plugin-jsx-a11y/src/util/implicitRoles/body.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/src/util/implicitRoles/body'>; +} +declare module 'eslint-plugin-jsx-a11y/src/util/implicitRoles/button.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/src/util/implicitRoles/button'>; +} +declare module 'eslint-plugin-jsx-a11y/src/util/implicitRoles/datalist.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/src/util/implicitRoles/datalist'>; +} +declare module 'eslint-plugin-jsx-a11y/src/util/implicitRoles/details.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/src/util/implicitRoles/details'>; +} +declare module 'eslint-plugin-jsx-a11y/src/util/implicitRoles/dialog.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/src/util/implicitRoles/dialog'>; +} +declare module 'eslint-plugin-jsx-a11y/src/util/implicitRoles/dl.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/src/util/implicitRoles/dl'>; +} +declare module 'eslint-plugin-jsx-a11y/src/util/implicitRoles/form.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/src/util/implicitRoles/form'>; +} +declare module 'eslint-plugin-jsx-a11y/src/util/implicitRoles/h1.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/src/util/implicitRoles/h1'>; +} +declare module 'eslint-plugin-jsx-a11y/src/util/implicitRoles/h2.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/src/util/implicitRoles/h2'>; +} +declare module 'eslint-plugin-jsx-a11y/src/util/implicitRoles/h3.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/src/util/implicitRoles/h3'>; +} +declare module 'eslint-plugin-jsx-a11y/src/util/implicitRoles/h4.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/src/util/implicitRoles/h4'>; +} +declare module 'eslint-plugin-jsx-a11y/src/util/implicitRoles/h5.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/src/util/implicitRoles/h5'>; +} +declare module 'eslint-plugin-jsx-a11y/src/util/implicitRoles/h6.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/src/util/implicitRoles/h6'>; +} +declare module 'eslint-plugin-jsx-a11y/src/util/implicitRoles/hr.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/src/util/implicitRoles/hr'>; +} +declare module 'eslint-plugin-jsx-a11y/src/util/implicitRoles/img.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/src/util/implicitRoles/img'>; +} +declare module 'eslint-plugin-jsx-a11y/src/util/implicitRoles/index.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/src/util/implicitRoles/index'>; +} +declare module 'eslint-plugin-jsx-a11y/src/util/implicitRoles/input.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/src/util/implicitRoles/input'>; +} +declare module 'eslint-plugin-jsx-a11y/src/util/implicitRoles/li.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/src/util/implicitRoles/li'>; +} +declare module 'eslint-plugin-jsx-a11y/src/util/implicitRoles/link.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/src/util/implicitRoles/link'>; +} +declare module 'eslint-plugin-jsx-a11y/src/util/implicitRoles/menu.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/src/util/implicitRoles/menu'>; +} +declare module 'eslint-plugin-jsx-a11y/src/util/implicitRoles/menuitem.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/src/util/implicitRoles/menuitem'>; +} +declare module 'eslint-plugin-jsx-a11y/src/util/implicitRoles/meter.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/src/util/implicitRoles/meter'>; +} +declare module 'eslint-plugin-jsx-a11y/src/util/implicitRoles/nav.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/src/util/implicitRoles/nav'>; +} +declare module 'eslint-plugin-jsx-a11y/src/util/implicitRoles/ol.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/src/util/implicitRoles/ol'>; +} +declare module 'eslint-plugin-jsx-a11y/src/util/implicitRoles/option.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/src/util/implicitRoles/option'>; +} +declare module 'eslint-plugin-jsx-a11y/src/util/implicitRoles/output.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/src/util/implicitRoles/output'>; +} +declare module 'eslint-plugin-jsx-a11y/src/util/implicitRoles/progress.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/src/util/implicitRoles/progress'>; +} +declare module 'eslint-plugin-jsx-a11y/src/util/implicitRoles/section.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/src/util/implicitRoles/section'>; +} +declare module 'eslint-plugin-jsx-a11y/src/util/implicitRoles/select.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/src/util/implicitRoles/select'>; +} +declare module 'eslint-plugin-jsx-a11y/src/util/implicitRoles/tbody.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/src/util/implicitRoles/tbody'>; +} +declare module 'eslint-plugin-jsx-a11y/src/util/implicitRoles/textarea.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/src/util/implicitRoles/textarea'>; +} +declare module 'eslint-plugin-jsx-a11y/src/util/implicitRoles/tfoot.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/src/util/implicitRoles/tfoot'>; +} +declare module 'eslint-plugin-jsx-a11y/src/util/implicitRoles/thead.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/src/util/implicitRoles/thead'>; +} +declare module 'eslint-plugin-jsx-a11y/src/util/implicitRoles/ul.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/src/util/implicitRoles/ul'>; +} +declare module 'eslint-plugin-jsx-a11y/src/util/isHiddenFromScreenReader.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/src/util/isHiddenFromScreenReader'>; +} +declare module 'eslint-plugin-jsx-a11y/src/util/isInteractiveElement.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/src/util/isInteractiveElement'>; +} +declare module 'eslint-plugin-jsx-a11y/src/util/isInteractiveRole.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/src/util/isInteractiveRole'>; +} +declare module 'eslint-plugin-jsx-a11y/src/util/schemas.js' { + declare module.exports: $Exports<'eslint-plugin-jsx-a11y/src/util/schemas'>; +} diff --git a/flow-typed/npm/eslint-plugin-prettier_vx.x.x.js b/flow-typed/npm/eslint-plugin-prettier_vx.x.x.js new file mode 100644 index 000000000..8b345c4ad --- /dev/null +++ b/flow-typed/npm/eslint-plugin-prettier_vx.x.x.js @@ -0,0 +1,32 @@ +// flow-typed signature: 409c518b379d758c595068e9eefec26b +// flow-typed version: <>/eslint-plugin-prettier_v^2.3.1/flow_v0.59.0 + +/** + * This is an autogenerated libdef stub for: + * + * 'eslint-plugin-prettier' + * + * Fill this stub out by replacing all the `any` types. + * + * Once filled out, we encourage you to share your work with the + * community by sending a pull request to: + * https://github.com/flowtype/flow-typed + */ + +declare module 'eslint-plugin-prettier' { + declare module.exports: any; +} + +/** + * We include stubs for each file inside this npm package in case you need to + * require those files directly. Feel free to delete any files that aren't + * needed. + */ +declare module 'eslint-plugin-prettier/eslint-plugin-prettier' { + declare module.exports: any; +} + +// Filename aliases +declare module 'eslint-plugin-prettier/eslint-plugin-prettier.js' { + declare module.exports: $Exports<'eslint-plugin-prettier/eslint-plugin-prettier'>; +} diff --git a/flow-typed/npm/eslint-plugin-prettify_vx.x.x.js b/flow-typed/npm/eslint-plugin-prettify_vx.x.x.js new file mode 100644 index 000000000..d99f8cc70 --- /dev/null +++ b/flow-typed/npm/eslint-plugin-prettify_vx.x.x.js @@ -0,0 +1,45 @@ +// flow-typed signature: bcecc715564737f1856994b80c3fff42 +// flow-typed version: <>/eslint-plugin-prettify_v^1.0.0/flow_v0.59.0 + +/** + * This is an autogenerated libdef stub for: + * + * 'eslint-plugin-prettify' + * + * Fill this stub out by replacing all the `any` types. + * + * Once filled out, we encourage you to share your work with the + * community by sending a pull request to: + * https://github.com/flowtype/flow-typed + */ + +declare module 'eslint-plugin-prettify' { + declare module.exports: any; +} + +/** + * We include stubs for each file inside this npm package in case you need to + * require those files directly. Feel free to delete any files that aren't + * needed. + */ +declare module 'eslint-plugin-prettify/no-styles' { + declare module.exports: any; +} + +declare module 'eslint-plugin-prettify/rule' { + declare module.exports: any; +} + +// Filename aliases +declare module 'eslint-plugin-prettify/index' { + declare module.exports: $Exports<'eslint-plugin-prettify'>; +} +declare module 'eslint-plugin-prettify/index.js' { + declare module.exports: $Exports<'eslint-plugin-prettify'>; +} +declare module 'eslint-plugin-prettify/no-styles.js' { + declare module.exports: $Exports<'eslint-plugin-prettify/no-styles'>; +} +declare module 'eslint-plugin-prettify/rule.js' { + declare module.exports: $Exports<'eslint-plugin-prettify/rule'>; +} diff --git a/flow-typed/npm/eslint-plugin-react_vx.x.x.js b/flow-typed/npm/eslint-plugin-react_vx.x.x.js new file mode 100644 index 000000000..fc36e09c4 --- /dev/null +++ b/flow-typed/npm/eslint-plugin-react_vx.x.x.js @@ -0,0 +1,500 @@ +// flow-typed signature: db9fe4d9399695da59af119fe46c104a +// flow-typed version: <>/eslint-plugin-react_v^6.10.3/flow_v0.59.0 + +/** + * This is an autogenerated libdef stub for: + * + * 'eslint-plugin-react' + * + * Fill this stub out by replacing all the `any` types. + * + * Once filled out, we encourage you to share your work with the + * community by sending a pull request to: + * https://github.com/flowtype/flow-typed + */ + +declare module 'eslint-plugin-react' { + declare module.exports: any; +} + +/** + * We include stubs for each file inside this npm package in case you need to + * require those files directly. Feel free to delete any files that aren't + * needed. + */ +declare module 'eslint-plugin-react/lib/rules/display-name' { + declare module.exports: any; +} + +declare module 'eslint-plugin-react/lib/rules/forbid-component-props' { + declare module.exports: any; +} + +declare module 'eslint-plugin-react/lib/rules/forbid-elements' { + declare module.exports: any; +} + +declare module 'eslint-plugin-react/lib/rules/forbid-foreign-prop-types' { + declare module.exports: any; +} + +declare module 'eslint-plugin-react/lib/rules/forbid-prop-types' { + declare module.exports: any; +} + +declare module 'eslint-plugin-react/lib/rules/jsx-boolean-value' { + declare module.exports: any; +} + +declare module 'eslint-plugin-react/lib/rules/jsx-closing-bracket-location' { + declare module.exports: any; +} + +declare module 'eslint-plugin-react/lib/rules/jsx-curly-spacing' { + declare module.exports: any; +} + +declare module 'eslint-plugin-react/lib/rules/jsx-equals-spacing' { + declare module.exports: any; +} + +declare module 'eslint-plugin-react/lib/rules/jsx-filename-extension' { + declare module.exports: any; +} + +declare module 'eslint-plugin-react/lib/rules/jsx-first-prop-new-line' { + declare module.exports: any; +} + +declare module 'eslint-plugin-react/lib/rules/jsx-handler-names' { + declare module.exports: any; +} + +declare module 'eslint-plugin-react/lib/rules/jsx-indent-props' { + declare module.exports: any; +} + +declare module 'eslint-plugin-react/lib/rules/jsx-indent' { + declare module.exports: any; +} + +declare module 'eslint-plugin-react/lib/rules/jsx-key' { + declare module.exports: any; +} + +declare module 'eslint-plugin-react/lib/rules/jsx-max-props-per-line' { + declare module.exports: any; +} + +declare module 'eslint-plugin-react/lib/rules/jsx-no-bind' { + declare module.exports: any; +} + +declare module 'eslint-plugin-react/lib/rules/jsx-no-comment-textnodes' { + declare module.exports: any; +} + +declare module 'eslint-plugin-react/lib/rules/jsx-no-duplicate-props' { + declare module.exports: any; +} + +declare module 'eslint-plugin-react/lib/rules/jsx-no-literals' { + declare module.exports: any; +} + +declare module 'eslint-plugin-react/lib/rules/jsx-no-target-blank' { + declare module.exports: any; +} + +declare module 'eslint-plugin-react/lib/rules/jsx-no-undef' { + declare module.exports: any; +} + +declare module 'eslint-plugin-react/lib/rules/jsx-pascal-case' { + declare module.exports: any; +} + +declare module 'eslint-plugin-react/lib/rules/jsx-sort-props' { + declare module.exports: any; +} + +declare module 'eslint-plugin-react/lib/rules/jsx-space-before-closing' { + declare module.exports: any; +} + +declare module 'eslint-plugin-react/lib/rules/jsx-tag-spacing' { + declare module.exports: any; +} + +declare module 'eslint-plugin-react/lib/rules/jsx-uses-react' { + declare module.exports: any; +} + +declare module 'eslint-plugin-react/lib/rules/jsx-uses-vars' { + declare module.exports: any; +} + +declare module 'eslint-plugin-react/lib/rules/jsx-wrap-multilines' { + declare module.exports: any; +} + +declare module 'eslint-plugin-react/lib/rules/no-array-index-key' { + declare module.exports: any; +} + +declare module 'eslint-plugin-react/lib/rules/no-children-prop' { + declare module.exports: any; +} + +declare module 'eslint-plugin-react/lib/rules/no-comment-textnodes' { + declare module.exports: any; +} + +declare module 'eslint-plugin-react/lib/rules/no-danger-with-children' { + declare module.exports: any; +} + +declare module 'eslint-plugin-react/lib/rules/no-danger' { + declare module.exports: any; +} + +declare module 'eslint-plugin-react/lib/rules/no-deprecated' { + declare module.exports: any; +} + +declare module 'eslint-plugin-react/lib/rules/no-did-mount-set-state' { + declare module.exports: any; +} + +declare module 'eslint-plugin-react/lib/rules/no-did-update-set-state' { + declare module.exports: any; +} + +declare module 'eslint-plugin-react/lib/rules/no-direct-mutation-state' { + declare module.exports: any; +} + +declare module 'eslint-plugin-react/lib/rules/no-find-dom-node' { + declare module.exports: any; +} + +declare module 'eslint-plugin-react/lib/rules/no-is-mounted' { + declare module.exports: any; +} + +declare module 'eslint-plugin-react/lib/rules/no-multi-comp' { + declare module.exports: any; +} + +declare module 'eslint-plugin-react/lib/rules/no-render-return-value' { + declare module.exports: any; +} + +declare module 'eslint-plugin-react/lib/rules/no-set-state' { + declare module.exports: any; +} + +declare module 'eslint-plugin-react/lib/rules/no-string-refs' { + declare module.exports: any; +} + +declare module 'eslint-plugin-react/lib/rules/no-unescaped-entities' { + declare module.exports: any; +} + +declare module 'eslint-plugin-react/lib/rules/no-unknown-property' { + declare module.exports: any; +} + +declare module 'eslint-plugin-react/lib/rules/no-unused-prop-types' { + declare module.exports: any; +} + +declare module 'eslint-plugin-react/lib/rules/prefer-es6-class' { + declare module.exports: any; +} + +declare module 'eslint-plugin-react/lib/rules/prefer-stateless-function' { + declare module.exports: any; +} + +declare module 'eslint-plugin-react/lib/rules/prop-types' { + declare module.exports: any; +} + +declare module 'eslint-plugin-react/lib/rules/react-in-jsx-scope' { + declare module.exports: any; +} + +declare module 'eslint-plugin-react/lib/rules/require-default-props' { + declare module.exports: any; +} + +declare module 'eslint-plugin-react/lib/rules/require-extension' { + declare module.exports: any; +} + +declare module 'eslint-plugin-react/lib/rules/require-optimization' { + declare module.exports: any; +} + +declare module 'eslint-plugin-react/lib/rules/require-render-return' { + declare module.exports: any; +} + +declare module 'eslint-plugin-react/lib/rules/self-closing-comp' { + declare module.exports: any; +} + +declare module 'eslint-plugin-react/lib/rules/sort-comp' { + declare module.exports: any; +} + +declare module 'eslint-plugin-react/lib/rules/sort-prop-types' { + declare module.exports: any; +} + +declare module 'eslint-plugin-react/lib/rules/style-prop-object' { + declare module.exports: any; +} + +declare module 'eslint-plugin-react/lib/rules/void-dom-elements-no-children' { + declare module.exports: any; +} + +declare module 'eslint-plugin-react/lib/rules/wrap-multilines' { + declare module.exports: any; +} + +declare module 'eslint-plugin-react/lib/util/annotations' { + declare module.exports: any; +} + +declare module 'eslint-plugin-react/lib/util/Components' { + declare module.exports: any; +} + +declare module 'eslint-plugin-react/lib/util/getTokenBeforeClosingBracket' { + declare module.exports: any; +} + +declare module 'eslint-plugin-react/lib/util/pragma' { + declare module.exports: any; +} + +declare module 'eslint-plugin-react/lib/util/variable' { + declare module.exports: any; +} + +declare module 'eslint-plugin-react/lib/util/version' { + declare module.exports: any; +} + +// Filename aliases +declare module 'eslint-plugin-react/index' { + declare module.exports: $Exports<'eslint-plugin-react'>; +} +declare module 'eslint-plugin-react/index.js' { + declare module.exports: $Exports<'eslint-plugin-react'>; +} +declare module 'eslint-plugin-react/lib/rules/display-name.js' { + declare module.exports: $Exports<'eslint-plugin-react/lib/rules/display-name'>; +} +declare module 'eslint-plugin-react/lib/rules/forbid-component-props.js' { + declare module.exports: $Exports<'eslint-plugin-react/lib/rules/forbid-component-props'>; +} +declare module 'eslint-plugin-react/lib/rules/forbid-elements.js' { + declare module.exports: $Exports<'eslint-plugin-react/lib/rules/forbid-elements'>; +} +declare module 'eslint-plugin-react/lib/rules/forbid-foreign-prop-types.js' { + declare module.exports: $Exports<'eslint-plugin-react/lib/rules/forbid-foreign-prop-types'>; +} +declare module 'eslint-plugin-react/lib/rules/forbid-prop-types.js' { + declare module.exports: $Exports<'eslint-plugin-react/lib/rules/forbid-prop-types'>; +} +declare module 'eslint-plugin-react/lib/rules/jsx-boolean-value.js' { + declare module.exports: $Exports<'eslint-plugin-react/lib/rules/jsx-boolean-value'>; +} +declare module 'eslint-plugin-react/lib/rules/jsx-closing-bracket-location.js' { + declare module.exports: $Exports<'eslint-plugin-react/lib/rules/jsx-closing-bracket-location'>; +} +declare module 'eslint-plugin-react/lib/rules/jsx-curly-spacing.js' { + declare module.exports: $Exports<'eslint-plugin-react/lib/rules/jsx-curly-spacing'>; +} +declare module 'eslint-plugin-react/lib/rules/jsx-equals-spacing.js' { + declare module.exports: $Exports<'eslint-plugin-react/lib/rules/jsx-equals-spacing'>; +} +declare module 'eslint-plugin-react/lib/rules/jsx-filename-extension.js' { + declare module.exports: $Exports<'eslint-plugin-react/lib/rules/jsx-filename-extension'>; +} +declare module 'eslint-plugin-react/lib/rules/jsx-first-prop-new-line.js' { + declare module.exports: $Exports<'eslint-plugin-react/lib/rules/jsx-first-prop-new-line'>; +} +declare module 'eslint-plugin-react/lib/rules/jsx-handler-names.js' { + declare module.exports: $Exports<'eslint-plugin-react/lib/rules/jsx-handler-names'>; +} +declare module 'eslint-plugin-react/lib/rules/jsx-indent-props.js' { + declare module.exports: $Exports<'eslint-plugin-react/lib/rules/jsx-indent-props'>; +} +declare module 'eslint-plugin-react/lib/rules/jsx-indent.js' { + declare module.exports: $Exports<'eslint-plugin-react/lib/rules/jsx-indent'>; +} +declare module 'eslint-plugin-react/lib/rules/jsx-key.js' { + declare module.exports: $Exports<'eslint-plugin-react/lib/rules/jsx-key'>; +} +declare module 'eslint-plugin-react/lib/rules/jsx-max-props-per-line.js' { + declare module.exports: $Exports<'eslint-plugin-react/lib/rules/jsx-max-props-per-line'>; +} +declare module 'eslint-plugin-react/lib/rules/jsx-no-bind.js' { + declare module.exports: $Exports<'eslint-plugin-react/lib/rules/jsx-no-bind'>; +} +declare module 'eslint-plugin-react/lib/rules/jsx-no-comment-textnodes.js' { + declare module.exports: $Exports<'eslint-plugin-react/lib/rules/jsx-no-comment-textnodes'>; +} +declare module 'eslint-plugin-react/lib/rules/jsx-no-duplicate-props.js' { + declare module.exports: $Exports<'eslint-plugin-react/lib/rules/jsx-no-duplicate-props'>; +} +declare module 'eslint-plugin-react/lib/rules/jsx-no-literals.js' { + declare module.exports: $Exports<'eslint-plugin-react/lib/rules/jsx-no-literals'>; +} +declare module 'eslint-plugin-react/lib/rules/jsx-no-target-blank.js' { + declare module.exports: $Exports<'eslint-plugin-react/lib/rules/jsx-no-target-blank'>; +} +declare module 'eslint-plugin-react/lib/rules/jsx-no-undef.js' { + declare module.exports: $Exports<'eslint-plugin-react/lib/rules/jsx-no-undef'>; +} +declare module 'eslint-plugin-react/lib/rules/jsx-pascal-case.js' { + declare module.exports: $Exports<'eslint-plugin-react/lib/rules/jsx-pascal-case'>; +} +declare module 'eslint-plugin-react/lib/rules/jsx-sort-props.js' { + declare module.exports: $Exports<'eslint-plugin-react/lib/rules/jsx-sort-props'>; +} +declare module 'eslint-plugin-react/lib/rules/jsx-space-before-closing.js' { + declare module.exports: $Exports<'eslint-plugin-react/lib/rules/jsx-space-before-closing'>; +} +declare module 'eslint-plugin-react/lib/rules/jsx-tag-spacing.js' { + declare module.exports: $Exports<'eslint-plugin-react/lib/rules/jsx-tag-spacing'>; +} +declare module 'eslint-plugin-react/lib/rules/jsx-uses-react.js' { + declare module.exports: $Exports<'eslint-plugin-react/lib/rules/jsx-uses-react'>; +} +declare module 'eslint-plugin-react/lib/rules/jsx-uses-vars.js' { + declare module.exports: $Exports<'eslint-plugin-react/lib/rules/jsx-uses-vars'>; +} +declare module 'eslint-plugin-react/lib/rules/jsx-wrap-multilines.js' { + declare module.exports: $Exports<'eslint-plugin-react/lib/rules/jsx-wrap-multilines'>; +} +declare module 'eslint-plugin-react/lib/rules/no-array-index-key.js' { + declare module.exports: $Exports<'eslint-plugin-react/lib/rules/no-array-index-key'>; +} +declare module 'eslint-plugin-react/lib/rules/no-children-prop.js' { + declare module.exports: $Exports<'eslint-plugin-react/lib/rules/no-children-prop'>; +} +declare module 'eslint-plugin-react/lib/rules/no-comment-textnodes.js' { + declare module.exports: $Exports<'eslint-plugin-react/lib/rules/no-comment-textnodes'>; +} +declare module 'eslint-plugin-react/lib/rules/no-danger-with-children.js' { + declare module.exports: $Exports<'eslint-plugin-react/lib/rules/no-danger-with-children'>; +} +declare module 'eslint-plugin-react/lib/rules/no-danger.js' { + declare module.exports: $Exports<'eslint-plugin-react/lib/rules/no-danger'>; +} +declare module 'eslint-plugin-react/lib/rules/no-deprecated.js' { + declare module.exports: $Exports<'eslint-plugin-react/lib/rules/no-deprecated'>; +} +declare module 'eslint-plugin-react/lib/rules/no-did-mount-set-state.js' { + declare module.exports: $Exports<'eslint-plugin-react/lib/rules/no-did-mount-set-state'>; +} +declare module 'eslint-plugin-react/lib/rules/no-did-update-set-state.js' { + declare module.exports: $Exports<'eslint-plugin-react/lib/rules/no-did-update-set-state'>; +} +declare module 'eslint-plugin-react/lib/rules/no-direct-mutation-state.js' { + declare module.exports: $Exports<'eslint-plugin-react/lib/rules/no-direct-mutation-state'>; +} +declare module 'eslint-plugin-react/lib/rules/no-find-dom-node.js' { + declare module.exports: $Exports<'eslint-plugin-react/lib/rules/no-find-dom-node'>; +} +declare module 'eslint-plugin-react/lib/rules/no-is-mounted.js' { + declare module.exports: $Exports<'eslint-plugin-react/lib/rules/no-is-mounted'>; +} +declare module 'eslint-plugin-react/lib/rules/no-multi-comp.js' { + declare module.exports: $Exports<'eslint-plugin-react/lib/rules/no-multi-comp'>; +} +declare module 'eslint-plugin-react/lib/rules/no-render-return-value.js' { + declare module.exports: $Exports<'eslint-plugin-react/lib/rules/no-render-return-value'>; +} +declare module 'eslint-plugin-react/lib/rules/no-set-state.js' { + declare module.exports: $Exports<'eslint-plugin-react/lib/rules/no-set-state'>; +} +declare module 'eslint-plugin-react/lib/rules/no-string-refs.js' { + declare module.exports: $Exports<'eslint-plugin-react/lib/rules/no-string-refs'>; +} +declare module 'eslint-plugin-react/lib/rules/no-unescaped-entities.js' { + declare module.exports: $Exports<'eslint-plugin-react/lib/rules/no-unescaped-entities'>; +} +declare module 'eslint-plugin-react/lib/rules/no-unknown-property.js' { + declare module.exports: $Exports<'eslint-plugin-react/lib/rules/no-unknown-property'>; +} +declare module 'eslint-plugin-react/lib/rules/no-unused-prop-types.js' { + declare module.exports: $Exports<'eslint-plugin-react/lib/rules/no-unused-prop-types'>; +} +declare module 'eslint-plugin-react/lib/rules/prefer-es6-class.js' { + declare module.exports: $Exports<'eslint-plugin-react/lib/rules/prefer-es6-class'>; +} +declare module 'eslint-plugin-react/lib/rules/prefer-stateless-function.js' { + declare module.exports: $Exports<'eslint-plugin-react/lib/rules/prefer-stateless-function'>; +} +declare module 'eslint-plugin-react/lib/rules/prop-types.js' { + declare module.exports: $Exports<'eslint-plugin-react/lib/rules/prop-types'>; +} +declare module 'eslint-plugin-react/lib/rules/react-in-jsx-scope.js' { + declare module.exports: $Exports<'eslint-plugin-react/lib/rules/react-in-jsx-scope'>; +} +declare module 'eslint-plugin-react/lib/rules/require-default-props.js' { + declare module.exports: $Exports<'eslint-plugin-react/lib/rules/require-default-props'>; +} +declare module 'eslint-plugin-react/lib/rules/require-extension.js' { + declare module.exports: $Exports<'eslint-plugin-react/lib/rules/require-extension'>; +} +declare module 'eslint-plugin-react/lib/rules/require-optimization.js' { + declare module.exports: $Exports<'eslint-plugin-react/lib/rules/require-optimization'>; +} +declare module 'eslint-plugin-react/lib/rules/require-render-return.js' { + declare module.exports: $Exports<'eslint-plugin-react/lib/rules/require-render-return'>; +} +declare module 'eslint-plugin-react/lib/rules/self-closing-comp.js' { + declare module.exports: $Exports<'eslint-plugin-react/lib/rules/self-closing-comp'>; +} +declare module 'eslint-plugin-react/lib/rules/sort-comp.js' { + declare module.exports: $Exports<'eslint-plugin-react/lib/rules/sort-comp'>; +} +declare module 'eslint-plugin-react/lib/rules/sort-prop-types.js' { + declare module.exports: $Exports<'eslint-plugin-react/lib/rules/sort-prop-types'>; +} +declare module 'eslint-plugin-react/lib/rules/style-prop-object.js' { + declare module.exports: $Exports<'eslint-plugin-react/lib/rules/style-prop-object'>; +} +declare module 'eslint-plugin-react/lib/rules/void-dom-elements-no-children.js' { + declare module.exports: $Exports<'eslint-plugin-react/lib/rules/void-dom-elements-no-children'>; +} +declare module 'eslint-plugin-react/lib/rules/wrap-multilines.js' { + declare module.exports: $Exports<'eslint-plugin-react/lib/rules/wrap-multilines'>; +} +declare module 'eslint-plugin-react/lib/util/annotations.js' { + declare module.exports: $Exports<'eslint-plugin-react/lib/util/annotations'>; +} +declare module 'eslint-plugin-react/lib/util/Components.js' { + declare module.exports: $Exports<'eslint-plugin-react/lib/util/Components'>; +} +declare module 'eslint-plugin-react/lib/util/getTokenBeforeClosingBracket.js' { + declare module.exports: $Exports<'eslint-plugin-react/lib/util/getTokenBeforeClosingBracket'>; +} +declare module 'eslint-plugin-react/lib/util/pragma.js' { + declare module.exports: $Exports<'eslint-plugin-react/lib/util/pragma'>; +} +declare module 'eslint-plugin-react/lib/util/variable.js' { + declare module.exports: $Exports<'eslint-plugin-react/lib/util/variable'>; +} +declare module 'eslint-plugin-react/lib/util/version.js' { + declare module.exports: $Exports<'eslint-plugin-react/lib/util/version'>; +} diff --git a/flow-typed/npm/eslint_vx.x.x.js b/flow-typed/npm/eslint_vx.x.x.js new file mode 100644 index 000000000..d05b36b11 --- /dev/null +++ b/flow-typed/npm/eslint_vx.x.x.js @@ -0,0 +1,2293 @@ +// flow-typed signature: 21bb1519e9485a20d45c150ed4f678de +// flow-typed version: <>/eslint_v^3.19.0/flow_v0.59.0 + +/** + * This is an autogenerated libdef stub for: + * + * 'eslint' + * + * Fill this stub out by replacing all the `any` types. + * + * Once filled out, we encourage you to share your work with the + * community by sending a pull request to: + * https://github.com/flowtype/flow-typed + */ + +declare module 'eslint' { + declare module.exports: any; +} + +/** + * We include stubs for each file inside this npm package in case you need to + * require those files directly. Feel free to delete any files that aren't + * needed. + */ +declare module 'eslint/bin/eslint' { + declare module.exports: any; +} + +declare module 'eslint/conf/cli-options' { + declare module.exports: any; +} + +declare module 'eslint/conf/environments' { + declare module.exports: any; +} + +declare module 'eslint/conf/eslint-all' { + declare module.exports: any; +} + +declare module 'eslint/conf/eslint-recommended' { + declare module.exports: any; +} + +declare module 'eslint/lib/api' { + declare module.exports: any; +} + +declare module 'eslint/lib/ast-utils' { + declare module.exports: any; +} + +declare module 'eslint/lib/cli-engine' { + declare module.exports: any; +} + +declare module 'eslint/lib/cli' { + declare module.exports: any; +} + +declare module 'eslint/lib/code-path-analysis/code-path-analyzer' { + declare module.exports: any; +} + +declare module 'eslint/lib/code-path-analysis/code-path-segment' { + declare module.exports: any; +} + +declare module 'eslint/lib/code-path-analysis/code-path-state' { + declare module.exports: any; +} + +declare module 'eslint/lib/code-path-analysis/code-path' { + declare module.exports: any; +} + +declare module 'eslint/lib/code-path-analysis/debug-helpers' { + declare module.exports: any; +} + +declare module 'eslint/lib/code-path-analysis/fork-context' { + declare module.exports: any; +} + +declare module 'eslint/lib/code-path-analysis/id-generator' { + declare module.exports: any; +} + +declare module 'eslint/lib/config' { + declare module.exports: any; +} + +declare module 'eslint/lib/config/autoconfig' { + declare module.exports: any; +} + +declare module 'eslint/lib/config/config-file' { + declare module.exports: any; +} + +declare module 'eslint/lib/config/config-initializer' { + declare module.exports: any; +} + +declare module 'eslint/lib/config/config-ops' { + declare module.exports: any; +} + +declare module 'eslint/lib/config/config-rule' { + declare module.exports: any; +} + +declare module 'eslint/lib/config/config-validator' { + declare module.exports: any; +} + +declare module 'eslint/lib/config/environments' { + declare module.exports: any; +} + +declare module 'eslint/lib/config/plugins' { + declare module.exports: any; +} + +declare module 'eslint/lib/eslint' { + declare module.exports: any; +} + +declare module 'eslint/lib/file-finder' { + declare module.exports: any; +} + +declare module 'eslint/lib/formatters/checkstyle' { + declare module.exports: any; +} + +declare module 'eslint/lib/formatters/codeframe' { + declare module.exports: any; +} + +declare module 'eslint/lib/formatters/compact' { + declare module.exports: any; +} + +declare module 'eslint/lib/formatters/html' { + declare module.exports: any; +} + +declare module 'eslint/lib/formatters/jslint-xml' { + declare module.exports: any; +} + +declare module 'eslint/lib/formatters/json' { + declare module.exports: any; +} + +declare module 'eslint/lib/formatters/junit' { + declare module.exports: any; +} + +declare module 'eslint/lib/formatters/stylish' { + declare module.exports: any; +} + +declare module 'eslint/lib/formatters/table' { + declare module.exports: any; +} + +declare module 'eslint/lib/formatters/tap' { + declare module.exports: any; +} + +declare module 'eslint/lib/formatters/unix' { + declare module.exports: any; +} + +declare module 'eslint/lib/formatters/visualstudio' { + declare module.exports: any; +} + +declare module 'eslint/lib/ignored-paths' { + declare module.exports: any; +} + +declare module 'eslint/lib/internal-rules/internal-consistent-docs-description' { + declare module.exports: any; +} + +declare module 'eslint/lib/internal-rules/internal-no-invalid-meta' { + declare module.exports: any; +} + +declare module 'eslint/lib/load-rules' { + declare module.exports: any; +} + +declare module 'eslint/lib/logging' { + declare module.exports: any; +} + +declare module 'eslint/lib/options' { + declare module.exports: any; +} + +declare module 'eslint/lib/rule-context' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/accessor-pairs' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/array-bracket-spacing' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/array-callback-return' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/arrow-body-style' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/arrow-parens' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/arrow-spacing' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/block-scoped-var' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/block-spacing' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/brace-style' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/callback-return' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/camelcase' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/capitalized-comments' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/class-methods-use-this' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/comma-dangle' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/comma-spacing' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/comma-style' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/complexity' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/computed-property-spacing' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/consistent-return' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/consistent-this' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/constructor-super' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/curly' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/default-case' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/dot-location' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/dot-notation' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/eol-last' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/eqeqeq' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/func-call-spacing' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/func-name-matching' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/func-names' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/func-style' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/generator-star-spacing' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/global-require' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/guard-for-in' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/handle-callback-err' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/id-blacklist' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/id-length' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/id-match' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/indent' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/init-declarations' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/jsx-quotes' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/key-spacing' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/keyword-spacing' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/line-comment-position' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/linebreak-style' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/lines-around-comment' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/lines-around-directive' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/max-depth' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/max-len' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/max-lines' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/max-nested-callbacks' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/max-params' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/max-statements-per-line' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/max-statements' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/multiline-ternary' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/new-cap' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/new-parens' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/newline-after-var' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/newline-before-return' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/newline-per-chained-call' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/no-alert' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/no-array-constructor' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/no-await-in-loop' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/no-bitwise' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/no-caller' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/no-case-declarations' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/no-catch-shadow' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/no-class-assign' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/no-compare-neg-zero' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/no-cond-assign' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/no-confusing-arrow' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/no-console' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/no-const-assign' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/no-constant-condition' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/no-continue' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/no-control-regex' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/no-debugger' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/no-delete-var' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/no-div-regex' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/no-dupe-args' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/no-dupe-class-members' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/no-dupe-keys' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/no-duplicate-case' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/no-duplicate-imports' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/no-else-return' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/no-empty-character-class' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/no-empty-function' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/no-empty-pattern' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/no-empty' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/no-eq-null' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/no-eval' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/no-ex-assign' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/no-extend-native' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/no-extra-bind' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/no-extra-boolean-cast' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/no-extra-label' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/no-extra-parens' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/no-extra-semi' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/no-fallthrough' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/no-floating-decimal' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/no-func-assign' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/no-global-assign' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/no-implicit-coercion' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/no-implicit-globals' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/no-implied-eval' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/no-inline-comments' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/no-inner-declarations' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/no-invalid-regexp' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/no-invalid-this' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/no-irregular-whitespace' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/no-iterator' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/no-label-var' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/no-labels' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/no-lone-blocks' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/no-lonely-if' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/no-loop-func' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/no-magic-numbers' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/no-mixed-operators' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/no-mixed-requires' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/no-mixed-spaces-and-tabs' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/no-multi-assign' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/no-multi-spaces' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/no-multi-str' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/no-multiple-empty-lines' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/no-native-reassign' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/no-negated-condition' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/no-negated-in-lhs' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/no-nested-ternary' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/no-new-func' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/no-new-object' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/no-new-require' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/no-new-symbol' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/no-new-wrappers' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/no-new' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/no-obj-calls' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/no-octal-escape' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/no-octal' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/no-param-reassign' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/no-path-concat' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/no-plusplus' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/no-process-env' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/no-process-exit' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/no-proto' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/no-prototype-builtins' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/no-redeclare' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/no-regex-spaces' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/no-restricted-globals' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/no-restricted-imports' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/no-restricted-modules' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/no-restricted-properties' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/no-restricted-syntax' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/no-return-assign' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/no-return-await' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/no-script-url' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/no-self-assign' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/no-self-compare' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/no-sequences' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/no-shadow-restricted-names' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/no-shadow' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/no-spaced-func' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/no-sparse-arrays' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/no-sync' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/no-tabs' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/no-template-curly-in-string' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/no-ternary' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/no-this-before-super' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/no-throw-literal' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/no-trailing-spaces' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/no-undef-init' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/no-undef' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/no-undefined' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/no-underscore-dangle' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/no-unexpected-multiline' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/no-unmodified-loop-condition' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/no-unneeded-ternary' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/no-unreachable' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/no-unsafe-finally' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/no-unsafe-negation' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/no-unused-expressions' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/no-unused-labels' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/no-unused-vars' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/no-use-before-define' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/no-useless-call' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/no-useless-computed-key' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/no-useless-concat' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/no-useless-constructor' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/no-useless-escape' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/no-useless-rename' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/no-useless-return' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/no-var' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/no-void' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/no-warning-comments' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/no-whitespace-before-property' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/no-with' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/nonblock-statement-body-position' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/object-curly-newline' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/object-curly-spacing' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/object-property-newline' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/object-shorthand' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/one-var-declaration-per-line' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/one-var' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/operator-assignment' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/operator-linebreak' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/padded-blocks' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/prefer-arrow-callback' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/prefer-const' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/prefer-destructuring' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/prefer-numeric-literals' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/prefer-promise-reject-errors' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/prefer-reflect' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/prefer-rest-params' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/prefer-spread' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/prefer-template' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/quote-props' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/quotes' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/radix' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/require-await' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/require-jsdoc' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/require-yield' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/rest-spread-spacing' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/semi-spacing' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/semi' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/sort-imports' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/sort-keys' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/sort-vars' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/space-before-blocks' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/space-before-function-paren' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/space-in-parens' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/space-infix-ops' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/space-unary-ops' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/spaced-comment' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/strict' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/symbol-description' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/template-curly-spacing' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/template-tag-spacing' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/unicode-bom' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/use-isnan' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/valid-jsdoc' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/valid-typeof' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/vars-on-top' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/wrap-iife' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/wrap-regex' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/yield-star-spacing' { + declare module.exports: any; +} + +declare module 'eslint/lib/rules/yoda' { + declare module.exports: any; +} + +declare module 'eslint/lib/testers/event-generator-tester' { + declare module.exports: any; +} + +declare module 'eslint/lib/testers/rule-tester' { + declare module.exports: any; +} + +declare module 'eslint/lib/timing' { + declare module.exports: any; +} + +declare module 'eslint/lib/token-store/backward-token-comment-cursor' { + declare module.exports: any; +} + +declare module 'eslint/lib/token-store/backward-token-cursor' { + declare module.exports: any; +} + +declare module 'eslint/lib/token-store/cursor' { + declare module.exports: any; +} + +declare module 'eslint/lib/token-store/cursors' { + declare module.exports: any; +} + +declare module 'eslint/lib/token-store/decorative-cursor' { + declare module.exports: any; +} + +declare module 'eslint/lib/token-store/filter-cursor' { + declare module.exports: any; +} + +declare module 'eslint/lib/token-store/forward-token-comment-cursor' { + declare module.exports: any; +} + +declare module 'eslint/lib/token-store/forward-token-cursor' { + declare module.exports: any; +} + +declare module 'eslint/lib/token-store/index' { + declare module.exports: any; +} + +declare module 'eslint/lib/token-store/limit-cursor' { + declare module.exports: any; +} + +declare module 'eslint/lib/token-store/padded-token-cursor' { + declare module.exports: any; +} + +declare module 'eslint/lib/token-store/skip-cursor' { + declare module.exports: any; +} + +declare module 'eslint/lib/token-store/utils' { + declare module.exports: any; +} + +declare module 'eslint/lib/util/comment-event-generator' { + declare module.exports: any; +} + +declare module 'eslint/lib/util/fix-tracker' { + declare module.exports: any; +} + +declare module 'eslint/lib/util/glob-util' { + declare module.exports: any; +} + +declare module 'eslint/lib/util/glob' { + declare module.exports: any; +} + +declare module 'eslint/lib/util/hash' { + declare module.exports: any; +} + +declare module 'eslint/lib/util/keywords' { + declare module.exports: any; +} + +declare module 'eslint/lib/util/module-resolver' { + declare module.exports: any; +} + +declare module 'eslint/lib/util/node-event-generator' { + declare module.exports: any; +} + +declare module 'eslint/lib/util/npm-util' { + declare module.exports: any; +} + +declare module 'eslint/lib/util/path-util' { + declare module.exports: any; +} + +declare module 'eslint/lib/util/patterns/letters' { + declare module.exports: any; +} + +declare module 'eslint/lib/util/rule-fixer' { + declare module.exports: any; +} + +declare module 'eslint/lib/util/source-code-fixer' { + declare module.exports: any; +} + +declare module 'eslint/lib/util/source-code-util' { + declare module.exports: any; +} + +declare module 'eslint/lib/util/source-code' { + declare module.exports: any; +} + +declare module 'eslint/lib/util/traverser' { + declare module.exports: any; +} + +declare module 'eslint/lib/util/xml-escape' { + declare module.exports: any; +} + +// Filename aliases +declare module 'eslint/bin/eslint.js' { + declare module.exports: $Exports<'eslint/bin/eslint'>; +} +declare module 'eslint/conf/cli-options.js' { + declare module.exports: $Exports<'eslint/conf/cli-options'>; +} +declare module 'eslint/conf/environments.js' { + declare module.exports: $Exports<'eslint/conf/environments'>; +} +declare module 'eslint/conf/eslint-all.js' { + declare module.exports: $Exports<'eslint/conf/eslint-all'>; +} +declare module 'eslint/conf/eslint-recommended.js' { + declare module.exports: $Exports<'eslint/conf/eslint-recommended'>; +} +declare module 'eslint/lib/api.js' { + declare module.exports: $Exports<'eslint/lib/api'>; +} +declare module 'eslint/lib/ast-utils.js' { + declare module.exports: $Exports<'eslint/lib/ast-utils'>; +} +declare module 'eslint/lib/cli-engine.js' { + declare module.exports: $Exports<'eslint/lib/cli-engine'>; +} +declare module 'eslint/lib/cli.js' { + declare module.exports: $Exports<'eslint/lib/cli'>; +} +declare module 'eslint/lib/code-path-analysis/code-path-analyzer.js' { + declare module.exports: $Exports<'eslint/lib/code-path-analysis/code-path-analyzer'>; +} +declare module 'eslint/lib/code-path-analysis/code-path-segment.js' { + declare module.exports: $Exports<'eslint/lib/code-path-analysis/code-path-segment'>; +} +declare module 'eslint/lib/code-path-analysis/code-path-state.js' { + declare module.exports: $Exports<'eslint/lib/code-path-analysis/code-path-state'>; +} +declare module 'eslint/lib/code-path-analysis/code-path.js' { + declare module.exports: $Exports<'eslint/lib/code-path-analysis/code-path'>; +} +declare module 'eslint/lib/code-path-analysis/debug-helpers.js' { + declare module.exports: $Exports<'eslint/lib/code-path-analysis/debug-helpers'>; +} +declare module 'eslint/lib/code-path-analysis/fork-context.js' { + declare module.exports: $Exports<'eslint/lib/code-path-analysis/fork-context'>; +} +declare module 'eslint/lib/code-path-analysis/id-generator.js' { + declare module.exports: $Exports<'eslint/lib/code-path-analysis/id-generator'>; +} +declare module 'eslint/lib/config.js' { + declare module.exports: $Exports<'eslint/lib/config'>; +} +declare module 'eslint/lib/config/autoconfig.js' { + declare module.exports: $Exports<'eslint/lib/config/autoconfig'>; +} +declare module 'eslint/lib/config/config-file.js' { + declare module.exports: $Exports<'eslint/lib/config/config-file'>; +} +declare module 'eslint/lib/config/config-initializer.js' { + declare module.exports: $Exports<'eslint/lib/config/config-initializer'>; +} +declare module 'eslint/lib/config/config-ops.js' { + declare module.exports: $Exports<'eslint/lib/config/config-ops'>; +} +declare module 'eslint/lib/config/config-rule.js' { + declare module.exports: $Exports<'eslint/lib/config/config-rule'>; +} +declare module 'eslint/lib/config/config-validator.js' { + declare module.exports: $Exports<'eslint/lib/config/config-validator'>; +} +declare module 'eslint/lib/config/environments.js' { + declare module.exports: $Exports<'eslint/lib/config/environments'>; +} +declare module 'eslint/lib/config/plugins.js' { + declare module.exports: $Exports<'eslint/lib/config/plugins'>; +} +declare module 'eslint/lib/eslint.js' { + declare module.exports: $Exports<'eslint/lib/eslint'>; +} +declare module 'eslint/lib/file-finder.js' { + declare module.exports: $Exports<'eslint/lib/file-finder'>; +} +declare module 'eslint/lib/formatters/checkstyle.js' { + declare module.exports: $Exports<'eslint/lib/formatters/checkstyle'>; +} +declare module 'eslint/lib/formatters/codeframe.js' { + declare module.exports: $Exports<'eslint/lib/formatters/codeframe'>; +} +declare module 'eslint/lib/formatters/compact.js' { + declare module.exports: $Exports<'eslint/lib/formatters/compact'>; +} +declare module 'eslint/lib/formatters/html.js' { + declare module.exports: $Exports<'eslint/lib/formatters/html'>; +} +declare module 'eslint/lib/formatters/jslint-xml.js' { + declare module.exports: $Exports<'eslint/lib/formatters/jslint-xml'>; +} +declare module 'eslint/lib/formatters/json.js' { + declare module.exports: $Exports<'eslint/lib/formatters/json'>; +} +declare module 'eslint/lib/formatters/junit.js' { + declare module.exports: $Exports<'eslint/lib/formatters/junit'>; +} +declare module 'eslint/lib/formatters/stylish.js' { + declare module.exports: $Exports<'eslint/lib/formatters/stylish'>; +} +declare module 'eslint/lib/formatters/table.js' { + declare module.exports: $Exports<'eslint/lib/formatters/table'>; +} +declare module 'eslint/lib/formatters/tap.js' { + declare module.exports: $Exports<'eslint/lib/formatters/tap'>; +} +declare module 'eslint/lib/formatters/unix.js' { + declare module.exports: $Exports<'eslint/lib/formatters/unix'>; +} +declare module 'eslint/lib/formatters/visualstudio.js' { + declare module.exports: $Exports<'eslint/lib/formatters/visualstudio'>; +} +declare module 'eslint/lib/ignored-paths.js' { + declare module.exports: $Exports<'eslint/lib/ignored-paths'>; +} +declare module 'eslint/lib/internal-rules/internal-consistent-docs-description.js' { + declare module.exports: $Exports<'eslint/lib/internal-rules/internal-consistent-docs-description'>; +} +declare module 'eslint/lib/internal-rules/internal-no-invalid-meta.js' { + declare module.exports: $Exports<'eslint/lib/internal-rules/internal-no-invalid-meta'>; +} +declare module 'eslint/lib/load-rules.js' { + declare module.exports: $Exports<'eslint/lib/load-rules'>; +} +declare module 'eslint/lib/logging.js' { + declare module.exports: $Exports<'eslint/lib/logging'>; +} +declare module 'eslint/lib/options.js' { + declare module.exports: $Exports<'eslint/lib/options'>; +} +declare module 'eslint/lib/rule-context.js' { + declare module.exports: $Exports<'eslint/lib/rule-context'>; +} +declare module 'eslint/lib/rules.js' { + declare module.exports: $Exports<'eslint/lib/rules'>; +} +declare module 'eslint/lib/rules/accessor-pairs.js' { + declare module.exports: $Exports<'eslint/lib/rules/accessor-pairs'>; +} +declare module 'eslint/lib/rules/array-bracket-spacing.js' { + declare module.exports: $Exports<'eslint/lib/rules/array-bracket-spacing'>; +} +declare module 'eslint/lib/rules/array-callback-return.js' { + declare module.exports: $Exports<'eslint/lib/rules/array-callback-return'>; +} +declare module 'eslint/lib/rules/arrow-body-style.js' { + declare module.exports: $Exports<'eslint/lib/rules/arrow-body-style'>; +} +declare module 'eslint/lib/rules/arrow-parens.js' { + declare module.exports: $Exports<'eslint/lib/rules/arrow-parens'>; +} +declare module 'eslint/lib/rules/arrow-spacing.js' { + declare module.exports: $Exports<'eslint/lib/rules/arrow-spacing'>; +} +declare module 'eslint/lib/rules/block-scoped-var.js' { + declare module.exports: $Exports<'eslint/lib/rules/block-scoped-var'>; +} +declare module 'eslint/lib/rules/block-spacing.js' { + declare module.exports: $Exports<'eslint/lib/rules/block-spacing'>; +} +declare module 'eslint/lib/rules/brace-style.js' { + declare module.exports: $Exports<'eslint/lib/rules/brace-style'>; +} +declare module 'eslint/lib/rules/callback-return.js' { + declare module.exports: $Exports<'eslint/lib/rules/callback-return'>; +} +declare module 'eslint/lib/rules/camelcase.js' { + declare module.exports: $Exports<'eslint/lib/rules/camelcase'>; +} +declare module 'eslint/lib/rules/capitalized-comments.js' { + declare module.exports: $Exports<'eslint/lib/rules/capitalized-comments'>; +} +declare module 'eslint/lib/rules/class-methods-use-this.js' { + declare module.exports: $Exports<'eslint/lib/rules/class-methods-use-this'>; +} +declare module 'eslint/lib/rules/comma-dangle.js' { + declare module.exports: $Exports<'eslint/lib/rules/comma-dangle'>; +} +declare module 'eslint/lib/rules/comma-spacing.js' { + declare module.exports: $Exports<'eslint/lib/rules/comma-spacing'>; +} +declare module 'eslint/lib/rules/comma-style.js' { + declare module.exports: $Exports<'eslint/lib/rules/comma-style'>; +} +declare module 'eslint/lib/rules/complexity.js' { + declare module.exports: $Exports<'eslint/lib/rules/complexity'>; +} +declare module 'eslint/lib/rules/computed-property-spacing.js' { + declare module.exports: $Exports<'eslint/lib/rules/computed-property-spacing'>; +} +declare module 'eslint/lib/rules/consistent-return.js' { + declare module.exports: $Exports<'eslint/lib/rules/consistent-return'>; +} +declare module 'eslint/lib/rules/consistent-this.js' { + declare module.exports: $Exports<'eslint/lib/rules/consistent-this'>; +} +declare module 'eslint/lib/rules/constructor-super.js' { + declare module.exports: $Exports<'eslint/lib/rules/constructor-super'>; +} +declare module 'eslint/lib/rules/curly.js' { + declare module.exports: $Exports<'eslint/lib/rules/curly'>; +} +declare module 'eslint/lib/rules/default-case.js' { + declare module.exports: $Exports<'eslint/lib/rules/default-case'>; +} +declare module 'eslint/lib/rules/dot-location.js' { + declare module.exports: $Exports<'eslint/lib/rules/dot-location'>; +} +declare module 'eslint/lib/rules/dot-notation.js' { + declare module.exports: $Exports<'eslint/lib/rules/dot-notation'>; +} +declare module 'eslint/lib/rules/eol-last.js' { + declare module.exports: $Exports<'eslint/lib/rules/eol-last'>; +} +declare module 'eslint/lib/rules/eqeqeq.js' { + declare module.exports: $Exports<'eslint/lib/rules/eqeqeq'>; +} +declare module 'eslint/lib/rules/func-call-spacing.js' { + declare module.exports: $Exports<'eslint/lib/rules/func-call-spacing'>; +} +declare module 'eslint/lib/rules/func-name-matching.js' { + declare module.exports: $Exports<'eslint/lib/rules/func-name-matching'>; +} +declare module 'eslint/lib/rules/func-names.js' { + declare module.exports: $Exports<'eslint/lib/rules/func-names'>; +} +declare module 'eslint/lib/rules/func-style.js' { + declare module.exports: $Exports<'eslint/lib/rules/func-style'>; +} +declare module 'eslint/lib/rules/generator-star-spacing.js' { + declare module.exports: $Exports<'eslint/lib/rules/generator-star-spacing'>; +} +declare module 'eslint/lib/rules/global-require.js' { + declare module.exports: $Exports<'eslint/lib/rules/global-require'>; +} +declare module 'eslint/lib/rules/guard-for-in.js' { + declare module.exports: $Exports<'eslint/lib/rules/guard-for-in'>; +} +declare module 'eslint/lib/rules/handle-callback-err.js' { + declare module.exports: $Exports<'eslint/lib/rules/handle-callback-err'>; +} +declare module 'eslint/lib/rules/id-blacklist.js' { + declare module.exports: $Exports<'eslint/lib/rules/id-blacklist'>; +} +declare module 'eslint/lib/rules/id-length.js' { + declare module.exports: $Exports<'eslint/lib/rules/id-length'>; +} +declare module 'eslint/lib/rules/id-match.js' { + declare module.exports: $Exports<'eslint/lib/rules/id-match'>; +} +declare module 'eslint/lib/rules/indent.js' { + declare module.exports: $Exports<'eslint/lib/rules/indent'>; +} +declare module 'eslint/lib/rules/init-declarations.js' { + declare module.exports: $Exports<'eslint/lib/rules/init-declarations'>; +} +declare module 'eslint/lib/rules/jsx-quotes.js' { + declare module.exports: $Exports<'eslint/lib/rules/jsx-quotes'>; +} +declare module 'eslint/lib/rules/key-spacing.js' { + declare module.exports: $Exports<'eslint/lib/rules/key-spacing'>; +} +declare module 'eslint/lib/rules/keyword-spacing.js' { + declare module.exports: $Exports<'eslint/lib/rules/keyword-spacing'>; +} +declare module 'eslint/lib/rules/line-comment-position.js' { + declare module.exports: $Exports<'eslint/lib/rules/line-comment-position'>; +} +declare module 'eslint/lib/rules/linebreak-style.js' { + declare module.exports: $Exports<'eslint/lib/rules/linebreak-style'>; +} +declare module 'eslint/lib/rules/lines-around-comment.js' { + declare module.exports: $Exports<'eslint/lib/rules/lines-around-comment'>; +} +declare module 'eslint/lib/rules/lines-around-directive.js' { + declare module.exports: $Exports<'eslint/lib/rules/lines-around-directive'>; +} +declare module 'eslint/lib/rules/max-depth.js' { + declare module.exports: $Exports<'eslint/lib/rules/max-depth'>; +} +declare module 'eslint/lib/rules/max-len.js' { + declare module.exports: $Exports<'eslint/lib/rules/max-len'>; +} +declare module 'eslint/lib/rules/max-lines.js' { + declare module.exports: $Exports<'eslint/lib/rules/max-lines'>; +} +declare module 'eslint/lib/rules/max-nested-callbacks.js' { + declare module.exports: $Exports<'eslint/lib/rules/max-nested-callbacks'>; +} +declare module 'eslint/lib/rules/max-params.js' { + declare module.exports: $Exports<'eslint/lib/rules/max-params'>; +} +declare module 'eslint/lib/rules/max-statements-per-line.js' { + declare module.exports: $Exports<'eslint/lib/rules/max-statements-per-line'>; +} +declare module 'eslint/lib/rules/max-statements.js' { + declare module.exports: $Exports<'eslint/lib/rules/max-statements'>; +} +declare module 'eslint/lib/rules/multiline-ternary.js' { + declare module.exports: $Exports<'eslint/lib/rules/multiline-ternary'>; +} +declare module 'eslint/lib/rules/new-cap.js' { + declare module.exports: $Exports<'eslint/lib/rules/new-cap'>; +} +declare module 'eslint/lib/rules/new-parens.js' { + declare module.exports: $Exports<'eslint/lib/rules/new-parens'>; +} +declare module 'eslint/lib/rules/newline-after-var.js' { + declare module.exports: $Exports<'eslint/lib/rules/newline-after-var'>; +} +declare module 'eslint/lib/rules/newline-before-return.js' { + declare module.exports: $Exports<'eslint/lib/rules/newline-before-return'>; +} +declare module 'eslint/lib/rules/newline-per-chained-call.js' { + declare module.exports: $Exports<'eslint/lib/rules/newline-per-chained-call'>; +} +declare module 'eslint/lib/rules/no-alert.js' { + declare module.exports: $Exports<'eslint/lib/rules/no-alert'>; +} +declare module 'eslint/lib/rules/no-array-constructor.js' { + declare module.exports: $Exports<'eslint/lib/rules/no-array-constructor'>; +} +declare module 'eslint/lib/rules/no-await-in-loop.js' { + declare module.exports: $Exports<'eslint/lib/rules/no-await-in-loop'>; +} +declare module 'eslint/lib/rules/no-bitwise.js' { + declare module.exports: $Exports<'eslint/lib/rules/no-bitwise'>; +} +declare module 'eslint/lib/rules/no-caller.js' { + declare module.exports: $Exports<'eslint/lib/rules/no-caller'>; +} +declare module 'eslint/lib/rules/no-case-declarations.js' { + declare module.exports: $Exports<'eslint/lib/rules/no-case-declarations'>; +} +declare module 'eslint/lib/rules/no-catch-shadow.js' { + declare module.exports: $Exports<'eslint/lib/rules/no-catch-shadow'>; +} +declare module 'eslint/lib/rules/no-class-assign.js' { + declare module.exports: $Exports<'eslint/lib/rules/no-class-assign'>; +} +declare module 'eslint/lib/rules/no-compare-neg-zero.js' { + declare module.exports: $Exports<'eslint/lib/rules/no-compare-neg-zero'>; +} +declare module 'eslint/lib/rules/no-cond-assign.js' { + declare module.exports: $Exports<'eslint/lib/rules/no-cond-assign'>; +} +declare module 'eslint/lib/rules/no-confusing-arrow.js' { + declare module.exports: $Exports<'eslint/lib/rules/no-confusing-arrow'>; +} +declare module 'eslint/lib/rules/no-console.js' { + declare module.exports: $Exports<'eslint/lib/rules/no-console'>; +} +declare module 'eslint/lib/rules/no-const-assign.js' { + declare module.exports: $Exports<'eslint/lib/rules/no-const-assign'>; +} +declare module 'eslint/lib/rules/no-constant-condition.js' { + declare module.exports: $Exports<'eslint/lib/rules/no-constant-condition'>; +} +declare module 'eslint/lib/rules/no-continue.js' { + declare module.exports: $Exports<'eslint/lib/rules/no-continue'>; +} +declare module 'eslint/lib/rules/no-control-regex.js' { + declare module.exports: $Exports<'eslint/lib/rules/no-control-regex'>; +} +declare module 'eslint/lib/rules/no-debugger.js' { + declare module.exports: $Exports<'eslint/lib/rules/no-debugger'>; +} +declare module 'eslint/lib/rules/no-delete-var.js' { + declare module.exports: $Exports<'eslint/lib/rules/no-delete-var'>; +} +declare module 'eslint/lib/rules/no-div-regex.js' { + declare module.exports: $Exports<'eslint/lib/rules/no-div-regex'>; +} +declare module 'eslint/lib/rules/no-dupe-args.js' { + declare module.exports: $Exports<'eslint/lib/rules/no-dupe-args'>; +} +declare module 'eslint/lib/rules/no-dupe-class-members.js' { + declare module.exports: $Exports<'eslint/lib/rules/no-dupe-class-members'>; +} +declare module 'eslint/lib/rules/no-dupe-keys.js' { + declare module.exports: $Exports<'eslint/lib/rules/no-dupe-keys'>; +} +declare module 'eslint/lib/rules/no-duplicate-case.js' { + declare module.exports: $Exports<'eslint/lib/rules/no-duplicate-case'>; +} +declare module 'eslint/lib/rules/no-duplicate-imports.js' { + declare module.exports: $Exports<'eslint/lib/rules/no-duplicate-imports'>; +} +declare module 'eslint/lib/rules/no-else-return.js' { + declare module.exports: $Exports<'eslint/lib/rules/no-else-return'>; +} +declare module 'eslint/lib/rules/no-empty-character-class.js' { + declare module.exports: $Exports<'eslint/lib/rules/no-empty-character-class'>; +} +declare module 'eslint/lib/rules/no-empty-function.js' { + declare module.exports: $Exports<'eslint/lib/rules/no-empty-function'>; +} +declare module 'eslint/lib/rules/no-empty-pattern.js' { + declare module.exports: $Exports<'eslint/lib/rules/no-empty-pattern'>; +} +declare module 'eslint/lib/rules/no-empty.js' { + declare module.exports: $Exports<'eslint/lib/rules/no-empty'>; +} +declare module 'eslint/lib/rules/no-eq-null.js' { + declare module.exports: $Exports<'eslint/lib/rules/no-eq-null'>; +} +declare module 'eslint/lib/rules/no-eval.js' { + declare module.exports: $Exports<'eslint/lib/rules/no-eval'>; +} +declare module 'eslint/lib/rules/no-ex-assign.js' { + declare module.exports: $Exports<'eslint/lib/rules/no-ex-assign'>; +} +declare module 'eslint/lib/rules/no-extend-native.js' { + declare module.exports: $Exports<'eslint/lib/rules/no-extend-native'>; +} +declare module 'eslint/lib/rules/no-extra-bind.js' { + declare module.exports: $Exports<'eslint/lib/rules/no-extra-bind'>; +} +declare module 'eslint/lib/rules/no-extra-boolean-cast.js' { + declare module.exports: $Exports<'eslint/lib/rules/no-extra-boolean-cast'>; +} +declare module 'eslint/lib/rules/no-extra-label.js' { + declare module.exports: $Exports<'eslint/lib/rules/no-extra-label'>; +} +declare module 'eslint/lib/rules/no-extra-parens.js' { + declare module.exports: $Exports<'eslint/lib/rules/no-extra-parens'>; +} +declare module 'eslint/lib/rules/no-extra-semi.js' { + declare module.exports: $Exports<'eslint/lib/rules/no-extra-semi'>; +} +declare module 'eslint/lib/rules/no-fallthrough.js' { + declare module.exports: $Exports<'eslint/lib/rules/no-fallthrough'>; +} +declare module 'eslint/lib/rules/no-floating-decimal.js' { + declare module.exports: $Exports<'eslint/lib/rules/no-floating-decimal'>; +} +declare module 'eslint/lib/rules/no-func-assign.js' { + declare module.exports: $Exports<'eslint/lib/rules/no-func-assign'>; +} +declare module 'eslint/lib/rules/no-global-assign.js' { + declare module.exports: $Exports<'eslint/lib/rules/no-global-assign'>; +} +declare module 'eslint/lib/rules/no-implicit-coercion.js' { + declare module.exports: $Exports<'eslint/lib/rules/no-implicit-coercion'>; +} +declare module 'eslint/lib/rules/no-implicit-globals.js' { + declare module.exports: $Exports<'eslint/lib/rules/no-implicit-globals'>; +} +declare module 'eslint/lib/rules/no-implied-eval.js' { + declare module.exports: $Exports<'eslint/lib/rules/no-implied-eval'>; +} +declare module 'eslint/lib/rules/no-inline-comments.js' { + declare module.exports: $Exports<'eslint/lib/rules/no-inline-comments'>; +} +declare module 'eslint/lib/rules/no-inner-declarations.js' { + declare module.exports: $Exports<'eslint/lib/rules/no-inner-declarations'>; +} +declare module 'eslint/lib/rules/no-invalid-regexp.js' { + declare module.exports: $Exports<'eslint/lib/rules/no-invalid-regexp'>; +} +declare module 'eslint/lib/rules/no-invalid-this.js' { + declare module.exports: $Exports<'eslint/lib/rules/no-invalid-this'>; +} +declare module 'eslint/lib/rules/no-irregular-whitespace.js' { + declare module.exports: $Exports<'eslint/lib/rules/no-irregular-whitespace'>; +} +declare module 'eslint/lib/rules/no-iterator.js' { + declare module.exports: $Exports<'eslint/lib/rules/no-iterator'>; +} +declare module 'eslint/lib/rules/no-label-var.js' { + declare module.exports: $Exports<'eslint/lib/rules/no-label-var'>; +} +declare module 'eslint/lib/rules/no-labels.js' { + declare module.exports: $Exports<'eslint/lib/rules/no-labels'>; +} +declare module 'eslint/lib/rules/no-lone-blocks.js' { + declare module.exports: $Exports<'eslint/lib/rules/no-lone-blocks'>; +} +declare module 'eslint/lib/rules/no-lonely-if.js' { + declare module.exports: $Exports<'eslint/lib/rules/no-lonely-if'>; +} +declare module 'eslint/lib/rules/no-loop-func.js' { + declare module.exports: $Exports<'eslint/lib/rules/no-loop-func'>; +} +declare module 'eslint/lib/rules/no-magic-numbers.js' { + declare module.exports: $Exports<'eslint/lib/rules/no-magic-numbers'>; +} +declare module 'eslint/lib/rules/no-mixed-operators.js' { + declare module.exports: $Exports<'eslint/lib/rules/no-mixed-operators'>; +} +declare module 'eslint/lib/rules/no-mixed-requires.js' { + declare module.exports: $Exports<'eslint/lib/rules/no-mixed-requires'>; +} +declare module 'eslint/lib/rules/no-mixed-spaces-and-tabs.js' { + declare module.exports: $Exports<'eslint/lib/rules/no-mixed-spaces-and-tabs'>; +} +declare module 'eslint/lib/rules/no-multi-assign.js' { + declare module.exports: $Exports<'eslint/lib/rules/no-multi-assign'>; +} +declare module 'eslint/lib/rules/no-multi-spaces.js' { + declare module.exports: $Exports<'eslint/lib/rules/no-multi-spaces'>; +} +declare module 'eslint/lib/rules/no-multi-str.js' { + declare module.exports: $Exports<'eslint/lib/rules/no-multi-str'>; +} +declare module 'eslint/lib/rules/no-multiple-empty-lines.js' { + declare module.exports: $Exports<'eslint/lib/rules/no-multiple-empty-lines'>; +} +declare module 'eslint/lib/rules/no-native-reassign.js' { + declare module.exports: $Exports<'eslint/lib/rules/no-native-reassign'>; +} +declare module 'eslint/lib/rules/no-negated-condition.js' { + declare module.exports: $Exports<'eslint/lib/rules/no-negated-condition'>; +} +declare module 'eslint/lib/rules/no-negated-in-lhs.js' { + declare module.exports: $Exports<'eslint/lib/rules/no-negated-in-lhs'>; +} +declare module 'eslint/lib/rules/no-nested-ternary.js' { + declare module.exports: $Exports<'eslint/lib/rules/no-nested-ternary'>; +} +declare module 'eslint/lib/rules/no-new-func.js' { + declare module.exports: $Exports<'eslint/lib/rules/no-new-func'>; +} +declare module 'eslint/lib/rules/no-new-object.js' { + declare module.exports: $Exports<'eslint/lib/rules/no-new-object'>; +} +declare module 'eslint/lib/rules/no-new-require.js' { + declare module.exports: $Exports<'eslint/lib/rules/no-new-require'>; +} +declare module 'eslint/lib/rules/no-new-symbol.js' { + declare module.exports: $Exports<'eslint/lib/rules/no-new-symbol'>; +} +declare module 'eslint/lib/rules/no-new-wrappers.js' { + declare module.exports: $Exports<'eslint/lib/rules/no-new-wrappers'>; +} +declare module 'eslint/lib/rules/no-new.js' { + declare module.exports: $Exports<'eslint/lib/rules/no-new'>; +} +declare module 'eslint/lib/rules/no-obj-calls.js' { + declare module.exports: $Exports<'eslint/lib/rules/no-obj-calls'>; +} +declare module 'eslint/lib/rules/no-octal-escape.js' { + declare module.exports: $Exports<'eslint/lib/rules/no-octal-escape'>; +} +declare module 'eslint/lib/rules/no-octal.js' { + declare module.exports: $Exports<'eslint/lib/rules/no-octal'>; +} +declare module 'eslint/lib/rules/no-param-reassign.js' { + declare module.exports: $Exports<'eslint/lib/rules/no-param-reassign'>; +} +declare module 'eslint/lib/rules/no-path-concat.js' { + declare module.exports: $Exports<'eslint/lib/rules/no-path-concat'>; +} +declare module 'eslint/lib/rules/no-plusplus.js' { + declare module.exports: $Exports<'eslint/lib/rules/no-plusplus'>; +} +declare module 'eslint/lib/rules/no-process-env.js' { + declare module.exports: $Exports<'eslint/lib/rules/no-process-env'>; +} +declare module 'eslint/lib/rules/no-process-exit.js' { + declare module.exports: $Exports<'eslint/lib/rules/no-process-exit'>; +} +declare module 'eslint/lib/rules/no-proto.js' { + declare module.exports: $Exports<'eslint/lib/rules/no-proto'>; +} +declare module 'eslint/lib/rules/no-prototype-builtins.js' { + declare module.exports: $Exports<'eslint/lib/rules/no-prototype-builtins'>; +} +declare module 'eslint/lib/rules/no-redeclare.js' { + declare module.exports: $Exports<'eslint/lib/rules/no-redeclare'>; +} +declare module 'eslint/lib/rules/no-regex-spaces.js' { + declare module.exports: $Exports<'eslint/lib/rules/no-regex-spaces'>; +} +declare module 'eslint/lib/rules/no-restricted-globals.js' { + declare module.exports: $Exports<'eslint/lib/rules/no-restricted-globals'>; +} +declare module 'eslint/lib/rules/no-restricted-imports.js' { + declare module.exports: $Exports<'eslint/lib/rules/no-restricted-imports'>; +} +declare module 'eslint/lib/rules/no-restricted-modules.js' { + declare module.exports: $Exports<'eslint/lib/rules/no-restricted-modules'>; +} +declare module 'eslint/lib/rules/no-restricted-properties.js' { + declare module.exports: $Exports<'eslint/lib/rules/no-restricted-properties'>; +} +declare module 'eslint/lib/rules/no-restricted-syntax.js' { + declare module.exports: $Exports<'eslint/lib/rules/no-restricted-syntax'>; +} +declare module 'eslint/lib/rules/no-return-assign.js' { + declare module.exports: $Exports<'eslint/lib/rules/no-return-assign'>; +} +declare module 'eslint/lib/rules/no-return-await.js' { + declare module.exports: $Exports<'eslint/lib/rules/no-return-await'>; +} +declare module 'eslint/lib/rules/no-script-url.js' { + declare module.exports: $Exports<'eslint/lib/rules/no-script-url'>; +} +declare module 'eslint/lib/rules/no-self-assign.js' { + declare module.exports: $Exports<'eslint/lib/rules/no-self-assign'>; +} +declare module 'eslint/lib/rules/no-self-compare.js' { + declare module.exports: $Exports<'eslint/lib/rules/no-self-compare'>; +} +declare module 'eslint/lib/rules/no-sequences.js' { + declare module.exports: $Exports<'eslint/lib/rules/no-sequences'>; +} +declare module 'eslint/lib/rules/no-shadow-restricted-names.js' { + declare module.exports: $Exports<'eslint/lib/rules/no-shadow-restricted-names'>; +} +declare module 'eslint/lib/rules/no-shadow.js' { + declare module.exports: $Exports<'eslint/lib/rules/no-shadow'>; +} +declare module 'eslint/lib/rules/no-spaced-func.js' { + declare module.exports: $Exports<'eslint/lib/rules/no-spaced-func'>; +} +declare module 'eslint/lib/rules/no-sparse-arrays.js' { + declare module.exports: $Exports<'eslint/lib/rules/no-sparse-arrays'>; +} +declare module 'eslint/lib/rules/no-sync.js' { + declare module.exports: $Exports<'eslint/lib/rules/no-sync'>; +} +declare module 'eslint/lib/rules/no-tabs.js' { + declare module.exports: $Exports<'eslint/lib/rules/no-tabs'>; +} +declare module 'eslint/lib/rules/no-template-curly-in-string.js' { + declare module.exports: $Exports<'eslint/lib/rules/no-template-curly-in-string'>; +} +declare module 'eslint/lib/rules/no-ternary.js' { + declare module.exports: $Exports<'eslint/lib/rules/no-ternary'>; +} +declare module 'eslint/lib/rules/no-this-before-super.js' { + declare module.exports: $Exports<'eslint/lib/rules/no-this-before-super'>; +} +declare module 'eslint/lib/rules/no-throw-literal.js' { + declare module.exports: $Exports<'eslint/lib/rules/no-throw-literal'>; +} +declare module 'eslint/lib/rules/no-trailing-spaces.js' { + declare module.exports: $Exports<'eslint/lib/rules/no-trailing-spaces'>; +} +declare module 'eslint/lib/rules/no-undef-init.js' { + declare module.exports: $Exports<'eslint/lib/rules/no-undef-init'>; +} +declare module 'eslint/lib/rules/no-undef.js' { + declare module.exports: $Exports<'eslint/lib/rules/no-undef'>; +} +declare module 'eslint/lib/rules/no-undefined.js' { + declare module.exports: $Exports<'eslint/lib/rules/no-undefined'>; +} +declare module 'eslint/lib/rules/no-underscore-dangle.js' { + declare module.exports: $Exports<'eslint/lib/rules/no-underscore-dangle'>; +} +declare module 'eslint/lib/rules/no-unexpected-multiline.js' { + declare module.exports: $Exports<'eslint/lib/rules/no-unexpected-multiline'>; +} +declare module 'eslint/lib/rules/no-unmodified-loop-condition.js' { + declare module.exports: $Exports<'eslint/lib/rules/no-unmodified-loop-condition'>; +} +declare module 'eslint/lib/rules/no-unneeded-ternary.js' { + declare module.exports: $Exports<'eslint/lib/rules/no-unneeded-ternary'>; +} +declare module 'eslint/lib/rules/no-unreachable.js' { + declare module.exports: $Exports<'eslint/lib/rules/no-unreachable'>; +} +declare module 'eslint/lib/rules/no-unsafe-finally.js' { + declare module.exports: $Exports<'eslint/lib/rules/no-unsafe-finally'>; +} +declare module 'eslint/lib/rules/no-unsafe-negation.js' { + declare module.exports: $Exports<'eslint/lib/rules/no-unsafe-negation'>; +} +declare module 'eslint/lib/rules/no-unused-expressions.js' { + declare module.exports: $Exports<'eslint/lib/rules/no-unused-expressions'>; +} +declare module 'eslint/lib/rules/no-unused-labels.js' { + declare module.exports: $Exports<'eslint/lib/rules/no-unused-labels'>; +} +declare module 'eslint/lib/rules/no-unused-vars.js' { + declare module.exports: $Exports<'eslint/lib/rules/no-unused-vars'>; +} +declare module 'eslint/lib/rules/no-use-before-define.js' { + declare module.exports: $Exports<'eslint/lib/rules/no-use-before-define'>; +} +declare module 'eslint/lib/rules/no-useless-call.js' { + declare module.exports: $Exports<'eslint/lib/rules/no-useless-call'>; +} +declare module 'eslint/lib/rules/no-useless-computed-key.js' { + declare module.exports: $Exports<'eslint/lib/rules/no-useless-computed-key'>; +} +declare module 'eslint/lib/rules/no-useless-concat.js' { + declare module.exports: $Exports<'eslint/lib/rules/no-useless-concat'>; +} +declare module 'eslint/lib/rules/no-useless-constructor.js' { + declare module.exports: $Exports<'eslint/lib/rules/no-useless-constructor'>; +} +declare module 'eslint/lib/rules/no-useless-escape.js' { + declare module.exports: $Exports<'eslint/lib/rules/no-useless-escape'>; +} +declare module 'eslint/lib/rules/no-useless-rename.js' { + declare module.exports: $Exports<'eslint/lib/rules/no-useless-rename'>; +} +declare module 'eslint/lib/rules/no-useless-return.js' { + declare module.exports: $Exports<'eslint/lib/rules/no-useless-return'>; +} +declare module 'eslint/lib/rules/no-var.js' { + declare module.exports: $Exports<'eslint/lib/rules/no-var'>; +} +declare module 'eslint/lib/rules/no-void.js' { + declare module.exports: $Exports<'eslint/lib/rules/no-void'>; +} +declare module 'eslint/lib/rules/no-warning-comments.js' { + declare module.exports: $Exports<'eslint/lib/rules/no-warning-comments'>; +} +declare module 'eslint/lib/rules/no-whitespace-before-property.js' { + declare module.exports: $Exports<'eslint/lib/rules/no-whitespace-before-property'>; +} +declare module 'eslint/lib/rules/no-with.js' { + declare module.exports: $Exports<'eslint/lib/rules/no-with'>; +} +declare module 'eslint/lib/rules/nonblock-statement-body-position.js' { + declare module.exports: $Exports<'eslint/lib/rules/nonblock-statement-body-position'>; +} +declare module 'eslint/lib/rules/object-curly-newline.js' { + declare module.exports: $Exports<'eslint/lib/rules/object-curly-newline'>; +} +declare module 'eslint/lib/rules/object-curly-spacing.js' { + declare module.exports: $Exports<'eslint/lib/rules/object-curly-spacing'>; +} +declare module 'eslint/lib/rules/object-property-newline.js' { + declare module.exports: $Exports<'eslint/lib/rules/object-property-newline'>; +} +declare module 'eslint/lib/rules/object-shorthand.js' { + declare module.exports: $Exports<'eslint/lib/rules/object-shorthand'>; +} +declare module 'eslint/lib/rules/one-var-declaration-per-line.js' { + declare module.exports: $Exports<'eslint/lib/rules/one-var-declaration-per-line'>; +} +declare module 'eslint/lib/rules/one-var.js' { + declare module.exports: $Exports<'eslint/lib/rules/one-var'>; +} +declare module 'eslint/lib/rules/operator-assignment.js' { + declare module.exports: $Exports<'eslint/lib/rules/operator-assignment'>; +} +declare module 'eslint/lib/rules/operator-linebreak.js' { + declare module.exports: $Exports<'eslint/lib/rules/operator-linebreak'>; +} +declare module 'eslint/lib/rules/padded-blocks.js' { + declare module.exports: $Exports<'eslint/lib/rules/padded-blocks'>; +} +declare module 'eslint/lib/rules/prefer-arrow-callback.js' { + declare module.exports: $Exports<'eslint/lib/rules/prefer-arrow-callback'>; +} +declare module 'eslint/lib/rules/prefer-const.js' { + declare module.exports: $Exports<'eslint/lib/rules/prefer-const'>; +} +declare module 'eslint/lib/rules/prefer-destructuring.js' { + declare module.exports: $Exports<'eslint/lib/rules/prefer-destructuring'>; +} +declare module 'eslint/lib/rules/prefer-numeric-literals.js' { + declare module.exports: $Exports<'eslint/lib/rules/prefer-numeric-literals'>; +} +declare module 'eslint/lib/rules/prefer-promise-reject-errors.js' { + declare module.exports: $Exports<'eslint/lib/rules/prefer-promise-reject-errors'>; +} +declare module 'eslint/lib/rules/prefer-reflect.js' { + declare module.exports: $Exports<'eslint/lib/rules/prefer-reflect'>; +} +declare module 'eslint/lib/rules/prefer-rest-params.js' { + declare module.exports: $Exports<'eslint/lib/rules/prefer-rest-params'>; +} +declare module 'eslint/lib/rules/prefer-spread.js' { + declare module.exports: $Exports<'eslint/lib/rules/prefer-spread'>; +} +declare module 'eslint/lib/rules/prefer-template.js' { + declare module.exports: $Exports<'eslint/lib/rules/prefer-template'>; +} +declare module 'eslint/lib/rules/quote-props.js' { + declare module.exports: $Exports<'eslint/lib/rules/quote-props'>; +} +declare module 'eslint/lib/rules/quotes.js' { + declare module.exports: $Exports<'eslint/lib/rules/quotes'>; +} +declare module 'eslint/lib/rules/radix.js' { + declare module.exports: $Exports<'eslint/lib/rules/radix'>; +} +declare module 'eslint/lib/rules/require-await.js' { + declare module.exports: $Exports<'eslint/lib/rules/require-await'>; +} +declare module 'eslint/lib/rules/require-jsdoc.js' { + declare module.exports: $Exports<'eslint/lib/rules/require-jsdoc'>; +} +declare module 'eslint/lib/rules/require-yield.js' { + declare module.exports: $Exports<'eslint/lib/rules/require-yield'>; +} +declare module 'eslint/lib/rules/rest-spread-spacing.js' { + declare module.exports: $Exports<'eslint/lib/rules/rest-spread-spacing'>; +} +declare module 'eslint/lib/rules/semi-spacing.js' { + declare module.exports: $Exports<'eslint/lib/rules/semi-spacing'>; +} +declare module 'eslint/lib/rules/semi.js' { + declare module.exports: $Exports<'eslint/lib/rules/semi'>; +} +declare module 'eslint/lib/rules/sort-imports.js' { + declare module.exports: $Exports<'eslint/lib/rules/sort-imports'>; +} +declare module 'eslint/lib/rules/sort-keys.js' { + declare module.exports: $Exports<'eslint/lib/rules/sort-keys'>; +} +declare module 'eslint/lib/rules/sort-vars.js' { + declare module.exports: $Exports<'eslint/lib/rules/sort-vars'>; +} +declare module 'eslint/lib/rules/space-before-blocks.js' { + declare module.exports: $Exports<'eslint/lib/rules/space-before-blocks'>; +} +declare module 'eslint/lib/rules/space-before-function-paren.js' { + declare module.exports: $Exports<'eslint/lib/rules/space-before-function-paren'>; +} +declare module 'eslint/lib/rules/space-in-parens.js' { + declare module.exports: $Exports<'eslint/lib/rules/space-in-parens'>; +} +declare module 'eslint/lib/rules/space-infix-ops.js' { + declare module.exports: $Exports<'eslint/lib/rules/space-infix-ops'>; +} +declare module 'eslint/lib/rules/space-unary-ops.js' { + declare module.exports: $Exports<'eslint/lib/rules/space-unary-ops'>; +} +declare module 'eslint/lib/rules/spaced-comment.js' { + declare module.exports: $Exports<'eslint/lib/rules/spaced-comment'>; +} +declare module 'eslint/lib/rules/strict.js' { + declare module.exports: $Exports<'eslint/lib/rules/strict'>; +} +declare module 'eslint/lib/rules/symbol-description.js' { + declare module.exports: $Exports<'eslint/lib/rules/symbol-description'>; +} +declare module 'eslint/lib/rules/template-curly-spacing.js' { + declare module.exports: $Exports<'eslint/lib/rules/template-curly-spacing'>; +} +declare module 'eslint/lib/rules/template-tag-spacing.js' { + declare module.exports: $Exports<'eslint/lib/rules/template-tag-spacing'>; +} +declare module 'eslint/lib/rules/unicode-bom.js' { + declare module.exports: $Exports<'eslint/lib/rules/unicode-bom'>; +} +declare module 'eslint/lib/rules/use-isnan.js' { + declare module.exports: $Exports<'eslint/lib/rules/use-isnan'>; +} +declare module 'eslint/lib/rules/valid-jsdoc.js' { + declare module.exports: $Exports<'eslint/lib/rules/valid-jsdoc'>; +} +declare module 'eslint/lib/rules/valid-typeof.js' { + declare module.exports: $Exports<'eslint/lib/rules/valid-typeof'>; +} +declare module 'eslint/lib/rules/vars-on-top.js' { + declare module.exports: $Exports<'eslint/lib/rules/vars-on-top'>; +} +declare module 'eslint/lib/rules/wrap-iife.js' { + declare module.exports: $Exports<'eslint/lib/rules/wrap-iife'>; +} +declare module 'eslint/lib/rules/wrap-regex.js' { + declare module.exports: $Exports<'eslint/lib/rules/wrap-regex'>; +} +declare module 'eslint/lib/rules/yield-star-spacing.js' { + declare module.exports: $Exports<'eslint/lib/rules/yield-star-spacing'>; +} +declare module 'eslint/lib/rules/yoda.js' { + declare module.exports: $Exports<'eslint/lib/rules/yoda'>; +} +declare module 'eslint/lib/testers/event-generator-tester.js' { + declare module.exports: $Exports<'eslint/lib/testers/event-generator-tester'>; +} +declare module 'eslint/lib/testers/rule-tester.js' { + declare module.exports: $Exports<'eslint/lib/testers/rule-tester'>; +} +declare module 'eslint/lib/timing.js' { + declare module.exports: $Exports<'eslint/lib/timing'>; +} +declare module 'eslint/lib/token-store/backward-token-comment-cursor.js' { + declare module.exports: $Exports<'eslint/lib/token-store/backward-token-comment-cursor'>; +} +declare module 'eslint/lib/token-store/backward-token-cursor.js' { + declare module.exports: $Exports<'eslint/lib/token-store/backward-token-cursor'>; +} +declare module 'eslint/lib/token-store/cursor.js' { + declare module.exports: $Exports<'eslint/lib/token-store/cursor'>; +} +declare module 'eslint/lib/token-store/cursors.js' { + declare module.exports: $Exports<'eslint/lib/token-store/cursors'>; +} +declare module 'eslint/lib/token-store/decorative-cursor.js' { + declare module.exports: $Exports<'eslint/lib/token-store/decorative-cursor'>; +} +declare module 'eslint/lib/token-store/filter-cursor.js' { + declare module.exports: $Exports<'eslint/lib/token-store/filter-cursor'>; +} +declare module 'eslint/lib/token-store/forward-token-comment-cursor.js' { + declare module.exports: $Exports<'eslint/lib/token-store/forward-token-comment-cursor'>; +} +declare module 'eslint/lib/token-store/forward-token-cursor.js' { + declare module.exports: $Exports<'eslint/lib/token-store/forward-token-cursor'>; +} +declare module 'eslint/lib/token-store/index.js' { + declare module.exports: $Exports<'eslint/lib/token-store/index'>; +} +declare module 'eslint/lib/token-store/limit-cursor.js' { + declare module.exports: $Exports<'eslint/lib/token-store/limit-cursor'>; +} +declare module 'eslint/lib/token-store/padded-token-cursor.js' { + declare module.exports: $Exports<'eslint/lib/token-store/padded-token-cursor'>; +} +declare module 'eslint/lib/token-store/skip-cursor.js' { + declare module.exports: $Exports<'eslint/lib/token-store/skip-cursor'>; +} +declare module 'eslint/lib/token-store/utils.js' { + declare module.exports: $Exports<'eslint/lib/token-store/utils'>; +} +declare module 'eslint/lib/util/comment-event-generator.js' { + declare module.exports: $Exports<'eslint/lib/util/comment-event-generator'>; +} +declare module 'eslint/lib/util/fix-tracker.js' { + declare module.exports: $Exports<'eslint/lib/util/fix-tracker'>; +} +declare module 'eslint/lib/util/glob-util.js' { + declare module.exports: $Exports<'eslint/lib/util/glob-util'>; +} +declare module 'eslint/lib/util/glob.js' { + declare module.exports: $Exports<'eslint/lib/util/glob'>; +} +declare module 'eslint/lib/util/hash.js' { + declare module.exports: $Exports<'eslint/lib/util/hash'>; +} +declare module 'eslint/lib/util/keywords.js' { + declare module.exports: $Exports<'eslint/lib/util/keywords'>; +} +declare module 'eslint/lib/util/module-resolver.js' { + declare module.exports: $Exports<'eslint/lib/util/module-resolver'>; +} +declare module 'eslint/lib/util/node-event-generator.js' { + declare module.exports: $Exports<'eslint/lib/util/node-event-generator'>; +} +declare module 'eslint/lib/util/npm-util.js' { + declare module.exports: $Exports<'eslint/lib/util/npm-util'>; +} +declare module 'eslint/lib/util/path-util.js' { + declare module.exports: $Exports<'eslint/lib/util/path-util'>; +} +declare module 'eslint/lib/util/patterns/letters.js' { + declare module.exports: $Exports<'eslint/lib/util/patterns/letters'>; +} +declare module 'eslint/lib/util/rule-fixer.js' { + declare module.exports: $Exports<'eslint/lib/util/rule-fixer'>; +} +declare module 'eslint/lib/util/source-code-fixer.js' { + declare module.exports: $Exports<'eslint/lib/util/source-code-fixer'>; +} +declare module 'eslint/lib/util/source-code-util.js' { + declare module.exports: $Exports<'eslint/lib/util/source-code-util'>; +} +declare module 'eslint/lib/util/source-code.js' { + declare module.exports: $Exports<'eslint/lib/util/source-code'>; +} +declare module 'eslint/lib/util/traverser.js' { + declare module.exports: $Exports<'eslint/lib/util/traverser'>; +} +declare module 'eslint/lib/util/xml-escape.js' { + declare module.exports: $Exports<'eslint/lib/util/xml-escape'>; +} diff --git a/flow-typed/npm/express_v4.x.x.js b/flow-typed/npm/express_v4.x.x.js new file mode 100644 index 000000000..82e05800e --- /dev/null +++ b/flow-typed/npm/express_v4.x.x.js @@ -0,0 +1,207 @@ +// flow-typed signature: f0e399a136d6e8dc8b1fbdc078e2850c +// flow-typed version: ed397013d1/express_v4.x.x/flow_>=v0.32.x + +import type { Server } from 'http'; +import type { Socket } from 'net'; + +declare type express$RouterOptions = { + caseSensitive?: boolean, + mergeParams?: boolean, + strict?: boolean +}; + +declare class express$RequestResponseBase { + app: express$Application; + get(field: string): string | void; +} + +declare type express$RequestParams = { + [param: string]: string +} + +declare class express$Request extends http$IncomingMessage mixins express$RequestResponseBase { + baseUrl: string; + body: any; + cookies: {[cookie: string]: string}; + connection: Socket; + fresh: boolean; + hostname: string; + ip: string; + ips: Array; + method: string; + originalUrl: string; + params: express$RequestParams; + path: string; + protocol: 'https' | 'http'; + query: {[name: string]: string | Array}; + route: string; + secure: boolean; + signedCookies: {[signedCookie: string]: string}; + stale: boolean; + subdomains: Array; + xhr: boolean; + accepts(types: string): string | false; + accepts(types: Array): string | false; + acceptsCharsets(...charsets: Array): string | false; + acceptsEncodings(...encoding: Array): string | false; + acceptsLanguages(...lang: Array): string | false; + header(field: string): string | void; + is(type: string): boolean; + param(name: string, defaultValue?: string): string | void; +} + +declare type express$CookieOptions = { + domain?: string, + encode?: (value: string) => string, + expires?: Date, + httpOnly?: boolean, + maxAge?: number, + path?: string, + secure?: boolean, + signed?: boolean +}; + +declare type express$Path = string | RegExp; + +declare type express$RenderCallback = (err: Error | null, html?: string) => mixed; + +declare type express$SendFileOptions = { + maxAge?: number, + root?: string, + lastModified?: boolean, + headers?: {[name: string]: string}, + dotfiles?: 'allow' | 'deny' | 'ignore' +}; + +declare class express$Response extends http$ServerResponse mixins express$RequestResponseBase { + headersSent: boolean; + locals: {[name: string]: mixed}; + append(field: string, value?: string): this; + attachment(filename?: string): this; + cookie(name: string, value: string, options?: express$CookieOptions): this; + clearCookie(name: string, options?: express$CookieOptions): this; + download(path: string, filename?: string, callback?: (err?: ?Error) => void): this; + format(typesObject: {[type: string]: Function}): this; + json(body?: mixed): this; + jsonp(body?: mixed): this; + links(links: {[name: string]: string}): this; + location(path: string): this; + redirect(url: string, ...args: Array): this; + redirect(status: number, url: string, ...args: Array): this; + render(view: string, locals?: {[name: string]: mixed}, callback?: express$RenderCallback): this; + send(body?: mixed): this; + sendFile(path: string, options?: express$SendFileOptions, callback?: (err?: ?Error) => mixed): this; + sendStatus(statusCode: number): this; + header(field: string, value?: string): this; + header(headers: {[name: string]: string}): this; + set(field: string, value?: string|string[]): this; + set(headers: {[name: string]: string}): this; + status(statusCode: number): this; + type(type: string): this; + vary(field: string): this; + req: express$Request; +} + +declare type express$NextFunction = (err?: ?Error | 'route') => mixed; +declare type express$Middleware = + ((req: $Subtype, res: express$Response, next: express$NextFunction) => mixed) | + ((error: Error, req: $Subtype, res: express$Response, next: express$NextFunction) => mixed); +declare interface express$RouteMethodType { + (middleware: express$Middleware): T; + (...middleware: Array): T; + (path: express$Path|express$Path[], ...middleware: Array): T; +} +declare class express$Route { + all: express$RouteMethodType; + get: express$RouteMethodType; + post: express$RouteMethodType; + put: express$RouteMethodType; + head: express$RouteMethodType; + delete: express$RouteMethodType; + options: express$RouteMethodType; + trace: express$RouteMethodType; + copy: express$RouteMethodType; + lock: express$RouteMethodType; + mkcol: express$RouteMethodType; + move: express$RouteMethodType; + purge: express$RouteMethodType; + propfind: express$RouteMethodType; + proppatch: express$RouteMethodType; + unlock: express$RouteMethodType; + report: express$RouteMethodType; + mkactivity: express$RouteMethodType; + checkout: express$RouteMethodType; + merge: express$RouteMethodType; + + // @TODO Missing 'm-search' but get flow illegal name error. + + notify: express$RouteMethodType; + subscribe: express$RouteMethodType; + unsubscribe: express$RouteMethodType; + patch: express$RouteMethodType; + search: express$RouteMethodType; + connect: express$RouteMethodType; +} + +declare class express$Router extends express$Route { + constructor(options?: express$RouterOptions): void; + route(path: string): express$Route; + static (options?: express$RouterOptions): express$Router; + use(middleware: express$Middleware): this; + use(...middleware: Array): this; + use(path: express$Path|express$Path[], ...middleware: Array): this; + use(path: string, router: express$Router): this; + handle(req: http$IncomingMessage, res: http$ServerResponse, next: express$NextFunction): void; + param( + param: string, + callback: ( + req: $Subtype, + res: express$Response, + next: express$NextFunction, + id: string + ) => mixed + ): void; + + // Can't use regular callable signature syntax due to https://github.com/facebook/flow/issues/3084 + $call: (req: http$IncomingMessage, res: http$ServerResponse, next?: ?express$NextFunction) => void; +} + +declare class express$Application extends express$Router mixins events$EventEmitter { + constructor(): void; + locals: {[name: string]: mixed}; + mountpath: string; + listen(port: number, hostname?: string, backlog?: number, callback?: (err?: ?Error) => mixed): Server; + listen(port: number, hostname?: string, callback?: (err?: ?Error) => mixed): Server; + listen(port: number, callback?: (err?: ?Error) => mixed): Server; + listen(path: string, callback?: (err?: ?Error) => mixed): Server; + listen(handle: Object, callback?: (err?: ?Error) => mixed): Server; + disable(name: string): void; + disabled(name: string): boolean; + enable(name: string): express$Application; + enabled(name: string): boolean; + engine(name: string, callback: Function): void; + /** + * Mixed will not be taken as a value option. Issue around using the GET http method name and the get for settings. + */ + // get(name: string): mixed; + set(name: string, value: mixed): mixed; + render(name: string, optionsOrFunction: {[name: string]: mixed}, callback: express$RenderCallback): void; + handle(req: http$IncomingMessage, res: http$ServerResponse, next?: ?express$NextFunction): void; +} + +declare module 'express' { + declare export type RouterOptions = express$RouterOptions; + declare export type CookieOptions = express$CookieOptions; + declare export type Middleware = express$Middleware; + declare export type NextFunction = express$NextFunction; + declare export type RequestParams = express$RequestParams; + declare export type $Response = express$Response; + declare export type $Request = express$Request; + declare export type $Application = express$Application; + + declare module.exports: { + (): express$Application, // If you try to call like a function, it will use this signature + static: (root: string, options?: Object) => express$Middleware, // `static` property on the function + Router: typeof express$Router, // `Router` property on the function + }; +} diff --git a/flow-typed/npm/flow-bin_v0.x.x.js b/flow-typed/npm/flow-bin_v0.x.x.js new file mode 100644 index 000000000..c538e2086 --- /dev/null +++ b/flow-typed/npm/flow-bin_v0.x.x.js @@ -0,0 +1,6 @@ +// flow-typed signature: 6a5610678d4b01e13bbfbbc62bdaf583 +// flow-typed version: 3817bc6980/flow-bin_v0.x.x/flow_>=v0.25.x + +declare module "flow-bin" { + declare module.exports: string; +} diff --git a/flow-typed/npm/fs-extra_vx.x.x.js b/flow-typed/npm/fs-extra_vx.x.x.js new file mode 100644 index 000000000..5606e57dd --- /dev/null +++ b/flow-typed/npm/fs-extra_vx.x.x.js @@ -0,0 +1,235 @@ +// flow-typed signature: 334664ea61c80495e1e70186a29a5fa7 +// flow-typed version: <>/fs-extra_v5.x.x/flow_v0.59.0 + +/** + * This is an autogenerated libdef stub for: + * + * 'fs-extra' + * + * Fill this stub out by replacing all the `any` types. + * + * Once filled out, we encourage you to share your work with the + * community by sending a pull request to: + * https://github.com/flowtype/flow-typed + */ + +declare module 'fs-extra' { + declare module.exports: any; +} + +/** + * We include stubs for each file inside this npm package in case you need to + * require those files directly. Feel free to delete any files that aren't + * needed. + */ +declare module 'fs-extra/lib/copy-sync/copy-sync' { + declare module.exports: any; +} + +declare module 'fs-extra/lib/copy-sync/index' { + declare module.exports: any; +} + +declare module 'fs-extra/lib/copy/copy' { + declare module.exports: any; +} + +declare module 'fs-extra/lib/copy/index' { + declare module.exports: any; +} + +declare module 'fs-extra/lib/empty/index' { + declare module.exports: any; +} + +declare module 'fs-extra/lib/ensure/file' { + declare module.exports: any; +} + +declare module 'fs-extra/lib/ensure/index' { + declare module.exports: any; +} + +declare module 'fs-extra/lib/ensure/link' { + declare module.exports: any; +} + +declare module 'fs-extra/lib/ensure/symlink-paths' { + declare module.exports: any; +} + +declare module 'fs-extra/lib/ensure/symlink-type' { + declare module.exports: any; +} + +declare module 'fs-extra/lib/ensure/symlink' { + declare module.exports: any; +} + +declare module 'fs-extra/lib/fs/index' { + declare module.exports: any; +} + +declare module 'fs-extra/lib/index' { + declare module.exports: any; +} + +declare module 'fs-extra/lib/json/index' { + declare module.exports: any; +} + +declare module 'fs-extra/lib/json/jsonfile' { + declare module.exports: any; +} + +declare module 'fs-extra/lib/json/output-json-sync' { + declare module.exports: any; +} + +declare module 'fs-extra/lib/json/output-json' { + declare module.exports: any; +} + +declare module 'fs-extra/lib/mkdirs/index' { + declare module.exports: any; +} + +declare module 'fs-extra/lib/mkdirs/mkdirs-sync' { + declare module.exports: any; +} + +declare module 'fs-extra/lib/mkdirs/mkdirs' { + declare module.exports: any; +} + +declare module 'fs-extra/lib/mkdirs/win32' { + declare module.exports: any; +} + +declare module 'fs-extra/lib/move-sync/index' { + declare module.exports: any; +} + +declare module 'fs-extra/lib/move/index' { + declare module.exports: any; +} + +declare module 'fs-extra/lib/output/index' { + declare module.exports: any; +} + +declare module 'fs-extra/lib/path-exists/index' { + declare module.exports: any; +} + +declare module 'fs-extra/lib/remove/index' { + declare module.exports: any; +} + +declare module 'fs-extra/lib/remove/rimraf' { + declare module.exports: any; +} + +declare module 'fs-extra/lib/util/assign' { + declare module.exports: any; +} + +declare module 'fs-extra/lib/util/buffer' { + declare module.exports: any; +} + +declare module 'fs-extra/lib/util/utimes' { + declare module.exports: any; +} + +// Filename aliases +declare module 'fs-extra/lib/copy-sync/copy-sync.js' { + declare module.exports: $Exports<'fs-extra/lib/copy-sync/copy-sync'>; +} +declare module 'fs-extra/lib/copy-sync/index.js' { + declare module.exports: $Exports<'fs-extra/lib/copy-sync/index'>; +} +declare module 'fs-extra/lib/copy/copy.js' { + declare module.exports: $Exports<'fs-extra/lib/copy/copy'>; +} +declare module 'fs-extra/lib/copy/index.js' { + declare module.exports: $Exports<'fs-extra/lib/copy/index'>; +} +declare module 'fs-extra/lib/empty/index.js' { + declare module.exports: $Exports<'fs-extra/lib/empty/index'>; +} +declare module 'fs-extra/lib/ensure/file.js' { + declare module.exports: $Exports<'fs-extra/lib/ensure/file'>; +} +declare module 'fs-extra/lib/ensure/index.js' { + declare module.exports: $Exports<'fs-extra/lib/ensure/index'>; +} +declare module 'fs-extra/lib/ensure/link.js' { + declare module.exports: $Exports<'fs-extra/lib/ensure/link'>; +} +declare module 'fs-extra/lib/ensure/symlink-paths.js' { + declare module.exports: $Exports<'fs-extra/lib/ensure/symlink-paths'>; +} +declare module 'fs-extra/lib/ensure/symlink-type.js' { + declare module.exports: $Exports<'fs-extra/lib/ensure/symlink-type'>; +} +declare module 'fs-extra/lib/ensure/symlink.js' { + declare module.exports: $Exports<'fs-extra/lib/ensure/symlink'>; +} +declare module 'fs-extra/lib/fs/index.js' { + declare module.exports: $Exports<'fs-extra/lib/fs/index'>; +} +declare module 'fs-extra/lib/index.js' { + declare module.exports: $Exports<'fs-extra/lib/index'>; +} +declare module 'fs-extra/lib/json/index.js' { + declare module.exports: $Exports<'fs-extra/lib/json/index'>; +} +declare module 'fs-extra/lib/json/jsonfile.js' { + declare module.exports: $Exports<'fs-extra/lib/json/jsonfile'>; +} +declare module 'fs-extra/lib/json/output-json-sync.js' { + declare module.exports: $Exports<'fs-extra/lib/json/output-json-sync'>; +} +declare module 'fs-extra/lib/json/output-json.js' { + declare module.exports: $Exports<'fs-extra/lib/json/output-json'>; +} +declare module 'fs-extra/lib/mkdirs/index.js' { + declare module.exports: $Exports<'fs-extra/lib/mkdirs/index'>; +} +declare module 'fs-extra/lib/mkdirs/mkdirs-sync.js' { + declare module.exports: $Exports<'fs-extra/lib/mkdirs/mkdirs-sync'>; +} +declare module 'fs-extra/lib/mkdirs/mkdirs.js' { + declare module.exports: $Exports<'fs-extra/lib/mkdirs/mkdirs'>; +} +declare module 'fs-extra/lib/mkdirs/win32.js' { + declare module.exports: $Exports<'fs-extra/lib/mkdirs/win32'>; +} +declare module 'fs-extra/lib/move-sync/index.js' { + declare module.exports: $Exports<'fs-extra/lib/move-sync/index'>; +} +declare module 'fs-extra/lib/move/index.js' { + declare module.exports: $Exports<'fs-extra/lib/move/index'>; +} +declare module 'fs-extra/lib/output/index.js' { + declare module.exports: $Exports<'fs-extra/lib/output/index'>; +} +declare module 'fs-extra/lib/path-exists/index.js' { + declare module.exports: $Exports<'fs-extra/lib/path-exists/index'>; +} +declare module 'fs-extra/lib/remove/index.js' { + declare module.exports: $Exports<'fs-extra/lib/remove/index'>; +} +declare module 'fs-extra/lib/remove/rimraf.js' { + declare module.exports: $Exports<'fs-extra/lib/remove/rimraf'>; +} +declare module 'fs-extra/lib/util/assign.js' { + declare module.exports: $Exports<'fs-extra/lib/util/assign'>; +} +declare module 'fs-extra/lib/util/buffer.js' { + declare module.exports: $Exports<'fs-extra/lib/util/buffer'>; +} +declare module 'fs-extra/lib/util/utimes.js' { + declare module.exports: $Exports<'fs-extra/lib/util/utimes'>; +} diff --git a/flow-typed/npm/graphiql_vx.x.x.js b/flow-typed/npm/graphiql_vx.x.x.js new file mode 100644 index 000000000..cdcee38bd --- /dev/null +++ b/flow-typed/npm/graphiql_vx.x.x.js @@ -0,0 +1,277 @@ +// flow-typed signature: 69ddad32e70eb9e1eb79e7ce2017117b +// flow-typed version: <>/graphiql_v0.11.10/flow_v0.59.0 + +/** + * This is an autogenerated libdef stub for: + * + * 'graphiql' + * + * Fill this stub out by replacing all the `any` types. + * + * Once filled out, we encourage you to share your work with the + * community by sending a pull request to: + * https://github.com/flowtype/flow-typed + */ + +declare module 'graphiql' { + declare module.exports: any; +} + +/** + * We include stubs for each file inside this npm package in case you need to + * require those files directly. Feel free to delete any files that aren't + * needed. + */ +declare module 'graphiql/dist/components/DocExplorer' { + declare module.exports: any; +} + +declare module 'graphiql/dist/components/DocExplorer/Argument' { + declare module.exports: any; +} + +declare module 'graphiql/dist/components/DocExplorer/DefaultValue' { + declare module.exports: any; +} + +declare module 'graphiql/dist/components/DocExplorer/FieldDoc' { + declare module.exports: any; +} + +declare module 'graphiql/dist/components/DocExplorer/MarkdownContent' { + declare module.exports: any; +} + +declare module 'graphiql/dist/components/DocExplorer/SchemaDoc' { + declare module.exports: any; +} + +declare module 'graphiql/dist/components/DocExplorer/SearchBox' { + declare module.exports: any; +} + +declare module 'graphiql/dist/components/DocExplorer/SearchResults' { + declare module.exports: any; +} + +declare module 'graphiql/dist/components/DocExplorer/TypeDoc' { + declare module.exports: any; +} + +declare module 'graphiql/dist/components/DocExplorer/TypeLink' { + declare module.exports: any; +} + +declare module 'graphiql/dist/components/ExecuteButton' { + declare module.exports: any; +} + +declare module 'graphiql/dist/components/GraphiQL' { + declare module.exports: any; +} + +declare module 'graphiql/dist/components/HistoryQuery' { + declare module.exports: any; +} + +declare module 'graphiql/dist/components/QueryEditor' { + declare module.exports: any; +} + +declare module 'graphiql/dist/components/QueryHistory' { + declare module.exports: any; +} + +declare module 'graphiql/dist/components/ResultViewer' { + declare module.exports: any; +} + +declare module 'graphiql/dist/components/ToolbarButton' { + declare module.exports: any; +} + +declare module 'graphiql/dist/components/ToolbarGroup' { + declare module.exports: any; +} + +declare module 'graphiql/dist/components/ToolbarMenu' { + declare module.exports: any; +} + +declare module 'graphiql/dist/components/ToolbarSelect' { + declare module.exports: any; +} + +declare module 'graphiql/dist/components/VariableEditor' { + declare module.exports: any; +} + +declare module 'graphiql/dist/index' { + declare module.exports: any; +} + +declare module 'graphiql/dist/utility/CodeMirrorSizer' { + declare module.exports: any; +} + +declare module 'graphiql/dist/utility/debounce' { + declare module.exports: any; +} + +declare module 'graphiql/dist/utility/elementPosition' { + declare module.exports: any; +} + +declare module 'graphiql/dist/utility/fillLeafs' { + declare module.exports: any; +} + +declare module 'graphiql/dist/utility/find' { + declare module.exports: any; +} + +declare module 'graphiql/dist/utility/getQueryFacts' { + declare module.exports: any; +} + +declare module 'graphiql/dist/utility/getSelectedOperationName' { + declare module.exports: any; +} + +declare module 'graphiql/dist/utility/introspectionQueries' { + declare module.exports: any; +} + +declare module 'graphiql/dist/utility/normalizeWhitespace' { + declare module.exports: any; +} + +declare module 'graphiql/dist/utility/onHasCompletion' { + declare module.exports: any; +} + +declare module 'graphiql/dist/utility/QueryStore' { + declare module.exports: any; +} + +declare module 'graphiql/dist/utility/StorageAPI' { + declare module.exports: any; +} + +declare module 'graphiql/graphiql' { + declare module.exports: any; +} + +declare module 'graphiql/graphiql.min' { + declare module.exports: any; +} + +// Filename aliases +declare module 'graphiql/dist/components/DocExplorer.js' { + declare module.exports: $Exports<'graphiql/dist/components/DocExplorer'>; +} +declare module 'graphiql/dist/components/DocExplorer/Argument.js' { + declare module.exports: $Exports<'graphiql/dist/components/DocExplorer/Argument'>; +} +declare module 'graphiql/dist/components/DocExplorer/DefaultValue.js' { + declare module.exports: $Exports<'graphiql/dist/components/DocExplorer/DefaultValue'>; +} +declare module 'graphiql/dist/components/DocExplorer/FieldDoc.js' { + declare module.exports: $Exports<'graphiql/dist/components/DocExplorer/FieldDoc'>; +} +declare module 'graphiql/dist/components/DocExplorer/MarkdownContent.js' { + declare module.exports: $Exports<'graphiql/dist/components/DocExplorer/MarkdownContent'>; +} +declare module 'graphiql/dist/components/DocExplorer/SchemaDoc.js' { + declare module.exports: $Exports<'graphiql/dist/components/DocExplorer/SchemaDoc'>; +} +declare module 'graphiql/dist/components/DocExplorer/SearchBox.js' { + declare module.exports: $Exports<'graphiql/dist/components/DocExplorer/SearchBox'>; +} +declare module 'graphiql/dist/components/DocExplorer/SearchResults.js' { + declare module.exports: $Exports<'graphiql/dist/components/DocExplorer/SearchResults'>; +} +declare module 'graphiql/dist/components/DocExplorer/TypeDoc.js' { + declare module.exports: $Exports<'graphiql/dist/components/DocExplorer/TypeDoc'>; +} +declare module 'graphiql/dist/components/DocExplorer/TypeLink.js' { + declare module.exports: $Exports<'graphiql/dist/components/DocExplorer/TypeLink'>; +} +declare module 'graphiql/dist/components/ExecuteButton.js' { + declare module.exports: $Exports<'graphiql/dist/components/ExecuteButton'>; +} +declare module 'graphiql/dist/components/GraphiQL.js' { + declare module.exports: $Exports<'graphiql/dist/components/GraphiQL'>; +} +declare module 'graphiql/dist/components/HistoryQuery.js' { + declare module.exports: $Exports<'graphiql/dist/components/HistoryQuery'>; +} +declare module 'graphiql/dist/components/QueryEditor.js' { + declare module.exports: $Exports<'graphiql/dist/components/QueryEditor'>; +} +declare module 'graphiql/dist/components/QueryHistory.js' { + declare module.exports: $Exports<'graphiql/dist/components/QueryHistory'>; +} +declare module 'graphiql/dist/components/ResultViewer.js' { + declare module.exports: $Exports<'graphiql/dist/components/ResultViewer'>; +} +declare module 'graphiql/dist/components/ToolbarButton.js' { + declare module.exports: $Exports<'graphiql/dist/components/ToolbarButton'>; +} +declare module 'graphiql/dist/components/ToolbarGroup.js' { + declare module.exports: $Exports<'graphiql/dist/components/ToolbarGroup'>; +} +declare module 'graphiql/dist/components/ToolbarMenu.js' { + declare module.exports: $Exports<'graphiql/dist/components/ToolbarMenu'>; +} +declare module 'graphiql/dist/components/ToolbarSelect.js' { + declare module.exports: $Exports<'graphiql/dist/components/ToolbarSelect'>; +} +declare module 'graphiql/dist/components/VariableEditor.js' { + declare module.exports: $Exports<'graphiql/dist/components/VariableEditor'>; +} +declare module 'graphiql/dist/index.js' { + declare module.exports: $Exports<'graphiql/dist/index'>; +} +declare module 'graphiql/dist/utility/CodeMirrorSizer.js' { + declare module.exports: $Exports<'graphiql/dist/utility/CodeMirrorSizer'>; +} +declare module 'graphiql/dist/utility/debounce.js' { + declare module.exports: $Exports<'graphiql/dist/utility/debounce'>; +} +declare module 'graphiql/dist/utility/elementPosition.js' { + declare module.exports: $Exports<'graphiql/dist/utility/elementPosition'>; +} +declare module 'graphiql/dist/utility/fillLeafs.js' { + declare module.exports: $Exports<'graphiql/dist/utility/fillLeafs'>; +} +declare module 'graphiql/dist/utility/find.js' { + declare module.exports: $Exports<'graphiql/dist/utility/find'>; +} +declare module 'graphiql/dist/utility/getQueryFacts.js' { + declare module.exports: $Exports<'graphiql/dist/utility/getQueryFacts'>; +} +declare module 'graphiql/dist/utility/getSelectedOperationName.js' { + declare module.exports: $Exports<'graphiql/dist/utility/getSelectedOperationName'>; +} +declare module 'graphiql/dist/utility/introspectionQueries.js' { + declare module.exports: $Exports<'graphiql/dist/utility/introspectionQueries'>; +} +declare module 'graphiql/dist/utility/normalizeWhitespace.js' { + declare module.exports: $Exports<'graphiql/dist/utility/normalizeWhitespace'>; +} +declare module 'graphiql/dist/utility/onHasCompletion.js' { + declare module.exports: $Exports<'graphiql/dist/utility/onHasCompletion'>; +} +declare module 'graphiql/dist/utility/QueryStore.js' { + declare module.exports: $Exports<'graphiql/dist/utility/QueryStore'>; +} +declare module 'graphiql/dist/utility/StorageAPI.js' { + declare module.exports: $Exports<'graphiql/dist/utility/StorageAPI'>; +} +declare module 'graphiql/graphiql.js' { + declare module.exports: $Exports<'graphiql/graphiql'>; +} +declare module 'graphiql/graphiql.min.js' { + declare module.exports: $Exports<'graphiql/graphiql.min'>; +} diff --git a/flow-typed/npm/graphql_vx.x.x.js b/flow-typed/npm/graphql_vx.x.x.js new file mode 100644 index 000000000..3326b36cd --- /dev/null +++ b/flow-typed/npm/graphql_vx.x.x.js @@ -0,0 +1,633 @@ +// flow-typed signature: 78a3b0630930ae254dcef08544af115d +// flow-typed version: <>/graphql_v^0.11.7/flow_v0.59.0 + +/** + * This is an autogenerated libdef stub for: + * + * 'graphql' + * + * Fill this stub out by replacing all the `any` types. + * + * Once filled out, we encourage you to share your work with the + * community by sending a pull request to: + * https://github.com/flowtype/flow-typed + */ + +declare module 'graphql' { + declare module.exports: any; +} + +/** + * We include stubs for each file inside this npm package in case you need to + * require those files directly. Feel free to delete any files that aren't + * needed. + */ +declare module 'graphql/error/formatError' { + declare module.exports: any; +} + +declare module 'graphql/error/GraphQLError' { + declare module.exports: any; +} + +declare module 'graphql/error/index' { + declare module.exports: any; +} + +declare module 'graphql/error/locatedError' { + declare module.exports: any; +} + +declare module 'graphql/error/syntaxError' { + declare module.exports: any; +} + +declare module 'graphql/execution/execute' { + declare module.exports: any; +} + +declare module 'graphql/execution/index' { + declare module.exports: any; +} + +declare module 'graphql/execution/values' { + declare module.exports: any; +} + +declare module 'graphql/graphql' { + declare module.exports: any; +} + +declare module 'graphql/jsutils/dedent' { + declare module.exports: any; +} + +declare module 'graphql/jsutils/find' { + declare module.exports: any; +} + +declare module 'graphql/jsutils/invariant' { + declare module.exports: any; +} + +declare module 'graphql/jsutils/isInvalid' { + declare module.exports: any; +} + +declare module 'graphql/jsutils/isNullish' { + declare module.exports: any; +} + +declare module 'graphql/jsutils/keyMap' { + declare module.exports: any; +} + +declare module 'graphql/jsutils/keyValMap' { + declare module.exports: any; +} + +declare module 'graphql/jsutils/ObjMap' { + declare module.exports: any; +} + +declare module 'graphql/jsutils/quotedOrList' { + declare module.exports: any; +} + +declare module 'graphql/jsutils/suggestionList' { + declare module.exports: any; +} + +declare module 'graphql/language/ast' { + declare module.exports: any; +} + +declare module 'graphql/language/index' { + declare module.exports: any; +} + +declare module 'graphql/language/kinds' { + declare module.exports: any; +} + +declare module 'graphql/language/lexer' { + declare module.exports: any; +} + +declare module 'graphql/language/location' { + declare module.exports: any; +} + +declare module 'graphql/language/parser' { + declare module.exports: any; +} + +declare module 'graphql/language/printer' { + declare module.exports: any; +} + +declare module 'graphql/language/source' { + declare module.exports: any; +} + +declare module 'graphql/language/visitor' { + declare module.exports: any; +} + +declare module 'graphql/subscription/asyncIteratorReject' { + declare module.exports: any; +} + +declare module 'graphql/subscription/index' { + declare module.exports: any; +} + +declare module 'graphql/subscription/mapAsyncIterator' { + declare module.exports: any; +} + +declare module 'graphql/subscription/subscribe' { + declare module.exports: any; +} + +declare module 'graphql/type/definition' { + declare module.exports: any; +} + +declare module 'graphql/type/directives' { + declare module.exports: any; +} + +declare module 'graphql/type/index' { + declare module.exports: any; +} + +declare module 'graphql/type/introspection' { + declare module.exports: any; +} + +declare module 'graphql/type/scalars' { + declare module.exports: any; +} + +declare module 'graphql/type/schema' { + declare module.exports: any; +} + +declare module 'graphql/utilities/assertValidName' { + declare module.exports: any; +} + +declare module 'graphql/utilities/astFromValue' { + declare module.exports: any; +} + +declare module 'graphql/utilities/buildASTSchema' { + declare module.exports: any; +} + +declare module 'graphql/utilities/buildClientSchema' { + declare module.exports: any; +} + +declare module 'graphql/utilities/concatAST' { + declare module.exports: any; +} + +declare module 'graphql/utilities/extendSchema' { + declare module.exports: any; +} + +declare module 'graphql/utilities/findBreakingChanges' { + declare module.exports: any; +} + +declare module 'graphql/utilities/findDeprecatedUsages' { + declare module.exports: any; +} + +declare module 'graphql/utilities/getOperationAST' { + declare module.exports: any; +} + +declare module 'graphql/utilities/index' { + declare module.exports: any; +} + +declare module 'graphql/utilities/introspectionQuery' { + declare module.exports: any; +} + +declare module 'graphql/utilities/isValidJSValue' { + declare module.exports: any; +} + +declare module 'graphql/utilities/isValidLiteralValue' { + declare module.exports: any; +} + +declare module 'graphql/utilities/schemaPrinter' { + declare module.exports: any; +} + +declare module 'graphql/utilities/separateOperations' { + declare module.exports: any; +} + +declare module 'graphql/utilities/typeComparators' { + declare module.exports: any; +} + +declare module 'graphql/utilities/typeFromAST' { + declare module.exports: any; +} + +declare module 'graphql/utilities/TypeInfo' { + declare module.exports: any; +} + +declare module 'graphql/utilities/valueFromAST' { + declare module.exports: any; +} + +declare module 'graphql/validation/index' { + declare module.exports: any; +} + +declare module 'graphql/validation/rules/ArgumentsOfCorrectType' { + declare module.exports: any; +} + +declare module 'graphql/validation/rules/DefaultValuesOfCorrectType' { + declare module.exports: any; +} + +declare module 'graphql/validation/rules/FieldsOnCorrectType' { + declare module.exports: any; +} + +declare module 'graphql/validation/rules/FragmentsOnCompositeTypes' { + declare module.exports: any; +} + +declare module 'graphql/validation/rules/KnownArgumentNames' { + declare module.exports: any; +} + +declare module 'graphql/validation/rules/KnownDirectives' { + declare module.exports: any; +} + +declare module 'graphql/validation/rules/KnownFragmentNames' { + declare module.exports: any; +} + +declare module 'graphql/validation/rules/KnownTypeNames' { + declare module.exports: any; +} + +declare module 'graphql/validation/rules/LoneAnonymousOperation' { + declare module.exports: any; +} + +declare module 'graphql/validation/rules/NoFragmentCycles' { + declare module.exports: any; +} + +declare module 'graphql/validation/rules/NoUndefinedVariables' { + declare module.exports: any; +} + +declare module 'graphql/validation/rules/NoUnusedFragments' { + declare module.exports: any; +} + +declare module 'graphql/validation/rules/NoUnusedVariables' { + declare module.exports: any; +} + +declare module 'graphql/validation/rules/OverlappingFieldsCanBeMerged' { + declare module.exports: any; +} + +declare module 'graphql/validation/rules/PossibleFragmentSpreads' { + declare module.exports: any; +} + +declare module 'graphql/validation/rules/ProvidedNonNullArguments' { + declare module.exports: any; +} + +declare module 'graphql/validation/rules/ScalarLeafs' { + declare module.exports: any; +} + +declare module 'graphql/validation/rules/SingleFieldSubscriptions' { + declare module.exports: any; +} + +declare module 'graphql/validation/rules/UniqueArgumentNames' { + declare module.exports: any; +} + +declare module 'graphql/validation/rules/UniqueDirectivesPerLocation' { + declare module.exports: any; +} + +declare module 'graphql/validation/rules/UniqueFragmentNames' { + declare module.exports: any; +} + +declare module 'graphql/validation/rules/UniqueInputFieldNames' { + declare module.exports: any; +} + +declare module 'graphql/validation/rules/UniqueOperationNames' { + declare module.exports: any; +} + +declare module 'graphql/validation/rules/UniqueVariableNames' { + declare module.exports: any; +} + +declare module 'graphql/validation/rules/VariablesAreInputTypes' { + declare module.exports: any; +} + +declare module 'graphql/validation/rules/VariablesInAllowedPosition' { + declare module.exports: any; +} + +declare module 'graphql/validation/specifiedRules' { + declare module.exports: any; +} + +declare module 'graphql/validation/validate' { + declare module.exports: any; +} + +// Filename aliases +declare module 'graphql/error/formatError.js' { + declare module.exports: $Exports<'graphql/error/formatError'>; +} +declare module 'graphql/error/GraphQLError.js' { + declare module.exports: $Exports<'graphql/error/GraphQLError'>; +} +declare module 'graphql/error/index.js' { + declare module.exports: $Exports<'graphql/error/index'>; +} +declare module 'graphql/error/locatedError.js' { + declare module.exports: $Exports<'graphql/error/locatedError'>; +} +declare module 'graphql/error/syntaxError.js' { + declare module.exports: $Exports<'graphql/error/syntaxError'>; +} +declare module 'graphql/execution/execute.js' { + declare module.exports: $Exports<'graphql/execution/execute'>; +} +declare module 'graphql/execution/index.js' { + declare module.exports: $Exports<'graphql/execution/index'>; +} +declare module 'graphql/execution/values.js' { + declare module.exports: $Exports<'graphql/execution/values'>; +} +declare module 'graphql/graphql.js' { + declare module.exports: $Exports<'graphql/graphql'>; +} +declare module 'graphql/index' { + declare module.exports: $Exports<'graphql'>; +} +declare module 'graphql/index.js' { + declare module.exports: $Exports<'graphql'>; +} +declare module 'graphql/jsutils/dedent.js' { + declare module.exports: $Exports<'graphql/jsutils/dedent'>; +} +declare module 'graphql/jsutils/find.js' { + declare module.exports: $Exports<'graphql/jsutils/find'>; +} +declare module 'graphql/jsutils/invariant.js' { + declare module.exports: $Exports<'graphql/jsutils/invariant'>; +} +declare module 'graphql/jsutils/isInvalid.js' { + declare module.exports: $Exports<'graphql/jsutils/isInvalid'>; +} +declare module 'graphql/jsutils/isNullish.js' { + declare module.exports: $Exports<'graphql/jsutils/isNullish'>; +} +declare module 'graphql/jsutils/keyMap.js' { + declare module.exports: $Exports<'graphql/jsutils/keyMap'>; +} +declare module 'graphql/jsutils/keyValMap.js' { + declare module.exports: $Exports<'graphql/jsutils/keyValMap'>; +} +declare module 'graphql/jsutils/ObjMap.js' { + declare module.exports: $Exports<'graphql/jsutils/ObjMap'>; +} +declare module 'graphql/jsutils/quotedOrList.js' { + declare module.exports: $Exports<'graphql/jsutils/quotedOrList'>; +} +declare module 'graphql/jsutils/suggestionList.js' { + declare module.exports: $Exports<'graphql/jsutils/suggestionList'>; +} +declare module 'graphql/language/ast.js' { + declare module.exports: $Exports<'graphql/language/ast'>; +} +declare module 'graphql/language/index.js' { + declare module.exports: $Exports<'graphql/language/index'>; +} +declare module 'graphql/language/kinds.js' { + declare module.exports: $Exports<'graphql/language/kinds'>; +} +declare module 'graphql/language/lexer.js' { + declare module.exports: $Exports<'graphql/language/lexer'>; +} +declare module 'graphql/language/location.js' { + declare module.exports: $Exports<'graphql/language/location'>; +} +declare module 'graphql/language/parser.js' { + declare module.exports: $Exports<'graphql/language/parser'>; +} +declare module 'graphql/language/printer.js' { + declare module.exports: $Exports<'graphql/language/printer'>; +} +declare module 'graphql/language/source.js' { + declare module.exports: $Exports<'graphql/language/source'>; +} +declare module 'graphql/language/visitor.js' { + declare module.exports: $Exports<'graphql/language/visitor'>; +} +declare module 'graphql/subscription/asyncIteratorReject.js' { + declare module.exports: $Exports<'graphql/subscription/asyncIteratorReject'>; +} +declare module 'graphql/subscription/index.js' { + declare module.exports: $Exports<'graphql/subscription/index'>; +} +declare module 'graphql/subscription/mapAsyncIterator.js' { + declare module.exports: $Exports<'graphql/subscription/mapAsyncIterator'>; +} +declare module 'graphql/subscription/subscribe.js' { + declare module.exports: $Exports<'graphql/subscription/subscribe'>; +} +declare module 'graphql/type/definition.js' { + declare module.exports: $Exports<'graphql/type/definition'>; +} +declare module 'graphql/type/directives.js' { + declare module.exports: $Exports<'graphql/type/directives'>; +} +declare module 'graphql/type/index.js' { + declare module.exports: $Exports<'graphql/type/index'>; +} +declare module 'graphql/type/introspection.js' { + declare module.exports: $Exports<'graphql/type/introspection'>; +} +declare module 'graphql/type/scalars.js' { + declare module.exports: $Exports<'graphql/type/scalars'>; +} +declare module 'graphql/type/schema.js' { + declare module.exports: $Exports<'graphql/type/schema'>; +} +declare module 'graphql/utilities/assertValidName.js' { + declare module.exports: $Exports<'graphql/utilities/assertValidName'>; +} +declare module 'graphql/utilities/astFromValue.js' { + declare module.exports: $Exports<'graphql/utilities/astFromValue'>; +} +declare module 'graphql/utilities/buildASTSchema.js' { + declare module.exports: $Exports<'graphql/utilities/buildASTSchema'>; +} +declare module 'graphql/utilities/buildClientSchema.js' { + declare module.exports: $Exports<'graphql/utilities/buildClientSchema'>; +} +declare module 'graphql/utilities/concatAST.js' { + declare module.exports: $Exports<'graphql/utilities/concatAST'>; +} +declare module 'graphql/utilities/extendSchema.js' { + declare module.exports: $Exports<'graphql/utilities/extendSchema'>; +} +declare module 'graphql/utilities/findBreakingChanges.js' { + declare module.exports: $Exports<'graphql/utilities/findBreakingChanges'>; +} +declare module 'graphql/utilities/findDeprecatedUsages.js' { + declare module.exports: $Exports<'graphql/utilities/findDeprecatedUsages'>; +} +declare module 'graphql/utilities/getOperationAST.js' { + declare module.exports: $Exports<'graphql/utilities/getOperationAST'>; +} +declare module 'graphql/utilities/index.js' { + declare module.exports: $Exports<'graphql/utilities/index'>; +} +declare module 'graphql/utilities/introspectionQuery.js' { + declare module.exports: $Exports<'graphql/utilities/introspectionQuery'>; +} +declare module 'graphql/utilities/isValidJSValue.js' { + declare module.exports: $Exports<'graphql/utilities/isValidJSValue'>; +} +declare module 'graphql/utilities/isValidLiteralValue.js' { + declare module.exports: $Exports<'graphql/utilities/isValidLiteralValue'>; +} +declare module 'graphql/utilities/schemaPrinter.js' { + declare module.exports: $Exports<'graphql/utilities/schemaPrinter'>; +} +declare module 'graphql/utilities/separateOperations.js' { + declare module.exports: $Exports<'graphql/utilities/separateOperations'>; +} +declare module 'graphql/utilities/typeComparators.js' { + declare module.exports: $Exports<'graphql/utilities/typeComparators'>; +} +declare module 'graphql/utilities/typeFromAST.js' { + declare module.exports: $Exports<'graphql/utilities/typeFromAST'>; +} +declare module 'graphql/utilities/TypeInfo.js' { + declare module.exports: $Exports<'graphql/utilities/TypeInfo'>; +} +declare module 'graphql/utilities/valueFromAST.js' { + declare module.exports: $Exports<'graphql/utilities/valueFromAST'>; +} +declare module 'graphql/validation/index.js' { + declare module.exports: $Exports<'graphql/validation/index'>; +} +declare module 'graphql/validation/rules/ArgumentsOfCorrectType.js' { + declare module.exports: $Exports<'graphql/validation/rules/ArgumentsOfCorrectType'>; +} +declare module 'graphql/validation/rules/DefaultValuesOfCorrectType.js' { + declare module.exports: $Exports<'graphql/validation/rules/DefaultValuesOfCorrectType'>; +} +declare module 'graphql/validation/rules/FieldsOnCorrectType.js' { + declare module.exports: $Exports<'graphql/validation/rules/FieldsOnCorrectType'>; +} +declare module 'graphql/validation/rules/FragmentsOnCompositeTypes.js' { + declare module.exports: $Exports<'graphql/validation/rules/FragmentsOnCompositeTypes'>; +} +declare module 'graphql/validation/rules/KnownArgumentNames.js' { + declare module.exports: $Exports<'graphql/validation/rules/KnownArgumentNames'>; +} +declare module 'graphql/validation/rules/KnownDirectives.js' { + declare module.exports: $Exports<'graphql/validation/rules/KnownDirectives'>; +} +declare module 'graphql/validation/rules/KnownFragmentNames.js' { + declare module.exports: $Exports<'graphql/validation/rules/KnownFragmentNames'>; +} +declare module 'graphql/validation/rules/KnownTypeNames.js' { + declare module.exports: $Exports<'graphql/validation/rules/KnownTypeNames'>; +} +declare module 'graphql/validation/rules/LoneAnonymousOperation.js' { + declare module.exports: $Exports<'graphql/validation/rules/LoneAnonymousOperation'>; +} +declare module 'graphql/validation/rules/NoFragmentCycles.js' { + declare module.exports: $Exports<'graphql/validation/rules/NoFragmentCycles'>; +} +declare module 'graphql/validation/rules/NoUndefinedVariables.js' { + declare module.exports: $Exports<'graphql/validation/rules/NoUndefinedVariables'>; +} +declare module 'graphql/validation/rules/NoUnusedFragments.js' { + declare module.exports: $Exports<'graphql/validation/rules/NoUnusedFragments'>; +} +declare module 'graphql/validation/rules/NoUnusedVariables.js' { + declare module.exports: $Exports<'graphql/validation/rules/NoUnusedVariables'>; +} +declare module 'graphql/validation/rules/OverlappingFieldsCanBeMerged.js' { + declare module.exports: $Exports<'graphql/validation/rules/OverlappingFieldsCanBeMerged'>; +} +declare module 'graphql/validation/rules/PossibleFragmentSpreads.js' { + declare module.exports: $Exports<'graphql/validation/rules/PossibleFragmentSpreads'>; +} +declare module 'graphql/validation/rules/ProvidedNonNullArguments.js' { + declare module.exports: $Exports<'graphql/validation/rules/ProvidedNonNullArguments'>; +} +declare module 'graphql/validation/rules/ScalarLeafs.js' { + declare module.exports: $Exports<'graphql/validation/rules/ScalarLeafs'>; +} +declare module 'graphql/validation/rules/SingleFieldSubscriptions.js' { + declare module.exports: $Exports<'graphql/validation/rules/SingleFieldSubscriptions'>; +} +declare module 'graphql/validation/rules/UniqueArgumentNames.js' { + declare module.exports: $Exports<'graphql/validation/rules/UniqueArgumentNames'>; +} +declare module 'graphql/validation/rules/UniqueDirectivesPerLocation.js' { + declare module.exports: $Exports<'graphql/validation/rules/UniqueDirectivesPerLocation'>; +} +declare module 'graphql/validation/rules/UniqueFragmentNames.js' { + declare module.exports: $Exports<'graphql/validation/rules/UniqueFragmentNames'>; +} +declare module 'graphql/validation/rules/UniqueInputFieldNames.js' { + declare module.exports: $Exports<'graphql/validation/rules/UniqueInputFieldNames'>; +} +declare module 'graphql/validation/rules/UniqueOperationNames.js' { + declare module.exports: $Exports<'graphql/validation/rules/UniqueOperationNames'>; +} +declare module 'graphql/validation/rules/UniqueVariableNames.js' { + declare module.exports: $Exports<'graphql/validation/rules/UniqueVariableNames'>; +} +declare module 'graphql/validation/rules/VariablesAreInputTypes.js' { + declare module.exports: $Exports<'graphql/validation/rules/VariablesAreInputTypes'>; +} +declare module 'graphql/validation/rules/VariablesInAllowedPosition.js' { + declare module.exports: $Exports<'graphql/validation/rules/VariablesInAllowedPosition'>; +} +declare module 'graphql/validation/specifiedRules.js' { + declare module.exports: $Exports<'graphql/validation/specifiedRules'>; +} +declare module 'graphql/validation/validate.js' { + declare module.exports: $Exports<'graphql/validation/validate'>; +} diff --git a/flow-typed/npm/invariant_v2.x.x.js b/flow-typed/npm/invariant_v2.x.x.js new file mode 100644 index 000000000..2b5894bdd --- /dev/null +++ b/flow-typed/npm/invariant_v2.x.x.js @@ -0,0 +1,6 @@ +// flow-typed signature: 41a21b97ad4a7c01c4caf3a8b9382354 +// flow-typed version: b43dff3e0e/invariant_v2.x.x/flow_>=v0.33.x + +declare module invariant { + declare var exports: (condition: boolean, message: string) => void; +} diff --git a/flow-typed/npm/jest_v21.x.x.js b/flow-typed/npm/jest_v21.x.x.js new file mode 100644 index 000000000..daaeda70e --- /dev/null +++ b/flow-typed/npm/jest_v21.x.x.js @@ -0,0 +1,584 @@ +// flow-typed signature: 107cf7068b8835594e97f938e8848244 +// flow-typed version: 8b4dd96654/jest_v21.x.x/flow_>=v0.39.x + +type JestMockFn, TReturn> = { + (...args: TArguments): TReturn, + /** + * An object for introspecting mock calls + */ + mock: { + /** + * An array that represents all calls that have been made into this mock + * function. Each call is represented by an array of arguments that were + * passed during the call. + */ + calls: Array, + /** + * An array that contains all the object instances that have been + * instantiated from this mock function. + */ + instances: Array + }, + /** + * Resets all information stored in the mockFn.mock.calls and + * mockFn.mock.instances arrays. Often this is useful when you want to clean + * up a mock's usage data between two assertions. + */ + mockClear(): void, + /** + * Resets all information stored in the mock. This is useful when you want to + * completely restore a mock back to its initial state. + */ + mockReset(): void, + /** + * Removes the mock and restores the initial implementation. This is useful + * when you want to mock functions in certain test cases and restore the + * original implementation in others. Beware that mockFn.mockRestore only + * works when mock was created with jest.spyOn. Thus you have to take care of + * restoration yourself when manually assigning jest.fn(). + */ + mockRestore(): void, + /** + * Accepts a function that should be used as the implementation of the mock. + * The mock itself will still record all calls that go into and instances + * that come from itself -- the only difference is that the implementation + * will also be executed when the mock is called. + */ + mockImplementation( + fn: (...args: TArguments) => TReturn + ): JestMockFn, + /** + * Accepts a function that will be used as an implementation of the mock for + * one call to the mocked function. Can be chained so that multiple function + * calls produce different results. + */ + mockImplementationOnce( + fn: (...args: TArguments) => TReturn + ): JestMockFn, + /** + * Just a simple sugar function for returning `this` + */ + mockReturnThis(): void, + /** + * Deprecated: use jest.fn(() => value) instead + */ + mockReturnValue(value: TReturn): JestMockFn, + /** + * Sugar for only returning a value once inside your mock + */ + mockReturnValueOnce(value: TReturn): JestMockFn +}; + +type JestAsymmetricEqualityType = { + /** + * A custom Jasmine equality tester + */ + asymmetricMatch(value: mixed): boolean +}; + +type JestCallsType = { + allArgs(): mixed, + all(): mixed, + any(): boolean, + count(): number, + first(): mixed, + mostRecent(): mixed, + reset(): void +}; + +type JestClockType = { + install(): void, + mockDate(date: Date): void, + tick(milliseconds?: number): void, + uninstall(): void +}; + +type JestMatcherResult = { + message?: string | (() => string), + pass: boolean +}; + +type JestMatcher = (actual: any, expected: any) => JestMatcherResult; + +type JestPromiseType = { + /** + * Use rejects to unwrap the reason of a rejected promise so any other + * matcher can be chained. If the promise is fulfilled the assertion fails. + */ + rejects: JestExpectType, + /** + * Use resolves to unwrap the value of a fulfilled promise so any other + * matcher can be chained. If the promise is rejected the assertion fails. + */ + resolves: JestExpectType +}; + +/** + * Plugin: jest-enzyme + */ +type EnzymeMatchersType = { + toBeChecked(): void, + toBeDisabled(): void, + toBeEmpty(): void, + toBePresent(): void, + toContainReact(element: React$Element): void, + toHaveClassName(className: string): void, + toHaveHTML(html: string): void, + toHaveProp(propKey: string, propValue?: any): void, + toHaveRef(refName: string): void, + toHaveState(stateKey: string, stateValue?: any): void, + toHaveStyle(styleKey: string, styleValue?: any): void, + toHaveTagName(tagName: string): void, + toHaveText(text: string): void, + toIncludeText(text: string): void, + toHaveValue(value: any): void, + toMatchElement(element: React$Element): void, + toMatchSelector(selector: string): void +}; + +type JestExpectType = { + not: JestExpectType & EnzymeMatchersType, + /** + * If you have a mock function, you can use .lastCalledWith to test what + * arguments it was last called with. + */ + lastCalledWith(...args: Array): void, + /** + * toBe just checks that a value is what you expect. It uses === to check + * strict equality. + */ + toBe(value: any): void, + /** + * Use .toHaveBeenCalled to ensure that a mock function got called. + */ + toBeCalled(): void, + /** + * Use .toBeCalledWith to ensure that a mock function was called with + * specific arguments. + */ + toBeCalledWith(...args: Array): void, + /** + * Using exact equality with floating point numbers is a bad idea. Rounding + * means that intuitive things fail. + */ + toBeCloseTo(num: number, delta: any): void, + /** + * Use .toBeDefined to check that a variable is not undefined. + */ + toBeDefined(): void, + /** + * Use .toBeFalsy when you don't care what a value is, you just want to + * ensure a value is false in a boolean context. + */ + toBeFalsy(): void, + /** + * To compare floating point numbers, you can use toBeGreaterThan. + */ + toBeGreaterThan(number: number): void, + /** + * To compare floating point numbers, you can use toBeGreaterThanOrEqual. + */ + toBeGreaterThanOrEqual(number: number): void, + /** + * To compare floating point numbers, you can use toBeLessThan. + */ + toBeLessThan(number: number): void, + /** + * To compare floating point numbers, you can use toBeLessThanOrEqual. + */ + toBeLessThanOrEqual(number: number): void, + /** + * Use .toBeInstanceOf(Class) to check that an object is an instance of a + * class. + */ + toBeInstanceOf(cls: Class<*>): void, + /** + * .toBeNull() is the same as .toBe(null) but the error messages are a bit + * nicer. + */ + toBeNull(): void, + /** + * Use .toBeTruthy when you don't care what a value is, you just want to + * ensure a value is true in a boolean context. + */ + toBeTruthy(): void, + /** + * Use .toBeUndefined to check that a variable is undefined. + */ + toBeUndefined(): void, + /** + * Use .toContain when you want to check that an item is in a list. For + * testing the items in the list, this uses ===, a strict equality check. + */ + toContain(item: any): void, + /** + * Use .toContainEqual when you want to check that an item is in a list. For + * testing the items in the list, this matcher recursively checks the + * equality of all fields, rather than checking for object identity. + */ + toContainEqual(item: any): void, + /** + * Use .toEqual when you want to check that two objects have the same value. + * This matcher recursively checks the equality of all fields, rather than + * checking for object identity. + */ + toEqual(value: any): void, + /** + * Use .toHaveBeenCalled to ensure that a mock function got called. + */ + toHaveBeenCalled(): void, + /** + * Use .toHaveBeenCalledTimes to ensure that a mock function got called exact + * number of times. + */ + toHaveBeenCalledTimes(number: number): void, + /** + * Use .toHaveBeenCalledWith to ensure that a mock function was called with + * specific arguments. + */ + toHaveBeenCalledWith(...args: Array): void, + /** + * Use .toHaveBeenLastCalledWith to ensure that a mock function was last called + * with specific arguments. + */ + toHaveBeenLastCalledWith(...args: Array): void, + /** + * Check that an object has a .length property and it is set to a certain + * numeric value. + */ + toHaveLength(number: number): void, + /** + * + */ + toHaveProperty(propPath: string, value?: any): void, + /** + * Use .toMatch to check that a string matches a regular expression or string. + */ + toMatch(regexpOrString: RegExp | string): void, + /** + * Use .toMatchObject to check that a javascript object matches a subset of the properties of an object. + */ + toMatchObject(object: Object | Array): void, + /** + * This ensures that a React component matches the most recent snapshot. + */ + toMatchSnapshot(name?: string): void, + /** + * Use .toThrow to test that a function throws when it is called. + * If you want to test that a specific error gets thrown, you can provide an + * argument to toThrow. The argument can be a string for the error message, + * a class for the error, or a regex that should match the error. + * + * Alias: .toThrowError + */ + toThrow(message?: string | Error | Class | RegExp): void, + toThrowError(message?: string | Error | Class | RegExp): void, + /** + * Use .toThrowErrorMatchingSnapshot to test that a function throws a error + * matching the most recent snapshot when it is called. + */ + toThrowErrorMatchingSnapshot(): void +}; + +type JestObjectType = { + /** + * Disables automatic mocking in the module loader. + * + * After this method is called, all `require()`s will return the real + * versions of each module (rather than a mocked version). + */ + disableAutomock(): JestObjectType, + /** + * An un-hoisted version of disableAutomock + */ + autoMockOff(): JestObjectType, + /** + * Enables automatic mocking in the module loader. + */ + enableAutomock(): JestObjectType, + /** + * An un-hoisted version of enableAutomock + */ + autoMockOn(): JestObjectType, + /** + * Clears the mock.calls and mock.instances properties of all mocks. + * Equivalent to calling .mockClear() on every mocked function. + */ + clearAllMocks(): JestObjectType, + /** + * Resets the state of all mocks. Equivalent to calling .mockReset() on every + * mocked function. + */ + resetAllMocks(): JestObjectType, + /** + * Removes any pending timers from the timer system. + */ + clearAllTimers(): void, + /** + * The same as `mock` but not moved to the top of the expectation by + * babel-jest. + */ + doMock(moduleName: string, moduleFactory?: any): JestObjectType, + /** + * The same as `unmock` but not moved to the top of the expectation by + * babel-jest. + */ + dontMock(moduleName: string): JestObjectType, + /** + * Returns a new, unused mock function. Optionally takes a mock + * implementation. + */ + fn, TReturn>( + implementation?: (...args: TArguments) => TReturn + ): JestMockFn, + /** + * Determines if the given function is a mocked function. + */ + isMockFunction(fn: Function): boolean, + /** + * Given the name of a module, use the automatic mocking system to generate a + * mocked version of the module for you. + */ + genMockFromModule(moduleName: string): any, + /** + * Mocks a module with an auto-mocked version when it is being required. + * + * The second argument can be used to specify an explicit module factory that + * is being run instead of using Jest's automocking feature. + * + * The third argument can be used to create virtual mocks -- mocks of modules + * that don't exist anywhere in the system. + */ + mock( + moduleName: string, + moduleFactory?: any, + options?: Object + ): JestObjectType, + /** + * Returns the actual module instead of a mock, bypassing all checks on + * whether the module should receive a mock implementation or not. + */ + requireActual(moduleName: string): any, + /** + * Returns a mock module instead of the actual module, bypassing all checks + * on whether the module should be required normally or not. + */ + requireMock(moduleName: string): any, + /** + * Resets the module registry - the cache of all required modules. This is + * useful to isolate modules where local state might conflict between tests. + */ + resetModules(): JestObjectType, + /** + * Exhausts the micro-task queue (usually interfaced in node via + * process.nextTick). + */ + runAllTicks(): void, + /** + * Exhausts the macro-task queue (i.e., all tasks queued by setTimeout(), + * setInterval(), and setImmediate()). + */ + runAllTimers(): void, + /** + * Exhausts all tasks queued by setImmediate(). + */ + runAllImmediates(): void, + /** + * Executes only the macro task queue (i.e. all tasks queued by setTimeout() + * or setInterval() and setImmediate()). + */ + runTimersToTime(msToRun: number): void, + /** + * Executes only the macro-tasks that are currently pending (i.e., only the + * tasks that have been queued by setTimeout() or setInterval() up to this + * point) + */ + runOnlyPendingTimers(): void, + /** + * Explicitly supplies the mock object that the module system should return + * for the specified module. Note: It is recommended to use jest.mock() + * instead. + */ + setMock(moduleName: string, moduleExports: any): JestObjectType, + /** + * Indicates that the module system should never return a mocked version of + * the specified module from require() (e.g. that it should always return the + * real module). + */ + unmock(moduleName: string): JestObjectType, + /** + * Instructs Jest to use fake versions of the standard timer functions + * (setTimeout, setInterval, clearTimeout, clearInterval, nextTick, + * setImmediate and clearImmediate). + */ + useFakeTimers(): JestObjectType, + /** + * Instructs Jest to use the real versions of the standard timer functions. + */ + useRealTimers(): JestObjectType, + /** + * Creates a mock function similar to jest.fn but also tracks calls to + * object[methodName]. + */ + spyOn(object: Object, methodName: string): JestMockFn, + /** + * Set the default timeout interval for tests and before/after hooks in milliseconds. + * Note: The default timeout interval is 5 seconds if this method is not called. + */ + setTimeout(timeout: number): JestObjectType +}; + +type JestSpyType = { + calls: JestCallsType +}; + +/** Runs this function after every test inside this context */ +declare function afterEach( + fn: (done: () => void) => ?Promise, + timeout?: number +): void; +/** Runs this function before every test inside this context */ +declare function beforeEach( + fn: (done: () => void) => ?Promise, + timeout?: number +): void; +/** Runs this function after all tests have finished inside this context */ +declare function afterAll( + fn: (done: () => void) => ?Promise, + timeout?: number +): void; +/** Runs this function before any tests have started inside this context */ +declare function beforeAll( + fn: (done: () => void) => ?Promise, + timeout?: number +): void; + +/** A context for grouping tests together */ +declare var describe: { + /** + * Creates a block that groups together several related tests in one "test suite" + */ + (name: string, fn: () => void): void, + + /** + * Only run this describe block + */ + only(name: string, fn: () => void): void, + + /** + * Skip running this describe block + */ + skip(name: string, fn: () => void): void +}; + +/** An individual test unit */ +declare var it: { + /** + * An individual test unit + * + * @param {string} Name of Test + * @param {Function} Test + * @param {number} Timeout for the test, in milliseconds. + */ + ( + name: string, + fn?: (done: () => void) => ?Promise, + timeout?: number + ): void, + /** + * Only run this test + * + * @param {string} Name of Test + * @param {Function} Test + * @param {number} Timeout for the test, in milliseconds. + */ + only( + name: string, + fn?: (done: () => void) => ?Promise, + timeout?: number + ): void, + /** + * Skip running this test + * + * @param {string} Name of Test + * @param {Function} Test + * @param {number} Timeout for the test, in milliseconds. + */ + skip( + name: string, + fn?: (done: () => void) => ?Promise, + timeout?: number + ): void, + /** + * Run the test concurrently + * + * @param {string} Name of Test + * @param {Function} Test + * @param {number} Timeout for the test, in milliseconds. + */ + concurrent( + name: string, + fn?: (done: () => void) => ?Promise, + timeout?: number + ): void +}; +declare function fit( + name: string, + fn: (done: () => void) => ?Promise, + timeout?: number +): void; +/** An individual test unit */ +declare var test: typeof it; +/** A disabled group of tests */ +declare var xdescribe: typeof describe; +/** A focused group of tests */ +declare var fdescribe: typeof describe; +/** A disabled individual test */ +declare var xit: typeof it; +/** A disabled individual test */ +declare var xtest: typeof it; + +/** The expect function is used every time you want to test a value */ +declare var expect: { + /** The object that you want to make assertions against */ + (value: any): JestExpectType & JestPromiseType & EnzymeMatchersType, + /** Add additional Jasmine matchers to Jest's roster */ + extend(matchers: { [name: string]: JestMatcher }): void, + /** Add a module that formats application-specific data structures. */ + addSnapshotSerializer(serializer: (input: Object) => string): void, + assertions(expectedAssertions: number): void, + hasAssertions(): void, + any(value: mixed): JestAsymmetricEqualityType, + anything(): void, + arrayContaining(value: Array): void, + objectContaining(value: Object): void, + /** Matches any received string that contains the exact expected string. */ + stringContaining(value: string): void, + stringMatching(value: string | RegExp): void +}; + +// TODO handle return type +// http://jasmine.github.io/2.4/introduction.html#section-Spies +declare function spyOn(value: mixed, method: string): Object; + +/** Holds all functions related to manipulating test runner */ +declare var jest: JestObjectType; + +/** + * The global Jasmine object, this is generally not exposed as the public API, + * using features inside here could break in later versions of Jest. + */ +declare var jasmine: { + DEFAULT_TIMEOUT_INTERVAL: number, + any(value: mixed): JestAsymmetricEqualityType, + anything(): void, + arrayContaining(value: Array): void, + clock(): JestClockType, + createSpy(name: string): JestSpyType, + createSpyObj( + baseName: string, + methodNames: Array + ): { [methodName: string]: JestSpyType }, + objectContaining(value: Object): void, + stringMatching(value: string): void +}; diff --git a/flow-typed/npm/lodash_v4.x.x.js b/flow-typed/npm/lodash_v4.x.x.js new file mode 100644 index 000000000..9bf5bdfef --- /dev/null +++ b/flow-typed/npm/lodash_v4.x.x.js @@ -0,0 +1,4207 @@ +// flow-typed signature: fcbc2c8209ca21df4e50468c1f1cf2cf +// flow-typed version: 9dc62314fe/lodash_v4.x.x/flow_>=v0.55.x + +declare module "lodash" { + declare type __CurriedFunction1 = (...r: [AA]) => R; + declare type CurriedFunction1 = __CurriedFunction1; + + declare type __CurriedFunction2 = (( + ...r: [AA] + ) => CurriedFunction1) & + ((...r: [AA, BB]) => R); + declare type CurriedFunction2 = __CurriedFunction2; + + declare type __CurriedFunction3 = (( + ...r: [AA] + ) => CurriedFunction2) & + ((...r: [AA, BB]) => CurriedFunction1) & + ((...r: [AA, BB, CC]) => R); + declare type CurriedFunction3 = __CurriedFunction3< + A, + B, + C, + R, + *, + *, + * + >; + + declare type __CurriedFunction4< + A, + B, + C, + D, + R, + AA: A, + BB: B, + CC: C, + DD: D + > = ((...r: [AA]) => CurriedFunction3) & + ((...r: [AA, BB]) => CurriedFunction2) & + ((...r: [AA, BB, CC]) => CurriedFunction1) & + ((...r: [AA, BB, CC, DD]) => R); + declare type CurriedFunction4 = __CurriedFunction4< + A, + B, + C, + D, + R, + *, + *, + *, + * + >; + + declare type __CurriedFunction5< + A, + B, + C, + D, + E, + R, + AA: A, + BB: B, + CC: C, + DD: D, + EE: E + > = ((...r: [AA]) => CurriedFunction4) & + ((...r: [AA, BB]) => CurriedFunction3) & + ((...r: [AA, BB, CC]) => CurriedFunction2) & + ((...r: [AA, BB, CC, DD]) => CurriedFunction1) & + ((...r: [AA, BB, CC, DD, EE]) => R); + declare type CurriedFunction5 = __CurriedFunction5< + A, + B, + C, + D, + E, + R, + *, + *, + *, + *, + * + >; + + declare type __CurriedFunction6< + A, + B, + C, + D, + E, + F, + R, + AA: A, + BB: B, + CC: C, + DD: D, + EE: E, + FF: F + > = ((...r: [AA]) => CurriedFunction5) & + ((...r: [AA, BB]) => CurriedFunction4) & + ((...r: [AA, BB, CC]) => CurriedFunction3) & + ((...r: [AA, BB, CC, DD]) => CurriedFunction2) & + ((...r: [AA, BB, CC, DD, EE]) => CurriedFunction1) & + ((...r: [AA, BB, CC, DD, EE, FF]) => R); + declare type CurriedFunction6 = __CurriedFunction6< + A, + B, + C, + D, + E, + F, + R, + *, + *, + *, + *, + *, + * + >; + + declare type Curry = (((...r: [A]) => R) => CurriedFunction1) & + (((...r: [A, B]) => R) => CurriedFunction2) & + (((...r: [A, B, C]) => R) => CurriedFunction3) & + (( + (...r: [A, B, C, D]) => R + ) => CurriedFunction4) & + (( + (...r: [A, B, C, D, E]) => R + ) => CurriedFunction5) & + (( + (...r: [A, B, C, D, E, F]) => R + ) => CurriedFunction6); + + declare type UnaryFn = (a: A) => R; + + declare type TemplateSettings = { + escape?: RegExp, + evaluate?: RegExp, + imports?: Object, + interpolate?: RegExp, + variable?: string + }; + + declare type TruncateOptions = { + length?: number, + omission?: string, + separator?: RegExp | string + }; + + declare type DebounceOptions = { + leading?: boolean, + maxWait?: number, + trailing?: boolean + }; + + declare type ThrottleOptions = { + leading?: boolean, + trailing?: boolean + }; + + declare type NestedArray = Array>; + + declare type matchesIterateeShorthand = Object; + declare type matchesPropertyIterateeShorthand = [string, any]; + declare type propertyIterateeShorthand = string; + + declare type OPredicate = + | ((value: A, key: string, object: O) => any) + | matchesIterateeShorthand + | matchesPropertyIterateeShorthand + | propertyIterateeShorthand; + + declare type OIterateeWithResult = + | Object + | string + | ((value: V, key: string, object: O) => R); + declare type OIteratee = OIterateeWithResult; + declare type OFlatMapIteratee = OIterateeWithResult>; + + declare type Predicate = + | ((value: T, index: number, array: Array) => any) + | matchesIterateeShorthand + | matchesPropertyIterateeShorthand + | propertyIterateeShorthand; + + declare type _ValueOnlyIteratee = (value: T) => mixed; + declare type ValueOnlyIteratee = _ValueOnlyIteratee | string; + declare type _Iteratee = ( + item: T, + index: number, + array: ?Array + ) => mixed; + declare type Iteratee = _Iteratee | Object | string; + declare type FlatMapIteratee = + | ((item: T, index: number, array: ?Array) => Array) + | Object + | string; + declare type Comparator = (item: T, item2: T) => boolean; + + declare type MapIterator = + | ((item: T, index: number, array: Array) => U) + | propertyIterateeShorthand; + + declare type OMapIterator = + | ((item: T, key: string, object: O) => U) + | propertyIterateeShorthand; + + declare class Lodash { + // Array + chunk(array: ?Array, size?: number): Array>; + compact(array: Array): Array; + concat(base: Array, ...elements: Array): Array; + difference(array: ?Array, values?: Array): Array; + differenceBy( + array: ?Array, + values: Array, + iteratee: ValueOnlyIteratee + ): T[]; + differenceWith(array: T[], values: T[], comparator?: Comparator): T[]; + drop(array: ?Array, n?: number): Array; + dropRight(array: ?Array, n?: number): Array; + dropRightWhile(array: ?Array, predicate?: Predicate): Array; + dropWhile(array: ?Array, predicate?: Predicate): Array; + fill( + array: ?Array, + value: U, + start?: number, + end?: number + ): Array; + findIndex( + array: ?$ReadOnlyArray, + predicate?: Predicate, + fromIndex?: number + ): number; + findLastIndex( + array: ?$ReadOnlyArray, + predicate?: Predicate, + fromIndex?: number + ): number; + // alias of _.head + first(array: ?Array): T; + flatten(array: Array | X>): Array; + flattenDeep(array: any[]): Array; + flattenDepth(array: any[], depth?: number): any[]; + fromPairs(pairs: Array<[A, B]>): { [key: A]: B }; + head(array: ?Array): T; + indexOf(array: ?Array, value: T, fromIndex?: number): number; + initial(array: ?Array): Array; + intersection(...arrays: Array>): Array; + //Workaround until (...parameter: T, parameter2: U) works + intersectionBy(a1: Array, iteratee?: ValueOnlyIteratee): Array; + intersectionBy( + a1: Array, + a2: Array, + iteratee?: ValueOnlyIteratee + ): Array; + intersectionBy( + a1: Array, + a2: Array, + a3: Array, + iteratee?: ValueOnlyIteratee + ): Array; + intersectionBy( + a1: Array, + a2: Array, + a3: Array, + a4: Array, + iteratee?: ValueOnlyIteratee + ): Array; + //Workaround until (...parameter: T, parameter2: U) works + intersectionWith(a1: Array, comparator: Comparator): Array; + intersectionWith( + a1: Array, + a2: Array, + comparator: Comparator + ): Array; + intersectionWith( + a1: Array, + a2: Array, + a3: Array, + comparator: Comparator + ): Array; + intersectionWith( + a1: Array, + a2: Array, + a3: Array, + a4: Array, + comparator: Comparator + ): Array; + join(array: ?Array, separator?: string): string; + last(array: ?Array): T; + lastIndexOf(array: ?Array, value: T, fromIndex?: number): number; + nth(array: T[], n?: number): T; + pull(array: ?Array, ...values?: Array): Array; + pullAll(array: ?Array, values: Array): Array; + pullAllBy( + array: ?Array, + values: Array, + iteratee?: ValueOnlyIteratee + ): Array; + pullAllWith(array?: T[], values: T[], comparator?: Function): T[]; + pullAt(array: ?Array, ...indexed?: Array): Array; + pullAt(array: ?Array, indexed?: Array): Array; + remove(array: ?Array, predicate?: Predicate): Array; + reverse(array: ?Array): Array; + slice(array: ?Array, start?: number, end?: number): Array; + sortedIndex(array: ?Array, value: T): number; + sortedIndexBy( + array: ?Array, + value: T, + iteratee?: ValueOnlyIteratee + ): number; + sortedIndexOf(array: ?Array, value: T): number; + sortedLastIndex(array: ?Array, value: T): number; + sortedLastIndexBy( + array: ?Array, + value: T, + iteratee?: ValueOnlyIteratee + ): number; + sortedLastIndexOf(array: ?Array, value: T): number; + sortedUniq(array: ?Array): Array; + sortedUniqBy(array: ?Array, iteratee?: (value: T) => mixed): Array; + tail(array: ?Array): Array; + take(array: ?Array, n?: number): Array; + takeRight(array: ?Array, n?: number): Array; + takeRightWhile(array: ?Array, predicate?: Predicate): Array; + takeWhile(array: ?Array, predicate?: Predicate): Array; + union(...arrays?: Array>): Array; + //Workaround until (...parameter: T, parameter2: U) works + unionBy(a1: Array, iteratee?: ValueOnlyIteratee): Array; + unionBy( + a1: Array, + a2: Array, + iteratee?: ValueOnlyIteratee + ): Array; + unionBy( + a1: Array, + a2: Array, + a3: Array, + iteratee?: ValueOnlyIteratee + ): Array; + unionBy( + a1: Array, + a2: Array, + a3: Array, + a4: Array, + iteratee?: ValueOnlyIteratee + ): Array; + //Workaround until (...parameter: T, parameter2: U) works + unionWith(a1: Array, comparator?: Comparator): Array; + unionWith( + a1: Array, + a2: Array, + comparator?: Comparator + ): Array; + unionWith( + a1: Array, + a2: Array, + a3: Array, + comparator?: Comparator + ): Array; + unionWith( + a1: Array, + a2: Array, + a3: Array, + a4: Array, + comparator?: Comparator + ): Array; + uniq(array: ?Array): Array; + uniqBy(array: ?Array, iteratee?: ValueOnlyIteratee): Array; + uniqWith(array: ?Array, comparator?: Comparator): Array; + unzip(array: ?Array): Array; + unzipWith(array: ?Array, iteratee?: Iteratee): Array; + without(array: ?Array, ...values?: Array): Array; + xor(...array: Array>): Array; + //Workaround until (...parameter: T, parameter2: U) works + xorBy(a1: Array, iteratee?: ValueOnlyIteratee): Array; + xorBy( + a1: Array, + a2: Array, + iteratee?: ValueOnlyIteratee + ): Array; + xorBy( + a1: Array, + a2: Array, + a3: Array, + iteratee?: ValueOnlyIteratee + ): Array; + xorBy( + a1: Array, + a2: Array, + a3: Array, + a4: Array, + iteratee?: ValueOnlyIteratee + ): Array; + //Workaround until (...parameter: T, parameter2: U) works + xorWith(a1: Array, comparator?: Comparator): Array; + xorWith( + a1: Array, + a2: Array, + comparator?: Comparator + ): Array; + xorWith( + a1: Array, + a2: Array, + a3: Array, + comparator?: Comparator + ): Array; + xorWith( + a1: Array, + a2: Array, + a3: Array, + a4: Array, + comparator?: Comparator + ): Array; + zip(a1: A[], a2: B[]): Array<[A, B]>; + zip(a1: A[], a2: B[], a3: C[]): Array<[A, B, C]>; + zip(a1: A[], a2: B[], a3: C[], a4: D[]): Array<[A, B, C, D]>; + zip( + a1: A[], + a2: B[], + a3: C[], + a4: D[], + a5: E[] + ): Array<[A, B, C, D, E]>; + + zipObject(props?: Array, values?: Array): { [key: K]: V }; + zipObjectDeep(props?: any[], values?: any): Object; + //Workaround until (...parameter: T, parameter2: U) works + zipWith(a1: NestedArray, iteratee?: Iteratee): Array; + zipWith( + a1: NestedArray, + a2: NestedArray, + iteratee?: Iteratee + ): Array; + zipWith( + a1: NestedArray, + a2: NestedArray, + a3: NestedArray, + iteratee?: Iteratee + ): Array; + zipWith( + a1: NestedArray, + a2: NestedArray, + a3: NestedArray, + a4: NestedArray, + iteratee?: Iteratee + ): Array; + + // Collection + countBy(array: ?Array, iteratee?: ValueOnlyIteratee): Object; + countBy(object: T, iteratee?: ValueOnlyIteratee): Object; + // alias of _.forEach + each(array: ?Array, iteratee?: Iteratee): Array; + each(object: T, iteratee?: OIteratee): T; + // alias of _.forEachRight + eachRight(array: ?Array, iteratee?: Iteratee): Array; + eachRight(object: T, iteratee?: OIteratee): T; + every(array: ?Array, iteratee?: Iteratee): boolean; + every(object: T, iteratee?: OIteratee): boolean; + filter(array: ?Array, predicate?: Predicate): Array; + filter( + object: T, + predicate?: OPredicate + ): Array; + find( + array: ?$ReadOnlyArray, + predicate?: Predicate, + fromIndex?: number + ): T | void; + find( + object: T, + predicate?: OPredicate, + fromIndex?: number + ): V; + findLast( + array: ?$ReadOnlyArray, + predicate?: Predicate, + fromIndex?: number + ): T | void; + findLast( + object: T, + predicate?: OPredicate + ): V; + flatMap(array: ?Array, iteratee?: FlatMapIteratee): Array; + flatMap( + object: T, + iteratee?: OFlatMapIteratee + ): Array; + flatMapDeep( + array: ?Array, + iteratee?: FlatMapIteratee + ): Array; + flatMapDeep( + object: T, + iteratee?: OFlatMapIteratee + ): Array; + flatMapDepth( + array: ?Array, + iteratee?: FlatMapIteratee, + depth?: number + ): Array; + flatMapDepth( + object: T, + iteratee?: OFlatMapIteratee, + depth?: number + ): Array; + forEach(array: ?Array, iteratee?: Iteratee): Array; + forEach(object: T, iteratee?: OIteratee): T; + forEachRight(array: ?Array, iteratee?: Iteratee): Array; + forEachRight(object: T, iteratee?: OIteratee): T; + groupBy( + array: ?Array, + iteratee?: ValueOnlyIteratee + ): { [key: V]: Array }; + groupBy( + object: T, + iteratee?: ValueOnlyIteratee + ): { [key: V]: Array }; + includes(array: ?Array, value: T, fromIndex?: number): boolean; + includes(object: T, value: any, fromIndex?: number): boolean; + includes(str: string, value: string, fromIndex?: number): boolean; + invokeMap( + array: ?Array, + path: ((value: T) => Array | string) | Array | string, + ...args?: Array + ): Array; + invokeMap( + object: T, + path: ((value: any) => Array | string) | Array | string, + ...args?: Array + ): Array; + keyBy( + array: ?Array, + iteratee?: ValueOnlyIteratee + ): { [key: V]: ?T }; + keyBy( + object: T, + iteratee?: ValueOnlyIteratee + ): { [key: V]: ?A }; + map(array: ?Array, iteratee?: MapIterator): Array; + map( + object: ?T, + iteratee?: OMapIterator + ): Array; + map( + str: ?string, + iteratee?: (char: string, index: number, str: string) => any + ): string; + orderBy( + array: ?Array, + iteratees?: Array> | string, + orders?: Array<"asc" | "desc"> | string + ): Array; + orderBy( + object: T, + iteratees?: Array> | string, + orders?: Array<"asc" | "desc"> | string + ): Array; + partition( + array: ?Array, + predicate?: Predicate + ): [Array, Array]; + partition( + object: T, + predicate?: OPredicate + ): [Array, Array]; + reduce( + array: ?Array, + iteratee?: ( + accumulator: U, + value: T, + index: number, + array: ?Array + ) => U, + accumulator?: U + ): U; + reduce( + object: T, + iteratee?: (accumulator: U, value: any, key: string, object: T) => U, + accumulator?: U + ): U; + reduceRight( + array: ?Array, + iteratee?: ( + accumulator: U, + value: T, + index: number, + array: ?Array + ) => U, + accumulator?: U + ): U; + reduceRight( + object: T, + iteratee?: (accumulator: U, value: any, key: string, object: T) => U, + accumulator?: U + ): U; + reject(array: ?Array, predicate?: Predicate): Array; + reject( + object: T, + predicate?: OPredicate + ): Array; + sample(array: ?Array): T; + sample(object: T): V; + sampleSize(array: ?Array, n?: number): Array; + sampleSize(object: T, n?: number): Array; + shuffle(array: ?Array): Array; + shuffle(object: T): Array; + size(collection: Array | Object): number; + some(array: ?Array, predicate?: Predicate): boolean; + some( + object?: ?T, + predicate?: OPredicate + ): boolean; + sortBy(array: ?Array, ...iteratees?: Array>): Array; + sortBy(array: ?Array, iteratees?: Array>): Array; + sortBy( + object: T, + ...iteratees?: Array> + ): Array; + sortBy(object: T, iteratees?: Array>): Array; + + // Date + now(): number; + + // Function + after(n: number, fn: Function): Function; + ary(func: Function, n?: number): Function; + before(n: number, fn: Function): Function; + bind(func: Function, thisArg: any, ...partials: Array): Function; + bindKey(obj: Object, key: string, ...partials: Array): Function; + curry: Curry; + curry(func: Function, arity?: number): Function; + curryRight(func: Function, arity?: number): Function; + debounce(func: F, wait?: number, options?: DebounceOptions): F; + defer(func: Function, ...args?: Array): number; + delay(func: Function, wait: number, ...args?: Array): number; + flip(func: Function): Function; + memoize(func: F, resolver?: Function): F; + negate(predicate: Function): Function; + once(func: Function): Function; + overArgs(func: Function, ...transforms: Array): Function; + overArgs(func: Function, transforms: Array): Function; + partial(func: Function, ...partials: any[]): Function; + partialRight(func: Function, ...partials: Array): Function; + partialRight(func: Function, partials: Array): Function; + rearg(func: Function, ...indexes: Array): Function; + rearg(func: Function, indexes: Array): Function; + rest(func: Function, start?: number): Function; + spread(func: Function): Function; + throttle( + func: Function, + wait?: number, + options?: ThrottleOptions + ): Function; + unary(func: Function): Function; + wrap(value: any, wrapper: Function): Function; + + // Lang + castArray(value: *): any[]; + clone(value: T): T; + cloneDeep(value: T): T; + cloneDeepWith( + value: T, + customizer?: ?(value: T, key: number | string, object: T, stack: any) => U + ): U; + cloneWith( + value: T, + customizer?: ?(value: T, key: number | string, object: T, stack: any) => U + ): U; + conformsTo( + source: T, + predicates: T & { [key: string]: (x: any) => boolean } + ): boolean; + eq(value: any, other: any): boolean; + gt(value: any, other: any): boolean; + gte(value: any, other: any): boolean; + isArguments(value: any): boolean; + isArray(value: any): boolean; + isArrayBuffer(value: any): boolean; + isArrayLike(value: any): boolean; + isArrayLikeObject(value: any): boolean; + isBoolean(value: any): boolean; + isBuffer(value: any): boolean; + isDate(value: any): boolean; + isElement(value: any): boolean; + isEmpty(value: any): boolean; + isEqual(value: any, other: any): boolean; + isEqualWith( + value: T, + other: U, + customizer?: ( + objValue: any, + otherValue: any, + key: number | string, + object: T, + other: U, + stack: any + ) => boolean | void + ): boolean; + isError(value: any): boolean; + isFinite(value: any): boolean; + isFunction(value: Function): true; + isFunction(value: number | string | void | null | Object): false; + isInteger(value: any): boolean; + isLength(value: any): boolean; + isMap(value: any): boolean; + isMatch(object?: ?Object, source: Object): boolean; + isMatchWith( + object: T, + source: U, + customizer?: ( + objValue: any, + srcValue: any, + key: number | string, + object: T, + source: U + ) => boolean | void + ): boolean; + isNaN(value: any): boolean; + isNative(value: any): boolean; + isNil(value: any): boolean; + isNull(value: any): boolean; + isNumber(value: any): boolean; + isObject(value: any): boolean; + isObjectLike(value: any): boolean; + isPlainObject(value: any): boolean; + isRegExp(value: any): boolean; + isSafeInteger(value: any): boolean; + isSet(value: any): boolean; + isString(value: string): true; + isString( + value: number | boolean | Function | void | null | Object | Array + ): false; + isSymbol(value: any): boolean; + isTypedArray(value: any): boolean; + isUndefined(value: any): boolean; + isWeakMap(value: any): boolean; + isWeakSet(value: any): boolean; + lt(value: any, other: any): boolean; + lte(value: any, other: any): boolean; + toArray(value: any): Array; + toFinite(value: any): number; + toInteger(value: any): number; + toLength(value: any): number; + toNumber(value: any): number; + toPlainObject(value: any): Object; + toSafeInteger(value: any): number; + toString(value: any): string; + + // Math + add(augend: number, addend: number): number; + ceil(number: number, precision?: number): number; + divide(dividend: number, divisor: number): number; + floor(number: number, precision?: number): number; + max(array: ?Array): T; + maxBy(array: ?Array, iteratee?: Iteratee): T; + mean(array: Array<*>): number; + meanBy(array: Array, iteratee?: Iteratee): number; + min(array: ?Array): T; + minBy(array: ?Array, iteratee?: Iteratee): T; + multiply(multiplier: number, multiplicand: number): number; + round(number: number, precision?: number): number; + subtract(minuend: number, subtrahend: number): number; + sum(array: Array<*>): number; + sumBy(array: Array, iteratee?: Iteratee): number; + + // number + clamp(number: number, lower?: number, upper: number): number; + inRange(number: number, start?: number, end: number): boolean; + random(lower?: number, upper?: number, floating?: boolean): number; + + // Object + assign(object?: ?Object, ...sources?: Array): Object; + assignIn(a: A, b: B): A & B; + assignIn(a: A, b: B, c: C): A & B & C; + assignIn(a: A, b: B, c: C, d: D): A & B & C & D; + assignIn(a: A, b: B, c: C, d: D, e: E): A & B & C & D & E; + assignInWith( + object: T, + s1: A, + customizer?: ( + objValue: any, + srcValue: any, + key: string, + object: T, + source: A + ) => any | void + ): Object; + assignInWith( + object: T, + s1: A, + s2: B, + customizer?: ( + objValue: any, + srcValue: any, + key: string, + object: T, + source: A | B + ) => any | void + ): Object; + assignInWith( + object: T, + s1: A, + s2: B, + s3: C, + customizer?: ( + objValue: any, + srcValue: any, + key: string, + object: T, + source: A | B | C + ) => any | void + ): Object; + assignInWith( + object: T, + s1: A, + s2: B, + s3: C, + s4: D, + customizer?: ( + objValue: any, + srcValue: any, + key: string, + object: T, + source: A | B | C | D + ) => any | void + ): Object; + assignWith( + object: T, + s1: A, + customizer?: ( + objValue: any, + srcValue: any, + key: string, + object: T, + source: A + ) => any | void + ): Object; + assignWith( + object: T, + s1: A, + s2: B, + customizer?: ( + objValue: any, + srcValue: any, + key: string, + object: T, + source: A | B + ) => any | void + ): Object; + assignWith( + object: T, + s1: A, + s2: B, + s3: C, + customizer?: ( + objValue: any, + srcValue: any, + key: string, + object: T, + source: A | B | C + ) => any | void + ): Object; + assignWith( + object: T, + s1: A, + s2: B, + s3: C, + s4: D, + customizer?: ( + objValue: any, + srcValue: any, + key: string, + object: T, + source: A | B | C | D + ) => any | void + ): Object; + at(object?: ?Object, ...paths: Array): Array; + at(object?: ?Object, paths: Array): Array; + create(prototype: T, properties?: Object): $Supertype; + defaults(object?: ?Object, ...sources?: Array): Object; + defaultsDeep(object?: ?Object, ...sources?: Array): Object; + // alias for _.toPairs + entries(object?: ?Object): Array<[string, any]>; + // alias for _.toPairsIn + entriesIn(object?: ?Object): Array<[string, any]>; + // alias for _.assignIn + extend(a: A, b: B): A & B; + extend(a: A, b: B, c: C): A & B & C; + extend(a: A, b: B, c: C, d: D): A & B & C & D; + extend(a: A, b: B, c: C, d: D, e: E): A & B & C & D & E; + // alias for _.assignInWith + extendWith( + object: T, + s1: A, + customizer?: ( + objValue: any, + srcValue: any, + key: string, + object: T, + source: A + ) => any | void + ): Object; + extendWith( + object: T, + s1: A, + s2: B, + customizer?: ( + objValue: any, + srcValue: any, + key: string, + object: T, + source: A | B + ) => any | void + ): Object; + extendWith( + object: T, + s1: A, + s2: B, + s3: C, + customizer?: ( + objValue: any, + srcValue: any, + key: string, + object: T, + source: A | B | C + ) => any | void + ): Object; + extendWith( + object: T, + s1: A, + s2: B, + s3: C, + s4: D, + customizer?: ( + objValue: any, + srcValue: any, + key: string, + object: T, + source: A | B | C | D + ) => any | void + ): Object; + findKey( + object?: ?T, + predicate?: OPredicate + ): string | void; + findLastKey( + object?: ?T, + predicate?: OPredicate + ): string | void; + forIn(object?: ?Object, iteratee?: OIteratee<*>): Object; + forInRight(object?: ?Object, iteratee?: OIteratee<*>): Object; + forOwn(object?: ?Object, iteratee?: OIteratee<*>): Object; + forOwnRight(object?: ?Object, iteratee?: OIteratee<*>): Object; + functions(object?: ?Object): Array; + functionsIn(object?: ?Object): Array; + get( + object?: ?Object | ?Array, + path?: ?Array | string, + defaultValue?: any + ): any; + has(object?: ?Object, path?: ?Array | string): boolean; + hasIn(object?: ?Object, path?: ?Array | string): boolean; + invert(object?: ?Object, multiVal?: boolean): Object; + invertBy(object: ?Object, iteratee?: Function): Object; + invoke( + object?: ?Object, + path?: ?Array | string, + ...args?: Array + ): any; + keys(object?: ?{ [key: K]: any }): Array; + keys(object?: ?Object): Array; + keysIn(object?: ?Object): Array; + mapKeys(object?: ?Object, iteratee?: OIteratee<*>): Object; + mapValues(object?: ?Object, iteratee?: OIteratee<*>): Object; + merge(object?: ?Object, ...sources?: Array): Object; + mergeWith( + object: T, + customizer?: ( + objValue: any, + srcValue: any, + key: string, + object: T, + source: A + ) => any | void + ): Object; + mergeWith( + object: T, + s1: A, + s2: B, + customizer?: ( + objValue: any, + srcValue: any, + key: string, + object: T, + source: A | B + ) => any | void + ): Object; + mergeWith( + object: T, + s1: A, + s2: B, + s3: C, + customizer?: ( + objValue: any, + srcValue: any, + key: string, + object: T, + source: A | B | C + ) => any | void + ): Object; + mergeWith( + object: T, + s1: A, + s2: B, + s3: C, + s4: D, + customizer?: ( + objValue: any, + srcValue: any, + key: string, + object: T, + source: A | B | C | D + ) => any | void + ): Object; + omit(object?: ?Object, ...props: Array): Object; + omit(object?: ?Object, props: Array): Object; + omitBy( + object?: ?T, + predicate?: OPredicate + ): Object; + pick(object?: ?Object, ...props: Array): Object; + pick(object?: ?Object, props: Array): Object; + pickBy( + object?: ?T, + predicate?: OPredicate + ): Object; + result( + object?: ?Object, + path?: ?Array | string, + defaultValue?: any + ): any; + set(object?: ?Object, path?: ?Array | string, value: any): Object; + setWith( + object: T, + path?: ?Array | string, + value: any, + customizer?: (nsValue: any, key: string, nsObject: T) => any + ): Object; + toPairs(object?: ?Object | Array<*>): Array<[string, any]>; + toPairsIn(object?: ?Object): Array<[string, any]>; + transform( + collection: Object | Array, + iteratee?: OIteratee<*>, + accumulator?: any + ): any; + unset(object?: ?Object, path?: ?Array | string): boolean; + update(object: Object, path: string[] | string, updater: Function): Object; + updateWith( + object: Object, + path: string[] | string, + updater: Function, + customizer?: Function + ): Object; + values(object?: ?Object): Array; + valuesIn(object?: ?Object): Array; + + // Seq + // harder to read, but this is _() + (value: any): any; + chain(value: T): any; + tap(value: T, interceptor: (value: T) => any): T; + thru(value: T1, interceptor: (value: T1) => T2): T2; + // TODO: _.prototype.* + + // String + camelCase(string?: ?string): string; + capitalize(string?: string): string; + deburr(string?: string): string; + endsWith(string?: string, target?: string, position?: number): boolean; + escape(string?: string): string; + escapeRegExp(string?: string): string; + kebabCase(string?: string): string; + lowerCase(string?: string): string; + lowerFirst(string?: string): string; + pad(string?: string, length?: number, chars?: string): string; + padEnd(string?: string, length?: number, chars?: string): string; + padStart(string?: string, length?: number, chars?: string): string; + parseInt(string: string, radix?: number): number; + repeat(string?: string, n?: number): string; + replace( + string?: string, + pattern: RegExp | string, + replacement: ((string: string) => string) | string + ): string; + snakeCase(string?: string): string; + split( + string?: string, + separator: RegExp | string, + limit?: number + ): Array; + startCase(string?: string): string; + startsWith(string?: string, target?: string, position?: number): boolean; + template(string?: string, options?: TemplateSettings): Function; + toLower(string?: string): string; + toUpper(string?: string): string; + trim(string?: string, chars?: string): string; + trimEnd(string?: string, chars?: string): string; + trimStart(string?: string, chars?: string): string; + truncate(string?: string, options?: TruncateOptions): string; + unescape(string?: string): string; + upperCase(string?: string): string; + upperFirst(string?: string): string; + words(string?: string, pattern?: RegExp | string): Array; + + // Util + attempt(func: Function, ...args: Array): any; + bindAll(object?: ?Object, methodNames: Array): Object; + bindAll(object?: ?Object, ...methodNames: Array): Object; + cond(pairs: NestedArray): Function; + conforms(source: Object): Function; + constant(value: T): () => T; + defaultTo( + value: T1, + defaultValue: T2 + ): T1; + // NaN is a number instead of its own type, otherwise it would behave like null/void + defaultTo(value: T1, defaultValue: T2): T1 | T2; + defaultTo(value: T1, defaultValue: T2): T2; + flow: $ComposeReverse; + flow(funcs?: Array): Function; + flowRight: $Compose; + flowRight(funcs?: Array): Function; + identity(value: T): T; + iteratee(func?: any): Function; + matches(source: Object): Function; + matchesProperty(path?: ?Array | string, srcValue: any): Function; + method(path?: ?Array | string, ...args?: Array): Function; + methodOf(object?: ?Object, ...args?: Array): Function; + mixin( + object?: T, + source: Object, + options?: { chain: boolean } + ): T; + noConflict(): Lodash; + noop(...args: Array): void; + nthArg(n?: number): Function; + over(...iteratees: Array): Function; + over(iteratees: Array): Function; + overEvery(...predicates: Array): Function; + overEvery(predicates: Array): Function; + overSome(...predicates: Array): Function; + overSome(predicates: Array): Function; + property(path?: ?Array | string): Function; + propertyOf(object?: ?Object): Function; + range(start: number, end: number, step?: number): Array; + range(end: number, step?: number): Array; + rangeRight(start: number, end: number, step?: number): Array; + rangeRight(end: number, step?: number): Array; + runInContext(context?: Object): Function; + + stubArray(): Array<*>; + stubFalse(): false; + stubObject(): {}; + stubString(): ""; + stubTrue(): true; + times(n: number, ...rest: Array): Array; + times(n: number, iteratee: (i: number) => T): Array; + toPath(value: any): Array; + uniqueId(prefix?: string): string; + + // Properties + VERSION: string; + templateSettings: TemplateSettings; + } + + declare module.exports: Lodash; +} + +declare module "lodash/fp" { + declare type __CurriedFunction1 = (...r: [AA]) => R; + declare type CurriedFunction1 = __CurriedFunction1; + + declare type __CurriedFunction2 = (( + ...r: [AA] + ) => CurriedFunction1) & + ((...r: [AA, BB]) => R); + declare type CurriedFunction2 = __CurriedFunction2; + + declare type __CurriedFunction3 = (( + ...r: [AA] + ) => CurriedFunction2) & + ((...r: [AA, BB]) => CurriedFunction1) & + ((...r: [AA, BB, CC]) => R); + declare type CurriedFunction3 = __CurriedFunction3< + A, + B, + C, + R, + *, + *, + * + >; + + declare type __CurriedFunction4< + A, + B, + C, + D, + R, + AA: A, + BB: B, + CC: C, + DD: D + > = ((...r: [AA]) => CurriedFunction3) & + ((...r: [AA, BB]) => CurriedFunction2) & + ((...r: [AA, BB, CC]) => CurriedFunction1) & + ((...r: [AA, BB, CC, DD]) => R); + declare type CurriedFunction4 = __CurriedFunction4< + A, + B, + C, + D, + R, + *, + *, + *, + * + >; + + declare type __CurriedFunction5< + A, + B, + C, + D, + E, + R, + AA: A, + BB: B, + CC: C, + DD: D, + EE: E + > = ((...r: [AA]) => CurriedFunction4) & + ((...r: [AA, BB]) => CurriedFunction3) & + ((...r: [AA, BB, CC]) => CurriedFunction2) & + ((...r: [AA, BB, CC, DD]) => CurriedFunction1) & + ((...r: [AA, BB, CC, DD, EE]) => R); + declare type CurriedFunction5 = __CurriedFunction5< + A, + B, + C, + D, + E, + R, + *, + *, + *, + *, + * + >; + + declare type __CurriedFunction6< + A, + B, + C, + D, + E, + F, + R, + AA: A, + BB: B, + CC: C, + DD: D, + EE: E, + FF: F + > = ((...r: [AA]) => CurriedFunction5) & + ((...r: [AA, BB]) => CurriedFunction4) & + ((...r: [AA, BB, CC]) => CurriedFunction3) & + ((...r: [AA, BB, CC, DD]) => CurriedFunction2) & + ((...r: [AA, BB, CC, DD, EE]) => CurriedFunction1) & + ((...r: [AA, BB, CC, DD, EE, FF]) => R); + declare type CurriedFunction6 = __CurriedFunction6< + A, + B, + C, + D, + E, + F, + R, + *, + *, + *, + *, + *, + * + >; + + declare type Curry = (((...r: [A]) => R) => CurriedFunction1) & + (((...r: [A, B]) => R) => CurriedFunction2) & + (((...r: [A, B, C]) => R) => CurriedFunction3) & + (( + (...r: [A, B, C, D]) => R + ) => CurriedFunction4) & + (( + (...r: [A, B, C, D, E]) => R + ) => CurriedFunction5) & + (( + (...r: [A, B, C, D, E, F]) => R + ) => CurriedFunction6); + + declare type UnaryFn = (a: A) => R; + + declare type TemplateSettings = { + escape?: RegExp, + evaluate?: RegExp, + imports?: Object, + interpolate?: RegExp, + variable?: string + }; + + declare type TruncateOptions = { + length?: number, + omission?: string, + separator?: RegExp | string + }; + + declare type DebounceOptions = { + leading?: boolean, + maxWait?: number, + trailing?: boolean + }; + + declare type ThrottleOptions = { + leading?: boolean, + trailing?: boolean + }; + + declare type NestedArray = Array>; + + declare type matchesIterateeShorthand = Object; + declare type matchesPropertyIterateeShorthand = [string, any]; + declare type propertyIterateeShorthand = string; + + declare type OPredicate = + | ((value: A) => any) + | matchesIterateeShorthand + | matchesPropertyIterateeShorthand + | propertyIterateeShorthand; + + declare type OIterateeWithResult = Object | string | ((value: V) => R); + declare type OIteratee = OIterateeWithResult; + declare type OFlatMapIteratee = OIterateeWithResult>; + + declare type Predicate = + | ((value: T) => any) + | matchesIterateeShorthand + | matchesPropertyIterateeShorthand + | propertyIterateeShorthand; + + declare type _ValueOnlyIteratee = (value: T) => mixed; + declare type ValueOnlyIteratee = _ValueOnlyIteratee | string; + declare type _Iteratee = (item: T) => mixed; + declare type Iteratee = _Iteratee | Object | string; + declare type FlatMapIteratee = + | ((item: T) => Array) + | Object + | string; + declare type Comparator = (item: T, item2: T) => boolean; + + declare type MapIterator = ((item: T) => U) | propertyIterateeShorthand; + + declare type OMapIterator = + | ((item: T) => U) + | propertyIterateeShorthand; + + declare class Lodash { + // Array + chunk(size: number): (array: Array) => Array>; + chunk(size: number, array: Array): Array>; + compact(array: Array): Array; + concat | T, B: Array | U>( + base: A + ): (elements: B) => Array; + concat | T, B: Array | U>( + base: A, + elements: B + ): Array; + difference(values: Array): (array: Array) => Array; + difference(values: Array, array: Array): Array; + differenceBy( + iteratee: ValueOnlyIteratee + ): ((values: Array) => (array: Array) => T[]) & + ((values: Array, array: Array) => T[]); + differenceBy( + iteratee: ValueOnlyIteratee, + values: Array + ): (array: Array) => T[]; + differenceBy( + iteratee: ValueOnlyIteratee, + values: Array, + array: Array + ): T[]; + differenceWith( + values: T[] + ): ((comparator: Comparator) => (array: T[]) => T[]) & + ((comparator: Comparator, array: T[]) => T[]); + differenceWith( + values: T[], + comparator: Comparator + ): (array: T[]) => T[]; + differenceWith(values: T[], comparator: Comparator, array: T[]): T[]; + drop(n: number): (array: Array) => Array; + drop(n: number, array: Array): Array; + dropLast(n: number): (array: Array) => Array; + dropLast(n: number, array: Array): Array; + dropRight(n: number): (array: Array) => Array; + dropRight(n: number, array: Array): Array; + dropRightWhile(predicate: Predicate): (array: Array) => Array; + dropRightWhile(predicate: Predicate, array: Array): Array; + dropWhile(predicate: Predicate): (array: Array) => Array; + dropWhile(predicate: Predicate, array: Array): Array; + dropLastWhile(predicate: Predicate): (array: Array) => Array; + dropLastWhile(predicate: Predicate, array: Array): Array; + fill( + start: number + ): (( + end: number + ) => ((value: U) => (array: Array) => Array) & + ((value: U, array: Array) => Array)) & + ((end: number, value: U) => (array: Array) => Array) & + ((end: number, value: U, array: Array) => Array); + fill( + start: number, + end: number + ): ((value: U) => (array: Array) => Array) & + ((value: U, array: Array) => Array); + fill( + start: number, + end: number, + value: U + ): (array: Array) => Array; + fill( + start: number, + end: number, + value: U, + array: Array + ): Array; + findIndex(predicate: Predicate): (array: $ReadOnlyArray) => number; + findIndex(predicate: Predicate, array: $ReadOnlyArray): number; + findIndexFrom( + predicate: Predicate + ): ((fromIndex: number) => (array: $ReadOnlyArray) => number) & + ((fromIndex: number, array: $ReadOnlyArray) => number); + findIndexFrom( + predicate: Predicate, + fromIndex: number + ): (array: $ReadOnlyArray) => number; + findIndexFrom( + predicate: Predicate, + fromIndex: number, + array: $ReadOnlyArray + ): number; + findLastIndex( + predicate: Predicate + ): (array: $ReadOnlyArray) => number; + findLastIndex(predicate: Predicate, array: $ReadOnlyArray): number; + findLastIndexFrom( + predicate: Predicate + ): ((fromIndex: number) => (array: $ReadOnlyArray) => number) & + ((fromIndex: number, array: $ReadOnlyArray) => number); + findLastIndexFrom( + predicate: Predicate, + fromIndex: number + ): (array: $ReadOnlyArray) => number; + findLastIndexFrom( + predicate: Predicate, + fromIndex: number, + array: $ReadOnlyArray + ): number; + // alias of _.head + first(array: Array): T; + flatten(array: Array | X>): Array; + unnest(array: Array | X>): Array; + flattenDeep(array: any[]): Array; + flattenDepth(depth: number): (array: any[]) => any[]; + flattenDepth(depth: number, array: any[]): any[]; + fromPairs(pairs: Array<[A, B]>): { [key: A]: B }; + head(array: Array): T; + indexOf(value: T): (array: Array) => number; + indexOf(value: T, array: Array): number; + indexOfFrom( + value: T + ): ((fromIndex: number) => (array: Array) => number) & + ((fromIndex: number, array: Array) => number); + indexOfFrom(value: T, fromIndex: number): (array: Array) => number; + indexOfFrom(value: T, fromIndex: number, array: Array): number; + initial(array: Array): Array; + init(array: Array): Array; + intersection(a1: Array): (a2: Array) => Array; + intersection(a1: Array, a2: Array): Array; + intersectionBy( + iteratee: ValueOnlyIteratee + ): ((a1: Array) => (a2: Array) => Array) & + ((a1: Array, a2: Array) => Array); + intersectionBy( + iteratee: ValueOnlyIteratee, + a1: Array + ): (a2: Array) => Array; + intersectionBy( + iteratee: ValueOnlyIteratee, + a1: Array, + a2: Array + ): Array; + intersectionWith( + comparator: Comparator + ): ((a1: Array) => (a2: Array) => Array) & + ((a1: Array, a2: Array) => Array); + intersectionWith( + comparator: Comparator, + a1: Array + ): (a2: Array) => Array; + intersectionWith( + comparator: Comparator, + a1: Array, + a2: Array + ): Array; + join(separator: string): (array: Array) => string; + join(separator: string, array: Array): string; + last(array: Array): T; + lastIndexOf(value: T): (array: Array) => number; + lastIndexOf(value: T, array: Array): number; + lastIndexOfFrom( + value: T + ): ((fromIndex: number) => (array: Array) => number) & + ((fromIndex: number, array: Array) => number); + lastIndexOfFrom( + value: T, + fromIndex: number + ): (array: Array) => number; + lastIndexOfFrom(value: T, fromIndex: number, array: Array): number; + nth(n: number): (array: T[]) => T; + nth(n: number, array: T[]): T; + pull(value: T): (array: Array) => Array; + pull(value: T, array: Array): Array; + pullAll(values: Array): (array: Array) => Array; + pullAll(values: Array, array: Array): Array; + pullAllBy( + iteratee: ValueOnlyIteratee + ): ((values: Array) => (array: Array) => Array) & + ((values: Array, array: Array) => Array); + pullAllBy( + iteratee: ValueOnlyIteratee, + values: Array + ): (array: Array) => Array; + pullAllBy( + iteratee: ValueOnlyIteratee, + values: Array, + array: Array + ): Array; + pullAllWith( + comparator: Function + ): ((values: T[]) => (array: T[]) => T[]) & + ((values: T[], array: T[]) => T[]); + pullAllWith(comparator: Function, values: T[]): (array: T[]) => T[]; + pullAllWith(comparator: Function, values: T[], array: T[]): T[]; + pullAt(indexed: Array): (array: Array) => Array; + pullAt(indexed: Array, array: Array): Array; + remove(predicate: Predicate): (array: Array) => Array; + remove(predicate: Predicate, array: Array): Array; + reverse(array: Array): Array; + slice( + start: number + ): ((end: number) => (array: Array) => Array) & + ((end: number, array: Array) => Array); + slice(start: number, end: number): (array: Array) => Array; + slice(start: number, end: number, array: Array): Array; + sortedIndex(value: T): (array: Array) => number; + sortedIndex(value: T, array: Array): number; + sortedIndexBy( + iteratee: ValueOnlyIteratee + ): ((value: T) => (array: Array) => number) & + ((value: T, array: Array) => number); + sortedIndexBy( + iteratee: ValueOnlyIteratee, + value: T + ): (array: Array) => number; + sortedIndexBy( + iteratee: ValueOnlyIteratee, + value: T, + array: Array + ): number; + sortedIndexOf(value: T): (array: Array) => number; + sortedIndexOf(value: T, array: Array): number; + sortedLastIndex(value: T): (array: Array) => number; + sortedLastIndex(value: T, array: Array): number; + sortedLastIndexBy( + iteratee: ValueOnlyIteratee + ): ((value: T) => (array: Array) => number) & + ((value: T, array: Array) => number); + sortedLastIndexBy( + iteratee: ValueOnlyIteratee, + value: T + ): (array: Array) => number; + sortedLastIndexBy( + iteratee: ValueOnlyIteratee, + value: T, + array: Array + ): number; + sortedLastIndexOf(value: T): (array: Array) => number; + sortedLastIndexOf(value: T, array: Array): number; + sortedUniq(array: Array): Array; + sortedUniqBy( + iteratee: (value: T) => mixed + ): (array: Array) => Array; + sortedUniqBy(iteratee: (value: T) => mixed, array: Array): Array; + tail(array: Array): Array; + take(n: number): (array: Array) => Array; + take(n: number, array: Array): Array; + takeRight(n: number): (array: Array) => Array; + takeRight(n: number, array: Array): Array; + takeLast(n: number): (array: Array) => Array; + takeLast(n: number, array: Array): Array; + takeRightWhile(predicate: Predicate): (array: Array) => Array; + takeRightWhile(predicate: Predicate, array: Array): Array; + takeLastWhile(predicate: Predicate): (array: Array) => Array; + takeLastWhile(predicate: Predicate, array: Array): Array; + takeWhile(predicate: Predicate): (array: Array) => Array; + takeWhile(predicate: Predicate, array: Array): Array; + union(a1: Array): (a2: Array) => Array; + union(a1: Array, a2: Array): Array; + unionBy( + iteratee: ValueOnlyIteratee + ): ((a1: Array) => (a2: Array) => Array) & + ((a1: Array, a2: Array) => Array); + unionBy( + iteratee: ValueOnlyIteratee, + a1: Array + ): (a2: Array) => Array; + unionBy( + iteratee: ValueOnlyIteratee, + a1: Array, + a2: Array + ): Array; + unionWith( + comparator: Comparator + ): ((a1: Array) => (a2: Array) => Array) & + ((a1: Array, a2: Array) => Array); + unionWith( + comparator: Comparator, + a1: Array + ): (a2: Array) => Array; + unionWith( + comparator: Comparator, + a1: Array, + a2: Array + ): Array; + uniq(array: Array): Array; + uniqBy(iteratee: ValueOnlyIteratee): (array: Array) => Array; + uniqBy(iteratee: ValueOnlyIteratee, array: Array): Array; + uniqWith(comparator: Comparator): (array: Array) => Array; + uniqWith(comparator: Comparator, array: Array): Array; + unzip(array: Array): Array; + unzipWith(iteratee: Iteratee): (array: Array) => Array; + unzipWith(iteratee: Iteratee, array: Array): Array; + without(values: Array): (array: Array) => Array; + without(values: Array, array: Array): Array; + xor(a1: Array): (a2: Array) => Array; + xor(a1: Array, a2: Array): Array; + symmetricDifference(a1: Array): (a2: Array) => Array; + symmetricDifference(a1: Array, a2: Array): Array; + xorBy( + iteratee: ValueOnlyIteratee + ): ((a1: Array) => (a2: Array) => Array) & + ((a1: Array, a2: Array) => Array); + xorBy( + iteratee: ValueOnlyIteratee, + a1: Array + ): (a2: Array) => Array; + xorBy( + iteratee: ValueOnlyIteratee, + a1: Array, + a2: Array + ): Array; + symmetricDifferenceBy( + iteratee: ValueOnlyIteratee + ): ((a1: Array) => (a2: Array) => Array) & + ((a1: Array, a2: Array) => Array); + symmetricDifferenceBy( + iteratee: ValueOnlyIteratee, + a1: Array + ): (a2: Array) => Array; + symmetricDifferenceBy( + iteratee: ValueOnlyIteratee, + a1: Array, + a2: Array + ): Array; + xorWith( + comparator: Comparator + ): ((a1: Array) => (a2: Array) => Array) & + ((a1: Array, a2: Array) => Array); + xorWith( + comparator: Comparator, + a1: Array + ): (a2: Array) => Array; + xorWith(comparator: Comparator, a1: Array, a2: Array): Array; + symmetricDifferenceWith( + comparator: Comparator + ): ((a1: Array) => (a2: Array) => Array) & + ((a1: Array, a2: Array) => Array); + symmetricDifferenceWith( + comparator: Comparator, + a1: Array + ): (a2: Array) => Array; + symmetricDifferenceWith( + comparator: Comparator, + a1: Array, + a2: Array + ): Array; + zip(a1: A[]): (a2: B[]) => Array<[A, B]>; + zip(a1: A[], a2: B[]): Array<[A, B]>; + zipAll(arrays: Array>): Array; + zipObject(props?: Array): (values?: Array) => { [key: K]: V }; + zipObject(props?: Array, values?: Array): { [key: K]: V }; + zipObj(props: Array): (values: Array) => Object; + zipObj(props: Array, values: Array): Object; + zipObjectDeep(props: any[]): (values: any) => Object; + zipObjectDeep(props: any[], values: any): Object; + zipWith( + iteratee: Iteratee + ): ((a1: NestedArray) => (a2: NestedArray) => Array) & + ((a1: NestedArray, a2: NestedArray) => Array); + zipWith( + iteratee: Iteratee, + a1: NestedArray + ): (a2: NestedArray) => Array; + zipWith( + iteratee: Iteratee, + a1: NestedArray, + a2: NestedArray + ): Array; + // Collection + countBy( + iteratee: ValueOnlyIteratee + ): (collection: Array | { [id: any]: T }) => { [string]: number }; + countBy( + iteratee: ValueOnlyIteratee, + collection: Array | { [id: any]: T } + ): { [string]: number }; + // alias of _.forEach + each( + iteratee: Iteratee | OIteratee + ): (collection: Array | { [id: any]: T }) => Array; + each( + iteratee: Iteratee | OIteratee, + collection: Array | { [id: any]: T } + ): Array; + // alias of _.forEachRight + eachRight( + iteratee: Iteratee | OIteratee + ): (collection: Array | { [id: any]: T }) => Array; + eachRight( + iteratee: Iteratee | OIteratee, + collection: Array | { [id: any]: T } + ): Array; + every( + iteratee: Iteratee | OIteratee + ): (collection: Array | { [id: any]: T }) => boolean; + every( + iteratee: Iteratee | OIteratee, + collection: Array | { [id: any]: T } + ): boolean; + all( + iteratee: Iteratee | OIteratee + ): (collection: Array | { [id: any]: T }) => boolean; + all( + iteratee: Iteratee | OIteratee, + collection: Array | { [id: any]: T } + ): boolean; + filter( + predicate: Predicate | OPredicate + ): (collection: Array | { [id: any]: T }) => Array; + filter( + predicate: Predicate | OPredicate, + collection: Array | { [id: any]: T } + ): Array; + find( + predicate: Predicate | OPredicate + ): (collection: $ReadOnlyArray | { [id: any]: T }) => T | void; + find( + predicate: Predicate | OPredicate, + collection: $ReadOnlyArray | { [id: any]: T } + ): T | void; + findFrom( + predicate: Predicate | OPredicate + ): (( + fromIndex: number + ) => (collection: $ReadOnlyArray | { [id: any]: T }) => T | void) & + (( + fromIndex: number, + collection: $ReadOnlyArray | { [id: any]: T } + ) => T | void); + findFrom( + predicate: Predicate | OPredicate, + fromIndex: number + ): (collection: Array | { [id: any]: T }) => T | void; + findFrom( + predicate: Predicate | OPredicate, + fromIndex: number, + collection: $ReadOnlyArray | { [id: any]: T } + ): T | void; + findLast( + predicate: Predicate | OPredicate + ): (collection: $ReadOnlyArray | { [id: any]: T }) => T | void; + findLast( + predicate: Predicate | OPredicate, + collection: $ReadOnlyArray | { [id: any]: T } + ): T | void; + findLastFrom( + predicate: Predicate | OPredicate + ): (( + fromIndex: number + ) => (collection: $ReadOnlyArray | { [id: any]: T }) => T | void) & + (( + fromIndex: number, + collection: $ReadOnlyArray | { [id: any]: T } + ) => T | void); + findLastFrom( + predicate: Predicate | OPredicate, + fromIndex: number + ): (collection: $ReadOnlyArray | { [id: any]: T }) => T | void; + findLastFrom( + predicate: Predicate | OPredicate, + fromIndex: number, + collection: $ReadOnlyArray | { [id: any]: T } + ): T | void; + flatMap( + iteratee: FlatMapIteratee | OFlatMapIteratee + ): (collection: Array | { [id: any]: T }) => Array; + flatMap( + iteratee: FlatMapIteratee | OFlatMapIteratee, + collection: Array | { [id: any]: T } + ): Array; + flatMapDeep( + iteratee: FlatMapIteratee | OFlatMapIteratee + ): (collection: Array | { [id: any]: T }) => Array; + flatMapDeep( + iteratee: FlatMapIteratee | OFlatMapIteratee, + collection: Array | { [id: any]: T } + ): Array; + flatMapDepth( + iteratee: FlatMapIteratee | OFlatMapIteratee + ): (( + depth: number + ) => (collection: Array | { [id: any]: T }) => Array) & + ((depth: number, collection: Array | { [id: any]: T }) => Array); + flatMapDepth( + iteratee: FlatMapIteratee | OFlatMapIteratee, + depth: number + ): (collection: Array | { [id: any]: T }) => Array; + flatMapDepth( + iteratee: FlatMapIteratee | OFlatMapIteratee, + depth: number, + collection: Array | { [id: any]: T } + ): Array; + forEach( + iteratee: Iteratee | OIteratee + ): (collection: Array | { [id: any]: T }) => Array; + forEach( + iteratee: Iteratee | OIteratee, + collection: Array | { [id: any]: T } + ): Array; + forEachRight( + iteratee: Iteratee | OIteratee + ): (collection: Array | { [id: any]: T }) => Array; + forEachRight( + iteratee: Iteratee | OIteratee, + collection: Array | { [id: any]: T } + ): Array; + groupBy( + iteratee: ValueOnlyIteratee + ): (collection: Array | { [id: any]: T }) => { [key: V]: Array }; + groupBy( + iteratee: ValueOnlyIteratee, + collection: Array | { [id: any]: T } + ): { [key: V]: Array }; + includes(value: string): (str: string) => boolean; + includes(value: string, str: string): boolean; + includes(value: T): (collection: Array | { [id: any]: T }) => boolean; + includes(value: T, collection: Array | { [id: any]: T }): boolean; + contains(value: string): (str: string) => boolean; + contains(value: string, str: string): boolean; + contains(value: T): (collection: Array | { [id: any]: T }) => boolean; + contains(value: T, collection: Array | { [id: any]: T }): boolean; + includesFrom( + value: string + ): ((fromIndex: number) => (str: string) => boolean) & + ((fromIndex: number, str: string) => boolean); + includesFrom(value: string, fromIndex: number): (str: string) => boolean; + includesFrom(value: string, fromIndex: number, str: string): boolean; + includesFrom( + value: T + ): ((fromIndex: number) => (collection: Array) => boolean) & + ((fromIndex: number, collection: Array) => boolean); + includesFrom( + value: T, + fromIndex: number + ): (collection: Array) => boolean; + includesFrom(value: T, fromIndex: number, collection: Array): boolean; + invokeMap( + path: ((value: T) => Array | string) | Array | string + ): (collection: Array | { [id: any]: T }) => Array; + invokeMap( + path: ((value: T) => Array | string) | Array | string, + collection: Array | { [id: any]: T } + ): Array; + invokeArgsMap( + path: ((value: T) => Array | string) | Array | string + ): (( + collection: Array | { [id: any]: T } + ) => (args: Array) => Array) & + (( + collection: Array | { [id: any]: T }, + args: Array + ) => Array); + invokeArgsMap( + path: ((value: T) => Array | string) | Array | string, + collection: Array | { [id: any]: T } + ): (args: Array) => Array; + invokeArgsMap( + path: ((value: T) => Array | string) | Array | string, + collection: Array | { [id: any]: T }, + args: Array + ): Array; + keyBy( + iteratee: ValueOnlyIteratee + ): (collection: Array | { [id: any]: T }) => { [key: V]: T }; + keyBy( + iteratee: ValueOnlyIteratee, + collection: Array | { [id: any]: T } + ): { [key: V]: T }; + indexBy( + iteratee: ValueOnlyIteratee + ): (collection: Array | { [id: any]: T }) => { [key: V]: T }; + indexBy( + iteratee: ValueOnlyIteratee, + collection: Array | { [id: any]: T } + ): { [key: V]: T }; + map( + iteratee: MapIterator | OMapIterator + ): (collection: Array | { [id: any]: T }) => Array; + map( + iteratee: MapIterator | OMapIterator, + collection: Array | { [id: any]: T } + ): Array; + map(iteratee: (char: string) => any): (str: string) => string; + map(iteratee: (char: string) => any, str: string): string; + pluck( + iteratee: MapIterator | OMapIterator + ): (collection: Array | { [id: any]: T }) => Array; + pluck( + iteratee: MapIterator | OMapIterator, + collection: Array | { [id: any]: T } + ): Array; + pluck(iteratee: (char: string) => any): (str: string) => string; + pluck(iteratee: (char: string) => any, str: string): string; + orderBy( + iteratees: Array | OIteratee<*>> | string + ): (( + orders: Array<"asc" | "desc"> | string + ) => (collection: Array | { [id: any]: T }) => Array) & + (( + orders: Array<"asc" | "desc"> | string, + collection: Array | { [id: any]: T } + ) => Array); + orderBy( + iteratees: Array | OIteratee<*>> | string, + orders: Array<"asc" | "desc"> | string + ): (collection: Array | { [id: any]: T }) => Array; + orderBy( + iteratees: Array | OIteratee<*>> | string, + orders: Array<"asc" | "desc"> | string, + collection: Array | { [id: any]: T } + ): Array; + partition( + predicate: Predicate | OPredicate + ): (collection: Array | { [id: any]: T }) => [Array, Array]; + partition( + predicate: Predicate | OPredicate, + collection: Array | { [id: any]: T } + ): [Array, Array]; + reduce( + iteratee: (accumulator: U, value: T) => U + ): ((accumulator: U) => (collection: Array | { [id: any]: T }) => U) & + ((accumulator: U, collection: Array | { [id: any]: T }) => U); + reduce( + iteratee: (accumulator: U, value: T) => U, + accumulator: U + ): (collection: Array | { [id: any]: T }) => U; + reduce( + iteratee: (accumulator: U, value: T) => U, + accumulator: U, + collection: Array | { [id: any]: T } + ): U; + reduceRight( + iteratee: (value: T, accumulator: U) => U + ): ((accumulator: U) => (collection: Array | { [id: any]: T }) => U) & + ((accumulator: U, collection: Array | { [id: any]: T }) => U); + reduceRight( + iteratee: (value: T, accumulator: U) => U, + accumulator: U + ): (collection: Array | { [id: any]: T }) => U; + reduceRight( + iteratee: (value: T, accumulator: U) => U, + accumulator: U, + collection: Array | { [id: any]: T } + ): U; + reject( + predicate: Predicate | OPredicate + ): (collection: Array | { [id: any]: T }) => Array; + reject( + predicate: Predicate | OPredicate, + collection: Array | { [id: any]: T } + ): Array; + sample(collection: Array | { [id: any]: T }): T; + sampleSize( + n: number + ): (collection: Array | { [id: any]: T }) => Array; + sampleSize(n: number, collection: Array | { [id: any]: T }): Array; + shuffle(collection: Array | { [id: any]: T }): Array; + size(collection: Array | Object): number; + some( + predicate: Predicate | OPredicate + ): (collection: Array | { [id: any]: T }) => boolean; + some( + predicate: Predicate | OPredicate, + collection: Array | { [id: any]: T } + ): boolean; + any( + predicate: Predicate | OPredicate + ): (collection: Array | { [id: any]: T }) => boolean; + any( + predicate: Predicate | OPredicate, + collection: Array | { [id: any]: T } + ): boolean; + sortBy( + iteratees: Array | OIteratee> | Iteratee | OIteratee + ): (collection: Array | { [id: any]: T }) => Array; + sortBy( + iteratees: Array | OIteratee> | Iteratee | OIteratee, + collection: Array | { [id: any]: T } + ): Array; + + // Date + now(): number; + + // Function + after(fn: Function): (n: number) => Function; + after(fn: Function, n: number): Function; + ary(func: Function): Function; + nAry(n: number): (func: Function) => Function; + nAry(n: number, func: Function): Function; + before(fn: Function): (n: number) => Function; + before(fn: Function, n: number): Function; + bind(func: Function): (thisArg: any) => Function; + bind(func: Function, thisArg: any): Function; + bindKey(obj: Object): (key: string) => Function; + bindKey(obj: Object, key: string): Function; + curry: Curry; + curryN(arity: number): (func: Function) => Function; + curryN(arity: number, func: Function): Function; + curryRight(func: Function): Function; + curryRightN(arity: number): (func: Function) => Function; + curryRightN(arity: number, func: Function): Function; + debounce(wait: number): (func: F) => F; + debounce(wait: number, func: F): F; + defer(func: Function): number; + delay(wait: number): (func: Function) => number; + delay(wait: number, func: Function): number; + flip(func: Function): Function; + memoize(func: F): F; + negate(predicate: Function): Function; + complement(predicate: Function): Function; + once(func: Function): Function; + overArgs(func: Function): (transforms: Array) => Function; + overArgs(func: Function, transforms: Array): Function; + useWith(func: Function): (transforms: Array) => Function; + useWith(func: Function, transforms: Array): Function; + partial(func: Function): (partials: any[]) => Function; + partial(func: Function, partials: any[]): Function; + partialRight(func: Function): (partials: Array) => Function; + partialRight(func: Function, partials: Array): Function; + rearg(indexes: Array): (func: Function) => Function; + rearg(indexes: Array, func: Function): Function; + rest(func: Function): Function; + unapply(func: Function): Function; + restFrom(start: number): (func: Function) => Function; + restFrom(start: number, func: Function): Function; + spread(func: Function): Function; + apply(func: Function): Function; + spreadFrom(start: number): (func: Function) => Function; + spreadFrom(start: number, func: Function): Function; + throttle(wait: number): (func: Function) => Function; + throttle(wait: number, func: Function): Function; + unary(func: Function): Function; + wrap(wrapper: Function): (value: any) => Function; + wrap(wrapper: Function, value: any): Function; + + // Lang + castArray(value: *): any[]; + clone(value: T): T; + cloneDeep(value: T): T; + cloneDeepWith( + customizer: (value: T, key: number | string, object: T, stack: any) => U + ): (value: T) => U; + cloneDeepWith( + customizer: (value: T, key: number | string, object: T, stack: any) => U, + value: T + ): U; + cloneWith( + customizer: (value: T, key: number | string, object: T, stack: any) => U + ): (value: T) => U; + cloneWith( + customizer: (value: T, key: number | string, object: T, stack: any) => U, + value: T + ): U; + conformsTo( + predicates: T & { [key: string]: (x: any) => boolean } + ): (source: T) => boolean; + conformsTo( + predicates: T & { [key: string]: (x: any) => boolean }, + source: T + ): boolean; + where( + predicates: T & { [key: string]: (x: any) => boolean } + ): (source: T) => boolean; + where( + predicates: T & { [key: string]: (x: any) => boolean }, + source: T + ): boolean; + conforms( + predicates: T & { [key: string]: (x: any) => boolean } + ): (source: T) => boolean; + conforms( + predicates: T & { [key: string]: (x: any) => boolean }, + source: T + ): boolean; + eq(value: any): (other: any) => boolean; + eq(value: any, other: any): boolean; + identical(value: any): (other: any) => boolean; + identical(value: any, other: any): boolean; + gt(value: any): (other: any) => boolean; + gt(value: any, other: any): boolean; + gte(value: any): (other: any) => boolean; + gte(value: any, other: any): boolean; + isArguments(value: any): boolean; + isArray(value: any): boolean; + isArrayBuffer(value: any): boolean; + isArrayLike(value: any): boolean; + isArrayLikeObject(value: any): boolean; + isBoolean(value: any): boolean; + isBuffer(value: any): boolean; + isDate(value: any): boolean; + isElement(value: any): boolean; + isEmpty(value: any): boolean; + isEqual(value: any): (other: any) => boolean; + isEqual(value: any, other: any): boolean; + equals(value: any): (other: any) => boolean; + equals(value: any, other: any): boolean; + isEqualWith( + customizer: ( + objValue: any, + otherValue: any, + key: number | string, + object: T, + other: U, + stack: any + ) => boolean | void + ): ((value: T) => (other: U) => boolean) & + ((value: T, other: U) => boolean); + isEqualWith( + customizer: ( + objValue: any, + otherValue: any, + key: number | string, + object: T, + other: U, + stack: any + ) => boolean | void, + value: T + ): (other: U) => boolean; + isEqualWith( + customizer: ( + objValue: any, + otherValue: any, + key: number | string, + object: T, + other: U, + stack: any + ) => boolean | void, + value: T, + other: U + ): boolean; + isError(value: any): boolean; + isFinite(value: any): boolean; + isFunction(value: Function): true; + isFunction(value: number | string | void | null | Object): false; + isInteger(value: any): boolean; + isLength(value: any): boolean; + isMap(value: any): boolean; + isMatch(source: Object): (object: Object) => boolean; + isMatch(source: Object, object: Object): boolean; + whereEq(source: Object): (object: Object) => boolean; + whereEq(source: Object, object: Object): boolean; + isMatchWith( + customizer: ( + objValue: any, + srcValue: any, + key: number | string, + object: T, + source: U + ) => boolean | void + ): ((source: U) => (object: T) => boolean) & + ((source: U, object: T) => boolean); + isMatchWith( + customizer: ( + objValue: any, + srcValue: any, + key: number | string, + object: T, + source: U + ) => boolean | void, + source: U + ): (object: T) => boolean; + isMatchWith( + customizer: ( + objValue: any, + srcValue: any, + key: number | string, + object: T, + source: U + ) => boolean | void, + source: U, + object: T + ): boolean; + isNaN(value: any): boolean; + isNative(value: any): boolean; + isNil(value: any): boolean; + isNull(value: any): boolean; + isNumber(value: any): boolean; + isObject(value: any): boolean; + isObjectLike(value: any): boolean; + isPlainObject(value: any): boolean; + isRegExp(value: any): boolean; + isSafeInteger(value: any): boolean; + isSet(value: any): boolean; + isString(value: string): true; + isString( + value: number | boolean | Function | void | null | Object | Array + ): false; + isSymbol(value: any): boolean; + isTypedArray(value: any): boolean; + isUndefined(value: any): boolean; + isWeakMap(value: any): boolean; + isWeakSet(value: any): boolean; + lt(value: any): (other: any) => boolean; + lt(value: any, other: any): boolean; + lte(value: any): (other: any) => boolean; + lte(value: any, other: any): boolean; + toArray(value: any): Array; + toFinite(value: any): number; + toInteger(value: any): number; + toLength(value: any): number; + toNumber(value: any): number; + toPlainObject(value: any): Object; + toSafeInteger(value: any): number; + toString(value: any): string; + + // Math + add(augend: number): (addend: number) => number; + add(augend: number, addend: number): number; + ceil(number: number): number; + divide(dividend: number): (divisor: number) => number; + divide(dividend: number, divisor: number): number; + floor(number: number): number; + max(array: Array): T; + maxBy(iteratee: Iteratee): (array: Array) => T; + maxBy(iteratee: Iteratee, array: Array): T; + mean(array: Array<*>): number; + meanBy(iteratee: Iteratee): (array: Array) => number; + meanBy(iteratee: Iteratee, array: Array): number; + min(array: Array): T; + minBy(iteratee: Iteratee): (array: Array) => T; + minBy(iteratee: Iteratee, array: Array): T; + multiply(multiplier: number): (multiplicand: number) => number; + multiply(multiplier: number, multiplicand: number): number; + round(number: number): number; + subtract(minuend: number): (subtrahend: number) => number; + subtract(minuend: number, subtrahend: number): number; + sum(array: Array<*>): number; + sumBy(iteratee: Iteratee): (array: Array) => number; + sumBy(iteratee: Iteratee, array: Array): number; + + // number + clamp( + lower: number + ): ((upper: number) => (number: number) => number) & + ((upper: number, number: number) => number); + clamp(lower: number, upper: number): (number: number) => number; + clamp(lower: number, upper: number, number: number): number; + inRange( + start: number + ): ((end: number) => (number: number) => boolean) & + ((end: number, number: number) => boolean); + inRange(start: number, end: number): (number: number) => boolean; + inRange(start: number, end: number, number: number): boolean; + random(lower: number): (upper: number) => number; + random(lower: number, upper: number): number; + + // Object + assign(object: Object): (source: Object) => Object; + assign(object: Object, source: Object): Object; + assignAll(objects: Array): Object; + assignInAll(objects: Array): Object; + extendAll(objects: Array): Object; + assignIn(a: A): (b: B) => A & B; + assignIn(a: A, b: B): A & B; + assignInWith( + customizer: ( + objValue: any, + srcValue: any, + key: string, + object: T, + source: A + ) => any | void + ): ((object: T) => (s1: A) => Object) & ((object: T, s1: A) => Object); + assignInWith( + customizer: ( + objValue: any, + srcValue: any, + key: string, + object: T, + source: A + ) => any | void, + object: T + ): (s1: A) => Object; + assignInWith( + customizer: ( + objValue: any, + srcValue: any, + key: string, + object: T, + source: A + ) => any | void, + object: T, + s1: A + ): Object; + assignWith( + customizer: ( + objValue: any, + srcValue: any, + key: string, + object: T, + source: A + ) => any | void + ): ((object: T) => (s1: A) => Object) & ((object: T, s1: A) => Object); + assignWith( + customizer: ( + objValue: any, + srcValue: any, + key: string, + object: T, + source: A + ) => any | void, + object: T + ): (s1: A) => Object; + assignWith( + customizer: ( + objValue: any, + srcValue: any, + key: string, + object: T, + source: A + ) => any | void, + object: T, + s1: A + ): Object; + assignInAllWith( + customizer: ( + objValue: any, + srcValue: any, + key: string, + object: Object, + source: Object + ) => any | void + ): (objects: Array) => Object; + assignInAllWith( + customizer: ( + objValue: any, + srcValue: any, + key: string, + object: Object, + source: Object + ) => any | void, + objects: Array + ): Object; + extendAllWith( + customizer: ( + objValue: any, + srcValue: any, + key: string, + object: Object, + source: Object + ) => any | void + ): (objects: Array) => Object; + extendAllWith( + customizer: ( + objValue: any, + srcValue: any, + key: string, + object: Object, + source: Object + ) => any | void, + objects: Array + ): Object; + assignAllWith( + customizer: ( + objValue: any, + srcValue: any, + key: string, + object: Object, + source: Object + ) => any | void + ): (objects: Array) => Object; + assignAllWith( + customizer: ( + objValue: any, + srcValue: any, + key: string, + object: Object, + source: Object + ) => any | void, + objects: Array + ): Object; + at(paths: Array): (object: Object) => Array; + at(paths: Array, object: Object): Array; + props(paths: Array): (object: Object) => Array; + props(paths: Array, object: Object): Array; + paths(paths: Array): (object: Object) => Array; + paths(paths: Array, object: Object): Array; + create(prototype: T): $Supertype; + defaults(source: Object): (object: Object) => Object; + defaults(source: Object, object: Object): Object; + defaultsAll(objects: Array): Object; + defaultsDeep(source: Object): (object: Object) => Object; + defaultsDeep(source: Object, object: Object): Object; + defaultsDeepAll(objects: Array): Object; + // alias for _.toPairs + entries(object: Object): Array<[string, any]>; + // alias for _.toPairsIn + entriesIn(object: Object): Array<[string, any]>; + // alias for _.assignIn + extend(a: A): (b: B) => A & B; + extend(a: A, b: B): A & B; + // alias for _.assignInWith + extendWith( + customizer: ( + objValue: any, + srcValue: any, + key: string, + object: T, + source: A + ) => any | void + ): ((object: T) => (s1: A) => Object) & ((object: T, s1: A) => Object); + extendWith( + customizer: ( + objValue: any, + srcValue: any, + key: string, + object: T, + source: A + ) => any | void, + object: T + ): (s1: A) => Object; + extendWith( + customizer: ( + objValue: any, + srcValue: any, + key: string, + object: T, + source: A + ) => any | void, + object: T, + s1: A + ): Object; + findKey( + predicate: OPredicate + ): (object: T) => string | void; + findKey( + predicate: OPredicate, + object: T + ): string | void; + findLastKey( + predicate: OPredicate + ): (object: T) => string | void; + findLastKey( + predicate: OPredicate, + object: T + ): string | void; + forIn(iteratee: OIteratee<*>): (object: Object) => Object; + forIn(iteratee: OIteratee<*>, object: Object): Object; + forInRight(iteratee: OIteratee<*>): (object: Object) => Object; + forInRight(iteratee: OIteratee<*>, object: Object): Object; + forOwn(iteratee: OIteratee<*>): (object: Object) => Object; + forOwn(iteratee: OIteratee<*>, object: Object): Object; + forOwnRight(iteratee: OIteratee<*>): (object: Object) => Object; + forOwnRight(iteratee: OIteratee<*>, object: Object): Object; + functions(object: Object): Array; + functionsIn(object: Object): Array; + get(path: Array | string): (object: Object | Array) => any; + get(path: Array | string, object: Object | Array): any; + prop(path: Array | string): (object: Object | Array) => any; + prop(path: Array | string, object: Object | Array): any; + path(path: Array | string): (object: Object | Array) => any; + path(path: Array | string, object: Object | Array): any; + getOr( + defaultValue: any + ): (( + path: Array | string + ) => (object: Object | Array) => any) & + ((path: Array | string, object: Object | Array) => any); + getOr( + defaultValue: any, + path: Array | string + ): (object: Object | Array) => any; + getOr( + defaultValue: any, + path: Array | string, + object: Object | Array + ): any; + propOr( + defaultValue: any + ): (( + path: Array | string + ) => (object: Object | Array) => any) & + ((path: Array | string, object: Object | Array) => any); + propOr( + defaultValue: any, + path: Array | string + ): (object: Object | Array) => any; + propOr( + defaultValue: any, + path: Array | string, + object: Object | Array + ): any; + pathOr( + defaultValue: any + ): (( + path: Array | string + ) => (object: Object | Array) => any) & + ((path: Array | string, object: Object | Array) => any); + pathOr( + defaultValue: any, + path: Array | string + ): (object: Object | Array) => any; + pathOr( + defaultValue: any, + path: Array | string, + object: Object | Array + ): any; + has(path: Array | string): (object: Object) => boolean; + has(path: Array | string, object: Object): boolean; + hasIn(path: Array | string): (object: Object) => boolean; + hasIn(path: Array | string, object: Object): boolean; + invert(object: Object): Object; + invertObj(object: Object): Object; + invertBy(iteratee: Function): (object: Object) => Object; + invertBy(iteratee: Function, object: Object): Object; + invoke(path: Array | string): (object: Object) => any; + invoke(path: Array | string, object: Object): any; + invokeArgs( + path: Array | string + ): ((object: Object) => (args: Array) => any) & + ((object: Object, args: Array) => any); + invokeArgs( + path: Array | string, + object: Object + ): (args: Array) => any; + invokeArgs( + path: Array | string, + object: Object, + args: Array + ): any; + keys(object: { [key: K]: any }): Array; + keys(object: Object): Array; + keysIn(object: Object): Array; + mapKeys(iteratee: OIteratee<*>): (object: Object) => Object; + mapKeys(iteratee: OIteratee<*>, object: Object): Object; + mapValues(iteratee: OIteratee<*>): (object: Object) => Object; + mapValues(iteratee: OIteratee<*>, object: Object): Object; + merge(object: Object): (source: Object) => Object; + merge(object: Object, source: Object): Object; + mergeAll(objects: Array): Object; + mergeWith( + customizer: ( + objValue: any, + srcValue: any, + key: string, + object: T, + source: A | B + ) => any | void + ): ((object: T) => (s1: A) => Object) & ((object: T, s1: A) => Object); + mergeWith( + customizer: ( + objValue: any, + srcValue: any, + key: string, + object: T, + source: A | B + ) => any | void, + object: T + ): (s1: A) => Object; + mergeWith( + customizer: ( + objValue: any, + srcValue: any, + key: string, + object: T, + source: A | B + ) => any | void, + object: T, + s1: A + ): Object; + mergeAllWith( + customizer: ( + objValue: any, + srcValue: any, + key: string, + object: Object, + source: Object + ) => any | void + ): (objects: Array) => Object; + mergeAllWith( + customizer: ( + objValue: any, + srcValue: any, + key: string, + object: Object, + source: Object + ) => any | void, + objects: Array + ): Object; + omit(props: Array): (object: Object) => Object; + omit(props: Array, object: Object): Object; + omitAll(props: Array): (object: Object) => Object; + omitAll(props: Array, object: Object): Object; + omitBy( + predicate: OPredicate + ): (object: T) => Object; + omitBy(predicate: OPredicate, object: T): Object; + pick(props: Array): (object: Object) => Object; + pick(props: Array, object: Object): Object; + pickAll(props: Array): (object: Object) => Object; + pickAll(props: Array, object: Object): Object; + pickBy( + predicate: OPredicate + ): (object: T) => Object; + pickBy(predicate: OPredicate, object: T): Object; + result(path: Array | string): (object: Object) => any; + result(path: Array | string, object: Object): any; + set( + path: Array | string + ): ((value: any) => (object: Object) => Object) & + ((value: any, object: Object) => Object); + set(path: Array | string, value: any): (object: Object) => Object; + set(path: Array | string, value: any, object: Object): Object; + assoc( + path: Array | string + ): ((value: any) => (object: Object) => Object) & + ((value: any, object: Object) => Object); + assoc(path: Array | string, value: any): (object: Object) => Object; + assoc(path: Array | string, value: any, object: Object): Object; + assocPath( + path: Array | string + ): ((value: any) => (object: Object) => Object) & + ((value: any, object: Object) => Object); + assocPath( + path: Array | string, + value: any + ): (object: Object) => Object; + assocPath(path: Array | string, value: any, object: Object): Object; + setWith( + customizer: (nsValue: any, key: string, nsObject: T) => any + ): (( + path: Array | string + ) => ((value: any) => (object: T) => Object) & + ((value: any, object: T) => Object)) & + ((path: Array | string, value: any) => (object: T) => Object) & + ((path: Array | string, value: any, object: T) => Object); + setWith( + customizer: (nsValue: any, key: string, nsObject: T) => any, + path: Array | string + ): ((value: any) => (object: T) => Object) & + ((value: any, object: T) => Object); + setWith( + customizer: (nsValue: any, key: string, nsObject: T) => any, + path: Array | string, + value: any + ): (object: T) => Object; + setWith( + customizer: (nsValue: any, key: string, nsObject: T) => any, + path: Array | string, + value: any, + object: T + ): Object; + toPairs(object: Object | Array<*>): Array<[string, any]>; + toPairsIn(object: Object): Array<[string, any]>; + transform( + iteratee: OIteratee<*> + ): ((accumulator: any) => (collection: Object | Array) => any) & + ((accumulator: any, collection: Object | Array) => any); + transform( + iteratee: OIteratee<*>, + accumulator: any + ): (collection: Object | Array) => any; + transform( + iteratee: OIteratee<*>, + accumulator: any, + collection: Object | Array + ): any; + unset(path: Array | string): (object: Object) => boolean; + unset(path: Array | string, object: Object): boolean; + dissoc(path: Array | string): (object: Object) => boolean; + dissoc(path: Array | string, object: Object): boolean; + dissocPath(path: Array | string): (object: Object) => boolean; + dissocPath(path: Array | string, object: Object): boolean; + update( + path: string[] | string + ): ((updater: Function) => (object: Object) => Object) & + ((updater: Function, object: Object) => Object); + update( + path: string[] | string, + updater: Function + ): (object: Object) => Object; + update(path: string[] | string, updater: Function, object: Object): Object; + updateWith( + customizer: Function + ): (( + path: string[] | string + ) => ((updater: Function) => (object: Object) => Object) & + ((updater: Function, object: Object) => Object)) & + (( + path: string[] | string, + updater: Function + ) => (object: Object) => Object) & + ((path: string[] | string, updater: Function, object: Object) => Object); + updateWith( + customizer: Function, + path: string[] | string + ): ((updater: Function) => (object: Object) => Object) & + ((updater: Function, object: Object) => Object); + updateWith( + customizer: Function, + path: string[] | string, + updater: Function + ): (object: Object) => Object; + updateWith( + customizer: Function, + path: string[] | string, + updater: Function, + object: Object + ): Object; + values(object: Object): Array; + valuesIn(object: Object): Array; + + tap(interceptor: (value: T) => any): (value: T) => T; + tap(interceptor: (value: T) => any, value: T): T; + thru(interceptor: (value: T1) => T2): (value: T1) => T2; + thru(interceptor: (value: T1) => T2, value: T1): T2; + + // String + camelCase(string: string): string; + capitalize(string: string): string; + deburr(string: string): string; + endsWith(target: string): (string: string) => boolean; + endsWith(target: string, string: string): boolean; + escape(string: string): string; + escapeRegExp(string: string): string; + kebabCase(string: string): string; + lowerCase(string: string): string; + lowerFirst(string: string): string; + pad(length: number): (string: string) => string; + pad(length: number, string: string): string; + padChars( + chars: string + ): ((length: number) => (string: string) => string) & + ((length: number, string: string) => string); + padChars(chars: string, length: number): (string: string) => string; + padChars(chars: string, length: number, string: string): string; + padEnd(length: number): (string: string) => string; + padEnd(length: number, string: string): string; + padCharsEnd( + chars: string + ): ((length: number) => (string: string) => string) & + ((length: number, string: string) => string); + padCharsEnd(chars: string, length: number): (string: string) => string; + padCharsEnd(chars: string, length: number, string: string): string; + padStart(length: number): (string: string) => string; + padStart(length: number, string: string): string; + padCharsStart( + chars: string + ): ((length: number) => (string: string) => string) & + ((length: number, string: string) => string); + padCharsStart(chars: string, length: number): (string: string) => string; + padCharsStart(chars: string, length: number, string: string): string; + parseInt(radix: number): (string: string) => number; + parseInt(radix: number, string: string): number; + repeat(n: number): (string: string) => string; + repeat(n: number, string: string): string; + replace( + pattern: RegExp | string + ): (( + replacement: ((string: string) => string) | string + ) => (string: string) => string) & + (( + replacement: ((string: string) => string) | string, + string: string + ) => string); + replace( + pattern: RegExp | string, + replacement: ((string: string) => string) | string + ): (string: string) => string; + replace( + pattern: RegExp | string, + replacement: ((string: string) => string) | string, + string: string + ): string; + snakeCase(string: string): string; + split(separator: RegExp | string): (string: string) => Array; + split(separator: RegExp | string, string: string): Array; + startCase(string: string): string; + startsWith(target: string): (string: string) => boolean; + startsWith(target: string, string: string): boolean; + template(string: string): Function; + toLower(string: string): string; + toUpper(string: string): string; + trim(string: string): string; + trimChars(chars: string): (string: string) => string; + trimChars(chars: string, string: string): string; + trimEnd(string: string): string; + trimCharsEnd(chars: string): (string: string) => string; + trimCharsEnd(chars: string, string: string): string; + trimStart(string: string): string; + trimCharsStart(chars: string): (string: string) => string; + trimCharsStart(chars: string, string: string): string; + truncate(options: TruncateOptions): (string: string) => string; + truncate(options: TruncateOptions, string: string): string; + unescape(string: string): string; + upperCase(string: string): string; + upperFirst(string: string): string; + words(string: string): Array; + + // Util + attempt(func: Function): any; + bindAll(methodNames: Array): (object: Object) => Object; + bindAll(methodNames: Array, object: Object): Object; + cond(pairs: NestedArray): Function; + constant(value: T): () => T; + always(value: T): () => T; + defaultTo( + defaultValue: T2 + ): (value: T1) => T1; + defaultTo( + defaultValue: T2, + value: T1 + ): T1; + // NaN is a number instead of its own type, otherwise it would behave like null/void + defaultTo(defaultValue: T2): (value: T1) => T1 | T2; + defaultTo(defaultValue: T2, value: T1): T1 | T2; + defaultTo(defaultValue: T2): (value: T1) => T2; + defaultTo(defaultValue: T2, value: T1): T2; + flow: $ComposeReverse; + flow(funcs: Array): Function; + pipe: $ComposeReverse; + pipe(funcs: Array): Function; + flowRight: $Compose; + flowRight(funcs: Array): Function; + compose: $Compose; + compose(funcs: Array): Function; + identity(value: T): T; + iteratee(func: any): Function; + matches(source: Object): (object: Object) => boolean; + matches(source: Object, object: Object): boolean; + matchesProperty(path: Array | string): (srcValue: any) => Function; + matchesProperty(path: Array | string, srcValue: any): Function; + propEq(path: Array | string): (srcValue: any) => Function; + propEq(path: Array | string, srcValue: any): Function; + pathEq(path: Array | string): (srcValue: any) => Function; + pathEq(path: Array | string, srcValue: any): Function; + method(path: Array | string): Function; + methodOf(object: Object): Function; + mixin( + object: T + ): ((source: Object) => (options: { chain: boolean }) => T) & + ((source: Object, options: { chain: boolean }) => T); + mixin( + object: T, + source: Object + ): (options: { chain: boolean }) => T; + mixin( + object: T, + source: Object, + options: { chain: boolean } + ): T; + noConflict(): Lodash; + noop(...args: Array): void; + nthArg(n: number): Function; + over(iteratees: Array): Function; + juxt(iteratees: Array): Function; + overEvery(predicates: Array): Function; + allPass(predicates: Array): Function; + overSome(predicates: Array): Function; + anyPass(predicates: Array): Function; + property( + path: Array | string + ): (object: Object | Array) => any; + property(path: Array | string, object: Object | Array): any; + propertyOf(object: Object): (path: Array | string) => Function; + propertyOf(object: Object, path: Array | string): Function; + range(start: number): (end: number) => Array; + range(start: number, end: number): Array; + rangeStep( + step: number + ): ((start: number) => (end: number) => Array) & + ((start: number, end: number) => Array); + rangeStep(step: number, start: number): (end: number) => Array; + rangeStep(step: number, start: number, end: number): Array; + rangeRight(start: number): (end: number) => Array; + rangeRight(start: number, end: number): Array; + rangeStepRight( + step: number + ): ((start: number) => (end: number) => Array) & + ((start: number, end: number) => Array); + rangeStepRight(step: number, start: number): (end: number) => Array; + rangeStepRight(step: number, start: number, end: number): Array; + runInContext(context: Object): Function; + + stubArray(): Array<*>; + stubFalse(): false; + F(): false; + stubObject(): {}; + stubString(): ""; + stubTrue(): true; + T(): true; + times(iteratee: (i: number) => T): (n: number) => Array; + times(iteratee: (i: number) => T, n: number): Array; + toPath(value: any): Array; + uniqueId(prefix: string): string; + + __: any; + placeholder: any; + + convert(options: { + cap?: boolean, + curry?: boolean, + fixed?: boolean, + immutable?: boolean, + rearg?: boolean + }): void; + + // Properties + VERSION: string; + templateSettings: TemplateSettings; + } + + declare module.exports: Lodash; +} + +declare module "lodash/chunk" { + declare module.exports: $PropertyType<$Exports<"lodash">, "chunk">; +} + +declare module "lodash/compact" { + declare module.exports: $PropertyType<$Exports<"lodash">, "compact">; +} + +declare module "lodash/concat" { + declare module.exports: $PropertyType<$Exports<"lodash">, "concat">; +} + +declare module "lodash/difference" { + declare module.exports: $PropertyType<$Exports<"lodash">, "difference">; +} + +declare module "lodash/differenceBy" { + declare module.exports: $PropertyType<$Exports<"lodash">, "differenceBy">; +} + +declare module "lodash/differenceWith" { + declare module.exports: $PropertyType<$Exports<"lodash">, "differenceWith">; +} + +declare module "lodash/drop" { + declare module.exports: $PropertyType<$Exports<"lodash">, "drop">; +} + +declare module "lodash/dropRight" { + declare module.exports: $PropertyType<$Exports<"lodash">, "dropRight">; +} + +declare module "lodash/dropRightWhile" { + declare module.exports: $PropertyType<$Exports<"lodash">, "dropRightWhile">; +} + +declare module "lodash/dropWhile" { + declare module.exports: $PropertyType<$Exports<"lodash">, "dropWhile">; +} + +declare module "lodash/fill" { + declare module.exports: $PropertyType<$Exports<"lodash">, "fill">; +} + +declare module "lodash/findIndex" { + declare module.exports: $PropertyType<$Exports<"lodash">, "findIndex">; +} + +declare module "lodash/findLastIndex" { + declare module.exports: $PropertyType<$Exports<"lodash">, "findLastIndex">; +} + +declare module "lodash/first" { + declare module.exports: $PropertyType<$Exports<"lodash">, "first">; +} + +declare module "lodash/flatten" { + declare module.exports: $PropertyType<$Exports<"lodash">, "flatten">; +} + +declare module "lodash/flattenDeep" { + declare module.exports: $PropertyType<$Exports<"lodash">, "flattenDeep">; +} + +declare module "lodash/flattenDepth" { + declare module.exports: $PropertyType<$Exports<"lodash">, "flattenDepth">; +} + +declare module "lodash/fromPairs" { + declare module.exports: $PropertyType<$Exports<"lodash">, "fromPairs">; +} + +declare module "lodash/head" { + declare module.exports: $PropertyType<$Exports<"lodash">, "head">; +} + +declare module "lodash/indexOf" { + declare module.exports: $PropertyType<$Exports<"lodash">, "indexOf">; +} + +declare module "lodash/initial" { + declare module.exports: $PropertyType<$Exports<"lodash">, "initial">; +} + +declare module "lodash/intersection" { + declare module.exports: $PropertyType<$Exports<"lodash">, "intersection">; +} + +declare module "lodash/intersectionBy" { + declare module.exports: $PropertyType<$Exports<"lodash">, "intersectionBy">; +} + +declare module "lodash/intersectionWith" { + declare module.exports: $PropertyType<$Exports<"lodash">, "intersectionWith">; +} + +declare module "lodash/join" { + declare module.exports: $PropertyType<$Exports<"lodash">, "join">; +} + +declare module "lodash/last" { + declare module.exports: $PropertyType<$Exports<"lodash">, "last">; +} + +declare module "lodash/lastIndexOf" { + declare module.exports: $PropertyType<$Exports<"lodash">, "lastIndexOf">; +} + +declare module "lodash/nth" { + declare module.exports: $PropertyType<$Exports<"lodash">, "nth">; +} + +declare module "lodash/pull" { + declare module.exports: $PropertyType<$Exports<"lodash">, "pull">; +} + +declare module "lodash/pullAll" { + declare module.exports: $PropertyType<$Exports<"lodash">, "pullAll">; +} + +declare module "lodash/pullAllBy" { + declare module.exports: $PropertyType<$Exports<"lodash">, "pullAllBy">; +} + +declare module "lodash/pullAllWith" { + declare module.exports: $PropertyType<$Exports<"lodash">, "pullAllWith">; +} + +declare module "lodash/pullAt" { + declare module.exports: $PropertyType<$Exports<"lodash">, "pullAt">; +} + +declare module "lodash/remove" { + declare module.exports: $PropertyType<$Exports<"lodash">, "remove">; +} + +declare module "lodash/reverse" { + declare module.exports: $PropertyType<$Exports<"lodash">, "reverse">; +} + +declare module "lodash/slice" { + declare module.exports: $PropertyType<$Exports<"lodash">, "slice">; +} + +declare module "lodash/sortedIndex" { + declare module.exports: $PropertyType<$Exports<"lodash">, "sortedIndex">; +} + +declare module "lodash/sortedIndexBy" { + declare module.exports: $PropertyType<$Exports<"lodash">, "sortedIndexBy">; +} + +declare module "lodash/sortedIndexOf" { + declare module.exports: $PropertyType<$Exports<"lodash">, "sortedIndexOf">; +} + +declare module "lodash/sortedLastIndex" { + declare module.exports: $PropertyType<$Exports<"lodash">, "sortedLastIndex">; +} + +declare module "lodash/sortedLastIndexBy" { + declare module.exports: $PropertyType< + $Exports<"lodash">, + "sortedLastIndexBy" + >; +} + +declare module "lodash/sortedLastIndexOf" { + declare module.exports: $PropertyType< + $Exports<"lodash">, + "sortedLastIndexOf" + >; +} + +declare module "lodash/sortedUniq" { + declare module.exports: $PropertyType<$Exports<"lodash">, "sortedUniq">; +} + +declare module "lodash/sortedUniqBy" { + declare module.exports: $PropertyType<$Exports<"lodash">, "sortedUniqBy">; +} + +declare module "lodash/tail" { + declare module.exports: $PropertyType<$Exports<"lodash">, "tail">; +} + +declare module "lodash/take" { + declare module.exports: $PropertyType<$Exports<"lodash">, "take">; +} + +declare module "lodash/takeRight" { + declare module.exports: $PropertyType<$Exports<"lodash">, "takeRight">; +} + +declare module "lodash/takeRightWhile" { + declare module.exports: $PropertyType<$Exports<"lodash">, "takeRightWhile">; +} + +declare module "lodash/takeWhile" { + declare module.exports: $PropertyType<$Exports<"lodash">, "takeWhile">; +} + +declare module "lodash/union" { + declare module.exports: $PropertyType<$Exports<"lodash">, "union">; +} + +declare module "lodash/unionBy" { + declare module.exports: $PropertyType<$Exports<"lodash">, "unionBy">; +} + +declare module "lodash/unionWith" { + declare module.exports: $PropertyType<$Exports<"lodash">, "unionWith">; +} + +declare module "lodash/uniq" { + declare module.exports: $PropertyType<$Exports<"lodash">, "uniq">; +} + +declare module "lodash/uniqBy" { + declare module.exports: $PropertyType<$Exports<"lodash">, "uniqBy">; +} + +declare module "lodash/uniqWith" { + declare module.exports: $PropertyType<$Exports<"lodash">, "uniqWith">; +} + +declare module "lodash/unzip" { + declare module.exports: $PropertyType<$Exports<"lodash">, "unzip">; +} + +declare module "lodash/unzipWith" { + declare module.exports: $PropertyType<$Exports<"lodash">, "unzipWith">; +} + +declare module "lodash/without" { + declare module.exports: $PropertyType<$Exports<"lodash">, "without">; +} + +declare module "lodash/xor" { + declare module.exports: $PropertyType<$Exports<"lodash">, "xor">; +} + +declare module "lodash/xorBy" { + declare module.exports: $PropertyType<$Exports<"lodash">, "xorBy">; +} + +declare module "lodash/xorWith" { + declare module.exports: $PropertyType<$Exports<"lodash">, "xorWith">; +} + +declare module "lodash/zip" { + declare module.exports: $PropertyType<$Exports<"lodash">, "zip">; +} + +declare module "lodash/zipObject" { + declare module.exports: $PropertyType<$Exports<"lodash">, "zipObject">; +} + +declare module "lodash/zipObjectDeep" { + declare module.exports: $PropertyType<$Exports<"lodash">, "zipObjectDeep">; +} + +declare module "lodash/zipWith" { + declare module.exports: $PropertyType<$Exports<"lodash">, "zipWith">; +} + +declare module "lodash/countBy" { + declare module.exports: $PropertyType<$Exports<"lodash">, "countBy">; +} + +declare module "lodash/each" { + declare module.exports: $PropertyType<$Exports<"lodash">, "each">; +} + +declare module "lodash/eachRight" { + declare module.exports: $PropertyType<$Exports<"lodash">, "eachRight">; +} + +declare module "lodash/every" { + declare module.exports: $PropertyType<$Exports<"lodash">, "every">; +} + +declare module "lodash/filter" { + declare module.exports: $PropertyType<$Exports<"lodash">, "filter">; +} + +declare module "lodash/find" { + declare module.exports: $PropertyType<$Exports<"lodash">, "find">; +} + +declare module "lodash/findLast" { + declare module.exports: $PropertyType<$Exports<"lodash">, "findLast">; +} + +declare module "lodash/flatMap" { + declare module.exports: $PropertyType<$Exports<"lodash">, "flatMap">; +} + +declare module "lodash/flatMapDeep" { + declare module.exports: $PropertyType<$Exports<"lodash">, "flatMapDeep">; +} + +declare module "lodash/flatMapDepth" { + declare module.exports: $PropertyType<$Exports<"lodash">, "flatMapDepth">; +} + +declare module "lodash/forEach" { + declare module.exports: $PropertyType<$Exports<"lodash">, "forEach">; +} + +declare module "lodash/forEachRight" { + declare module.exports: $PropertyType<$Exports<"lodash">, "forEachRight">; +} + +declare module "lodash/groupBy" { + declare module.exports: $PropertyType<$Exports<"lodash">, "groupBy">; +} + +declare module "lodash/includes" { + declare module.exports: $PropertyType<$Exports<"lodash">, "includes">; +} + +declare module "lodash/invokeMap" { + declare module.exports: $PropertyType<$Exports<"lodash">, "invokeMap">; +} + +declare module "lodash/keyBy" { + declare module.exports: $PropertyType<$Exports<"lodash">, "keyBy">; +} + +declare module "lodash/map" { + declare module.exports: $PropertyType<$Exports<"lodash">, "map">; +} + +declare module "lodash/orderBy" { + declare module.exports: $PropertyType<$Exports<"lodash">, "orderBy">; +} + +declare module "lodash/partition" { + declare module.exports: $PropertyType<$Exports<"lodash">, "partition">; +} + +declare module "lodash/reduce" { + declare module.exports: $PropertyType<$Exports<"lodash">, "reduce">; +} + +declare module "lodash/reduceRight" { + declare module.exports: $PropertyType<$Exports<"lodash">, "reduceRight">; +} + +declare module "lodash/reject" { + declare module.exports: $PropertyType<$Exports<"lodash">, "reject">; +} + +declare module "lodash/sample" { + declare module.exports: $PropertyType<$Exports<"lodash">, "sample">; +} + +declare module "lodash/sampleSize" { + declare module.exports: $PropertyType<$Exports<"lodash">, "sampleSize">; +} + +declare module "lodash/shuffle" { + declare module.exports: $PropertyType<$Exports<"lodash">, "shuffle">; +} + +declare module "lodash/size" { + declare module.exports: $PropertyType<$Exports<"lodash">, "size">; +} + +declare module "lodash/some" { + declare module.exports: $PropertyType<$Exports<"lodash">, "some">; +} + +declare module "lodash/sortBy" { + declare module.exports: $PropertyType<$Exports<"lodash">, "sortBy">; +} + +declare module "lodash/now" { + declare module.exports: $PropertyType<$Exports<"lodash">, "now">; +} + +declare module "lodash/after" { + declare module.exports: $PropertyType<$Exports<"lodash">, "after">; +} + +declare module "lodash/ary" { + declare module.exports: $PropertyType<$Exports<"lodash">, "ary">; +} + +declare module "lodash/before" { + declare module.exports: $PropertyType<$Exports<"lodash">, "before">; +} + +declare module "lodash/bind" { + declare module.exports: $PropertyType<$Exports<"lodash">, "bind">; +} + +declare module "lodash/bindKey" { + declare module.exports: $PropertyType<$Exports<"lodash">, "bindKey">; +} + +declare module "lodash/curry" { + declare module.exports: $PropertyType<$Exports<"lodash">, "curry">; +} + +declare module "lodash/curryRight" { + declare module.exports: $PropertyType<$Exports<"lodash">, "curryRight">; +} + +declare module "lodash/debounce" { + declare module.exports: $PropertyType<$Exports<"lodash">, "debounce">; +} + +declare module "lodash/defer" { + declare module.exports: $PropertyType<$Exports<"lodash">, "defer">; +} + +declare module "lodash/delay" { + declare module.exports: $PropertyType<$Exports<"lodash">, "delay">; +} + +declare module "lodash/flip" { + declare module.exports: $PropertyType<$Exports<"lodash">, "flip">; +} + +declare module "lodash/memoize" { + declare module.exports: $PropertyType<$Exports<"lodash">, "memoize">; +} + +declare module "lodash/negate" { + declare module.exports: $PropertyType<$Exports<"lodash">, "negate">; +} + +declare module "lodash/once" { + declare module.exports: $PropertyType<$Exports<"lodash">, "once">; +} + +declare module "lodash/overArgs" { + declare module.exports: $PropertyType<$Exports<"lodash">, "overArgs">; +} + +declare module "lodash/partial" { + declare module.exports: $PropertyType<$Exports<"lodash">, "partial">; +} + +declare module "lodash/partialRight" { + declare module.exports: $PropertyType<$Exports<"lodash">, "partialRight">; +} + +declare module "lodash/rearg" { + declare module.exports: $PropertyType<$Exports<"lodash">, "rearg">; +} + +declare module "lodash/rest" { + declare module.exports: $PropertyType<$Exports<"lodash">, "rest">; +} + +declare module "lodash/spread" { + declare module.exports: $PropertyType<$Exports<"lodash">, "spread">; +} + +declare module "lodash/throttle" { + declare module.exports: $PropertyType<$Exports<"lodash">, "throttle">; +} + +declare module "lodash/unary" { + declare module.exports: $PropertyType<$Exports<"lodash">, "unary">; +} + +declare module "lodash/wrap" { + declare module.exports: $PropertyType<$Exports<"lodash">, "wrap">; +} + +declare module "lodash/castArray" { + declare module.exports: $PropertyType<$Exports<"lodash">, "castArray">; +} + +declare module "lodash/clone" { + declare module.exports: $PropertyType<$Exports<"lodash">, "clone">; +} + +declare module "lodash/cloneDeep" { + declare module.exports: $PropertyType<$Exports<"lodash">, "cloneDeep">; +} + +declare module "lodash/cloneDeepWith" { + declare module.exports: $PropertyType<$Exports<"lodash">, "cloneDeepWith">; +} + +declare module "lodash/cloneWith" { + declare module.exports: $PropertyType<$Exports<"lodash">, "cloneWith">; +} + +declare module "lodash/conformsTo" { + declare module.exports: $PropertyType<$Exports<"lodash">, "conformsTo">; +} + +declare module "lodash/eq" { + declare module.exports: $PropertyType<$Exports<"lodash">, "eq">; +} + +declare module "lodash/gt" { + declare module.exports: $PropertyType<$Exports<"lodash">, "gt">; +} + +declare module "lodash/gte" { + declare module.exports: $PropertyType<$Exports<"lodash">, "gte">; +} + +declare module "lodash/isArguments" { + declare module.exports: $PropertyType<$Exports<"lodash">, "isArguments">; +} + +declare module "lodash/isArray" { + declare module.exports: $PropertyType<$Exports<"lodash">, "isArray">; +} + +declare module "lodash/isArrayBuffer" { + declare module.exports: $PropertyType<$Exports<"lodash">, "isArrayBuffer">; +} + +declare module "lodash/isArrayLike" { + declare module.exports: $PropertyType<$Exports<"lodash">, "isArrayLike">; +} + +declare module "lodash/isArrayLikeObject" { + declare module.exports: $PropertyType< + $Exports<"lodash">, + "isArrayLikeObject" + >; +} + +declare module "lodash/isBoolean" { + declare module.exports: $PropertyType<$Exports<"lodash">, "isBoolean">; +} + +declare module "lodash/isBuffer" { + declare module.exports: $PropertyType<$Exports<"lodash">, "isBuffer">; +} + +declare module "lodash/isDate" { + declare module.exports: $PropertyType<$Exports<"lodash">, "isDate">; +} + +declare module "lodash/isElement" { + declare module.exports: $PropertyType<$Exports<"lodash">, "isElement">; +} + +declare module "lodash/isEmpty" { + declare module.exports: $PropertyType<$Exports<"lodash">, "isEmpty">; +} + +declare module "lodash/isEqual" { + declare module.exports: $PropertyType<$Exports<"lodash">, "isEqual">; +} + +declare module "lodash/isEqualWith" { + declare module.exports: $PropertyType<$Exports<"lodash">, "isEqualWith">; +} + +declare module "lodash/isError" { + declare module.exports: $PropertyType<$Exports<"lodash">, "isError">; +} + +declare module "lodash/isFinite" { + declare module.exports: $PropertyType<$Exports<"lodash">, "isFinite">; +} + +declare module "lodash/isFunction" { + declare module.exports: $PropertyType<$Exports<"lodash">, "isFunction">; +} + +declare module "lodash/isInteger" { + declare module.exports: $PropertyType<$Exports<"lodash">, "isInteger">; +} + +declare module "lodash/isLength" { + declare module.exports: $PropertyType<$Exports<"lodash">, "isLength">; +} + +declare module "lodash/isMap" { + declare module.exports: $PropertyType<$Exports<"lodash">, "isMap">; +} + +declare module "lodash/isMatch" { + declare module.exports: $PropertyType<$Exports<"lodash">, "isMatch">; +} + +declare module "lodash/isMatchWith" { + declare module.exports: $PropertyType<$Exports<"lodash">, "isMatchWith">; +} + +declare module "lodash/isNaN" { + declare module.exports: $PropertyType<$Exports<"lodash">, "isNaN">; +} + +declare module "lodash/isNative" { + declare module.exports: $PropertyType<$Exports<"lodash">, "isNative">; +} + +declare module "lodash/isNil" { + declare module.exports: $PropertyType<$Exports<"lodash">, "isNil">; +} + +declare module "lodash/isNull" { + declare module.exports: $PropertyType<$Exports<"lodash">, "isNull">; +} + +declare module "lodash/isNumber" { + declare module.exports: $PropertyType<$Exports<"lodash">, "isNumber">; +} + +declare module "lodash/isObject" { + declare module.exports: $PropertyType<$Exports<"lodash">, "isObject">; +} + +declare module "lodash/isObjectLike" { + declare module.exports: $PropertyType<$Exports<"lodash">, "isObjectLike">; +} + +declare module "lodash/isPlainObject" { + declare module.exports: $PropertyType<$Exports<"lodash">, "isPlainObject">; +} + +declare module "lodash/isRegExp" { + declare module.exports: $PropertyType<$Exports<"lodash">, "isRegExp">; +} + +declare module "lodash/isSafeInteger" { + declare module.exports: $PropertyType<$Exports<"lodash">, "isSafeInteger">; +} + +declare module "lodash/isSet" { + declare module.exports: $PropertyType<$Exports<"lodash">, "isSet">; +} + +declare module "lodash/isString" { + declare module.exports: $PropertyType<$Exports<"lodash">, "isString">; +} + +declare module "lodash/isSymbol" { + declare module.exports: $PropertyType<$Exports<"lodash">, "isSymbol">; +} + +declare module "lodash/isTypedArray" { + declare module.exports: $PropertyType<$Exports<"lodash">, "isTypedArray">; +} + +declare module "lodash/isUndefined" { + declare module.exports: $PropertyType<$Exports<"lodash">, "isUndefined">; +} + +declare module "lodash/isWeakMap" { + declare module.exports: $PropertyType<$Exports<"lodash">, "isWeakMap">; +} + +declare module "lodash/isWeakSet" { + declare module.exports: $PropertyType<$Exports<"lodash">, "isWeakSet">; +} + +declare module "lodash/lt" { + declare module.exports: $PropertyType<$Exports<"lodash">, "lt">; +} + +declare module "lodash/lte" { + declare module.exports: $PropertyType<$Exports<"lodash">, "lte">; +} + +declare module "lodash/toArray" { + declare module.exports: $PropertyType<$Exports<"lodash">, "toArray">; +} + +declare module "lodash/toFinite" { + declare module.exports: $PropertyType<$Exports<"lodash">, "toFinite">; +} + +declare module "lodash/toInteger" { + declare module.exports: $PropertyType<$Exports<"lodash">, "toInteger">; +} + +declare module "lodash/toLength" { + declare module.exports: $PropertyType<$Exports<"lodash">, "toLength">; +} + +declare module "lodash/toNumber" { + declare module.exports: $PropertyType<$Exports<"lodash">, "toNumber">; +} + +declare module "lodash/toPlainObject" { + declare module.exports: $PropertyType<$Exports<"lodash">, "toPlainObject">; +} + +declare module "lodash/toSafeInteger" { + declare module.exports: $PropertyType<$Exports<"lodash">, "toSafeInteger">; +} + +declare module "lodash/toString" { + declare module.exports: $PropertyType<$Exports<"lodash">, "toString">; +} + +declare module "lodash/add" { + declare module.exports: $PropertyType<$Exports<"lodash">, "add">; +} + +declare module "lodash/ceil" { + declare module.exports: $PropertyType<$Exports<"lodash">, "ceil">; +} + +declare module "lodash/divide" { + declare module.exports: $PropertyType<$Exports<"lodash">, "divide">; +} + +declare module "lodash/floor" { + declare module.exports: $PropertyType<$Exports<"lodash">, "floor">; +} + +declare module "lodash/max" { + declare module.exports: $PropertyType<$Exports<"lodash">, "max">; +} + +declare module "lodash/maxBy" { + declare module.exports: $PropertyType<$Exports<"lodash">, "maxBy">; +} + +declare module "lodash/mean" { + declare module.exports: $PropertyType<$Exports<"lodash">, "mean">; +} + +declare module "lodash/meanBy" { + declare module.exports: $PropertyType<$Exports<"lodash">, "meanBy">; +} + +declare module "lodash/min" { + declare module.exports: $PropertyType<$Exports<"lodash">, "min">; +} + +declare module "lodash/minBy" { + declare module.exports: $PropertyType<$Exports<"lodash">, "minBy">; +} + +declare module "lodash/multiply" { + declare module.exports: $PropertyType<$Exports<"lodash">, "multiply">; +} + +declare module "lodash/round" { + declare module.exports: $PropertyType<$Exports<"lodash">, "round">; +} + +declare module "lodash/subtract" { + declare module.exports: $PropertyType<$Exports<"lodash">, "subtract">; +} + +declare module "lodash/sum" { + declare module.exports: $PropertyType<$Exports<"lodash">, "sum">; +} + +declare module "lodash/sumBy" { + declare module.exports: $PropertyType<$Exports<"lodash">, "sumBy">; +} + +declare module "lodash/clamp" { + declare module.exports: $PropertyType<$Exports<"lodash">, "clamp">; +} + +declare module "lodash/inRange" { + declare module.exports: $PropertyType<$Exports<"lodash">, "inRange">; +} + +declare module "lodash/random" { + declare module.exports: $PropertyType<$Exports<"lodash">, "random">; +} + +declare module "lodash/assign" { + declare module.exports: $PropertyType<$Exports<"lodash">, "assign">; +} + +declare module "lodash/assignIn" { + declare module.exports: $PropertyType<$Exports<"lodash">, "assignIn">; +} + +declare module "lodash/assignInWith" { + declare module.exports: $PropertyType<$Exports<"lodash">, "assignInWith">; +} + +declare module "lodash/assignWith" { + declare module.exports: $PropertyType<$Exports<"lodash">, "assignWith">; +} + +declare module "lodash/at" { + declare module.exports: $PropertyType<$Exports<"lodash">, "at">; +} + +declare module "lodash/create" { + declare module.exports: $PropertyType<$Exports<"lodash">, "create">; +} + +declare module "lodash/defaults" { + declare module.exports: $PropertyType<$Exports<"lodash">, "defaults">; +} + +declare module "lodash/defaultsDeep" { + declare module.exports: $PropertyType<$Exports<"lodash">, "defaultsDeep">; +} + +declare module "lodash/entries" { + declare module.exports: $PropertyType<$Exports<"lodash">, "entries">; +} + +declare module "lodash/entriesIn" { + declare module.exports: $PropertyType<$Exports<"lodash">, "entriesIn">; +} + +declare module "lodash/extend" { + declare module.exports: $PropertyType<$Exports<"lodash">, "extend">; +} + +declare module "lodash/extendWith" { + declare module.exports: $PropertyType<$Exports<"lodash">, "extendWith">; +} + +declare module "lodash/findKey" { + declare module.exports: $PropertyType<$Exports<"lodash">, "findKey">; +} + +declare module "lodash/findLastKey" { + declare module.exports: $PropertyType<$Exports<"lodash">, "findLastKey">; +} + +declare module "lodash/forIn" { + declare module.exports: $PropertyType<$Exports<"lodash">, "forIn">; +} + +declare module "lodash/forInRight" { + declare module.exports: $PropertyType<$Exports<"lodash">, "forInRight">; +} + +declare module "lodash/forOwn" { + declare module.exports: $PropertyType<$Exports<"lodash">, "forOwn">; +} + +declare module "lodash/forOwnRight" { + declare module.exports: $PropertyType<$Exports<"lodash">, "forOwnRight">; +} + +declare module "lodash/functions" { + declare module.exports: $PropertyType<$Exports<"lodash">, "functions">; +} + +declare module "lodash/functionsIn" { + declare module.exports: $PropertyType<$Exports<"lodash">, "functionsIn">; +} + +declare module "lodash/get" { + declare module.exports: $PropertyType<$Exports<"lodash">, "get">; +} + +declare module "lodash/has" { + declare module.exports: $PropertyType<$Exports<"lodash">, "has">; +} + +declare module "lodash/hasIn" { + declare module.exports: $PropertyType<$Exports<"lodash">, "hasIn">; +} + +declare module "lodash/invert" { + declare module.exports: $PropertyType<$Exports<"lodash">, "invert">; +} + +declare module "lodash/invertBy" { + declare module.exports: $PropertyType<$Exports<"lodash">, "invertBy">; +} + +declare module "lodash/invoke" { + declare module.exports: $PropertyType<$Exports<"lodash">, "invoke">; +} + +declare module "lodash/keys" { + declare module.exports: $PropertyType<$Exports<"lodash">, "keys">; +} + +declare module "lodash/keysIn" { + declare module.exports: $PropertyType<$Exports<"lodash">, "keysIn">; +} + +declare module "lodash/mapKeys" { + declare module.exports: $PropertyType<$Exports<"lodash">, "mapKeys">; +} + +declare module "lodash/mapValues" { + declare module.exports: $PropertyType<$Exports<"lodash">, "mapValues">; +} + +declare module "lodash/merge" { + declare module.exports: $PropertyType<$Exports<"lodash">, "merge">; +} + +declare module "lodash/mergeWith" { + declare module.exports: $PropertyType<$Exports<"lodash">, "mergeWith">; +} + +declare module "lodash/omit" { + declare module.exports: $PropertyType<$Exports<"lodash">, "omit">; +} + +declare module "lodash/omitBy" { + declare module.exports: $PropertyType<$Exports<"lodash">, "omitBy">; +} + +declare module "lodash/pick" { + declare module.exports: $PropertyType<$Exports<"lodash">, "pick">; +} + +declare module "lodash/pickBy" { + declare module.exports: $PropertyType<$Exports<"lodash">, "pickBy">; +} + +declare module "lodash/result" { + declare module.exports: $PropertyType<$Exports<"lodash">, "result">; +} + +declare module "lodash/set" { + declare module.exports: $PropertyType<$Exports<"lodash">, "set">; +} + +declare module "lodash/setWith" { + declare module.exports: $PropertyType<$Exports<"lodash">, "setWith">; +} + +declare module "lodash/toPairs" { + declare module.exports: $PropertyType<$Exports<"lodash">, "toPairs">; +} + +declare module "lodash/toPairsIn" { + declare module.exports: $PropertyType<$Exports<"lodash">, "toPairsIn">; +} + +declare module "lodash/transform" { + declare module.exports: $PropertyType<$Exports<"lodash">, "transform">; +} + +declare module "lodash/unset" { + declare module.exports: $PropertyType<$Exports<"lodash">, "unset">; +} + +declare module "lodash/update" { + declare module.exports: $PropertyType<$Exports<"lodash">, "update">; +} + +declare module "lodash/updateWith" { + declare module.exports: $PropertyType<$Exports<"lodash">, "updateWith">; +} + +declare module "lodash/values" { + declare module.exports: $PropertyType<$Exports<"lodash">, "values">; +} + +declare module "lodash/valuesIn" { + declare module.exports: $PropertyType<$Exports<"lodash">, "valuesIn">; +} + +declare module "lodash/chain" { + declare module.exports: $PropertyType<$Exports<"lodash">, "chain">; +} + +declare module "lodash/tap" { + declare module.exports: $PropertyType<$Exports<"lodash">, "tap">; +} + +declare module "lodash/thru" { + declare module.exports: $PropertyType<$Exports<"lodash">, "thru">; +} + +declare module "lodash/camelCase" { + declare module.exports: $PropertyType<$Exports<"lodash">, "camelCase">; +} + +declare module "lodash/capitalize" { + declare module.exports: $PropertyType<$Exports<"lodash">, "capitalize">; +} + +declare module "lodash/deburr" { + declare module.exports: $PropertyType<$Exports<"lodash">, "deburr">; +} + +declare module "lodash/endsWith" { + declare module.exports: $PropertyType<$Exports<"lodash">, "endsWith">; +} + +declare module "lodash/escape" { + declare module.exports: $PropertyType<$Exports<"lodash">, "escape">; +} + +declare module "lodash/escapeRegExp" { + declare module.exports: $PropertyType<$Exports<"lodash">, "escapeRegExp">; +} + +declare module "lodash/kebabCase" { + declare module.exports: $PropertyType<$Exports<"lodash">, "kebabCase">; +} + +declare module "lodash/lowerCase" { + declare module.exports: $PropertyType<$Exports<"lodash">, "lowerCase">; +} + +declare module "lodash/lowerFirst" { + declare module.exports: $PropertyType<$Exports<"lodash">, "lowerFirst">; +} + +declare module "lodash/pad" { + declare module.exports: $PropertyType<$Exports<"lodash">, "pad">; +} + +declare module "lodash/padEnd" { + declare module.exports: $PropertyType<$Exports<"lodash">, "padEnd">; +} + +declare module "lodash/padStart" { + declare module.exports: $PropertyType<$Exports<"lodash">, "padStart">; +} + +declare module "lodash/parseInt" { + declare module.exports: $PropertyType<$Exports<"lodash">, "parseInt">; +} + +declare module "lodash/repeat" { + declare module.exports: $PropertyType<$Exports<"lodash">, "repeat">; +} + +declare module "lodash/replace" { + declare module.exports: $PropertyType<$Exports<"lodash">, "replace">; +} + +declare module "lodash/snakeCase" { + declare module.exports: $PropertyType<$Exports<"lodash">, "snakeCase">; +} + +declare module "lodash/split" { + declare module.exports: $PropertyType<$Exports<"lodash">, "split">; +} + +declare module "lodash/startCase" { + declare module.exports: $PropertyType<$Exports<"lodash">, "startCase">; +} + +declare module "lodash/startsWith" { + declare module.exports: $PropertyType<$Exports<"lodash">, "startsWith">; +} + +declare module "lodash/template" { + declare module.exports: $PropertyType<$Exports<"lodash">, "template">; +} + +declare module "lodash/toLower" { + declare module.exports: $PropertyType<$Exports<"lodash">, "toLower">; +} + +declare module "lodash/toUpper" { + declare module.exports: $PropertyType<$Exports<"lodash">, "toUpper">; +} + +declare module "lodash/trim" { + declare module.exports: $PropertyType<$Exports<"lodash">, "trim">; +} + +declare module "lodash/trimEnd" { + declare module.exports: $PropertyType<$Exports<"lodash">, "trimEnd">; +} + +declare module "lodash/trimStart" { + declare module.exports: $PropertyType<$Exports<"lodash">, "trimStart">; +} + +declare module "lodash/truncate" { + declare module.exports: $PropertyType<$Exports<"lodash">, "truncate">; +} + +declare module "lodash/unescape" { + declare module.exports: $PropertyType<$Exports<"lodash">, "unescape">; +} + +declare module "lodash/upperCase" { + declare module.exports: $PropertyType<$Exports<"lodash">, "upperCase">; +} + +declare module "lodash/upperFirst" { + declare module.exports: $PropertyType<$Exports<"lodash">, "upperFirst">; +} + +declare module "lodash/words" { + declare module.exports: $PropertyType<$Exports<"lodash">, "words">; +} + +declare module "lodash/attempt" { + declare module.exports: $PropertyType<$Exports<"lodash">, "attempt">; +} + +declare module "lodash/bindAll" { + declare module.exports: $PropertyType<$Exports<"lodash">, "bindAll">; +} + +declare module "lodash/cond" { + declare module.exports: $PropertyType<$Exports<"lodash">, "cond">; +} + +declare module "lodash/conforms" { + declare module.exports: $PropertyType<$Exports<"lodash">, "conforms">; +} + +declare module "lodash/constant" { + declare module.exports: $PropertyType<$Exports<"lodash">, "constant">; +} + +declare module "lodash/defaultTo" { + declare module.exports: $PropertyType<$Exports<"lodash">, "defaultTo">; +} + +declare module "lodash/flow" { + declare module.exports: $PropertyType<$Exports<"lodash">, "flow">; +} + +declare module "lodash/flowRight" { + declare module.exports: $PropertyType<$Exports<"lodash">, "flowRight">; +} + +declare module "lodash/identity" { + declare module.exports: $PropertyType<$Exports<"lodash">, "identity">; +} + +declare module "lodash/iteratee" { + declare module.exports: $PropertyType<$Exports<"lodash">, "iteratee">; +} + +declare module "lodash/matches" { + declare module.exports: $PropertyType<$Exports<"lodash">, "matches">; +} + +declare module "lodash/matchesProperty" { + declare module.exports: $PropertyType<$Exports<"lodash">, "matchesProperty">; +} + +declare module "lodash/method" { + declare module.exports: $PropertyType<$Exports<"lodash">, "method">; +} + +declare module "lodash/methodOf" { + declare module.exports: $PropertyType<$Exports<"lodash">, "methodOf">; +} + +declare module "lodash/mixin" { + declare module.exports: $PropertyType<$Exports<"lodash">, "mixin">; +} + +declare module "lodash/noConflict" { + declare module.exports: $PropertyType<$Exports<"lodash">, "noConflict">; +} + +declare module "lodash/noop" { + declare module.exports: $PropertyType<$Exports<"lodash">, "noop">; +} + +declare module "lodash/nthArg" { + declare module.exports: $PropertyType<$Exports<"lodash">, "nthArg">; +} + +declare module "lodash/over" { + declare module.exports: $PropertyType<$Exports<"lodash">, "over">; +} + +declare module "lodash/overEvery" { + declare module.exports: $PropertyType<$Exports<"lodash">, "overEvery">; +} + +declare module "lodash/overSome" { + declare module.exports: $PropertyType<$Exports<"lodash">, "overSome">; +} + +declare module "lodash/property" { + declare module.exports: $PropertyType<$Exports<"lodash">, "property">; +} + +declare module "lodash/propertyOf" { + declare module.exports: $PropertyType<$Exports<"lodash">, "propertyOf">; +} + +declare module "lodash/range" { + declare module.exports: $PropertyType<$Exports<"lodash">, "range">; +} + +declare module "lodash/rangeRight" { + declare module.exports: $PropertyType<$Exports<"lodash">, "rangeRight">; +} + +declare module "lodash/runInContext" { + declare module.exports: $PropertyType<$Exports<"lodash">, "runInContext">; +} + +declare module "lodash/stubArray" { + declare module.exports: $PropertyType<$Exports<"lodash">, "stubArray">; +} + +declare module "lodash/stubFalse" { + declare module.exports: $PropertyType<$Exports<"lodash">, "stubFalse">; +} + +declare module "lodash/stubObject" { + declare module.exports: $PropertyType<$Exports<"lodash">, "stubObject">; +} + +declare module "lodash/stubString" { + declare module.exports: $PropertyType<$Exports<"lodash">, "stubString">; +} + +declare module "lodash/stubTrue" { + declare module.exports: $PropertyType<$Exports<"lodash">, "stubTrue">; +} + +declare module "lodash/times" { + declare module.exports: $PropertyType<$Exports<"lodash">, "times">; +} + +declare module "lodash/toPath" { + declare module.exports: $PropertyType<$Exports<"lodash">, "toPath">; +} + +declare module "lodash/uniqueId" { + declare module.exports: $PropertyType<$Exports<"lodash">, "uniqueId">; +} diff --git a/flow-typed/npm/openssl-wrapper_vx.x.x.js b/flow-typed/npm/openssl-wrapper_vx.x.x.js new file mode 100644 index 000000000..4b4c2438c --- /dev/null +++ b/flow-typed/npm/openssl-wrapper_vx.x.x.js @@ -0,0 +1,46 @@ +// flow-typed signature: de535bf82f2186287df01b1d05ef7355 +// flow-typed version: <>/openssl-wrapper_v0.3.4/flow_v0.69.0 + +/** + * This is an autogenerated libdef stub for: + * + * 'openssl-wrapper' + * + * Fill this stub out by replacing all the `any` types. + * + * Once filled out, we encourage you to share your work with the + * community by sending a pull request to: + * https://github.com/flowtype/flow-typed + */ + +declare module 'openssl-wrapper' { + declare module.exports: any; +} + +/** + * We include stubs for each file inside this npm package in case you need to + * require those files directly. Feel free to delete any files that aren't + * needed. + */ +declare module 'openssl-wrapper/lib/index' { + declare module.exports: any; +} + +declare module 'openssl-wrapper/src/index' { + declare module.exports: any; +} + +declare module 'openssl-wrapper/test/index.spec' { + declare module.exports: any; +} + +// Filename aliases +declare module 'openssl-wrapper/lib/index.js' { + declare module.exports: $Exports<'openssl-wrapper/lib/index'>; +} +declare module 'openssl-wrapper/src/index.js' { + declare module.exports: $Exports<'openssl-wrapper/src/index'>; +} +declare module 'openssl-wrapper/test/index.spec.js' { + declare module.exports: $Exports<'openssl-wrapper/test/index.spec'>; +} diff --git a/flow-typed/npm/polished_vx.x.x.js b/flow-typed/npm/polished_vx.x.x.js new file mode 100644 index 000000000..3b9d63d2d --- /dev/null +++ b/flow-typed/npm/polished_vx.x.x.js @@ -0,0 +1,585 @@ +// flow-typed signature: 41ed726d42e8bdc8e940fef3395a9649 +// flow-typed version: <>/polished_v^1.1.1/flow_v0.59.0 + +/** + * This is an autogenerated libdef stub for: + * + * 'polished' + * + * Fill this stub out by replacing all the `any` types. + * + * Once filled out, we encourage you to share your work with the + * community by sending a pull request to: + * https://github.com/flowtype/flow-typed + */ + +declare module 'polished' { + declare module.exports: any; +} + +/** + * We include stubs for each file inside this npm package in case you need to + * require those files directly. Feel free to delete any files that aren't + * needed. + */ +declare module 'polished/dist/polished.es' { + declare module.exports: any; +} + +declare module 'polished/dist/polished' { + declare module.exports: any; +} + +declare module 'polished/dist/polished.min' { + declare module.exports: any; +} + +declare module 'polished/docs/assets/anchor' { + declare module.exports: any; +} + +declare module 'polished/docs/assets/docs' { + declare module.exports: any; +} + +declare module 'polished/docs/assets/highlight.pack' { + declare module.exports: any; +} + +declare module 'polished/docs/assets/polished' { + declare module.exports: any; +} + +declare module 'polished/docs/assets/script' { + declare module.exports: any; +} + +declare module 'polished/lib/color/adjustHue' { + declare module.exports: any; +} + +declare module 'polished/lib/color/complement' { + declare module.exports: any; +} + +declare module 'polished/lib/color/darken' { + declare module.exports: any; +} + +declare module 'polished/lib/color/desaturate' { + declare module.exports: any; +} + +declare module 'polished/lib/color/grayscale' { + declare module.exports: any; +} + +declare module 'polished/lib/color/hsl' { + declare module.exports: any; +} + +declare module 'polished/lib/color/hsla' { + declare module.exports: any; +} + +declare module 'polished/lib/color/invert' { + declare module.exports: any; +} + +declare module 'polished/lib/color/lighten' { + declare module.exports: any; +} + +declare module 'polished/lib/color/mix' { + declare module.exports: any; +} + +declare module 'polished/lib/color/opacify' { + declare module.exports: any; +} + +declare module 'polished/lib/color/parseToHsl' { + declare module.exports: any; +} + +declare module 'polished/lib/color/parseToRgb' { + declare module.exports: any; +} + +declare module 'polished/lib/color/readableColor' { + declare module.exports: any; +} + +declare module 'polished/lib/color/rgb' { + declare module.exports: any; +} + +declare module 'polished/lib/color/rgba' { + declare module.exports: any; +} + +declare module 'polished/lib/color/saturate' { + declare module.exports: any; +} + +declare module 'polished/lib/color/setHue' { + declare module.exports: any; +} + +declare module 'polished/lib/color/setLightness' { + declare module.exports: any; +} + +declare module 'polished/lib/color/setSaturation' { + declare module.exports: any; +} + +declare module 'polished/lib/color/shade' { + declare module.exports: any; +} + +declare module 'polished/lib/color/tint' { + declare module.exports: any; +} + +declare module 'polished/lib/color/toColorString' { + declare module.exports: any; +} + +declare module 'polished/lib/color/transparentize' { + declare module.exports: any; +} + +declare module 'polished/lib/helpers/directionalProperty' { + declare module.exports: any; +} + +declare module 'polished/lib/helpers/em' { + declare module.exports: any; +} + +declare module 'polished/lib/helpers/modularScale' { + declare module.exports: any; +} + +declare module 'polished/lib/helpers/rem' { + declare module.exports: any; +} + +declare module 'polished/lib/helpers/stripUnit' { + declare module.exports: any; +} + +declare module 'polished/lib/index' { + declare module.exports: any; +} + +declare module 'polished/lib/internalHelpers/_capitalizeString' { + declare module.exports: any; +} + +declare module 'polished/lib/internalHelpers/_curry' { + declare module.exports: any; +} + +declare module 'polished/lib/internalHelpers/_endsWith' { + declare module.exports: any; +} + +declare module 'polished/lib/internalHelpers/_guard' { + declare module.exports: any; +} + +declare module 'polished/lib/internalHelpers/_hslToHex' { + declare module.exports: any; +} + +declare module 'polished/lib/internalHelpers/_hslToRgb' { + declare module.exports: any; +} + +declare module 'polished/lib/internalHelpers/_isValidDimensionValue' { + declare module.exports: any; +} + +declare module 'polished/lib/internalHelpers/_nameToHex' { + declare module.exports: any; +} + +declare module 'polished/lib/internalHelpers/_numberToHex' { + declare module.exports: any; +} + +declare module 'polished/lib/internalHelpers/_polishedLogs' { + declare module.exports: any; +} + +declare module 'polished/lib/internalHelpers/_pxto' { + declare module.exports: any; +} + +declare module 'polished/lib/internalHelpers/_reduceHexValue' { + declare module.exports: any; +} + +declare module 'polished/lib/internalHelpers/_rgbToHsl' { + declare module.exports: any; +} + +declare module 'polished/lib/internalHelpers/_statefulSelectors' { + declare module.exports: any; +} + +declare module 'polished/lib/mixins/clearFix' { + declare module.exports: any; +} + +declare module 'polished/lib/mixins/ellipsis' { + declare module.exports: any; +} + +declare module 'polished/lib/mixins/fontFace' { + declare module.exports: any; +} + +declare module 'polished/lib/mixins/hideText' { + declare module.exports: any; +} + +declare module 'polished/lib/mixins/hiDPI' { + declare module.exports: any; +} + +declare module 'polished/lib/mixins/normalize' { + declare module.exports: any; +} + +declare module 'polished/lib/mixins/placeholder' { + declare module.exports: any; +} + +declare module 'polished/lib/mixins/radialGradient' { + declare module.exports: any; +} + +declare module 'polished/lib/mixins/retinaImage' { + declare module.exports: any; +} + +declare module 'polished/lib/mixins/selection' { + declare module.exports: any; +} + +declare module 'polished/lib/mixins/timingFunctions' { + declare module.exports: any; +} + +declare module 'polished/lib/mixins/triangle' { + declare module.exports: any; +} + +declare module 'polished/lib/mixins/wordWrap' { + declare module.exports: any; +} + +declare module 'polished/lib/shorthands/animation' { + declare module.exports: any; +} + +declare module 'polished/lib/shorthands/backgroundImages' { + declare module.exports: any; +} + +declare module 'polished/lib/shorthands/backgrounds' { + declare module.exports: any; +} + +declare module 'polished/lib/shorthands/borderColor' { + declare module.exports: any; +} + +declare module 'polished/lib/shorthands/borderRadius' { + declare module.exports: any; +} + +declare module 'polished/lib/shorthands/borderStyle' { + declare module.exports: any; +} + +declare module 'polished/lib/shorthands/borderWidth' { + declare module.exports: any; +} + +declare module 'polished/lib/shorthands/buttons' { + declare module.exports: any; +} + +declare module 'polished/lib/shorthands/margin' { + declare module.exports: any; +} + +declare module 'polished/lib/shorthands/padding' { + declare module.exports: any; +} + +declare module 'polished/lib/shorthands/position' { + declare module.exports: any; +} + +declare module 'polished/lib/shorthands/size' { + declare module.exports: any; +} + +declare module 'polished/lib/shorthands/textInputs' { + declare module.exports: any; +} + +declare module 'polished/lib/shorthands/transitions' { + declare module.exports: any; +} + +declare module 'polished/lib/types/color' { + declare module.exports: any; +} + +// Filename aliases +declare module 'polished/dist/polished.es.js' { + declare module.exports: $Exports<'polished/dist/polished.es'>; +} +declare module 'polished/dist/polished.js' { + declare module.exports: $Exports<'polished/dist/polished'>; +} +declare module 'polished/dist/polished.min.js' { + declare module.exports: $Exports<'polished/dist/polished.min'>; +} +declare module 'polished/docs/assets/anchor.js' { + declare module.exports: $Exports<'polished/docs/assets/anchor'>; +} +declare module 'polished/docs/assets/docs.js' { + declare module.exports: $Exports<'polished/docs/assets/docs'>; +} +declare module 'polished/docs/assets/highlight.pack.js' { + declare module.exports: $Exports<'polished/docs/assets/highlight.pack'>; +} +declare module 'polished/docs/assets/polished.js' { + declare module.exports: $Exports<'polished/docs/assets/polished'>; +} +declare module 'polished/docs/assets/script.js' { + declare module.exports: $Exports<'polished/docs/assets/script'>; +} +declare module 'polished/lib/color/adjustHue.js' { + declare module.exports: $Exports<'polished/lib/color/adjustHue'>; +} +declare module 'polished/lib/color/complement.js' { + declare module.exports: $Exports<'polished/lib/color/complement'>; +} +declare module 'polished/lib/color/darken.js' { + declare module.exports: $Exports<'polished/lib/color/darken'>; +} +declare module 'polished/lib/color/desaturate.js' { + declare module.exports: $Exports<'polished/lib/color/desaturate'>; +} +declare module 'polished/lib/color/grayscale.js' { + declare module.exports: $Exports<'polished/lib/color/grayscale'>; +} +declare module 'polished/lib/color/hsl.js' { + declare module.exports: $Exports<'polished/lib/color/hsl'>; +} +declare module 'polished/lib/color/hsla.js' { + declare module.exports: $Exports<'polished/lib/color/hsla'>; +} +declare module 'polished/lib/color/invert.js' { + declare module.exports: $Exports<'polished/lib/color/invert'>; +} +declare module 'polished/lib/color/lighten.js' { + declare module.exports: $Exports<'polished/lib/color/lighten'>; +} +declare module 'polished/lib/color/mix.js' { + declare module.exports: $Exports<'polished/lib/color/mix'>; +} +declare module 'polished/lib/color/opacify.js' { + declare module.exports: $Exports<'polished/lib/color/opacify'>; +} +declare module 'polished/lib/color/parseToHsl.js' { + declare module.exports: $Exports<'polished/lib/color/parseToHsl'>; +} +declare module 'polished/lib/color/parseToRgb.js' { + declare module.exports: $Exports<'polished/lib/color/parseToRgb'>; +} +declare module 'polished/lib/color/readableColor.js' { + declare module.exports: $Exports<'polished/lib/color/readableColor'>; +} +declare module 'polished/lib/color/rgb.js' { + declare module.exports: $Exports<'polished/lib/color/rgb'>; +} +declare module 'polished/lib/color/rgba.js' { + declare module.exports: $Exports<'polished/lib/color/rgba'>; +} +declare module 'polished/lib/color/saturate.js' { + declare module.exports: $Exports<'polished/lib/color/saturate'>; +} +declare module 'polished/lib/color/setHue.js' { + declare module.exports: $Exports<'polished/lib/color/setHue'>; +} +declare module 'polished/lib/color/setLightness.js' { + declare module.exports: $Exports<'polished/lib/color/setLightness'>; +} +declare module 'polished/lib/color/setSaturation.js' { + declare module.exports: $Exports<'polished/lib/color/setSaturation'>; +} +declare module 'polished/lib/color/shade.js' { + declare module.exports: $Exports<'polished/lib/color/shade'>; +} +declare module 'polished/lib/color/tint.js' { + declare module.exports: $Exports<'polished/lib/color/tint'>; +} +declare module 'polished/lib/color/toColorString.js' { + declare module.exports: $Exports<'polished/lib/color/toColorString'>; +} +declare module 'polished/lib/color/transparentize.js' { + declare module.exports: $Exports<'polished/lib/color/transparentize'>; +} +declare module 'polished/lib/helpers/directionalProperty.js' { + declare module.exports: $Exports<'polished/lib/helpers/directionalProperty'>; +} +declare module 'polished/lib/helpers/em.js' { + declare module.exports: $Exports<'polished/lib/helpers/em'>; +} +declare module 'polished/lib/helpers/modularScale.js' { + declare module.exports: $Exports<'polished/lib/helpers/modularScale'>; +} +declare module 'polished/lib/helpers/rem.js' { + declare module.exports: $Exports<'polished/lib/helpers/rem'>; +} +declare module 'polished/lib/helpers/stripUnit.js' { + declare module.exports: $Exports<'polished/lib/helpers/stripUnit'>; +} +declare module 'polished/lib/index.js' { + declare module.exports: $Exports<'polished/lib/index'>; +} +declare module 'polished/lib/internalHelpers/_capitalizeString.js' { + declare module.exports: $Exports<'polished/lib/internalHelpers/_capitalizeString'>; +} +declare module 'polished/lib/internalHelpers/_curry.js' { + declare module.exports: $Exports<'polished/lib/internalHelpers/_curry'>; +} +declare module 'polished/lib/internalHelpers/_endsWith.js' { + declare module.exports: $Exports<'polished/lib/internalHelpers/_endsWith'>; +} +declare module 'polished/lib/internalHelpers/_guard.js' { + declare module.exports: $Exports<'polished/lib/internalHelpers/_guard'>; +} +declare module 'polished/lib/internalHelpers/_hslToHex.js' { + declare module.exports: $Exports<'polished/lib/internalHelpers/_hslToHex'>; +} +declare module 'polished/lib/internalHelpers/_hslToRgb.js' { + declare module.exports: $Exports<'polished/lib/internalHelpers/_hslToRgb'>; +} +declare module 'polished/lib/internalHelpers/_isValidDimensionValue.js' { + declare module.exports: $Exports<'polished/lib/internalHelpers/_isValidDimensionValue'>; +} +declare module 'polished/lib/internalHelpers/_nameToHex.js' { + declare module.exports: $Exports<'polished/lib/internalHelpers/_nameToHex'>; +} +declare module 'polished/lib/internalHelpers/_numberToHex.js' { + declare module.exports: $Exports<'polished/lib/internalHelpers/_numberToHex'>; +} +declare module 'polished/lib/internalHelpers/_polishedLogs.js' { + declare module.exports: $Exports<'polished/lib/internalHelpers/_polishedLogs'>; +} +declare module 'polished/lib/internalHelpers/_pxto.js' { + declare module.exports: $Exports<'polished/lib/internalHelpers/_pxto'>; +} +declare module 'polished/lib/internalHelpers/_reduceHexValue.js' { + declare module.exports: $Exports<'polished/lib/internalHelpers/_reduceHexValue'>; +} +declare module 'polished/lib/internalHelpers/_rgbToHsl.js' { + declare module.exports: $Exports<'polished/lib/internalHelpers/_rgbToHsl'>; +} +declare module 'polished/lib/internalHelpers/_statefulSelectors.js' { + declare module.exports: $Exports<'polished/lib/internalHelpers/_statefulSelectors'>; +} +declare module 'polished/lib/mixins/clearFix.js' { + declare module.exports: $Exports<'polished/lib/mixins/clearFix'>; +} +declare module 'polished/lib/mixins/ellipsis.js' { + declare module.exports: $Exports<'polished/lib/mixins/ellipsis'>; +} +declare module 'polished/lib/mixins/fontFace.js' { + declare module.exports: $Exports<'polished/lib/mixins/fontFace'>; +} +declare module 'polished/lib/mixins/hideText.js' { + declare module.exports: $Exports<'polished/lib/mixins/hideText'>; +} +declare module 'polished/lib/mixins/hiDPI.js' { + declare module.exports: $Exports<'polished/lib/mixins/hiDPI'>; +} +declare module 'polished/lib/mixins/normalize.js' { + declare module.exports: $Exports<'polished/lib/mixins/normalize'>; +} +declare module 'polished/lib/mixins/placeholder.js' { + declare module.exports: $Exports<'polished/lib/mixins/placeholder'>; +} +declare module 'polished/lib/mixins/radialGradient.js' { + declare module.exports: $Exports<'polished/lib/mixins/radialGradient'>; +} +declare module 'polished/lib/mixins/retinaImage.js' { + declare module.exports: $Exports<'polished/lib/mixins/retinaImage'>; +} +declare module 'polished/lib/mixins/selection.js' { + declare module.exports: $Exports<'polished/lib/mixins/selection'>; +} +declare module 'polished/lib/mixins/timingFunctions.js' { + declare module.exports: $Exports<'polished/lib/mixins/timingFunctions'>; +} +declare module 'polished/lib/mixins/triangle.js' { + declare module.exports: $Exports<'polished/lib/mixins/triangle'>; +} +declare module 'polished/lib/mixins/wordWrap.js' { + declare module.exports: $Exports<'polished/lib/mixins/wordWrap'>; +} +declare module 'polished/lib/shorthands/animation.js' { + declare module.exports: $Exports<'polished/lib/shorthands/animation'>; +} +declare module 'polished/lib/shorthands/backgroundImages.js' { + declare module.exports: $Exports<'polished/lib/shorthands/backgroundImages'>; +} +declare module 'polished/lib/shorthands/backgrounds.js' { + declare module.exports: $Exports<'polished/lib/shorthands/backgrounds'>; +} +declare module 'polished/lib/shorthands/borderColor.js' { + declare module.exports: $Exports<'polished/lib/shorthands/borderColor'>; +} +declare module 'polished/lib/shorthands/borderRadius.js' { + declare module.exports: $Exports<'polished/lib/shorthands/borderRadius'>; +} +declare module 'polished/lib/shorthands/borderStyle.js' { + declare module.exports: $Exports<'polished/lib/shorthands/borderStyle'>; +} +declare module 'polished/lib/shorthands/borderWidth.js' { + declare module.exports: $Exports<'polished/lib/shorthands/borderWidth'>; +} +declare module 'polished/lib/shorthands/buttons.js' { + declare module.exports: $Exports<'polished/lib/shorthands/buttons'>; +} +declare module 'polished/lib/shorthands/margin.js' { + declare module.exports: $Exports<'polished/lib/shorthands/margin'>; +} +declare module 'polished/lib/shorthands/padding.js' { + declare module.exports: $Exports<'polished/lib/shorthands/padding'>; +} +declare module 'polished/lib/shorthands/position.js' { + declare module.exports: $Exports<'polished/lib/shorthands/position'>; +} +declare module 'polished/lib/shorthands/size.js' { + declare module.exports: $Exports<'polished/lib/shorthands/size'>; +} +declare module 'polished/lib/shorthands/textInputs.js' { + declare module.exports: $Exports<'polished/lib/shorthands/textInputs'>; +} +declare module 'polished/lib/shorthands/transitions.js' { + declare module.exports: $Exports<'polished/lib/shorthands/transitions'>; +} +declare module 'polished/lib/types/color.js' { + declare module.exports: $Exports<'polished/lib/types/color'>; +} diff --git a/flow-typed/npm/prettier_vx.x.x.js b/flow-typed/npm/prettier_vx.x.x.js new file mode 100644 index 000000000..f1730aef6 --- /dev/null +++ b/flow-typed/npm/prettier_vx.x.x.js @@ -0,0 +1,87 @@ +// flow-typed signature: 8bbe6221bd08557b01d489734074fd02 +// flow-typed version: <>/prettier_v1.5.0/flow_v0.59.0 + +/** + * This is an autogenerated libdef stub for: + * + * 'prettier' + * + * Fill this stub out by replacing all the `any` types. + * + * Once filled out, we encourage you to share your work with the + * community by sending a pull request to: + * https://github.com/flowtype/flow-typed + */ + +declare module 'prettier' { + declare module.exports: any; +} + +/** + * We include stubs for each file inside this npm package in case you need to + * require those files directly. Feel free to delete any files that aren't + * needed. + */ +declare module 'prettier/bin/prettier' { + declare module.exports: any; +} + +declare module 'prettier/parser-babylon' { + declare module.exports: any; +} + +declare module 'prettier/parser-flow' { + declare module.exports: any; +} + +declare module 'prettier/parser-graphql' { + declare module.exports: any; +} + +declare module 'prettier/parser-json' { + declare module.exports: any; +} + +declare module 'prettier/parser-parse5' { + declare module.exports: any; +} + +declare module 'prettier/parser-postcss' { + declare module.exports: any; +} + +declare module 'prettier/parser-typescript' { + declare module.exports: any; +} + +// Filename aliases +declare module 'prettier/bin/prettier.js' { + declare module.exports: $Exports<'prettier/bin/prettier'>; +} +declare module 'prettier/index' { + declare module.exports: $Exports<'prettier'>; +} +declare module 'prettier/index.js' { + declare module.exports: $Exports<'prettier'>; +} +declare module 'prettier/parser-babylon.js' { + declare module.exports: $Exports<'prettier/parser-babylon'>; +} +declare module 'prettier/parser-flow.js' { + declare module.exports: $Exports<'prettier/parser-flow'>; +} +declare module 'prettier/parser-graphql.js' { + declare module.exports: $Exports<'prettier/parser-graphql'>; +} +declare module 'prettier/parser-json.js' { + declare module.exports: $Exports<'prettier/parser-json'>; +} +declare module 'prettier/parser-parse5.js' { + declare module.exports: $Exports<'prettier/parser-parse5'>; +} +declare module 'prettier/parser-postcss.js' { + declare module.exports: $Exports<'prettier/parser-postcss'>; +} +declare module 'prettier/parser-typescript.js' { + declare module.exports: $Exports<'prettier/parser-typescript'>; +} diff --git a/flow-typed/npm/prop-types_v15.x.x.js b/flow-typed/npm/prop-types_v15.x.x.js new file mode 100644 index 000000000..113b0b5c4 --- /dev/null +++ b/flow-typed/npm/prop-types_v15.x.x.js @@ -0,0 +1,34 @@ +// flow-typed signature: 3eaa1f24c7397b78a7481992d2cddcb2 +// flow-typed version: a1a20d4928/prop-types_v15.x.x/flow_>=v0.41.x + +type $npm$propTypes$ReactPropsCheckType = ( + props: any, + propName: string, + componentName: string, + href?: string) => ?Error; + +declare module 'prop-types' { + declare var array: React$PropType$Primitive>; + declare var bool: React$PropType$Primitive; + declare var func: React$PropType$Primitive; + declare var number: React$PropType$Primitive; + declare var object: React$PropType$Primitive; + declare var string: React$PropType$Primitive; + declare var any: React$PropType$Primitive; + declare var arrayOf: React$PropType$ArrayOf; + declare var element: React$PropType$Primitive; /* TODO */ + declare var instanceOf: React$PropType$InstanceOf; + declare var node: React$PropType$Primitive; /* TODO */ + declare var objectOf: React$PropType$ObjectOf; + declare var oneOf: React$PropType$OneOf; + declare var oneOfType: React$PropType$OneOfType; + declare var shape: React$PropType$Shape; + + declare function checkPropTypes( + propTypes: $Subtype<{[_: $Keys]: $npm$propTypes$ReactPropsCheckType}>, + values: V, + location: string, + componentName: string, + getStack: ?(() => ?string) + ) : void; +} diff --git a/flow-typed/npm/react-color_vx.x.x.js b/flow-typed/npm/react-color_vx.x.x.js new file mode 100644 index 000000000..cab5f273f --- /dev/null +++ b/flow-typed/npm/react-color_vx.x.x.js @@ -0,0 +1,704 @@ +// flow-typed signature: d3fd33836d3ae586d973d7728260a311 +// flow-typed version: <>/react-color_v^2.11.7/flow_v0.59.0 + +/** + * This is an autogenerated libdef stub for: + * + * 'react-color' + * + * Fill this stub out by replacing all the `any` types. + * + * Once filled out, we encourage you to share your work with the + * community by sending a pull request to: + * https://github.com/flowtype/flow-typed + */ + +declare module 'react-color' { + declare module.exports: any; +} + +/** + * We include stubs for each file inside this npm package in case you need to + * require those files directly. Feel free to delete any files that aren't + * needed. + */ +declare module 'react-color/examples/Button' { + declare module.exports: any; +} + +declare module 'react-color/examples/index' { + declare module.exports: any; +} + +declare module 'react-color/examples/Sketch' { + declare module.exports: any; +} + +declare module 'react-color/lib/components/alpha/Alpha' { + declare module.exports: any; +} + +declare module 'react-color/lib/components/alpha/AlphaPointer' { + declare module.exports: any; +} + +declare module 'react-color/lib/components/alpha/spec' { + declare module.exports: any; +} + +declare module 'react-color/lib/components/block/Block' { + declare module.exports: any; +} + +declare module 'react-color/lib/components/block/BlockSwatches' { + declare module.exports: any; +} + +declare module 'react-color/lib/components/block/spec' { + declare module.exports: any; +} + +declare module 'react-color/lib/components/chrome/Chrome' { + declare module.exports: any; +} + +declare module 'react-color/lib/components/chrome/ChromeFields' { + declare module.exports: any; +} + +declare module 'react-color/lib/components/chrome/ChromePointer' { + declare module.exports: any; +} + +declare module 'react-color/lib/components/chrome/ChromePointerCircle' { + declare module.exports: any; +} + +declare module 'react-color/lib/components/chrome/spec' { + declare module.exports: any; +} + +declare module 'react-color/lib/components/circle/Circle' { + declare module.exports: any; +} + +declare module 'react-color/lib/components/circle/CircleSwatch' { + declare module.exports: any; +} + +declare module 'react-color/lib/components/circle/spec' { + declare module.exports: any; +} + +declare module 'react-color/lib/components/common/Alpha' { + declare module.exports: any; +} + +declare module 'react-color/lib/components/common/Checkboard' { + declare module.exports: any; +} + +declare module 'react-color/lib/components/common/ColorWrap' { + declare module.exports: any; +} + +declare module 'react-color/lib/components/common/EditableInput' { + declare module.exports: any; +} + +declare module 'react-color/lib/components/common/Hue' { + declare module.exports: any; +} + +declare module 'react-color/lib/components/common/index' { + declare module.exports: any; +} + +declare module 'react-color/lib/components/common/Saturation' { + declare module.exports: any; +} + +declare module 'react-color/lib/components/common/spec' { + declare module.exports: any; +} + +declare module 'react-color/lib/components/common/Swatch' { + declare module.exports: any; +} + +declare module 'react-color/lib/components/compact/Compact' { + declare module.exports: any; +} + +declare module 'react-color/lib/components/compact/CompactColor' { + declare module.exports: any; +} + +declare module 'react-color/lib/components/compact/CompactFields' { + declare module.exports: any; +} + +declare module 'react-color/lib/components/compact/spec' { + declare module.exports: any; +} + +declare module 'react-color/lib/components/github/Github' { + declare module.exports: any; +} + +declare module 'react-color/lib/components/github/GithubSwatch' { + declare module.exports: any; +} + +declare module 'react-color/lib/components/github/spec' { + declare module.exports: any; +} + +declare module 'react-color/lib/components/hue/Hue' { + declare module.exports: any; +} + +declare module 'react-color/lib/components/hue/HuePointer' { + declare module.exports: any; +} + +declare module 'react-color/lib/components/hue/spec' { + declare module.exports: any; +} + +declare module 'react-color/lib/components/material/Material' { + declare module.exports: any; +} + +declare module 'react-color/lib/components/material/spec' { + declare module.exports: any; +} + +declare module 'react-color/lib/components/photoshop/Photoshop' { + declare module.exports: any; +} + +declare module 'react-color/lib/components/photoshop/PhotoshopButton' { + declare module.exports: any; +} + +declare module 'react-color/lib/components/photoshop/PhotoshopFields' { + declare module.exports: any; +} + +declare module 'react-color/lib/components/photoshop/PhotoshopPointer' { + declare module.exports: any; +} + +declare module 'react-color/lib/components/photoshop/PhotoshopPointerCircle' { + declare module.exports: any; +} + +declare module 'react-color/lib/components/photoshop/PhotoshopPreviews' { + declare module.exports: any; +} + +declare module 'react-color/lib/components/photoshop/spec' { + declare module.exports: any; +} + +declare module 'react-color/lib/components/sketch/Sketch' { + declare module.exports: any; +} + +declare module 'react-color/lib/components/sketch/SketchFields' { + declare module.exports: any; +} + +declare module 'react-color/lib/components/sketch/SketchPresetColors' { + declare module.exports: any; +} + +declare module 'react-color/lib/components/sketch/spec' { + declare module.exports: any; +} + +declare module 'react-color/lib/components/slider/Slider' { + declare module.exports: any; +} + +declare module 'react-color/lib/components/slider/SliderPointer' { + declare module.exports: any; +} + +declare module 'react-color/lib/components/slider/SliderSwatch' { + declare module.exports: any; +} + +declare module 'react-color/lib/components/slider/SliderSwatches' { + declare module.exports: any; +} + +declare module 'react-color/lib/components/slider/spec' { + declare module.exports: any; +} + +declare module 'react-color/lib/components/swatches/spec' { + declare module.exports: any; +} + +declare module 'react-color/lib/components/swatches/Swatches' { + declare module.exports: any; +} + +declare module 'react-color/lib/components/swatches/SwatchesColor' { + declare module.exports: any; +} + +declare module 'react-color/lib/components/swatches/SwatchesGroup' { + declare module.exports: any; +} + +declare module 'react-color/lib/components/twitter/spec' { + declare module.exports: any; +} + +declare module 'react-color/lib/components/twitter/Twitter' { + declare module.exports: any; +} + +declare module 'react-color/lib/helpers/alpha' { + declare module.exports: any; +} + +declare module 'react-color/lib/helpers/checkboard' { + declare module.exports: any; +} + +declare module 'react-color/lib/helpers/color' { + declare module.exports: any; +} + +declare module 'react-color/lib/helpers/hue' { + declare module.exports: any; +} + +declare module 'react-color/lib/helpers/interaction' { + declare module.exports: any; +} + +declare module 'react-color/lib/helpers/saturation' { + declare module.exports: any; +} + +declare module 'react-color/lib/helpers/spec' { + declare module.exports: any; +} + +declare module 'react-color/lib/index' { + declare module.exports: any; +} + +declare module 'react-color/modules/highlight' { + declare module.exports: any; +} + +declare module 'react-color/modules/highlight.js/highlight' { + declare module.exports: any; +} + +declare module 'react-color/modules/highlight.js/index' { + declare module.exports: any; +} + +declare module 'react-color/modules/highlight.js/languages/javascript' { + declare module.exports: any; +} + +declare module 'react-color/modules/react-basic-layout/index' { + declare module.exports: any; +} + +declare module 'react-color/modules/react-basic-layout/lib/components/Container' { + declare module.exports: any; +} + +declare module 'react-color/modules/react-basic-layout/lib/components/Grid' { + declare module.exports: any; +} + +declare module 'react-color/modules/react-docs/index' { + declare module.exports: any; +} + +declare module 'react-color/modules/react-docs/lib/components/Code' { + declare module.exports: any; +} + +declare module 'react-color/modules/react-docs/lib/components/Docs' { + declare module.exports: any; +} + +declare module 'react-color/modules/react-docs/lib/components/Markdown' { + declare module.exports: any; +} + +declare module 'react-color/modules/react-docs/lib/components/MarkdownTitle' { + declare module.exports: any; +} + +declare module 'react-color/modules/react-docs/lib/components/Sidebar' { + declare module.exports: any; +} + +declare module 'react-color/modules/react-docs/lib/components/SidebarItem' { + declare module.exports: any; +} + +declare module 'react-color/modules/react-docs/lib/helpers/markdown' { + declare module.exports: any; +} + +declare module 'react-color/modules/react-material-design/index' { + declare module.exports: any; +} + +declare module 'react-color/modules/react-material-design/lib/components/Link' { + declare module.exports: any; +} + +declare module 'react-color/modules/react-material-design/lib/components/Raised' { + declare module.exports: any; +} + +declare module 'react-color/modules/react-material-design/lib/components/Tab' { + declare module.exports: any; +} + +declare module 'react-color/modules/react-material-design/lib/components/Tabs' { + declare module.exports: any; +} + +declare module 'react-color/modules/react-material-design/lib/components/Tile' { + declare module.exports: any; +} + +declare module 'react-color/modules/react-move/index' { + declare module.exports: any; +} + +declare module 'react-color/modules/react-move/lib/components/Move' { + declare module.exports: any; +} + +declare module 'react-color/modules/remarkable/index' { + declare module.exports: any; +} + +declare module 'react-color/modules/tinycolor2/index' { + declare module.exports: any; +} + +declare module 'react-color/modules/webpack-react-static/index' { + declare module.exports: any; +} + +declare module 'react-color/scripts/docs-dist' { + declare module.exports: any; +} + +declare module 'react-color/scripts/docs-server' { + declare module.exports: any; +} + +declare module 'react-color/webpack.config' { + declare module.exports: any; +} + +// Filename aliases +declare module 'react-color/examples/Button.js' { + declare module.exports: $Exports<'react-color/examples/Button'>; +} +declare module 'react-color/examples/index.js' { + declare module.exports: $Exports<'react-color/examples/index'>; +} +declare module 'react-color/examples/Sketch.js' { + declare module.exports: $Exports<'react-color/examples/Sketch'>; +} +declare module 'react-color/lib/components/alpha/Alpha.js' { + declare module.exports: $Exports<'react-color/lib/components/alpha/Alpha'>; +} +declare module 'react-color/lib/components/alpha/AlphaPointer.js' { + declare module.exports: $Exports<'react-color/lib/components/alpha/AlphaPointer'>; +} +declare module 'react-color/lib/components/alpha/spec.js' { + declare module.exports: $Exports<'react-color/lib/components/alpha/spec'>; +} +declare module 'react-color/lib/components/block/Block.js' { + declare module.exports: $Exports<'react-color/lib/components/block/Block'>; +} +declare module 'react-color/lib/components/block/BlockSwatches.js' { + declare module.exports: $Exports<'react-color/lib/components/block/BlockSwatches'>; +} +declare module 'react-color/lib/components/block/spec.js' { + declare module.exports: $Exports<'react-color/lib/components/block/spec'>; +} +declare module 'react-color/lib/components/chrome/Chrome.js' { + declare module.exports: $Exports<'react-color/lib/components/chrome/Chrome'>; +} +declare module 'react-color/lib/components/chrome/ChromeFields.js' { + declare module.exports: $Exports<'react-color/lib/components/chrome/ChromeFields'>; +} +declare module 'react-color/lib/components/chrome/ChromePointer.js' { + declare module.exports: $Exports<'react-color/lib/components/chrome/ChromePointer'>; +} +declare module 'react-color/lib/components/chrome/ChromePointerCircle.js' { + declare module.exports: $Exports<'react-color/lib/components/chrome/ChromePointerCircle'>; +} +declare module 'react-color/lib/components/chrome/spec.js' { + declare module.exports: $Exports<'react-color/lib/components/chrome/spec'>; +} +declare module 'react-color/lib/components/circle/Circle.js' { + declare module.exports: $Exports<'react-color/lib/components/circle/Circle'>; +} +declare module 'react-color/lib/components/circle/CircleSwatch.js' { + declare module.exports: $Exports<'react-color/lib/components/circle/CircleSwatch'>; +} +declare module 'react-color/lib/components/circle/spec.js' { + declare module.exports: $Exports<'react-color/lib/components/circle/spec'>; +} +declare module 'react-color/lib/components/common/Alpha.js' { + declare module.exports: $Exports<'react-color/lib/components/common/Alpha'>; +} +declare module 'react-color/lib/components/common/Checkboard.js' { + declare module.exports: $Exports<'react-color/lib/components/common/Checkboard'>; +} +declare module 'react-color/lib/components/common/ColorWrap.js' { + declare module.exports: $Exports<'react-color/lib/components/common/ColorWrap'>; +} +declare module 'react-color/lib/components/common/EditableInput.js' { + declare module.exports: $Exports<'react-color/lib/components/common/EditableInput'>; +} +declare module 'react-color/lib/components/common/Hue.js' { + declare module.exports: $Exports<'react-color/lib/components/common/Hue'>; +} +declare module 'react-color/lib/components/common/index.js' { + declare module.exports: $Exports<'react-color/lib/components/common/index'>; +} +declare module 'react-color/lib/components/common/Saturation.js' { + declare module.exports: $Exports<'react-color/lib/components/common/Saturation'>; +} +declare module 'react-color/lib/components/common/spec.js' { + declare module.exports: $Exports<'react-color/lib/components/common/spec'>; +} +declare module 'react-color/lib/components/common/Swatch.js' { + declare module.exports: $Exports<'react-color/lib/components/common/Swatch'>; +} +declare module 'react-color/lib/components/compact/Compact.js' { + declare module.exports: $Exports<'react-color/lib/components/compact/Compact'>; +} +declare module 'react-color/lib/components/compact/CompactColor.js' { + declare module.exports: $Exports<'react-color/lib/components/compact/CompactColor'>; +} +declare module 'react-color/lib/components/compact/CompactFields.js' { + declare module.exports: $Exports<'react-color/lib/components/compact/CompactFields'>; +} +declare module 'react-color/lib/components/compact/spec.js' { + declare module.exports: $Exports<'react-color/lib/components/compact/spec'>; +} +declare module 'react-color/lib/components/github/Github.js' { + declare module.exports: $Exports<'react-color/lib/components/github/Github'>; +} +declare module 'react-color/lib/components/github/GithubSwatch.js' { + declare module.exports: $Exports<'react-color/lib/components/github/GithubSwatch'>; +} +declare module 'react-color/lib/components/github/spec.js' { + declare module.exports: $Exports<'react-color/lib/components/github/spec'>; +} +declare module 'react-color/lib/components/hue/Hue.js' { + declare module.exports: $Exports<'react-color/lib/components/hue/Hue'>; +} +declare module 'react-color/lib/components/hue/HuePointer.js' { + declare module.exports: $Exports<'react-color/lib/components/hue/HuePointer'>; +} +declare module 'react-color/lib/components/hue/spec.js' { + declare module.exports: $Exports<'react-color/lib/components/hue/spec'>; +} +declare module 'react-color/lib/components/material/Material.js' { + declare module.exports: $Exports<'react-color/lib/components/material/Material'>; +} +declare module 'react-color/lib/components/material/spec.js' { + declare module.exports: $Exports<'react-color/lib/components/material/spec'>; +} +declare module 'react-color/lib/components/photoshop/Photoshop.js' { + declare module.exports: $Exports<'react-color/lib/components/photoshop/Photoshop'>; +} +declare module 'react-color/lib/components/photoshop/PhotoshopButton.js' { + declare module.exports: $Exports<'react-color/lib/components/photoshop/PhotoshopButton'>; +} +declare module 'react-color/lib/components/photoshop/PhotoshopFields.js' { + declare module.exports: $Exports<'react-color/lib/components/photoshop/PhotoshopFields'>; +} +declare module 'react-color/lib/components/photoshop/PhotoshopPointer.js' { + declare module.exports: $Exports<'react-color/lib/components/photoshop/PhotoshopPointer'>; +} +declare module 'react-color/lib/components/photoshop/PhotoshopPointerCircle.js' { + declare module.exports: $Exports<'react-color/lib/components/photoshop/PhotoshopPointerCircle'>; +} +declare module 'react-color/lib/components/photoshop/PhotoshopPreviews.js' { + declare module.exports: $Exports<'react-color/lib/components/photoshop/PhotoshopPreviews'>; +} +declare module 'react-color/lib/components/photoshop/spec.js' { + declare module.exports: $Exports<'react-color/lib/components/photoshop/spec'>; +} +declare module 'react-color/lib/components/sketch/Sketch.js' { + declare module.exports: $Exports<'react-color/lib/components/sketch/Sketch'>; +} +declare module 'react-color/lib/components/sketch/SketchFields.js' { + declare module.exports: $Exports<'react-color/lib/components/sketch/SketchFields'>; +} +declare module 'react-color/lib/components/sketch/SketchPresetColors.js' { + declare module.exports: $Exports<'react-color/lib/components/sketch/SketchPresetColors'>; +} +declare module 'react-color/lib/components/sketch/spec.js' { + declare module.exports: $Exports<'react-color/lib/components/sketch/spec'>; +} +declare module 'react-color/lib/components/slider/Slider.js' { + declare module.exports: $Exports<'react-color/lib/components/slider/Slider'>; +} +declare module 'react-color/lib/components/slider/SliderPointer.js' { + declare module.exports: $Exports<'react-color/lib/components/slider/SliderPointer'>; +} +declare module 'react-color/lib/components/slider/SliderSwatch.js' { + declare module.exports: $Exports<'react-color/lib/components/slider/SliderSwatch'>; +} +declare module 'react-color/lib/components/slider/SliderSwatches.js' { + declare module.exports: $Exports<'react-color/lib/components/slider/SliderSwatches'>; +} +declare module 'react-color/lib/components/slider/spec.js' { + declare module.exports: $Exports<'react-color/lib/components/slider/spec'>; +} +declare module 'react-color/lib/components/swatches/spec.js' { + declare module.exports: $Exports<'react-color/lib/components/swatches/spec'>; +} +declare module 'react-color/lib/components/swatches/Swatches.js' { + declare module.exports: $Exports<'react-color/lib/components/swatches/Swatches'>; +} +declare module 'react-color/lib/components/swatches/SwatchesColor.js' { + declare module.exports: $Exports<'react-color/lib/components/swatches/SwatchesColor'>; +} +declare module 'react-color/lib/components/swatches/SwatchesGroup.js' { + declare module.exports: $Exports<'react-color/lib/components/swatches/SwatchesGroup'>; +} +declare module 'react-color/lib/components/twitter/spec.js' { + declare module.exports: $Exports<'react-color/lib/components/twitter/spec'>; +} +declare module 'react-color/lib/components/twitter/Twitter.js' { + declare module.exports: $Exports<'react-color/lib/components/twitter/Twitter'>; +} +declare module 'react-color/lib/helpers/alpha.js' { + declare module.exports: $Exports<'react-color/lib/helpers/alpha'>; +} +declare module 'react-color/lib/helpers/checkboard.js' { + declare module.exports: $Exports<'react-color/lib/helpers/checkboard'>; +} +declare module 'react-color/lib/helpers/color.js' { + declare module.exports: $Exports<'react-color/lib/helpers/color'>; +} +declare module 'react-color/lib/helpers/hue.js' { + declare module.exports: $Exports<'react-color/lib/helpers/hue'>; +} +declare module 'react-color/lib/helpers/interaction.js' { + declare module.exports: $Exports<'react-color/lib/helpers/interaction'>; +} +declare module 'react-color/lib/helpers/saturation.js' { + declare module.exports: $Exports<'react-color/lib/helpers/saturation'>; +} +declare module 'react-color/lib/helpers/spec.js' { + declare module.exports: $Exports<'react-color/lib/helpers/spec'>; +} +declare module 'react-color/lib/index.js' { + declare module.exports: $Exports<'react-color/lib/index'>; +} +declare module 'react-color/modules/highlight.js' { + declare module.exports: $Exports<'react-color/modules/highlight'>; +} +declare module 'react-color/modules/highlight.js/highlight.js' { + declare module.exports: $Exports<'react-color/modules/highlight.js/highlight'>; +} +declare module 'react-color/modules/highlight.js/index.js' { + declare module.exports: $Exports<'react-color/modules/highlight.js/index'>; +} +declare module 'react-color/modules/highlight.js/languages/javascript.js' { + declare module.exports: $Exports<'react-color/modules/highlight.js/languages/javascript'>; +} +declare module 'react-color/modules/react-basic-layout/index.js' { + declare module.exports: $Exports<'react-color/modules/react-basic-layout/index'>; +} +declare module 'react-color/modules/react-basic-layout/lib/components/Container.js' { + declare module.exports: $Exports<'react-color/modules/react-basic-layout/lib/components/Container'>; +} +declare module 'react-color/modules/react-basic-layout/lib/components/Grid.js' { + declare module.exports: $Exports<'react-color/modules/react-basic-layout/lib/components/Grid'>; +} +declare module 'react-color/modules/react-docs/index.js' { + declare module.exports: $Exports<'react-color/modules/react-docs/index'>; +} +declare module 'react-color/modules/react-docs/lib/components/Code.js' { + declare module.exports: $Exports<'react-color/modules/react-docs/lib/components/Code'>; +} +declare module 'react-color/modules/react-docs/lib/components/Docs.js' { + declare module.exports: $Exports<'react-color/modules/react-docs/lib/components/Docs'>; +} +declare module 'react-color/modules/react-docs/lib/components/Markdown.js' { + declare module.exports: $Exports<'react-color/modules/react-docs/lib/components/Markdown'>; +} +declare module 'react-color/modules/react-docs/lib/components/MarkdownTitle.js' { + declare module.exports: $Exports<'react-color/modules/react-docs/lib/components/MarkdownTitle'>; +} +declare module 'react-color/modules/react-docs/lib/components/Sidebar.js' { + declare module.exports: $Exports<'react-color/modules/react-docs/lib/components/Sidebar'>; +} +declare module 'react-color/modules/react-docs/lib/components/SidebarItem.js' { + declare module.exports: $Exports<'react-color/modules/react-docs/lib/components/SidebarItem'>; +} +declare module 'react-color/modules/react-docs/lib/helpers/markdown.js' { + declare module.exports: $Exports<'react-color/modules/react-docs/lib/helpers/markdown'>; +} +declare module 'react-color/modules/react-material-design/index.js' { + declare module.exports: $Exports<'react-color/modules/react-material-design/index'>; +} +declare module 'react-color/modules/react-material-design/lib/components/Link.js' { + declare module.exports: $Exports<'react-color/modules/react-material-design/lib/components/Link'>; +} +declare module 'react-color/modules/react-material-design/lib/components/Raised.js' { + declare module.exports: $Exports<'react-color/modules/react-material-design/lib/components/Raised'>; +} +declare module 'react-color/modules/react-material-design/lib/components/Tab.js' { + declare module.exports: $Exports<'react-color/modules/react-material-design/lib/components/Tab'>; +} +declare module 'react-color/modules/react-material-design/lib/components/Tabs.js' { + declare module.exports: $Exports<'react-color/modules/react-material-design/lib/components/Tabs'>; +} +declare module 'react-color/modules/react-material-design/lib/components/Tile.js' { + declare module.exports: $Exports<'react-color/modules/react-material-design/lib/components/Tile'>; +} +declare module 'react-color/modules/react-move/index.js' { + declare module.exports: $Exports<'react-color/modules/react-move/index'>; +} +declare module 'react-color/modules/react-move/lib/components/Move.js' { + declare module.exports: $Exports<'react-color/modules/react-move/lib/components/Move'>; +} +declare module 'react-color/modules/remarkable/index.js' { + declare module.exports: $Exports<'react-color/modules/remarkable/index'>; +} +declare module 'react-color/modules/tinycolor2/index.js' { + declare module.exports: $Exports<'react-color/modules/tinycolor2/index'>; +} +declare module 'react-color/modules/webpack-react-static/index.js' { + declare module.exports: $Exports<'react-color/modules/webpack-react-static/index'>; +} +declare module 'react-color/scripts/docs-dist.js' { + declare module.exports: $Exports<'react-color/scripts/docs-dist'>; +} +declare module 'react-color/scripts/docs-server.js' { + declare module.exports: $Exports<'react-color/scripts/docs-server'>; +} +declare module 'react-color/webpack.config.js' { + declare module.exports: $Exports<'react-color/webpack.config'>; +} diff --git a/flow-typed/npm/react-devtools-core_vx.x.x.js b/flow-typed/npm/react-devtools-core_vx.x.x.js new file mode 100644 index 000000000..3ae4bcb67 --- /dev/null +++ b/flow-typed/npm/react-devtools-core_vx.x.x.js @@ -0,0 +1,52 @@ +// flow-typed signature: fd664fcf7a2fc39e3ce5d7776ec7ae24 +// flow-typed version: <>/react-devtools-core_v3.0.0/flow_v0.59.0 + +/** + * This is an autogenerated libdef stub for: + * + * 'react-devtools-core' + * + * Fill this stub out by replacing all the `any` types. + * + * Once filled out, we encourage you to share your work with the + * community by sending a pull request to: + * https://github.com/flowtype/flow-typed + */ + +declare module 'react-devtools-core' { + declare module.exports: any; +} + +/** + * We include stubs for each file inside this npm package in case you need to + * require those files directly. Feel free to delete any files that aren't + * needed. + */ +declare module 'react-devtools-core/build/backend' { + declare module.exports: any; +} + +declare module 'react-devtools-core/build/standalone' { + declare module.exports: any; +} + +declare module 'react-devtools-core/standalone' { + declare module.exports: any; +} + +// Filename aliases +declare module 'react-devtools-core/build/backend.js' { + declare module.exports: $Exports<'react-devtools-core/build/backend'>; +} +declare module 'react-devtools-core/build/standalone.js' { + declare module.exports: $Exports<'react-devtools-core/build/standalone'>; +} +declare module 'react-devtools-core/index' { + declare module.exports: $Exports<'react-devtools-core'>; +} +declare module 'react-devtools-core/index.js' { + declare module.exports: $Exports<'react-devtools-core'>; +} +declare module 'react-devtools-core/standalone.js' { + declare module.exports: $Exports<'react-devtools-core/standalone'>; +} diff --git a/flow-typed/npm/react-redux_v5.x.x.js b/flow-typed/npm/react-redux_v5.x.x.js new file mode 100644 index 000000000..ac2894267 --- /dev/null +++ b/flow-typed/npm/react-redux_v5.x.x.js @@ -0,0 +1,157 @@ +// flow-typed signature: 16b40ff613d36712444ef20fb107de7c +// flow-typed version: be6cfc6753/react-redux_v5.x.x/flow_>=v0.62.0 + +import type { Dispatch, Store } from "redux"; + +declare module "react-redux" { + import type { ComponentType, ElementConfig } from 'react'; + + declare export class Provider extends React$Component<{ + store: Store, + children?: any + }> {} + + declare export function createProvider( + storeKey?: string, + subKey?: string + ): Provider<*, *>; + + /* + + S = State + A = Action + OP = OwnProps + SP = StateProps + DP = DispatchProps + MP = Merge props + MDP = Map dispatch to props object + RSP = Returned state props + RDP = Returned dispatch props + RMP = Returned merge props + CP = Props for returned component + Com = React Component + */ + + declare type MapStateToProps = (state: S, props: SP) => RSP; + + declare type MapDispatchToProps = (dispatch: Dispatch, ownProps: OP) => RDP; + + declare type MergeProps = ( + stateProps: SP, + dispatchProps: DP, + ownProps: MP + ) => RMP; + + declare type ConnectOptions = {| + pure?: boolean, + withRef?: boolean, + areStatesEqual?: (next: S, prev: S) => boolean, + areOwnPropsEqual?: (next: OP, prev: OP) => boolean, + areStatePropsEqual?: (next: RSP, prev: RSP) => boolean, + areMergedPropsEqual?: (next: RMP, prev: RMP) => boolean, + storeKey?: string + |}; + + declare type OmitDispatch = $Diff}>; + + declare export function connect< + Com: ComponentType<*>, + S: Object, + DP: Object, + RSP: Object, + CP: $Diff>, RSP> + >( + mapStateToProps: MapStateToProps, + mapDispatchToProps?: null + ): (component: Com) => ComponentType; + + declare export function connect>( + mapStateToProps?: null, + mapDispatchToProps?: null + ): (component: Com) => ComponentType>>; + + declare export function connect< + Com: ComponentType<*>, + A, + S: Object, + DP: Object, + SP: Object, + RSP: Object, + RDP: Object, + CP: $Diff<$Diff, RSP>, RDP> + >( + mapStateToProps: MapStateToProps, + mapDispatchToProps: MapDispatchToProps + ): (component: Com) => ComponentType; + + declare export function connect< + Com: ComponentType<*>, + A, + OP: Object, + DP: Object, + PR: Object, + CP: $Diff, DP> + >( + mapStateToProps?: null, + mapDispatchToProps: MapDispatchToProps + ): (Com) => ComponentType; + + declare export function connect< + Com: ComponentType<*>, + MDP: Object + >( + mapStateToProps?: null, + mapDispatchToProps: MDP + ): (component: Com) => ComponentType<$Diff, MDP>>; + + declare export function connect< + Com: ComponentType<*>, + S: Object, + SP: Object, + RSP: Object, + MDP: Object, + CP: $Diff, RSP> + >( + mapStateToProps: MapStateToProps, + mapDispatchToPRops: MDP + ): (component: Com) => ComponentType<$Diff & SP>; + + declare export function connect< + Com: ComponentType<*>, + A, + S: Object, + DP: Object, + SP: Object, + RSP: Object, + RDP: Object, + MP: Object, + RMP: Object, + CP: $Diff, RMP> + >( + mapStateToProps: MapStateToProps, + mapDispatchToProps: ?MapDispatchToProps, + mergeProps: MergeProps + ): (component: Com) => ComponentType; + + declare export function connect, + A, + S: Object, + DP: Object, + SP: Object, + RSP: Object, + RDP: Object, + MP: Object, + RMP: Object + >( + mapStateToProps: ?MapStateToProps, + mapDispatchToProps: ?MapDispatchToProps, + mergeProps: ?MergeProps, + options: ConnectOptions + ): (component: Com) => ComponentType<$Diff, RMP> & SP & DP & MP>; + + declare export default { + Provider: typeof Provider, + createProvider: typeof createProvider, + connect: typeof connect, + }; +} diff --git a/flow-typed/npm/react-test-renderer_vx.x.x.js b/flow-typed/npm/react-test-renderer_vx.x.x.js new file mode 100644 index 000000000..3669cea22 --- /dev/null +++ b/flow-typed/npm/react-test-renderer_vx.x.x.js @@ -0,0 +1,66 @@ +// flow-typed signature: d75e9be7ed16f88e288f787e982584b8 +// flow-typed version: <>/react-test-renderer_v^16/flow_v0.59.0 + +/** + * This is an autogenerated libdef stub for: + * + * 'react-test-renderer' + * + * Fill this stub out by replacing all the `any` types. + * + * Once filled out, we encourage you to share your work with the + * community by sending a pull request to: + * https://github.com/flowtype/flow-typed + */ + +declare module 'react-test-renderer' { + declare module.exports: any; +} + +/** + * We include stubs for each file inside this npm package in case you need to + * require those files directly. Feel free to delete any files that aren't + * needed. + */ +declare module 'react-test-renderer/cjs/react-test-renderer-shallow.development' { + declare module.exports: any; +} + +declare module 'react-test-renderer/cjs/react-test-renderer-shallow.production.min' { + declare module.exports: any; +} + +declare module 'react-test-renderer/cjs/react-test-renderer.development' { + declare module.exports: any; +} + +declare module 'react-test-renderer/cjs/react-test-renderer.production.min' { + declare module.exports: any; +} + +declare module 'react-test-renderer/shallow' { + declare module.exports: any; +} + +// Filename aliases +declare module 'react-test-renderer/cjs/react-test-renderer-shallow.development.js' { + declare module.exports: $Exports<'react-test-renderer/cjs/react-test-renderer-shallow.development'>; +} +declare module 'react-test-renderer/cjs/react-test-renderer-shallow.production.min.js' { + declare module.exports: $Exports<'react-test-renderer/cjs/react-test-renderer-shallow.production.min'>; +} +declare module 'react-test-renderer/cjs/react-test-renderer.development.js' { + declare module.exports: $Exports<'react-test-renderer/cjs/react-test-renderer.development'>; +} +declare module 'react-test-renderer/cjs/react-test-renderer.production.min.js' { + declare module.exports: $Exports<'react-test-renderer/cjs/react-test-renderer.production.min'>; +} +declare module 'react-test-renderer/index' { + declare module.exports: $Exports<'react-test-renderer'>; +} +declare module 'react-test-renderer/index.js' { + declare module.exports: $Exports<'react-test-renderer'>; +} +declare module 'react-test-renderer/shallow.js' { + declare module.exports: $Exports<'react-test-renderer/shallow'>; +} diff --git a/flow-typed/npm/react-virtualized_vx.x.x.js b/flow-typed/npm/react-virtualized_vx.x.x.js new file mode 100644 index 000000000..e26d1aa95 --- /dev/null +++ b/flow-typed/npm/react-virtualized_vx.x.x.js @@ -0,0 +1,1376 @@ +// flow-typed signature: 7ad3746a26284155ba00efee65b4be9b +// flow-typed version: <>/react-virtualized_v^9.13.0/flow_v0.59.0 + +/** + * This is an autogenerated libdef stub for: + * + * 'react-virtualized' + * + * Fill this stub out by replacing all the `any` types. + * + * Once filled out, we encourage you to share your work with the + * community by sending a pull request to: + * https://github.com/flowtype/flow-typed + */ + +declare module 'react-virtualized' { + declare module.exports: any; +} + +/** + * We include stubs for each file inside this npm package in case you need to + * require those files directly. Feel free to delete any files that aren't + * needed. + */ +declare module 'react-virtualized/dist/commonjs/ArrowKeyStepper/ArrowKeyStepper.jest' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/commonjs/ArrowKeyStepper/ArrowKeyStepper' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/commonjs/ArrowKeyStepper/index' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/commonjs/ArrowKeyStepper/types' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/commonjs/AutoSizer/AutoSizer.jest' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/commonjs/AutoSizer/AutoSizer' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/commonjs/AutoSizer/index' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/commonjs/AutoSizer/types' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/commonjs/CellMeasurer/CellMeasurer.jest' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/commonjs/CellMeasurer/CellMeasurer' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/commonjs/CellMeasurer/CellMeasurerCache.jest' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/commonjs/CellMeasurer/CellMeasurerCache' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/commonjs/CellMeasurer/index' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/commonjs/Collection/Collection.jest' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/commonjs/Collection/Collection' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/commonjs/Collection/CollectionView' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/commonjs/Collection/index' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/commonjs/Collection/Section.jest' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/commonjs/Collection/Section' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/commonjs/Collection/SectionManager.jest' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/commonjs/Collection/SectionManager' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/commonjs/Collection/TestData' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/commonjs/Collection/types' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/commonjs/Collection/utils/calculateSizeAndPositionData.jest' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/commonjs/Collection/utils/calculateSizeAndPositionData' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/commonjs/ColumnSizer/ColumnSizer.jest' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/commonjs/ColumnSizer/ColumnSizer' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/commonjs/ColumnSizer/index' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/commonjs/Grid/accessibilityOverscanIndicesGetter.jest' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/commonjs/Grid/accessibilityOverscanIndicesGetter' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/commonjs/Grid/defaultCellRangeRenderer' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/commonjs/Grid/defaultOverscanIndicesGetter.jest' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/commonjs/Grid/defaultOverscanIndicesGetter' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/commonjs/Grid/Grid.jest' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/commonjs/Grid/Grid' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/commonjs/Grid/index' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/commonjs/Grid/types' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/commonjs/Grid/utils/calculateSizeAndPositionDataAndUpdateScrollOffset.jest' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/commonjs/Grid/utils/calculateSizeAndPositionDataAndUpdateScrollOffset' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/commonjs/Grid/utils/CellSizeAndPositionManager.jest' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/commonjs/Grid/utils/CellSizeAndPositionManager' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/commonjs/Grid/utils/ScalingCellSizeAndPositionManager.jest' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/commonjs/Grid/utils/ScalingCellSizeAndPositionManager' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/commonjs/Grid/utils/updateScrollIndexHelper.jest' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/commonjs/Grid/utils/updateScrollIndexHelper' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/commonjs/index' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/commonjs/InfiniteLoader/index' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/commonjs/InfiniteLoader/InfiniteLoader.jest' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/commonjs/InfiniteLoader/InfiniteLoader' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/commonjs/jest-setup' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/commonjs/List/index' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/commonjs/List/List.jest' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/commonjs/List/List' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/commonjs/List/types' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/commonjs/Masonry/createCellPositioner' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/commonjs/Masonry/index' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/commonjs/Masonry/Masonry.jest' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/commonjs/Masonry/Masonry' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/commonjs/Masonry/PositionCache' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/commonjs/MultiGrid/CellMeasurerCacheDecorator' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/commonjs/MultiGrid/index' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/commonjs/MultiGrid/MultiGrid.jest' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/commonjs/MultiGrid/MultiGrid' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/commonjs/ScrollSync/index' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/commonjs/ScrollSync/ScrollSync.jest' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/commonjs/ScrollSync/ScrollSync' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/commonjs/Table/Column.jest' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/commonjs/Table/Column' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/commonjs/Table/defaultCellDataGetter' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/commonjs/Table/defaultCellRenderer' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/commonjs/Table/defaultHeaderRenderer' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/commonjs/Table/defaultHeaderRowRenderer' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/commonjs/Table/defaultRowRenderer' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/commonjs/Table/index' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/commonjs/Table/SortDirection' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/commonjs/Table/SortIndicator' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/commonjs/Table/Table.jest' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/commonjs/Table/Table' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/commonjs/Table/types' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/commonjs/TestUtils' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/commonjs/utils/animationFrame' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/commonjs/utils/createCallbackMemoizer.jest' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/commonjs/utils/createCallbackMemoizer' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/commonjs/utils/getUpdatedOffsetForIndex.jest' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/commonjs/utils/getUpdatedOffsetForIndex' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/commonjs/utils/initCellMetadata' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/commonjs/utils/requestAnimationTimeout' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/commonjs/utils/TestHelper' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/commonjs/vendor/binarySearchBounds' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/commonjs/vendor/detectElementResize' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/commonjs/vendor/intervalTree' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/commonjs/WindowScroller/index' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/commonjs/WindowScroller/utils/dimensions' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/commonjs/WindowScroller/utils/onScroll' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/commonjs/WindowScroller/WindowScroller.jest' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/commonjs/WindowScroller/WindowScroller' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/es/ArrowKeyStepper/ArrowKeyStepper.jest' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/es/ArrowKeyStepper/ArrowKeyStepper' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/es/ArrowKeyStepper/index' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/es/ArrowKeyStepper/types' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/es/AutoSizer/AutoSizer.jest' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/es/AutoSizer/AutoSizer' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/es/AutoSizer/index' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/es/AutoSizer/types' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/es/CellMeasurer/CellMeasurer.jest' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/es/CellMeasurer/CellMeasurer' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/es/CellMeasurer/CellMeasurerCache.jest' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/es/CellMeasurer/CellMeasurerCache' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/es/CellMeasurer/index' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/es/Collection/Collection.jest' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/es/Collection/Collection' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/es/Collection/CollectionView' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/es/Collection/index' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/es/Collection/Section.jest' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/es/Collection/Section' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/es/Collection/SectionManager.jest' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/es/Collection/SectionManager' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/es/Collection/TestData' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/es/Collection/types' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/es/Collection/utils/calculateSizeAndPositionData.jest' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/es/Collection/utils/calculateSizeAndPositionData' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/es/ColumnSizer/ColumnSizer.jest' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/es/ColumnSizer/ColumnSizer' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/es/ColumnSizer/index' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/es/Grid/accessibilityOverscanIndicesGetter.jest' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/es/Grid/accessibilityOverscanIndicesGetter' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/es/Grid/defaultCellRangeRenderer' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/es/Grid/defaultOverscanIndicesGetter.jest' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/es/Grid/defaultOverscanIndicesGetter' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/es/Grid/Grid.jest' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/es/Grid/Grid' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/es/Grid/index' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/es/Grid/types' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/es/Grid/utils/calculateSizeAndPositionDataAndUpdateScrollOffset.jest' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/es/Grid/utils/calculateSizeAndPositionDataAndUpdateScrollOffset' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/es/Grid/utils/CellSizeAndPositionManager.jest' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/es/Grid/utils/CellSizeAndPositionManager' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/es/Grid/utils/ScalingCellSizeAndPositionManager.jest' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/es/Grid/utils/ScalingCellSizeAndPositionManager' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/es/Grid/utils/updateScrollIndexHelper.jest' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/es/Grid/utils/updateScrollIndexHelper' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/es/index' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/es/InfiniteLoader/index' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/es/InfiniteLoader/InfiniteLoader.jest' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/es/InfiniteLoader/InfiniteLoader' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/es/jest-setup' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/es/List/index' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/es/List/List.jest' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/es/List/List' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/es/List/types' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/es/Masonry/createCellPositioner' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/es/Masonry/index' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/es/Masonry/Masonry.jest' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/es/Masonry/Masonry' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/es/Masonry/PositionCache' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/es/MultiGrid/CellMeasurerCacheDecorator' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/es/MultiGrid/index' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/es/MultiGrid/MultiGrid.jest' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/es/MultiGrid/MultiGrid' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/es/ScrollSync/index' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/es/ScrollSync/ScrollSync.jest' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/es/ScrollSync/ScrollSync' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/es/Table/Column.jest' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/es/Table/Column' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/es/Table/defaultCellDataGetter' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/es/Table/defaultCellRenderer' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/es/Table/defaultHeaderRenderer' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/es/Table/defaultHeaderRowRenderer' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/es/Table/defaultRowRenderer' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/es/Table/index' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/es/Table/SortDirection' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/es/Table/SortIndicator' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/es/Table/Table.jest' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/es/Table/Table' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/es/Table/types' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/es/TestUtils' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/es/utils/animationFrame' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/es/utils/createCallbackMemoizer.jest' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/es/utils/createCallbackMemoizer' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/es/utils/getUpdatedOffsetForIndex.jest' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/es/utils/getUpdatedOffsetForIndex' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/es/utils/initCellMetadata' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/es/utils/requestAnimationTimeout' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/es/utils/TestHelper' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/es/vendor/binarySearchBounds' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/es/vendor/detectElementResize' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/es/vendor/intervalTree' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/es/WindowScroller/index' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/es/WindowScroller/utils/dimensions' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/es/WindowScroller/utils/onScroll' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/es/WindowScroller/WindowScroller.jest' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/es/WindowScroller/WindowScroller' { + declare module.exports: any; +} + +declare module 'react-virtualized/dist/umd/react-virtualized' { + declare module.exports: any; +} + +// Filename aliases +declare module 'react-virtualized/dist/commonjs/ArrowKeyStepper/ArrowKeyStepper.jest.js' { + declare module.exports: $Exports<'react-virtualized/dist/commonjs/ArrowKeyStepper/ArrowKeyStepper.jest'>; +} +declare module 'react-virtualized/dist/commonjs/ArrowKeyStepper/ArrowKeyStepper.js' { + declare module.exports: $Exports<'react-virtualized/dist/commonjs/ArrowKeyStepper/ArrowKeyStepper'>; +} +declare module 'react-virtualized/dist/commonjs/ArrowKeyStepper/index.js' { + declare module.exports: $Exports<'react-virtualized/dist/commonjs/ArrowKeyStepper/index'>; +} +declare module 'react-virtualized/dist/commonjs/ArrowKeyStepper/types.js' { + declare module.exports: $Exports<'react-virtualized/dist/commonjs/ArrowKeyStepper/types'>; +} +declare module 'react-virtualized/dist/commonjs/AutoSizer/AutoSizer.jest.js' { + declare module.exports: $Exports<'react-virtualized/dist/commonjs/AutoSizer/AutoSizer.jest'>; +} +declare module 'react-virtualized/dist/commonjs/AutoSizer/AutoSizer.js' { + declare module.exports: $Exports<'react-virtualized/dist/commonjs/AutoSizer/AutoSizer'>; +} +declare module 'react-virtualized/dist/commonjs/AutoSizer/index.js' { + declare module.exports: $Exports<'react-virtualized/dist/commonjs/AutoSizer/index'>; +} +declare module 'react-virtualized/dist/commonjs/AutoSizer/types.js' { + declare module.exports: $Exports<'react-virtualized/dist/commonjs/AutoSizer/types'>; +} +declare module 'react-virtualized/dist/commonjs/CellMeasurer/CellMeasurer.jest.js' { + declare module.exports: $Exports<'react-virtualized/dist/commonjs/CellMeasurer/CellMeasurer.jest'>; +} +declare module 'react-virtualized/dist/commonjs/CellMeasurer/CellMeasurer.js' { + declare module.exports: $Exports<'react-virtualized/dist/commonjs/CellMeasurer/CellMeasurer'>; +} +declare module 'react-virtualized/dist/commonjs/CellMeasurer/CellMeasurerCache.jest.js' { + declare module.exports: $Exports<'react-virtualized/dist/commonjs/CellMeasurer/CellMeasurerCache.jest'>; +} +declare module 'react-virtualized/dist/commonjs/CellMeasurer/CellMeasurerCache.js' { + declare module.exports: $Exports<'react-virtualized/dist/commonjs/CellMeasurer/CellMeasurerCache'>; +} +declare module 'react-virtualized/dist/commonjs/CellMeasurer/index.js' { + declare module.exports: $Exports<'react-virtualized/dist/commonjs/CellMeasurer/index'>; +} +declare module 'react-virtualized/dist/commonjs/Collection/Collection.jest.js' { + declare module.exports: $Exports<'react-virtualized/dist/commonjs/Collection/Collection.jest'>; +} +declare module 'react-virtualized/dist/commonjs/Collection/Collection.js' { + declare module.exports: $Exports<'react-virtualized/dist/commonjs/Collection/Collection'>; +} +declare module 'react-virtualized/dist/commonjs/Collection/CollectionView.js' { + declare module.exports: $Exports<'react-virtualized/dist/commonjs/Collection/CollectionView'>; +} +declare module 'react-virtualized/dist/commonjs/Collection/index.js' { + declare module.exports: $Exports<'react-virtualized/dist/commonjs/Collection/index'>; +} +declare module 'react-virtualized/dist/commonjs/Collection/Section.jest.js' { + declare module.exports: $Exports<'react-virtualized/dist/commonjs/Collection/Section.jest'>; +} +declare module 'react-virtualized/dist/commonjs/Collection/Section.js' { + declare module.exports: $Exports<'react-virtualized/dist/commonjs/Collection/Section'>; +} +declare module 'react-virtualized/dist/commonjs/Collection/SectionManager.jest.js' { + declare module.exports: $Exports<'react-virtualized/dist/commonjs/Collection/SectionManager.jest'>; +} +declare module 'react-virtualized/dist/commonjs/Collection/SectionManager.js' { + declare module.exports: $Exports<'react-virtualized/dist/commonjs/Collection/SectionManager'>; +} +declare module 'react-virtualized/dist/commonjs/Collection/TestData.js' { + declare module.exports: $Exports<'react-virtualized/dist/commonjs/Collection/TestData'>; +} +declare module 'react-virtualized/dist/commonjs/Collection/types.js' { + declare module.exports: $Exports<'react-virtualized/dist/commonjs/Collection/types'>; +} +declare module 'react-virtualized/dist/commonjs/Collection/utils/calculateSizeAndPositionData.jest.js' { + declare module.exports: $Exports<'react-virtualized/dist/commonjs/Collection/utils/calculateSizeAndPositionData.jest'>; +} +declare module 'react-virtualized/dist/commonjs/Collection/utils/calculateSizeAndPositionData.js' { + declare module.exports: $Exports<'react-virtualized/dist/commonjs/Collection/utils/calculateSizeAndPositionData'>; +} +declare module 'react-virtualized/dist/commonjs/ColumnSizer/ColumnSizer.jest.js' { + declare module.exports: $Exports<'react-virtualized/dist/commonjs/ColumnSizer/ColumnSizer.jest'>; +} +declare module 'react-virtualized/dist/commonjs/ColumnSizer/ColumnSizer.js' { + declare module.exports: $Exports<'react-virtualized/dist/commonjs/ColumnSizer/ColumnSizer'>; +} +declare module 'react-virtualized/dist/commonjs/ColumnSizer/index.js' { + declare module.exports: $Exports<'react-virtualized/dist/commonjs/ColumnSizer/index'>; +} +declare module 'react-virtualized/dist/commonjs/Grid/accessibilityOverscanIndicesGetter.jest.js' { + declare module.exports: $Exports<'react-virtualized/dist/commonjs/Grid/accessibilityOverscanIndicesGetter.jest'>; +} +declare module 'react-virtualized/dist/commonjs/Grid/accessibilityOverscanIndicesGetter.js' { + declare module.exports: $Exports<'react-virtualized/dist/commonjs/Grid/accessibilityOverscanIndicesGetter'>; +} +declare module 'react-virtualized/dist/commonjs/Grid/defaultCellRangeRenderer.js' { + declare module.exports: $Exports<'react-virtualized/dist/commonjs/Grid/defaultCellRangeRenderer'>; +} +declare module 'react-virtualized/dist/commonjs/Grid/defaultOverscanIndicesGetter.jest.js' { + declare module.exports: $Exports<'react-virtualized/dist/commonjs/Grid/defaultOverscanIndicesGetter.jest'>; +} +declare module 'react-virtualized/dist/commonjs/Grid/defaultOverscanIndicesGetter.js' { + declare module.exports: $Exports<'react-virtualized/dist/commonjs/Grid/defaultOverscanIndicesGetter'>; +} +declare module 'react-virtualized/dist/commonjs/Grid/Grid.jest.js' { + declare module.exports: $Exports<'react-virtualized/dist/commonjs/Grid/Grid.jest'>; +} +declare module 'react-virtualized/dist/commonjs/Grid/Grid.js' { + declare module.exports: $Exports<'react-virtualized/dist/commonjs/Grid/Grid'>; +} +declare module 'react-virtualized/dist/commonjs/Grid/index.js' { + declare module.exports: $Exports<'react-virtualized/dist/commonjs/Grid/index'>; +} +declare module 'react-virtualized/dist/commonjs/Grid/types.js' { + declare module.exports: $Exports<'react-virtualized/dist/commonjs/Grid/types'>; +} +declare module 'react-virtualized/dist/commonjs/Grid/utils/calculateSizeAndPositionDataAndUpdateScrollOffset.jest.js' { + declare module.exports: $Exports<'react-virtualized/dist/commonjs/Grid/utils/calculateSizeAndPositionDataAndUpdateScrollOffset.jest'>; +} +declare module 'react-virtualized/dist/commonjs/Grid/utils/calculateSizeAndPositionDataAndUpdateScrollOffset.js' { + declare module.exports: $Exports<'react-virtualized/dist/commonjs/Grid/utils/calculateSizeAndPositionDataAndUpdateScrollOffset'>; +} +declare module 'react-virtualized/dist/commonjs/Grid/utils/CellSizeAndPositionManager.jest.js' { + declare module.exports: $Exports<'react-virtualized/dist/commonjs/Grid/utils/CellSizeAndPositionManager.jest'>; +} +declare module 'react-virtualized/dist/commonjs/Grid/utils/CellSizeAndPositionManager.js' { + declare module.exports: $Exports<'react-virtualized/dist/commonjs/Grid/utils/CellSizeAndPositionManager'>; +} +declare module 'react-virtualized/dist/commonjs/Grid/utils/ScalingCellSizeAndPositionManager.jest.js' { + declare module.exports: $Exports<'react-virtualized/dist/commonjs/Grid/utils/ScalingCellSizeAndPositionManager.jest'>; +} +declare module 'react-virtualized/dist/commonjs/Grid/utils/ScalingCellSizeAndPositionManager.js' { + declare module.exports: $Exports<'react-virtualized/dist/commonjs/Grid/utils/ScalingCellSizeAndPositionManager'>; +} +declare module 'react-virtualized/dist/commonjs/Grid/utils/updateScrollIndexHelper.jest.js' { + declare module.exports: $Exports<'react-virtualized/dist/commonjs/Grid/utils/updateScrollIndexHelper.jest'>; +} +declare module 'react-virtualized/dist/commonjs/Grid/utils/updateScrollIndexHelper.js' { + declare module.exports: $Exports<'react-virtualized/dist/commonjs/Grid/utils/updateScrollIndexHelper'>; +} +declare module 'react-virtualized/dist/commonjs/index.js' { + declare module.exports: $Exports<'react-virtualized/dist/commonjs/index'>; +} +declare module 'react-virtualized/dist/commonjs/InfiniteLoader/index.js' { + declare module.exports: $Exports<'react-virtualized/dist/commonjs/InfiniteLoader/index'>; +} +declare module 'react-virtualized/dist/commonjs/InfiniteLoader/InfiniteLoader.jest.js' { + declare module.exports: $Exports<'react-virtualized/dist/commonjs/InfiniteLoader/InfiniteLoader.jest'>; +} +declare module 'react-virtualized/dist/commonjs/InfiniteLoader/InfiniteLoader.js' { + declare module.exports: $Exports<'react-virtualized/dist/commonjs/InfiniteLoader/InfiniteLoader'>; +} +declare module 'react-virtualized/dist/commonjs/jest-setup.js' { + declare module.exports: $Exports<'react-virtualized/dist/commonjs/jest-setup'>; +} +declare module 'react-virtualized/dist/commonjs/List/index.js' { + declare module.exports: $Exports<'react-virtualized/dist/commonjs/List/index'>; +} +declare module 'react-virtualized/dist/commonjs/List/List.jest.js' { + declare module.exports: $Exports<'react-virtualized/dist/commonjs/List/List.jest'>; +} +declare module 'react-virtualized/dist/commonjs/List/List.js' { + declare module.exports: $Exports<'react-virtualized/dist/commonjs/List/List'>; +} +declare module 'react-virtualized/dist/commonjs/List/types.js' { + declare module.exports: $Exports<'react-virtualized/dist/commonjs/List/types'>; +} +declare module 'react-virtualized/dist/commonjs/Masonry/createCellPositioner.js' { + declare module.exports: $Exports<'react-virtualized/dist/commonjs/Masonry/createCellPositioner'>; +} +declare module 'react-virtualized/dist/commonjs/Masonry/index.js' { + declare module.exports: $Exports<'react-virtualized/dist/commonjs/Masonry/index'>; +} +declare module 'react-virtualized/dist/commonjs/Masonry/Masonry.jest.js' { + declare module.exports: $Exports<'react-virtualized/dist/commonjs/Masonry/Masonry.jest'>; +} +declare module 'react-virtualized/dist/commonjs/Masonry/Masonry.js' { + declare module.exports: $Exports<'react-virtualized/dist/commonjs/Masonry/Masonry'>; +} +declare module 'react-virtualized/dist/commonjs/Masonry/PositionCache.js' { + declare module.exports: $Exports<'react-virtualized/dist/commonjs/Masonry/PositionCache'>; +} +declare module 'react-virtualized/dist/commonjs/MultiGrid/CellMeasurerCacheDecorator.js' { + declare module.exports: $Exports<'react-virtualized/dist/commonjs/MultiGrid/CellMeasurerCacheDecorator'>; +} +declare module 'react-virtualized/dist/commonjs/MultiGrid/index.js' { + declare module.exports: $Exports<'react-virtualized/dist/commonjs/MultiGrid/index'>; +} +declare module 'react-virtualized/dist/commonjs/MultiGrid/MultiGrid.jest.js' { + declare module.exports: $Exports<'react-virtualized/dist/commonjs/MultiGrid/MultiGrid.jest'>; +} +declare module 'react-virtualized/dist/commonjs/MultiGrid/MultiGrid.js' { + declare module.exports: $Exports<'react-virtualized/dist/commonjs/MultiGrid/MultiGrid'>; +} +declare module 'react-virtualized/dist/commonjs/ScrollSync/index.js' { + declare module.exports: $Exports<'react-virtualized/dist/commonjs/ScrollSync/index'>; +} +declare module 'react-virtualized/dist/commonjs/ScrollSync/ScrollSync.jest.js' { + declare module.exports: $Exports<'react-virtualized/dist/commonjs/ScrollSync/ScrollSync.jest'>; +} +declare module 'react-virtualized/dist/commonjs/ScrollSync/ScrollSync.js' { + declare module.exports: $Exports<'react-virtualized/dist/commonjs/ScrollSync/ScrollSync'>; +} +declare module 'react-virtualized/dist/commonjs/Table/Column.jest.js' { + declare module.exports: $Exports<'react-virtualized/dist/commonjs/Table/Column.jest'>; +} +declare module 'react-virtualized/dist/commonjs/Table/Column.js' { + declare module.exports: $Exports<'react-virtualized/dist/commonjs/Table/Column'>; +} +declare module 'react-virtualized/dist/commonjs/Table/defaultCellDataGetter.js' { + declare module.exports: $Exports<'react-virtualized/dist/commonjs/Table/defaultCellDataGetter'>; +} +declare module 'react-virtualized/dist/commonjs/Table/defaultCellRenderer.js' { + declare module.exports: $Exports<'react-virtualized/dist/commonjs/Table/defaultCellRenderer'>; +} +declare module 'react-virtualized/dist/commonjs/Table/defaultHeaderRenderer.js' { + declare module.exports: $Exports<'react-virtualized/dist/commonjs/Table/defaultHeaderRenderer'>; +} +declare module 'react-virtualized/dist/commonjs/Table/defaultHeaderRowRenderer.js' { + declare module.exports: $Exports<'react-virtualized/dist/commonjs/Table/defaultHeaderRowRenderer'>; +} +declare module 'react-virtualized/dist/commonjs/Table/defaultRowRenderer.js' { + declare module.exports: $Exports<'react-virtualized/dist/commonjs/Table/defaultRowRenderer'>; +} +declare module 'react-virtualized/dist/commonjs/Table/index.js' { + declare module.exports: $Exports<'react-virtualized/dist/commonjs/Table/index'>; +} +declare module 'react-virtualized/dist/commonjs/Table/SortDirection.js' { + declare module.exports: $Exports<'react-virtualized/dist/commonjs/Table/SortDirection'>; +} +declare module 'react-virtualized/dist/commonjs/Table/SortIndicator.js' { + declare module.exports: $Exports<'react-virtualized/dist/commonjs/Table/SortIndicator'>; +} +declare module 'react-virtualized/dist/commonjs/Table/Table.jest.js' { + declare module.exports: $Exports<'react-virtualized/dist/commonjs/Table/Table.jest'>; +} +declare module 'react-virtualized/dist/commonjs/Table/Table.js' { + declare module.exports: $Exports<'react-virtualized/dist/commonjs/Table/Table'>; +} +declare module 'react-virtualized/dist/commonjs/Table/types.js' { + declare module.exports: $Exports<'react-virtualized/dist/commonjs/Table/types'>; +} +declare module 'react-virtualized/dist/commonjs/TestUtils.js' { + declare module.exports: $Exports<'react-virtualized/dist/commonjs/TestUtils'>; +} +declare module 'react-virtualized/dist/commonjs/utils/animationFrame.js' { + declare module.exports: $Exports<'react-virtualized/dist/commonjs/utils/animationFrame'>; +} +declare module 'react-virtualized/dist/commonjs/utils/createCallbackMemoizer.jest.js' { + declare module.exports: $Exports<'react-virtualized/dist/commonjs/utils/createCallbackMemoizer.jest'>; +} +declare module 'react-virtualized/dist/commonjs/utils/createCallbackMemoizer.js' { + declare module.exports: $Exports<'react-virtualized/dist/commonjs/utils/createCallbackMemoizer'>; +} +declare module 'react-virtualized/dist/commonjs/utils/getUpdatedOffsetForIndex.jest.js' { + declare module.exports: $Exports<'react-virtualized/dist/commonjs/utils/getUpdatedOffsetForIndex.jest'>; +} +declare module 'react-virtualized/dist/commonjs/utils/getUpdatedOffsetForIndex.js' { + declare module.exports: $Exports<'react-virtualized/dist/commonjs/utils/getUpdatedOffsetForIndex'>; +} +declare module 'react-virtualized/dist/commonjs/utils/initCellMetadata.js' { + declare module.exports: $Exports<'react-virtualized/dist/commonjs/utils/initCellMetadata'>; +} +declare module 'react-virtualized/dist/commonjs/utils/requestAnimationTimeout.js' { + declare module.exports: $Exports<'react-virtualized/dist/commonjs/utils/requestAnimationTimeout'>; +} +declare module 'react-virtualized/dist/commonjs/utils/TestHelper.js' { + declare module.exports: $Exports<'react-virtualized/dist/commonjs/utils/TestHelper'>; +} +declare module 'react-virtualized/dist/commonjs/vendor/binarySearchBounds.js' { + declare module.exports: $Exports<'react-virtualized/dist/commonjs/vendor/binarySearchBounds'>; +} +declare module 'react-virtualized/dist/commonjs/vendor/detectElementResize.js' { + declare module.exports: $Exports<'react-virtualized/dist/commonjs/vendor/detectElementResize'>; +} +declare module 'react-virtualized/dist/commonjs/vendor/intervalTree.js' { + declare module.exports: $Exports<'react-virtualized/dist/commonjs/vendor/intervalTree'>; +} +declare module 'react-virtualized/dist/commonjs/WindowScroller/index.js' { + declare module.exports: $Exports<'react-virtualized/dist/commonjs/WindowScroller/index'>; +} +declare module 'react-virtualized/dist/commonjs/WindowScroller/utils/dimensions.js' { + declare module.exports: $Exports<'react-virtualized/dist/commonjs/WindowScroller/utils/dimensions'>; +} +declare module 'react-virtualized/dist/commonjs/WindowScroller/utils/onScroll.js' { + declare module.exports: $Exports<'react-virtualized/dist/commonjs/WindowScroller/utils/onScroll'>; +} +declare module 'react-virtualized/dist/commonjs/WindowScroller/WindowScroller.jest.js' { + declare module.exports: $Exports<'react-virtualized/dist/commonjs/WindowScroller/WindowScroller.jest'>; +} +declare module 'react-virtualized/dist/commonjs/WindowScroller/WindowScroller.js' { + declare module.exports: $Exports<'react-virtualized/dist/commonjs/WindowScroller/WindowScroller'>; +} +declare module 'react-virtualized/dist/es/ArrowKeyStepper/ArrowKeyStepper.jest.js' { + declare module.exports: $Exports<'react-virtualized/dist/es/ArrowKeyStepper/ArrowKeyStepper.jest'>; +} +declare module 'react-virtualized/dist/es/ArrowKeyStepper/ArrowKeyStepper.js' { + declare module.exports: $Exports<'react-virtualized/dist/es/ArrowKeyStepper/ArrowKeyStepper'>; +} +declare module 'react-virtualized/dist/es/ArrowKeyStepper/index.js' { + declare module.exports: $Exports<'react-virtualized/dist/es/ArrowKeyStepper/index'>; +} +declare module 'react-virtualized/dist/es/ArrowKeyStepper/types.js' { + declare module.exports: $Exports<'react-virtualized/dist/es/ArrowKeyStepper/types'>; +} +declare module 'react-virtualized/dist/es/AutoSizer/AutoSizer.jest.js' { + declare module.exports: $Exports<'react-virtualized/dist/es/AutoSizer/AutoSizer.jest'>; +} +declare module 'react-virtualized/dist/es/AutoSizer/AutoSizer.js' { + declare module.exports: $Exports<'react-virtualized/dist/es/AutoSizer/AutoSizer'>; +} +declare module 'react-virtualized/dist/es/AutoSizer/index.js' { + declare module.exports: $Exports<'react-virtualized/dist/es/AutoSizer/index'>; +} +declare module 'react-virtualized/dist/es/AutoSizer/types.js' { + declare module.exports: $Exports<'react-virtualized/dist/es/AutoSizer/types'>; +} +declare module 'react-virtualized/dist/es/CellMeasurer/CellMeasurer.jest.js' { + declare module.exports: $Exports<'react-virtualized/dist/es/CellMeasurer/CellMeasurer.jest'>; +} +declare module 'react-virtualized/dist/es/CellMeasurer/CellMeasurer.js' { + declare module.exports: $Exports<'react-virtualized/dist/es/CellMeasurer/CellMeasurer'>; +} +declare module 'react-virtualized/dist/es/CellMeasurer/CellMeasurerCache.jest.js' { + declare module.exports: $Exports<'react-virtualized/dist/es/CellMeasurer/CellMeasurerCache.jest'>; +} +declare module 'react-virtualized/dist/es/CellMeasurer/CellMeasurerCache.js' { + declare module.exports: $Exports<'react-virtualized/dist/es/CellMeasurer/CellMeasurerCache'>; +} +declare module 'react-virtualized/dist/es/CellMeasurer/index.js' { + declare module.exports: $Exports<'react-virtualized/dist/es/CellMeasurer/index'>; +} +declare module 'react-virtualized/dist/es/Collection/Collection.jest.js' { + declare module.exports: $Exports<'react-virtualized/dist/es/Collection/Collection.jest'>; +} +declare module 'react-virtualized/dist/es/Collection/Collection.js' { + declare module.exports: $Exports<'react-virtualized/dist/es/Collection/Collection'>; +} +declare module 'react-virtualized/dist/es/Collection/CollectionView.js' { + declare module.exports: $Exports<'react-virtualized/dist/es/Collection/CollectionView'>; +} +declare module 'react-virtualized/dist/es/Collection/index.js' { + declare module.exports: $Exports<'react-virtualized/dist/es/Collection/index'>; +} +declare module 'react-virtualized/dist/es/Collection/Section.jest.js' { + declare module.exports: $Exports<'react-virtualized/dist/es/Collection/Section.jest'>; +} +declare module 'react-virtualized/dist/es/Collection/Section.js' { + declare module.exports: $Exports<'react-virtualized/dist/es/Collection/Section'>; +} +declare module 'react-virtualized/dist/es/Collection/SectionManager.jest.js' { + declare module.exports: $Exports<'react-virtualized/dist/es/Collection/SectionManager.jest'>; +} +declare module 'react-virtualized/dist/es/Collection/SectionManager.js' { + declare module.exports: $Exports<'react-virtualized/dist/es/Collection/SectionManager'>; +} +declare module 'react-virtualized/dist/es/Collection/TestData.js' { + declare module.exports: $Exports<'react-virtualized/dist/es/Collection/TestData'>; +} +declare module 'react-virtualized/dist/es/Collection/types.js' { + declare module.exports: $Exports<'react-virtualized/dist/es/Collection/types'>; +} +declare module 'react-virtualized/dist/es/Collection/utils/calculateSizeAndPositionData.jest.js' { + declare module.exports: $Exports<'react-virtualized/dist/es/Collection/utils/calculateSizeAndPositionData.jest'>; +} +declare module 'react-virtualized/dist/es/Collection/utils/calculateSizeAndPositionData.js' { + declare module.exports: $Exports<'react-virtualized/dist/es/Collection/utils/calculateSizeAndPositionData'>; +} +declare module 'react-virtualized/dist/es/ColumnSizer/ColumnSizer.jest.js' { + declare module.exports: $Exports<'react-virtualized/dist/es/ColumnSizer/ColumnSizer.jest'>; +} +declare module 'react-virtualized/dist/es/ColumnSizer/ColumnSizer.js' { + declare module.exports: $Exports<'react-virtualized/dist/es/ColumnSizer/ColumnSizer'>; +} +declare module 'react-virtualized/dist/es/ColumnSizer/index.js' { + declare module.exports: $Exports<'react-virtualized/dist/es/ColumnSizer/index'>; +} +declare module 'react-virtualized/dist/es/Grid/accessibilityOverscanIndicesGetter.jest.js' { + declare module.exports: $Exports<'react-virtualized/dist/es/Grid/accessibilityOverscanIndicesGetter.jest'>; +} +declare module 'react-virtualized/dist/es/Grid/accessibilityOverscanIndicesGetter.js' { + declare module.exports: $Exports<'react-virtualized/dist/es/Grid/accessibilityOverscanIndicesGetter'>; +} +declare module 'react-virtualized/dist/es/Grid/defaultCellRangeRenderer.js' { + declare module.exports: $Exports<'react-virtualized/dist/es/Grid/defaultCellRangeRenderer'>; +} +declare module 'react-virtualized/dist/es/Grid/defaultOverscanIndicesGetter.jest.js' { + declare module.exports: $Exports<'react-virtualized/dist/es/Grid/defaultOverscanIndicesGetter.jest'>; +} +declare module 'react-virtualized/dist/es/Grid/defaultOverscanIndicesGetter.js' { + declare module.exports: $Exports<'react-virtualized/dist/es/Grid/defaultOverscanIndicesGetter'>; +} +declare module 'react-virtualized/dist/es/Grid/Grid.jest.js' { + declare module.exports: $Exports<'react-virtualized/dist/es/Grid/Grid.jest'>; +} +declare module 'react-virtualized/dist/es/Grid/Grid.js' { + declare module.exports: $Exports<'react-virtualized/dist/es/Grid/Grid'>; +} +declare module 'react-virtualized/dist/es/Grid/index.js' { + declare module.exports: $Exports<'react-virtualized/dist/es/Grid/index'>; +} +declare module 'react-virtualized/dist/es/Grid/types.js' { + declare module.exports: $Exports<'react-virtualized/dist/es/Grid/types'>; +} +declare module 'react-virtualized/dist/es/Grid/utils/calculateSizeAndPositionDataAndUpdateScrollOffset.jest.js' { + declare module.exports: $Exports<'react-virtualized/dist/es/Grid/utils/calculateSizeAndPositionDataAndUpdateScrollOffset.jest'>; +} +declare module 'react-virtualized/dist/es/Grid/utils/calculateSizeAndPositionDataAndUpdateScrollOffset.js' { + declare module.exports: $Exports<'react-virtualized/dist/es/Grid/utils/calculateSizeAndPositionDataAndUpdateScrollOffset'>; +} +declare module 'react-virtualized/dist/es/Grid/utils/CellSizeAndPositionManager.jest.js' { + declare module.exports: $Exports<'react-virtualized/dist/es/Grid/utils/CellSizeAndPositionManager.jest'>; +} +declare module 'react-virtualized/dist/es/Grid/utils/CellSizeAndPositionManager.js' { + declare module.exports: $Exports<'react-virtualized/dist/es/Grid/utils/CellSizeAndPositionManager'>; +} +declare module 'react-virtualized/dist/es/Grid/utils/ScalingCellSizeAndPositionManager.jest.js' { + declare module.exports: $Exports<'react-virtualized/dist/es/Grid/utils/ScalingCellSizeAndPositionManager.jest'>; +} +declare module 'react-virtualized/dist/es/Grid/utils/ScalingCellSizeAndPositionManager.js' { + declare module.exports: $Exports<'react-virtualized/dist/es/Grid/utils/ScalingCellSizeAndPositionManager'>; +} +declare module 'react-virtualized/dist/es/Grid/utils/updateScrollIndexHelper.jest.js' { + declare module.exports: $Exports<'react-virtualized/dist/es/Grid/utils/updateScrollIndexHelper.jest'>; +} +declare module 'react-virtualized/dist/es/Grid/utils/updateScrollIndexHelper.js' { + declare module.exports: $Exports<'react-virtualized/dist/es/Grid/utils/updateScrollIndexHelper'>; +} +declare module 'react-virtualized/dist/es/index.js' { + declare module.exports: $Exports<'react-virtualized/dist/es/index'>; +} +declare module 'react-virtualized/dist/es/InfiniteLoader/index.js' { + declare module.exports: $Exports<'react-virtualized/dist/es/InfiniteLoader/index'>; +} +declare module 'react-virtualized/dist/es/InfiniteLoader/InfiniteLoader.jest.js' { + declare module.exports: $Exports<'react-virtualized/dist/es/InfiniteLoader/InfiniteLoader.jest'>; +} +declare module 'react-virtualized/dist/es/InfiniteLoader/InfiniteLoader.js' { + declare module.exports: $Exports<'react-virtualized/dist/es/InfiniteLoader/InfiniteLoader'>; +} +declare module 'react-virtualized/dist/es/jest-setup.js' { + declare module.exports: $Exports<'react-virtualized/dist/es/jest-setup'>; +} +declare module 'react-virtualized/dist/es/List/index.js' { + declare module.exports: $Exports<'react-virtualized/dist/es/List/index'>; +} +declare module 'react-virtualized/dist/es/List/List.jest.js' { + declare module.exports: $Exports<'react-virtualized/dist/es/List/List.jest'>; +} +declare module 'react-virtualized/dist/es/List/List.js' { + declare module.exports: $Exports<'react-virtualized/dist/es/List/List'>; +} +declare module 'react-virtualized/dist/es/List/types.js' { + declare module.exports: $Exports<'react-virtualized/dist/es/List/types'>; +} +declare module 'react-virtualized/dist/es/Masonry/createCellPositioner.js' { + declare module.exports: $Exports<'react-virtualized/dist/es/Masonry/createCellPositioner'>; +} +declare module 'react-virtualized/dist/es/Masonry/index.js' { + declare module.exports: $Exports<'react-virtualized/dist/es/Masonry/index'>; +} +declare module 'react-virtualized/dist/es/Masonry/Masonry.jest.js' { + declare module.exports: $Exports<'react-virtualized/dist/es/Masonry/Masonry.jest'>; +} +declare module 'react-virtualized/dist/es/Masonry/Masonry.js' { + declare module.exports: $Exports<'react-virtualized/dist/es/Masonry/Masonry'>; +} +declare module 'react-virtualized/dist/es/Masonry/PositionCache.js' { + declare module.exports: $Exports<'react-virtualized/dist/es/Masonry/PositionCache'>; +} +declare module 'react-virtualized/dist/es/MultiGrid/CellMeasurerCacheDecorator.js' { + declare module.exports: $Exports<'react-virtualized/dist/es/MultiGrid/CellMeasurerCacheDecorator'>; +} +declare module 'react-virtualized/dist/es/MultiGrid/index.js' { + declare module.exports: $Exports<'react-virtualized/dist/es/MultiGrid/index'>; +} +declare module 'react-virtualized/dist/es/MultiGrid/MultiGrid.jest.js' { + declare module.exports: $Exports<'react-virtualized/dist/es/MultiGrid/MultiGrid.jest'>; +} +declare module 'react-virtualized/dist/es/MultiGrid/MultiGrid.js' { + declare module.exports: $Exports<'react-virtualized/dist/es/MultiGrid/MultiGrid'>; +} +declare module 'react-virtualized/dist/es/ScrollSync/index.js' { + declare module.exports: $Exports<'react-virtualized/dist/es/ScrollSync/index'>; +} +declare module 'react-virtualized/dist/es/ScrollSync/ScrollSync.jest.js' { + declare module.exports: $Exports<'react-virtualized/dist/es/ScrollSync/ScrollSync.jest'>; +} +declare module 'react-virtualized/dist/es/ScrollSync/ScrollSync.js' { + declare module.exports: $Exports<'react-virtualized/dist/es/ScrollSync/ScrollSync'>; +} +declare module 'react-virtualized/dist/es/Table/Column.jest.js' { + declare module.exports: $Exports<'react-virtualized/dist/es/Table/Column.jest'>; +} +declare module 'react-virtualized/dist/es/Table/Column.js' { + declare module.exports: $Exports<'react-virtualized/dist/es/Table/Column'>; +} +declare module 'react-virtualized/dist/es/Table/defaultCellDataGetter.js' { + declare module.exports: $Exports<'react-virtualized/dist/es/Table/defaultCellDataGetter'>; +} +declare module 'react-virtualized/dist/es/Table/defaultCellRenderer.js' { + declare module.exports: $Exports<'react-virtualized/dist/es/Table/defaultCellRenderer'>; +} +declare module 'react-virtualized/dist/es/Table/defaultHeaderRenderer.js' { + declare module.exports: $Exports<'react-virtualized/dist/es/Table/defaultHeaderRenderer'>; +} +declare module 'react-virtualized/dist/es/Table/defaultHeaderRowRenderer.js' { + declare module.exports: $Exports<'react-virtualized/dist/es/Table/defaultHeaderRowRenderer'>; +} +declare module 'react-virtualized/dist/es/Table/defaultRowRenderer.js' { + declare module.exports: $Exports<'react-virtualized/dist/es/Table/defaultRowRenderer'>; +} +declare module 'react-virtualized/dist/es/Table/index.js' { + declare module.exports: $Exports<'react-virtualized/dist/es/Table/index'>; +} +declare module 'react-virtualized/dist/es/Table/SortDirection.js' { + declare module.exports: $Exports<'react-virtualized/dist/es/Table/SortDirection'>; +} +declare module 'react-virtualized/dist/es/Table/SortIndicator.js' { + declare module.exports: $Exports<'react-virtualized/dist/es/Table/SortIndicator'>; +} +declare module 'react-virtualized/dist/es/Table/Table.jest.js' { + declare module.exports: $Exports<'react-virtualized/dist/es/Table/Table.jest'>; +} +declare module 'react-virtualized/dist/es/Table/Table.js' { + declare module.exports: $Exports<'react-virtualized/dist/es/Table/Table'>; +} +declare module 'react-virtualized/dist/es/Table/types.js' { + declare module.exports: $Exports<'react-virtualized/dist/es/Table/types'>; +} +declare module 'react-virtualized/dist/es/TestUtils.js' { + declare module.exports: $Exports<'react-virtualized/dist/es/TestUtils'>; +} +declare module 'react-virtualized/dist/es/utils/animationFrame.js' { + declare module.exports: $Exports<'react-virtualized/dist/es/utils/animationFrame'>; +} +declare module 'react-virtualized/dist/es/utils/createCallbackMemoizer.jest.js' { + declare module.exports: $Exports<'react-virtualized/dist/es/utils/createCallbackMemoizer.jest'>; +} +declare module 'react-virtualized/dist/es/utils/createCallbackMemoizer.js' { + declare module.exports: $Exports<'react-virtualized/dist/es/utils/createCallbackMemoizer'>; +} +declare module 'react-virtualized/dist/es/utils/getUpdatedOffsetForIndex.jest.js' { + declare module.exports: $Exports<'react-virtualized/dist/es/utils/getUpdatedOffsetForIndex.jest'>; +} +declare module 'react-virtualized/dist/es/utils/getUpdatedOffsetForIndex.js' { + declare module.exports: $Exports<'react-virtualized/dist/es/utils/getUpdatedOffsetForIndex'>; +} +declare module 'react-virtualized/dist/es/utils/initCellMetadata.js' { + declare module.exports: $Exports<'react-virtualized/dist/es/utils/initCellMetadata'>; +} +declare module 'react-virtualized/dist/es/utils/requestAnimationTimeout.js' { + declare module.exports: $Exports<'react-virtualized/dist/es/utils/requestAnimationTimeout'>; +} +declare module 'react-virtualized/dist/es/utils/TestHelper.js' { + declare module.exports: $Exports<'react-virtualized/dist/es/utils/TestHelper'>; +} +declare module 'react-virtualized/dist/es/vendor/binarySearchBounds.js' { + declare module.exports: $Exports<'react-virtualized/dist/es/vendor/binarySearchBounds'>; +} +declare module 'react-virtualized/dist/es/vendor/detectElementResize.js' { + declare module.exports: $Exports<'react-virtualized/dist/es/vendor/detectElementResize'>; +} +declare module 'react-virtualized/dist/es/vendor/intervalTree.js' { + declare module.exports: $Exports<'react-virtualized/dist/es/vendor/intervalTree'>; +} +declare module 'react-virtualized/dist/es/WindowScroller/index.js' { + declare module.exports: $Exports<'react-virtualized/dist/es/WindowScroller/index'>; +} +declare module 'react-virtualized/dist/es/WindowScroller/utils/dimensions.js' { + declare module.exports: $Exports<'react-virtualized/dist/es/WindowScroller/utils/dimensions'>; +} +declare module 'react-virtualized/dist/es/WindowScroller/utils/onScroll.js' { + declare module.exports: $Exports<'react-virtualized/dist/es/WindowScroller/utils/onScroll'>; +} +declare module 'react-virtualized/dist/es/WindowScroller/WindowScroller.jest.js' { + declare module.exports: $Exports<'react-virtualized/dist/es/WindowScroller/WindowScroller.jest'>; +} +declare module 'react-virtualized/dist/es/WindowScroller/WindowScroller.js' { + declare module.exports: $Exports<'react-virtualized/dist/es/WindowScroller/WindowScroller'>; +} +declare module 'react-virtualized/dist/umd/react-virtualized.js' { + declare module.exports: $Exports<'react-virtualized/dist/umd/react-virtualized'>; +} diff --git a/flow-typed/npm/redux_v3.x.x.js b/flow-typed/npm/redux_v3.x.x.js new file mode 100644 index 000000000..7bc662368 --- /dev/null +++ b/flow-typed/npm/redux_v3.x.x.js @@ -0,0 +1,59 @@ +// flow-typed signature: cca4916b0213065533df8335c3285a4a +// flow-typed version: cab04034e7/redux_v3.x.x/flow_>=v0.55.x + +declare module 'redux' { + + /* + + S = State + A = Action + D = Dispatch + + */ + + declare export type DispatchAPI = (action: A) => A; + declare export type Dispatch }> = DispatchAPI; + + declare export type MiddlewareAPI> = { + dispatch: D; + getState(): S; + }; + + declare export type Store> = { + // rewrite MiddlewareAPI members in order to get nicer error messages (intersections produce long messages) + dispatch: D; + getState(): S; + subscribe(listener: () => void): () => void; + replaceReducer(nextReducer: Reducer): void + }; + + declare export type Reducer = (state: S | void, action: A) => S; + + declare export type CombinedReducer = (state: $Shape & {} | void, action: A) => S; + + declare export type Middleware> = + (api: MiddlewareAPI) => + (next: D) => D; + + declare export type StoreCreator> = { + (reducer: Reducer, enhancer?: StoreEnhancer): Store; + (reducer: Reducer, preloadedState: S, enhancer?: StoreEnhancer): Store; + }; + + declare export type StoreEnhancer> = (next: StoreCreator) => StoreCreator; + + declare export function createStore(reducer: Reducer, enhancer?: StoreEnhancer): Store; + declare export function createStore(reducer: Reducer, preloadedState?: S, enhancer?: StoreEnhancer): Store; + + declare export function applyMiddleware(...middlewares: Array>): StoreEnhancer; + + declare export type ActionCreator = (...args: Array) => A; + declare export type ActionCreators = { [key: K]: ActionCreator }; + + declare export function bindActionCreators, D: DispatchAPI>(actionCreator: C, dispatch: D): C; + declare export function bindActionCreators, D: DispatchAPI>(actionCreators: C, dispatch: D): C; + + declare export function combineReducers(reducers: O): CombinedReducer<$ObjMap(r: Reducer) => S>, A>; + + declare export var compose: $Compose; +} diff --git a/flow-typed/npm/rsocket.js b/flow-typed/npm/rsocket.js new file mode 100644 index 000000000..89ded1656 --- /dev/null +++ b/flow-typed/npm/rsocket.js @@ -0,0 +1,8 @@ + +declare module 'rsocket-core' { + declare module.exports: $Exports<'rsocket-core'>; +} + +declare module 'rsocket-tcp-server' { + declare module.exports: $Exports<'rsocket-tcp-server'>; +} diff --git a/flow-typed/npm/string-natural-compare_vx.x.x.js b/flow-typed/npm/string-natural-compare_vx.x.x.js new file mode 100644 index 000000000..d0edbb271 --- /dev/null +++ b/flow-typed/npm/string-natural-compare_vx.x.x.js @@ -0,0 +1,32 @@ +// flow-typed signature: 843db49f208e061075c2c057f6db5c4d +// flow-typed version: <>/string-natural-compare_v^2.0.2/flow_v0.59.0 + +/** + * This is an autogenerated libdef stub for: + * + * 'string-natural-compare' + * + * Fill this stub out by replacing all the `any` types. + * + * Once filled out, we encourage you to share your work with the + * community by sending a pull request to: + * https://github.com/flowtype/flow-typed + */ + +declare module 'string-natural-compare' { + declare module.exports: any; +} + +/** + * We include stubs for each file inside this npm package in case you need to + * require those files directly. Feel free to delete any files that aren't + * needed. + */ +declare module 'string-natural-compare/natural-compare' { + declare module.exports: any; +} + +// Filename aliases +declare module 'string-natural-compare/natural-compare.js' { + declare module.exports: $Exports<'string-natural-compare/natural-compare'>; +} diff --git a/flow-typed/npm/vis_vx.x.x.js b/flow-typed/npm/vis_vx.x.x.js new file mode 100644 index 000000000..df2194a1e --- /dev/null +++ b/flow-typed/npm/vis_vx.x.x.js @@ -0,0 +1,1305 @@ +// flow-typed signature: ab12cb0bb6ca55414cab3e4d58ebf17e +// flow-typed version: <>/vis_v4.21.0/flow_v0.69.0 + +/** + * This is an autogenerated libdef stub for: + * + * 'vis' + * + * Fill this stub out by replacing all the `any` types. + * + * Once filled out, we encourage you to share your work with the + * community by sending a pull request to: + * https://github.com/flowtype/flow-typed + */ + +declare module 'vis' { + declare module.exports: any; +} + +/** + * We include stubs for each file inside this npm package in case you need to + * require those files directly. Feel free to delete any files that aren't + * needed. + */ +declare module 'vis/dist/vis-graph3d.min' { + declare module.exports: any; +} + +declare module 'vis/dist/vis-network.min' { + declare module.exports: any; +} + +declare module 'vis/dist/vis-timeline-graph2d.min' { + declare module.exports: any; +} + +declare module 'vis/dist/vis' { + declare module.exports: any; +} + +declare module 'vis/dist/vis.min' { + declare module.exports: any; +} + +declare module 'vis/docs/js/bootstrap' { + declare module.exports: any; +} + +declare module 'vis/docs/js/bootstrap.min' { + declare module.exports: any; +} + +declare module 'vis/docs/js/docs.min' { + declare module.exports: any; +} + +declare module 'vis/docs/js/googleAnalytics' { + declare module.exports: any; +} + +declare module 'vis/docs/js/ie-emulation-modes-warning' { + declare module.exports: any; +} + +declare module 'vis/docs/js/ie10-viewport-bug-workaround' { + declare module.exports: any; +} + +declare module 'vis/docs/js/jquery.highlight' { + declare module.exports: any; +} + +declare module 'vis/docs/js/jquery.min' { + declare module.exports: any; +} + +declare module 'vis/docs/js/jquery.url.min' { + declare module.exports: any; +} + +declare module 'vis/docs/js/main' { + declare module.exports: any; +} + +declare module 'vis/docs/js/prettify/lang-apollo' { + declare module.exports: any; +} + +declare module 'vis/docs/js/prettify/lang-css' { + declare module.exports: any; +} + +declare module 'vis/docs/js/prettify/lang-hs' { + declare module.exports: any; +} + +declare module 'vis/docs/js/prettify/lang-lisp' { + declare module.exports: any; +} + +declare module 'vis/docs/js/prettify/lang-lua' { + declare module.exports: any; +} + +declare module 'vis/docs/js/prettify/lang-ml' { + declare module.exports: any; +} + +declare module 'vis/docs/js/prettify/lang-proto' { + declare module.exports: any; +} + +declare module 'vis/docs/js/prettify/lang-scala' { + declare module.exports: any; +} + +declare module 'vis/docs/js/prettify/lang-sql' { + declare module.exports: any; +} + +declare module 'vis/docs/js/prettify/lang-vb' { + declare module.exports: any; +} + +declare module 'vis/docs/js/prettify/lang-vhdl' { + declare module.exports: any; +} + +declare module 'vis/docs/js/prettify/lang-wiki' { + declare module.exports: any; +} + +declare module 'vis/docs/js/prettify/lang-yaml' { + declare module.exports: any; +} + +declare module 'vis/docs/js/prettify/prettify' { + declare module.exports: any; +} + +declare module 'vis/docs/js/smooth-scroll.min' { + declare module.exports: any; +} + +declare module 'vis/docs/js/tipuesearch.config' { + declare module.exports: any; +} + +declare module 'vis/docs/js/tipuesearch' { + declare module.exports: any; +} + +declare module 'vis/docs/js/tipuesearch.min' { + declare module.exports: any; +} + +declare module 'vis/docs/js/toggleTable' { + declare module.exports: any; +} + +declare module 'vis/examples/graph3d/playground/csv2array' { + declare module.exports: any; +} + +declare module 'vis/examples/graph3d/playground/playground' { + declare module.exports: any; +} + +declare module 'vis/examples/graph3d/playground/prettify/lang-apollo' { + declare module.exports: any; +} + +declare module 'vis/examples/graph3d/playground/prettify/lang-css' { + declare module.exports: any; +} + +declare module 'vis/examples/graph3d/playground/prettify/lang-hs' { + declare module.exports: any; +} + +declare module 'vis/examples/graph3d/playground/prettify/lang-lisp' { + declare module.exports: any; +} + +declare module 'vis/examples/graph3d/playground/prettify/lang-lua' { + declare module.exports: any; +} + +declare module 'vis/examples/graph3d/playground/prettify/lang-ml' { + declare module.exports: any; +} + +declare module 'vis/examples/graph3d/playground/prettify/lang-proto' { + declare module.exports: any; +} + +declare module 'vis/examples/graph3d/playground/prettify/lang-scala' { + declare module.exports: any; +} + +declare module 'vis/examples/graph3d/playground/prettify/lang-sql' { + declare module.exports: any; +} + +declare module 'vis/examples/graph3d/playground/prettify/lang-vb' { + declare module.exports: any; +} + +declare module 'vis/examples/graph3d/playground/prettify/lang-vhdl' { + declare module.exports: any; +} + +declare module 'vis/examples/graph3d/playground/prettify/lang-wiki' { + declare module.exports: any; +} + +declare module 'vis/examples/graph3d/playground/prettify/lang-yaml' { + declare module.exports: any; +} + +declare module 'vis/examples/graph3d/playground/prettify/prettify' { + declare module.exports: any; +} + +declare module 'vis/examples/network/datasources/largeHierarchicalDataset' { + declare module.exports: any; +} + +declare module 'vis/examples/network/datasources/WorldCup2014' { + declare module.exports: any; +} + +declare module 'vis/examples/network/exampleApplications/disassemblerExample' { + declare module.exports: any; +} + +declare module 'vis/examples/network/exampleUtil' { + declare module.exports: any; +} + +declare module 'vis/examples/timeline/other/requirejs/scripts/main' { + declare module.exports: any; +} + +declare module 'vis/examples/timeline/other/requirejs/scripts/require' { + declare module.exports: any; +} + +declare module 'vis/gulpfile' { + declare module.exports: any; +} + +declare module 'vis/index-graph3d' { + declare module.exports: any; +} + +declare module 'vis/index-network' { + declare module.exports: any; +} + +declare module 'vis/index-timeline-graph2d' { + declare module.exports: any; +} + +declare module 'vis/lib/DataSet' { + declare module.exports: any; +} + +declare module 'vis/lib/DataView' { + declare module.exports: any; +} + +declare module 'vis/lib/DOMutil' { + declare module.exports: any; +} + +declare module 'vis/lib/graph3d/Camera' { + declare module.exports: any; +} + +declare module 'vis/lib/graph3d/DataGroup' { + declare module.exports: any; +} + +declare module 'vis/lib/graph3d/Filter' { + declare module.exports: any; +} + +declare module 'vis/lib/graph3d/Graph3d' { + declare module.exports: any; +} + +declare module 'vis/lib/graph3d/options' { + declare module.exports: any; +} + +declare module 'vis/lib/graph3d/Point2d' { + declare module.exports: any; +} + +declare module 'vis/lib/graph3d/Point3d' { + declare module.exports: any; +} + +declare module 'vis/lib/graph3d/Range' { + declare module.exports: any; +} + +declare module 'vis/lib/graph3d/Settings' { + declare module.exports: any; +} + +declare module 'vis/lib/graph3d/Slider' { + declare module.exports: any; +} + +declare module 'vis/lib/graph3d/StepNumber' { + declare module.exports: any; +} + +declare module 'vis/lib/hammerUtil' { + declare module.exports: any; +} + +declare module 'vis/lib/header' { + declare module.exports: any; +} + +declare module 'vis/lib/module/hammer' { + declare module.exports: any; +} + +declare module 'vis/lib/module/moment' { + declare module.exports: any; +} + +declare module 'vis/lib/module/uuid' { + declare module.exports: any; +} + +declare module 'vis/lib/network/CachedImage' { + declare module.exports: any; +} + +declare module 'vis/lib/network/dotparser' { + declare module.exports: any; +} + +declare module 'vis/lib/network/gephiParser' { + declare module.exports: any; +} + +declare module 'vis/lib/network/Images' { + declare module.exports: any; +} + +declare module 'vis/lib/network/locales' { + declare module.exports: any; +} + +declare module 'vis/lib/network/modules/Canvas' { + declare module.exports: any; +} + +declare module 'vis/lib/network/modules/CanvasRenderer' { + declare module.exports: any; +} + +declare module 'vis/lib/network/modules/Clustering' { + declare module.exports: any; +} + +declare module 'vis/lib/network/modules/components/algorithms/FloydWarshall' { + declare module.exports: any; +} + +declare module 'vis/lib/network/modules/components/DirectionStrategy' { + declare module.exports: any; +} + +declare module 'vis/lib/network/modules/components/Edge' { + declare module.exports: any; +} + +declare module 'vis/lib/network/modules/components/edges/BezierEdgeDynamic' { + declare module.exports: any; +} + +declare module 'vis/lib/network/modules/components/edges/BezierEdgeStatic' { + declare module.exports: any; +} + +declare module 'vis/lib/network/modules/components/edges/CubicBezierEdge' { + declare module.exports: any; +} + +declare module 'vis/lib/network/modules/components/edges/StraightEdge' { + declare module.exports: any; +} + +declare module 'vis/lib/network/modules/components/edges/util/BezierEdgeBase' { + declare module.exports: any; +} + +declare module 'vis/lib/network/modules/components/edges/util/CubicBezierEdgeBase' { + declare module.exports: any; +} + +declare module 'vis/lib/network/modules/components/edges/util/EdgeBase' { + declare module.exports: any; +} + +declare module 'vis/lib/network/modules/components/edges/util/EndPoints' { + declare module.exports: any; +} + +declare module 'vis/lib/network/modules/components/NavigationHandler' { + declare module.exports: any; +} + +declare module 'vis/lib/network/modules/components/Node' { + declare module.exports: any; +} + +declare module 'vis/lib/network/modules/components/nodes/Cluster' { + declare module.exports: any; +} + +declare module 'vis/lib/network/modules/components/nodes/shapes/Box' { + declare module.exports: any; +} + +declare module 'vis/lib/network/modules/components/nodes/shapes/Circle' { + declare module.exports: any; +} + +declare module 'vis/lib/network/modules/components/nodes/shapes/CircularImage' { + declare module.exports: any; +} + +declare module 'vis/lib/network/modules/components/nodes/shapes/Database' { + declare module.exports: any; +} + +declare module 'vis/lib/network/modules/components/nodes/shapes/Diamond' { + declare module.exports: any; +} + +declare module 'vis/lib/network/modules/components/nodes/shapes/Dot' { + declare module.exports: any; +} + +declare module 'vis/lib/network/modules/components/nodes/shapes/Ellipse' { + declare module.exports: any; +} + +declare module 'vis/lib/network/modules/components/nodes/shapes/Hexagon' { + declare module.exports: any; +} + +declare module 'vis/lib/network/modules/components/nodes/shapes/Icon' { + declare module.exports: any; +} + +declare module 'vis/lib/network/modules/components/nodes/shapes/Image' { + declare module.exports: any; +} + +declare module 'vis/lib/network/modules/components/nodes/shapes/Square' { + declare module.exports: any; +} + +declare module 'vis/lib/network/modules/components/nodes/shapes/Star' { + declare module.exports: any; +} + +declare module 'vis/lib/network/modules/components/nodes/shapes/Text' { + declare module.exports: any; +} + +declare module 'vis/lib/network/modules/components/nodes/shapes/Triangle' { + declare module.exports: any; +} + +declare module 'vis/lib/network/modules/components/nodes/shapes/TriangleDown' { + declare module.exports: any; +} + +declare module 'vis/lib/network/modules/components/nodes/util/CircleImageBase' { + declare module.exports: any; +} + +declare module 'vis/lib/network/modules/components/nodes/util/NodeBase' { + declare module.exports: any; +} + +declare module 'vis/lib/network/modules/components/nodes/util/ShapeBase' { + declare module.exports: any; +} + +declare module 'vis/lib/network/modules/components/physics/BarnesHutSolver' { + declare module.exports: any; +} + +declare module 'vis/lib/network/modules/components/physics/CentralGravitySolver' { + declare module.exports: any; +} + +declare module 'vis/lib/network/modules/components/physics/FA2BasedCentralGravitySolver' { + declare module.exports: any; +} + +declare module 'vis/lib/network/modules/components/physics/FA2BasedRepulsionSolver' { + declare module.exports: any; +} + +declare module 'vis/lib/network/modules/components/physics/HierarchicalRepulsionSolver' { + declare module.exports: any; +} + +declare module 'vis/lib/network/modules/components/physics/HierarchicalSpringSolver' { + declare module.exports: any; +} + +declare module 'vis/lib/network/modules/components/physics/RepulsionSolver' { + declare module.exports: any; +} + +declare module 'vis/lib/network/modules/components/physics/SpringSolver' { + declare module.exports: any; +} + +declare module 'vis/lib/network/modules/components/shared/ComponentUtil' { + declare module.exports: any; +} + +declare module 'vis/lib/network/modules/components/shared/Label' { + declare module.exports: any; +} + +declare module 'vis/lib/network/modules/components/shared/LabelAccumulator' { + declare module.exports: any; +} + +declare module 'vis/lib/network/modules/components/shared/LabelSplitter' { + declare module.exports: any; +} + +declare module 'vis/lib/network/modules/EdgesHandler' { + declare module.exports: any; +} + +declare module 'vis/lib/network/modules/Groups' { + declare module.exports: any; +} + +declare module 'vis/lib/network/modules/InteractionHandler' { + declare module.exports: any; +} + +declare module 'vis/lib/network/modules/KamadaKawai' { + declare module.exports: any; +} + +declare module 'vis/lib/network/modules/LayoutEngine' { + declare module.exports: any; +} + +declare module 'vis/lib/network/modules/ManipulationSystem' { + declare module.exports: any; +} + +declare module 'vis/lib/network/modules/NodesHandler' { + declare module.exports: any; +} + +declare module 'vis/lib/network/modules/PhysicsEngine' { + declare module.exports: any; +} + +declare module 'vis/lib/network/modules/SelectionHandler' { + declare module.exports: any; +} + +declare module 'vis/lib/network/modules/View' { + declare module.exports: any; +} + +declare module 'vis/lib/network/Network' { + declare module.exports: any; +} + +declare module 'vis/lib/network/NetworkUtil' { + declare module.exports: any; +} + +declare module 'vis/lib/network/options' { + declare module.exports: any; +} + +declare module 'vis/lib/network/shapes' { + declare module.exports: any; +} + +declare module 'vis/lib/Queue' { + declare module.exports: any; +} + +declare module 'vis/lib/shared/Activator' { + declare module.exports: any; +} + +declare module 'vis/lib/shared/ColorPicker' { + declare module.exports: any; +} + +declare module 'vis/lib/shared/Configurator' { + declare module.exports: any; +} + +declare module 'vis/lib/shared/Popup' { + declare module.exports: any; +} + +declare module 'vis/lib/shared/Validator' { + declare module.exports: any; +} + +declare module 'vis/lib/timeline/component/BackgroundGroup' { + declare module.exports: any; +} + +declare module 'vis/lib/timeline/component/Component' { + declare module.exports: any; +} + +declare module 'vis/lib/timeline/component/CurrentTime' { + declare module.exports: any; +} + +declare module 'vis/lib/timeline/component/CustomTime' { + declare module.exports: any; +} + +declare module 'vis/lib/timeline/component/DataAxis' { + declare module.exports: any; +} + +declare module 'vis/lib/timeline/component/DataScale' { + declare module.exports: any; +} + +declare module 'vis/lib/timeline/component/graph2d_types/bar' { + declare module.exports: any; +} + +declare module 'vis/lib/timeline/component/graph2d_types/line' { + declare module.exports: any; +} + +declare module 'vis/lib/timeline/component/graph2d_types/points' { + declare module.exports: any; +} + +declare module 'vis/lib/timeline/component/GraphGroup' { + declare module.exports: any; +} + +declare module 'vis/lib/timeline/component/Group' { + declare module.exports: any; +} + +declare module 'vis/lib/timeline/component/item/BackgroundItem' { + declare module.exports: any; +} + +declare module 'vis/lib/timeline/component/item/BoxItem' { + declare module.exports: any; +} + +declare module 'vis/lib/timeline/component/item/Item' { + declare module.exports: any; +} + +declare module 'vis/lib/timeline/component/item/PointItem' { + declare module.exports: any; +} + +declare module 'vis/lib/timeline/component/item/RangeItem' { + declare module.exports: any; +} + +declare module 'vis/lib/timeline/component/ItemSet' { + declare module.exports: any; +} + +declare module 'vis/lib/timeline/component/Legend' { + declare module.exports: any; +} + +declare module 'vis/lib/timeline/component/LineGraph' { + declare module.exports: any; +} + +declare module 'vis/lib/timeline/component/TimeAxis' { + declare module.exports: any; +} + +declare module 'vis/lib/timeline/Core' { + declare module.exports: any; +} + +declare module 'vis/lib/timeline/DateUtil' { + declare module.exports: any; +} + +declare module 'vis/lib/timeline/Graph2d' { + declare module.exports: any; +} + +declare module 'vis/lib/timeline/locales' { + declare module.exports: any; +} + +declare module 'vis/lib/timeline/optionsGraph2d' { + declare module.exports: any; +} + +declare module 'vis/lib/timeline/optionsTimeline' { + declare module.exports: any; +} + +declare module 'vis/lib/timeline/Range' { + declare module.exports: any; +} + +declare module 'vis/lib/timeline/Stack' { + declare module.exports: any; +} + +declare module 'vis/lib/timeline/Timeline' { + declare module.exports: any; +} + +declare module 'vis/lib/timeline/TimeStep' { + declare module.exports: any; +} + +declare module 'vis/lib/util' { + declare module.exports: any; +} + +// Filename aliases +declare module 'vis/dist/vis-graph3d.min.js' { + declare module.exports: $Exports<'vis/dist/vis-graph3d.min'>; +} +declare module 'vis/dist/vis-network.min.js' { + declare module.exports: $Exports<'vis/dist/vis-network.min'>; +} +declare module 'vis/dist/vis-timeline-graph2d.min.js' { + declare module.exports: $Exports<'vis/dist/vis-timeline-graph2d.min'>; +} +declare module 'vis/dist/vis.js' { + declare module.exports: $Exports<'vis/dist/vis'>; +} +declare module 'vis/dist/vis.min.js' { + declare module.exports: $Exports<'vis/dist/vis.min'>; +} +declare module 'vis/docs/js/bootstrap.js' { + declare module.exports: $Exports<'vis/docs/js/bootstrap'>; +} +declare module 'vis/docs/js/bootstrap.min.js' { + declare module.exports: $Exports<'vis/docs/js/bootstrap.min'>; +} +declare module 'vis/docs/js/docs.min.js' { + declare module.exports: $Exports<'vis/docs/js/docs.min'>; +} +declare module 'vis/docs/js/googleAnalytics.js' { + declare module.exports: $Exports<'vis/docs/js/googleAnalytics'>; +} +declare module 'vis/docs/js/ie-emulation-modes-warning.js' { + declare module.exports: $Exports<'vis/docs/js/ie-emulation-modes-warning'>; +} +declare module 'vis/docs/js/ie10-viewport-bug-workaround.js' { + declare module.exports: $Exports<'vis/docs/js/ie10-viewport-bug-workaround'>; +} +declare module 'vis/docs/js/jquery.highlight.js' { + declare module.exports: $Exports<'vis/docs/js/jquery.highlight'>; +} +declare module 'vis/docs/js/jquery.min.js' { + declare module.exports: $Exports<'vis/docs/js/jquery.min'>; +} +declare module 'vis/docs/js/jquery.url.min.js' { + declare module.exports: $Exports<'vis/docs/js/jquery.url.min'>; +} +declare module 'vis/docs/js/main.js' { + declare module.exports: $Exports<'vis/docs/js/main'>; +} +declare module 'vis/docs/js/prettify/lang-apollo.js' { + declare module.exports: $Exports<'vis/docs/js/prettify/lang-apollo'>; +} +declare module 'vis/docs/js/prettify/lang-css.js' { + declare module.exports: $Exports<'vis/docs/js/prettify/lang-css'>; +} +declare module 'vis/docs/js/prettify/lang-hs.js' { + declare module.exports: $Exports<'vis/docs/js/prettify/lang-hs'>; +} +declare module 'vis/docs/js/prettify/lang-lisp.js' { + declare module.exports: $Exports<'vis/docs/js/prettify/lang-lisp'>; +} +declare module 'vis/docs/js/prettify/lang-lua.js' { + declare module.exports: $Exports<'vis/docs/js/prettify/lang-lua'>; +} +declare module 'vis/docs/js/prettify/lang-ml.js' { + declare module.exports: $Exports<'vis/docs/js/prettify/lang-ml'>; +} +declare module 'vis/docs/js/prettify/lang-proto.js' { + declare module.exports: $Exports<'vis/docs/js/prettify/lang-proto'>; +} +declare module 'vis/docs/js/prettify/lang-scala.js' { + declare module.exports: $Exports<'vis/docs/js/prettify/lang-scala'>; +} +declare module 'vis/docs/js/prettify/lang-sql.js' { + declare module.exports: $Exports<'vis/docs/js/prettify/lang-sql'>; +} +declare module 'vis/docs/js/prettify/lang-vb.js' { + declare module.exports: $Exports<'vis/docs/js/prettify/lang-vb'>; +} +declare module 'vis/docs/js/prettify/lang-vhdl.js' { + declare module.exports: $Exports<'vis/docs/js/prettify/lang-vhdl'>; +} +declare module 'vis/docs/js/prettify/lang-wiki.js' { + declare module.exports: $Exports<'vis/docs/js/prettify/lang-wiki'>; +} +declare module 'vis/docs/js/prettify/lang-yaml.js' { + declare module.exports: $Exports<'vis/docs/js/prettify/lang-yaml'>; +} +declare module 'vis/docs/js/prettify/prettify.js' { + declare module.exports: $Exports<'vis/docs/js/prettify/prettify'>; +} +declare module 'vis/docs/js/smooth-scroll.min.js' { + declare module.exports: $Exports<'vis/docs/js/smooth-scroll.min'>; +} +declare module 'vis/docs/js/tipuesearch.config.js' { + declare module.exports: $Exports<'vis/docs/js/tipuesearch.config'>; +} +declare module 'vis/docs/js/tipuesearch.js' { + declare module.exports: $Exports<'vis/docs/js/tipuesearch'>; +} +declare module 'vis/docs/js/tipuesearch.min.js' { + declare module.exports: $Exports<'vis/docs/js/tipuesearch.min'>; +} +declare module 'vis/docs/js/toggleTable.js' { + declare module.exports: $Exports<'vis/docs/js/toggleTable'>; +} +declare module 'vis/examples/graph3d/playground/csv2array.js' { + declare module.exports: $Exports<'vis/examples/graph3d/playground/csv2array'>; +} +declare module 'vis/examples/graph3d/playground/playground.js' { + declare module.exports: $Exports<'vis/examples/graph3d/playground/playground'>; +} +declare module 'vis/examples/graph3d/playground/prettify/lang-apollo.js' { + declare module.exports: $Exports<'vis/examples/graph3d/playground/prettify/lang-apollo'>; +} +declare module 'vis/examples/graph3d/playground/prettify/lang-css.js' { + declare module.exports: $Exports<'vis/examples/graph3d/playground/prettify/lang-css'>; +} +declare module 'vis/examples/graph3d/playground/prettify/lang-hs.js' { + declare module.exports: $Exports<'vis/examples/graph3d/playground/prettify/lang-hs'>; +} +declare module 'vis/examples/graph3d/playground/prettify/lang-lisp.js' { + declare module.exports: $Exports<'vis/examples/graph3d/playground/prettify/lang-lisp'>; +} +declare module 'vis/examples/graph3d/playground/prettify/lang-lua.js' { + declare module.exports: $Exports<'vis/examples/graph3d/playground/prettify/lang-lua'>; +} +declare module 'vis/examples/graph3d/playground/prettify/lang-ml.js' { + declare module.exports: $Exports<'vis/examples/graph3d/playground/prettify/lang-ml'>; +} +declare module 'vis/examples/graph3d/playground/prettify/lang-proto.js' { + declare module.exports: $Exports<'vis/examples/graph3d/playground/prettify/lang-proto'>; +} +declare module 'vis/examples/graph3d/playground/prettify/lang-scala.js' { + declare module.exports: $Exports<'vis/examples/graph3d/playground/prettify/lang-scala'>; +} +declare module 'vis/examples/graph3d/playground/prettify/lang-sql.js' { + declare module.exports: $Exports<'vis/examples/graph3d/playground/prettify/lang-sql'>; +} +declare module 'vis/examples/graph3d/playground/prettify/lang-vb.js' { + declare module.exports: $Exports<'vis/examples/graph3d/playground/prettify/lang-vb'>; +} +declare module 'vis/examples/graph3d/playground/prettify/lang-vhdl.js' { + declare module.exports: $Exports<'vis/examples/graph3d/playground/prettify/lang-vhdl'>; +} +declare module 'vis/examples/graph3d/playground/prettify/lang-wiki.js' { + declare module.exports: $Exports<'vis/examples/graph3d/playground/prettify/lang-wiki'>; +} +declare module 'vis/examples/graph3d/playground/prettify/lang-yaml.js' { + declare module.exports: $Exports<'vis/examples/graph3d/playground/prettify/lang-yaml'>; +} +declare module 'vis/examples/graph3d/playground/prettify/prettify.js' { + declare module.exports: $Exports<'vis/examples/graph3d/playground/prettify/prettify'>; +} +declare module 'vis/examples/network/datasources/largeHierarchicalDataset.js' { + declare module.exports: $Exports<'vis/examples/network/datasources/largeHierarchicalDataset'>; +} +declare module 'vis/examples/network/datasources/WorldCup2014.js' { + declare module.exports: $Exports<'vis/examples/network/datasources/WorldCup2014'>; +} +declare module 'vis/examples/network/exampleApplications/disassemblerExample.js' { + declare module.exports: $Exports<'vis/examples/network/exampleApplications/disassemblerExample'>; +} +declare module 'vis/examples/network/exampleUtil.js' { + declare module.exports: $Exports<'vis/examples/network/exampleUtil'>; +} +declare module 'vis/examples/timeline/other/requirejs/scripts/main.js' { + declare module.exports: $Exports<'vis/examples/timeline/other/requirejs/scripts/main'>; +} +declare module 'vis/examples/timeline/other/requirejs/scripts/require.js' { + declare module.exports: $Exports<'vis/examples/timeline/other/requirejs/scripts/require'>; +} +declare module 'vis/gulpfile.js' { + declare module.exports: $Exports<'vis/gulpfile'>; +} +declare module 'vis/index-graph3d.js' { + declare module.exports: $Exports<'vis/index-graph3d'>; +} +declare module 'vis/index-network.js' { + declare module.exports: $Exports<'vis/index-network'>; +} +declare module 'vis/index-timeline-graph2d.js' { + declare module.exports: $Exports<'vis/index-timeline-graph2d'>; +} +declare module 'vis/index' { + declare module.exports: $Exports<'vis'>; +} +declare module 'vis/index.js' { + declare module.exports: $Exports<'vis'>; +} +declare module 'vis/lib/DataSet.js' { + declare module.exports: $Exports<'vis/lib/DataSet'>; +} +declare module 'vis/lib/DataView.js' { + declare module.exports: $Exports<'vis/lib/DataView'>; +} +declare module 'vis/lib/DOMutil.js' { + declare module.exports: $Exports<'vis/lib/DOMutil'>; +} +declare module 'vis/lib/graph3d/Camera.js' { + declare module.exports: $Exports<'vis/lib/graph3d/Camera'>; +} +declare module 'vis/lib/graph3d/DataGroup.js' { + declare module.exports: $Exports<'vis/lib/graph3d/DataGroup'>; +} +declare module 'vis/lib/graph3d/Filter.js' { + declare module.exports: $Exports<'vis/lib/graph3d/Filter'>; +} +declare module 'vis/lib/graph3d/Graph3d.js' { + declare module.exports: $Exports<'vis/lib/graph3d/Graph3d'>; +} +declare module 'vis/lib/graph3d/options.js' { + declare module.exports: $Exports<'vis/lib/graph3d/options'>; +} +declare module 'vis/lib/graph3d/Point2d.js' { + declare module.exports: $Exports<'vis/lib/graph3d/Point2d'>; +} +declare module 'vis/lib/graph3d/Point3d.js' { + declare module.exports: $Exports<'vis/lib/graph3d/Point3d'>; +} +declare module 'vis/lib/graph3d/Range.js' { + declare module.exports: $Exports<'vis/lib/graph3d/Range'>; +} +declare module 'vis/lib/graph3d/Settings.js' { + declare module.exports: $Exports<'vis/lib/graph3d/Settings'>; +} +declare module 'vis/lib/graph3d/Slider.js' { + declare module.exports: $Exports<'vis/lib/graph3d/Slider'>; +} +declare module 'vis/lib/graph3d/StepNumber.js' { + declare module.exports: $Exports<'vis/lib/graph3d/StepNumber'>; +} +declare module 'vis/lib/hammerUtil.js' { + declare module.exports: $Exports<'vis/lib/hammerUtil'>; +} +declare module 'vis/lib/header.js' { + declare module.exports: $Exports<'vis/lib/header'>; +} +declare module 'vis/lib/module/hammer.js' { + declare module.exports: $Exports<'vis/lib/module/hammer'>; +} +declare module 'vis/lib/module/moment.js' { + declare module.exports: $Exports<'vis/lib/module/moment'>; +} +declare module 'vis/lib/module/uuid.js' { + declare module.exports: $Exports<'vis/lib/module/uuid'>; +} +declare module 'vis/lib/network/CachedImage.js' { + declare module.exports: $Exports<'vis/lib/network/CachedImage'>; +} +declare module 'vis/lib/network/dotparser.js' { + declare module.exports: $Exports<'vis/lib/network/dotparser'>; +} +declare module 'vis/lib/network/gephiParser.js' { + declare module.exports: $Exports<'vis/lib/network/gephiParser'>; +} +declare module 'vis/lib/network/Images.js' { + declare module.exports: $Exports<'vis/lib/network/Images'>; +} +declare module 'vis/lib/network/locales.js' { + declare module.exports: $Exports<'vis/lib/network/locales'>; +} +declare module 'vis/lib/network/modules/Canvas.js' { + declare module.exports: $Exports<'vis/lib/network/modules/Canvas'>; +} +declare module 'vis/lib/network/modules/CanvasRenderer.js' { + declare module.exports: $Exports<'vis/lib/network/modules/CanvasRenderer'>; +} +declare module 'vis/lib/network/modules/Clustering.js' { + declare module.exports: $Exports<'vis/lib/network/modules/Clustering'>; +} +declare module 'vis/lib/network/modules/components/algorithms/FloydWarshall.js' { + declare module.exports: $Exports<'vis/lib/network/modules/components/algorithms/FloydWarshall'>; +} +declare module 'vis/lib/network/modules/components/DirectionStrategy.js' { + declare module.exports: $Exports<'vis/lib/network/modules/components/DirectionStrategy'>; +} +declare module 'vis/lib/network/modules/components/Edge.js' { + declare module.exports: $Exports<'vis/lib/network/modules/components/Edge'>; +} +declare module 'vis/lib/network/modules/components/edges/BezierEdgeDynamic.js' { + declare module.exports: $Exports<'vis/lib/network/modules/components/edges/BezierEdgeDynamic'>; +} +declare module 'vis/lib/network/modules/components/edges/BezierEdgeStatic.js' { + declare module.exports: $Exports<'vis/lib/network/modules/components/edges/BezierEdgeStatic'>; +} +declare module 'vis/lib/network/modules/components/edges/CubicBezierEdge.js' { + declare module.exports: $Exports<'vis/lib/network/modules/components/edges/CubicBezierEdge'>; +} +declare module 'vis/lib/network/modules/components/edges/StraightEdge.js' { + declare module.exports: $Exports<'vis/lib/network/modules/components/edges/StraightEdge'>; +} +declare module 'vis/lib/network/modules/components/edges/util/BezierEdgeBase.js' { + declare module.exports: $Exports<'vis/lib/network/modules/components/edges/util/BezierEdgeBase'>; +} +declare module 'vis/lib/network/modules/components/edges/util/CubicBezierEdgeBase.js' { + declare module.exports: $Exports<'vis/lib/network/modules/components/edges/util/CubicBezierEdgeBase'>; +} +declare module 'vis/lib/network/modules/components/edges/util/EdgeBase.js' { + declare module.exports: $Exports<'vis/lib/network/modules/components/edges/util/EdgeBase'>; +} +declare module 'vis/lib/network/modules/components/edges/util/EndPoints.js' { + declare module.exports: $Exports<'vis/lib/network/modules/components/edges/util/EndPoints'>; +} +declare module 'vis/lib/network/modules/components/NavigationHandler.js' { + declare module.exports: $Exports<'vis/lib/network/modules/components/NavigationHandler'>; +} +declare module 'vis/lib/network/modules/components/Node.js' { + declare module.exports: $Exports<'vis/lib/network/modules/components/Node'>; +} +declare module 'vis/lib/network/modules/components/nodes/Cluster.js' { + declare module.exports: $Exports<'vis/lib/network/modules/components/nodes/Cluster'>; +} +declare module 'vis/lib/network/modules/components/nodes/shapes/Box.js' { + declare module.exports: $Exports<'vis/lib/network/modules/components/nodes/shapes/Box'>; +} +declare module 'vis/lib/network/modules/components/nodes/shapes/Circle.js' { + declare module.exports: $Exports<'vis/lib/network/modules/components/nodes/shapes/Circle'>; +} +declare module 'vis/lib/network/modules/components/nodes/shapes/CircularImage.js' { + declare module.exports: $Exports<'vis/lib/network/modules/components/nodes/shapes/CircularImage'>; +} +declare module 'vis/lib/network/modules/components/nodes/shapes/Database.js' { + declare module.exports: $Exports<'vis/lib/network/modules/components/nodes/shapes/Database'>; +} +declare module 'vis/lib/network/modules/components/nodes/shapes/Diamond.js' { + declare module.exports: $Exports<'vis/lib/network/modules/components/nodes/shapes/Diamond'>; +} +declare module 'vis/lib/network/modules/components/nodes/shapes/Dot.js' { + declare module.exports: $Exports<'vis/lib/network/modules/components/nodes/shapes/Dot'>; +} +declare module 'vis/lib/network/modules/components/nodes/shapes/Ellipse.js' { + declare module.exports: $Exports<'vis/lib/network/modules/components/nodes/shapes/Ellipse'>; +} +declare module 'vis/lib/network/modules/components/nodes/shapes/Hexagon.js' { + declare module.exports: $Exports<'vis/lib/network/modules/components/nodes/shapes/Hexagon'>; +} +declare module 'vis/lib/network/modules/components/nodes/shapes/Icon.js' { + declare module.exports: $Exports<'vis/lib/network/modules/components/nodes/shapes/Icon'>; +} +declare module 'vis/lib/network/modules/components/nodes/shapes/Image.js' { + declare module.exports: $Exports<'vis/lib/network/modules/components/nodes/shapes/Image'>; +} +declare module 'vis/lib/network/modules/components/nodes/shapes/Square.js' { + declare module.exports: $Exports<'vis/lib/network/modules/components/nodes/shapes/Square'>; +} +declare module 'vis/lib/network/modules/components/nodes/shapes/Star.js' { + declare module.exports: $Exports<'vis/lib/network/modules/components/nodes/shapes/Star'>; +} +declare module 'vis/lib/network/modules/components/nodes/shapes/Text.js' { + declare module.exports: $Exports<'vis/lib/network/modules/components/nodes/shapes/Text'>; +} +declare module 'vis/lib/network/modules/components/nodes/shapes/Triangle.js' { + declare module.exports: $Exports<'vis/lib/network/modules/components/nodes/shapes/Triangle'>; +} +declare module 'vis/lib/network/modules/components/nodes/shapes/TriangleDown.js' { + declare module.exports: $Exports<'vis/lib/network/modules/components/nodes/shapes/TriangleDown'>; +} +declare module 'vis/lib/network/modules/components/nodes/util/CircleImageBase.js' { + declare module.exports: $Exports<'vis/lib/network/modules/components/nodes/util/CircleImageBase'>; +} +declare module 'vis/lib/network/modules/components/nodes/util/NodeBase.js' { + declare module.exports: $Exports<'vis/lib/network/modules/components/nodes/util/NodeBase'>; +} +declare module 'vis/lib/network/modules/components/nodes/util/ShapeBase.js' { + declare module.exports: $Exports<'vis/lib/network/modules/components/nodes/util/ShapeBase'>; +} +declare module 'vis/lib/network/modules/components/physics/BarnesHutSolver.js' { + declare module.exports: $Exports<'vis/lib/network/modules/components/physics/BarnesHutSolver'>; +} +declare module 'vis/lib/network/modules/components/physics/CentralGravitySolver.js' { + declare module.exports: $Exports<'vis/lib/network/modules/components/physics/CentralGravitySolver'>; +} +declare module 'vis/lib/network/modules/components/physics/FA2BasedCentralGravitySolver.js' { + declare module.exports: $Exports<'vis/lib/network/modules/components/physics/FA2BasedCentralGravitySolver'>; +} +declare module 'vis/lib/network/modules/components/physics/FA2BasedRepulsionSolver.js' { + declare module.exports: $Exports<'vis/lib/network/modules/components/physics/FA2BasedRepulsionSolver'>; +} +declare module 'vis/lib/network/modules/components/physics/HierarchicalRepulsionSolver.js' { + declare module.exports: $Exports<'vis/lib/network/modules/components/physics/HierarchicalRepulsionSolver'>; +} +declare module 'vis/lib/network/modules/components/physics/HierarchicalSpringSolver.js' { + declare module.exports: $Exports<'vis/lib/network/modules/components/physics/HierarchicalSpringSolver'>; +} +declare module 'vis/lib/network/modules/components/physics/RepulsionSolver.js' { + declare module.exports: $Exports<'vis/lib/network/modules/components/physics/RepulsionSolver'>; +} +declare module 'vis/lib/network/modules/components/physics/SpringSolver.js' { + declare module.exports: $Exports<'vis/lib/network/modules/components/physics/SpringSolver'>; +} +declare module 'vis/lib/network/modules/components/shared/ComponentUtil.js' { + declare module.exports: $Exports<'vis/lib/network/modules/components/shared/ComponentUtil'>; +} +declare module 'vis/lib/network/modules/components/shared/Label.js' { + declare module.exports: $Exports<'vis/lib/network/modules/components/shared/Label'>; +} +declare module 'vis/lib/network/modules/components/shared/LabelAccumulator.js' { + declare module.exports: $Exports<'vis/lib/network/modules/components/shared/LabelAccumulator'>; +} +declare module 'vis/lib/network/modules/components/shared/LabelSplitter.js' { + declare module.exports: $Exports<'vis/lib/network/modules/components/shared/LabelSplitter'>; +} +declare module 'vis/lib/network/modules/EdgesHandler.js' { + declare module.exports: $Exports<'vis/lib/network/modules/EdgesHandler'>; +} +declare module 'vis/lib/network/modules/Groups.js' { + declare module.exports: $Exports<'vis/lib/network/modules/Groups'>; +} +declare module 'vis/lib/network/modules/InteractionHandler.js' { + declare module.exports: $Exports<'vis/lib/network/modules/InteractionHandler'>; +} +declare module 'vis/lib/network/modules/KamadaKawai.js' { + declare module.exports: $Exports<'vis/lib/network/modules/KamadaKawai'>; +} +declare module 'vis/lib/network/modules/LayoutEngine.js' { + declare module.exports: $Exports<'vis/lib/network/modules/LayoutEngine'>; +} +declare module 'vis/lib/network/modules/ManipulationSystem.js' { + declare module.exports: $Exports<'vis/lib/network/modules/ManipulationSystem'>; +} +declare module 'vis/lib/network/modules/NodesHandler.js' { + declare module.exports: $Exports<'vis/lib/network/modules/NodesHandler'>; +} +declare module 'vis/lib/network/modules/PhysicsEngine.js' { + declare module.exports: $Exports<'vis/lib/network/modules/PhysicsEngine'>; +} +declare module 'vis/lib/network/modules/SelectionHandler.js' { + declare module.exports: $Exports<'vis/lib/network/modules/SelectionHandler'>; +} +declare module 'vis/lib/network/modules/View.js' { + declare module.exports: $Exports<'vis/lib/network/modules/View'>; +} +declare module 'vis/lib/network/Network.js' { + declare module.exports: $Exports<'vis/lib/network/Network'>; +} +declare module 'vis/lib/network/NetworkUtil.js' { + declare module.exports: $Exports<'vis/lib/network/NetworkUtil'>; +} +declare module 'vis/lib/network/options.js' { + declare module.exports: $Exports<'vis/lib/network/options'>; +} +declare module 'vis/lib/network/shapes.js' { + declare module.exports: $Exports<'vis/lib/network/shapes'>; +} +declare module 'vis/lib/Queue.js' { + declare module.exports: $Exports<'vis/lib/Queue'>; +} +declare module 'vis/lib/shared/Activator.js' { + declare module.exports: $Exports<'vis/lib/shared/Activator'>; +} +declare module 'vis/lib/shared/ColorPicker.js' { + declare module.exports: $Exports<'vis/lib/shared/ColorPicker'>; +} +declare module 'vis/lib/shared/Configurator.js' { + declare module.exports: $Exports<'vis/lib/shared/Configurator'>; +} +declare module 'vis/lib/shared/Popup.js' { + declare module.exports: $Exports<'vis/lib/shared/Popup'>; +} +declare module 'vis/lib/shared/Validator.js' { + declare module.exports: $Exports<'vis/lib/shared/Validator'>; +} +declare module 'vis/lib/timeline/component/BackgroundGroup.js' { + declare module.exports: $Exports<'vis/lib/timeline/component/BackgroundGroup'>; +} +declare module 'vis/lib/timeline/component/Component.js' { + declare module.exports: $Exports<'vis/lib/timeline/component/Component'>; +} +declare module 'vis/lib/timeline/component/CurrentTime.js' { + declare module.exports: $Exports<'vis/lib/timeline/component/CurrentTime'>; +} +declare module 'vis/lib/timeline/component/CustomTime.js' { + declare module.exports: $Exports<'vis/lib/timeline/component/CustomTime'>; +} +declare module 'vis/lib/timeline/component/DataAxis.js' { + declare module.exports: $Exports<'vis/lib/timeline/component/DataAxis'>; +} +declare module 'vis/lib/timeline/component/DataScale.js' { + declare module.exports: $Exports<'vis/lib/timeline/component/DataScale'>; +} +declare module 'vis/lib/timeline/component/graph2d_types/bar.js' { + declare module.exports: $Exports<'vis/lib/timeline/component/graph2d_types/bar'>; +} +declare module 'vis/lib/timeline/component/graph2d_types/line.js' { + declare module.exports: $Exports<'vis/lib/timeline/component/graph2d_types/line'>; +} +declare module 'vis/lib/timeline/component/graph2d_types/points.js' { + declare module.exports: $Exports<'vis/lib/timeline/component/graph2d_types/points'>; +} +declare module 'vis/lib/timeline/component/GraphGroup.js' { + declare module.exports: $Exports<'vis/lib/timeline/component/GraphGroup'>; +} +declare module 'vis/lib/timeline/component/Group.js' { + declare module.exports: $Exports<'vis/lib/timeline/component/Group'>; +} +declare module 'vis/lib/timeline/component/item/BackgroundItem.js' { + declare module.exports: $Exports<'vis/lib/timeline/component/item/BackgroundItem'>; +} +declare module 'vis/lib/timeline/component/item/BoxItem.js' { + declare module.exports: $Exports<'vis/lib/timeline/component/item/BoxItem'>; +} +declare module 'vis/lib/timeline/component/item/Item.js' { + declare module.exports: $Exports<'vis/lib/timeline/component/item/Item'>; +} +declare module 'vis/lib/timeline/component/item/PointItem.js' { + declare module.exports: $Exports<'vis/lib/timeline/component/item/PointItem'>; +} +declare module 'vis/lib/timeline/component/item/RangeItem.js' { + declare module.exports: $Exports<'vis/lib/timeline/component/item/RangeItem'>; +} +declare module 'vis/lib/timeline/component/ItemSet.js' { + declare module.exports: $Exports<'vis/lib/timeline/component/ItemSet'>; +} +declare module 'vis/lib/timeline/component/Legend.js' { + declare module.exports: $Exports<'vis/lib/timeline/component/Legend'>; +} +declare module 'vis/lib/timeline/component/LineGraph.js' { + declare module.exports: $Exports<'vis/lib/timeline/component/LineGraph'>; +} +declare module 'vis/lib/timeline/component/TimeAxis.js' { + declare module.exports: $Exports<'vis/lib/timeline/component/TimeAxis'>; +} +declare module 'vis/lib/timeline/Core.js' { + declare module.exports: $Exports<'vis/lib/timeline/Core'>; +} +declare module 'vis/lib/timeline/DateUtil.js' { + declare module.exports: $Exports<'vis/lib/timeline/DateUtil'>; +} +declare module 'vis/lib/timeline/Graph2d.js' { + declare module.exports: $Exports<'vis/lib/timeline/Graph2d'>; +} +declare module 'vis/lib/timeline/locales.js' { + declare module.exports: $Exports<'vis/lib/timeline/locales'>; +} +declare module 'vis/lib/timeline/optionsGraph2d.js' { + declare module.exports: $Exports<'vis/lib/timeline/optionsGraph2d'>; +} +declare module 'vis/lib/timeline/optionsTimeline.js' { + declare module.exports: $Exports<'vis/lib/timeline/optionsTimeline'>; +} +declare module 'vis/lib/timeline/Range.js' { + declare module.exports: $Exports<'vis/lib/timeline/Range'>; +} +declare module 'vis/lib/timeline/Stack.js' { + declare module.exports: $Exports<'vis/lib/timeline/Stack'>; +} +declare module 'vis/lib/timeline/Timeline.js' { + declare module.exports: $Exports<'vis/lib/timeline/Timeline'>; +} +declare module 'vis/lib/timeline/TimeStep.js' { + declare module.exports: $Exports<'vis/lib/timeline/TimeStep'>; +} +declare module 'vis/lib/util.js' { + declare module.exports: $Exports<'vis/lib/util'>; +} diff --git a/flow-typed/npm/websocket_vx.x.x.js b/flow-typed/npm/websocket_vx.x.x.js new file mode 100644 index 000000000..6d7ec8824 --- /dev/null +++ b/flow-typed/npm/websocket_vx.x.x.js @@ -0,0 +1,164 @@ +// flow-typed signature: a099122576a24c7a78325271cdd0048f +// flow-typed version: <>/websocket_v^1.0.24/flow_v0.59.0 + +/** + * This is an autogenerated libdef stub for: + * + * 'websocket' + * + * Fill this stub out by replacing all the `any` types. + * + * Once filled out, we encourage you to share your work with the + * community by sending a pull request to: + * https://github.com/flowtype/flow-typed + */ + +declare module 'websocket' { + declare module.exports: any; +} + +/** + * We include stubs for each file inside this npm package in case you need to + * require those files directly. Feel free to delete any files that aren't + * needed. + */ +declare module 'websocket/gulpfile' { + declare module.exports: any; +} + +declare module 'websocket/lib/browser' { + declare module.exports: any; +} + +declare module 'websocket/lib/BufferUtil.fallback' { + declare module.exports: any; +} + +declare module 'websocket/lib/BufferUtil' { + declare module.exports: any; +} + +declare module 'websocket/lib/Deprecation' { + declare module.exports: any; +} + +declare module 'websocket/lib/utils' { + declare module.exports: any; +} + +declare module 'websocket/lib/Validation.fallback' { + declare module.exports: any; +} + +declare module 'websocket/lib/Validation' { + declare module.exports: any; +} + +declare module 'websocket/lib/version' { + declare module.exports: any; +} + +declare module 'websocket/lib/W3CWebSocket' { + declare module.exports: any; +} + +declare module 'websocket/lib/websocket' { + declare module.exports: any; +} + +declare module 'websocket/lib/WebSocketClient' { + declare module.exports: any; +} + +declare module 'websocket/lib/WebSocketConnection' { + declare module.exports: any; +} + +declare module 'websocket/lib/WebSocketFrame' { + declare module.exports: any; +} + +declare module 'websocket/lib/WebSocketRequest' { + declare module.exports: any; +} + +declare module 'websocket/lib/WebSocketRouter' { + declare module.exports: any; +} + +declare module 'websocket/lib/WebSocketRouterRequest' { + declare module.exports: any; +} + +declare module 'websocket/lib/WebSocketServer' { + declare module.exports: any; +} + +declare module 'websocket/vendor/FastBufferList' { + declare module.exports: any; +} + +// Filename aliases +declare module 'websocket/gulpfile.js' { + declare module.exports: $Exports<'websocket/gulpfile'>; +} +declare module 'websocket/index' { + declare module.exports: $Exports<'websocket'>; +} +declare module 'websocket/index.js' { + declare module.exports: $Exports<'websocket'>; +} +declare module 'websocket/lib/browser.js' { + declare module.exports: $Exports<'websocket/lib/browser'>; +} +declare module 'websocket/lib/BufferUtil.fallback.js' { + declare module.exports: $Exports<'websocket/lib/BufferUtil.fallback'>; +} +declare module 'websocket/lib/BufferUtil.js' { + declare module.exports: $Exports<'websocket/lib/BufferUtil'>; +} +declare module 'websocket/lib/Deprecation.js' { + declare module.exports: $Exports<'websocket/lib/Deprecation'>; +} +declare module 'websocket/lib/utils.js' { + declare module.exports: $Exports<'websocket/lib/utils'>; +} +declare module 'websocket/lib/Validation.fallback.js' { + declare module.exports: $Exports<'websocket/lib/Validation.fallback'>; +} +declare module 'websocket/lib/Validation.js' { + declare module.exports: $Exports<'websocket/lib/Validation'>; +} +declare module 'websocket/lib/version.js' { + declare module.exports: $Exports<'websocket/lib/version'>; +} +declare module 'websocket/lib/W3CWebSocket.js' { + declare module.exports: $Exports<'websocket/lib/W3CWebSocket'>; +} +declare module 'websocket/lib/websocket.js' { + declare module.exports: $Exports<'websocket/lib/websocket'>; +} +declare module 'websocket/lib/WebSocketClient.js' { + declare module.exports: $Exports<'websocket/lib/WebSocketClient'>; +} +declare module 'websocket/lib/WebSocketConnection.js' { + declare module.exports: $Exports<'websocket/lib/WebSocketConnection'>; +} +declare module 'websocket/lib/WebSocketFrame.js' { + declare module.exports: $Exports<'websocket/lib/WebSocketFrame'>; +} +declare module 'websocket/lib/WebSocketRequest.js' { + declare module.exports: $Exports<'websocket/lib/WebSocketRequest'>; +} +declare module 'websocket/lib/WebSocketRouter.js' { + declare module.exports: $Exports<'websocket/lib/WebSocketRouter'>; +} +declare module 'websocket/lib/WebSocketRouterRequest.js' { + declare module.exports: $Exports<'websocket/lib/WebSocketRouterRequest'>; +} +declare module 'websocket/lib/WebSocketServer.js' { + declare module.exports: $Exports<'websocket/lib/WebSocketServer'>; +} +declare module 'websocket/vendor/FastBufferList.js' { + declare module.exports: $Exports<'websocket/vendor/FastBufferList'>; +} diff --git a/flow-typed/npm/ws_vx.x.x.js b/flow-typed/npm/ws_vx.x.x.js new file mode 100644 index 000000000..24a07f25e --- /dev/null +++ b/flow-typed/npm/ws_vx.x.x.js @@ -0,0 +1,108 @@ +// flow-typed signature: efc8a980cb830128a9eaa7f9ee01567b +// flow-typed version: <>/ws_v^3.0.0/flow_v0.59.0 + +/** + * This is an autogenerated libdef stub for: + * + * 'ws' + * + * Fill this stub out by replacing all the `any` types. + * + * Once filled out, we encourage you to share your work with the + * community by sending a pull request to: + * https://github.com/flowtype/flow-typed + */ + +declare module 'ws' { + declare module.exports: any; +} + +/** + * We include stubs for each file inside this npm package in case you need to + * require those files directly. Feel free to delete any files that aren't + * needed. + */ +declare module 'ws/lib/BufferUtil' { + declare module.exports: any; +} + +declare module 'ws/lib/Constants' { + declare module.exports: any; +} + +declare module 'ws/lib/ErrorCodes' { + declare module.exports: any; +} + +declare module 'ws/lib/EventTarget' { + declare module.exports: any; +} + +declare module 'ws/lib/Extensions' { + declare module.exports: any; +} + +declare module 'ws/lib/PerMessageDeflate' { + declare module.exports: any; +} + +declare module 'ws/lib/Receiver' { + declare module.exports: any; +} + +declare module 'ws/lib/Sender' { + declare module.exports: any; +} + +declare module 'ws/lib/Validation' { + declare module.exports: any; +} + +declare module 'ws/lib/WebSocket' { + declare module.exports: any; +} + +declare module 'ws/lib/WebSocketServer' { + declare module.exports: any; +} + +// Filename aliases +declare module 'ws/index' { + declare module.exports: $Exports<'ws'>; +} +declare module 'ws/index.js' { + declare module.exports: $Exports<'ws'>; +} +declare module 'ws/lib/BufferUtil.js' { + declare module.exports: $Exports<'ws/lib/BufferUtil'>; +} +declare module 'ws/lib/Constants.js' { + declare module.exports: $Exports<'ws/lib/Constants'>; +} +declare module 'ws/lib/ErrorCodes.js' { + declare module.exports: $Exports<'ws/lib/ErrorCodes'>; +} +declare module 'ws/lib/EventTarget.js' { + declare module.exports: $Exports<'ws/lib/EventTarget'>; +} +declare module 'ws/lib/Extensions.js' { + declare module.exports: $Exports<'ws/lib/Extensions'>; +} +declare module 'ws/lib/PerMessageDeflate.js' { + declare module.exports: $Exports<'ws/lib/PerMessageDeflate'>; +} +declare module 'ws/lib/Receiver.js' { + declare module.exports: $Exports<'ws/lib/Receiver'>; +} +declare module 'ws/lib/Sender.js' { + declare module.exports: $Exports<'ws/lib/Sender'>; +} +declare module 'ws/lib/Validation.js' { + declare module.exports: $Exports<'ws/lib/Validation'>; +} +declare module 'ws/lib/WebSocket.js' { + declare module.exports: $Exports<'ws/lib/WebSocket'>; +} +declare module 'ws/lib/WebSocketServer.js' { + declare module.exports: $Exports<'ws/lib/WebSocketServer'>; +} diff --git a/flow-typed/npm/yargs_vx.x.x.js b/flow-typed/npm/yargs_vx.x.x.js new file mode 100644 index 000000000..9dcec4252 --- /dev/null +++ b/flow-typed/npm/yargs_vx.x.x.js @@ -0,0 +1,101 @@ +// flow-typed signature: 3efe3623a87ff36c0bcfb0fbcdbdf729 +// flow-typed version: <>/yargs_v^10.0.3/flow_v0.59.0 + +/** + * This is an autogenerated libdef stub for: + * + * 'yargs' + * + * Fill this stub out by replacing all the `any` types. + * + * Once filled out, we encourage you to share your work with the + * community by sending a pull request to: + * https://github.com/flowtype/flow-typed + */ + +declare module 'yargs' { + declare module.exports: any; +} + +/** + * We include stubs for each file inside this npm package in case you need to + * require those files directly. Feel free to delete any files that aren't + * needed. + */ +declare module 'yargs/lib/apply-extends' { + declare module.exports: any; +} + +declare module 'yargs/lib/argsert' { + declare module.exports: any; +} + +declare module 'yargs/lib/command' { + declare module.exports: any; +} + +declare module 'yargs/lib/completion' { + declare module.exports: any; +} + +declare module 'yargs/lib/levenshtein' { + declare module.exports: any; +} + +declare module 'yargs/lib/obj-filter' { + declare module.exports: any; +} + +declare module 'yargs/lib/usage' { + declare module.exports: any; +} + +declare module 'yargs/lib/validation' { + declare module.exports: any; +} + +declare module 'yargs/lib/yerror' { + declare module.exports: any; +} + +declare module 'yargs/yargs' { + declare module.exports: any; +} + +// Filename aliases +declare module 'yargs/index' { + declare module.exports: $Exports<'yargs'>; +} +declare module 'yargs/index.js' { + declare module.exports: $Exports<'yargs'>; +} +declare module 'yargs/lib/apply-extends.js' { + declare module.exports: $Exports<'yargs/lib/apply-extends'>; +} +declare module 'yargs/lib/argsert.js' { + declare module.exports: $Exports<'yargs/lib/argsert'>; +} +declare module 'yargs/lib/command.js' { + declare module.exports: $Exports<'yargs/lib/command'>; +} +declare module 'yargs/lib/completion.js' { + declare module.exports: $Exports<'yargs/lib/completion'>; +} +declare module 'yargs/lib/levenshtein.js' { + declare module.exports: $Exports<'yargs/lib/levenshtein'>; +} +declare module 'yargs/lib/obj-filter.js' { + declare module.exports: $Exports<'yargs/lib/obj-filter'>; +} +declare module 'yargs/lib/usage.js' { + declare module.exports: $Exports<'yargs/lib/usage'>; +} +declare module 'yargs/lib/validation.js' { + declare module.exports: $Exports<'yargs/lib/validation'>; +} +declare module 'yargs/lib/yerror.js' { + declare module.exports: $Exports<'yargs/lib/yerror'>; +} +declare module 'yargs/yargs.js' { + declare module.exports: $Exports<'yargs/yargs'>; +} diff --git a/flow-typed/react.js b/flow-typed/react.js new file mode 100644 index 000000000..b34c9ab39 --- /dev/null +++ b/flow-typed/react.js @@ -0,0 +1,8 @@ +/** + * Copyright 2018-present Facebook. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * @format + */ + +declare var React: $Exports<'react'>; diff --git a/gradle.properties b/gradle.properties new file mode 100644 index 000000000..40cb82f06 --- /dev/null +++ b/gradle.properties @@ -0,0 +1,7 @@ +GRADLE_VERSIONS_PLUGIN_VERSION=0.15.0 + +KOTLIN_VERSION=1.2.41 + +# Deps for publishing +GRADLE_BINTRAY_PLUGIN_VERSION=1.8.0 +ANDROID_MAVEN_GRADLE_PLUGIN_VERSION=2.1 diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000000000000000000000000000000000000..91ca28c8b802289c3a438766657a5e98f20eff03 GIT binary patch literal 54413 zcmafaV|Zr4wq`oEZQHiZj%|LijZQlLf{tz5M#r{o+fI6V=G-$g=gzrzeyqLskF}nv zRZs0&c;EUi2L_G~0s;*U0szbK}f6%Pvi zRZ#mYf6f1oqJoH`jHHCB8l!^by~4z}yc`4LEP@;Z?bO6{g9`Hk+s@(L1jC5Tq{1Yf z4E;CQvrx0-gF+peRxFC*gF=&$zNYk(w0q}U=WqXMz`tYs@0o%B{dRD+{C_6(f9t^g zhmNJQv6-#;f2)f2uc{u-#*U8W&i{|ewYN^n_1~cv|1J!}zc&$eaBy{T{cEpa46s*q zHFkD2cV;xTHFj}{*3kBt*FgS4A5SI|$F%$gB@It9FlC}D3y`sbZG{2P6gGwC$U`6O zb_cId9AhQl#A<&=x>-xDD%=Ppt$;y71@Lwsl{x943#T@8*?cbR<~d`@@}4V${+r$jICUIOzgZJy_9I zu*eA(F)$~J07zX%tmQN}1^wj+RM|9bbwhQA=xrPE*{vB_P!pPYT5{Or^m*;Qz#@Bl zRywCG_RDyM6bf~=xn}FtiFAw|rrUxa1+z^H`j6e|GwKDuq}P)z&@J>MEhsVBvnF|O zOEm)dADU1wi8~mX(j_8`DwMT_OUAnjbWYer;P*^Uku_qMu3}qJU zTAkza-K9aj&wcsGuhQ>RQoD?gz~L8RwCHOZDzhBD$az*$TQ3!uygnx_rsXG`#_x5t zn*lb(%JI3%G^MpYp-Y(KI4@_!&kBRa3q z|Fzn&3R%ZsoMNEn4pN3-BSw2S_{IB8RzRv(eQ1X zyBQZHJ<(~PfUZ~EoI!Aj`9k<+Cy z2DtI<+9sXQu!6&-Sk4SW3oz}?Q~mFvy(urUy<)x!KQ>#7yIPC)(ORhKl7k)4eSy~} z7#H3KG<|lt68$tk^`=yjev%^usOfpQ#+Tqyx|b#dVA(>fPlGuS@9ydo z!Cs#hse9nUETfGX-7lg;F>9)+ml@M8OO^q|W~NiysX2N|2dH>qj%NM`=*d3GvES_# zyLEHw&1Fx<-dYxCQbk_wk^CI?W44%Q9!!9aJKZW-bGVhK?N;q`+Cgc*WqyXcxZ%U5QXKu!Xn)u_dxeQ z;uw9Vysk!3OFzUmVoe)qt3ifPin0h25TU zrG*03L~0|aaBg7^YPEW^Yq3>mSNQgk-o^CEH?wXZ^QiPiuH}jGk;75PUMNquJjm$3 zLcXN*uDRf$Jukqg3;046b;3s8zkxa_6yAlG{+7{81O3w96i_A$KcJhD&+oz1<>?lun#C3+X0q zO4JxN{qZ!e#FCl@e_3G?0I^$CX6e$cy7$BL#4<`AA)Lw+k`^15pmb-447~5lkSMZ` z>Ce|adKhb-F%yy!vx>yQbXFgHyl(an=x^zi(!-~|k;G1=E(e@JgqbAF{;nv`3i)oi zDeT*Q+Mp{+NkURoabYb9@#Bi5FMQnBFEU?H{~9c;g3K%m{+^hNe}(MdpPb?j9`?2l z#%AO!|2QxGq7-2Jn2|%atvGb(+?j&lmP509i5y87`9*BSY++<%%DXb)kaqG0(4Eft zj|2!Od~2TfVTi^0dazAIeVe&b#{J4DjN6;4W;M{yWj7#+oLhJyqeRaO;>?%mX>Ec{Mp~;`bo}p;`)@5dA8fNQ38FyMf;wUPOdZS{U*8SN6xa z-kq3>*Zos!2`FMA7qjhw-`^3ci%c91Lh`;h{qX1r;x1}eW2hYaE*3lTk4GwenoxQ1kHt1Lw!*N8Z%DdZSGg5~Bw}+L!1#d$u+S=Bzo7gi zqGsBV29i)Jw(vix>De)H&PC; z-t2OX_ak#~eSJ?Xq=q9A#0oaP*dO7*MqV;dJv|aUG00UX=cIhdaet|YEIhv6AUuyM zH1h7fK9-AV)k8sr#POIhl+?Z^r?wI^GE)ZI=H!WR<|UI(3_YUaD#TYV$Fxd015^mT zpy&#-IK>ahfBlJm-J(n(A%cKV;)8&Y{P!E|AHPtRHk=XqvYUX?+9po4B$0-6t74UUef${01V{QLEE8gzw* z5nFnvJ|T4dlRiW9;Ed_yB{R@)fC=zo4hCtD?TPW*WJmMXYxN_&@YQYg zBQ$XRHa&EE;YJrS{bn7q?}Y&DH*h;){5MmE(9A6aSU|W?{3Ox%5fHLFScv7O-txuRbPG1KQtI`Oay=IcEG=+hPhlnYC;`wSHeo|XGio0aTS6&W($E$ z?N&?TK*l8;Y^-xPl-WVZwrfdiQv10KdsAb9u-*1co*0-Z(h#H)k{Vc5CT!708cs%sExvPC+7-^UY~jTfFq=cj z!Dmy<+NtKp&}}$}rD{l?%MwHdpE(cPCd;-QFPk1`E5EVNY2i6E`;^aBlx4}h*l42z zpY#2cYzC1l6EDrOY*ccb%kP;k8LHE3tP>l3iK?XZ%FI<3666yPw1rM%>eCgnv^JS_ zK7c~;g7yXt9fz@(49}Dj7VO%+P!eEm& z;z8UXs%NsQ%@2S5nve)@;yT^61BpVlc}=+i6{ZZ9r7<({yUYqe==9*Z+HguP3`sA& z{`inI4G)eLieUQ*pH9M@)u7yVnWTQva;|xq&-B<>MoP(|xP(HqeCk1&h>DHNLT>Zi zQ$uH%s6GoPAi0~)sC;`;ngsk+StYL9NFzhFEoT&Hzfma1f|tEnL0 zMWdX4(@Y*?*tM2@H<#^_l}BC&;PYJl%~E#veQ61{wG6!~nyop<^e)scV5#VkGjYc2 z$u)AW-NmMm%T7WschOnQ!Hbbw&?`oMZrJ&%dVlN3VNra1d0TKfbOz{dHfrCmJ2Jj= zS#Gr}JQcVD?S9X!u|oQ7LZ+qcq{$40 ziG5=X^+WqeqxU00YuftU7o;db=K+Tq!y^daCZgQ)O=M} zK>j*<3oxs=Rcr&W2h%w?0Cn3);~vqG>JO_tTOzuom^g&^vzlEjkx>Sv!@NNX%_C!v zaMpB>%yVb}&ND9b*O>?HxQ$5-%@xMGe4XKjWh7X>CYoRI2^JIwi&3Q5UM)?G^k8;8 zmY$u;(KjZx>vb3fe2zgD7V;T2_|1KZQW$Yq%y5Ioxmna9#xktcgVitv7Sb3SlLd6D zfmBM9Vs4rt1s0M}c_&%iP5O{Dnyp|g1(cLYz^qLqTfN6`+o}59Zlu%~oR3Q3?{Bnr zkx+wTpeag^G12fb_%SghFcl|p2~<)Av?Agumf@v7y-)ecVs`US=q~=QG%(_RTsqQi z%B&JdbOBOmoywgDW|DKR5>l$1^FPhxsBrja<&}*pfvE|5dQ7j-wV|ur%QUCRCzBR3q*X`05O3U@?#$<>@e+Zh&Z&`KfuM!0XL& zI$gc@ZpM4o>d&5)mg7+-Mmp98K^b*28(|Ew8kW}XEV7k^vnX-$onm9OtaO@NU9a|as7iA%5Wrw9*%UtJYacltplA5}gx^YQM` zVkn`TIw~avq)mIQO0F0xg)w$c)=8~6Jl|gdqnO6<5XD)&e7z7ypd3HOIR+ss0ikSVrWar?548HFQ*+hC)NPCq*;cG#B$7 z!n?{e9`&Nh-y}v=nK&PR>PFdut*q&i81Id`Z<0vXUPEbbJ|<~_D!)DJMqSF~ly$tN zygoa)um~xdYT<7%%m!K8+V(&%83{758b0}`b&=`))Tuv_)OL6pf=XOdFk&Mfx9y{! z6nL>V?t=#eFfM$GgGT8DgbGRCF@0ZcWaNs_#yl+6&sK~(JFwJmN-aHX{#Xkpmg;!} zgNyYYrtZdLzW1tN#QZAh!z5>h|At3m+ryJ-DFl%V>w?cmVTxt^DsCi1ZwPaCe*D{) z?#AZV6Debz{*D#C2>44Czy^yT3y92AYDcIXtZrK{L-XacVl$4i=X2|K=Fy5vAzhk{ zu3qG=qSb_YYh^HirWf~n!_Hn;TwV8FU9H8+=BO)XVFV`nt)b>5yACVr!b98QlLOBDY=^KS<*m9@_h3;64VhBQzb_QI)gbM zSDto2i*iFrvxSmAIrePB3i`Ib>LdM8wXq8(R{-)P6DjUi{2;?}9S7l7bND4w%L2!; zUh~sJ(?Yp}o!q6)2CwG*mgUUWlZ;xJZo`U`tiqa)H4j>QVC_dE7ha0)nP5mWGB268 zn~MVG<#fP#R%F=Ic@(&Va4dMk$ysM$^Avr1&hS!p=-7F>UMzd(M^N9Ijb|364}qcj zcIIh7suk$fQE3?Z^W4XKIPh~|+3(@{8*dSo&+Kr(J4^VtC{z*_{2}ld<`+mDE2)S| zQ}G#Q0@ffZCw!%ZGc@kNoMIdQ?1db%N1O0{IPPesUHI;(h8I}ETudk5ESK#boZgln z(0kvE`&6z1xH!s&={%wQe;{^&5e@N0s7IqR?L*x%iXM_czI5R1aU?!bA7)#c4UN2u zc_LZU+@elD5iZ=4*X&8%7~mA;SA$SJ-8q^tL6y)d150iM)!-ry@TI<=cnS#$kJAS# zq%eK**T*Wi2OlJ#w+d_}4=VN^A%1O+{?`BK00wkm)g8;u?vM;RR+F1G?}({ENT3i= zQsjJkp-dmJ&3-jMNo)wrz0!g*1z!V7D(StmL(A}gr^H-CZ~G9u?*Uhcx|x7rb`v^X z9~QGx;wdF4VcxCmEBp$F#sms@MR?CF67)rlpMxvwhEZLgp2?wQq|ci#rLtrYRV~iR zN?UrkDDTu114&d~Utjcyh#tXE_1x%!dY?G>qb81pWWH)Ku@Kxbnq0=zL#x@sCB(gs zm}COI(!{6-XO5li0>1n}Wz?w7AT-Sp+=NQ1aV@fM$`PGZjs*L+H^EW&s!XafStI!S zzgdntht=*p#R*o8-ZiSb5zf6z?TZr$^BtmIfGAGK;cdg=EyEG)fc*E<*T=#a?l=R5 zv#J;6C(umoSfc)W*EODW4z6czg3tXIm?x8{+8i^b;$|w~k)KLhJQnNW7kWXcR^sol z1GYOp?)a+}9Dg*nJ4fy*_riThdkbHO37^csfZRGN;CvQOtRacu6uoh^gg%_oEZKDd z?X_k67s$`|Q&huidfEonytrq!wOg07H&z@`&BU6D114p!rtT2|iukF}>k?71-3Hk< zs6yvmsMRO%KBQ44X4_FEYW~$yx@Y9tKrQ|rC1%W$6w}-9!2%4Zk%NycTzCB=nb)r6*92_Dg+c0;a%l1 zsJ$X)iyYR2iSh|%pIzYV1OUWER&np{w1+RXb~ zMUMRymjAw*{M)UtbT)T!kq5ZAn%n=gq3ssk3mYViE^$paZ;c^7{vXDJ`)q<}QKd2?{r9`X3mpZ{AW^UaRe2^wWxIZ$tuyKzp#!X-hXkHwfD zj@2tA--vFi3o_6B?|I%uwD~emwn0a z+?2Lc1xs(`H{Xu>IHXpz=@-84uw%dNV;{|c&ub|nFz(=W-t4|MME(dE4tZQi?0CE|4_?O_dyZj1)r zBcqB8I^Lt*#)ABdw#yq{OtNgf240Jvjm8^zdSf40 z;H)cp*rj>WhGSy|RC5A@mwnmQ`y4{O*SJ&S@UFbvLWyPdh)QnM=(+m3p;0&$^ysbZ zJt!ZkNQ%3hOY*sF2_~-*`aP|3Jq7_<18PX*MEUH*)t{eIx%#ibC|d&^L5FwoBN}Oe z?!)9RS@Zz%X1mqpHgym75{_BM4g)k1!L{$r4(2kL<#Oh$Ei7koqoccI3(MN1+6cDJ zp=xQhmilz1?+ZjkX%kfn4{_6K_D{wb~rdbkh!!k!Z@cE z^&jz55*QtsuNSlGPrU=R?}{*_8?4L7(+?>?(^3Ss)f!ou&{6<9QgH>#2$?-HfmDPN z6oIJ$lRbDZb)h-fFEm^1-v?Slb8udG{7GhbaGD_JJ8a9f{6{TqQN;m@$&)t81k77A z?{{)61za|e2GEq2)-OqcEjP`fhIlUs_Es-dfgX-3{S08g`w=wGj2{?`k^GD8d$}6Z zBT0T1lNw~fuwjO5BurKM593NGYGWAK%UCYiq{$p^GoYz^Uq0$YQ$j5CBXyog8(p_E znTC+$D`*^PFNc3Ih3b!2Lu|OOH6@46D)bbvaZHy%-9=$cz}V^|VPBpmPB6Ivzlu&c zPq6s7(2c4=1M;xlr}bkSmo9P`DAF>?Y*K%VPsY`cVZ{mN&0I=jagJ?GA!I;R)i&@{ z0Gl^%TLf_N`)`WKs?zlWolWvEM_?{vVyo(!taG$`FH2bqB`(o50pA=W34kl-qI62lt z1~4LG_j%sR2tBFteI{&mOTRVU7AH>>-4ZCD_p6;-J<=qrod`YFBwJz(Siu(`S}&}1 z6&OVJS@(O!=HKr-Xyzuhi;swJYK*ums~y1ePdX#~*04=b9)UqHHg;*XJOxnS6XK#j zG|O$>^2eW2ZVczP8#$C`EpcWwPFX4^}$omn{;P(fL z>J~%-r5}*D3$Kii z34r@JmMW2XEa~UV{bYP=F;Y5=9miJ+Jw6tjkR+cUD5+5TuKI`mSnEaYE2=usXNBs9 zac}V13%|q&Yg6**?H9D620qj62dM+&&1&a{NjF}JqmIP1I1RGppZ|oIfR}l1>itC% zl>ed${{_}8^}m2^br*AIX$L!Vc?Sm@H^=|LnpJg`a7EC+B;)j#9#tx-o0_e4!F5-4 zF4gA;#>*qrpow9W%tBzQ89U6hZ9g=-$gQpCh6Nv_I0X7t=th2ajJ8dBbh{i)Ok4{I z`Gacpl?N$LjC$tp&}7Sm(?A;;Nb0>rAWPN~@3sZ~0_j5bR+dz;Qs|R|k%LdreS3Nn zp*36^t#&ASm=jT)PIjNqaSe4mTjAzlAFr*@nQ~F+Xdh$VjHWZMKaI+s#FF#zjx)BJ zufxkW_JQcPcHa9PviuAu$lhwPR{R{7CzMUi49=MaOA%ElpK;A)6Sgsl7lw)D$8FwE zi(O6g;m*86kcJQ{KIT-Rv&cbv_SY4 zpm1|lSL*o_1LGOlBK0KuU2?vWcEcQ6f4;&K=&?|f`~X+s8H)se?|~2HcJo{M?Ity) zE9U!EKGz2^NgB6Ud;?GcV*1xC^1RYIp&0fr;DrqWLi_Kts()-#&3|wz{wFQsKfnnsC||T?oIgUp z{O(?Df7&vW!i#_~*@naguLLjDAz+)~*_xV2iz2?(N|0y8DMneikrT*dG`mu6vdK`% z=&nX5{F-V!Reau}+w_V3)4?}h@A@O)6GCY7eXC{p-5~p8x{cH=hNR;Sb{*XloSZ_%0ZKYG=w<|!vy?spR4!6mF!sXMUB5S9o_lh^g0!=2m55hGR; z-&*BZ*&;YSo474=SAM!WzrvjmNtq17L`kxbrZ8RN419e=5CiQ-bP1j-C#@@-&5*(8 zRQdU~+e(teUf}I3tu%PB1@Tr{r=?@0KOi3+Dy8}+y#bvgeY(FdN!!`Kb>-nM;7u=6 z;0yBwOJ6OdWn0gnuM{0`*fd=C(f8ASnH5aNYJjpbY1apTAY$-%)uDi$%2)lpH=#)=HH z<9JaYwPKil@QbfGOWvJ?cN6RPBr`f+jBC|-dO|W@x_Vv~)bmY(U(!cs6cnhe0z31O z>yTtL4@KJ*ac85u9|=LFST22~!lb>n7IeHs)_(P_gU}|8G>{D_fJX)8BJ;Se? z67QTTlTzZykb^4!{xF!=C}VeFd@n!9E)JAK4|vWVwWop5vSWcD<;2!88v-lS&ve7C zuYRH^85#hGKX(Mrk};f$j_V&`Nb}MZy1mmfz(e`nnI4Vpq(R}26pZx?fq%^|(n~>* z5a5OFtFJJfrZmgjyHbj1`9||Yp?~`p2?4NCwu_!!*4w8K`&G7U_|np&g7oY*-i;sI zu)~kYH;FddS{7Ri#Z5)U&X3h1$Mj{{yk1Q6bh4!7!)r&rqO6K~{afz@bis?*a56i& zxi#(Ss6tkU5hDQJ0{4sKfM*ah0f$>WvuRL zunQ-eOqa3&(rv4kiQ(N4`FO6w+nko_HggKFWx@5aYr}<~8wuEbD(Icvyl~9QL^MBt zSvD)*C#{2}!Z55k1ukV$kcJLtW2d~%z$t0qMe(%2qG`iF9K_Gsae7OO%Tf8E>ooch ztAw01`WVv6?*14e1w%Wovtj7jz_)4bGAqqo zvTD|B4)Ls8x7-yr6%tYp)A7|A)x{WcI&|&DTQR&2ir(KGR7~_RhNOft)wS<+vQ*|sf;d>s zEfl&B^*ZJp$|N`w**cXOza8(ARhJT{O3np#OlfxP9Nnle4Sto)Fv{w6ifKIN^f1qO*m8+MOgA1^Du!=(@MAh8)@wU8t=Ymh!iuT_lzfm za~xEazL-0xwy9$48!+?^lBwMV{!Gx)N>}CDi?Jwax^YX@_bxl*+4itP;DrTswv~n{ zZ0P>@EB({J9ZJ(^|ptn4ks^Z2UI&87d~J_^z0&vD2yb%*H^AE!w= zm&FiH*c%vvm{v&i3S>_hacFH${|(2+q!`X~zn4$aJDAry>=n|{C7le(0a)nyV{kAD zlud4-6X>1@-XZd`3SKKHm*XNn_zCyKHmf*`C_O509$iy$Wj`Sm3y?nWLCDy>MUx1x zl-sz7^{m(&NUk*%_0(G^>wLDnXW90FzNi$Tu6* z<+{ePBD`%IByu977rI^x;gO5M)Tfa-l*A2mU-#IL2?+NXK-?np<&2rlF;5kaGGrx2 zy8Xrz`kHtTVlSSlC=nlV4_oCsbwyVHG4@Adb6RWzd|Otr!LU=% zEjM5sZ#Ib4#jF(l!)8Na%$5VK#tzS>=05GpV?&o* z3goH1co0YR=)98rPJ~PuHvkA59KUi#i(Mq_$rApn1o&n1mUuZfFLjx@3;h`0^|S##QiTP8rD`r8P+#D@gvDJh>amMIl065I)PxT6Hg(lJ?X7*|XF2Le zv36p8dWHCo)f#C&(|@i1RAag->5ch8TY!LJ3(+KBmLxyMA%8*X%_ARR*!$AL66nF= z=D}uH)D)dKGZ5AG)8N-;Il*-QJ&d8u30&$_Q0n1B58S0ykyDAyGa+BZ>FkiOHm1*& zNOVH;#>Hg5p?3f(7#q*dL74;$4!t?a#6cfy#}9H3IFGiCmevir5@zXQj6~)@zYrWZ zRl*e66rjwksx-)Flr|Kzd#Bg>We+a&E{h7bKSae9P~ z(g|zuXmZ zD?R*MlmoZ##+0c|cJ(O{*h(JtRdA#lChYhfsx25(Z`@AK?Q-S8_PQqk z>|Z@Ki1=wL1_c6giS%E4YVYD|Y-{^ZzFwB*yN8-4#+TxeQ`jhks7|SBu7X|g=!_XL z`mY=0^chZfXm%2DYHJ4z#soO7=NONxn^K3WX={dV>$CTWSZe@<81-8DVtJEw#Uhd3 zxZx+($6%4a&y_rD8a&E`4$pD6-_zZJ%LEE*1|!9uOm!kYXW< zOBXZAowsX-&$5C`xgWkC43GcnY)UQt2Qkib4!!8Mh-Q!_M%5{EC=Gim@_;0+lP%O^ zG~Q$QmatQk{Mu&l{q~#kOD;T-{b1P5u7)o-QPPnqi?7~5?7%IIFKdj{;3~Hu#iS|j z)Zoo2wjf%+rRj?vzWz(6JU`=7H}WxLF*|?WE)ci7aK?SCmd}pMW<{#1Z!_7BmVP{w zSrG>?t}yNyCR%ZFP?;}e8_ zRy67~&u11TN4UlopWGj6IokS{vB!v!n~TJYD6k?~XQkpiPMUGLG2j;lh>Eb5bLTkX zx>CZlXdoJsiPx=E48a4Fkla>8dZYB%^;Xkd(BZK$z3J&@({A`aspC6$qnK`BWL;*O z-nRF{XRS`3Y&b+}G&|pE1K-Ll_NpT!%4@7~l=-TtYRW0JJ!s2C-_UsRBQ=v@VQ+4> z*6jF0;R@5XLHO^&PFyaMDvyo?-lAD(@H61l-No#t@at@Le9xOgTFqkc%07KL^&iss z!S2Ghm)u#26D(e1Q7E;L`rxOy-N{kJ zTgfw}az9=9Su?NEMMtpRlYwDxUAUr8F+P=+9pkX4%iA4&&D<|=B|~s*-U+q6cq`y* zIE+;2rD7&D5X;VAv=5rC5&nP$E9Z3HKTqIFCEV%V;b)Y|dY?8ySn|FD?s3IO>VZ&&f)idp_7AGnwVd1Z znBUOBA}~wogNpEWTt^1Rm-(YLftB=SU|#o&pT7vTr`bQo;=ZqJHIj2MP{JuXQPV7% z0k$5Ha6##aGly<}u>d&d{Hkpu?ZQeL_*M%A8IaXq2SQl35yW9zs4^CZheVgHF`%r= zs(Z|N!gU5gj-B^5{*sF>;~fauKVTq-Ml2>t>E0xl9wywD&nVYZfs1F9Lq}(clpNLz z4O(gm_i}!k`wUoKr|H#j#@XOXQ<#eDGJ=eRJjhOUtiKOG;hym-1Hu)1JYj+Kl*To<8( za1Kf4_Y@Cy>eoC59HZ4o&xY@!G(2p^=wTCV>?rQE`Upo^pbhWdM$WP4HFdDy$HiZ~ zRUJFWTII{J$GLVWR?miDjowFk<1#foE3}C2AKTNFku+BhLUuT>?PATB?WVLzEYyu+ zM*x((pGdotzLJ{}R=OD*jUexKi`mb1MaN0Hr(Wk8-Uj0zA;^1w2rmxLI$qq68D>^$ zj@)~T1l@K|~@YJ6+@1vlWl zHg5g%F{@fW5K!u>4LX8W;ua(t6YCCO_oNu}IIvI6>Fo@MilYuwUR?9p)rKNzDmTAN zzN2d>=Za&?Z!rJFV*;mJ&-sBV80%<-HN1;ciLb*Jk^p?u<~T25%7jjFnorfr={+wm zzl5Q6O>tsN8q*?>uSU6#xG}FpAVEQ_++@}G$?;S7owlK~@trhc#C)TeIYj^N(R&a} zypm~c=fIs;M!YQrL}5{xl=tUU-Tfc0ZfhQuA-u5(*w5RXg!2kChQRd$Fa8xQ0CQIU zC`cZ*!!|O!*y1k1J^m8IIi|Sl3R}gm@CC&;4840^9_bb9%&IZTRk#=^H0w%`5pMDCUef5 zYt-KpWp2ijh+FM`!zZ35>+7eLN;s3*P!bp%-oSx34fdTZ14Tsf2v7ZrP+mitUx$rS zW(sOi^CFxe$g3$x45snQwPV5wpf}>5OB?}&Gh<~i(mU&ss#7;utaLZ!|KaTHniGO9 zVC9OTzuMKz)afey_{93x5S*Hfp$+r*W>O^$2ng|ik!<`U1pkxm3*)PH*d#>7md1y} zs7u^a8zW8bvl92iN;*hfOc-=P7{lJeJ|3=NfX{(XRXr;*W3j845SKG&%N zuBqCtDWj*>KooINK1 zFPCsCWr!-8G}G)X*QM~34R*k zmRmDGF*QE?jCeNfc?k{w<}@29e}W|qKJ1K|AX!htt2|B`nL=HkC4?1bEaHtGBg}V( zl(A`6z*tck_F$4;kz-TNF%7?=20iqQo&ohf@S{_!TTXnVh}FaW2jxAh(DI0f*SDG- z7tqf5X@p#l?7pUNI(BGi>n_phw=lDm>2OgHx-{`T>KP2YH9Gm5ma zb{>7>`tZ>0d5K$j|s2!{^sFWQo3+xDb~#=9-jp(1ydI3_&RXGB~rxWSMgDCGQG)oNoc#>)td zqE|X->35U?_M6{^lB4l(HSN|`TC2U*-`1jSQeiXPtvVXdN-?i1?d#;pw%RfQuKJ|e zjg75M+Q4F0p@8I3ECpBhGs^kK;^0;7O@MV=sX^EJLVJf>L;GmO z3}EbTcoom7QbI(N8ad!z(!6$!MzKaajSRb0c+ZDQ($kFT&&?GvXmu7+V3^_(VJx1z zP-1kW_AB&_A;cxm*g`$ z#Pl@Cg{siF0ST2-w)zJkzi@X)5i@)Z;7M5ewX+xcY36IaE0#flASPY2WmF8St0am{ zV|P|j9wqcMi%r-TaU>(l*=HxnrN?&qAyzimA@wtf;#^%{$G7i4nXu=Pp2#r@O~wi)zB>@25A*|axl zEclXBlXx1LP3x0yrSx@s-kVW4qlF+idF+{M7RG54CgA&soDU-3SfHW@-6_ z+*;{n_SixmGCeZjHmEE!IF}!#aswth_{zm5Qhj0z-@I}pR?cu=P)HJUBClC;U+9;$#@xia30o$% zDw%BgOl>%vRenxL#|M$s^9X}diJ9q7wI1-0n2#6>@q}rK@ng(4M68(t52H_Jc{f&M9NPxRr->vj-88hoI?pvpn}llcv_r0`;uN>wuE{ z&TOx_i4==o;)>V4vCqG)A!mW>dI^Ql8BmhOy$6^>OaUAnI3>mN!Zr#qo4A>BegYj` zNG_)2Nvy2Cqxs1SF9A5HHhL7sai#Umw%K@+riaF+q)7&MUJvA&;$`(w)+B@c6!kX@ zzuY;LGu6|Q2eu^06PzSLspV2v4E?IPf`?Su_g8CX!75l)PCvyWKi4YRoRThB!-BhG zubQ#<7oCvj@z`^y&mPhSlbMf0<;0D z?5&!I?nV-jh-j1g~&R(YL@c=KB_gNup$8abPzXZN`N|WLqxlN)ZJ+#k4UWq#WqvVD z^|j+8f5uxTJtgcUscKTqKcr?5g-Ih3nmbvWvvEk})u-O}h$=-p4WE^qq7Z|rLas0$ zh0j&lhm@Rk(6ZF0_6^>Rd?Ni-#u1y`;$9tS;~!ph8T7fLlYE{P=XtWfV0Ql z#z{_;A%p|8+LhbZT0D_1!b}}MBx9`R9uM|+*`4l3^O(>Mk%@ha>VDY=nZMMb2TnJ= zGlQ+#+pmE98zuFxwAQcVkH1M887y;Bz&EJ7chIQQe!pgWX>(2ruI(emhz@_6t@k8Z zqFEyJFX2PO`$gJ6p$=ku{7!vR#u+$qo|1r;orjtp9FP^o2`2_vV;W&OT)acRXLN^m zY8a;geAxg!nbVu|uS8>@Gvf@JoL&GP`2v4s$Y^5vE32&l;2)`S%e#AnFI-YY7_>d#IKJI!oL6e z_7W3e=-0iz{bmuB*HP+D{Nb;rn+RyimTFqNV9Bzpa0?l`pWmR0yQOu&9c0S*1EPr1 zdoHMYlr>BycjTm%WeVuFd|QF8I{NPT&`fm=dITj&3(M^q ze2J{_2zB;wDME%}SzVWSW6)>1QtiX)Iiy^p2eT}Ii$E9w$5m)kv(3wSCNWq=#DaKZ zs%P`#^b7F-J0DgQ1?~2M`5ClYtYN{AlU|v4pEg4z03=g6nqH`JjQuM{k`!6jaIL_F zC;sn?1x?~uMo_DFg#ypNeie{3udcm~M&bYJ1LI zE%y}P9oCX3I1Y9yhF(y9Ix_=8L(p)EYr&|XZWCOb$7f2qX|A4aJ9bl7pt40Xr zXUT#NMBB8I@xoIGSHAZkYdCj>eEd#>a;W-?v4k%CwBaR5N>e3IFLRbDQTH#m_H+4b zk2UHVymC`%IqwtHUmpS1!1p-uQB`CW1Y!+VD!N4TT}D8(V0IOL|&R&)Rwj@n8g@=`h&z9YTPDT+R9agnwPuM!JW~=_ya~% zIJ*>$Fl;y7_`B7G4*P!kcy=MnNmR`(WS5_sRsvHF42NJ;EaDram5HwQ4Aw*qbYn0j;#)bh1lyKLg#dYjN*BMlh+fxmCL~?zB;HBWho;20WA==ci0mAqMfyG>1!HW zO7rOga-I9bvut1Ke_1eFo9tbzsoPTXDW1Si4}w3fq^Z|5LGf&egnw%DV=b11$F=P~ z(aV+j8S}m=CkI*8=RcrT>GmuYifP%hCoKY22Z4 zmu}o08h3YhcXx-v-QC??8mDn<+}+*X{+gZH-I;G^|7=1fBveS?J$27H&wV5^V^P$! z84?{UeYSmZ3M!@>UFoIN?GJT@IroYr;X@H~ax*CQ>b5|Xi9FXt5j`AwUPBq`0sWEJ z3O|k+g^JKMl}L(wfCqyMdRj9yS8ncE7nI14Tv#&(?}Q7oZpti{Q{Hw&5rN-&i|=fWH`XTQSu~1jx(hqm$Ibv zRzFW9$xf@oZAxL~wpj<0ZJ3rdPAE=0B>G+495QJ7D>=A&v^zXC9)2$$EnxQJ<^WlV zYKCHb1ZzzB!mBEW2WE|QG@&k?VXarY?umPPQ|kziS4{EqlIxqYHP!HN!ncw6BKQzKjqk!M&IiOJ9M^wc~ZQ1xoaI z;4je%ern~?qi&J?eD!vTl__*kd*nFF0n6mGEwI7%dI9rzCe~8vU1=nE&n4d&8}pdL zaz`QAY?6K@{s2x%Sx%#(y+t6qLw==>2(gb>AksEebXv=@ht>NBpqw=mkJR(c?l7vo z&cV)hxNoYPGqUh9KAKT)kc(NqekzE6(wjjotP(ac?`DJF=Sb7^Xet-A3PRl%n&zKk zruT9cS~vV1{%p>OVm1-miuKr<@rotj*5gd$?K`oteNibI&K?D63RoBjw)SommJ5<4 zus$!C8aCP{JHiFn2>XpX&l&jI7E7DcTjzuLYvON2{rz<)#$HNu(;ie-5$G<%eLKnTK7QXfn(UR(n+vX%aeS6!q6kv z!3nzY76-pdJp339zsl_%EI|;ic_m56({wdc(0C5LvLULW=&tWc5PW-4;&n+hm1m`f zzQV0T>OPSTjw=Ox&UF^y< zarsYKY8}YZF+~k70=olu$b$zdLaozBE|QE@H{_R21QlD5BilYBTOyv$D5DQZ8b1r- zIpSKX!SbA0Pb5#cT)L5!KpxX+x+8DRy&`o-nj+nmgV6-Gm%Fe91R1ca3`nt*hRS|^ z<&we;TJcUuPDqkM7k0S~cR%t7a`YP#80{BI$e=E!pY}am)2v3-Iqk2qvuAa1YM>xj#bh+H2V z{b#St2<;Gg>$orQ)c2a4AwD5iPcgZ7o_}7xhO86(JSJ(q(EWKTJDl|iBjGEMbX8|P z4PQHi+n(wZ_5QrX0?X_J)e_yGcTM#E#R^u_n8pK@l5416`c9S=q-e!%0RjoPyTliO zkp{OC@Ep^#Ig-n!C)K0Cy%8~**Vci8F1U(viN{==KU0nAg2(+K+GD_Gu#Bx!{tmUm zCwTrT(tCr6X8j43_n96H9%>>?4akSGMvgd+krS4wRexwZ1JxrJy!Uhz#yt$-=aq?A z@?*)bRZxjG9OF~7d$J0cwE_^CLceRK=LvjfH-~{S><^D;6B2&p-02?cl?|$@>`Qt$ zP*iaOxg<+(rbk>34VQDQpNQ|a9*)wScu!}<{oXC87hRPqyrNWpo?#=;1%^D2n2+C* zKKQH;?rWn-@%Y9g%NHG&lHwK9pBfV1a`!TqeU_Fv8s6_(@=RHua7`VYO|!W&WL*x= zIWE9eQaPq3zMaXuf)D0$V`RIZ74f)0P73xpeyk4)-?8j;|K%pD$eq4j2%tL=;&+E91O(2p91K|85b)GQcbRe&u6Ilu@SnE={^{Ix1Eqgv8D z4=w65+&36|;5WhBm$!n*!)ACCwT9Sip#1_z&g~E1kB=AlEhO0lu`Ls@6gw*a)lzc# zKx!fFP%eSBBs)U>xIcQKF(r_$SWD3TD@^^2Ylm=kC*tR+I@X>&SoPZdJ2fT!ysjH% z-U%|SznY8Fhsq7Vau%{Ad^Pvbf3IqVk{M2oD+w>MWimJA@VSZC$QooAO3 zC=DplXdkyl>mSp^$zk7&2+eoGQ6VVh_^E#Z3>tX7Dmi<2aqlM&YBmK&U}m>a%8)LQ z8v+c}a0QtXmyd%Kc2QNGf8TK?_EK4wtRUQ*VDnf5jHa?VvH2K(FDZOjAqYufW8oIZ z31|o~MR~T;ZS!Lz%8M0*iVARJ>_G2BXEF8(}6Dmn_rFV~5NI`lJjp`Mi~g7~P%H zO`S&-)Fngo3VXDMo7ImlaZxY^s!>2|csKca6!|m7)l^M0SQT1_L~K29%x4KV8*xiu zwP=GlyIE9YPSTC0BV`6|#)30=hJ~^aYeq7d6TNfoYUkk-^k0!(3qp(7Mo-$|48d8Z2d zrsfsRM)y$5)0G`fNq!V?qQ+nh0xwFbcp{nhW%vZ?h);=LxvM(pWd9FG$Bg1;@Bv)mKDW>AP{ol zD(R~mLzdDrBv$OSi{E%OD`Ano=F^vwc)rNb*Bg3-o)bbAgYE=M7Gj2OHY{8#pM${_^ zwkU|tnTKawxUF7vqM9UfcQ`V49zg78V%W)$#5ssR}Rj7E&p(4_ib^?9luZPJ%iJTvW&-U$nFYky>KJwHpEHHx zVEC;!ETdkCnO|${Vj#CY>LLut_+c|(hpWk8HRgMGRY%E--%oKh@{KnbQ~0GZd}{b@ z`J2qHBcqqjfHk^q=uQL!>6HSSF3LXL*cCd%opM|k#=xTShX~qcxpHTW*BI!c3`)hQq{@!7^mdUaG7sFsFYnl1%blslM;?B8Q zuifKqUAmR=>33g~#>EMNfdye#rz@IHgpM$~Z7c5@bO@S>MyFE3_F}HVNLnG0TjtXU zJeRWH^j5w_qXb$IGs+E>daTa}XPtrUnnpTRO9NEx4g6uaFEfHP9gW;xZnJi{oqAH~ z5dHS(ch3^hbvkv@u3QPLuWa}ImaElDrmIc%5HN<^bwej}3+?g) z-ai7D&6Iq_P(}k`i^4l?hRLbCb>X9iq2UYMl=`9U9Rf=3Y!gnJbr?eJqy>Zpp)m>Ae zcQ4Qfs&AaE?UDTODcEj#$_n4KeERZHx-I+E5I~E#L_T3WI3cj$5EYR75H7hy%80a8Ej?Y6hv+fR6wHN%_0$-xL!eI}fdjOK7(GdFD%`f%-qY@-i@fTAS&ETI99jUVg8 zslPSl#d4zbOcrgvopvB2c2A6r^pEr&Sa5I5%@1~BpGq`Wo|x=&)WnnQjE+)$^U-wW zr2Kv?XJby(8fcn z8JgPn)2_#-OhZ+;72R6PspMfCVvtLxFHeb7d}fo(GRjm_+R(*?9QRBr+yPF(iPO~ zA4Tp1<0}#fa{v0CU6jz}q9;!3Pew>ikG1qh$5WPRTQZ~ExQH}b1hDuzRS1}65uydS z~Te*3@?o8fih=mZ`iI!hL5iv3?VUBLQv0X zLtu58MIE7Jbm?)NFUZuMN2_~eh_Sqq*56yIo!+d_zr@^c@UwR&*j!fati$W<=rGGN zD$X`$lI%8Qe+KzBU*y3O+;f-Csr4$?3_l+uJ=K@dxOfZ?3APc5_x2R=a^kLFoxt*_ z4)nvvP+(zwlT5WYi!4l7+HKqzmXKYyM9kL5wX$dTSFSN&)*-&8Q{Q$K-})rWMin8S zy*5G*tRYNqk7&+v;@+>~EIQgf_SB;VxRTQFcm5VtqtKZ)x=?-f+%OY(VLrXb^6*aP zP&0Nu@~l2L!aF8i2!N~fJiHyxRl?I1QNjB)`uP_DuaU?2W;{?0#RGKTr2qH5QqdhK zP__ojm4WV^PUgmrV)`~f>(769t3|13DrzdDeXxqN6XA|_GK*;zHU()a(20>X{y-x| z2P6Ahq;o=)Nge`l+!+xEwY`7Q(8V=93A9C+WS^W%p&yR)eiSX+lp)?*7&WSYSh4i> zJa6i5T9o;Cd5z%%?FhB?J{l+t_)c&_f86gZMU{HpOA=-KoU5lIL#*&CZ_66O5$3?# ztgjGLo`Y7bj&eYnK#5x1trB_6tpu4$EomotZLb*9l6P(JmqG`{z$?lNKgq?GAVhkA zvw!oFhLyX=$K=jTAMwDQ)E-8ZW5$X%P2$YB5aq!VAnhwGv$VR&;Ix#fu%xlG{|j_K zbEYL&bx%*YpXcaGZj<{Y{k@rsrFKh7(|saspt?OxQ~oj_6En(&!rTZPa7fLCEU~mA zB7tbVs=-;cnzv*#INgF_9f3OZhp8c5yk!Dy1+`uA7@eJfvd~g34~wKI1PW%h(y&nA zRwMni12AHEw36)C4Tr-pt6s82EJa^8N#bjy??F*rg4fS@?6^MbiY3;7x=gd~G|Hi& zwmG+pAn!aV>>nNfP7-Zn8BLbJm&7}&ZX+$|z5*5{{F}BRSxN=JKZTa#{ut$v0Z0Fs za@UjXo#3!wACv+p9k*^9^n+(0(YKIUFo`@ib@bjz?Mh8*+V$`c%`Q>mrc5bs4aEf4 zh0qtL1qNE|xQ9JrM}qE>X>Y@dQ?%` zBx(*|1FMzVY&~|dE^}gHJ37O9bjnk$d8vKipgcf+As(kt2cbxAR3^4d0?`}}hYO*O z{+L&>G>AYaauAxE8=#F&u#1YGv%`d*v+EyDcU2TnqvRE33l1r}p#Vmcl%n>NrYOqV z2Car_^^NsZ&K=a~bj%SZlfxzHAxX$>=Q|Zi;E0oyfhgGgqe1Sd5-E$8KV9=`!3jWZCb2crb;rvQ##iw}xm7Da za!H${ls5Ihwxkh^D)M<4Yy3bp<-0a+&KfV@CVd9X6Q?v)$R3*rfT@jsedSEhoV(vqv?R1E8oWV;_{l_+_6= zLjV^-bZU$D_ocfSpRxDGk*J>n4G6s-e>D8JK6-gA>aM^Hv8@)txvKMi7Pi#DS5Y?r zK0%+L;QJdrIPXS2 ztjWAxkSwt2xG$L)Zb7F??cjs!KCTF+D{mZ5e0^8bdu_NLgFHTnO*wx!_8#}NO^mu{FaYeCXGjnUgt_+B-Ru!2_Ue-0UPg2Y)K3phLmR<4 zqUCWYX!KDU!jYF6c?k;;vF@Qh^q(PWwp1ez#I+0>d7V(u_h|L+kX+MN1f5WqMLn!L z!c(pozt7tRQi&duH8n=t-|d)c^;%K~6Kpyz(o53IQ_J+aCapAif$Ek#i0F9U>i+94 zFb=OH5(fk-o`L(o|DyQ(hlozl*2cu#)Y(D*zgNMi1Z!DTex#w#)x(8A-T=S+eByJW z%-k&|XhdZOWjJ&(FTrZNWRm^pHEot_MRQ_?>tKQ&MB~g(&D_e>-)u|`Ot(4j=UT6? zQ&YMi2UnCKlBpwltP!}8a2NJ`LlfL=k8SQf69U)~=G;bq9<2GU&Q#cHwL|o4?ah1` z;fG)%t0wMC;DR?^!jCoKib_iiIjsxCSxRUgJDCE%0P;4JZhJCy)vR1%zRl>K?V6#) z2lDi*W3q9rA zo;yvMujs+)a&00~W<-MNj=dJ@4%tccwT<@+c$#CPR%#aE#Dra+-5eSDl^E>is2v^~ z8lgRwkpeU$|1LW4yFwA{PQ^A{5JY!N5PCZ=hog~|FyPPK0-i;fCl4a%1 z?&@&E-)b4cK)wjXGq|?Kqv0s7y~xqvSj-NpOImt{Riam*Z!wz-coZIMuQU>M%6ben z>P@#o^W;fizVd#?`eeEPs#Gz^ySqJn+~`Pq%-Ee6*X+E>!PJGU#rs6qu0z5{+?`-N zxf1#+JNk7e6AoJTdQwxs&GMTq?Djch_8^xL^A;9XggtGL>!@0|BRuIdE&j$tzvt7I zr@I@0<0io%lpF697s1|qNS|BsA>!>-9DVlgGgw2;;k;=7)3+&t!);W3ulPgR>#JiV zUerO;WxuJqr$ghj-veVGfKF?O7si#mzX@GVt+F&atsB@NmBoV4dK|!owGP005$7LN7AqCG(S+={YA- zn#I{UoP_$~Epc=j78{(!2NLN)3qSm-1&{F&1z4Dz&7Mj_+SdlR^Q5{J=r822d4A@?Rj~xATaWewHUOus{*C|KoH`G zHB8SUT06GpSt)}cFJ18!$Kp@r+V3tE_L^^J%9$&fcyd_AHB)WBghwqBEWW!oh@StV zDrC?ttu4#?Aun!PhC4_KF1s2#kvIh~zds!y9#PIrnk9BWkJpq}{Hlqi+xPOR&A1oP zB0~1tV$Zt1pQuHpJw1TAOS=3$Jl&n{n!a+&SgYVe%igUtvE>eHqKY0`e5lwAf}2x( zP>9Wz+9uirp7<7kK0m2&Y*mzArUx%$CkV661=AIAS=V=|xY{;$B7cS5q0)=oq0uXU z_roo90&gHSfM6@6kmB_FJZ)3y_tt0}7#PA&pWo@_qzdIMRa-;U*Dy>Oo#S_n61Fn! z%mrH%tRmvQvg%UqN_2(C#LSxgQ>m}FKLGG=uqJQuSkk=S@c~QLi4N+>lr}QcOuP&% zQCP^cRk&rk-@lpa0^Lcvdu`F*qE)-0$TnxJlwZf|dP~s8cjhL%>^+L~{umxl5Xr6@ z^7zVKiN1Xg;-h+kr4Yt2BzjZs-Mo54`pDbLc}fWq{34=6>U9@sBP~iWZE`+FhtU|x zTV}ajn*Hc}Y?3agQ+bV@oIRm=qAu%|zE;hBw7kCcDx{pm!_qCxfPX3sh5^B$k_2d` z6#rAeUZC;e-LuMZ-f?gHeZogOa*mE>ffs+waQ+fQl4YKoAyZii_!O0;h55EMzD{;) z8lSJvv((#UqgJ?SCQFqJ-UU?2(0V{;7zT3TW`u6GH6h4m3}SuAAj_K(raGBu>|S&Q zZGL?r9@caTbmRm7p=&Tv?Y1)60*9At38w)$(1c?4cpFY2RLyw9c<{OwQE{b@WI}FQ zTT<2HOF4222d%k70yL~x_d#6SNz`*%@4++8gYQ8?yq0T@w~bF@aOHL2)T4xj`AVps9k z?m;<2ClJh$B6~fOYTWIV*T9y1BpB1*C?dgE{%lVtIjw>4MK{wP6OKTb znbPWrkZjYCbr`GGa%Xo0h;iFPNJBI3fK5`wtJV?wq_G<_PZ<`eiKtvN$IKfyju*^t zXc}HNg>^PPZ16m6bfTpmaW5=qoSsj>3)HS}teRa~qj+Y}mGRE?cH!qMDBJ8 zJB!&-=MG8Tb;V4cZjI_#{>ca0VhG_P=j0kcXVX5)^Sdpk+LKNv#yhpwC$k@v^Am&! z_cz2^4Cc{_BC!K#zN!KEkPzviUFPJ^N_L-kHG6}(X#$>Q=9?!{$A(=B3)P?PkxG9gs#l! zo6TOHo$F|IvjTC3MW%XrDoc7;m-6wb9mL(^2(>PQXY53hE?%4FW$rTHtN`!VgH72U zRY)#?Y*pMA<)x3B-&fgWQ(TQ6S6nUeSY{9)XOo_k=j$<*mA=f+ghSALYwBw~!Egn!jtjubOh?6Cb-Zi3IYn*fYl()^3u zRiX0I{5QaNPJ9w{yh4(o#$geO7b5lSh<5ZaRg9_=aFdZjxjXv(_SCv^v-{ZKQFtAA}kw=GPC7l81GY zeP@0Da{aR#{6`lbI0ON0y#K=t|L*}MG_HSl$e{U;v=BSs{SU3(e*qa(l%rD;(zM^3 zrRgN3M#Sf(Cr9>v{FtB`8JBK?_zO+~{H_0$lLA!l{YOs9KQd4Zt<3*Ns7dVbT{1Ut z?N9{XkN(96?r(4BH~3qeiJ_CAt+h1}O_4IUF$S(5EyTyo=`{^16P z=VhDY!NxkDukQz>T`0*H=(D3G7Np*2P`s(6M*(*ZJa;?@JYj&_z`d5bap=KK37p3I zr5#`%aC)7fUo#;*X5k7g&gQjxlC9CF{0dz*m2&+mf$Sc1LnyXn9lpZ!!Bl!@hnsE5px};b-b-`qne0Kh;hziNC zXV|zH%+PE!2@-IrIq!HM2+ld;VyNUZiDc@Tjt|-1&kq}>muY;TA3#Oy zWdYGP3NOZWSWtx6?S6ES@>)_Yz%%nLG3P>Z7`SrhkZ?shTfrHkYI;2zAn8h65wV3r z^{4izW-c9!MTge3eN=~r5aTnz6*6l#sD68kJ7Nv2wMbL~Ojj0H;M`mAvk*`Q!`KI? z7nCYBqbu$@MSNd+O&_oWdX()8Eh|Z&v&dJPg*o-sOBb2hriny)< zd(o&&kZM^NDtV=hufp8L zCkKu7)k`+czHaAU567$?GPRGdkb4$37zlIuS&<&1pgArURzoWCbyTEl9OiXZBn4p<$48-Gekh7>e)v*?{9xBt z=|Rx!@Y3N@ffW5*5!bio$jhJ7&{!B&SkAaN`w+&3x|D^o@s{ZAuqNss8K;211tUWIi1B!%-ViYX+Ys6w)Q z^o1{V=hK#+tt&aC(g+^bt-J9zNRdv>ZYm9KV^L0y-yoY7QVZJ_ivBS02I|mGD2;9c zR%+KD&jdXjPiUv#t1VmFOM&=OUE2`SNm4jm&a<;ZH`cYqBZoAglCyixC?+I+}*ScG#;?SEAFob{v0ZKw{`zw*tX}<2k zoH(fNh!>b5w8SWSV}rQ*E24cO=_eQHWy8J!5;Y>Bh|p;|nWH|nK9+ol$k`A*u*Y^Uz^%|h4Owu}Cb$zhIxlVJ8XJ0xtrErT zcK;34CB;ohd|^NfmVIF=XlmB5raI}nXjFz;ObQ4Mpl_`$dUe7sj!P3_WIC~I`_Xy@ z>P5*QE{RSPpuV=3z4p3}dh>Dp0=We@fdaF{sJ|+_E*#jyaTrj-6Y!GfD@#y@DUa;& zu4Iqw5(5AamgF!2SI&WT$rvChhIB$RFFF|W6A>(L9XT{0%DM{L`knIQPC$4F`8FWb zGlem_>>JK-Fib;g*xd<-9^&_ue95grYH>5OvTiM;#uT^LVmNXM-n8chJBD2KeDV7t zbnv3CaiyN>w(HfGv86K5MEM{?f#BTR7**smpNZ}ftm+gafRSt=6fN$(&?#6m3hF!>e$X)hFyCF++Qvx(<~q3esTI zH#8Sv!WIl2<&~=B)#sz1x2=+KTHj=0v&}iAi8eD=M->H|a@Qm|CSSzH#eVIR3_Tvu zG8S**NFbz%*X?DbDuP(oNv2;Lo@#_y4k$W+r^#TtJ8NyL&&Rk;@Q}~24`BB)bgwcp z=a^r(K_NEukZ*|*7c2JKrm&h&NP)9<($f)eTN}3|Rt`$5uB0|!$Xr4Vn#i;muSljn zxG?zbRD(M6+8MzGhbOn%C`M#OcRK!&ZHihwl{F+OAnR>cyg~No44>vliu$8^T!>>*vYQJCJg=EF^lJ*3M^=nGCw`Yg@hCmP(Gq^=eCEE1!t-2>%Al{w@*c% zUK{maww*>K$tu;~I@ERb9*uU@LsIJ|&@qcb!&b zsWIvDo4#9Qbvc#IS%sV1_4>^`newSxEcE08c9?rHY2%TRJfK2}-I=Fq-C)jc`gzV( zCn?^noD(9pAf2MP$>ur0;da`>Hr>o>N@8M;X@&mkf;%2A*2CmQBXirsJLY zlX21ma}mKH_LgYUM-->;tt;6F?E5=fUWDwQhp*drQ%hH0<5t2m)rFP%=6aPIC0j$R znGI0hcV~}vk?^&G`v~YCKc7#DrdMM3TcPBmxx#XUC_JVEt@k=%3-+7<3*fTcQ>f~?TdLjv96nb66xj=wVQfpuCD(?kzs~dUV<}P+Fpd)BOTO^<*E#H zeE80(b~h<*Qgez(iFFOkl!G!6#9NZAnsxghe$L=Twi^(Q&48 zD0ohTj)kGLD){xu%pm|}f#ZaFPYpHtg!HB30>F1c=cP)RqzK2co`01O5qwAP zUJm0jS0#mci>|Nu4#MF@u-%-4t>oUTnn_#3K09Hrwnw13HO@9L;wFJ*Z@=gCgpA@p zMswqk;)PTXWuMC-^MQxyNu8_G-i3W9!MLd2>;cM+;Hf&w| zLv{p*hArp9+h2wsMqT5WVqkkc0>1uokMox{AgAvDG^YJebD-czexMB!lJKWllLoBI zetW2;;FKI1xNtA(ZWys!_un~+834+6y|uV&Lo%dKwhcoDzRADYM*peh{o`-tHvwWIBIXW`PKwS3|M>CW37Z2dr!uJWNFS5UwY4;I zNIy1^sr+@8Fob%DHRNa&G{lm?KWU7sV2x9(Ft5?QKsLXi!v6@n&Iyaz5&U*|hCz+d z9vu60IG<v6+^ZmBs_aN!}p|{f(ikVl&LcB+UY;PPz* zj84Tm>g5~-X=GF_4JrVmtEtm=3mMEL1#z+pc~t^Iify^ft~cE=R0TymXu*iQL+XLX zdSK$~5pglr3f@Lrcp`>==b5Z6r7c=p=@A5nXNacsPfr(5m;~ks@*Wu7A z%WyY$Pt*RAKHz_7cghHuQqdU>hq$vD?plol_1EU(Fkgyo&Q2&2e?FT3;H%!|bhU~D z>VX4-6}JLQz8g3%Bq}n^NhfJur~v5H0dbB^$~+7lY{f3ES}E?|JnoLsAG%l^%eu_PM zEl0W(sbMRB3rFeYG&tR~(i2J0)RjngE`N_Jvxx!UAA1mc7J>9)`c=`}4bVbm8&{A` z3sMPU-!r-8de=P(C@7-{GgB<5I%)x{WfzJwEvG#hn3ict8@mexdoTz*(XX!C&~}L* z^%3eYQ8{Smsmq(GIM4d5ilDUk{t@2@*-aevxhy7yk(wH?8yFz%gOAXRbCYzm)=AsM z?~+vo2;{-jkA%Pqwq&co;|m{=y}y2lN$QPK>G_+jP`&?U&Ubq~T`BzAj1TlC`%8+$ zzdwNf<3suPnbh&`AI7RAYuQ<#!sD|A=ky2?hca{uHsB|0VqShI1G3lG5g}9~WSvy4 zX3p~Us^f5AfXlBZ0hA;mR6aj~Q8yb^QDaS*LFQwg!!<|W!%WX9Yu}HThc7>oC9##H zEW`}UQ%JQ38UdsxEUBrA@=6R-v1P6IoIw8$8fw6F{OSC7`cOr*u?p_0*Jvj|S)1cd z-9T);F8F-Y_*+h-Yt9cQQq{E|y^b@r&6=Cd9j0EZL}Pj*RdyxgJentY49AyC@PM<< zl&*aq_ubX%*pqUkQ^Zsi@DqhIeR&Ad)slJ2g zmeo&+(g!tg$z1ao1a#Qq1J022mH4}y?AvWboI4H028;trScqDQrB36t!gs|uZS9}KG0}DD$ zf2xF}M*@VJSzEJ5>ucf+L_AtN-Ht=34g&C?oPP>W^bwoigIncKUyf61!ce!2zpcNT zj&;rPGI~q2!Sy>Q7_lRX*DoIs-1Cei=Cd=+Xv4=%bn#Yqo@C=V`|QwlF0Y- zONtrwpHQ##4}VCL-1ol(e<~KU9-ja^kryz!g!})y-2S5z2^gE$Isj8l{%tF=Rzy`r z^RcP7vu`jHgHLKUE957n3j+BeE(bf;f)Zw($XaU6rZ26Upl#Yv28=8Y`hew{MbH>* z-sGI6dnb5D&dUCUBS`NLAIBP!Vi!2+~=AU+)^X^IpOEAn#+ab=`7c z%7B|mZ>wU+L;^&abXKan&N)O;=XI#dTV|9OMYxYqLbtT#GY8PP$45Rm2~of+J>>HIKIVn(uQf-rp09_MwOVIp@6!8bKV(C#(KxcW z;Pesq(wSafCc>iJNV8sg&`!g&G55<06{_1pIoL`2<7hPvAzR1+>H6Rx0Ra%4j7H-<-fnivydlm{TBr06;J-Bq8GdE^Amo)ptV>kS!Kyp*`wUx=K@{3cGZnz53`+C zLco1jxLkLNgbEdU)pRKB#Pq(#(Jt>)Yh8M?j^w&RPUueC)X(6`@@2R~PV@G(8xPwO z^B8^+`qZnQr$8AJ7<06J**+T8xIs)XCV6E_3W+al18!ycMqCfV>=rW0KBRjC* zuJkvrv;t&xBpl?OB3+Li(vQsS(-TPZ)Pw2>s8(3eF3=n*i0uqv@RM^T#Ql7(Em{(~%f2Fw|Reg@eSCey~P zBQlW)_DioA*yxxDcER@_=C1MC{UswPMLr5BQ~T6AcRyt0W44ffJG#T~Fk}wU^aYoF zYTayu-s?)<`2H(w+1(6X&I4?m3&8sok^jpXBB<|ZENso#?v@R1^DdVvKoD?}3%@{}}_E7;wt9USgrfR3(wabPRhJ{#1es81yP!o4)n~CGsh2_Yj2F^z|t zk((i&%nDLA%4KFdG96pQR26W>R2^?C1X4+a*hIzL$L=n4M7r$NOTQEo+k|2~SUI{XL{ynLSCPe%gWMMPFLO{&VN2pom zBUCQ(30qj=YtD_6H0-ZrJ46~YY*A;?tmaGvHvS^H&FXUG4)%-a1K~ly6LYaIn+4lG zt=wuGLw!%h=Pyz?TP=?6O-K-sT4W%_|Nl~;k~YA^_`gqfe{Xw=PWn#9f1mNz)sFuL zJbrevo(DPgpirvGMb6ByuEPd=Rgn}fYXqeUKyM+!n(cKeo|IY%p!#va6`D8?A*{u3 zEeWw0*oylJ1X!L#OCKktX2|>-z3#>`9xr~azOH+2dXHRwdfnpri9|xmK^Q~AuY!Fg z`9Xx?hxkJge~)NVkPQ(VaW(Ce2pXEtgY*cL8i4E)mM(iz_vdm|f@%cSb*Lw{WbShh41VGuplex9E^VvW}irx|;_{VK=N_WF39^ zH4<*peWzgc)0UQi4fBk2{FEzldDh5+KlRd!$_*@eYRMMRb1gU~9lSO_>Vh-~q|NTD zL}X*~hgMj$*Gp5AEs~>Bbjjq7G>}>ki1VxA>@kIhLe+(EQS0mjNEP&eXs5)I;7m1a zmK0Ly*!d~Dk4uxRIO%iZ!1-ztZxOG#W!Q_$M7_DKND0OwI+uC;PQCbQ#k#Y=^zQve zTZVepdX>5{JSJb;DX3%3g42Wz2D@%rhIhLBaFmx#ZV8mhya}jo1u{t^tzoiQy=jJp zjY2b7D2f$ZzJx)8fknqdD6fd5-iF8e(V}(@xe)N=fvS%{X$BRvW!N3TS8jn=P%;5j zShSbzsLs3uqycFi3=iSvqH~}bQn1WQGOL4?trj(kl?+q2R23I42!ipQ&`I*&?G#i9 zWvNh8xoGKDt>%@i0+}j?Ykw&_2C4!aYEW0^7)h2Hi7$;qgF3;Go?bs=v)kHmvd|`R z%(n94LdfxxZ)zh$ET8dH1F&J#O5&IcPH3=8o;%>OIT6w$P1Yz4S!}kJHNhMQ1(prc zM-jSA-7Iq=PiqxKSWb+YbLB-)lSkD6=!`4VL~`ExISOh2ud=TI&SKfR4J08Bad&rj zcXxMpcNgOB?w$~L7l^wPcXxw$0=$oV?)`I44)}b#ChS`_lBQhvb6ks?HDr3tFgkg&td19?b8=!sETXtp=&+3T$cCwZe z0nAET-7561gsbBws$TVjP7QxY(NuBYXVn9~9%vyN-B#&tJhWgtL1B<%BTS*-2$xB` zO)cMDHoWsm%JACZF--Pa7oP;f!n%p`*trlpvZ!HKoB={l+-(8O;;eYv2A=ra z3U7rSMCkP_6wAy`l|Se(&5|AefXvV1E#XA(LT!% zjj4|~xlZ-kPLNeQLFyXb%$K}YEfCBvHA-Znw#dZSI6V%3YD{Wj2@utT5Hieyofp6Qi+lz!u)htnI1GWzvQsA)baEuw9|+&(E@p8M+#&fsX@Kf`_YQ>VM+40YLv`3-(!Z7HKYg@+l00WGr779i-%t`kid%e zDtbh8UfBVT3|=8FrNian@aR3*DTUy&u&05x%(Lm3yNoBZXMHWS7OjdqHp>cD>g!wK z#~R{1`%v$IP;rBoP0B0P><;dxN9Xr+fp*s_EK3{EZ94{AV0#Mtv?;$1YaAdEiq5)g zYME;XN9cZs$;*2p63Q9^x&>PaA1p^5m7|W?hrXp2^m;B@xg0bD?J;wIbm6O~Nq^^K z2AYQs@7k)L#tgUkTOUHsh&*6b*EjYmwngU}qesKYPWxU-z_D> zDWr|K)XLf_3#k_9Rd;(@=P^S^?Wqlwert#9(A$*Y$s-Hy)BA0U0+Y58zs~h=YtDKxY0~BO^0&9{?6Nny;3=l59(6ec9j(79M?P1cE zex!T%$Ta-KhjFZLHjmPl_D=NhJULC}i$}9Qt?nm6K6-i8&X_P+i(c*LI3mtl3 z*B+F+7pnAZ5}UU_eImDj(et;Khf-z^4uHwrA7dwAm-e4 zwP1$Ov3NP5ts+e(SvM)u!3aZMuFQq@KE-W;K6 zag=H~vzsua&4Sb$4ja>&cSJ)jjVebuj+?ivYqrwp3!5>ul`B*4hJGrF;!`FaE+wKo z#};5)euvxC1zX0-G;AV@R(ZMl=q_~u8mQ5OYl;@BAkt)~#PynFX#c1K zUQ1^_N8g+IZwUl*n0Bb-vvliVtM=zuMGU-4a8|_8f|2GEd(2zSV?aSHUN9X^GDA8M zgTZW06m*iAy@7l>F3!7+_Y3mj^vjBsAux3$%U#d$BT^fTf-7{Y z_W0l=7$ro5IDt7jp;^cWh^Zl3Ga1qFNrprdu#g=n9=KH!CjLF#ucU5gy6*uASO~|b z7gcqm90K@rqe({P>;ww_q%4}@bq`ST8!0{V08YXY)5&V!>Td)?j7#K}HVaN4FU4DZ z%|7OppQq-h`HJ;rw-BAfH* z1H$ufM~W{%+b@9NK?RAp-$(P0N=b<(;wFbBN0{u5vc+>aoZ|3&^a866X@el7E8!E7 z=9V(Ma**m_{DKZit2k;ZOINI~E$|wO99by=HO{GNc1t?nl8soP@gxk8)WfxhIoxTP zoO`RA0VCaq)&iRDN9yh_@|zqF+f07Esbhe!e-j$^PS57%mq2p=+C%0KiwV#t^%_hH zoO?{^_yk5x~S)haR6akK6d|#2TN& zfWcN zc7QAWl)E9`!KlY>7^DNw$=yYmmRto>w0L(~fe?|n6k2TBsyG@sI)goigj=mn)E)I* z4_AGyEL7?(_+2z=1N@D}9$7FYdTu;%MFGP_mEJXc2OuXEcY1-$fpt8m_r2B|<~Xfs zX@3RQi`E-1}^9N{$(|YS@#{ZWuCxo)91{k>ESD54g_LYhm~vlOK_CAJHeYFfuIVB^%cqCfvpy#sU8Do8u}# z>>%PLKOZ^+$H54o@brtL-hHorSKcsjk_ZibBKBgyHt~L z=T6?e0oLX|h!Z3lbkPMO27MM?xn|uZAJwvmX?Yvp#lE3sQFY)xqet>`S2Y@1t)Z*& z;*I3;Ha8DFhk=YBt~{zp=%%*fEC}_8?9=(-k7HfFeN^GrhNw4e?vx*#oMztnO*&zY zmRT9dGI@O)t^=Wj&Og1R3b%(m*kb&yc;i`^-tqY9(0t!eyOkH<$@~1lXmm!SJllE_ zr~{a&w|8*LI>Z^h!m%YLgKv06Js7j7RaoX}ZJGYirR<#4Mghd{#;38j3|V+&=ZUq#1$ zgZb-7kV)WJUko?{R`hpSrC;w2{qa`(Z4gM5*ZL`|#8szO=PV^vpSI-^K_*OQji^J2 zZ_1142N}zG$1E0fI%uqHOhV+7%Tp{9$bAR=kRRs4{0a`r%o%$;vu!_Xgv;go)3!B#;hC5qD-bcUrKR&Sc%Zb1Y($r78T z=eG`X#IpBzmXm(o6NVmZdCQf6wzqawqI63v@e%3TKuF!cQ#NQbZ^?6K-3`_b=?ztW zA>^?F#dvVH=H-r3;;5%6hTN_KVZ=ps4^YtRk>P1i>uLZ)Ii2G7V5vy;OJ0}0!g>j^ z&TY&E2!|BDIf1}U(+4G5L~X6sQ_e7In0qJmWYpn!5j|2V{1zhjZt9cdKm!we6|Pp$ z07E+C8=tOwF<<}11VgVMzV8tCg+cD_z?u+$sBjwPXl^(Ge7y8-=c=fgNg@FxI1i5Y-HYQMEH z_($je;nw`Otdhd1G{Vn*w*u@j8&T=xnL;X?H6;{=WaFY+NJfB2(xN`G)LW?4u39;x z6?eSh3Wc@LR&yA2tJj;0{+h6rxF zKyHo}N}@004HA(adG~0solJ(7>?LoXKoH0~bm+xItnZ;3)VJt!?ue|~2C=ylHbPP7 zv2{DH()FXXS_ho-sbto)gk|2V#;BThoE}b1EkNYGT8U#0ItdHG>vOZx8JYN*5jUh5Fdr9#12^ zsEyffqFEQD(u&76zA^9Jklbiz#S|o1EET$ujLJAVDYF znX&4%;vPm-rT<8fDutDIPC@L=zskw49`G%}q#l$1G3atT(w70lgCyfYkg7-=+r7$%E`G?1NjiH)MvnKMWo-ivPSQHbk&_l5tedNp|3NbU^wk0SSXF9ohtM zUqXiOg*8ERKx{wO%BimK)=g^?w=pxB1Vu_x<9jKOcU7N;(!o3~UxyO+*ZCw|jy2}V*Z22~KhmvxoTszc+#EMWXTM6QF*ks% zW47#2B~?wS)6>_ciKe1Fu!@Tc6oN7e+6nriSU;qT7}f@DJiDF@P2jXUv|o|Wh1QPf zLG31d>@CpThA+Ex#y)ny8wkC4x-ELYCXGm1rFI=1C4`I5qboYgDf322B_Nk@#eMZ% znluCKW2GZ{r9HR@VY`>sNgy~s+D_GkqFyz6jgXKD)U|*eKBkJRRIz{gm3tUd*yXmR z(O4&#ZA*us6!^O*TzpKAZ#}B5@}?f=vdnqnRmG}xyt=)2o%<9jj>-4wLP1X-bI{(n zD9#|rN#J;G%LJ&$+Gl2eTRPx6BQC6Uc~YK?nMmktvy^E8#Y*6ZJVZ>Y(cgsVnd!tV z!%twMNznd)?}YCWyy1-#P|2Fu%~}hcTGoy>_uawRTVl=(xo5!%F#A38L109wyh@wm zdy+S8E_&$Gjm=7va-b7@Hv=*sNo0{i8B7=n4ex-mfg`$!n#)v@xxyQCr3m&O1Jxg! z+FXX^jtlw=utuQ+>Yj$`9!E<5-c!|FX(~q`mvt6i*K!L(MHaqZBTtuSA9V~V9Q$G? zC8wAV|#XY=;TQD#H;;dcHVb9I7Vu2nI0hHo)!_{qIa@|2}9d ztpC*Q{4Py~2;~6URN^4FBCBip`QDf|O_Y%iZyA0R`^MQf$ce0JuaV(_=YA`knEMXw zP6TbjYSGXi#B4eX=QiWqb3bEw-N*a;Yg?dsVPpeYFS*&AsqtW1j2D$h$*ZOdEb$8n0 zGET4Igs^cMTXWG{2#A7w_usx=KMmNfi4oAk8!MA8Y=Rh9^*r>jEV(-{I0=rc);`Y) zm+6KHz-;MIy|@2todN&F+Yv1e&b&ZvycbTHpDoZ>FIiUn+M-=%A2C(I*^Yx@VKf(Z zxJOny&WoWcyKodkeN^5))aV|-UBFw{?AGo?;NNFFcKzk+6|gYfA#FR=y@?;3IoQ zUMI=7lwo9gV9fRvYi}Nd)&gQw7(K3=a0#p27u6Q)7JlP#A)piUUF8B3Li&38Xk$@| z9OR+tU~qgd3T3322E))eV)hAAHYIj$TmhH#R+C-&E-}5Qd{3B}gD{MXnsrS;{Erv1 z6IyQ=S2qD>Weqqj#Pd65rDSdK54%boN+a?=CkR|agnIP6;INm0A*4gF;G4PlA^3%b zN{H%#wYu|!3fl*UL1~f+Iu|;cqDax?DBkZWSUQodSDL4Es@u6zA>sIm>^Aq-&X#X8 zI=#-ucD|iAodfOIY4AaBL$cFO@s(xJ#&_@ZbtU+jjSAW^g;_w`FK%aH_hAY=!MTjI zwh_OEJ_25zTQv$#9&u0A11x_cGd92E74AbOrD`~f6Ir9ENNQAV2_J2Ig~mHWhaO5a zc>fYG$zke^S+fBupw+klDkiljJAha z6DnTemhkf>hv`8J*W_#wBj-2w(cVtXbkWWtE(3j@!A-IfF?`r$MhVknTs3D1N`rYN zKth9jZtX#>v#%U@^DVN!;ni#n1)U&H_uB{6pcq7$TqXJX!Q0P7U*JUZyclb~)l*DS zOLpoQfW_3;a0S$#V0SOwVeeqE$Hd^L`$;l_~2giLYd?7!gUYIpOs!jqSL~pI)4`YuB_692~A z^T#YYQ_W3Rakk}$SL&{`H8mc{>j+3eKprw6BK`$vSSIn;s31M~YlJLApJ)+Gi1{^- zw96WnT9M0Vr_D=e=a}${raR{(35Q!g+8`}vOFj1e&Or(_wp2U2aVQP0_jP57 z2(R4E(E$n!xl<}Zx38wO;27wuQ`P#_j!}L2 z2qr;As4D4n2X$-Jd_-!fsbu_D(64i;c4cJnP576x_>Q4WNushFwkBV!kVd(AYFXe{ zaqO5`Qfr!#ETmE(B;u_&FITotv~W}QYFCI!&ENKIb1p4fg*Yv1)EDMb==EjHHWM#{ zGMpqb2-LXdHB@D~pE3|+B392Gh4q)y9jBd$a^&cJM60VEUnLtHQD5i-X6PVF>9m_k zDvG3P(?CzdaIrC8s4cu~N9MEb!Tt(g*GK~gIp1Gyeaw3b7#YPx_1T6i zRi#pAMr~PJKe9P~I+ARa$a!K~)t(4LaVbjva1yd;b1Yz2$7MMc`aLmMl(a^DgN(u? zq2o9&Gif@Tq~Yq+qDfx^F*nCnpuPv%hRFc$I!p74*quLt^M}D_rwl10uMTr!)(*=7 zSC5ea@#;l(h87k4T4x)(o^#l76P-GYJA(pOa&F9YT=fS<*O{4agzba^dIrh0hjls<~APlIz9{ zgRY{OMv2s|`;VCoYVj?InYoq^QWuA&*VDyOn@pPvK8l~g#1~~MGVVvtLDt}>id_Z` zn(ihfL?Y}Y4YX335m*Xx(y+bbukchHrM zycIGp#1*K3$!(tgTsMD2VyUSg^yvCwB8*V~sACE(yq2!MS6f+gsxv^GR|Q7R_euYx z&X+@@H?_oQddGxJYS&ZG-9O(X+l{wcw;W7srpYjZZvanY(>Q1utSiyuuonkjh5J0q zGz6`&meSuxixIPt{UoHVupUbFKIA+3V5(?ijn}(C(v>=v?L*lJF8|yRjl-m#^|krg zLVbFV6+VkoEGNz6he;EkP!Z6|a@n8?yCzX9>FEzLnp21JpU0x!Qee}lwVKA})LZJq zlI|C??|;gZ8#fC3`gzDU%7R87KZyd)H__0c^T^$zo@TBKTP*i{)Gp3E0TZ}s3mKSY zix@atp^j#QnSc5K&LsU38#{lUdwj%xF zcx&l^?95uq9on1m*0gp$ruu||5MQo)XaN>|ngV5Jb#^wWH^5AdYcn_1>H~XtNwJd3 zd9&?orMSSuj=lhO?6)Ay7;gdU#E}pTBa5wFu`nejq##Xd71BHzH2XqLA5 zeLEo;9$}~u0pEu@(?hXB_l;{jQ=7m?~mwj-ME~Tw-OHPrR7K2Xq9eCNwQO$hR z3_A?=`FJctNXA#yQEorVoh{RWxJbdQga zU%K##XEPgy?E|K(=o#IPgnbk7E&5%J=VHube|2%!Qp}@LznjE%VQhJ?L(XJOmFVY~ zo-az+^5!Ck7Lo<7b~XC6JFk>17*_dY;=z!<0eSdFD2L?CSp_XB+?;N+(5;@=_Ss3& zXse>@sA7hpq;IAeIp3hTe9^$DVYf&?)={zc9*hZAV)|UgKoD!1w{UVo8D)Htwi8*P z%#NAn+8sd@b{h=O)dy9EGKbpyDtl@NBZw0}+Wd=@65JyQ2QgU}q2ii;ot1OsAj zUI&+Pz+NvuRv#8ugesT<<@l4L$zso0AQMh{we$tkeG*mpLmOTiy8|dNYhsqhp+q*yfZA`Z)UC*(oxTNPfOFk3RXkbzAEPofVUy zZ3A%mO?WyTRh@WdXz+zD!ogo}gbUMV!YtTNhr zrt@3PcP%5F;_SQ>Ui`Gq-lUe&taU4*h2)6RDh@8G1$o!){k~3)DT87%tQeHYdO?B` zAmoJvG6wWS?=0(Cj?Aqj59`p(SIEvYyPGJ^reI z`Hr?3#U2zI7k0=UmqMD35l`>3xMcWlDv$oo6;b`dZq3d!~)W z=4Qk)lE8&>#HV>?kRLOHZYz83{u7?^KoXmM^pazj8`7OwQ=5I!==; zA!uN`Q#n=Drmzg}@^nG!mJp9ml3ukWk96^6*us*;&>s+7hWfLXtl?a}(|-#=P12>A zon1}yqh^?9!;on?tRd6Fk0knQSLl4vBGb87A_kJNDGyrnpmn48lz_%P{* z_G*3D#IR<2SS54L5^h*%=)4D9NPpji7DZ5&lHD|99W86QN_(|aJ<5C~PX%YB`Qt_W z>jF_Os@kI6R!ub4n-!orS(G6~mKL7()1g=Lf~{D!LR7#wRHfLxTjYr{*c{neyhz#U zbm@WBKozE+kTd+h-mgF+ELWqTKin57P;0b){ zii5=(B%S(N!Z=rAFGnM6iePtvpxB_Q9-oq_xH!URn2_d-H~i;lro8r{-g!k-Ydb6_w5K@FOV?zPF_hi z%rlxBv$lQi%bjsu^7KT~@u#*c$2-;AkuP)hVEN?W5MO8C9snj*EC&|M!aK6o12q3+ z8e?+dH17E!A$tRlbJW~GtMDkMPT=m1g-v67q{sznnWOI$`g(8E!Pf!#KpO?FETxLK z2b^8^@mE#AR1z(DT~R3!nnvq}LG2zDGoE1URR=A2SA z%lN$#V@#E&ip_KZL}Q6mvm(dsS?oHoRf8TWL~1)4^5<3JvvVbEsQqSa3(lF*_mA$g zv`LWarC79G)zR0J+#=6kB`SgjQZ2460W zN%lZt%M@=EN>Wz4I;eH>C0VnDyFe)DBS_2{h6=0ZJ*w%s)QFxLq+%L%e~UQ0mM9ud zm&|r){_<*Om%vlT(K9>dE(3AHjSYro5Y1I?ZjMqWyHzuCE0nyCn`6eq%MEt(aY=M2rIzHeMds)4^Aub^iTIT|%*izG4YH;sT`D9MR(eND-SB+e66LZT z2VX)RJsn${O{D48aUBl|(>ocol$1@glsxisc#GE*=DXHXA?|hJT#{;X{i$XibrA}X zFHJa+ssa2$F_UC(o2k2Z0vwx%Wb(<6_bdDO#=a$0gK2NoscCr;vyx?#cF)JjM%;a| z$^GIlIzvz%Hx3WVU481}_e4~aWcyC|j&BZ@uWW1`bH1y9EWXOxd~f-VE5DpueNofN zv7vZeV<*!A^|36hUE;`#x%MHhL(~?eZ5fhA9Ql3KHTWoAeO-^7&|2)$IcD1r5X#-u zN~N0$6pHPhop@t1_d`dO3#TC0>y5jm>8;$F5_A2& zt#=^IDfYv?JjPPTPNx2TL-Lrl82VClQSLWW_$3=XPbH}xM34)cyW5@lnxy=&h%eRq zv29&h^fMoxjsDnmua(>~OnX{Cq!7vM0M4Mr@_18|YuSKPBKUTV$s^So zc}JlAW&bVz|JY#Eyup6Ny{|P_s0Pq;5*tinH+>5Xa--{ z2;?2PBs((S4{g=G`S?B3Ien`o#5DmUVwzpGuABthYG~OKIY`2ms;33SN9u^I8i_H5`BQ%yOfW+N3r|ufHS_;U;TWT5z;b14n1gX%Pn`uuO z6#>Vl)L0*8yl|#mICWQUtgzeFp9$puHl~m&O+vj3Ox#SxQUa?fY*uK?A;00RiFg(G zK?g=7b5~U4QIK`C*um%=Sw=OJ1eeaV@WZ%hh-3<=lR#(Xesk%?)l4p(EpTwPvN99V@TT)!A8SeFTV+frN=r|5l?K#odjijx2nFgc3kI zC$hVs1S-!z9>xn9MZcRk0YXdYlf~8*LfH$IHKD59H&gLz%6 z#mAYSRJufbRi~LRadwM*G!O2>&U<^d`@<)otXZJJxT@G}4kTx0zPDVhVXwiU)$}5Y z`0iV`8EEh&GlUk&VY9m0Mqr*U&|^Bc?FB`<%{x-o0ATntwIA%(YDcxWs$C)%a%d_@ z?fx!Co+@3p7ha$|pWYD}p6#(PG%_h8K7sQjT_P~|3ZEH0DRxa3~bP&&lPMj3C~!H2QD zq>(f^RUFSqf6K3BMBFy$jiuoSE+DhEq$xLDb7{57 z0B|1pSjYJ5F@cHG%qDZ{ogL$P!BK&sR%zD`gbK#9gRZX17EtAJxN% zys^gb2=X9=7HP}N(iRqt(tot2yyeE%s;L}AcMh;~-W~s_eAe!gIUYdQz5j~T)0trh z>#1U$uOyyl%!Pi(gD&)uHe9Q^27_kHyFCC}n^-KL(=OxHqUfex1YS__RJh0m-S>eM zqAk`aSev*z1lI&-?CycgDm=bdQCp}RqS0_d-4Mf&>u2KyGFxKe8JM1N{GNWw0n$FL z1UDp(h0(1I2Jh9I`?IS}h4R~n zRwRz>8?$fFMB2{UPe^$Ifl;Oc>}@Q9`|8DCeR{?LUQLPfaMsxs8ps=D_aAXORZH~< zdcIOca-F;+D3~M+)Vi4h)I4O3<)$65yI)goQ_vk#fb;Uim>UI4Dv9#2b1;N_Wg>-F zNwKeMKY+su#~NL0uE%_$mw1%ddX2Qs2P!ncM+>wnz}OCQX1!q~oS?OqYU;&ESAAwP z452QWL0&u^mraF#=j_ZeBWhm&F|d!QjwRl^7=Bl7@(43=BkN=3{BRv#QHIk>Umc_w zvP>q|q{lJ=zs|W9%a@8%W>C@MYN1D5{(=Af31+pR#kB`cd0-YlQQTg}+ zL|_h=F9JQ|Gux5c0ehaffHNYLf8VwF+qnM6IjBEI_eceee;o;FY@#~FFVsZjBSp!j z8V*Bgmn{RK!!zqGc;jy)z@Zjo>5{%m1?K}fLEL$l6Dl4f=ye0wNI#)2L=^K(&18Gb zJoj8@WBB;P^T#V)I0`aDSy?$rJU{+-5472NyFp>;Vw43j@3Z=;D2eSfyw5*0Q+&ML zsV&&*3c3$pa`qcaGbEB0*CA~Wp3%PkF?B87FV&rWNb|@GU$LB;l|;YutU*k za1hjUL_BX%G^s;BuzRi4Hl?eqC2z&ZrKh1tZDwnufG$g$LX(j!h%F5(n8D@in3lnX z(*8+3ZT6TVYRcSpM1eMeCps=Fz8q%gyM&B=a7(Vf`4k3dN$IM+`BO^_7HZq4BR|7w z+5kOJ;9_$X%-~arA@qmXSzD|+NMh--%5-9u6t(M=f%&z$<_V#Y_lzn{E$MZZG)+A> zu2E`_Y(MBJ2l*AqvCUmU;yBT}#oQ{V=((mC-QGJwsCOH*a;{1JRTKv7DBNG+M!XL7(^jbv&Qy-o9HNFrmN)-`D3WFtXs>1vBOJpI(=x; zKhJlFdfMf^G#oU(w1+ucMKYPZaDp>$kt=wiYsBCjUY-uz<4JziB>6fXDSLH*2Y z&Px5y`#3!fF=c4>fCMdg-tX582pemU@ZxyFbznL8-=TTo1Sybg9>7h*J^9^~XxXJO z`k9v~=4amxl<;FCV9h2k%?^-ZUzQy^#{JleyH23o1S{r<+t#z6jKS<9rbAM96^1iY zi6{IjauB)UwBhC-_L(MzGCxhhv`?ryc zja_Uwi7$8l!}*vjJppGyp#Wz=*?;jC*xQ&J894rql5A$2giJRtV&DWQh#(+Vs3-5_ z69_tj(>8%z1VtVp>a74r5}j2rG%&;uaTQ|fr&r%ew-HO}76i8`&ki%#)~}q4Y|d$_ zfNp9uc#$#OEca>>MaY6rF`dB|5#S)bghf>>TmmE&S~IFw;PF0UztO6+R-0!TSC?QP z{b(RA_;q3QAPW^XN?qQqu{h<}Vfiv}Rr!lA$C79^1=U>+ng9Dh>v{`?AOZt>CrQ=o zI}=mSnR))8fJpO->rcX?H);oqSQUZ?sR!fH2SoFdcPm5*2y<_u;4h;BqcF*XbwWSv zcJN%!g|L(22Xp!^1?c;T&qm%rpkP&2EQC3JF+SENm$+@7#e!UKD1uQ{TDw43?!b!3 zUooS_rt=xJfa&h?c^hfV>YwQXre3qosz_^c#)FO~d!<)2o}Oxz5HWtr<)1Yw012v4 zhv0w(RfJspDnA^-6Jmr;GkWt%{mAYOm6yPb&Vl&rv@D^K&;#?=X{kaK5FhScNJ_3> z#5u(Saisq2(~pVlrfG#@kLM#Ot~5rZZc%B&h1=gen?R+#t^1bYKf zVvtefX=D$*)39e^2@!~A_}9c${Gf0?1;dk=!Itp#s%0>Io%k`9(bDeI-udd&E6Zfu zcaiv(h`DM3W3Mfda)fYwhB=8RAPkotVt5-z21Ij~Ot9A^SK-1u*zFVK&mF?q1;|wy zrF+XWs^5Q-%Z6I62gTwrRe#F>riVM#fv_TihxSJ6to1X7NVszgivoTa!fPfBBYj94 zuc2m zL_k-<1FoORng190; z+@DGs;NHgGW8%wjH$EpvQ-Hd! znZdIh#!H5nOStiOKNV8}QvY~=VMqtG&p$ByF&%pe_gR`|H5ULg47lk20(Xe=k8ptc zn%EmTI7k9gNE=!IN4WnbymtsKoHn2-cL65z^9cQOSp>XFzo;!h*x1s^0U!<{Y-VZ1 zXJ7zekkYf(`@dZ3F9|?O+*dUL4K4?0@V^>I2;k-a1%ZgY9w2|C5r0R5?80e-|&4yEwkklXmZ)!QSYG) zXBKOz|IPC2W_X!t^cgb^@D=|>r@x$f{3Y+`%NoDT^Y@JIuJ%jxe;es9vi`kJmbnPYT%X}rzs0K#=H)Q`)_L7%?KLLJP+0XJbL&JgdJE{i*){MOFSK z{7XUfXZR-Te}aE8RelNkQV0AQ7RC0TVE^o8c!~K^RQ4GY+xed`|A+zjZ(qij@~zLP zkS@Q0`rpM|UsnI6B;_+vw)^iA{n0%C7N~ql@KXNonIOUIHwgYg4Dcn>OOdc=rUl>M zVEQe|u$P=Kb)TL&-2#4t^Pg0pUQ)dj%6O)#3;zwOe~`_1$@Ef`;F+l=>NlAFFbBS0 zN))`LdKnA;OjQ{B+f;z>i|wCv-CmNs46S`8X-oKRl0V+pKZ%XJWO*6G`OMOs^xG_d zj_7-p06{fybw_P;UzX^eX5Pkcrm04%9rPFa56 zyZE \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS="" + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn () { + echo "$*" +} + +die () { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; + NONSTOP* ) + nonstop=true + ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin, switch paths to Windows format before running java +if $cygwin ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=$((i+1)) + done + case $i in + (0) set -- ;; + (1) set -- "$args0" ;; + (2) set -- "$args0" "$args1" ;; + (3) set -- "$args0" "$args1" "$args2" ;; + (4) set -- "$args0" "$args1" "$args2" "$args3" ;; + (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " +} +APP_ARGS=$(save "$@") + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong +if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then + cd "$(dirname "$0")" +fi + +exec "$JAVACMD" "$@" diff --git a/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutComponentKitSupport/CKComponent+Sonar.h b/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutComponentKitSupport/CKComponent+Sonar.h new file mode 100644 index 000000000..8ebfd7151 --- /dev/null +++ b/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutComponentKitSupport/CKComponent+Sonar.h @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +#import +#import +#import +#import + +FB_LINK_REQUIRE(CKComponent_Sonar) +@interface CKComponent (Sonar) + +- (NSArray *> *> *)sonar_getData; +- (NSDictionary *)sonar_getDataMutations; +- (NSString *)sonar_getName; +- (NSString *)sonar_getDecoration; + +@end diff --git a/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutComponentKitSupport/CKComponent+Sonar.mm b/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutComponentKitSupport/CKComponent+Sonar.mm new file mode 100644 index 000000000..22e34ab78 --- /dev/null +++ b/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutComponentKitSupport/CKComponent+Sonar.mm @@ -0,0 +1,166 @@ +/* + * Copyright (c) 2004-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +#if FB_SONARKIT_ENABLED + +#import "CKComponent+Sonar.h" + +#import +#import +#import +#import +#import +#import +#import + +/** This protocol isn't actually adopted anywhere, it just lets us use the SEL below */ +@protocol SonarKitLayoutComponentKitOverrideInformalProtocol +- (NSString *)sonar_componentNameOverride; +- (NSString *)sonar_componentDecorationOverride; +- (NSArray *> *> *)sonar_additionalDataOverride; +@end + +static BOOL AccessibilityContextIsDefault(CKComponentAccessibilityContext accessibilityContext) { + return accessibilityContext == CKComponentAccessibilityContext(); +} + +static NSDictionary *AccessibilityContextDict(CKComponentAccessibilityContext accessibilityContext) { + NSMutableDictionary *accessibilityDict = [NSMutableDictionary new]; + if (accessibilityContext.isAccessibilityElement != nil) { + accessibilityDict[@"isAccessibilityElement"] = SKObject(@([accessibilityContext.isAccessibilityElement boolValue])); + } + if (accessibilityContext.accessibilityLabel.hasText()) { + accessibilityDict[@"accessibilityLabel"] = SKObject(accessibilityContext.accessibilityLabel.value()); + } + if (accessibilityContext.accessibilityHint.hasText()) { + accessibilityDict[@"accessibilityHint"] = SKObject(accessibilityContext.accessibilityHint.value()); + } + if (accessibilityContext.accessibilityValue.hasText()) { + accessibilityDict[@"accessibilityValue"] = SKObject(accessibilityContext.accessibilityValue.value()); + } + if (accessibilityContext.accessibilityTraits != nil) { + accessibilityDict[@"accessibilityTraits"] = SKObject(@([accessibilityContext.accessibilityTraits integerValue])); + } + if (accessibilityContext.accessibilityComponentAction) { + accessibilityDict[@"accessibilityComponentAction.identifier"] = SKObject(@(accessibilityContext.accessibilityComponentAction.identifier().c_str())); + } + return accessibilityDict; +} + +FB_LINKABLE(CKComponent_Sonar) +@implementation CKComponent (Sonar) + +- (NSString *)sonar_getName +{ + if ([self respondsToSelector:@selector(sonar_componentNameOverride)]) { + return [(id)self sonar_componentNameOverride]; + } + return NSStringFromClass([self class]); +} + +- (NSString *)sonar_getDecoration +{ + if ([self respondsToSelector:@selector(sonar_componentDecorationOverride)]) { + return [(id)self sonar_componentDecorationOverride]; + } + return @"componentkit"; +} + +- (NSArray *> *> *)sonar_getData +{ + static NSDictionary *UIControlEventsEnumMap = @{ + @(UIControlEventTouchDown): @"UIControlEventTouchDown", + @(UIControlEventTouchDownRepeat): @"UIControlEventTouchDownRepeat", + @(UIControlEventTouchDragInside): @"UIControlEventTouchDragInside", + @(UIControlEventTouchDragOutside): @"UIControlEventTouchDragOutside", + @(UIControlEventTouchDragEnter): @"UIControlEventTouchDragEnter", + @(UIControlEventTouchDragExit): @"UIControlEventTouchDragExit", + @(UIControlEventTouchUpInside): @"UIControlEventTouchUpInside", + @(UIControlEventTouchUpOutside): @"UIControlEventTouchUpOutside", + @(UIControlEventTouchCancel): @"UIControlEventTouchTouchCancel", + + @(UIControlEventValueChanged): @"UIControlEventValueChanged", + @(UIControlEventPrimaryActionTriggered): @"UIControlEventPrimaryActionTriggered", + + @(UIControlEventEditingDidBegin): @"UIControlEventEditingDidBegin", + @(UIControlEventEditingChanged): @"UIControlEventEditingChanged", + @(UIControlEventEditingDidEnd): @"UIControlEventEditingDidEnd", + @(UIControlEventEditingDidEndOnExit): @"UIControlEventEditingDidEndOnExit", + }; + + + NSMutableArray *> *> *data = [NSMutableArray new]; + + [data addObject: [SKNamed newWithName: @"CKComponent" + withValue: @{ + @"frame": SKObject(self.viewContext.frame), + @"controller": SKObject(NSStringFromClass([self.controller class])), + }]]; + + if (self.viewContext.view) { + auto _actions = _CKComponentDebugControlActionsForComponent(self); + if (_actions.size() > 0) { + NSMutableDictionary *actions = [NSMutableDictionary new]; + + for (NSNumber *controlEvent : [UIControlEventsEnumMap allKeys]) { + NSMutableArray *> *responders = [NSMutableArray new]; + + for (const auto action : _actions) { + if ((action.first & [controlEvent integerValue]) == 0) { + continue; + } + + for (auto responder : action.second) { + id initialTarget = _CKTypedComponentDebugInitialTarget(responder).get(self); + const CKActionInfo actionInfo = CKActionFind(responder.selector(), initialTarget); + [responders addObject: @{ + @"initialTarget": SKObject(NSStringFromClass([initialTarget class])), + @"identifier": SKObject(@(responder.identifier().c_str())), + @"handler": SKObject(NSStringFromClass([actionInfo.responder class])), + @"selector": SKObject(NSStringFromSelector(responder.selector())), + }]; + } + } + + if (responders.count > 0) { + actions[UIControlEventsEnumMap[controlEvent]] = responders; + } + } + + [data addObject: [SKNamed newWithName: @"Actions" withValue: actions]]; + } + } + + // Only add accessibility panel if accessibilityContext is not default + CKComponentAccessibilityContext accessibilityContext = [self viewConfiguration].accessibilityContext(); + if (!AccessibilityContextIsDefault(accessibilityContext)) { + [data addObject: + [SKNamed newWithName: @"Accessibility" + withValue: @{ + @"accessibilityContext": AccessibilityContextDict(accessibilityContext), + @"accessibilityEnabled": SKMutableObject(@(CK::Component::Accessibility::IsAccessibilityEnabled())), + }]]; + } + + if ([self respondsToSelector:@selector(sonar_additionalDataOverride)]) { + [data addObjectsFromArray:[(id)self sonar_additionalDataOverride]]; + } + + return data; +} + +- (NSDictionary *)sonar_getDataMutations { + return @{ + @"CKComponentAccessibility.accessibilityEnabled": ^(NSNumber *value) { + CK::Component::Accessibility::SetForceAccessibilityEnabled([value boolValue]); + } + }; +} + +@end + +#endif diff --git a/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutComponentKitSupport/CKFlexboxComponent+Sonar.h b/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutComponentKitSupport/CKFlexboxComponent+Sonar.h new file mode 100644 index 000000000..c574a9c7c --- /dev/null +++ b/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutComponentKitSupport/CKFlexboxComponent+Sonar.h @@ -0,0 +1,14 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +#import +#import + +FB_LINK_REQUIRE(CKFlexboxComponent_Sonar) +@interface CKFlexboxComponent (Sonar) + +@end diff --git a/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutComponentKitSupport/CKFlexboxComponent+Sonar.mm b/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutComponentKitSupport/CKFlexboxComponent+Sonar.mm new file mode 100644 index 000000000..dcbc5f36f --- /dev/null +++ b/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutComponentKitSupport/CKFlexboxComponent+Sonar.mm @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +#if FB_SONARKIT_ENABLED + +#import "CKFlexboxComponent+Sonar.h" + +#import +#import + +#import "CKComponent+Sonar.h" +#import "Utils.h" + +FB_LINKABLE(CKFlexboxComponent_Sonar) +@implementation CKFlexboxComponent (Sonar) + +- (NSArray *> *> *)sonar_additionalDataOverride +{ + static NSDictionary *CKFlexboxDirectionEnumMap = @{ + @(CKFlexboxDirectionColumn): @"vertical", + @(CKFlexboxDirectionRow): @"horizontal", + @(CKFlexboxDirectionColumnReverse): @"vertical-reverse", + @(CKFlexboxDirectionRowReverse): @"horizontal-reverse", + }; + + static NSDictionary *CKFlexboxJustifyContentEnumMap = @{ + @(CKFlexboxJustifyContentStart): @"start", + @(CKFlexboxJustifyContentCenter): @"center", + @(CKFlexboxJustifyContentEnd): @"end", + @(CKFlexboxJustifyContentSpaceBetween): @"space-between", + @(CKFlexboxJustifyContentSpaceAround): @"space-around", + }; + + static NSDictionary *CKFlexboxAlignItemsEnumMap = @{ + @(CKFlexboxAlignItemsStart): @"start", + @(CKFlexboxAlignItemsEnd): @"end", + @(CKFlexboxAlignItemsCenter): @"center", + @(CKFlexboxAlignItemsBaseline): @"baseline", + @(CKFlexboxAlignItemsStretch): @"stretch", + }; + + static NSDictionary *CKFlexboxAlignContentEnumMap = @{ + @(CKFlexboxAlignContentStart): @"start", + @(CKFlexboxAlignContentEnd): @"end", + @(CKFlexboxAlignContentCenter): @"center", + @(CKFlexboxAlignContentSpaceBetween): @"space-between", + @(CKFlexboxAlignContentSpaceAround): @"space-around", + @(CKFlexboxAlignContentStretch): @"stretch", + }; + + static NSDictionary *CKFlexboxWrapEnumMap = @{ + @(CKFlexboxWrapWrap): @"wrap", + @(CKFlexboxWrapNoWrap): @"no-wrap", + @(CKFlexboxWrapWrapReverse): @"wrap-reverse", + }; + + CKFlexboxComponentStyle style; + [[self valueForKey: @"_style"] getValue: &style]; + + return @[[SKNamed + newWithName:@"CKFlexboxComponent" + withValue:@{ + @"spacing": SKObject(@(style.spacing)), + @"direction": SKObject(CKFlexboxDirectionEnumMap[@(style.direction)]), + @"justifyContent": SKObject(CKFlexboxJustifyContentEnumMap[@(style.justifyContent)]), + @"alignItems": SKObject(CKFlexboxAlignItemsEnumMap[@(style.alignItems)]), + @"alignContent": SKObject(CKFlexboxAlignContentEnumMap[@(style.alignContent)]), + @"wrap": SKObject(CKFlexboxWrapEnumMap[@(style.wrap)]), + @"margin": SKObject(flexboxRect(style.margin)), + @"padding": SKObject(flexboxRect(style.padding)), + }]]; +} + +@end + +#endif diff --git a/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutComponentKitSupport/CKInsetComponent+Sonar.h b/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutComponentKitSupport/CKInsetComponent+Sonar.h new file mode 100644 index 000000000..e6329223a --- /dev/null +++ b/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutComponentKitSupport/CKInsetComponent+Sonar.h @@ -0,0 +1,14 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +#import +#import + +FB_LINK_REQUIRE(CKInsetComponent_Sonar) +@interface CKInsetComponent (Sonar) + +@end diff --git a/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutComponentKitSupport/CKInsetComponent+Sonar.mm b/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutComponentKitSupport/CKInsetComponent+Sonar.mm new file mode 100644 index 000000000..780aa1272 --- /dev/null +++ b/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutComponentKitSupport/CKInsetComponent+Sonar.mm @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +#if FB_SONARKIT_ENABLED + +#import "CKInsetComponent+Sonar.h" + +#import +#import + +#import "CKComponent+Sonar.h" + +FB_LINKABLE(CKInsetComponent_Sonar) +@implementation CKInsetComponent (Sonar) + +- (NSArray *> *> *)sonar_additionalDataOverride +{ + return @[[SKNamed newWithName:@"CKInsetComponent" withValue:@{@"insets": SKObject([[self valueForKey: @"_insets"] UIEdgeInsetsValue])}]]; +} + +@end + +#endif diff --git a/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutComponentKitSupport/SKComponentHostingViewDescriptor.h b/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutComponentKitSupport/SKComponentHostingViewDescriptor.h new file mode 100644 index 000000000..f2f448177 --- /dev/null +++ b/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutComponentKitSupport/SKComponentHostingViewDescriptor.h @@ -0,0 +1,14 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +#import + +@class CKComponentHostingView; + +@interface SKComponentHostingViewDescriptor : SKNodeDescriptor + +@end diff --git a/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutComponentKitSupport/SKComponentHostingViewDescriptor.mm b/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutComponentKitSupport/SKComponentHostingViewDescriptor.mm new file mode 100644 index 000000000..87a8327fd --- /dev/null +++ b/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutComponentKitSupport/SKComponentHostingViewDescriptor.mm @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +#if FB_SONARKIT_ENABLED + +#import "SKComponentHostingViewDescriptor.h" + +#import +#import +#import +#import +#import +#import + +#import + +#import "SKComponentLayoutWrapper.h" + +@implementation SKComponentHostingViewDescriptor + +- (NSString *)identifierForNode:(CKComponentHostingView *)node { + return [NSString stringWithFormat: @"%p", node]; +} + +- (NSUInteger)childCountForNode:(CKComponentHostingView *)node { + return node.mountedLayout.component ? 1 : 0; +} + +- (id)childForNode:(CKComponentHostingView *)node atIndex:(NSUInteger)index { + return [SKComponentLayoutWrapper newFromRoot:node]; +} + +- (void)setHighlighted:(BOOL)highlighted forNode:(CKComponentHostingView *)node { + SKNodeDescriptor *viewDescriptor = [self descriptorForClass: [UIView class]]; + [viewDescriptor setHighlighted: highlighted forNode: node]; +} + +- (void)hitTest:(SKTouch *)touch forNode:(CKComponentHostingView *)node { + [touch continueWithChildIndex: 0 withOffset: (CGPoint){ 0, 0 }]; +} + +@end + +#endif diff --git a/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutComponentKitSupport/SKComponentLayoutDescriptor.h b/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutComponentKitSupport/SKComponentLayoutDescriptor.h new file mode 100644 index 000000000..fb8ed237c --- /dev/null +++ b/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutComponentKitSupport/SKComponentLayoutDescriptor.h @@ -0,0 +1,14 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +#import + +@class SKComponentLayoutWrapper; + +@interface SKComponentLayoutDescriptor: SKNodeDescriptor + +@end diff --git a/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutComponentKitSupport/SKComponentLayoutDescriptor.mm b/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutComponentKitSupport/SKComponentLayoutDescriptor.mm new file mode 100644 index 000000000..0a14f8398 --- /dev/null +++ b/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutComponentKitSupport/SKComponentLayoutDescriptor.mm @@ -0,0 +1,178 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +#if FB_SONARKIT_ENABLED + +#import "SKComponentLayoutDescriptor.h" + +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import + +#import +#import + +#import "SKComponentLayoutWrapper.h" +#import "CKComponent+Sonar.h" +#import "Utils.h" + +@implementation SKComponentLayoutDescriptor +{ + NSDictionary *CKFlexboxAlignSelfEnumMap; + NSDictionary *CKFlexboxPositionTypeEnumMap; +} + +- (void)setUp { + [super setUp]; + + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + [self initEnumMaps]; + }); +} + +- (void)initEnumMaps { + CKFlexboxAlignSelfEnumMap = @{ + @(CKFlexboxAlignSelfAuto): @"auto", + @(CKFlexboxAlignSelfStart): @"start", + @(CKFlexboxAlignSelfEnd): @"end", + @(CKFlexboxAlignSelfCenter): @"center", + @(CKFlexboxAlignSelfBaseline): @"baseline", + @(CKFlexboxAlignSelfStretch): @"stretch", + }; + + CKFlexboxPositionTypeEnumMap = @{ + @(CKFlexboxPositionTypeRelative): @"relative", + @(CKFlexboxPositionTypeAbsolute): @"absolute", + }; +} + +- (NSString *)identifierForNode:(SKComponentLayoutWrapper *)node { + return node.identifier; +} + +- (NSString *)nameForNode:(SKComponentLayoutWrapper *)node { + return [node.component sonar_getName]; +} + +- (NSString *)decorationForNode:(SKComponentLayoutWrapper *)node { + return [node.component sonar_getDecoration]; +} + +- (NSUInteger)childCountForNode:(SKComponentLayoutWrapper *)node { + NSUInteger count = node.children.size(); + if (count == 0) { + count = node.component.viewContext.view ? 1 : 0; + } + return count; +} + +- (id)childForNode:(SKComponentLayoutWrapper *)node atIndex:(NSUInteger)index { + if (node.children.size() == 0) { + return node.component.viewContext.view; + } + return node.children[index]; +} + +- (NSArray *> *> *)dataForNode:(SKComponentLayoutWrapper *)node { + NSMutableArray *> *> *data = [NSMutableArray new]; + + if (node.isFlexboxChild) { + [data addObject: [SKNamed newWithName:@"Layout" withValue:[self propsForFlexboxChild:node.flexboxChild]]]; + } + + [data addObjectsFromArray:[node.component sonar_getData]]; + + return data; +} + +- (NSDictionary *)propsForFlexboxChild:(CKFlexboxComponentChild)child { + return @{ + @"spacingBefore": SKObject(@(child.spacingBefore)), + @"spacingAfter": SKObject(@(child.spacingAfter)), + @"flexGrow": SKObject(@(child.flexGrow)), + @"flexShrink": SKObject(@(child.flexShrink)), + @"zIndex": SKObject(@(child.zIndex)), + @"useTextRounding": SKObject(@(child.useTextRounding)), + @"margin": flexboxRect(child.margin), + @"flexBasis": relativeDimension(child.flexBasis), + @"padding": flexboxRect(child.padding), + @"alignSelf": CKFlexboxAlignSelfEnumMap[@(child.alignSelf)], + @"position": @{ + @"type": CKFlexboxPositionTypeEnumMap[@(child.position.type)], + @"start": relativeDimension(child.position.start), + @"top": relativeDimension(child.position.top), + @"end": relativeDimension(child.position.end), + @"bottom": relativeDimension(child.position.bottom), + @"left": relativeDimension(child.position.left), + @"right": relativeDimension(child.position.right), + }, + @"aspectRatio": @(child.aspectRatio.aspectRatio()), + }; +} + +- (NSDictionary *)dataMutationsForNode:(SKComponentLayoutWrapper *)node { + return [node.component sonar_getDataMutations]; +} + +- (NSArray *> *)attributesForNode:(SKComponentLayoutWrapper *)node { + return @[ + [SKNamed newWithName: @"responder" + withValue: SKObject(NSStringFromClass([node.component.nextResponder class]))] + ]; +} + +- (void)setHighlighted:(BOOL)highlighted forNode:(SKComponentLayoutWrapper *)node { + SKHighlightOverlay *overlay = [SKHighlightOverlay sharedInstance]; + if (highlighted) { + CKComponentViewContext viewContext = node.component.viewContext; + [overlay mountInView: viewContext.view + withFrame: viewContext.frame]; + } else { + [overlay unmount]; + } +} + +- (void)hitTest:(SKTouch *)touch forNode:(SKComponentLayoutWrapper *)node { + if (node.children.size() == 0) { + UIView *componentView = node.component.viewContext.view; + if (componentView != nil) { + if ([touch containedIn: componentView.bounds]) { + [touch continueWithChildIndex: 0 withOffset: componentView.bounds.origin]; + return; + } + } + } + + NSInteger index = 0; + for (index = node.children.size() - 1; index >= 0; index--) { + const auto child = node.children[index]; + + CGRect frame = { + .origin = child.position, + .size = child.size + }; + + if ([touch containedIn: frame]) { + [touch continueWithChildIndex: index withOffset: child.position]; + return; + } + } + + [touch finish]; +} + +@end + +#endif diff --git a/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutComponentKitSupport/SKComponentLayoutWrapper.h b/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutComponentKitSupport/SKComponentLayoutWrapper.h new file mode 100644 index 000000000..d706c0b8a --- /dev/null +++ b/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutComponentKitSupport/SKComponentLayoutWrapper.h @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +#import + +#import +#import + +@protocol CKInspectableView; + +@interface SKComponentLayoutWrapper : NSObject + +@property (nonatomic, weak, readonly) CKComponent *component; +@property (nonatomic, readonly) NSString *identifier; +@property (nonatomic, readonly) CGSize size; +@property (nonatomic, readonly) CGPoint position; +@property (nonatomic, readonly) std::vector children; + +// Null for layouts which are not direct children of a CKFlexboxComponent +@property (nonatomic, readonly) BOOL isFlexboxChild; +@property (nonatomic, readonly) CKFlexboxComponentChild flexboxChild; + ++ (instancetype)newFromRoot:(id)root; + +@end diff --git a/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutComponentKitSupport/SKComponentLayoutWrapper.mm b/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutComponentKitSupport/SKComponentLayoutWrapper.mm new file mode 100644 index 000000000..adfe43442 --- /dev/null +++ b/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutComponentKitSupport/SKComponentLayoutWrapper.mm @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +#if FB_SONARKIT_ENABLED + +#import "SKComponentLayoutWrapper.h" + +#import +#import +#import +#import +#import + +static char const kLayoutWrapperKey = ' '; + +static CKFlexboxComponentChild findFlexboxLayoutParams(CKComponent *parent, CKComponent *child) { + if ([parent isKindOfClass:[CKFlexboxComponent class]]) { + static Ivar ivar = class_getInstanceVariable([CKFlexboxComponent class], "_children"); + static ptrdiff_t offset = ivar_getOffset(ivar); + + unsigned char *pComponent = (unsigned char*)(__bridge void*)parent; + auto children = (std::vector *)(pComponent + offset); + + if (children) { + for (auto it = children->begin(); it != children->end(); it++) { + if (it->component == child) { + return *it; + } + } + } + } + + return {}; +} + +@implementation SKComponentLayoutWrapper + ++ (instancetype)newFromRoot:(id)root { + const CKComponentLayout layout = [root mountedLayout]; + SKComponentLayoutWrapper *const wrapper = + [[SKComponentLayoutWrapper alloc] initWithLayout:layout + position:CGPointMake(0, 0) + parentKey:[NSString stringWithFormat: @"%p.", layout.component]]; + if (layout.component) + objc_setAssociatedObject(layout.component, &kLayoutWrapperKey, wrapper, OBJC_ASSOCIATION_RETAIN_NONATOMIC); + return wrapper; +} + +- (instancetype)initWithLayout:(const CKComponentLayout &)layout position:(CGPoint)position parentKey:(NSString *)parentKey { + if (self = [super init]) { + _component = layout.component; + _size = layout.size; + _position = position; + _identifier = [parentKey stringByAppendingString:layout.component ? NSStringFromClass([layout.component class]) : @"(null)"]; + + if (layout.children != nullptr) { + int index = 0; + for (const auto &child : *layout.children) { + if (child.layout.component == nil) { + continue; // nil children are allowed, ignore them + } + SKComponentLayoutWrapper *childWrapper = [[SKComponentLayoutWrapper alloc] initWithLayout:child.layout + position:child.position + parentKey:[_identifier stringByAppendingFormat:@"[%d].", index++]]; + childWrapper->_isFlexboxChild = [_component isKindOfClass:[CKFlexboxComponent class]]; + childWrapper->_flexboxChild = findFlexboxLayoutParams(_component, child.layout.component); + _children.push_back(childWrapper); + } + } + } + + return self; +} + +@end + +#endif diff --git a/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutComponentKitSupport/SKComponentRootViewDescriptor.h b/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutComponentKitSupport/SKComponentRootViewDescriptor.h new file mode 100644 index 000000000..cc2995a81 --- /dev/null +++ b/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutComponentKitSupport/SKComponentRootViewDescriptor.h @@ -0,0 +1,14 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +#import + +@class CKComponentRootView; + +@interface SKComponentRootViewDescriptor : SKNodeDescriptor + +@end diff --git a/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutComponentKitSupport/SKComponentRootViewDescriptor.mm b/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutComponentKitSupport/SKComponentRootViewDescriptor.mm new file mode 100644 index 000000000..7769c82fb --- /dev/null +++ b/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutComponentKitSupport/SKComponentRootViewDescriptor.mm @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +#if FB_SONARKIT_ENABLED + +#import "SKComponentRootViewDescriptor.h" + +#import +#import +#import +#import +#import +#import + +#import + +#import "SKComponentLayoutWrapper.h" + +@implementation SKComponentRootViewDescriptor + +- (NSString *)identifierForNode:(CKComponentRootView *)node { + return [NSString stringWithFormat: @"%p", node]; +} + +- (NSUInteger)childCountForNode:(CKComponentRootView *)node { + if ([node respondsToSelector:@selector(ck_attachState)]) { + CKComponentDataSourceAttachState *state = [node ck_attachState]; + return state == nil ? 0 : 1; + } + return 0; +} + +- (id)childForNode:(CKComponentRootView *)node atIndex:(NSUInteger)index { + return [SKComponentLayoutWrapper newFromRoot:node]; +} + +- (void)setHighlighted:(BOOL)highlighted forNode:(CKComponentRootView *)node { + SKNodeDescriptor *viewDescriptor = [self descriptorForClass: [UIView class]]; + [viewDescriptor setHighlighted: highlighted forNode: node]; +} + +- (void)hitTest:(SKTouch *)touch forNode:(CKComponentRootView *)node { + [touch continueWithChildIndex: 0 withOffset: (CGPoint){ 0, 0 }]; +} + +@end + +#endif diff --git a/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutComponentKitSupport/SonarKitLayoutComponentKitSupport.h b/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutComponentKitSupport/SonarKitLayoutComponentKitSupport.h new file mode 100644 index 000000000..8512169dc --- /dev/null +++ b/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutComponentKitSupport/SonarKitLayoutComponentKitSupport.h @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +#import + +#import + +@interface SonarKitLayoutComponentKitSupport : NSObject + ++ (void)setUpWithDescriptorMapper:(SKDescriptorMapper *)mapper; + +@end diff --git a/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutComponentKitSupport/SonarKitLayoutComponentKitSupport.mm b/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutComponentKitSupport/SonarKitLayoutComponentKitSupport.mm new file mode 100644 index 000000000..894e7a098 --- /dev/null +++ b/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutComponentKitSupport/SonarKitLayoutComponentKitSupport.mm @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +#if FB_SONARKIT_ENABLED + +#import "SonarKitLayoutComponentKitSupport.h" + +#import +#import + +#import + +#import "SKComponentHostingViewDescriptor.h" +#import "SKComponentRootViewDescriptor.h" +#import "SKComponentLayoutDescriptor.h" +#import "SKComponentLayoutWrapper.h" + +@implementation SonarKitLayoutComponentKitSupport + ++ (void)setUpWithDescriptorMapper:(SKDescriptorMapper *)mapper { + // What we really want here is "forProtocol:@protocol(CKInspectableView)" but no such luck. + [mapper registerDescriptor: [[SKComponentHostingViewDescriptor alloc] initWithDescriptorMapper: mapper] + forClass: [CKComponentHostingView class]]; + [mapper registerDescriptor: [[SKComponentRootViewDescriptor alloc] initWithDescriptorMapper: mapper] + forClass: [CKComponentRootView class]]; + [mapper registerDescriptor: [[SKComponentLayoutDescriptor alloc] initWithDescriptorMapper: mapper] + forClass: [SKComponentLayoutWrapper class]]; +} + + +@end + +#endif diff --git a/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutComponentKitSupport/Utils.h b/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutComponentKitSupport/Utils.h new file mode 100644 index 000000000..15adcbe1a --- /dev/null +++ b/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutComponentKitSupport/Utils.h @@ -0,0 +1,12 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +#import +#import + +NSString *relativeDimension(CKRelativeDimension dimension); +NSDictionary *flexboxRect(CKFlexboxSpacing spacing); diff --git a/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutComponentKitSupport/Utils.mm b/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutComponentKitSupport/Utils.mm new file mode 100644 index 000000000..a03b8c420 --- /dev/null +++ b/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutComponentKitSupport/Utils.mm @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +#if FB_SONARKIT_ENABLED + +#include "Utils.h" + +NSString *relativeDimension(CKRelativeDimension dimension) { + switch(dimension.type()) { + case CKRelativeDimension::Type::PERCENT: + return [NSString stringWithFormat: @"%@%%", @(dimension.value())]; + case CKRelativeDimension::Type::POINTS: + return [NSString stringWithFormat: @"%@pt", @(dimension.value())]; + default: + return @"auto"; + } +} + +NSDictionary *flexboxRect(CKFlexboxSpacing spacing) { + return @{ + @"top": relativeDimension(spacing.top.dimension()), + @"bottom": relativeDimension(spacing.bottom.dimension()), + @"start": relativeDimension(spacing.start.dimension()), + @"end": relativeDimension(spacing.end.dimension()) + }; +} + +#endif diff --git a/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/SKDescriptorMapper.h b/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/SKDescriptorMapper.h new file mode 100644 index 000000000..dd42e76fd --- /dev/null +++ b/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/SKDescriptorMapper.h @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +#import + +@class SKNodeDescriptor; + +@interface SKDescriptorMapper : NSObject + +- (instancetype)initWithDefaults; + +- (SKNodeDescriptor *)descriptorForClass:(Class)cls; + +- (void)registerDescriptor:(SKNodeDescriptor *)descriptor forClass:(Class)cls; + +- (NSArray *)allDescriptors; + +@end diff --git a/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/SKDescriptorMapper.mm b/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/SKDescriptorMapper.mm new file mode 100644 index 000000000..15114e529 --- /dev/null +++ b/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/SKDescriptorMapper.mm @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +#if FB_SONARKIT_ENABLED + +#import "SKDescriptorMapper.h" + +#import "SKApplicationDescriptor.h" +#import "SKButtonDescriptor.h" +#import "SKScrollViewDescriptor.h" +#import "SKViewControllerDescriptor.h" +#import "SKViewDescriptor.h" + +@implementation SKDescriptorMapper +{ + NSMutableDictionary *_descriptors; +} + +- (instancetype)initWithDefaults { + if (self = [super init]) { + _descriptors = [NSMutableDictionary new]; + + [self registerDescriptor: [[SKApplicationDescriptor alloc] initWithDescriptorMapper: self] + forClass: [UIApplication class]]; + [self registerDescriptor: [[SKViewControllerDescriptor alloc] initWithDescriptorMapper: self] + forClass: [UIViewController class]]; + [self registerDescriptor: [[SKScrollViewDescriptor alloc] initWithDescriptorMapper: self] + forClass: [UIScrollView class]]; + [self registerDescriptor: [[SKButtonDescriptor alloc] initWithDescriptorMapper: self] + forClass: [UIButton class]]; + [self registerDescriptor: [[SKViewDescriptor alloc] initWithDescriptorMapper: self] + forClass: [UIView class]]; + } + + return self; +} + +- (SKNodeDescriptor *)descriptorForClass:(Class)cls { + SKNodeDescriptor *classDescriptor = nil; + + while (classDescriptor == nil && cls != nil) { + classDescriptor = [_descriptors objectForKey: NSStringFromClass(cls)]; + cls = [cls superclass]; + } + + return classDescriptor; +} + +- (void)registerDescriptor:(SKNodeDescriptor *)descriptor forClass:(Class)cls { + NSString *className = NSStringFromClass(cls); + _descriptors[className] = descriptor; +} + +- (NSArray *)allDescriptors { + return [_descriptors allValues]; +} + +@end + +#endif diff --git a/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/SKHighlightOverlay.h b/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/SKHighlightOverlay.h new file mode 100644 index 000000000..a3dfd7b5e --- /dev/null +++ b/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/SKHighlightOverlay.h @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +#import + +@interface SKHighlightOverlay : NSObject + ++ (instancetype)sharedInstance; ++ (UIColor*)overlayColor; + +- (void)mountInView:(UIView *)view withFrame:(CGRect)frame; +- (void)unmount; + +@end diff --git a/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/SKHighlightOverlay.m b/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/SKHighlightOverlay.m new file mode 100644 index 000000000..e39726033 --- /dev/null +++ b/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/SKHighlightOverlay.m @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +#if FB_SONARKIT_ENABLED + +#import "SKHighlightOverlay.h" + +@implementation SKHighlightOverlay +{ + CALayer *_overlayLayer; +} + ++ (instancetype)sharedInstance { + static SKHighlightOverlay *sharedInstance = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + sharedInstance = [self new]; + }); + return sharedInstance; +} + +- (instancetype)init { + if (self = [super init]) { + _overlayLayer = [CALayer layer]; + _overlayLayer.backgroundColor = [SKHighlightOverlay overlayColor].CGColor; + } + + return self; +} + +- (void)mountInView:(UIView *)view withFrame:(CGRect)frame { + [CATransaction begin]; + [CATransaction setValue:(id)kCFBooleanTrue + forKey:kCATransactionDisableActions]; + _overlayLayer.frame = frame; + [view.layer addSublayer: _overlayLayer]; + [CATransaction commit]; +} + +- (void)unmount { + [_overlayLayer removeFromSuperlayer]; +} + ++ (UIColor*)overlayColor { + return [UIColor colorWithRed:136.0 / 255.0 green:117.0 / 255.0 blue:197.0 / 255.0 alpha:0.6]; +} + +@end + +#endif diff --git a/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/SKInvalidation.h b/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/SKInvalidation.h new file mode 100644 index 000000000..81543aa0b --- /dev/null +++ b/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/SKInvalidation.h @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +#import + +@protocol SKInvalidationDelegate + +- (void)invalidateNode:(id)node; + +- (void)updateNodeReference:(id)node; + +@end + +@interface SKInvalidation : NSObject + ++ (instancetype)sharedInstance; + ++ (void)enableInvalidations; + +@property (nonatomic, weak) id delegate; + +@end diff --git a/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/SKInvalidation.m b/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/SKInvalidation.m new file mode 100644 index 000000000..33aa5c4fe --- /dev/null +++ b/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/SKInvalidation.m @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +#if FB_SONARKIT_ENABLED + +#import + +#import "SKInvalidation.h" +#import "UIView+SKInvalidation.h" +#import "UICollectionView+SKInvalidation.h" + +@implementation SKInvalidation + ++ (instancetype)sharedInstance { + static SKInvalidation *sInstance = nil; + + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + sInstance = [SKInvalidation new]; + }); + + return sInstance; +} + ++ (void)enableInvalidations { + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + [UIView enableInvalidation]; + [UICollectionView enableInvalidations]; + + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(windowDidBecomeVisible:) + name:UIWindowDidBecomeVisibleNotification + object:nil]; + + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(windowDidBecomeHidden:) + name:UIWindowDidBecomeHiddenNotification + object:nil]; + }); +} + ++ (void)windowDidBecomeVisible:(NSNotification*)notification { + [[SKInvalidation sharedInstance].delegate invalidateNode:[notification.object nextResponder]]; +} + ++ (void)windowDidBecomeHidden:(NSNotification*)notification { + [[SKInvalidation sharedInstance].delegate invalidateNode:[notification.object nextResponder]]; +} + +@end + +#endif diff --git a/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/SKNamed.h b/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/SKNamed.h new file mode 100644 index 000000000..294fe98b6 --- /dev/null +++ b/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/SKNamed.h @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +#import + +@interface SKNamed<__covariant T> : NSObject + ++ (instancetype)newWithName:(NSString *)name withValue:(T)value; + +@property (nonatomic, readonly) NSString *name; +@property (nonatomic, readonly) T value; + +@end diff --git a/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/SKNamed.mm b/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/SKNamed.mm new file mode 100644 index 000000000..20fdfe0f7 --- /dev/null +++ b/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/SKNamed.mm @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +#if FB_SONARKIT_ENABLED + +#import "SKNamed.h" + +@implementation SKNamed + ++ (instancetype)newWithName:(NSString *)name withValue:(id)value { + return [[SKNamed alloc] initWithName: name withValue: value]; +} + +- (instancetype)initWithName:(NSString *)name withValue:(id)value { + if (self = [super init]) { + _name = name; + _value = value; + } + + return self; +} + +- (NSString *)description { + return [NSString stringWithFormat:@"%@: %@", _name, _value]; +} + +@end + +#endif diff --git a/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/SKNodeDescriptor.h b/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/SKNodeDescriptor.h new file mode 100644 index 000000000..cd612de85 --- /dev/null +++ b/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/SKNodeDescriptor.h @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +#import + +#import "SKDescriptorMapper.h" +#import "SKNamed.h" +#import "SKTouch.h" + +typedef void (^SKNodeUpdateData)(id value); + +/** + A SKNodeDescriptor is an object which know how to expose an Object of type T + to SonarKitLayoutPlugin. This class is the extension point for SonarKitLayoutPlugin and + is how custom objects or data can be exposed to Sonar. + */ +@interface SKNodeDescriptor<__covariant T> : NSObject + +/** + If the descriptor class is dependent on some set-up, use this. + This is invoked once Sonar connects. + */ +- (void)setUp; + +/** + Initializes the node-descriptor with a SKDescriptorMapper which contains mappings + between Class -> SKNodeDescriptor. + */ +- (instancetype)initWithDescriptorMapper:(SKDescriptorMapper *)mapper; + +/** + Gets the node-descriptor registered for a specific class. + */ +- (SKNodeDescriptor *)descriptorForClass:(Class)cls; + +/** + A globally unique ID used to identify a node in the hierarchy. This is used + in the communication between SonarKitLayoutPlugin and the Sonar desktop application + in order to identify nodes. + */ +- (NSString *)identifierForNode:(T)node; + +/** + The name used to identify this node in the Sonar desktop application. This is what + will be visible in the hierarchy. + */ +- (NSString *)nameForNode:(T)node; + +/** + The number of children this node exposes in the layout hierarchy. + */ +- (NSUInteger)childCountForNode:(T)node; + +/** + Get the child for a specific node at a specified index. + */ +- (id)childForNode:(T)node atIndex:(NSUInteger)index; + +/** + Get the data to show for this node in the sidebar of the Sonar application. The objects + will be shown in order by SKNamed.name as their header. + */ +- (NSArray *> *)dataForNode:(T)node; + +/** + Get the attributes for this node. Attributes will be showed in the Sonar application right + next to the name of the node. + */ +- (NSArray *> *)attributesForNode:(T)node; + +/** + A mapping of the path for a specific value, and a block responsible for updating + its corresponding value for a specific node. + + The paths (string) is dependent on what `dataForNode` returns (e.g "SKNodeDescriptor.name"). + */ +- (NSDictionary *)dataMutationsForNode:(T)node; + +/** + This is used in order to highlight any specific node which is currently + selected in the Sonar application. The plugin automatically takes care of de-selecting + the previously highlighted node. + */ +- (void)setHighlighted:(BOOL)highlighted forNode:(T)node; + +/** + Perform hit testing on the given node. Either continue the search in + one of the children of the node, or finish the hit testing on this + node. + */ +- (void)hitTest:(SKTouch *)point forNode:(T)node; + +/** + Invalidate a specific node. This is called once a node is removed or added + from or to the layout hierarchy. + */ +- (void)invalidateNode:(T)node; + +/** + The decoration for this node. Valid values are defined in the Sonar + applictation. + */ +- (NSString *)decorationForNode:(T)node; + +/** + Whether the node matches the given query. + Used for layout search. + */ +- (BOOL)matchesQuery:(NSString *)query forNode:(T)node; + +@end diff --git a/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/SKNodeDescriptor.mm b/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/SKNodeDescriptor.mm new file mode 100644 index 000000000..961dc5fa3 --- /dev/null +++ b/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/SKNodeDescriptor.mm @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +#if FB_SONARKIT_ENABLED + +#import "SKNodeDescriptor.h" + +@implementation SKNodeDescriptor +{ + SKDescriptorMapper *_mapper; +} + +- (void)setUp { +} + +- (instancetype)initWithDescriptorMapper:(SKDescriptorMapper *)mapper { + if (self = [super init]) { + _mapper = mapper; + } + return self; +} + +- (SKNodeDescriptor *)descriptorForClass:(Class)cls { + return [_mapper descriptorForClass: cls]; +} + +- (NSString *)identifierForNode:(id)node { + @throw [NSString stringWithFormat:@"need to implement %@", NSStringFromSelector(_cmd)]; +} + +- (NSString *)nameForNode:(id)node { + return NSStringFromClass([node class]); +} + +- (NSUInteger)childCountForNode:(id)node { + @throw [NSString stringWithFormat:@"need to implement %@", NSStringFromSelector(_cmd)]; +} + +- (id)childForNode:(id)node atIndex:(NSUInteger)index { + @throw [NSString stringWithFormat:@"need to implement %@", NSStringFromSelector(_cmd)]; +} + +- (NSDictionary *)dataMutationsForNode:(id)node { + return @{}; +} + +- (NSArray *> *)dataForNode:(id)node { + return @[]; +} + +- (NSArray *> *)attributesForNode:(id)node { + return @[]; +} + +- (void)setHighlighted:(BOOL)highlighted forNode:(id)node { +} + +- (void)hitTest:(SKTouch *)point forNode:(id)node { +} + +- (void)invalidateNode:(id)node { +} + +- (NSString *)decorationForNode:(id)node { + return @""; +} + +- (BOOL)matchesQuery:(NSString *)query forNode:(id)node { + NSString *name = [self nameForNode: node]; + return [self string:name contains:query] || [self string:[self identifierForNode: node] contains: query]; +} + +- (BOOL)string:(NSString *)string contains:(NSString *)substring { + return string != nil && substring != nil && [string rangeOfString: substring options: NSCaseInsensitiveSearch].location != NSNotFound; +} + +@end + +#endif diff --git a/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/SKObject.h b/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/SKObject.h new file mode 100644 index 000000000..24cbfe766 --- /dev/null +++ b/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/SKObject.h @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +#import + +@protocol SKSonarValueCoder + ++ (instancetype)fromSonarValue:(id)sonarValue; + +- (NSDictionary> *)sonarValue; + +@end + +class SKObject { +public: + SKObject(CGRect rect); + SKObject(CGSize size); + SKObject(CGPoint point); + SKObject(UIEdgeInsets insets); + SKObject(CGAffineTransform transform); + SKObject(id value); + SKObject(id value); + + operator id () const noexcept { + return _actual ?: [NSNull null]; + } +protected: + id _actual; +}; + +class SKMutableObject : public SKObject { +public: + SKMutableObject(CGRect rect) : SKObject(rect) { } + SKMutableObject(CGSize size) : SKObject(size) { }; + SKMutableObject(CGPoint point) : SKObject(point) { }; + SKMutableObject(UIEdgeInsets insets) : SKObject(insets) { }; + SKMutableObject(CGAffineTransform transform) : SKObject(transform) { }; + SKMutableObject(id value) : SKObject(value) { }; + SKMutableObject(id value) : SKObject(value) { }; + + operator id () { + convertToMutable(); + return _actual; + } +protected: + BOOL _convertedToMutable = NO; + void convertToMutable(); +}; diff --git a/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/SKObject.mm b/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/SKObject.mm new file mode 100644 index 000000000..1f596878f --- /dev/null +++ b/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/SKObject.mm @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +#if FB_SONARKIT_ENABLED + +#import "SKObject.h" + +SKObject::SKObject(CGRect rect) { + _actual = @{ + @"origin": SKObject(rect.origin), + @"size": SKObject(rect.size) + }; +} + +SKObject::SKObject(CGSize size) { + _actual = @{ + @"height": @(size.height), + @"width": @(size.width) + }; +} + +SKObject::SKObject(CGPoint point) { + _actual = @{ + @"x": @(point.x), + @"y": @(point.y) + }; +} + +SKObject::SKObject(UIEdgeInsets insets) { + _actual = @{ + @"top": @(insets.top), + @"bottom": @(insets.bottom), + @"left": @(insets.left), + @"right": @(insets.right), + }; +} + +SKObject::SKObject(CGAffineTransform transform) { + _actual = @{ + @"a": @(transform.a), + @"b": @(transform.b), + @"c": @(transform.c), + @"d": @(transform.d), + @"tx": @(transform.tx), + @"ty": @(transform.ty), + }; +} + +SKObject::SKObject(id value) : _actual([value sonarValue]) { } + +SKObject::SKObject(id value) : _actual(value) { } + +static NSString *_objectType(id object) { + if ([object isKindOfClass: [NSDictionary class]]) { + return (NSString *)((NSDictionary *)object)[@"__type__"]; + } + + return nil; +} + +static id _objectValue(id object) { + if ([object isKindOfClass: [NSDictionary class]]) { + return ((NSDictionary *)object)[@"value"]; + } + + return object; +} + +static NSDictionary> *_SKValue(id object, BOOL isMutable) { + NSString *type = _objectType(object); + id value = _objectValue(object); + + return @{ + @"__type__": (type != nil ? type : @"auto"), + @"__mutable__": @(isMutable), + @"value": (value != nil ? value : [NSNull null]), + }; +} + +static NSDictionary *_SKMutable(const NSDictionary> *skObject) { + NSMutableDictionary *mutableObject = [NSMutableDictionary new]; + for (NSString *key: skObject) { + id value = skObject[key]; + + if (_objectType(value) != nil) { + mutableObject[key] = _SKValue(value, YES); + } else if ([value isKindOfClass: [NSDictionary class]]) { + auto objectValue = (NSDictionary>*) value; + mutableObject[key] = _SKMutable(objectValue); + } else { + mutableObject[key] = _SKValue(value, YES); + } + } + + return mutableObject; +} + +void SKMutableObject::convertToMutable() { + if (_convertedToMutable) { + return; + } + + if (_objectType(_actual) == nil && [_actual isKindOfClass: [NSDictionary class]]) { + auto object = (const NSDictionary> *)_actual; + _actual = _SKMutable(object); + } else { + _actual = _SKValue(_actual, YES); + } + + _convertedToMutable = YES; +} + +#endif diff --git a/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/SKSearchResultNode.h b/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/SKSearchResultNode.h new file mode 100644 index 000000000..d156af6cc --- /dev/null +++ b/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/SKSearchResultNode.h @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2004-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +#ifndef SKSearchResultNode_h +#define SKSearchResultNode_h + +#import + +@interface SKSearchResultNode : NSObject + +@property (nonatomic, copy, readonly) NSString *nodeId; + +- (instancetype)initWithNode:(NSString *)nodeId + asMatch:(BOOL)isMatch + withElement:(NSDictionary *)element + andChildren:(NSArray *)children; + +- (NSDictionary *)toNSDictionary; + +@end +#endif /* SKSearchResultNode_h */ diff --git a/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/SKSearchResultNode.m b/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/SKSearchResultNode.m new file mode 100644 index 000000000..a1e99cc6c --- /dev/null +++ b/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/SKSearchResultNode.m @@ -0,0 +1,50 @@ +// Copyright 2004-present Facebook. All Rights Reserved. + +#import "SKSearchResultNode.h" + +@implementation SKSearchResultNode { + NSString *_nodeId; + BOOL _isMatch; + NSDictionary *_element; + NSArray *_children; +} + +- (instancetype)initWithNode:(NSString *)nodeId + asMatch:(BOOL)isMatch + withElement:(NSDictionary *)element + andChildren:(NSArray *)children { + self = [super init]; + if (self) { + _nodeId = nodeId; + _isMatch = isMatch; + _element = element; + _children = children; + } + return self; +} + +- (NSDictionary *)toNSDictionary { + if (_element == nil) { + return nil; + } + NSMutableArray *childArray; + if (_children) { + childArray = [NSMutableArray new]; + for (SKSearchResultNode *child in _children) { + NSDictionary *childDict = [child toNSDictionary]; + if (childDict) { + [childArray addObject:childDict]; + } + } + } else { + childArray = nil; + } + return @{ + @"id": _nodeId, + @"isMatch": @(_isMatch), + @"element": _element, + @"children": childArray ?: [NSNull null] + }; +} + +@end diff --git a/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/SKTapListener.h b/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/SKTapListener.h new file mode 100644 index 000000000..87ccb3d60 --- /dev/null +++ b/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/SKTapListener.h @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +#import + +typedef void (^SKTapReceiver)(CGPoint touchPoint); + +@protocol SKTapListener + +@property (nonatomic, readonly) BOOL isMounted; + +- (void)mountWithFrame:(CGRect)frame; + +- (void)unmount; + +- (void)listenForTapWithBlock:(SKTapReceiver)receiver; + +@end diff --git a/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/SKTapListenerImpl.h b/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/SKTapListenerImpl.h new file mode 100644 index 000000000..73d23722b --- /dev/null +++ b/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/SKTapListenerImpl.h @@ -0,0 +1,12 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +#import "SKTapListener.h" + +@interface SKTapListenerImpl : NSObject + +@end diff --git a/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/SKTapListenerImpl.m b/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/SKTapListenerImpl.m new file mode 100644 index 000000000..08af8d5f5 --- /dev/null +++ b/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/SKTapListenerImpl.m @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +#if FB_SONARKIT_ENABLED + +#import "SKTapListenerImpl.h" + +#import "SKHighlightOverlay.h" +#import "SKHiddenWindow.h" + +@implementation SKTapListenerImpl +{ + NSMutableArray *_receiversWaitingForInput; + UITapGestureRecognizer *_gestureRecognizer; + + SKHiddenWindow *_overlayWindow; +} + +@synthesize isMounted = _isMounted; + +- (instancetype)init { + if (self = [super init]) { + _receiversWaitingForInput = [NSMutableArray new]; + + _gestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget: self action: nil]; + _gestureRecognizer.delegate = self; + + _isMounted = NO; + + _overlayWindow = [SKHiddenWindow new]; + _overlayWindow.hidden = YES; + _overlayWindow.windowLevel = UIWindowLevelAlert; + _overlayWindow.backgroundColor = [SKHighlightOverlay overlayColor]; + + [_overlayWindow addGestureRecognizer: _gestureRecognizer]; + } + + return self; +} + +- (void)mountWithFrame:(CGRect)frame { + if (_isMounted) { + return; + } + + [_overlayWindow setFrame: frame]; + [_overlayWindow makeKeyAndVisible]; + _overlayWindow.hidden = NO; + + _isMounted = YES; +} + +- (void)unmount { + if (!_isMounted) { + return; + } + + [_receiversWaitingForInput removeAllObjects]; + [_overlayWindow removeFromSuperview]; + _overlayWindow.hidden = YES; + + _isMounted = NO; +} + +- (void)listenForTapWithBlock:(SKTapReceiver)receiver { + [_receiversWaitingForInput addObject: receiver]; +} + +- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch { + if ([_receiversWaitingForInput count] == 0) { + return YES; + } + + CGPoint touchPoint = [touch locationInView: _overlayWindow]; + + for (SKTapReceiver recv in _receiversWaitingForInput) { + recv(touchPoint); + } + + [_receiversWaitingForInput removeAllObjects]; + + return NO; +} + +@end + +#endif diff --git a/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/SKTouch.h b/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/SKTouch.h new file mode 100644 index 000000000..9b2633fdb --- /dev/null +++ b/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/SKTouch.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +#import + +#import "SKDescriptorMapper.h" + +typedef void (^SKTouchFinishDelegate)(NSArray *path); + +@interface SKTouch : NSObject + +- (instancetype)initWithTouchPoint:(CGPoint)touchPoint + withRootNode:(id)node + withDescriptorMapper:(SKDescriptorMapper *)mapper + finishWithBlock:(SKTouchFinishDelegate)d; + +- (void)continueWithChildIndex:(NSUInteger)childIndex + withOffset:(CGPoint)offset; + +- (void)finish; + +- (BOOL)containedIn:(CGRect)bounds; + +@end diff --git a/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/SKTouch.m b/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/SKTouch.m new file mode 100644 index 000000000..72cab85bf --- /dev/null +++ b/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/SKTouch.m @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +#if FB_SONARKIT_ENABLED + +#import "SKTouch.h" +#import "SKNodeDescriptor.h" + +@implementation SKTouch +{ + SKTouchFinishDelegate _onFinish; + NSMutableArray *_path; + + CGPoint _currentTouchPoint; + id _currentNode; + + SKDescriptorMapper *_descriptorMapper; +} + +- (instancetype)initWithTouchPoint:(CGPoint)touchPoint + withRootNode:(id)node + withDescriptorMapper:(SKDescriptorMapper *)mapper + finishWithBlock:(SKTouchFinishDelegate)finishBlock { + if (self = [super init]) { + _onFinish = finishBlock; + _currentTouchPoint = touchPoint; + _currentNode = node; + _descriptorMapper = mapper; + _path = [NSMutableArray new]; + } + + return self; +} + +- (void)continueWithChildIndex:(NSUInteger)childIndex withOffset:(CGPoint)offset { + _currentTouchPoint.x -= offset.x; + _currentTouchPoint.y -= offset.y; + + SKNodeDescriptor *descriptor = [_descriptorMapper descriptorForClass: [_currentNode class]]; + _currentNode = [descriptor childForNode: _currentNode atIndex: childIndex]; + + descriptor = [_descriptorMapper descriptorForClass: [_currentNode class]]; + [_path addObject: [descriptor identifierForNode: _currentNode]]; + + [descriptor hitTest: self forNode: _currentNode]; +} + +- (void)finish { + _onFinish(_path); +} + +- (BOOL)containedIn:(CGRect)bounds { + return CGRectContainsPoint(bounds, _currentTouchPoint); +} + +@end + +#endif diff --git a/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/SonarKitLayoutPlugin.h b/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/SonarKitLayoutPlugin.h new file mode 100644 index 000000000..db1e31777 --- /dev/null +++ b/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/SonarKitLayoutPlugin.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +#if FB_SONARKIT_ENABLED + +#import + +#import + +#import "SKTapListener.h" +#import "SKInvalidation.h" +#import "SKDescriptorMapper.h" + +@interface SonarKitLayoutPlugin : NSObject + +- (instancetype)initWithRootNode:(id)rootNode + withDescriptorMapper:(SKDescriptorMapper *)mapper; + +- (instancetype)initWithRootNode:(id)rootNode + withTapListener:(id)tapListener + withDescriptorMapper:(SKDescriptorMapper *)mapper; + +@property (nonatomic, readonly, strong) SKDescriptorMapper *descriptorMapper; + +@end + +#endif diff --git a/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/SonarKitLayoutPlugin.mm b/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/SonarKitLayoutPlugin.mm new file mode 100644 index 000000000..2e75a97a8 --- /dev/null +++ b/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/SonarKitLayoutPlugin.mm @@ -0,0 +1,414 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +#if FB_SONARKIT_ENABLED + +#import "SonarKitLayoutPlugin.h" + +#import +#import +#import +#import +#import "SKDescriptorMapper.h" +#import "SKNodeDescriptor.h" +#import "SKTapListener.h" +#import "SKTapListenerImpl.h" +#import "SKSearchResultNode.h" +#import + +@implementation SonarKitLayoutPlugin +{ + + NSMapTable *_trackedObjects; + NSString *_lastHighlightedNode; + NSMutableSet *_invalidObjects; + Boolean _invalidateMessageQueued; + NSDate *_lastInvalidateMessage; + std::mutex invalidObjectsMutex; + + id _rootNode; + id _tapListener; + + id _connection; + + NSMutableSet *_registeredDelegates; +} + +- (instancetype)initWithRootNode:(id)rootNode + withDescriptorMapper:(SKDescriptorMapper *)mapper{ + return [self initWithRootNode: rootNode + withTapListener: [SKTapListenerImpl new] + withDescriptorMapper: mapper]; +} + +- (instancetype)initWithRootNode:(id)rootNode + withTapListener:(id)tapListener + withDescriptorMapper:(SKDescriptorMapper *)mapper { + if (self = [super init]) { + _descriptorMapper = mapper; + _trackedObjects = [NSMapTable strongToWeakObjectsMapTable]; + _lastHighlightedNode = nil; + _invalidObjects = [NSMutableSet new]; + _invalidateMessageQueued = false; + _lastInvalidateMessage = [NSDate date]; + _rootNode = rootNode; + _tapListener = tapListener; + + _registeredDelegates = [NSMutableSet new]; + [SKInvalidation sharedInstance].delegate = self; + } + + return self; +} + +- (NSString *)identifier +{ + return @"Inspector"; +} + +- (void)didConnect:(id)connection { + _connection = connection; + + [SKInvalidation enableInvalidations]; + + // Run setup logic for each descriptor + for (SKNodeDescriptor *descriptor in _descriptorMapper.allDescriptors) { + [descriptor setUp]; + } + + // In order to avoid a retain cycle (Connection -> Block -> SonarKitLayoutPlugin -> Connection ...) + __weak SonarKitLayoutPlugin *weakSelf = self; + + [connection receive:@"getRoot" withBlock:^(NSDictionary *params, id responder) { + SonarPerformBlockOnMainThread(^{ [weakSelf onCallGetRoot: responder]; }); + }]; + + [connection receive:@"getNodes" withBlock:^(NSDictionary *params, id responder) { + SonarPerformBlockOnMainThread(^{ [weakSelf onCallGetNodes: params[@"ids"] withResponder: responder]; }); + }]; + + [connection receive:@"setData" withBlock:^(NSDictionary *params, id responder) { + SonarPerformBlockOnMainThread(^{ + [weakSelf onCallSetData: params[@"id"] + withPath: params[@"path"] + toValue: params[@"value"] + withConnection: connection]; + }); + }]; + + [connection receive:@"setHighlighted" withBlock:^(NSDictionary *params, id responder) { + SonarPerformBlockOnMainThread(^{ [weakSelf onCallSetHighlighted: params[@"id"] withResponder: responder]; }); + }]; + + [connection receive:@"setSearchActive" withBlock:^(NSDictionary *params, id responder) { + SonarPerformBlockOnMainThread(^{ [weakSelf onCallSetSearchActive: [params[@"active"] boolValue] withConnection: connection]; }); + }]; + + [connection receive:@"isConsoleEnabled" withBlock:^(NSDictionary *params, id responder) { + SonarPerformBlockOnMainThread(^{ [responder success: @{@"isEnabled": @NO}];}); + }]; + + [connection receive:@"getSearchResults" withBlock:^(NSDictionary *params, id responder) { + SonarPerformBlockOnMainThread(^{ [weakSelf onCallGetSearchResults: params[@"query"] withResponder: responder]; }); + }]; +} + +- (void)didDisconnect { + // Clear the last highlight if there is any + [self onCallSetHighlighted: nil withResponder: nil]; + // Disable search if it is active + [self onCallSetSearchActive: NO withConnection: nil]; +} + +- (void)onCallGetRoot:(id)responder { + const auto rootNode= [self getNode: [self trackObject: _rootNode]]; + + [responder success: rootNode]; +} + +- (void)onCallGetNodes:(NSArray *)nodeIds withResponder:(id)responder { + NSMutableArray *elements = [NSMutableArray new]; + + for (id nodeId in nodeIds) { + const auto node = [self getNode: nodeId]; + if (node == nil) { + continue; + } + [elements addObject: node]; + } + + [responder success: @{ @"elements": elements }]; +} + +- (void)onCallSetData:(NSString *)objectId + withPath:(NSArray *)path + toValue:(id)value + withConnection:(id)connection { + id node = [_trackedObjects objectForKey: objectId]; + if (node == nil) { + SKLog(@"node is nil, trying to setData: \ + objectId: %@ \ + path: %@ \ + value: %@", + objectId, path, value); + return; + } + + // Sonar sends nil/NSNull on some values when the text-field + // is empty, disregard these changes otherwise we'll crash. + if (value == nil || [value isKindOfClass: [NSNull class]]) { + return; + } + + SKNodeDescriptor *descriptor = [_descriptorMapper descriptorForClass: [node class]]; + + NSString *dotJoinedPath = [path componentsJoinedByString: @"."]; + SKNodeUpdateData updateDataForPath = [[descriptor dataMutationsForNode: node] objectForKey: dotJoinedPath]; + if (updateDataForPath != nil) { + updateDataForPath(value); + [connection send: @"invalidate" withParams: @{ @"id": [descriptor identifierForNode: node] }]; + } +} + +- (void)onCallGetSearchResults:(NSString *)query withResponder:(id)responder { + const auto alreadyAddedElements = [NSMutableSet new]; + SKSearchResultNode *matchTree = [self searchForQuery:(NSString *)[query lowercaseString] fromNode:(id)_rootNode withElementsAlreadyAdded: alreadyAddedElements]; + + [responder success: @{ + @"results": [matchTree toNSDictionary] ?: [NSNull null], + @"query": query + }]; + return; +} + +- (void)onCallSetHighlighted:(NSString *)objectId withResponder:(id)responder { + if (_lastHighlightedNode != nil) { + id lastHighlightedObject = [_trackedObjects objectForKey: _lastHighlightedNode]; + if (lastHighlightedObject == nil) { + [responder error: @{ @"error": @"unable to get last highlighted object" }]; + return; + } + + SKNodeDescriptor *descriptor = [self->_descriptorMapper descriptorForClass: [lastHighlightedObject class]]; + [descriptor setHighlighted: NO forNode: lastHighlightedObject]; + + _lastHighlightedNode = nil; + } + + if (objectId == nil || [objectId isKindOfClass:[NSNull class]]) { + return; + } + + id object = [_trackedObjects objectForKey: objectId]; + if (object == nil) { + SKLog(@"tried to setHighlighted for untracked id, objectId: %@", objectId); + return; + } + + SKNodeDescriptor *descriptor = [self->_descriptorMapper descriptorForClass: [object class]]; + [descriptor setHighlighted: YES forNode: object]; + + _lastHighlightedNode = objectId; +} + +- (void)onCallSetSearchActive:(BOOL)active withConnection:(id)connection { + if (active) { + [_tapListener mountWithFrame: [[UIScreen mainScreen] bounds]]; + __block id rootNode = _rootNode; + + [_tapListener listenForTapWithBlock:^(CGPoint touchPoint) { + SKTouch *touch = + [[SKTouch alloc] initWithTouchPoint: touchPoint + withRootNode: rootNode + withDescriptorMapper: self->_descriptorMapper + finishWithBlock:^(NSArray *path) { + [connection send: @"select" + withParams: @{ @"path": path }]; + }]; + + SKNodeDescriptor *descriptor = [self->_descriptorMapper descriptorForClass: [rootNode class]]; + [descriptor hitTest: touch forNode: rootNode]; + }]; + } else { + [_tapListener unmount]; + } +} + +- (void)invalidateNode:(id)node { + SKNodeDescriptor *descriptor = [_descriptorMapper descriptorForClass: [node class]]; + if (descriptor == nil) { + return; + } + + NSString *nodeId = [descriptor identifierForNode: node]; + if (![_trackedObjects objectForKey: nodeId]) { + return; + } + [descriptor invalidateNode: node]; + + // Collect invalidate messages before sending in a batch + std::lock_guard lock(invalidObjectsMutex); + [_invalidObjects addObject:nodeId]; + if (_invalidateMessageQueued) { + return; + } + _invalidateMessageQueued = true; + + if (_lastInvalidateMessage.timeIntervalSinceNow < -1) { + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 500 * NSEC_PER_MSEC), dispatch_get_main_queue(), ^{ + [self reportInvalidatedObjects]; + }); + } +} + +- (void)reportInvalidatedObjects { + std::lock_guard lock(invalidObjectsMutex); + NSMutableArray *nodes = [NSMutableArray new]; + for (NSString *nodeId in self->_invalidObjects) { + [nodes addObject: [NSDictionary dictionaryWithObject: nodeId forKey: @"id"]]; + } + [self->_connection send: @"invalidate" withParams: [NSDictionary dictionaryWithObject: nodes forKey: @"nodes"]]; + self->_lastInvalidateMessage = [NSDate date]; + self->_invalidObjects = [NSMutableSet new]; + self->_invalidateMessageQueued = false; + return; +} + +- (void)updateNodeReference:(id)node { + SKNodeDescriptor *descriptor = [_descriptorMapper descriptorForClass: [node class]]; + if (descriptor == nil) { + return; + } + + NSString *nodeId = [descriptor identifierForNode: node]; + [_trackedObjects setObject:node forKey:nodeId]; +} + +- (SKSearchResultNode *)searchForQuery:(NSString *)query fromNode:(id)node withElementsAlreadyAdded:(NSMutableSet *)alreadyAdded { + SKNodeDescriptor *descriptor = [_descriptorMapper descriptorForClass: [node class]]; + if (node == nil || descriptor == nil) { + return nil; + } + + NSMutableArray *childTrees = nil; + BOOL isMatch = [descriptor matchesQuery: query forNode: node]; + + NSString *nodeId = [self trackObject: node]; + + for (auto i = 0; i < [descriptor childCountForNode: node]; i++) { + id child = [descriptor childForNode: node atIndex: i]; + if (child) { + SKSearchResultNode *childTree = [self searchForQuery: query fromNode: child withElementsAlreadyAdded:alreadyAdded]; + if (childTree != nil) { + if (childTrees == nil) { + childTrees = [NSMutableArray new]; + } + [childTrees addObject: childTree]; + } + } + } + + if (isMatch || childTrees != nil) { + + NSDictionary *element = [self getNode: nodeId]; + if (nodeId == nil || element == nil) { + return nil; + } + NSMutableArray *descriptorChildElements = [element objectForKey: @"children"]; + NSMutableDictionary *newElement = [element mutableCopy]; + + NSMutableArray *childElementsToReturn = [NSMutableArray new]; + for (NSString *child in descriptorChildElements) { + if (![alreadyAdded containsObject: child]) { + [alreadyAdded addObject: child]; //todo add all at end + [childElementsToReturn addObject: child]; + } + } + [newElement setObject: childElementsToReturn forKey: @"children"]; + return [[SKSearchResultNode alloc] initWithNode: nodeId + asMatch: isMatch + withElement: newElement + andChildren: childTrees]; + } + return nil; +} + +- (NSDictionary *)getNode:(NSString *)nodeId { + id node = [_trackedObjects objectForKey: nodeId]; + if (node == nil) { + SKLog(@"node is nil, no tracked node found for nodeId: %@", nodeId); + return nil; + } + + SKNodeDescriptor *nodeDescriptor = [_descriptorMapper descriptorForClass: [node class]]; + if (nodeDescriptor == nil) { + SKLog(@"No registered descriptor for class: %@", [node class]); + return nil; + } + + NSMutableArray *attributes = [NSMutableArray new]; + NSMutableDictionary *data = [NSMutableDictionary new]; + + const auto *nodeAttributes = [nodeDescriptor attributesForNode: node]; + for (const SKNamed *namedPair in nodeAttributes) { + const auto name = namedPair.name; + if (name) { + const NSDictionary *attribute = @{ + @"name": name, + @"value": namedPair.value ?: [NSNull null], + }; + [attributes addObject: attribute]; + } + } + + const auto *nodeData = [nodeDescriptor dataForNode: node]; + for (const SKNamed *namedPair in nodeData) { + data[namedPair.name] = namedPair.value; + } + + NSMutableArray *children = [NSMutableArray new]; + for (NSUInteger i = 0; i < [nodeDescriptor childCountForNode: node]; i++) { + id childNode = [nodeDescriptor childForNode: node atIndex: i]; + + NSString *childIdentifier = [self trackObject: childNode]; + if (childIdentifier) { + [children addObject: childIdentifier]; + } + } + + NSDictionary *nodeDic = + @{ + // We shouldn't get nil for id/name/decoration, but let's not crash if we do. + @"id": [nodeDescriptor identifierForNode: node] ?: @"(unknown)", + @"name": [nodeDescriptor nameForNode: node] ?: @"(unknown)", + @"children": children, + @"attributes": attributes, + @"data": data, + @"decoration": [nodeDescriptor decorationForNode: node] ?: @"(unknown)", + }; + + return nodeDic; +} + +- (NSString *)trackObject:(id)object { + const SKNodeDescriptor *descriptor = [_descriptorMapper descriptorForClass: [object class]]; + NSString *objectIdentifier = [descriptor identifierForNode: object]; + + if (objectIdentifier == nil) { + return nil; + } + + if (! [_trackedObjects objectForKey: objectIdentifier]) { + [_trackedObjects setObject:object forKey:objectIdentifier]; + } + + return objectIdentifier; +} + +@end + +#endif diff --git a/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/UICollectionView+SKInvalidation.h b/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/UICollectionView+SKInvalidation.h new file mode 100644 index 000000000..f2b013d84 --- /dev/null +++ b/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/UICollectionView+SKInvalidation.h @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +#import + +#import + +FB_LINK_REQUIRE(UICollectionView_SKInvalidation) +@interface UICollectionView (SKInvalidation) + ++ (void)enableInvalidations; + +@end diff --git a/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/UICollectionView+SKInvalidation.mm b/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/UICollectionView+SKInvalidation.mm new file mode 100644 index 000000000..b33e58094 --- /dev/null +++ b/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/UICollectionView+SKInvalidation.mm @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +#if FB_SONARKIT_ENABLED + +#import "UICollectionView+SKInvalidation.h" + +#import "SKInvalidation.h" +#import "SKSwizzle.h" + +FB_LINKABLE(UICollectionView_SKInvalidation) +@implementation UICollectionView (SKInvalidation) + ++ (void)enableInvalidations { + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + swizzleMethods([self class], @selector(cellForItemAtIndexPath:), @selector(swizzle_cellForItemAtIndexPath:)); + }); +} + +- (UICollectionViewCell *)swizzle_cellForItemAtIndexPath:(NSIndexPath *)indexPath { + dispatch_async(dispatch_get_main_queue(), ^{ + [[SKInvalidation sharedInstance].delegate invalidateNode: self]; + }); + + return [self swizzle_cellForItemAtIndexPath: indexPath]; +} + +@end + +#endif diff --git a/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/UIColor+SKSonarValueCoder.h b/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/UIColor+SKSonarValueCoder.h new file mode 100644 index 000000000..811204077 --- /dev/null +++ b/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/UIColor+SKSonarValueCoder.h @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +#import + +#import + +#import "SKObject.h" + +FB_LINK_REQUIRE(UIColor_SonarValueCoder) +@interface UIColor (SonarValueCoder) + +@end diff --git a/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/UIColor+SKSonarValueCoder.mm b/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/UIColor+SKSonarValueCoder.mm new file mode 100644 index 000000000..4540be2a3 --- /dev/null +++ b/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/UIColor+SKSonarValueCoder.mm @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +#if FB_SONARKIT_ENABLED + +#import "UIColor+SKSonarValueCoder.h" + +FB_LINKABLE(UIColor_SonarValueCoder) +@implementation UIColor (SonarValueCoder) + ++ (instancetype)fromSonarValue:(NSNumber *)sonarValue { + NSUInteger intColor = [sonarValue integerValue]; + + CGFloat r, g, b, a; + + b = CGFloat(intColor & 0xFF) / 255; + g = CGFloat((intColor >> 8) & 0xFF) / 255; + r = CGFloat((intColor >> 16) & 0xFF) / 255; + a = CGFloat((intColor >> 24) & 0xFF) / 255; + + return [[UIColor alloc] initWithRed: r green: g blue: b alpha: a]; +} + +- (NSDictionary> *)sonarValue { + CGColorSpaceRef colorSpace = CGColorGetColorSpace([self CGColor]); + CGColorSpaceModel colorSpaceModel = CGColorSpaceGetModel(colorSpace); + + NSUInteger red, green, blue, alpha; + + switch (colorSpaceModel) { + case kCGColorSpaceModelUnknown: + case kCGColorSpaceModelRGB: { + CGFloat r, g, b, a; + [self getRed: &r green: &g blue: &b alpha: &a]; + + red = (NSUInteger)(r * 255) & 0xFF; + green = (NSUInteger)(g * 255) & 0xFF; + blue = (NSUInteger)(b * 255) & 0xFF; + alpha = (NSUInteger)(a * 255) & 0xFF; + } break; + + case kCGColorSpaceModelMonochrome: { + CGFloat a, w; + [self getWhite: &w alpha: &a]; + + red = green = blue = (NSUInteger)(w * 255) & 0xFF; + alpha = (NSUInteger)(a * 255) & 0xFF; + } break; + + default: + red = green = blue = alpha = 0; + } + + NSUInteger intColor = (alpha << 24) | (red << 16) | (green << 8) | blue; + return @{ + @"__type__": @"color", + @"__mutable__": @NO, + @"value": @(intColor) + }; +} + +@end + +#endif diff --git a/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/UIView+SKInvalidation.h b/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/UIView+SKInvalidation.h new file mode 100644 index 000000000..ee0699925 --- /dev/null +++ b/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/UIView+SKInvalidation.h @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +#import + +FB_LINK_REQUIRE(UIView_SKInvalidation) +@interface UIView (SKInvalidation) + ++ (void)enableInvalidation; + +@end diff --git a/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/UIView+SKInvalidation.mm b/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/UIView+SKInvalidation.mm new file mode 100644 index 000000000..ca1e6acf3 --- /dev/null +++ b/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/UIView+SKInvalidation.mm @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +#if FB_SONARKIT_ENABLED + +#import +#import + +#import "SKInvalidation.h" +#import "SKSwizzle.h" +#import "UIView+SKInvalidation.h" + +FB_LINKABLE(UIView_SKInvalidation) +@implementation UIView (SKInvalidation) + ++ (void)enableInvalidation { + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + swizzleMethods([self class], @selector(setHidden:), @selector(swizzle_setHidden:)); + swizzleMethods([self class], @selector(addSubview:), @selector(swizzle_addSubview:)); + swizzleMethods([self class], @selector(removeFromSuperview), @selector(swizzle_removeFromSuperview)); + }); +} + +- (void)swizzle_setHidden:(BOOL)hidden { + [self swizzle_setHidden: hidden]; + + id delegate = [SKInvalidation sharedInstance].delegate; + if (delegate != nil) { + [delegate invalidateNode: self.superview]; + } +} + +- (void)swizzle_addSubview:(UIView *)view { + [self swizzle_addSubview: view]; + + id delegate = [SKInvalidation sharedInstance].delegate; + if (delegate != nil) { + [delegate invalidateNode: view]; + } +} + +- (void)swizzle_removeFromSuperview { + id delegate = [SKInvalidation sharedInstance].delegate; + if (delegate != nil && self.superview != nil) { + [delegate invalidateNode: self.superview]; + } + + [self swizzle_removeFromSuperview]; +} + +@end + +#endif diff --git a/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/descriptors/SKApplicationDescriptor.h b/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/descriptors/SKApplicationDescriptor.h new file mode 100644 index 000000000..8b4b7c4fa --- /dev/null +++ b/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/descriptors/SKApplicationDescriptor.h @@ -0,0 +1,14 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +#import + +#import "SKNodeDescriptor.h" + +@interface SKApplicationDescriptor : SKNodeDescriptor + +@end diff --git a/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/descriptors/SKApplicationDescriptor.m b/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/descriptors/SKApplicationDescriptor.m new file mode 100644 index 000000000..9221f112d --- /dev/null +++ b/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/descriptors/SKApplicationDescriptor.m @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +#if FB_SONARKIT_ENABLED + +#import "SKApplicationDescriptor.h" + +#import "SKDescriptorMapper.h" +#import "SKHiddenWindow.h" +#import + +@implementation SKApplicationDescriptor + +- (NSString *)identifierForNode:(UIApplication *)node { + return [NSString stringWithFormat: @"%p", node]; +} + +- (NSUInteger)childCountForNode:(UIApplication *)node { + return [[self visibleChildrenForNode: node] count]; +} + +- (id)childForNode:(UIApplication *)node atIndex:(NSUInteger)index { + return [self visibleChildrenForNode: node][index]; +} + +- (void)setHighlighted:(BOOL)highlighted forNode:(UIApplication *)node { + SKNodeDescriptor *windowDescriptor = [self descriptorForClass: [UIWindow class]]; + [windowDescriptor setHighlighted: highlighted forNode: [node keyWindow]]; +} + +- (void)hitTest:(SKTouch *)touch forNode:(UIApplication *)node { + for (NSInteger index = [self childCountForNode: node] - 1; index >= 0; index--) { + UIWindow *child = [self childForNode: node atIndex: index]; + if (child.isHidden || child.alpha <= 0) { + continue; + } + + if ([touch containedIn: child.frame]) { + [touch continueWithChildIndex: index withOffset: child.frame.origin]; + return; + } + } + + [touch finish]; +} + +- (NSArray *)visibleChildrenForNode:(UIApplication *)node { + NSMutableArray *children = [NSMutableArray new]; + for (UIWindow *window in node.windows) { + if ([window isKindOfClass: [SKHiddenWindow class]] + || [window isKindOfClass:objc_lookUpClass("FBAccessibilityOverlayWindow")] + || [window isKindOfClass:objc_lookUpClass("UITextEffectsWindow")]) { + continue; + } + [children addObject: window]; + } + return children; +} + +@end + +#endif diff --git a/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/descriptors/SKButtonDescriptor.h b/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/descriptors/SKButtonDescriptor.h new file mode 100644 index 000000000..cd76d94b0 --- /dev/null +++ b/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/descriptors/SKButtonDescriptor.h @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +#import + +#import "SKNodeDescriptor.h" + +@class UIButton; + +@interface SKButtonDescriptor : SKNodeDescriptor + +@end diff --git a/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/descriptors/SKButtonDescriptor.mm b/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/descriptors/SKButtonDescriptor.mm new file mode 100644 index 000000000..e486fbd21 --- /dev/null +++ b/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/descriptors/SKButtonDescriptor.mm @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +#if FB_SONARKIT_ENABLED + +#import "SKButtonDescriptor.h" + +#import "SKDescriptorMapper.h" +#import "SKObject.h" +#import "UIColor+SKSonarValueCoder.h" + +@implementation SKButtonDescriptor + +- (NSString *)identifierForNode:(UIButton *)node { + return [NSString stringWithFormat: @"%p", node]; +} + +- (NSUInteger)childCountForNode:(UIButton *)node { + return 0; +} + +- (id)childForNode:(UIButton *)node atIndex:(NSUInteger)index { + return nil; +} + +- (NSArray *> *)dataForNode:(UIButton *)node { + SKNodeDescriptor *viewDescriptor = [self descriptorForClass: [UIView class]]; + auto *viewData = [viewDescriptor dataForNode: node]; + + NSMutableArray *data = [NSMutableArray new]; + [data addObjectsFromArray: viewData]; + [data addObject: + [SKNamed newWithName: @"UIButton" + withValue: @{ + @"focused": @(node.focused), + @"enabled": SKMutableObject(@(node.enabled)), + @"highlighted": SKMutableObject(@(node.highlighted)), + @"titleEdgeInsets": SKObject(node.titleEdgeInsets), + @"titleLabel": SKMutableObject(node.titleLabel.attributedText.string.stringByStandardizingPath), + @"currentTitleColor": SKMutableObject(node.currentTitleColor), + }] + ]; + + return data; +} + +- (NSDictionary *)dataMutationsForNode:(UIButton *)node { + NSDictionary *buttonMutations = @{ + @"UIButton.titleLabel": ^(NSString *newValue) { + [node setTitle: newValue forState: node.state]; + }, + @"UIButton.currentTitleColor": ^(NSNumber *newValue) { + [node setTitleColor: [UIColor fromSonarValue: newValue] forState: node.state]; + }, + @"UIButton.highlighted": ^(NSNumber *highlighted) { + [node setHighlighted: [highlighted boolValue]]; + }, + @"UIButton.enabled": ^(NSNumber *enabled) { + [node setEnabled: [enabled boolValue]]; + } + }; + + SKNodeDescriptor *viewDescriptor = [self descriptorForClass: [UIView class]]; + NSDictionary *viewMutations = [viewDescriptor dataMutationsForNode: node]; + + NSMutableDictionary *mutations = [NSMutableDictionary new]; + [mutations addEntriesFromDictionary: buttonMutations]; + [mutations addEntriesFromDictionary: viewMutations]; + + return mutations; +} + +- (NSArray *> *)attributesForNode:(UIScrollView *)node { + SKNodeDescriptor *descriptor = [self descriptorForClass: [UIView class]]; + return [descriptor attributesForNode: node]; +} + +- (void)setHighlighted:(BOOL)highlighted forNode:(UIButton *)node { + SKNodeDescriptor *viewDescriptor = [self descriptorForClass: [UIView class]]; + [viewDescriptor setHighlighted: highlighted forNode: node]; +} + +- (void)hitTest:(SKTouch *)touch forNode:(UIButton *)node { + [touch finish]; +} + +@end + +#endif diff --git a/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/descriptors/SKScrollViewDescriptor.h b/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/descriptors/SKScrollViewDescriptor.h new file mode 100644 index 000000000..4a221d93c --- /dev/null +++ b/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/descriptors/SKScrollViewDescriptor.h @@ -0,0 +1,14 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +#import + +#import "SKNodeDescriptor.h" + +@interface SKScrollViewDescriptor : SKNodeDescriptor + +@end diff --git a/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/descriptors/SKScrollViewDescriptor.m b/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/descriptors/SKScrollViewDescriptor.m new file mode 100644 index 000000000..66e7991e4 --- /dev/null +++ b/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/descriptors/SKScrollViewDescriptor.m @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +#if FB_SONARKIT_ENABLED + +#import "SKScrollViewDescriptor.h" + +#import "SKDescriptorMapper.h" + +@implementation SKScrollViewDescriptor + +- (NSString *)identifierForNode:(UIScrollView *)node { + SKNodeDescriptor *descriptor = [self descriptorForClass: [UIView class]]; + return [descriptor identifierForNode: node]; +} + +- (NSUInteger)childCountForNode:(UIScrollView *)node { + SKNodeDescriptor *descriptor = [self descriptorForClass: [UIView class]]; + return [descriptor childCountForNode: node]; +} + +- (id)childForNode:(UIScrollView *)node atIndex:(NSUInteger)index { + SKNodeDescriptor *descriptor = [self descriptorForClass: [UIView class]]; + return [descriptor childForNode: node atIndex: index]; +} + +- (id)dataForNode:(UIScrollView *)node { + SKNodeDescriptor *descriptor = [self descriptorForClass: [UIView class]]; + return [descriptor dataForNode:node]; +} + +- (id)dataMutationsForNode:(UIScrollView *)node { + SKNodeDescriptor *descriptor = [self descriptorForClass: [UIView class]]; + return [descriptor dataMutationsForNode:node]; +} + +- (NSArray *> *)attributesForNode:(UIScrollView *)node { + SKNodeDescriptor *descriptor = [self descriptorForClass: [UIView class]]; + return [descriptor attributesForNode: node]; +} + +- (void)setHighlighted:(BOOL)highlighted forNode:(UIScrollView *)node { + SKNodeDescriptor *descriptor = [self descriptorForClass: [UIView class]]; + [descriptor setHighlighted: highlighted forNode: node]; +} + +- (void)hitTest:(SKTouch *)touch forNode:(UIScrollView *)node { + for (NSInteger index = [self childCountForNode: node] - 1; index >= 0; index--) { + id childNode = [self childForNode: node atIndex: index]; + CGRect frame; + + if ([childNode isKindOfClass: [UIViewController class]]) { + UIViewController *child = (UIViewController *)childNode; + if (child.view.isHidden) { + continue; + } + + frame = child.view.frame; + } else { + UIView *child = (UIView *)childNode; + if (child.isHidden) { + continue; + } + + frame = child.frame; + } + + frame.origin.x -= node.contentOffset.x; + frame.origin.y -= node.contentOffset.y; + + if ([touch containedIn: frame]) { + [touch continueWithChildIndex: index withOffset: frame.origin]; + return; + } + } + + [touch finish]; +} + +@end + +#endif diff --git a/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/descriptors/SKViewControllerDescriptor.h b/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/descriptors/SKViewControllerDescriptor.h new file mode 100644 index 000000000..6e7280899 --- /dev/null +++ b/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/descriptors/SKViewControllerDescriptor.h @@ -0,0 +1,14 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +#import + +#import "SKNodeDescriptor.h" + +@interface SKViewControllerDescriptor : SKNodeDescriptor + +@end diff --git a/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/descriptors/SKViewControllerDescriptor.m b/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/descriptors/SKViewControllerDescriptor.m new file mode 100644 index 000000000..f1fab8858 --- /dev/null +++ b/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/descriptors/SKViewControllerDescriptor.m @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +#if FB_SONARKIT_ENABLED + +#import "SKViewControllerDescriptor.h" + +#import "SKDescriptorMapper.h" + +@implementation SKViewControllerDescriptor + +- (NSString *)identifierForNode:(UIViewController *)node { + return [NSString stringWithFormat: @"%p", node]; +} + +- (NSUInteger)childCountForNode:(UIViewController *)node { + return 1; +} + +- (id)childForNode:(UIViewController *)node atIndex:(NSUInteger)index { + return node.view; +} + +- (void)setHighlightedForNode:(UIViewController *)node { +} + +- (NSArray *> *)attributesForNode:(UIViewController *)node { + return @[ + [SKNamed newWithName: @"addr" + withValue: [NSString stringWithFormat: @"%p", node]] + ]; +} + +- (void)setHighlighted:(BOOL)highlighted forNode:(UIViewController *)node { + SKNodeDescriptor *descriptor = [self descriptorForClass: [UIView class]]; + [descriptor setHighlighted: highlighted forNode: node.view]; +} + +- (void)hitTest:(SKTouch *)touch forNode:(UIViewController *)node { + [touch continueWithChildIndex: 0 withOffset: (CGPoint){ 0, 0}]; +} + + +@end + +#endif diff --git a/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/descriptors/SKViewDescriptor.h b/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/descriptors/SKViewDescriptor.h new file mode 100644 index 000000000..410e83c79 --- /dev/null +++ b/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/descriptors/SKViewDescriptor.h @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +#if FB_SONARKIT_ENABLED + +#import + +#import "SKNodeDescriptor.h" + +@interface SKViewDescriptor : SKNodeDescriptor + +@end + +#endif diff --git a/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/descriptors/SKViewDescriptor.mm b/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/descriptors/SKViewDescriptor.mm new file mode 100644 index 000000000..c6b1be3f7 --- /dev/null +++ b/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/descriptors/SKViewDescriptor.mm @@ -0,0 +1,575 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +#if FB_SONARKIT_ENABLED + +#import "SKViewDescriptor.h" + +#import "SKDescriptorMapper.h" +#import "SKHighlightOverlay.h" +#import "SKNamed.h" +#import "SKObject.h" +#import "SKYogaKitHelper.h" +#import "UIColor+SKSonarValueCoder.h" +#import + +@implementation SKViewDescriptor + +static NSDictionary *YGDirectionEnumMap = nil; +static NSDictionary *YGFlexDirectionEnumMap = nil; +static NSDictionary *YGJustifyEnumMap = nil; +static NSDictionary *YGAlignEnumMap = nil; +static NSDictionary *YGPositionTypeEnumMap = nil; +static NSDictionary *YGWrapEnumMap = nil; +static NSDictionary *YGOverflowEnumMap = nil; +static NSDictionary *YGDisplayEnumMap = nil; +static NSDictionary *YGUnitEnumMap = nil; + +- (instancetype)initWithDescriptorMapper:(SKDescriptorMapper *)mapper { + if (self = [super initWithDescriptorMapper: mapper]) { + initEnumDictionaries(); + } + + return self; +} + +- (NSString *)identifierForNode:(UIView *)node { + return [NSString stringWithFormat: @"%p", node]; +} + +- (NSUInteger)childCountForNode:(UIView *)node { + return [[self validChildrenForNode: node] count]; +} + +- (id)childForNode:(UIView *)node atIndex:(NSUInteger)index { + return [[self validChildrenForNode:node] objectAtIndex: index]; +} + +- (NSArray *)validChildrenForNode:(UIView *)node { + NSMutableArray *validChildren = [NSMutableArray new]; + + // Use UIViewControllers for children which responds to a different + // viewController than their parent + for (UIView *child in node.subviews) { + BOOL responderIsUIViewController = [child.nextResponder isKindOfClass: [UIViewController class]]; + + if (!child.isHidden) { + if (responderIsUIViewController && child.nextResponder != node.nextResponder) { + [validChildren addObject: child.nextResponder]; + } else { + [validChildren addObject: child]; + } + } + } + + return validChildren; +} + +- (NSArray *> *)dataForNode:(UIView *)node { + return [NSArray arrayWithObjects: + [SKNamed newWithName: @"UIView" + withValue: @{ + @"frame": SKMutableObject(node.frame), + @"bounds": SKObject(node.bounds), + @"center": SKObject(node.center), + @"layoutMargins": SKObject(node.layoutMargins), + @"clipsToBounds": @(node.clipsToBounds), + @"alpha": SKMutableObject(@(node.alpha)), + @"tag": @(node.tag), + @"backgroundColor": SKMutableObject(node.backgroundColor) + }], + [SKNamed newWithName: @"CALayer" + withValue: @{ + @"shadowColor": SKMutableObject([UIColor colorWithCGColor:node.layer.shadowColor]), + @"shadowOpacity": SKMutableObject(@(node.layer.shadowOpacity)), + @"shadowRadius": SKMutableObject(@(node.layer.shadowRadius)), + @"shadowOffset": SKMutableObject(node.layer.shadowOffset), + @"backgroundColor": SKMutableObject([UIColor colorWithCGColor:node.layer.backgroundColor]), + @"borderColor": SKMutableObject([UIColor colorWithCGColor:node.layer.borderColor]), + @"borderWidth": SKMutableObject(@(node.layer.borderWidth)), + @"cornerRadius": SKMutableObject(@(node.layer.cornerRadius)), + @"masksToBounds": SKMutableObject(@(node.layer.masksToBounds)), + }], + [SKNamed newWithName: @"Accessibility" + withValue: @{ + @"isAccessibilityElement": SKMutableObject(@(node.isAccessibilityElement)), + @"accessibilityLabel": SKMutableObject(node.accessibilityLabel ?: @""), + @"accessibilityValue": SKMutableObject(node.accessibilityValue ?: @""), + @"accessibilityHint": SKMutableObject(node.accessibilityHint ?: @""), + @"accessibilityTraits": AccessibilityTraitsDict(node.accessibilityTraits), + @"accessibilityViewIsModal": SKMutableObject(@(node.accessibilityViewIsModal)), + @"shouldGroupAccessibilityChildren": SKMutableObject(@(node.shouldGroupAccessibilityChildren)), + }], + !node.isYogaEnabled ? nil : + [SKNamed newWithName: @"YGLayout" + withValue: @{ + @"direction": SKMutableObject(YGDirectionEnumMap[@(node.yoga.direction)]), + @"justifyContent": SKMutableObject(YGJustifyEnumMap[@(node.yoga.justifyContent)]), + @"aligns": @{ + @"alignContent": SKMutableObject(YGAlignEnumMap[@(node.yoga.alignContent)]), + @"alignItems": SKMutableObject(YGAlignEnumMap[@(node.yoga.alignItems)]), + @"alignSelf": SKMutableObject(YGAlignEnumMap[@(node.yoga.alignSelf)]), + }, + @"position": @{ + @"type": SKMutableObject(YGPositionTypeEnumMap[@(node.yoga.position)]), + @"left": SKYGValueObject(node.yoga.left), + @"top": SKYGValueObject(node.yoga.top), + @"right": SKYGValueObject(node.yoga.right), + @"bottom": SKYGValueObject(node.yoga.bottom), + @"start": SKYGValueObject(node.yoga.start), + @"end": SKYGValueObject(node.yoga.end), + }, + @"overflow": SKMutableObject(YGOverflowEnumMap[@(node.yoga.overflow)]), + @"display": SKMutableObject(YGDisplayEnumMap[@(node.yoga.display)]), + @"flex": @{ + @"flexDirection": SKMutableObject(YGFlexDirectionEnumMap[@(node.yoga.flexDirection)]), + @"flexWrap": SKMutableObject(YGWrapEnumMap[@(node.yoga.flexWrap)]), + @"flexGrow": SKMutableObject(@(node.yoga.flexGrow)), + @"flexShrink": SKMutableObject(@(node.yoga.flexShrink)), + @"flexBasis": SKYGValueObject(node.yoga.flexBasis), + }, + @"margin": @{ + @"left": SKYGValueObject(node.yoga.marginLeft), + @"top": SKYGValueObject(node.yoga.marginTop), + @"right": SKYGValueObject(node.yoga.marginRight), + @"bottom": SKYGValueObject(node.yoga.marginBottom), + @"start": SKYGValueObject(node.yoga.marginStart), + @"end": SKYGValueObject(node.yoga.marginEnd), + @"horizontal": SKYGValueObject(node.yoga.marginHorizontal), + @"vertical": SKYGValueObject(node.yoga.marginVertical), + @"all": SKYGValueObject(node.yoga.margin), + }, + @"padding": @{ + @"left": SKYGValueObject(node.yoga.paddingLeft), + @"top": SKYGValueObject(node.yoga.paddingTop), + @"right": SKYGValueObject(node.yoga.paddingRight), + @"bottom": SKYGValueObject(node.yoga.paddingBottom), + @"start": SKYGValueObject(node.yoga.paddingStart), + @"end": SKYGValueObject(node.yoga.paddingEnd), + @"horizontal": SKYGValueObject(node.yoga.paddingHorizontal), + @"vertical": SKYGValueObject(node.yoga.paddingVertical), + @"all": SKYGValueObject(node.yoga.padding), + }, + @"border": @{ + @"leftWidth": SKMutableObject(@(node.yoga.borderLeftWidth)), + @"topWidth": SKMutableObject(@(node.yoga.borderTopWidth)), + @"rightWidth": SKMutableObject(@(node.yoga.borderRightWidth)), + @"bottomWidth": SKMutableObject(@(node.yoga.borderBottomWidth)), + @"startWidth": SKMutableObject(@(node.yoga.borderStartWidth)), + @"endWidth": SKMutableObject(@(node.yoga.borderEndWidth)), + @"all": SKMutableObject(@(node.yoga.borderWidth)), + }, + @"dimensions": @{ + @"width": SKYGValueObject(node.yoga.width), + @"height": SKYGValueObject(node.yoga.height), + @"minWidth": SKYGValueObject(node.yoga.minWidth), + @"minHeight": SKYGValueObject(node.yoga.minHeight), + @"maxWidth": SKYGValueObject(node.yoga.maxWidth), + @"maxHeight": SKYGValueObject(node.yoga.maxHeight), + }, + @"aspectRatio": SKMutableObject(@(node.yoga.aspectRatio)), + @"resolvedDirection": SKObject(YGDirectionEnumMap[@(node.yoga.resolvedDirection)]), + }], + nil]; +} + +- (NSDictionary *)dataMutationsForNode:(UIView *)node { + return @{ + // UIView + @"UIView.alpha": ^(NSNumber *value) { + node.alpha = [value floatValue]; + }, + @"UIView.backgroundColor": ^(NSNumber *value) { + node.backgroundColor = [UIColor fromSonarValue: value]; + }, + @"UIView.frame.origin.y": ^(NSNumber *value) { + CGRect frame = node.frame; + frame.origin.y = [value floatValue]; + node.frame = frame; + }, + @"UIView.frame.origin.x": ^(NSNumber *value) { + CGRect frame = node.frame; + frame.origin.x = [value floatValue]; + node.frame = frame; + }, + @"UIView.frame.size.width": ^(NSNumber *value) { + CGRect frame = node.frame; + frame.size.width = [value floatValue]; + node.frame = frame; + }, + @"UIView.frame.size.height": ^(NSNumber *value) { + CGRect frame = node.frame; + frame.size.width = [value floatValue]; + node.frame = frame; + }, + // CALayer + @"CALayer.shadowColor": ^(NSNumber *value) { + node.layer.shadowColor = [UIColor fromSonarValue:value].CGColor; + }, + @"CALayer.shadowOpacity": ^(NSNumber *value) { + node.layer.shadowOpacity = [value floatValue]; + }, + @"CALayer.shadowRadius": ^(NSNumber *value) { + node.layer.shadowRadius = [value floatValue]; + }, + @"CALayer.shadowOffset.width": ^(NSNumber *value) { + CGSize offset = node.layer.shadowOffset; + offset.width = [value floatValue]; + node.layer.shadowOffset = offset; + }, + @"CALayer.shadowOffset.height": ^(NSNumber *value) { + CGSize offset = node.layer.shadowOffset; + offset.height = [value floatValue]; + node.layer.shadowOffset = offset; + }, + @"CALayer.backgroundColor": ^(NSNumber *value) { + node.layer.backgroundColor = [UIColor fromSonarValue:value].CGColor; + }, + @"CALayer.borderColor": ^(NSNumber *value) { + node.layer.borderColor = [UIColor fromSonarValue:value].CGColor; + }, + @"CALayer.borderWidth": ^(NSNumber *value) { + node.layer.borderWidth = [value floatValue]; + }, + @"CALayer.cornerRadius": ^(NSNumber *value) { + node.layer.cornerRadius = [value floatValue]; + }, + @"CALayer.masksToBounds": ^(NSNumber *value) { + node.layer.masksToBounds = [value boolValue]; + }, + // YGLayout + @"YGLayout.direction": APPLY_ENUM_TO_YOGA_PROPERTY(direction, YGDirection), + @"YGLayout.justifyContent": APPLY_ENUM_TO_YOGA_PROPERTY(justifyContent, YGJustify), + @"YGLayout.aligns.alignContent": APPLY_ENUM_TO_YOGA_PROPERTY(alignContent, YGAlign), + @"YGLayout.aligns.alignItems": APPLY_ENUM_TO_YOGA_PROPERTY(alignItems, YGAlign), + @"YGLayout.aligns.alignSelf": APPLY_ENUM_TO_YOGA_PROPERTY(alignSelf, YGAlign), + @"YGLayout.position.type": APPLY_ENUM_TO_YOGA_PROPERTY(position, YGPositionType), + @"YGLayout.position.left.value": APPLY_VALUE_TO_YGVALUE(left), + @"YGLayout.position.left.unit": APPLY_UNIT_TO_YGVALUE(left, YGUnit), + @"YGLayout.position.top.value": APPLY_VALUE_TO_YGVALUE(top), + @"YGLayout.position.top.unit": APPLY_UNIT_TO_YGVALUE(top, YGUnit), + @"YGLayout.position.right.value": APPLY_VALUE_TO_YGVALUE(right), + @"YGLayout.position.right.unit": APPLY_UNIT_TO_YGVALUE(right, YGUnit), + @"YGLayout.position.bottom.value": APPLY_VALUE_TO_YGVALUE(bottom), + @"YGLayout.position.bottom.unit": APPLY_UNIT_TO_YGVALUE(bottom, YGUnit), + @"YGLayout.position.start.value": APPLY_VALUE_TO_YGVALUE(start), + @"YGLayout.position.start.unit": APPLY_UNIT_TO_YGVALUE(start, YGUnit), + @"YGLayout.position.end.value": APPLY_VALUE_TO_YGVALUE(end), + @"YGLayout.position.end.unit": APPLY_UNIT_TO_YGVALUE(end, YGUnit), + @"YGLayout.overflow": APPLY_ENUM_TO_YOGA_PROPERTY(overflow, YGOverflow), + @"YGLayout.display": APPLY_ENUM_TO_YOGA_PROPERTY(display, YGDisplay), + @"YGLayout.flex.flexDirection": APPLY_ENUM_TO_YOGA_PROPERTY(flexDirection, YGFlexDirection), + @"YGLayout.flex.flexWrap": APPLY_ENUM_TO_YOGA_PROPERTY(flexWrap, YGWrap), + @"YGLayout.flex.flexGrow": ^(NSNumber *value) { + node.yoga.flexGrow = [value floatValue]; + }, + @"YGLayout.flex.flexShrink": ^(NSNumber *value) { + node.yoga.flexShrink = [value floatValue]; + }, + @"YGLayout.flex.flexBasis.value": APPLY_VALUE_TO_YGVALUE(flexBasis), + @"YGLayout.flex.flexBasis.unit": APPLY_UNIT_TO_YGVALUE(flexBasis, YGUnit), + @"YGLayout.margin.left.value": APPLY_VALUE_TO_YGVALUE(marginLeft), + @"YGLayout.margin.left.unit": APPLY_UNIT_TO_YGVALUE(marginLeft, YGUnit), + @"YGLayout.margin.top.value": APPLY_VALUE_TO_YGVALUE(marginTop), + @"YGLayout.margin.top.unit": APPLY_UNIT_TO_YGVALUE(marginTop, YGUnit), + @"YGLayout.margin.right.value": APPLY_VALUE_TO_YGVALUE(marginRight), + @"YGLayout.margin.right.unit": APPLY_UNIT_TO_YGVALUE(marginRight, YGUnit), + @"YGLayout.margin.bottom.value": APPLY_VALUE_TO_YGVALUE(marginBottom), + @"YGLayout.margin.bottom.unit": APPLY_UNIT_TO_YGVALUE(marginBottom, YGUnit), + @"YGLayout.margin.start.value": APPLY_VALUE_TO_YGVALUE(marginStart), + @"YGLayout.margin.start.unit": APPLY_UNIT_TO_YGVALUE(marginStart, YGUnit), + @"YGLayout.margin.end.value": APPLY_VALUE_TO_YGVALUE(marginEnd), + @"YGLayout.margin.end.unit": APPLY_UNIT_TO_YGVALUE(marginEnd, YGUnit), + @"YGLayout.margin.horizontal.value": APPLY_VALUE_TO_YGVALUE(marginHorizontal), + @"YGLayout.margin.horizontal.unit": APPLY_UNIT_TO_YGVALUE(marginHorizontal, YGUnit), + @"YGLayout.margin.vertical.value": APPLY_VALUE_TO_YGVALUE(marginVertical), + @"YGLayout.margin.vertical.unit": APPLY_UNIT_TO_YGVALUE(marginVertical, YGUnit), + @"YGLayout.margin.all.value": APPLY_VALUE_TO_YGVALUE(margin), + @"YGLayout.margin.all.unit": APPLY_UNIT_TO_YGVALUE(margin, YGUnit), + @"YGLayout.padding.left.value": APPLY_VALUE_TO_YGVALUE(paddingLeft), + @"YGLayout.padding.left.unit": APPLY_UNIT_TO_YGVALUE(paddingLeft, YGUnit), + @"YGLayout.padding.top.value": APPLY_VALUE_TO_YGVALUE(paddingTop), + @"YGLayout.padding.top.unit": APPLY_UNIT_TO_YGVALUE(paddingTop, YGUnit), + @"YGLayout.padding.right.value": APPLY_VALUE_TO_YGVALUE(paddingRight), + @"YGLayout.padding.right.unit": APPLY_UNIT_TO_YGVALUE(paddingRight, YGUnit), + @"YGLayout.padding.bottom.value": APPLY_VALUE_TO_YGVALUE(paddingBottom), + @"YGLayout.padding.bottom.unit": APPLY_UNIT_TO_YGVALUE(paddingBottom, YGUnit), + @"YGLayout.padding.start.value": APPLY_VALUE_TO_YGVALUE(paddingStart), + @"YGLayout.padding.start.unit": APPLY_UNIT_TO_YGVALUE(paddingStart, YGUnit), + @"YGLayout.padding.end.value": APPLY_VALUE_TO_YGVALUE(paddingEnd), + @"YGLayout.padding.end.unit": APPLY_UNIT_TO_YGVALUE(paddingEnd, YGUnit), + @"YGLayout.padding.horizontal.value": APPLY_VALUE_TO_YGVALUE(paddingHorizontal), + @"YGLayout.padding.horizontal.unit": APPLY_UNIT_TO_YGVALUE(paddingHorizontal, YGUnit), + @"YGLayout.padding.vertical.value": APPLY_VALUE_TO_YGVALUE(paddingVertical), + @"YGLayout.padding.vertical.unit": APPLY_UNIT_TO_YGVALUE(paddingVertical, YGUnit), + @"YGLayout.padding.all.value": APPLY_VALUE_TO_YGVALUE(padding), + @"YGLayout.padding.all.unit": APPLY_UNIT_TO_YGVALUE(padding, YGUnit), + @"YGLayout.border.leftWidth": ^(NSNumber *value) { + node.yoga.borderLeftWidth = [value floatValue]; + }, + @"YGLayout.border.topWidth": ^(NSNumber *value) { + node.yoga.borderTopWidth = [value floatValue]; + }, + @"YGLayout.border.rightWidth": ^(NSNumber *value) { + node.yoga.borderRightWidth = [value floatValue]; + }, + @"YGLayout.border.bottomWidth": ^(NSNumber *value) { + node.yoga.borderBottomWidth = [value floatValue]; + }, + @"YGLayout.border.startWidth": ^(NSNumber *value) { + node.yoga.borderStartWidth = [value floatValue]; + }, + @"YGLayout.border.endWidth": ^(NSNumber *value) { + node.yoga.borderEndWidth = [value floatValue]; + }, + @"YGLayout.border.all": ^(NSNumber *value) { + node.yoga.borderWidth = [value floatValue]; + }, + @"YGLayout.dimensions.width.value": APPLY_VALUE_TO_YGVALUE(width), + @"YGLayout.dimensions.width.unit": APPLY_UNIT_TO_YGVALUE(width, YGUnit), + @"YGLayout.dimensions.height.value": APPLY_VALUE_TO_YGVALUE(height), + @"YGLayout.dimensions.height.unit": APPLY_UNIT_TO_YGVALUE(height, YGUnit), + @"YGLayout.dimensions.minWidth.value": APPLY_VALUE_TO_YGVALUE(minWidth), + @"YGLayout.dimensions.minWidth.unit": APPLY_UNIT_TO_YGVALUE(minWidth, YGUnit), + @"YGLayout.dimensions.minHeight.value": APPLY_VALUE_TO_YGVALUE(minHeight), + @"YGLayout.dimensions.minHeight.unit": APPLY_UNIT_TO_YGVALUE(minHeight, YGUnit), + @"YGLayout.dimensions.maxWidth.value": APPLY_VALUE_TO_YGVALUE(maxWidth), + @"YGLayout.dimensions.maxWidth.unit": APPLY_UNIT_TO_YGVALUE(maxWidth, YGUnit), + @"YGLayout.dimensions.maxHeight.value": APPLY_VALUE_TO_YGVALUE(maxHeight), + @"YGLayout.dimensions.maxHeight.unit": APPLY_UNIT_TO_YGVALUE(maxHeight, YGUnit), + @"YGLayout.aspectRatio": ^(NSNumber *value) { + node.yoga.aspectRatio = [value floatValue]; + }, + // Accessibility + @"Accessibility.isAccessibilityElement": ^(NSNumber *value) { + node.isAccessibilityElement = [value boolValue]; + }, + @"Accessibility.accessibilityLabel": ^(NSString *value) { + node.accessibilityLabel = value; + }, + @"Accessibility.accessibilityValue": ^(NSString *value) { + node.accessibilityValue = value; + }, + @"Accessibility.accessibilityHint": ^(NSString *value) { + node.accessibilityHint = value; + }, + @"Accessibility.accessibilityTraits.UIAccessibilityTraitButton": ^(NSNumber *value) { + node.accessibilityTraits = AccessibilityTraitsToggle(node.accessibilityTraits, UIAccessibilityTraitButton, [value boolValue]); + }, + @"Accessibility.accessibilityTraits.UIAccessibilityTraitLink": ^(NSNumber *value) { + node.accessibilityTraits = AccessibilityTraitsToggle(node.accessibilityTraits, UIAccessibilityTraitLink, [value boolValue]); + }, + @"Accessibility.accessibilityTraits.UIAccessibilityTraitHeader": ^(NSNumber *value) { + node.accessibilityTraits = AccessibilityTraitsToggle(node.accessibilityTraits, UIAccessibilityTraitHeader, [value boolValue]); + }, + @"Accessibility.accessibilityTraits.UIAccessibilityTraitSearchField": ^(NSNumber *value) { + node.accessibilityTraits = AccessibilityTraitsToggle(node.accessibilityTraits, UIAccessibilityTraitSearchField, [value boolValue]); + }, + @"Accessibility.accessibilityTraits.UIAccessibilityTraitImage": ^(NSNumber *value) { + node.accessibilityTraits = AccessibilityTraitsToggle(node.accessibilityTraits, UIAccessibilityTraitImage, [value boolValue]); + }, + @"Accessibility.accessibilityTraits.UIAccessibilityTraitSelected": ^(NSNumber *value) { + node.accessibilityTraits = AccessibilityTraitsToggle(node.accessibilityTraits, UIAccessibilityTraitSelected, [value boolValue]); + }, + @"Accessibility.accessibilityTraits.UIAccessibilityTraitPlaysSound": ^(NSNumber *value) { + node.accessibilityTraits = AccessibilityTraitsToggle(node.accessibilityTraits, UIAccessibilityTraitPlaysSound, [value boolValue]); + }, + @"Accessibility.accessibilityTraits.UIAccessibilityTraitKeyboardKey": ^(NSNumber *value) { + node.accessibilityTraits = AccessibilityTraitsToggle(node.accessibilityTraits, UIAccessibilityTraitKeyboardKey, [value boolValue]); + }, + @"Accessibility.accessibilityTraits.UIAccessibilityTraitStaticText": ^(NSNumber *value) { + node.accessibilityTraits = AccessibilityTraitsToggle(node.accessibilityTraits, UIAccessibilityTraitStaticText, [value boolValue]); + }, + @"Accessibility.accessibilityTraits.UIAccessibilityTraitSummaryElement": ^(NSNumber *value) { + node.accessibilityTraits = AccessibilityTraitsToggle(node.accessibilityTraits, UIAccessibilityTraitSummaryElement, [value boolValue]); + }, + @"Accessibility.accessibilityTraits.UIAccessibilityTraitNotEnabled": ^(NSNumber *value) { + node.accessibilityTraits = AccessibilityTraitsToggle(node.accessibilityTraits, UIAccessibilityTraitNotEnabled, [value boolValue]); + }, + @"Accessibility.accessibilityTraits.UIAccessibilityTraitUpdatesFrequently": ^(NSNumber *value) { + node.accessibilityTraits = AccessibilityTraitsToggle(node.accessibilityTraits, UIAccessibilityTraitUpdatesFrequently, [value boolValue]); + }, + @"Accessibility.accessibilityTraits.UIAccessibilityTraitStartsMediaSession": ^(NSNumber *value) { + node.accessibilityTraits = AccessibilityTraitsToggle(node.accessibilityTraits, UIAccessibilityTraitStartsMediaSession, [value boolValue]); + }, + @"Accessibility.accessibilityTraits.UIAccessibilityTraitAdjustable": ^(NSNumber *value) { + node.accessibilityTraits = AccessibilityTraitsToggle(node.accessibilityTraits, UIAccessibilityTraitAdjustable, [value boolValue]); + }, + @"Accessibility.accessibilityTraits.UIAccessibilityTraitAllowsDirectInteraction": ^(NSNumber *value) { + node.accessibilityTraits = AccessibilityTraitsToggle(node.accessibilityTraits, UIAccessibilityTraitAllowsDirectInteraction, [value boolValue]); + }, + @"Accessibility.accessibilityTraits.UIAccessibilityTraitCausesPageTurn": ^(NSNumber *value) { + node.accessibilityTraits = AccessibilityTraitsToggle(node.accessibilityTraits, UIAccessibilityTraitCausesPageTurn, [value boolValue]); + }, + @"Accessibility.accessibilityTraits.UIAccessibilityTraitTabBar": ^(NSNumber *value) { + node.accessibilityTraits = AccessibilityTraitsToggle(node.accessibilityTraits, UIAccessibilityTraitTabBar, [value boolValue]); + }, + @"Accessibility.accessibilityViewIsModal": ^(NSNumber *value) { + node.accessibilityViewIsModal = [value boolValue]; + }, + @"Accessibility.shouldGroupAccessibilityChildren": ^(NSNumber *value) { + node.shouldGroupAccessibilityChildren = [value boolValue]; + }, + }; +} + +- (NSArray *> *)attributesForNode:(UIView *)node { + return @[ + [SKNamed newWithName: @"addr" + withValue: [NSString stringWithFormat: @"%p", node]] + ]; +} + +- (void)setHighlighted:(BOOL)highlighted forNode:(UIView *)node { + SKHighlightOverlay *overlay = [SKHighlightOverlay sharedInstance]; + if (highlighted == YES) { + [overlay mountInView: node withFrame: node.bounds]; + } else { + [overlay unmount]; + } +} + +- (void)hitTest:(SKTouch *)touch forNode:(UIView *)node { + for (NSInteger index = [self childCountForNode: node] - 1; index >= 0; index--) { + id childNode = [self childForNode: node atIndex: index]; + UIView *viewForNode = nil; + + if ([childNode isKindOfClass: [UIViewController class]]) { + UIViewController *child = (UIViewController *)childNode; + viewForNode = child.view; + } else { + viewForNode = (UIView *)childNode; + } + + if (viewForNode.isHidden || viewForNode.alpha <= 0) { + continue; + } + + if ([touch containedIn: viewForNode.frame]) { + [touch continueWithChildIndex: index withOffset: viewForNode.frame.origin ]; + return; + } + } + + [touch finish]; +} + +static void initEnumDictionaries() { + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + YGDirectionEnumMap = @{ + @(YGDirectionInherit): @"inherit", + @(YGDirectionLTR): @"LTR", + @(YGDirectionRTL): @"RTL", + }; + + YGFlexDirectionEnumMap = @{ + @(YGFlexDirectionColumn): @"column", + @(YGFlexDirectionColumnReverse): @"column-reverse", + @(YGFlexDirectionRow): @"row", + @(YGFlexDirectionRowReverse): @"row-reverse", + }; + + YGJustifyEnumMap = @{ + @(YGJustifyFlexStart): @"flex-start", + @(YGJustifyCenter): @"center", + @(YGJustifyFlexEnd): @"flex-end", + @(YGJustifySpaceBetween): @"space-between", + @(YGJustifySpaceAround): @"space-around", + }; + + YGAlignEnumMap = @{ + @(YGAlignAuto): @"auto", + @(YGAlignFlexStart): @"flex-start", + @(YGAlignCenter): @"end", + @(YGAlignFlexEnd): @"flex-end", + @(YGAlignStretch): @"stretch", + @(YGAlignBaseline): @"baseline", + @(YGAlignSpaceBetween): @"space-between", + @(YGAlignSpaceAround): @"space-around", + }; + + YGPositionTypeEnumMap = @{ + @(YGPositionTypeRelative): @"relative", + @(YGPositionTypeAbsolute): @"absolute", + }; + + YGWrapEnumMap = @{ + @(YGWrapNoWrap): @"no-wrap", + @(YGWrapWrap): @"wrap", + @(YGWrapWrapReverse): @"wrap-reverse", + }; + + YGOverflowEnumMap = @{ + @(YGOverflowVisible): @"visible", + @(YGOverflowHidden): @"hidden", + @(YGOverflowScroll): @"scroll", + }; + + YGDisplayEnumMap = @{ + @(YGDisplayFlex): @"flex", + @(YGDisplayNone): @"none", + }; + + YGUnitEnumMap = @{ + @(YGUnitUndefined): @"undefined", + @(YGUnitPoint): @"point", + @(YGUnitPercent): @"percent", + @(YGUnitAuto): @"auto", + }; + }); +} + +static NSDictionary *SKYGValueObject(YGValue value) { + return @{ + @"value": SKMutableObject(@(value.value)), + @"unit": SKMutableObject(YGUnitEnumMap[@(value.unit)]), + }; +} + +/* + Takes the originalTraits, and set all bits from toggleTraits to the toggleValue + e.g. originalTraits = UIAccessibilityTraitButton | UIAccessibilityTraitSelected + toggleTraits = UIAccessibilityTraitImage + toggleValue = YES + return value = UIAccessibilityTraitButton | UIAccessibilityTraitSelected | UIAccessibilityTraitImage + */ +static UIAccessibilityTraits AccessibilityTraitsToggle(UIAccessibilityTraits originalTraits, UIAccessibilityTraits toggleTraits, BOOL toggleValue) { + // NEGATE all bits of toggleTraits from originalTraits and OR it against either toggleTraits or 0 (UIAccessibilityTraitNone) based on toggleValue + UIAccessibilityTraits bitsValue = toggleValue ? toggleTraits : UIAccessibilityTraitNone; + return (originalTraits & ~(toggleTraits)) | bitsValue; +} + +static NSDictionary *AccessibilityTraitsDict(UIAccessibilityTraits accessibilityTraits) { + NSMutableDictionary *traitsDict = [NSMutableDictionary new]; + [traitsDict addEntriesFromDictionary:@{ + @"UIAccessibilityTraitButton": SKMutableObject(@(!!(accessibilityTraits & UIAccessibilityTraitButton))), + @"UIAccessibilityTraitLink": SKMutableObject(@(!!(accessibilityTraits & UIAccessibilityTraitLink))), + @"UIAccessibilityTraitHeader": SKMutableObject(@(!!(accessibilityTraits & UIAccessibilityTraitHeader))), + @"UIAccessibilityTraitSearchField": SKMutableObject(@(!!(accessibilityTraits & UIAccessibilityTraitSearchField))), + @"UIAccessibilityTraitImage": SKMutableObject(@(!!(accessibilityTraits & UIAccessibilityTraitImage))), + @"UIAccessibilityTraitSelected": SKMutableObject(@(!!(accessibilityTraits & UIAccessibilityTraitSelected))), + @"UIAccessibilityTraitPlaysSound": SKMutableObject(@(!!(accessibilityTraits & UIAccessibilityTraitPlaysSound))), + @"UIAccessibilityTraitKeyboardKey": SKMutableObject(@(!!(accessibilityTraits & UIAccessibilityTraitKeyboardKey))), + @"UIAccessibilityTraitStaticText": SKMutableObject(@(!!(accessibilityTraits & UIAccessibilityTraitStaticText))), + @"UIAccessibilityTraitSummaryElement": SKMutableObject(@(!!(accessibilityTraits & UIAccessibilityTraitSummaryElement))), + @"UIAccessibilityTraitNotEnabled": SKMutableObject(@(!!(accessibilityTraits & UIAccessibilityTraitNotEnabled))), + @"UIAccessibilityTraitUpdatesFrequently": SKMutableObject(@(!!(accessibilityTraits & UIAccessibilityTraitUpdatesFrequently))), + @"UIAccessibilityTraitStartsMediaSession": SKMutableObject(@(!!(accessibilityTraits & UIAccessibilityTraitStartsMediaSession))), + @"UIAccessibilityTraitAdjustable": SKMutableObject(@(!!(accessibilityTraits & UIAccessibilityTraitAdjustable))), + @"UIAccessibilityTraitAllowsDirectInteraction": SKMutableObject(@(!!(accessibilityTraits & UIAccessibilityTraitAllowsDirectInteraction))), + @"UIAccessibilityTraitCausesPageTurn": SKMutableObject(@(!!(accessibilityTraits & UIAccessibilityTraitCausesPageTurn))), + }]; + if (@available(iOS 10.0, *)) { + traitsDict[@"UIAccessibilityTraitTabBar"] = SKMutableObject(@(!!(accessibilityTraits & UIAccessibilityTraitTabBar))); + } + return traitsDict; +} + +@end + +#endif diff --git a/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/utils/SKHiddenWindow.h b/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/utils/SKHiddenWindow.h new file mode 100644 index 000000000..44eb12649 --- /dev/null +++ b/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/utils/SKHiddenWindow.h @@ -0,0 +1,11 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +#import + +@interface SKHiddenWindow : UIWindow +@end diff --git a/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/utils/SKHiddenWindow.m b/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/utils/SKHiddenWindow.m new file mode 100644 index 000000000..bbd91c033 --- /dev/null +++ b/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/utils/SKHiddenWindow.m @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +#if FB_SONARKIT_ENABLED + +#import "SKHiddenWindow.h" + +@implementation SKHiddenWindow + +@end + +#endif diff --git a/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/utils/SKObjectHash.h b/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/utils/SKObjectHash.h new file mode 100644 index 000000000..ba3852d64 --- /dev/null +++ b/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/utils/SKObjectHash.h @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +#import + +/* + A hash function is needed in order to use NSObject classes + as keys in C++ STL + */ +class SKObjectHash { +public: + size_t operator()(const NSObject *x) const { + return (size_t)[x hash]; + } +}; diff --git a/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/utils/SKSwizzle.h b/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/utils/SKSwizzle.h new file mode 100644 index 000000000..baf88df9a --- /dev/null +++ b/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/utils/SKSwizzle.h @@ -0,0 +1,10 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +#import + +void swizzleMethods(Class cls, SEL original, SEL swissled); diff --git a/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/utils/SKSwizzle.mm b/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/utils/SKSwizzle.mm new file mode 100644 index 000000000..0b5d29291 --- /dev/null +++ b/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/utils/SKSwizzle.mm @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +#if FB_SONARKIT_ENABLED + +#import "SKSwizzle.h" + +#import +#import + +void swizzleMethods(Class cls, SEL original, SEL swissled) { + Method originalMethod = class_getInstanceMethod(cls, original); + Method swissledMethod = class_getInstanceMethod(cls, swissled); + + BOOL didAddMethod = class_addMethod(cls, original, + method_getImplementation(swissledMethod), + method_getTypeEncoding(swissledMethod)); + + if (didAddMethod) { + class_replaceMethod(cls, swissled, + method_getImplementation(originalMethod), + method_getTypeEncoding(originalMethod)); + } else { + method_exchangeImplementations(originalMethod, swissledMethod); + } +} + +#endif diff --git a/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/utils/SKYogaKitHelper.h b/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/utils/SKYogaKitHelper.h new file mode 100644 index 000000000..a0ded21ac --- /dev/null +++ b/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/utils/SKYogaKitHelper.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +#import + +#define APPLY_ENUM_TO_YOGA_PROPERTY(varName, enumName) \ +^(NSString *newValue) { \ +NSNumber *varName = [[enumName##EnumMap allKeysForObject:newValue] lastObject]; \ +if (varName == nil) { return; } \ +node.yoga.varName = (enumName)[varName unsignedIntegerValue]; \ +} + +#define APPLY_VALUE_TO_YGVALUE(varName) \ +^(NSNumber *value) { \ +YGValue newValue = node.yoga.varName; \ +newValue.value = [value floatValue]; \ +node.yoga.varName = newValue; \ +} + +#define APPLY_UNIT_TO_YGVALUE(varName, enumName) \ +^(NSString *value) { \ +NSNumber *varName = [[enumName##EnumMap allKeysForObject:value] lastObject]; \ +if (varName == nil) { return; } \ +YGValue newValue = node.yoga.varName; \ +newValue.unit = (enumName)[varName unsignedIntegerValue]; \ +node.yoga.varName = newValue; \ +} diff --git a/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPluginTests/SKTapListenerMock.h b/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPluginTests/SKTapListenerMock.h new file mode 100644 index 000000000..cabd0e95c --- /dev/null +++ b/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPluginTests/SKTapListenerMock.h @@ -0,0 +1,14 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +#import + +@interface SKTapListenerMock : NSObject + +- (void)tapAt:(CGPoint)point; + +@end diff --git a/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPluginTests/SKTapListenerMock.m b/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPluginTests/SKTapListenerMock.m new file mode 100644 index 000000000..e3bd05f01 --- /dev/null +++ b/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPluginTests/SKTapListenerMock.m @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +#import "SKTapListenerMock.h" + +@implementation SKTapListenerMock +{ + NSMutableArray *_tapReceivers; +} + +@synthesize isMounted; + +- (instancetype)init { + if (self = [super init]) { + _tapReceivers = [NSMutableArray new]; + } + + return self; +} + +- (void)listenForTapWithBlock:(SKTapReceiver)receiver { + [_tapReceivers addObject: receiver]; +} + +- (void)tapAt:(CGPoint)point { + for (SKTapReceiver recv in _tapReceivers) { + recv(point); + } + + [_tapReceivers removeAllObjects]; +} + +- (void)mountWithFrame:(CGRect)frame { + isMounted = YES; +} + +- (void)unmount { + isMounted = NO; +} + +@end diff --git a/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPluginTests/SonarKitLayoutPluginTests.m b/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPluginTests/SonarKitLayoutPluginTests.m new file mode 100644 index 000000000..b7e4d4dd7 --- /dev/null +++ b/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPluginTests/SonarKitLayoutPluginTests.m @@ -0,0 +1,250 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +#import + +#if FB_SONARKIT_ENABLED + +#import +#import +#import +#import +#import + +#import "SKTapListenerMock.h" +#import "TestNode.h" +#import "TestNodeDescriptor.h" + +@interface SonarKitLayoutPluginTests : XCTestCase +@end + +@implementation SonarKitLayoutPluginTests +{ + SKDescriptorMapper *_descriptorMapper; +} + +- (void)setUp { + [super setUp]; + + _descriptorMapper = [[SKDescriptorMapper alloc] initWithDefaults]; + + [_descriptorMapper registerDescriptor: [TestNodeDescriptor new] + forClass: [TestNode class]]; +} + +- (void)testGetRoot { + SonarKitLayoutPlugin *plugin = [[SonarKitLayoutPlugin alloc] + initWithRootNode: [[TestNode alloc] initWithName: @"rootNode"] + withTapListener: nil + withDescriptorMapper: _descriptorMapper]; + + SonarConnectionMock *connection = [SonarConnectionMock new]; + SonarResponderMock *responder = [SonarResponderMock new]; + [plugin didConnect:connection]; + + SonarReceiver receiver = connection.receivers[@"getRoot"]; + receiver(@{}, responder); + + XCTAssertTrue(([responder.successes containsObject: @{ + @"id": @"rootNode", + @"name": @"TestNode", + @"children": @[], + @"attributes": @[], + @"data": @{}, + @"decoration": @"", + }])); +} + +- (void)testGetEmptyNodes { + SonarKitLayoutPlugin *plugin = [SonarKitLayoutPlugin new]; + SonarConnectionMock *connection = [SonarConnectionMock new]; + SonarResponderMock *responder = [SonarResponderMock new]; + [plugin didConnect:connection]; + + SonarReceiver receiver = connection.receivers[@"getNodes"]; + receiver(@{@"ids": @[]}, responder); + + XCTAssertTrue(([responder.successes containsObject:@{@"elements": @[]}])); +} + +- (void)testGetNodes { + TestNode *rootNode = [[TestNode alloc] initWithName: @"rootNode"]; + NSArray *childNodes = @[ + [[TestNode alloc] initWithName: @"testNode1"], + [[TestNode alloc] initWithName: @"testNode2"], + [[TestNode alloc] initWithName: @"testNode3"], + ]; + + rootNode.children = childNodes; + + SonarKitLayoutPlugin *plugin = [[SonarKitLayoutPlugin alloc] initWithRootNode: rootNode + withTapListener: nil + withDescriptorMapper: _descriptorMapper]; + + SonarConnectionMock *connection = [SonarConnectionMock new]; + SonarResponderMock *responder = [SonarResponderMock new]; + [plugin didConnect:connection]; + + // Ensure that nodes are tracked + connection.receivers[@"getRoot"](@{}, responder); + + SonarReceiver receiver = connection.receivers[@"getNodes"]; + receiver(@{@"ids": @[ @"testNode1", @"testNode2", @"testNode3" ]}, responder); + + XCTAssertTrue(([responder.successes containsObject:@{@"elements": @[ + @{ + @"id": @"testNode1", + @"name": @"TestNode", + @"children": @[], + @"attributes": @[], + @"data": @{}, + @"decoration": @"", + }, + @{ + @"id": @"testNode2", + @"name": @"TestNode", + @"children": @[], + @"attributes": @[], + @"data": @{}, + @"decoration": @"", + }, + @{ + @"id": @"testNode3", + @"name": @"TestNode", + @"children": @[], + @"attributes": @[], + @"data": @{}, + @"decoration": @"", + }, + ]}])); +} + +- (void)testSetHighlighted { + TestNode *rootNode = [[TestNode alloc] initWithName: @"rootNode"]; + + TestNode *testNode1 = [[TestNode alloc] initWithName: @"testNode1"]; + TestNode *testNode2 = [[TestNode alloc] initWithName: @"testNode2"]; + NSArray *childNodes = @[ testNode1, testNode2 ]; + + rootNode.children = childNodes; + + SonarKitLayoutPlugin *plugin = [[SonarKitLayoutPlugin alloc] initWithRootNode: rootNode + withTapListener: nil + withDescriptorMapper: _descriptorMapper]; + + SonarConnectionMock *connection = [SonarConnectionMock new]; + SonarResponderMock *responder = [SonarResponderMock new]; + [plugin didConnect:connection]; + + // Setup in order to track nodes successfully + connection.receivers[@"getRoot"](@{}, responder); + SonarReceiver getNodesCall = connection.receivers[@"getNodes"]; + getNodesCall(@{@"ids": @[ @"testNode1", @"testNode2" ]}, responder); + + SonarReceiver setHighlighted = connection.receivers[@"setHighlighted"]; + setHighlighted(@{@"id":@"testNode2"}, responder); + + XCTAssertTrue(testNode2.highlighted); + + setHighlighted(@{@"id":@"testNode1"}, responder); + + // Ensure that old highlight was removed + XCTAssertTrue(testNode1.highlighted && !testNode2.highlighted); +} + +- (void)testSetSearchActive { + TestNode *rootNode = [[TestNode alloc] initWithName: @"rootNode" + withFrame: CGRectMake(0, 0, 20, 60)]; + + TestNode *testNode1 = [[TestNode alloc] initWithName: @"testNode1" + withFrame: CGRectMake(20, 20, 20, 20)]; + TestNode *testNode2 = [[TestNode alloc] initWithName: @"testNode2" + withFrame: CGRectMake(20, 40, 20, 20)]; + TestNode *testNode3 = [[TestNode alloc] initWithName: @"testNode3" + withFrame: CGRectMake(25, 42, 5, 5)]; + + rootNode.children = @[ testNode1, testNode2 ]; + testNode2.children = @[ testNode3 ]; + + SKTapListenerMock *tapListener = [SKTapListenerMock new]; + SonarKitLayoutPlugin *plugin = [[SonarKitLayoutPlugin alloc] initWithRootNode: rootNode + withTapListener: tapListener + withDescriptorMapper: _descriptorMapper]; + + SonarConnectionMock *connection = [SonarConnectionMock new]; + SonarResponderMock *responder = [SonarResponderMock new]; + [plugin didConnect:connection]; + + connection.receivers[@"setSearchActive"](@{@"active":@YES}, responder); + + // Fake a tap at `testNode3` + [tapListener tapAt: (CGPoint){ 26, 43 }]; + + XCTAssertTrue(([connection.sent[@"select"] containsObject: @{ @"path": @[ @"testNode2", @"testNode3" ] }])); +} + +- (void)testSetSearchActiveMountAndUnmount { + TestNode *rootNode = [[TestNode alloc] initWithName: @"rootNode"]; + + SKTapListenerMock *tapListener = [SKTapListenerMock new]; + SonarKitLayoutPlugin *plugin = [[SonarKitLayoutPlugin alloc] initWithRootNode: rootNode + withTapListener: tapListener + withDescriptorMapper: _descriptorMapper]; + + SonarConnectionMock *connection = [SonarConnectionMock new]; + SonarResponderMock *responder = [SonarResponderMock new]; + [plugin didConnect:connection]; + + SonarReceiver setSearchActive = connection.receivers[@"setSearchActive"]; + setSearchActive(@{@"active":@YES}, responder); + + XCTAssertTrue(tapListener.isMounted); + + setSearchActive(@{@"active":@NO}, responder); + XCTAssertTrue(! tapListener.isMounted); +} + +- (void)testSetData { + TestNode *rootNode = [[TestNode alloc] initWithName: @"rootNode" + withFrame: CGRectMake(0, 0, 20, 60)]; + + TestNode *testNode1 = [[TestNode alloc] initWithName: @"testNode1" + withFrame: CGRectMake(20, 20, 20, 20)]; + TestNode *testNode2 = [[TestNode alloc] initWithName: @"testNode2" + withFrame: CGRectMake(20, 40, 20, 20)]; + TestNode *testNode3 = [[TestNode alloc] initWithName: @"testNode3" + withFrame: CGRectMake(25, 42, 5, 5)]; + + rootNode.children = @[ testNode1, testNode2 ]; + testNode2.children = @[ testNode3 ]; + + SKTapListenerMock *tapListener = [SKTapListenerMock new]; + SonarKitLayoutPlugin *plugin = [[SonarKitLayoutPlugin alloc] initWithRootNode: rootNode + withTapListener: tapListener + withDescriptorMapper: _descriptorMapper]; + + SonarConnectionMock *connection = [SonarConnectionMock new]; + SonarResponderMock *responder = [SonarResponderMock new]; + [plugin didConnect:connection]; + + // Setup in order to track nodes successfully + connection.receivers[@"getRoot"](@{}, responder); + connection.receivers[@"getNodes"](@{ @"ids": @[ @"testNode2" ] }, responder); + + // Modify the name of testNode3 + connection.receivers[@"setData"](@{ + @"id": @"testNode3", + @"path": @[ @"TestNode", @"name" ], + @"value": @"changedNameForTestNode3", + }, responder); + + XCTAssertTrue([testNode3.nodeName isEqualToString: @"changedNameForTestNode3"]); +} + +@end + +#endif diff --git a/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPluginTests/TestNode.h b/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPluginTests/TestNode.h new file mode 100644 index 000000000..51a286a1b --- /dev/null +++ b/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPluginTests/TestNode.h @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +#import + +@interface TestNode : NSObject + +@property (nonatomic, copy) NSString *nodeName; +@property (nonatomic, copy) NSArray *children; + +@property (nonatomic, assign) BOOL highlighted; +@property (nonatomic, assign) CGRect frame; + +- (instancetype)initWithName:(NSString *)name; +- (instancetype)initWithName:(NSString *)name withFrame:(CGRect)frame; + +@end diff --git a/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPluginTests/TestNode.m b/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPluginTests/TestNode.m new file mode 100644 index 000000000..810761939 --- /dev/null +++ b/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPluginTests/TestNode.m @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +#import "TestNode.h" + +@implementation TestNode + +- (instancetype)initWithName:(NSString *)name { + return [self initWithName: name + withFrame: CGRectZero]; +} + +- (instancetype)initWithName:(NSString *)name withFrame:(CGRect)frame { + if (self = [super init]) { + _nodeName = name; + _frame = frame; + } + + return self; +} + +@end diff --git a/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPluginTests/TestNodeDescriptor.h b/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPluginTests/TestNodeDescriptor.h new file mode 100644 index 000000000..8e0f58763 --- /dev/null +++ b/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPluginTests/TestNodeDescriptor.h @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +#import + +#import "TestNode.h" + +@interface TestNodeDescriptor : SKNodeDescriptor +@end diff --git a/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPluginTests/TestNodeDescriptor.m b/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPluginTests/TestNodeDescriptor.m new file mode 100644 index 000000000..aeb3d9bc1 --- /dev/null +++ b/iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPluginTests/TestNodeDescriptor.m @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +#import "TestNodeDescriptor.h" + +@implementation TestNodeDescriptor + +- (NSString *)identifierForNode:(TestNode *)node { + return node.nodeName; +} + +- (NSUInteger)childCountForNode:(TestNode *)node { + return [node.children count]; +} + +- (id)childForNode:(TestNode *)node atIndex:(NSUInteger)index { + return [node.children objectAtIndex: index]; +} + +- (void)setHighlighted:(BOOL)highlighted forNode:(TestNode *)node { + node.highlighted = highlighted; +} + +- (void)hitTest:(SKTouch *)touch forNode:(TestNode *)node { + NSUInteger index = [node.children count] - 1; + for (TestNode *childNode in [node.children reverseObjectEnumerator]) { + if ([touch containedIn: childNode.frame]) { + [touch continueWithChildIndex: index withOffset: node.frame.origin]; + return; + } + + index = index - 1; + } + + [touch finish]; +} + +- (NSDictionary *)dataMutationsForNode:(TestNode *)node { + return @{ + @"TestNode.name": ^(NSString *newName) { + node.nodeName = newName; + } + }; +} + +@end diff --git a/iOS/Plugins/SonarKitNetworkPlugin/SKIOSNetworkPlugin/FLEXNetworkLib/FLEXNetworkObserver.h b/iOS/Plugins/SonarKitNetworkPlugin/SKIOSNetworkPlugin/FLEXNetworkLib/FLEXNetworkObserver.h new file mode 100755 index 000000000..2262805ee --- /dev/null +++ b/iOS/Plugins/SonarKitNetworkPlugin/SKIOSNetworkPlugin/FLEXNetworkLib/FLEXNetworkObserver.h @@ -0,0 +1,27 @@ +// Copyright 2004-present Facebook. All Rights Reserved. + +// +// FLEXNetworkObserver.h +// Derived from: +// +// PDAFNetworkDomainController.h +// PonyDebugger +// +// Created by Mike Lewis on 2/27/12. +// +// Licensed to Square, Inc. under one or more contributor license agreements. +// See the LICENSE file distributed with this work for the terms under +// which Square, Inc. licenses this file to you. +// + +#import + +FOUNDATION_EXTERN NSString *const kFLEXNetworkObserverEnabledStateChangedNotification; + +/// This class swizzles NSURLConnection and NSURLSession delegate methods to observe events in the URL loading system. +/// High level network events are sent to the default FLEXNetworkRecorder instance which maintains the request history and caches response bodies. +@interface FLEXNetworkObserver : NSObject + ++ (void)start; + +@end diff --git a/iOS/Plugins/SonarKitNetworkPlugin/SKIOSNetworkPlugin/FLEXNetworkLib/FLEXNetworkObserver.mm b/iOS/Plugins/SonarKitNetworkPlugin/SKIOSNetworkPlugin/FLEXNetworkLib/FLEXNetworkObserver.mm new file mode 100755 index 000000000..723345b4b --- /dev/null +++ b/iOS/Plugins/SonarKitNetworkPlugin/SKIOSNetworkPlugin/FLEXNetworkLib/FLEXNetworkObserver.mm @@ -0,0 +1,1088 @@ +// Copyright 2004-present Facebook. All Rights Reserved. + +// +// FLEXNetworkObserver.m +// Derived from: +// +// PDAFNetworkDomainController.m +// PonyDebugger +// +// Created by Mike Lewis on 2/27/12. +// +// Licensed to Square, Inc. under one or more contributor license agreements. +// See the LICENSE file distributed with this work for the terms under +// which Square, Inc. licenses this file to you. +// + +#import "FLEXNetworkObserver.h" + +#import +#import + +#import + +#import "FLEXNetworkRecorder.h" +#import "FLEXUtility.h" + +NSString *const kFLEXNetworkObserverEnabledStateChangedNotification = @"kFLEXNetworkObserverEnabledStateChangedNotification"; +static NSString *const kFLEXNetworkObserverEnabledDefaultsKey = @"com.flex.FLEXNetworkObserver.enableOnLaunch"; + +typedef void (^NSURLSessionAsyncCompletion)(id fileURLOrData, NSURLResponse *response, NSError *error); + +@interface FLEXInternalRequestState : NSObject + +@property (nonatomic, copy) NSURLRequest *request; +@property (nonatomic, strong) NSMutableData *dataAccumulator; + +@end + +@implementation FLEXInternalRequestState + +@end + +@interface FLEXNetworkObserver (NSURLConnectionHelpers) + +- (void)connection:(NSURLConnection *)connection willSendRequest:(NSURLRequest *)request redirectResponse:(NSURLResponse *)response delegate:(id)delegate; +- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response delegate:(id)delegate; + +- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data delegate:(id)delegate; + +- (void)connectionDidFinishLoading:(NSURLConnection *)connection delegate:(id)delegate; +- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error delegate:(id)delegate; + +- (void)connectionWillCancel:(NSURLConnection *)connection; + +@end + + +@interface FLEXNetworkObserver (NSURLSessionTaskHelpers) + +- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task willPerformHTTPRedirection:(NSHTTPURLResponse *)response newRequest:(NSURLRequest *)request completionHandler:(void (^)(NSURLRequest *))completionHandler delegate:(id)delegate; +- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition disposition))completionHandler delegate:(id)delegate; +- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data delegate:(id)delegate; +- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask +didBecomeDownloadTask:(NSURLSessionDownloadTask *)downloadTask delegate:(id)delegate; +- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error delegate:(id)delegate; +- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite delegate:(id)delegate; +- (void)URLSession:(NSURLSession *)session task:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location data:(NSData *)data delegate:(id)delegate; + +- (void)URLSessionTaskWillResume:(NSURLSessionTask *)task; + +@end + +@interface FLEXNetworkObserver () + +@property (nonatomic, strong) NSMutableDictionary *requestStatesForRequestIDs; +@property (nonatomic, strong) dispatch_queue_t queue; + +@end + +@implementation FLEXNetworkObserver + +#pragma mark - Public Methods + ++ (void)start { + [self injectIntoAllNSURLConnectionDelegateClasses]; + +} + +#pragma mark - Statics + ++ (instancetype)sharedObserver +{ + static FLEXNetworkObserver *sharedObserver = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + sharedObserver = [[[self class] alloc] init]; + }); + return sharedObserver; +} + ++ (NSString *)nextRequestID +{ + return [[NSUUID UUID] UUIDString]; +} + +#pragma mark Delegate Injection Convenience Methods + +/// All swizzled delegate methods should make use of this guard. +/// This will prevent duplicated sniffing when the original implementation calls up to a superclass implementation which we've also swizzled. +/// The superclass implementation (and implementations in classes above that) will be executed without inteference if called from the original implementation. ++ (void)sniffWithoutDuplicationForObject:(NSObject *)object selector:(SEL)selector sniffingBlock:(void (^)(void))sniffingBlock originalImplementationBlock:(void (^)(void))originalImplementationBlock +{ + // If we don't have an object to detect nested calls on, just run the original implmentation and bail. + // This case can happen if someone besides the URL loading system calls the delegate methods directly. + // See https://github.com/Flipboard/FLEX/issues/61 for an example. + if (!object) { + originalImplementationBlock(); + return; + } + + const void *key = selector; + + // Don't run the sniffing block if we're inside a nested call + if (!objc_getAssociatedObject(object, key)) { + sniffingBlock(); + } + + // Mark that we're calling through to the original so we can detect nested calls + objc_setAssociatedObject(object, key, @YES, OBJC_ASSOCIATION_RETAIN_NONATOMIC); + originalImplementationBlock(); + objc_setAssociatedObject(object, key, nil, OBJC_ASSOCIATION_RETAIN_NONATOMIC); +} + +#pragma mark - Delegate Injection + ++ (void)injectIntoAllNSURLConnectionDelegateClasses +{ + // Only allow swizzling once. + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + // Swizzle any classes that implement one of these selectors. + const SEL selectors[] = { + @selector(connectionDidFinishLoading:), + @selector(connection:willSendRequest:redirectResponse:), + @selector(connection:didReceiveResponse:), + @selector(connection:didReceiveData:), + @selector(connection:didFailWithError:), + @selector(URLSession:task:willPerformHTTPRedirection:newRequest:completionHandler:), + @selector(URLSession:dataTask:didReceiveData:), + @selector(URLSession:dataTask:didReceiveResponse:completionHandler:), + @selector(URLSession:task:didCompleteWithError:), + @selector(URLSession:dataTask:didBecomeDownloadTask:), + @selector(URLSession:downloadTask:didWriteData:totalBytesWritten:totalBytesExpectedToWrite:), + @selector(URLSession:downloadTask:didFinishDownloadingToURL:) + }; + + const int numSelectors = sizeof(selectors) / sizeof(SEL); + + Class *classes = NULL; + int numClasses = objc_getClassList(NULL, 0); + + if (numClasses > 0) { + classes = (__unsafe_unretained Class *)malloc(sizeof(Class) * numClasses); + numClasses = objc_getClassList(classes, numClasses); + for (NSInteger classIndex = 0; classIndex < numClasses; ++classIndex) { + Class className = classes[classIndex]; + + if (className == [FLEXNetworkObserver class]) { + continue; + } + + // Use the runtime API rather than the methods on NSObject to avoid sending messages to + // classes we're not interested in swizzling. Otherwise we hit +initialize on all classes. + // NOTE: calling class_getInstanceMethod() DOES send +initialize to the class. That's why we iterate through the method list. + unsigned int methodCount = 0; + Method *methods = class_copyMethodList(className, &methodCount); + BOOL matchingSelectorFound = NO; + for (unsigned int methodIndex = 0; methodIndex < methodCount; methodIndex++) { + for (int selectorIndex = 0; selectorIndex < numSelectors; ++selectorIndex) { + if (method_getName(methods[methodIndex]) == selectors[selectorIndex]) { + [self injectIntoDelegateClass:className]; + matchingSelectorFound = YES; + break; + } + } + if (matchingSelectorFound) { + break; + } + } + free(methods); + } + + free(classes); + } + + [self injectIntoNSURLConnectionCancel]; + [self injectIntoNSURLSessionTaskResume]; + + [self injectIntoNSURLConnectionAsynchronousClassMethod]; + [self injectIntoNSURLConnectionSynchronousClassMethod]; + + [self injectIntoNSURLSessionAsyncDataAndDownloadTaskMethods]; + [self injectIntoNSURLSessionAsyncUploadTaskMethods]; + }); +} + ++ (void)injectIntoDelegateClass:(Class)cls +{ + // Connections + [self injectWillSendRequestIntoDelegateClass:cls]; + [self injectDidReceiveDataIntoDelegateClass:cls]; + [self injectDidReceiveResponseIntoDelegateClass:cls]; + [self injectDidFinishLoadingIntoDelegateClass:cls]; + [self injectDidFailWithErrorIntoDelegateClass:cls]; + + // Sessions + [self injectTaskWillPerformHTTPRedirectionIntoDelegateClass:cls]; + [self injectTaskDidReceiveDataIntoDelegateClass:cls]; + [self injectTaskDidReceiveResponseIntoDelegateClass:cls]; + [self injectTaskDidCompleteWithErrorIntoDelegateClass:cls]; + [self injectRespondsToSelectorIntoDelegateClass:cls]; + + // Data tasks + [self injectDataTaskDidBecomeDownloadTaskIntoDelegateClass:cls]; + + // Download tasks + [self injectDownloadTaskDidWriteDataIntoDelegateClass:cls]; + [self injectDownloadTaskDidFinishDownloadingIntoDelegateClass:cls]; +} + ++ (void)injectIntoNSURLConnectionCancel +{ + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + Class className = [NSURLConnection class]; + SEL selector = @selector(cancel); + SEL swizzledSelector = [FLEXUtility swizzledSelectorForSelector:selector]; + Method originalCancel = class_getInstanceMethod(className, selector); + + void (^swizzleBlock)(NSURLConnection *) = ^(NSURLConnection *slf) { + [[FLEXNetworkObserver sharedObserver] connectionWillCancel:slf]; + ((void(*)(id, SEL))objc_msgSend)(slf, swizzledSelector); + }; + + IMP implementation = imp_implementationWithBlock(swizzleBlock); + class_addMethod(className, swizzledSelector, implementation, method_getTypeEncoding(originalCancel)); + Method newCancel = class_getInstanceMethod(className, swizzledSelector); + method_exchangeImplementations(originalCancel, newCancel); + }); +} + ++ (void)injectIntoNSURLSessionTaskResume +{ + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + // In iOS 7 resume lives in __NSCFLocalSessionTask + // In iOS 8 resume lives in NSURLSessionTask + // In iOS 9 resume lives in __NSCFURLSessionTask + Class className = Nil; + if (![[NSProcessInfo processInfo] respondsToSelector:@selector(operatingSystemVersion)]) { + className = NSClassFromString([@[@"__", @"NSC", @"FLocalS", @"ession", @"Task"] componentsJoinedByString:@""]); + } else if ([[NSProcessInfo processInfo] operatingSystemVersion].majorVersion < 9) { + className = [NSURLSessionTask class]; + } else { + className = NSClassFromString([@[@"__", @"NSC", @"FURLS", @"ession", @"Task"] componentsJoinedByString:@""]); + } + SEL selector = @selector(resume); + SEL swizzledSelector = [FLEXUtility swizzledSelectorForSelector:selector]; + + Method originalResume = class_getInstanceMethod(className, selector); + + void (^swizzleBlock)(NSURLSessionTask *) = ^(NSURLSessionTask *slf) { + [[FLEXNetworkObserver sharedObserver] URLSessionTaskWillResume:slf]; + ((void(*)(id, SEL))objc_msgSend)(slf, swizzledSelector); + }; + + IMP implementation = imp_implementationWithBlock(swizzleBlock); + class_addMethod(className, swizzledSelector, implementation, method_getTypeEncoding(originalResume)); + Method newResume = class_getInstanceMethod(className, swizzledSelector); + method_exchangeImplementations(originalResume, newResume); + }); +} + ++ (void)injectIntoNSURLConnectionAsynchronousClassMethod +{ + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + Class className = objc_getMetaClass(class_getName([NSURLConnection class])); + SEL selector = @selector(sendAsynchronousRequest:queue:completionHandler:); + SEL swizzledSelector = [FLEXUtility swizzledSelectorForSelector:selector]; + + typedef void (^NSURLConnectionAsyncCompletion)(NSURLResponse *response, NSData *data, NSError *connectionError); + + void (^asyncSwizzleBlock)(Class, NSURLRequest *, NSOperationQueue *, NSURLConnectionAsyncCompletion) = ^(Class slf, NSURLRequest *request, NSOperationQueue *queue, NSURLConnectionAsyncCompletion completion) { + NSString *requestID = [self nextRequestID]; + [[FLEXNetworkRecorder defaultRecorder] recordRequestWillBeSentWithRequestID:requestID request:request redirectResponse:nil]; + NSString *mechanism = [self mechanismFromClassMethod:selector onClass:className]; + [[FLEXNetworkRecorder defaultRecorder] recordMechanism:mechanism forRequestID:requestID]; + NSURLConnectionAsyncCompletion completionWrapper = ^(NSURLResponse *response, NSData *data, NSError *connectionError) { + [[FLEXNetworkRecorder defaultRecorder] recordResponseReceivedWithRequestID:requestID response:response]; + [[FLEXNetworkRecorder defaultRecorder] recordDataReceivedWithRequestID:requestID dataLength:[data length]]; + if (connectionError) { + [[FLEXNetworkRecorder defaultRecorder] recordLoadingFailedWithRequestID:requestID error:connectionError]; + } else { + [[FLEXNetworkRecorder defaultRecorder] recordLoadingFinishedWithRequestID:requestID responseBody:data]; + } + + // Call through to the original completion handler + if (completion) { + completion(response, data, connectionError); + } + }; + ((void(*)(id, SEL, id, id, id))objc_msgSend)(slf, swizzledSelector, request, queue, completionWrapper); + }; + + [FLEXUtility replaceImplementationOfKnownSelector:selector onClass:className withBlock:asyncSwizzleBlock swizzledSelector:swizzledSelector]; + }); +} + ++ (void)injectIntoNSURLConnectionSynchronousClassMethod +{ + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + Class className = objc_getMetaClass(class_getName([NSURLConnection class])); + SEL selector = @selector(sendSynchronousRequest:returningResponse:error:); + SEL swizzledSelector = [FLEXUtility swizzledSelectorForSelector:selector]; + + NSData *(^syncSwizzleBlock)(Class, NSURLRequest *, NSURLResponse **, NSError **) = ^NSData *(Class slf, NSURLRequest *request, NSURLResponse **response, NSError **error) { + NSData *data = nil; + NSString *requestID = [self nextRequestID]; + [[FLEXNetworkRecorder defaultRecorder] recordRequestWillBeSentWithRequestID:requestID request:request redirectResponse:nil]; + NSString *mechanism = [self mechanismFromClassMethod:selector onClass:className]; + [[FLEXNetworkRecorder defaultRecorder] recordMechanism:mechanism forRequestID:requestID]; + NSError *temporaryError = nil; + NSURLResponse *temporaryResponse = nil; + data = ((id(*)(id, SEL, id, NSURLResponse **, NSError **))objc_msgSend)(slf, swizzledSelector, request, &temporaryResponse, &temporaryError); + [[FLEXNetworkRecorder defaultRecorder] recordResponseReceivedWithRequestID:requestID response:temporaryResponse]; + [[FLEXNetworkRecorder defaultRecorder] recordDataReceivedWithRequestID:requestID dataLength:[data length]]; + if (temporaryError) { + [[FLEXNetworkRecorder defaultRecorder] recordLoadingFailedWithRequestID:requestID error:temporaryError]; + } else { + [[FLEXNetworkRecorder defaultRecorder] recordLoadingFinishedWithRequestID:requestID responseBody:data]; + } + if (error) { + *error = temporaryError; + } + if (response) { + *response = temporaryResponse; + } + return data; + }; + + [FLEXUtility replaceImplementationOfKnownSelector:selector onClass:className withBlock:syncSwizzleBlock swizzledSelector:swizzledSelector]; + }); +} + ++ (void)injectIntoNSURLSessionAsyncDataAndDownloadTaskMethods +{ + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + Class className = [NSURLSession class]; + + // The method signatures here are close enough that we can use the same logic to inject into all of them. + const SEL selectors[] = { + @selector(dataTaskWithRequest:completionHandler:), + @selector(dataTaskWithURL:completionHandler:), + @selector(downloadTaskWithRequest:completionHandler:), + @selector(downloadTaskWithResumeData:completionHandler:), + @selector(downloadTaskWithURL:completionHandler:) + }; + + const int numSelectors = sizeof(selectors) / sizeof(SEL); + + for (int selectorIndex = 0; selectorIndex < numSelectors; selectorIndex++) { + SEL selector = selectors[selectorIndex]; + SEL swizzledSelector = [FLEXUtility swizzledSelectorForSelector:selector]; + + if ([FLEXUtility instanceRespondsButDoesNotImplementSelector:selector class:className]) { + // iOS 7 does not implement these methods on NSURLSession. We actually want to + // swizzle __NSCFURLSession, which we can get from the class of the shared session + className = [[NSURLSession sharedSession] class]; + } + + NSURLSessionTask *(^asyncDataOrDownloadSwizzleBlock)(Class, id, NSURLSessionAsyncCompletion) = ^NSURLSessionTask *(Class slf, id argument, NSURLSessionAsyncCompletion completion) { + NSURLSessionTask *task = nil; + // If completion block was not provided sender expect to receive delegated methods or does not + // interested in callback at all. In this case we should just call original method implementation + // with nil completion block. + if (completion) { + NSString *requestID = [self nextRequestID]; + NSString *mechanism = [self mechanismFromClassMethod:selector onClass:className]; + NSURLSessionAsyncCompletion completionWrapper = [self asyncCompletionWrapperForRequestID:requestID mechanism:mechanism completion:completion]; + task = ((id(*)(id, SEL, id, id))objc_msgSend)(slf, swizzledSelector, argument, completionWrapper); + [self setRequestID:requestID forConnectionOrTask:task]; + } else { + task = ((id(*)(id, SEL, id, id))objc_msgSend)(slf, swizzledSelector, argument, completion); + } + return task; + }; + + [FLEXUtility replaceImplementationOfKnownSelector:selector onClass:className withBlock:asyncDataOrDownloadSwizzleBlock swizzledSelector:swizzledSelector]; + } + }); +} + ++ (void)injectIntoNSURLSessionAsyncUploadTaskMethods +{ + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + Class className = [NSURLSession class]; + + // The method signatures here are close enough that we can use the same logic to inject into both of them. + // Note that they have 3 arguments, so we can't easily combine with the data and download method above. + const SEL selectors[] = { + @selector(uploadTaskWithRequest:fromData:completionHandler:), + @selector(uploadTaskWithRequest:fromFile:completionHandler:) + }; + + const int numSelectors = sizeof(selectors) / sizeof(SEL); + + for (int selectorIndex = 0; selectorIndex < numSelectors; selectorIndex++) { + SEL selector = selectors[selectorIndex]; + SEL swizzledSelector = [FLEXUtility swizzledSelectorForSelector:selector]; + + if ([FLEXUtility instanceRespondsButDoesNotImplementSelector:selector class:className]) { + // iOS 7 does not implement these methods on NSURLSession. We actually want to + // swizzle __NSCFURLSession, which we can get from the class of the shared session + className = [[NSURLSession sharedSession] class]; + } + + NSURLSessionUploadTask *(^asyncUploadTaskSwizzleBlock)(Class, NSURLRequest *, id, NSURLSessionAsyncCompletion) = ^NSURLSessionUploadTask *(Class slf, NSURLRequest *request, id argument, NSURLSessionAsyncCompletion completion) { + NSURLSessionUploadTask *task = nil; + if (completion) { + NSString *requestID = [self nextRequestID]; + NSString *mechanism = [self mechanismFromClassMethod:selector onClass:className]; + NSURLSessionAsyncCompletion completionWrapper = [self asyncCompletionWrapperForRequestID:requestID mechanism:mechanism completion:completion]; + task = ((id(*)(id, SEL, id, id, id))objc_msgSend)(slf, swizzledSelector, request, argument, completionWrapper); + [self setRequestID:requestID forConnectionOrTask:task]; + } else { + task = ((id(*)(id, SEL, id, id, id))objc_msgSend)(slf, swizzledSelector, request, argument, completion); + } + return task; + }; + + [FLEXUtility replaceImplementationOfKnownSelector:selector onClass:className withBlock:asyncUploadTaskSwizzleBlock swizzledSelector:swizzledSelector]; + } + }); +} + ++ (NSString *)mechanismFromClassMethod:(SEL)selector onClass:(Class)className +{ + return [NSString stringWithFormat:@"+[%@ %@]", NSStringFromClass(className), NSStringFromSelector(selector)]; +} + ++ (NSURLSessionAsyncCompletion)asyncCompletionWrapperForRequestID:(NSString *)requestID mechanism:(NSString *)mechanism completion:(NSURLSessionAsyncCompletion)completion +{ + NSURLSessionAsyncCompletion completionWrapper = ^(id fileURLOrData, NSURLResponse *response, NSError *error) { + [[FLEXNetworkRecorder defaultRecorder] recordMechanism:mechanism forRequestID:requestID]; + [[FLEXNetworkRecorder defaultRecorder] recordResponseReceivedWithRequestID:requestID response:response]; + NSData *data = nil; + if ([fileURLOrData isKindOfClass:[NSURL class]]) { + data = [NSData dataWithContentsOfURL:fileURLOrData]; + } else if ([fileURLOrData isKindOfClass:[NSData class]]) { + data = fileURLOrData; + } + [[FLEXNetworkRecorder defaultRecorder] recordDataReceivedWithRequestID:requestID dataLength:[data length]]; + if (error) { + [[FLEXNetworkRecorder defaultRecorder] recordLoadingFailedWithRequestID:requestID error:error]; + } else { + [[FLEXNetworkRecorder defaultRecorder] recordLoadingFinishedWithRequestID:requestID responseBody:data]; + } + + // Call through to the original completion handler + if (completion) { + completion(fileURLOrData, response, error); + } + }; + return completionWrapper; +} + ++ (void)injectWillSendRequestIntoDelegateClass:(Class)cls +{ + SEL selector = @selector(connection:willSendRequest:redirectResponse:); + SEL swizzledSelector = [FLEXUtility swizzledSelectorForSelector:selector]; + + Protocol *protocol = @protocol(NSURLConnectionDataDelegate); + if (!protocol) { + protocol = @protocol(NSURLConnectionDelegate); + } + + struct objc_method_description methodDescription = protocol_getMethodDescription(protocol, selector, NO, YES); + + typedef NSURLRequest *(^NSURLConnectionWillSendRequestBlock)(id slf, NSURLConnection *connection, NSURLRequest *request, NSURLResponse *response); + + NSURLConnectionWillSendRequestBlock undefinedBlock = ^NSURLRequest *(id slf, NSURLConnection *connection, NSURLRequest *request, NSURLResponse *response) { + [[FLEXNetworkObserver sharedObserver] connection:connection willSendRequest:request redirectResponse:response delegate:slf]; + return request; + }; + + NSURLConnectionWillSendRequestBlock implementationBlock = ^NSURLRequest *(id slf, NSURLConnection *connection, NSURLRequest *request, NSURLResponse *response) { + __block NSURLRequest *returnValue = nil; + [self sniffWithoutDuplicationForObject:connection selector:selector sniffingBlock:^{ + undefinedBlock(slf, connection, request, response); + } originalImplementationBlock:^{ + returnValue = ((id(*)(id, SEL, id, id, id))objc_msgSend)(slf, swizzledSelector, connection, request, response); + }]; + return returnValue; + }; + + [FLEXUtility replaceImplementationOfSelector:selector withSelector:swizzledSelector forClass:cls withMethodDescription:methodDescription implementationBlock:implementationBlock undefinedBlock:undefinedBlock]; +} + ++ (void)injectDidReceiveResponseIntoDelegateClass:(Class)cls +{ + SEL selector = @selector(connection:didReceiveResponse:); + SEL swizzledSelector = [FLEXUtility swizzledSelectorForSelector:selector]; + + Protocol *protocol = @protocol(NSURLConnectionDataDelegate); + if (!protocol) { + protocol = @protocol(NSURLConnectionDelegate); + } + + struct objc_method_description methodDescription = protocol_getMethodDescription(protocol, selector, NO, YES); + + typedef void (^NSURLConnectionDidReceiveResponseBlock)(id slf, NSURLConnection *connection, NSURLResponse *response); + + NSURLConnectionDidReceiveResponseBlock undefinedBlock = ^(id slf, NSURLConnection *connection, NSURLResponse *response) { + [[FLEXNetworkObserver sharedObserver] connection:connection didReceiveResponse:response delegate:slf]; + }; + + NSURLConnectionDidReceiveResponseBlock implementationBlock = ^(id slf, NSURLConnection *connection, NSURLResponse *response) { + [self sniffWithoutDuplicationForObject:connection selector:selector sniffingBlock:^{ + undefinedBlock(slf, connection, response); + } originalImplementationBlock:^{ + ((void(*)(id, SEL, id, id))objc_msgSend)(slf, swizzledSelector, connection, response); + }]; + }; + + [FLEXUtility replaceImplementationOfSelector:selector withSelector:swizzledSelector forClass:cls withMethodDescription:methodDescription implementationBlock:implementationBlock undefinedBlock:undefinedBlock]; +} + ++ (void)injectDidReceiveDataIntoDelegateClass:(Class)cls +{ + SEL selector = @selector(connection:didReceiveData:); + SEL swizzledSelector = [FLEXUtility swizzledSelectorForSelector:selector]; + + Protocol *protocol = @protocol(NSURLConnectionDataDelegate); + if (!protocol) { + protocol = @protocol(NSURLConnectionDelegate); + } + + struct objc_method_description methodDescription = protocol_getMethodDescription(protocol, selector, NO, YES); + + typedef void (^NSURLConnectionDidReceiveDataBlock)(id slf, NSURLConnection *connection, NSData *data); + + NSURLConnectionDidReceiveDataBlock undefinedBlock = ^(id slf, NSURLConnection *connection, NSData *data) { + [[FLEXNetworkObserver sharedObserver] connection:connection didReceiveData:data delegate:slf]; + }; + + NSURLConnectionDidReceiveDataBlock implementationBlock = ^(id slf, NSURLConnection *connection, NSData *data) { + [self sniffWithoutDuplicationForObject:connection selector:selector sniffingBlock:^{ + undefinedBlock(slf, connection, data); + } originalImplementationBlock:^{ + ((void(*)(id, SEL, id, id))objc_msgSend)(slf, swizzledSelector, connection, data); + }]; + }; + + [FLEXUtility replaceImplementationOfSelector:selector withSelector:swizzledSelector forClass:cls withMethodDescription:methodDescription implementationBlock:implementationBlock undefinedBlock:undefinedBlock]; +} + ++ (void)injectDidFinishLoadingIntoDelegateClass:(Class)cls +{ + SEL selector = @selector(connectionDidFinishLoading:); + SEL swizzledSelector = [FLEXUtility swizzledSelectorForSelector:selector]; + + Protocol *protocol = @protocol(NSURLConnectionDataDelegate); + if (!protocol) { + protocol = @protocol(NSURLConnectionDelegate); + } + + struct objc_method_description methodDescription = protocol_getMethodDescription(protocol, selector, NO, YES); + + typedef void (^NSURLConnectionDidFinishLoadingBlock)(id slf, NSURLConnection *connection); + + NSURLConnectionDidFinishLoadingBlock undefinedBlock = ^(id slf, NSURLConnection *connection) { + [[FLEXNetworkObserver sharedObserver] connectionDidFinishLoading:connection delegate:slf]; + }; + + NSURLConnectionDidFinishLoadingBlock implementationBlock = ^(id slf, NSURLConnection *connection) { + [self sniffWithoutDuplicationForObject:connection selector:selector sniffingBlock:^{ + undefinedBlock(slf, connection); + } originalImplementationBlock:^{ + ((void(*)(id, SEL, id))objc_msgSend)(slf, swizzledSelector, connection); + }]; + }; + + [FLEXUtility replaceImplementationOfSelector:selector withSelector:swizzledSelector forClass:cls withMethodDescription:methodDescription implementationBlock:implementationBlock undefinedBlock:undefinedBlock]; +} + ++ (void)injectDidFailWithErrorIntoDelegateClass:(Class)cls +{ + SEL selector = @selector(connection:didFailWithError:); + SEL swizzledSelector = [FLEXUtility swizzledSelectorForSelector:selector]; + + Protocol *protocol = @protocol(NSURLConnectionDelegate); + struct objc_method_description methodDescription = protocol_getMethodDescription(protocol, selector, NO, YES); + + typedef void (^NSURLConnectionDidFailWithErrorBlock)(id slf, NSURLConnection *connection, NSError *error); + + NSURLConnectionDidFailWithErrorBlock undefinedBlock = ^(id slf, NSURLConnection *connection, NSError *error) { + [[FLEXNetworkObserver sharedObserver] connection:connection didFailWithError:error delegate:slf]; + }; + + NSURLConnectionDidFailWithErrorBlock implementationBlock = ^(id slf, NSURLConnection *connection, NSError *error) { + [self sniffWithoutDuplicationForObject:connection selector:selector sniffingBlock:^{ + undefinedBlock(slf, connection, error); + } originalImplementationBlock:^{ + ((void(*)(id, SEL, id, id))objc_msgSend)(slf, swizzledSelector, connection, error); + }]; + }; + + [FLEXUtility replaceImplementationOfSelector:selector withSelector:swizzledSelector forClass:cls withMethodDescription:methodDescription implementationBlock:implementationBlock undefinedBlock:undefinedBlock]; +} + ++ (void)injectTaskWillPerformHTTPRedirectionIntoDelegateClass:(Class)cls +{ + SEL selector = @selector(URLSession:task:willPerformHTTPRedirection:newRequest:completionHandler:); + SEL swizzledSelector = [FLEXUtility swizzledSelectorForSelector:selector]; + + Protocol *protocol = @protocol(NSURLSessionTaskDelegate); + + struct objc_method_description methodDescription = protocol_getMethodDescription(protocol, selector, NO, YES); + + typedef void (^NSURLSessionWillPerformHTTPRedirectionBlock)(id slf, NSURLSession *session, NSURLSessionTask *task, NSHTTPURLResponse *response, NSURLRequest *newRequest, void(^completionHandler)(NSURLRequest *)); + + NSURLSessionWillPerformHTTPRedirectionBlock undefinedBlock = ^(id slf, NSURLSession *session, NSURLSessionTask *task, NSHTTPURLResponse *response, NSURLRequest *newRequest, void(^completionHandler)(NSURLRequest *)) { + [[FLEXNetworkObserver sharedObserver] URLSession:session task:task willPerformHTTPRedirection:response newRequest:newRequest completionHandler:completionHandler delegate:slf]; + completionHandler(newRequest); + }; + + NSURLSessionWillPerformHTTPRedirectionBlock implementationBlock = ^(id slf, NSURLSession *session, NSURLSessionTask *task, NSHTTPURLResponse *response, NSURLRequest *newRequest, void(^completionHandler)(NSURLRequest *)) { + [self sniffWithoutDuplicationForObject:session selector:selector sniffingBlock:^{ + [[FLEXNetworkObserver sharedObserver] URLSession:session task:task willPerformHTTPRedirection:response newRequest:newRequest completionHandler:completionHandler delegate:slf]; + } originalImplementationBlock:^{ + ((id(*)(id, SEL, id, id, id, id, void(^)(NSURLRequest *)))objc_msgSend)(slf, swizzledSelector, session, task, response, newRequest, completionHandler); + }]; + }; + + [FLEXUtility replaceImplementationOfSelector:selector withSelector:swizzledSelector forClass:cls withMethodDescription:methodDescription implementationBlock:implementationBlock undefinedBlock:undefinedBlock]; + +} + ++ (void)injectTaskDidReceiveDataIntoDelegateClass:(Class)cls +{ + SEL selector = @selector(URLSession:dataTask:didReceiveData:); + SEL swizzledSelector = [FLEXUtility swizzledSelectorForSelector:selector]; + + Protocol *protocol = @protocol(NSURLSessionDataDelegate); + + struct objc_method_description methodDescription = protocol_getMethodDescription(protocol, selector, NO, YES); + + typedef void (^NSURLSessionDidReceiveDataBlock)(id slf, NSURLSession *session, NSURLSessionDataTask *dataTask, NSData *data); + + NSURLSessionDidReceiveDataBlock undefinedBlock = ^(id slf, NSURLSession *session, NSURLSessionDataTask *dataTask, NSData *data) { + [[FLEXNetworkObserver sharedObserver] URLSession:session dataTask:dataTask didReceiveData:data delegate:slf]; + }; + + NSURLSessionDidReceiveDataBlock implementationBlock = ^(id slf, NSURLSession *session, NSURLSessionDataTask *dataTask, NSData *data) { + [self sniffWithoutDuplicationForObject:session selector:selector sniffingBlock:^{ + undefinedBlock(slf, session, dataTask, data); + } originalImplementationBlock:^{ + ((void(*)(id, SEL, id, id, id))objc_msgSend)(slf, swizzledSelector, session, dataTask, data); + }]; + }; + + [FLEXUtility replaceImplementationOfSelector:selector withSelector:swizzledSelector forClass:cls withMethodDescription:methodDescription implementationBlock:implementationBlock undefinedBlock:undefinedBlock]; + +} + ++ (void)injectDataTaskDidBecomeDownloadTaskIntoDelegateClass:(Class)cls +{ + SEL selector = @selector(URLSession:dataTask:didBecomeDownloadTask:); + SEL swizzledSelector = [FLEXUtility swizzledSelectorForSelector:selector]; + + Protocol *protocol = @protocol(NSURLSessionDataDelegate); + + struct objc_method_description methodDescription = protocol_getMethodDescription(protocol, selector, NO, YES); + + typedef void (^NSURLSessionDidBecomeDownloadTaskBlock)(id slf, NSURLSession *session, NSURLSessionDataTask *dataTask, NSURLSessionDownloadTask *downloadTask); + + NSURLSessionDidBecomeDownloadTaskBlock undefinedBlock = ^(id slf, NSURLSession *session, NSURLSessionDataTask *dataTask, NSURLSessionDownloadTask *downloadTask) { + [[FLEXNetworkObserver sharedObserver] URLSession:session dataTask:dataTask didBecomeDownloadTask:downloadTask delegate:slf]; + }; + + NSURLSessionDidBecomeDownloadTaskBlock implementationBlock = ^(id slf, NSURLSession *session, NSURLSessionDataTask *dataTask, NSURLSessionDownloadTask *downloadTask) { + [self sniffWithoutDuplicationForObject:session selector:selector sniffingBlock:^{ + undefinedBlock(slf, session, dataTask, downloadTask); + } originalImplementationBlock:^{ + ((void(*)(id, SEL, id, id, id))objc_msgSend)(slf, swizzledSelector, session, dataTask, downloadTask); + }]; + }; + + [FLEXUtility replaceImplementationOfSelector:selector withSelector:swizzledSelector forClass:cls withMethodDescription:methodDescription implementationBlock:implementationBlock undefinedBlock:undefinedBlock]; +} + ++ (void)injectTaskDidReceiveResponseIntoDelegateClass:(Class)cls +{ + SEL selector = @selector(URLSession:dataTask:didReceiveResponse:completionHandler:); + SEL swizzledSelector = [FLEXUtility swizzledSelectorForSelector:selector]; + + Protocol *protocol = @protocol(NSURLSessionDataDelegate); + + struct objc_method_description methodDescription = protocol_getMethodDescription(protocol, selector, NO, YES); + + typedef void (^NSURLSessionDidReceiveResponseBlock)(id slf, NSURLSession *session, NSURLSessionDataTask *dataTask, NSURLResponse *response, void(^completionHandler)(NSURLSessionResponseDisposition disposition)); + + NSURLSessionDidReceiveResponseBlock undefinedBlock = ^(id slf, NSURLSession *session, NSURLSessionDataTask *dataTask, NSURLResponse *response, void(^completionHandler)(NSURLSessionResponseDisposition disposition)) { + [[FLEXNetworkObserver sharedObserver] URLSession:session dataTask:dataTask didReceiveResponse:response completionHandler:completionHandler delegate:slf]; + completionHandler(NSURLSessionResponseAllow); + }; + + NSURLSessionDidReceiveResponseBlock implementationBlock = ^(id slf, NSURLSession *session, NSURLSessionDataTask *dataTask, NSURLResponse *response, void(^completionHandler)(NSURLSessionResponseDisposition disposition)) { + [self sniffWithoutDuplicationForObject:session selector:selector sniffingBlock:^{ + [[FLEXNetworkObserver sharedObserver] URLSession:session dataTask:dataTask didReceiveResponse:response completionHandler:completionHandler delegate:slf]; + } originalImplementationBlock:^{ + ((void(*)(id, SEL, id, id, id, void(^)(NSURLSessionResponseDisposition)))objc_msgSend)(slf, swizzledSelector, session, dataTask, response, completionHandler); + }]; + }; + + [FLEXUtility replaceImplementationOfSelector:selector withSelector:swizzledSelector forClass:cls withMethodDescription:methodDescription implementationBlock:implementationBlock undefinedBlock:undefinedBlock]; + +} + ++ (void)injectTaskDidCompleteWithErrorIntoDelegateClass:(Class)cls +{ + SEL selector = @selector(URLSession:task:didCompleteWithError:); + SEL swizzledSelector = [FLEXUtility swizzledSelectorForSelector:selector]; + + Protocol *protocol = @protocol(NSURLSessionTaskDelegate); + struct objc_method_description methodDescription = protocol_getMethodDescription(protocol, selector, NO, YES); + + typedef void (^NSURLSessionTaskDidCompleteWithErrorBlock)(id slf, NSURLSession *session, NSURLSessionTask *task, NSError *error); + + NSURLSessionTaskDidCompleteWithErrorBlock undefinedBlock = ^(id slf, NSURLSession *session, NSURLSessionTask *task, NSError *error) { + [[FLEXNetworkObserver sharedObserver] URLSession:session task:task didCompleteWithError:error delegate:slf]; + }; + + NSURLSessionTaskDidCompleteWithErrorBlock implementationBlock = ^(id slf, NSURLSession *session, NSURLSessionTask *task, NSError *error) { + [self sniffWithoutDuplicationForObject:session selector:selector sniffingBlock:^{ + undefinedBlock(slf, session, task, error); + } originalImplementationBlock:^{ + ((void(*)(id, SEL, id, id, id))objc_msgSend)(slf, swizzledSelector, session, task, error); + }]; + }; + + [FLEXUtility replaceImplementationOfSelector:selector withSelector:swizzledSelector forClass:cls withMethodDescription:methodDescription implementationBlock:implementationBlock undefinedBlock:undefinedBlock]; +} + +// Used for overriding AFNetworking behavior ++ (void)injectRespondsToSelectorIntoDelegateClass:(Class)cls +{ + SEL selector = @selector(respondsToSelector:); + SEL swizzledSelector = [FLEXUtility swizzledSelectorForSelector:selector]; + + //Protocol *protocol = @protocol(NSURLSessionTaskDelegate); + Method method = class_getInstanceMethod(cls, selector); + struct objc_method_description methodDescription = *method_getDescription(method); + + BOOL (^undefinedBlock)(id , SEL) = ^(id slf, SEL sel) { + return YES; + }; + + BOOL (^implementationBlock)(id , SEL) = ^(id slf, SEL sel) { + if (sel == @selector(URLSession:dataTask:didReceiveResponse:completionHandler:)) { + return undefinedBlock(slf, sel); + } + return ((BOOL(*)(id, SEL, SEL))objc_msgSend)(slf, swizzledSelector, sel); + }; + + [FLEXUtility replaceImplementationOfSelector:selector withSelector:swizzledSelector forClass:cls withMethodDescription:methodDescription implementationBlock:implementationBlock undefinedBlock:undefinedBlock]; +} + + ++ (void)injectDownloadTaskDidFinishDownloadingIntoDelegateClass:(Class)cls +{ + SEL selector = @selector(URLSession:downloadTask:didFinishDownloadingToURL:); + SEL swizzledSelector = [FLEXUtility swizzledSelectorForSelector:selector]; + + Protocol *protocol = @protocol(NSURLSessionDownloadDelegate); + struct objc_method_description methodDescription = protocol_getMethodDescription(protocol, selector, NO, YES); + + typedef void (^NSURLSessionDownloadTaskDidFinishDownloadingBlock)(id slf, NSURLSession *session, NSURLSessionDownloadTask *task, NSURL *location); + + NSURLSessionDownloadTaskDidFinishDownloadingBlock undefinedBlock = ^(id slf, NSURLSession *session, NSURLSessionDownloadTask *task, NSURL *location) { + NSData *data = [NSData dataWithContentsOfFile:location.relativePath]; + [[FLEXNetworkObserver sharedObserver] URLSession:session task:task didFinishDownloadingToURL:location data:data delegate:slf]; + }; + + NSURLSessionDownloadTaskDidFinishDownloadingBlock implementationBlock = ^(id slf, NSURLSession *session, NSURLSessionDownloadTask *task, NSURL *location) { + [self sniffWithoutDuplicationForObject:session selector:selector sniffingBlock:^{ + undefinedBlock(slf, session, task, location); + } originalImplementationBlock:^{ + ((void(*)(id, SEL, id, id, id))objc_msgSend)(slf, swizzledSelector, session, task, location); + }]; + }; + + [FLEXUtility replaceImplementationOfSelector:selector withSelector:swizzledSelector forClass:cls withMethodDescription:methodDescription implementationBlock:implementationBlock undefinedBlock:undefinedBlock]; +} + ++ (void)injectDownloadTaskDidWriteDataIntoDelegateClass:(Class)cls +{ + SEL selector = @selector(URLSession:downloadTask:didWriteData:totalBytesWritten:totalBytesExpectedToWrite:); + SEL swizzledSelector = [FLEXUtility swizzledSelectorForSelector:selector]; + + Protocol *protocol = @protocol(NSURLSessionDownloadDelegate); + struct objc_method_description methodDescription = protocol_getMethodDescription(protocol, selector, NO, YES); + + typedef void (^NSURLSessionDownloadTaskDidWriteDataBlock)(id slf, NSURLSession *session, NSURLSessionDownloadTask *task, int64_t bytesWritten, int64_t totalBytesWritten, int64_t totalBytesExpectedToWrite); + + NSURLSessionDownloadTaskDidWriteDataBlock undefinedBlock = ^(id slf, NSURLSession *session, NSURLSessionDownloadTask *task, int64_t bytesWritten, int64_t totalBytesWritten, int64_t totalBytesExpectedToWrite) { + [[FLEXNetworkObserver sharedObserver] URLSession:session downloadTask:task didWriteData:bytesWritten totalBytesWritten:totalBytesWritten totalBytesExpectedToWrite:totalBytesExpectedToWrite delegate:slf]; + }; + + NSURLSessionDownloadTaskDidWriteDataBlock implementationBlock = ^(id slf, NSURLSession *session, NSURLSessionDownloadTask *task, int64_t bytesWritten, int64_t totalBytesWritten, int64_t totalBytesExpectedToWrite) { + [self sniffWithoutDuplicationForObject:session selector:selector sniffingBlock:^{ + undefinedBlock(slf, session, task, bytesWritten, totalBytesWritten, totalBytesExpectedToWrite); + } originalImplementationBlock:^{ + ((void(*)(id, SEL, id, id, int64_t, int64_t, int64_t))objc_msgSend)(slf, swizzledSelector, session, task, bytesWritten, totalBytesWritten, totalBytesExpectedToWrite); + }]; + }; + + [FLEXUtility replaceImplementationOfSelector:selector withSelector:swizzledSelector forClass:cls withMethodDescription:methodDescription implementationBlock:implementationBlock undefinedBlock:undefinedBlock]; + +} + +static char const *const kFLEXRequestIDKey = "kFLEXRequestIDKey"; + ++ (NSString *)requestIDForConnectionOrTask:(id)connectionOrTask +{ + NSString *requestID = objc_getAssociatedObject(connectionOrTask, kFLEXRequestIDKey); + if (!requestID) { + requestID = [self nextRequestID]; + [self setRequestID:requestID forConnectionOrTask:connectionOrTask]; + } + return requestID; +} + ++ (void)setRequestID:(NSString *)requestID forConnectionOrTask:(id)connectionOrTask +{ + objc_setAssociatedObject(connectionOrTask, kFLEXRequestIDKey, requestID, OBJC_ASSOCIATION_RETAIN_NONATOMIC); +} + +#pragma mark - Initialization + +- (id)init +{ + self = [super init]; + if (self) { + self.requestStatesForRequestIDs = [NSMutableDictionary new]; + self.queue = dispatch_queue_create("com.flex.FLEXNetworkObserver", DISPATCH_QUEUE_SERIAL); + } + return self; +} + +#pragma mark - Private Methods + +- (void)performBlock:(dispatch_block_t)block +{ + dispatch_async(_queue, block); +} + +- (FLEXInternalRequestState *)requestStateForRequestID:(NSString *)requestID +{ + FLEXInternalRequestState *requestState = self.requestStatesForRequestIDs[requestID]; + if (!requestState) { + requestState = [FLEXInternalRequestState new]; + [self.requestStatesForRequestIDs setObject:requestState forKey:requestID]; + } + return requestState; +} + +- (void)removeRequestStateForRequestID:(NSString *)requestID +{ + [self.requestStatesForRequestIDs removeObjectForKey:requestID]; +} + +@end + + +@implementation FLEXNetworkObserver (NSURLConnectionHelpers) + +- (void)connection:(NSURLConnection *)connection willSendRequest:(NSURLRequest *)request redirectResponse:(NSURLResponse *)response delegate:(id)delegate +{ + [self performBlock:^{ + NSString *requestID = [[self class] requestIDForConnectionOrTask:connection]; + FLEXInternalRequestState *requestState = [self requestStateForRequestID:requestID]; + requestState.request = request; + [[FLEXNetworkRecorder defaultRecorder] recordRequestWillBeSentWithRequestID:requestID request:request redirectResponse:response]; + NSString *mechanism = [NSString stringWithFormat:@"NSURLConnection (delegate: %@)", [delegate class]]; + [[FLEXNetworkRecorder defaultRecorder] recordMechanism:mechanism forRequestID:requestID]; + }]; +} + +- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response delegate:(id)delegate +{ + [self performBlock:^{ + NSString *requestID = [[self class] requestIDForConnectionOrTask:connection]; + FLEXInternalRequestState *requestState = [self requestStateForRequestID:requestID]; + + NSMutableData *dataAccumulator = nil; + if (response.expectedContentLength < 0) { + dataAccumulator = [NSMutableData new]; + } else { + dataAccumulator = [[NSMutableData alloc] initWithCapacity:(NSUInteger)response.expectedContentLength]; + } + requestState.dataAccumulator = dataAccumulator; + + [[FLEXNetworkRecorder defaultRecorder] recordResponseReceivedWithRequestID:requestID response:response]; + }]; +} + +- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data delegate:(id)delegate +{ + // Just to be safe since we're doing this async + data = [data copy]; + [self performBlock:^{ + NSString *requestID = [[self class] requestIDForConnectionOrTask:connection]; + FLEXInternalRequestState *requestState = [self requestStateForRequestID:requestID]; + [requestState.dataAccumulator appendData:data]; + [[FLEXNetworkRecorder defaultRecorder] recordDataReceivedWithRequestID:requestID dataLength:data.length]; + }]; +} + +- (void)connectionDidFinishLoading:(NSURLConnection *)connection delegate:(id)delegate +{ + [self performBlock:^{ + NSString *requestID = [[self class] requestIDForConnectionOrTask:connection]; + FLEXInternalRequestState *requestState = [self requestStateForRequestID:requestID]; + [[FLEXNetworkRecorder defaultRecorder] recordLoadingFinishedWithRequestID:requestID responseBody:requestState.dataAccumulator]; + [self removeRequestStateForRequestID:requestID]; + }]; +} + +- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error delegate:(id)delegate +{ + [self performBlock:^{ + NSString *requestID = [[self class] requestIDForConnectionOrTask:connection]; + FLEXInternalRequestState *requestState = [self requestStateForRequestID:requestID]; + + // Cancellations can occur prior to the willSendRequest:... NSURLConnection delegate call. + // These are pretty common and clutter up the logs. Only record the failure if the recorder already knows about the request through willSendRequest:... + if (requestState.request) { + [[FLEXNetworkRecorder defaultRecorder] recordLoadingFailedWithRequestID:requestID error:error]; + } + + [self removeRequestStateForRequestID:requestID]; + }]; +} + +- (void)connectionWillCancel:(NSURLConnection *)connection +{ + [self performBlock:^{ + // Mimic the behavior of NSURLSession which is to create an error on cancellation. + NSDictionary *userInfo = @{ NSLocalizedDescriptionKey : @"cancelled" }; + NSError *error = [NSError errorWithDomain:NSURLErrorDomain code:NSURLErrorCancelled userInfo:userInfo]; + [self connection:connection didFailWithError:error delegate:nil]; + }]; +} + +@end + + +@implementation FLEXNetworkObserver (NSURLSessionTaskHelpers) + +- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task willPerformHTTPRedirection:(NSHTTPURLResponse *)response newRequest:(NSURLRequest *)request completionHandler:(void (^)(NSURLRequest *))completionHandler delegate:(id)delegate +{ + [self performBlock:^{ + NSString *requestID = [[self class] requestIDForConnectionOrTask:task]; + [[FLEXNetworkRecorder defaultRecorder] recordRequestWillBeSentWithRequestID:requestID request:request redirectResponse:response]; + }]; +} + +- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition disposition))completionHandler delegate:(id)delegate +{ + [self performBlock:^{ + NSString *requestID = [[self class] requestIDForConnectionOrTask:dataTask]; + FLEXInternalRequestState *requestState = [self requestStateForRequestID:requestID]; + + NSMutableData *dataAccumulator = nil; + if (response.expectedContentLength < 0) { + dataAccumulator = [NSMutableData new]; + } else { + dataAccumulator = [[NSMutableData alloc] initWithCapacity:(NSUInteger)response.expectedContentLength]; + } + requestState.dataAccumulator = dataAccumulator; + + NSString *requestMechanism = [NSString stringWithFormat:@"NSURLSessionDataTask (delegate: %@)", [delegate class]]; + [[FLEXNetworkRecorder defaultRecorder] recordMechanism:requestMechanism forRequestID:requestID]; + + [[FLEXNetworkRecorder defaultRecorder] recordResponseReceivedWithRequestID:requestID response:response]; + }]; +} + +- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didBecomeDownloadTask:(NSURLSessionDownloadTask *)downloadTask delegate:(id)delegate +{ + [self performBlock:^{ + // By setting the request ID of the download task to match the data task, + // it can pick up where the data task left off. + NSString *requestID = [[self class] requestIDForConnectionOrTask:dataTask]; + [[self class] setRequestID:requestID forConnectionOrTask:downloadTask]; + }]; +} + +- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data delegate:(id)delegate +{ + // Just to be safe since we're doing this async + data = [data copy]; + [self performBlock:^{ + NSString *requestID = [[self class] requestIDForConnectionOrTask:dataTask]; + FLEXInternalRequestState *requestState = [self requestStateForRequestID:requestID]; + + [requestState.dataAccumulator appendData:data]; + + [[FLEXNetworkRecorder defaultRecorder] recordDataReceivedWithRequestID:requestID dataLength:data.length]; + }]; +} + +- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error delegate:(id)delegate +{ + [self performBlock:^{ + NSString *requestID = [[self class] requestIDForConnectionOrTask:task]; + FLEXInternalRequestState *requestState = [self requestStateForRequestID:requestID]; + + if (error) { + [[FLEXNetworkRecorder defaultRecorder] recordLoadingFailedWithRequestID:requestID error:error]; + } else { + [[FLEXNetworkRecorder defaultRecorder] recordLoadingFinishedWithRequestID:requestID responseBody:requestState.dataAccumulator]; + } + + [self removeRequestStateForRequestID:requestID]; + }]; +} + +- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite delegate:(id)delegate +{ + [self performBlock:^{ + NSString *requestID = [[self class] requestIDForConnectionOrTask:downloadTask]; + FLEXInternalRequestState *requestState = [self requestStateForRequestID:requestID]; + + if (!requestState.dataAccumulator) { + NSUInteger unsignedBytesExpectedToWrite = totalBytesExpectedToWrite > 0 ? (NSUInteger)totalBytesExpectedToWrite : 0; + requestState.dataAccumulator = [[NSMutableData alloc] initWithCapacity:unsignedBytesExpectedToWrite]; + [[FLEXNetworkRecorder defaultRecorder] recordResponseReceivedWithRequestID:requestID response:downloadTask.response]; + + NSString *requestMechanism = [NSString stringWithFormat:@"NSURLSessionDownloadTask (delegate: %@)", [delegate class]]; + [[FLEXNetworkRecorder defaultRecorder] recordMechanism:requestMechanism forRequestID:requestID]; + } + + [[FLEXNetworkRecorder defaultRecorder] recordDataReceivedWithRequestID:requestID dataLength:bytesWritten]; + }]; +} + +- (void)URLSession:(NSURLSession *)session task:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location data:(NSData *)data delegate:(id)delegate +{ + data = [data copy]; + [self performBlock:^{ + NSString *requestID = [[self class] requestIDForConnectionOrTask:downloadTask]; + FLEXInternalRequestState *requestState = [self requestStateForRequestID:requestID]; + [requestState.dataAccumulator appendData:data]; + }]; +} + +- (void)URLSessionTaskWillResume:(NSURLSessionTask *)task +{ + // Since resume can be called multiple times on the same task, only treat the first resume as + // the equivalent to connection:willSendRequest:... + [self performBlock:^{ + NSString *requestID = [[self class] requestIDForConnectionOrTask:task]; + FLEXInternalRequestState *requestState = [self requestStateForRequestID:requestID]; + if (!requestState.request) { + requestState.request = task.currentRequest; + + [[FLEXNetworkRecorder defaultRecorder] recordRequestWillBeSentWithRequestID:requestID request:task.currentRequest redirectResponse:nil]; + } + }]; +} + +@end diff --git a/iOS/Plugins/SonarKitNetworkPlugin/SKIOSNetworkPlugin/FLEXNetworkLib/FLEXNetworkRecorder.h b/iOS/Plugins/SonarKitNetworkPlugin/SKIOSNetworkPlugin/FLEXNetworkLib/FLEXNetworkRecorder.h new file mode 100755 index 000000000..518e2cf7d --- /dev/null +++ b/iOS/Plugins/SonarKitNetworkPlugin/SKIOSNetworkPlugin/FLEXNetworkLib/FLEXNetworkRecorder.h @@ -0,0 +1,70 @@ +// +// FLEXNetworkRecorder.h +// Flipboard +// +// Created by Ryan Olson on 2/4/15. +// Copyright 2004-present Facebook. All Rights Reserved. +// + +#import + +#import + +// Notifications posted when the record is updated +extern NSString *const kFLEXNetworkRecorderNewTransactionNotification; +extern NSString *const kFLEXNetworkRecorderTransactionUpdatedNotification; +extern NSString *const kFLEXNetworkRecorderUserInfoTransactionKey; +extern NSString *const kFLEXNetworkRecorderTransactionsClearedNotification; + +@class FLEXNetworkTransaction; + +@interface FLEXNetworkRecorder : NSObject + +/// In general, it only makes sense to have one recorder for the entire application. ++ (instancetype)defaultRecorder; + +@property (nonatomic, weak) id delegate; + +/// Defaults to 25 MB if never set. Values set here are presisted across launches of the app. +@property (nonatomic, assign) NSUInteger responseCacheByteLimit; + +/// If NO, the recorder not cache will not cache response for content types with an "image", "video", or "audio" prefix. +@property (nonatomic, assign) BOOL shouldCacheMediaResponses; + +@property (nonatomic, copy) NSArray *hostBlacklist; + + +// Accessing recorded network activity + +/// Array of FLEXNetworkTransaction objects ordered by start time with the newest first. +- (NSArray *)networkTransactions; + +/// The full response data IFF it hasn't been purged due to memory pressure. +- (NSData *)cachedResponseBodyForTransaction:(FLEXNetworkTransaction *)transaction; + +/// Dumps all network transactions and cached response bodies. +- (void)clearRecordedActivity; + + +// Recording network activity + +/// Call when app is about to send HTTP request. +- (void)recordRequestWillBeSentWithRequestID:(NSString *)requestID request:(NSURLRequest *)request redirectResponse:(NSURLResponse *)redirectResponse; + +/// Call when HTTP response is available. +- (void)recordResponseReceivedWithRequestID:(NSString *)requestID response:(NSURLResponse *)response; + +/// Call when data chunk is received over the network. +- (void)recordDataReceivedWithRequestID:(NSString *)requestID dataLength:(int64_t)dataLength; + +/// Call when HTTP request has finished loading. +- (void)recordLoadingFinishedWithRequestID:(NSString *)requestID responseBody:(NSData *)responseBody; + +/// Call when HTTP request has failed to load. +- (void)recordLoadingFailedWithRequestID:(NSString *)requestID error:(NSError *)error; + +/// Call to set the request mechanism anytime after recordRequestWillBeSent... has been called. +/// This string can be set to anything useful about the API used to make the request. +- (void)recordMechanism:(NSString *)mechanism forRequestID:(NSString *)requestID; + +@end diff --git a/iOS/Plugins/SonarKitNetworkPlugin/SKIOSNetworkPlugin/FLEXNetworkLib/FLEXNetworkRecorder.mm b/iOS/Plugins/SonarKitNetworkPlugin/SKIOSNetworkPlugin/FLEXNetworkLib/FLEXNetworkRecorder.mm new file mode 100755 index 000000000..b9d5004c1 --- /dev/null +++ b/iOS/Plugins/SonarKitNetworkPlugin/SKIOSNetworkPlugin/FLEXNetworkLib/FLEXNetworkRecorder.mm @@ -0,0 +1,235 @@ +// +// FLEXNetworkRecorder.m +// Flipboard +// +// Created by Ryan Olson on 2/4/15. +// Copyright 2004-present Facebook. All Rights Reserved. +// + +#import "FLEXNetworkRecorder.h" + +#import "FLEXNetworkTransaction.h" +#import "FLEXUtility.h" + +NSString *const kFLEXNetworkRecorderNewTransactionNotification = @"kFLEXNetworkRecorderNewTransactionNotification"; +NSString *const kFLEXNetworkRecorderTransactionUpdatedNotification = @"kFLEXNetworkRecorderTransactionUpdatedNotification"; +NSString *const kFLEXNetworkRecorderUserInfoTransactionKey = @"transaction"; +NSString *const kFLEXNetworkRecorderTransactionsClearedNotification = @"kFLEXNetworkRecorderTransactionsClearedNotification"; + +NSString *const kFLEXNetworkRecorderResponseCacheLimitDefaultsKey = @"com.flex.responseCacheLimit"; + +@interface FLEXNetworkRecorder () + +@property (nonatomic, strong) NSCache *responseCache; +@property (nonatomic, strong) NSMutableArray *orderedTransactions; +@property (nonatomic, strong) NSMutableDictionary *networkTransactionsForRequestIdentifiers; +@property (nonatomic, strong) dispatch_queue_t queue; +@property (nonatomic, strong) NSMutableDictionary *identifierDict; +@end + +@implementation FLEXNetworkRecorder + +- (instancetype)init +{ + self = [super init]; + if (self) { + _responseCache = [NSCache new]; + NSUInteger responseCacheLimit = [[[NSUserDefaults standardUserDefaults] objectForKey:kFLEXNetworkRecorderResponseCacheLimitDefaultsKey] unsignedIntegerValue]; + if (responseCacheLimit) { + [_responseCache setTotalCostLimit:responseCacheLimit]; + } else { + // Default to 25 MB max. The cache will purge earlier if there is memory pressure. + [_responseCache setTotalCostLimit:25 * 1024 * 1024]; + } + _orderedTransactions = [NSMutableArray array]; + _networkTransactionsForRequestIdentifiers = [NSMutableDictionary dictionary]; + + // Serial queue used because we use mutable objects that are not thread safe + _queue = dispatch_queue_create("com.flex.FLEXNetworkRecorder", DISPATCH_QUEUE_SERIAL); + _identifierDict = [NSMutableDictionary dictionary]; + } + return self; +} + ++ (instancetype)defaultRecorder +{ + static FLEXNetworkRecorder *defaultRecorder = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + defaultRecorder = [[[self class] alloc] init]; + }); + return defaultRecorder; +} + +#pragma mark - Public Data Access + +- (void)setDelegate:(id)delegate { + _delegate = delegate; +} + +- (NSUInteger)responseCacheByteLimit +{ + return [self.responseCache totalCostLimit]; +} + +- (void)setResponseCacheByteLimit:(NSUInteger)responseCacheByteLimit +{ + [self.responseCache setTotalCostLimit:responseCacheByteLimit]; + [[NSUserDefaults standardUserDefaults] setObject:@(responseCacheByteLimit) forKey:kFLEXNetworkRecorderResponseCacheLimitDefaultsKey]; +} + +- (NSArray *)networkTransactions +{ + __block NSArray *transactions = nil; + dispatch_sync(self.queue, ^{ + transactions = [self.orderedTransactions copy]; + }); + return transactions; +} + +- (NSData *)cachedResponseBodyForTransaction:(FLEXNetworkTransaction *)transaction +{ + return [self.responseCache objectForKey:transaction.requestID]; +} + +- (void)clearRecordedActivity +{ + dispatch_async(self.queue, ^{ + [self.responseCache removeAllObjects]; + [self.orderedTransactions removeAllObjects]; + [self.networkTransactionsForRequestIdentifiers removeAllObjects]; + }); +} + +#pragma mark - Network Events + +- (void)recordRequestWillBeSentWithRequestID:(NSString *)requestID request:(NSURLRequest *)request redirectResponse:(NSURLResponse *)redirectResponse +{ + if (![self.identifierDict objectForKey:requestID]) { + self.identifierDict[requestID] = [NSNumber random]; + } + NSDate *startDate = [NSDate date]; + + if (redirectResponse) { + [self recordResponseReceivedWithRequestID:requestID response:redirectResponse]; + [self recordLoadingFinishedWithRequestID:requestID responseBody:nil]; + } + + dispatch_async(self.queue, ^{ + RequestInfo info = { + .identifier = self.identifierDict[requestID].longLongValue, + .timestamp = [NSDate timestamp], + .request = request, + }; + + info.setBody(request.HTTPBody); + [self.delegate didObserveRequest:info]; + + FLEXNetworkTransaction *transaction = [FLEXNetworkTransaction new]; + transaction.requestID = requestID; + transaction.request = request; + transaction.startTime = startDate; + + [self.orderedTransactions insertObject:transaction atIndex:0]; + [self.networkTransactionsForRequestIdentifiers setObject:transaction forKey:requestID]; + transaction.transactionState = FLEXNetworkTransactionStateAwaitingResponse; + }); +} + +/// Call when HTTP response is available. +- (void)recordResponseReceivedWithRequestID:(NSString *)requestID response:(NSURLResponse *)response +{ + NSDate *responseDate = [NSDate date]; + + dispatch_async(self.queue, ^{ + FLEXNetworkTransaction *transaction = self.networkTransactionsForRequestIdentifiers[requestID]; + if (!transaction) { + return; + } + transaction.response = response; + transaction.transactionState = FLEXNetworkTransactionStateReceivingData; + transaction.latency = -[transaction.startTime timeIntervalSinceDate:responseDate]; + }); +} + +/// Call when data chunk is received over the network. +- (void)recordDataReceivedWithRequestID:(NSString *)requestID dataLength:(int64_t)dataLength +{ + dispatch_async(self.queue, ^{ + FLEXNetworkTransaction *transaction = self.networkTransactionsForRequestIdentifiers[requestID]; + if (!transaction) { + return; + } + transaction.receivedDataLength += dataLength; + }); +} + +/// Call when HTTP request has finished loading. +- (void)recordLoadingFinishedWithRequestID:(NSString *)requestID responseBody:(NSData *)responseBody +{ + NSDate *finishedDate = [NSDate date]; + dispatch_async(self.queue, ^{ + + FLEXNetworkTransaction *transaction = self.networkTransactionsForRequestIdentifiers[requestID]; + if (!transaction) { + return; + } + transaction.transactionState = FLEXNetworkTransactionStateFinished; + transaction.duration = -[transaction.startTime timeIntervalSinceDate:finishedDate]; + ResponseInfo responseInfo = { + .identifier = self.identifierDict[requestID].longLongValue, + .timestamp = [NSDate timestamp], + .response = transaction.response, + .body = nil, + }; + responseInfo.setBody(responseBody); + self.identifierDict[requestID] = nil; //Clear the entry + [self.delegate didObserveResponse:responseInfo]; + + BOOL shouldCache = [responseBody length] > 0; + if (!self.shouldCacheMediaResponses) { + NSArray *ignoredMIMETypePrefixes = @[ @"audio", @"image", @"video" ]; + for (NSString *ignoredPrefix in ignoredMIMETypePrefixes) { + shouldCache = shouldCache && ![transaction.response.MIMEType hasPrefix:ignoredPrefix]; + } + } + + if (shouldCache) { + [self.responseCache setObject:responseBody forKey:requestID cost:[responseBody length]]; + } + }); +} + +- (void)recordLoadingFailedWithRequestID:(NSString *)requestID error:(NSError *)error +{ + dispatch_async(self.queue, ^{ + FLEXNetworkTransaction *transaction = self.networkTransactionsForRequestIdentifiers[requestID]; + if (!transaction) { + return; + } + ResponseInfo responseInfo = { + .identifier = self.identifierDict[requestID].longLongValue, + .timestamp = [NSDate timestamp], + .response = transaction.response, + .body = nil, + }; + self.identifierDict[requestID] = nil; //Clear the entry + [self.delegate didObserveResponse:responseInfo]; + transaction.transactionState = FLEXNetworkTransactionStateFailed; + transaction.duration = -[transaction.startTime timeIntervalSinceNow]; + transaction.error = error; + }); +} + +- (void)recordMechanism:(NSString *)mechanism forRequestID:(NSString *)requestID +{ + dispatch_async(self.queue, ^{ + FLEXNetworkTransaction *transaction = self.networkTransactionsForRequestIdentifiers[requestID]; + if (!transaction) { + return; + } + transaction.requestMechanism = mechanism; + }); +} + +@end diff --git a/iOS/Plugins/SonarKitNetworkPlugin/SKIOSNetworkPlugin/FLEXNetworkLib/FLEXNetworkTransaction.h b/iOS/Plugins/SonarKitNetworkPlugin/SKIOSNetworkPlugin/FLEXNetworkLib/FLEXNetworkTransaction.h new file mode 100755 index 000000000..b6026bbb1 --- /dev/null +++ b/iOS/Plugins/SonarKitNetworkPlugin/SKIOSNetworkPlugin/FLEXNetworkLib/FLEXNetworkTransaction.h @@ -0,0 +1,45 @@ +// +// FLEXNetworkTransaction.h +// Flipboard +// +// Created by Ryan Olson on 2/8/15. +// Copyright 2004-present Facebook. All Rights Reserved. +// + +#import + +#import "UIKit/UIKit.h" + +typedef NS_ENUM(NSInteger, FLEXNetworkTransactionState) { + FLEXNetworkTransactionStateUnstarted, + FLEXNetworkTransactionStateAwaitingResponse, + FLEXNetworkTransactionStateReceivingData, + FLEXNetworkTransactionStateFinished, + FLEXNetworkTransactionStateFailed +}; + +@interface FLEXNetworkTransaction : NSObject + +@property (nonatomic, copy) NSString *requestID; + +@property (nonatomic, strong) NSURLRequest *request; +@property (nonatomic, strong) NSURLResponse *response; +@property (nonatomic, copy) NSString *requestMechanism; +@property (nonatomic, assign) FLEXNetworkTransactionState transactionState; +@property (nonatomic, strong) NSError *error; + +@property (nonatomic, strong) NSDate *startTime; +@property (nonatomic, assign) NSTimeInterval latency; +@property (nonatomic, assign) NSTimeInterval duration; + +@property (nonatomic, assign) int64_t receivedDataLength; + +/// Only applicable for image downloads. A small thumbnail to preview the full response. +@property (nonatomic, strong) UIImage *responseThumbnail; + +/// Populated lazily. Handles both normal HTTPBody data and HTTPBodyStreams. +@property (nonatomic, strong, readonly) NSData *cachedRequestBody; + ++ (NSString *)readableStringFromTransactionState:(FLEXNetworkTransactionState)state; + +@end diff --git a/iOS/Plugins/SonarKitNetworkPlugin/SKIOSNetworkPlugin/FLEXNetworkLib/FLEXNetworkTransaction.m b/iOS/Plugins/SonarKitNetworkPlugin/SKIOSNetworkPlugin/FLEXNetworkLib/FLEXNetworkTransaction.m new file mode 100755 index 000000000..455e1f56f --- /dev/null +++ b/iOS/Plugins/SonarKitNetworkPlugin/SKIOSNetworkPlugin/FLEXNetworkLib/FLEXNetworkTransaction.m @@ -0,0 +1,74 @@ +// Copyright 2004-present Facebook. All Rights Reserved. + +#import "FLEXNetworkTransaction.h" + +@interface FLEXNetworkTransaction () + +@property (nonatomic, strong, readwrite) NSData *cachedRequestBody; + +@end + +@implementation FLEXNetworkTransaction + +- (NSString *)description +{ + NSString *description = [super description]; + + description = [description stringByAppendingFormat:@" id = %@;", self.requestID]; + description = [description stringByAppendingFormat:@" url = %@;", self.request.URL]; + description = [description stringByAppendingFormat:@" duration = %f;", self.duration]; + description = [description stringByAppendingFormat:@" receivedDataLength = %lld", self.receivedDataLength]; + + return description; +} + +- (NSData *)cachedRequestBody { + if (!_cachedRequestBody) { + if (self.request.HTTPBody != nil) { + _cachedRequestBody = self.request.HTTPBody; + } else if ([self.request.HTTPBodyStream conformsToProtocol:@protocol(NSCopying)]) { + NSInputStream *bodyStream = [self.request.HTTPBodyStream copy]; + const NSUInteger bufferSize = 1024; + uint8_t buffer[bufferSize]; + NSMutableData *data = [NSMutableData data]; + [bodyStream open]; + NSInteger readBytes = 0; + do { + readBytes = [bodyStream read:buffer maxLength:bufferSize]; + [data appendBytes:buffer length:readBytes]; + } while (readBytes > 0); + [bodyStream close]; + _cachedRequestBody = data; + } + } + return _cachedRequestBody; +} + ++ (NSString *)readableStringFromTransactionState:(FLEXNetworkTransactionState)state +{ + NSString *readableString = nil; + switch (state) { + case FLEXNetworkTransactionStateUnstarted: + readableString = @"Unstarted"; + break; + + case FLEXNetworkTransactionStateAwaitingResponse: + readableString = @"Awaiting Response"; + break; + + case FLEXNetworkTransactionStateReceivingData: + readableString = @"Receiving Data"; + break; + + case FLEXNetworkTransactionStateFinished: + readableString = @"Finished"; + break; + + case FLEXNetworkTransactionStateFailed: + readableString = @"Failed"; + break; + } + return readableString; +} + +@end diff --git a/iOS/Plugins/SonarKitNetworkPlugin/SKIOSNetworkPlugin/FLEXNetworkLib/FLEXUtility.h b/iOS/Plugins/SonarKitNetworkPlugin/SKIOSNetworkPlugin/FLEXNetworkLib/FLEXUtility.h new file mode 100755 index 000000000..aca2b5a99 --- /dev/null +++ b/iOS/Plugins/SonarKitNetworkPlugin/SKIOSNetworkPlugin/FLEXNetworkLib/FLEXUtility.h @@ -0,0 +1,34 @@ +// Copyright 2004-present Facebook. All Rights Reserved. + +#import +#import +#import + +#import +#import + +#define FLEXFloor(x) (floor([[UIScreen mainScreen] scale] * (x)) / [[UIScreen mainScreen] scale]) + +#define FLEX_AT_LEAST_IOS11_SDK defined(__IPHONE_11_0) && (__IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_11_0) + +@interface NSNumber (SonarUtility) + ++ (NSNumber *)random; + +@end + +@interface NSDate (SonarUtility) + ++ (uint64_t)timestamp; +@end + +@interface FLEXUtility : NSObject + +// Swizzling utilities + ++ (SEL)swizzledSelectorForSelector:(SEL)selector; ++ (BOOL)instanceRespondsButDoesNotImplementSelector:(SEL)selector class:(Class)cls; ++ (void)replaceImplementationOfKnownSelector:(SEL)originalSelector onClass:(Class)className withBlock:(id)block swizzledSelector:(SEL)swizzledSelector; ++ (void)replaceImplementationOfSelector:(SEL)selector withSelector:(SEL)swizzledSelector forClass:(Class)cls withMethodDescription:(struct objc_method_description)methodDescription implementationBlock:(id)implementationBlock undefinedBlock:(id)undefinedBlock; + +@end diff --git a/iOS/Plugins/SonarKitNetworkPlugin/SKIOSNetworkPlugin/FLEXNetworkLib/FLEXUtility.mm b/iOS/Plugins/SonarKitNetworkPlugin/SKIOSNetworkPlugin/FLEXNetworkLib/FLEXUtility.mm new file mode 100755 index 000000000..c287d90c8 --- /dev/null +++ b/iOS/Plugins/SonarKitNetworkPlugin/SKIOSNetworkPlugin/FLEXNetworkLib/FLEXUtility.mm @@ -0,0 +1,117 @@ +// +// FLEXUtility.m +// Flipboard +// +// Created by Ryan Olson on 4/18/14. +// Copyright 2004-present Facebook. All Rights Reserved. +// + +#import "FLEXUtility.h" + +#import +#include +#import +#include +#include + +#import + +@implementation FLEXUtility + ++ (SEL)swizzledSelectorForSelector:(SEL)selector +{ + return NSSelectorFromString([NSString stringWithFormat:@"_flex_swizzle_%x_%@", arc4random(), NSStringFromSelector(selector)]); +} + ++ (BOOL)instanceRespondsButDoesNotImplementSelector:(SEL)selector class:(Class)cls +{ + if ([cls instancesRespondToSelector:selector]) { + unsigned int numMethods = 0; + Method *methods = class_copyMethodList(cls, &numMethods); + + BOOL implementsSelector = NO; + for (int index = 0; index < numMethods; index++) { + SEL methodSelector = method_getName(methods[index]); + if (selector == methodSelector) { + implementsSelector = YES; + break; + } + } + + free(methods); + + if (!implementsSelector) { + return YES; + } + } + + return NO; +} + ++ (void)replaceImplementationOfKnownSelector:(SEL)originalSelector onClass:(Class)className withBlock:(id)block swizzledSelector:(SEL)swizzledSelector +{ + // This method is only intended for swizzling methods that are know to exist on the class. + // Bail if that isn't the case. + Method originalMethod = class_getInstanceMethod(className, originalSelector); + if (!originalMethod) { + return; + } + + IMP implementation = imp_implementationWithBlock(block); + class_addMethod(className, swizzledSelector, implementation, method_getTypeEncoding(originalMethod)); + Method newMethod = class_getInstanceMethod(className, swizzledSelector); + method_exchangeImplementations(originalMethod, newMethod); +} + ++ (void)replaceImplementationOfSelector:(SEL)selector withSelector:(SEL)swizzledSelector forClass:(Class)cls withMethodDescription:(struct objc_method_description)methodDescription implementationBlock:(id)implementationBlock undefinedBlock:(id)undefinedBlock +{ + if ([self instanceRespondsButDoesNotImplementSelector:selector class:cls]) { + return; + } + + IMP implementation = imp_implementationWithBlock((id)([cls instancesRespondToSelector:selector] ? implementationBlock : undefinedBlock)); + + Method oldMethod = class_getInstanceMethod(cls, selector); + if (oldMethod) { + class_addMethod(cls, swizzledSelector, implementation, methodDescription.types); + + Method newMethod = class_getInstanceMethod(cls, swizzledSelector); + + method_exchangeImplementations(oldMethod, newMethod); + } else { + class_addMethod(cls, selector, implementation, methodDescription.types); + } +} + +@end + +@implementation NSNumber (SonarUtility) + ++ (NSNumber *)random { + int64_t identifier; + arc4random_buf(&identifier, sizeof(int64_t)); + return @(identifier); +} + +@end + +@implementation NSDate (SonarUtility) + ++ (uint64_t)getTimeNanoseconds +{ + static struct mach_timebase_info tb_info = {0}; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + __unused int ret = mach_timebase_info(&tb_info); + assert(0 == ret); + }); + + return (mach_absolute_time() * tb_info.numer) / tb_info.denom; +} + ++ (uint64_t)timestamp { + const uint64_t nowNanoSeconds = [self getTimeNanoseconds]; + return nowNanoSeconds / 1000000; +} + +@end diff --git a/iOS/Plugins/SonarKitNetworkPlugin/SKIOSNetworkPlugin/SKIOSNetworkAdapter.h b/iOS/Plugins/SonarKitNetworkPlugin/SKIOSNetworkPlugin/SKIOSNetworkAdapter.h new file mode 100644 index 000000000..6bb5e8858 --- /dev/null +++ b/iOS/Plugins/SonarKitNetworkPlugin/SKIOSNetworkPlugin/SKIOSNetworkAdapter.h @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +#if FB_SONARKIT_ENABLED + +#import +#import + +@interface SKIOSNetworkAdapter : NSObject +- (instancetype)init NS_DESIGNATED_INITIALIZER; +@property (weak, nonatomic) id delegate; + +@end + +#endif diff --git a/iOS/Plugins/SonarKitNetworkPlugin/SKIOSNetworkPlugin/SKIOSNetworkAdapter.mm b/iOS/Plugins/SonarKitNetworkPlugin/SKIOSNetworkPlugin/SKIOSNetworkAdapter.mm new file mode 100644 index 000000000..e96098d1b --- /dev/null +++ b/iOS/Plugins/SonarKitNetworkPlugin/SKIOSNetworkPlugin/SKIOSNetworkAdapter.mm @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +#if FB_SONARKIT_ENABLED + +#import "SKIOSNetworkAdapter.h" +#import "FLEXNetworkObserver.h" +#import "FLEXNetworkRecorder.h" + +@implementation SKIOSNetworkAdapter +@synthesize delegate = _delegate; +- (instancetype)init{ + if (self=[super init]){ + _delegate = nil; + } + return self; +} + +- (void)setDelegate:(id)delegate { + _delegate = delegate; + [FLEXNetworkObserver start]; + [FLEXNetworkRecorder defaultRecorder].delegate = _delegate; +} + +@end + +#endif diff --git a/iOS/Plugins/SonarKitNetworkPlugin/SonarKitNetworkPlugin/SKBufferingPlugin.h b/iOS/Plugins/SonarKitNetworkPlugin/SonarKitNetworkPlugin/SKBufferingPlugin.h new file mode 100644 index 000000000..45ec23df4 --- /dev/null +++ b/iOS/Plugins/SonarKitNetworkPlugin/SonarKitNetworkPlugin/SKBufferingPlugin.h @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +#if FB_SONARKIT_ENABLED + +#import + +#import + +#import + +#import "SKDispatchQueue.h" + +@interface SKBufferingPlugin : NSObject + +- (instancetype)initWithQueue:(const std::shared_ptr &)queue NS_DESIGNATED_INITIALIZER; + +- (void)send:(NSString *)method sonarObject:(NSDictionary *)sonarObject; + +@end + +#endif diff --git a/iOS/Plugins/SonarKitNetworkPlugin/SonarKitNetworkPlugin/SKBufferingPlugin.mm b/iOS/Plugins/SonarKitNetworkPlugin/SonarKitNetworkPlugin/SKBufferingPlugin.mm new file mode 100644 index 000000000..0e8ae8512 --- /dev/null +++ b/iOS/Plugins/SonarKitNetworkPlugin/SonarKitNetworkPlugin/SKBufferingPlugin.mm @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +#if FB_SONARKIT_ENABLED + +#import + +#import "SKBufferingPlugin.h" +#import + +struct CachedEvent { + NSString *method; + NSDictionary *sonarObject; +}; + +static const NSUInteger bufferSize = 500; + +@implementation SKBufferingPlugin +{ + std::vector _ringBuffer; + std::shared_ptr _connectionAccessQueue; + + id _connection; +} + +- (instancetype)initWithQueue:(const std::shared_ptr &)queue { + if (self = [super init]) { + _ringBuffer.reserve(bufferSize); + _connectionAccessQueue = queue; + } + return self; +} + +- (NSString *)identifier { + // Note: This must match with the javascript pulgin identifier!! + return @"Network"; +} + +- (void)didConnect:(id)connection { + _connectionAccessQueue->async(^{ + self->_connection = connection; + [self sendBufferedEvents]; + }); +} + +- (void)didDisconnect { + _connectionAccessQueue->async(^{ + self->_connection = nil; + }); +} + +- (void)send:(NSString *)method + sonarObject:(NSDictionary *)sonarObject { + _connectionAccessQueue->async(^{ + if (self->_connection) { + [self->_connection send:method withParams:sonarObject]; + } else { + if (self->_ringBuffer.size() == bufferSize) { + return; + } + self->_ringBuffer.push_back({ + .method = method, + .sonarObject = sonarObject + }); + } + }); +} + +- (void)sendBufferedEvents { + NSAssert(_connection, @"connection object cannot be nil"); + for (const auto &event : _ringBuffer) { + [_connection send:event.method withParams:event.sonarObject]; + } + _ringBuffer.clear(); +} + +@end + +#endif diff --git a/iOS/Plugins/SonarKitNetworkPlugin/SonarKitNetworkPlugin/SKDispatchQueue.h b/iOS/Plugins/SonarKitNetworkPlugin/SonarKitNetworkPlugin/SKDispatchQueue.h new file mode 100644 index 000000000..bce514719 --- /dev/null +++ b/iOS/Plugins/SonarKitNetworkPlugin/SonarKitNetworkPlugin/SKDispatchQueue.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +#if FB_SONARKIT_ENABLED + +#pragma once + +#import + +namespace facebook { + namespace sonar { + class DispatchQueue + { + public: + virtual void async(dispatch_block_t block) = 0; + }; + + class GCDQueue: public DispatchQueue + { + public: + GCDQueue(dispatch_queue_t underlyingQueue) + :_underlyingQueue(underlyingQueue) { } + + void async(dispatch_block_t block) override + { + dispatch_async(_underlyingQueue, block); + } + + private: + dispatch_queue_t _underlyingQueue; + }; + } +} + +#endif diff --git a/iOS/Plugins/SonarKitNetworkPlugin/SonarKitNetworkPlugin/SKNetworkReporter.h b/iOS/Plugins/SonarKitNetworkPlugin/SonarKitNetworkPlugin/SKNetworkReporter.h new file mode 100644 index 000000000..a08d18ba1 --- /dev/null +++ b/iOS/Plugins/SonarKitNetworkPlugin/SonarKitNetworkPlugin/SKNetworkReporter.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +#import + +struct RequestInfo { + int64_t identifier; + uint64_t timestamp; + NSURLRequest *request; + NSString *body; + + void setBody(NSData *data) { + body = data ? [data base64EncodedStringWithOptions: 0] + : [request.HTTPBody base64EncodedStringWithOptions: 0]; + } +}; + +struct ResponseInfo { + int64_t identifier; + uint64_t timestamp; + NSURLResponse *response; + NSString *body; + + bool shouldStripReponseBody() { + NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse*)response; + NSString *contentType = httpResponse.allHeaderFields[@"content-type"]; + if (!contentType) { + return NO; + } + + return [contentType containsString:@"image/"] || + [contentType containsString:@"video/"] || + [contentType containsString:@"application/zip"]; + } + + void setBody(NSData *data) { + body = shouldStripReponseBody() ? nil : [data base64EncodedStringWithOptions: 0]; + } + +}; + +@protocol SKNetworkReporterDelegate + +- (void)didObserveRequest:(RequestInfo)request; +- (void)didObserveResponse:(ResponseInfo)response; + +@end + +@protocol SKNetworkAdapterDelegate + +@property (weak, nonatomic) id delegate; + +@end diff --git a/iOS/Plugins/SonarKitNetworkPlugin/SonarKitNetworkPlugin/SonarKitNetworkPlugin.h b/iOS/Plugins/SonarKitNetworkPlugin/SonarKitNetworkPlugin/SonarKitNetworkPlugin.h new file mode 100644 index 000000000..7792e41ce --- /dev/null +++ b/iOS/Plugins/SonarKitNetworkPlugin/SonarKitNetworkPlugin/SonarKitNetworkPlugin.h @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +#if FB_SONARKIT_ENABLED +#import + +#import + +#import "SKBufferingPlugin.h" +#import "SKNetworkReporter.h" +#import "SKDispatchQueue.h" + +@interface SonarKitNetworkPlugin : SKBufferingPlugin + +- (instancetype)initWithNetworkAdapter:(id)adapter NS_DESIGNATED_INITIALIZER; +- (instancetype)initWithNetworkAdapter:(id)adapter queue:(const std::shared_ptr &)queue; //For test purposes + +@property (strong, nonatomic) id adapter; + +@end + +#endif diff --git a/iOS/Plugins/SonarKitNetworkPlugin/SonarKitNetworkPlugin/SonarKitNetworkPlugin.mm b/iOS/Plugins/SonarKitNetworkPlugin/SonarKitNetworkPlugin/SonarKitNetworkPlugin.mm new file mode 100644 index 000000000..4c54dd8fb --- /dev/null +++ b/iOS/Plugins/SonarKitNetworkPlugin/SonarKitNetworkPlugin/SonarKitNetworkPlugin.mm @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +#if FB_SONARKIT_ENABLED +#import "SonarKitNetworkPlugin.h" +#import "SKNetworkReporter.h" + +@interface SonarKitNetworkPlugin () + +@end + +@implementation SonarKitNetworkPlugin + +- (void)setAdapter:(id)adapter { + _adapter = adapter; + _adapter.delegate = self; +} + +- (instancetype)init { + if (self = [super initWithQueue:std::make_shared(dispatch_queue_create("com.sonarkit.network.buffer", DISPATCH_QUEUE_SERIAL))]) { + } + return self; +} + +- (instancetype)initWithNetworkAdapter:(id)adapter { + if (self = [super initWithQueue:std::make_shared(dispatch_queue_create("com.sonarkit.network.buffer", DISPATCH_QUEUE_SERIAL))]) { + adapter.delegate = self; + _adapter = adapter; + } + return self; +} + +- (instancetype)initWithNetworkAdapter:(id)adapter queue:(const std::shared_ptr &)queue; { + if (self = [super initWithQueue:queue]) { + adapter.delegate = self; + _adapter = adapter; + } + return self; +} + +#pragma mark - SKNetworkReporterDelegate + + +- (void)didObserveRequest:(RequestInfo)request; +{ + NSMutableArray *> *headers = [NSMutableArray new]; + for (NSString *key in [request.request.allHTTPHeaderFields allKeys]) { + NSDictionary *header = @{ + @"key": key, + @"value": request.request.allHTTPHeaderFields[key] + }; + [headers addObject: header]; + } + + NSString *body = request.body; + + [self send:@"newRequest" + sonarObject:@{ + @"id": @(request.identifier), + @"timestamp": @(request.timestamp), + @"method": request.request.HTTPMethod ?: [NSNull null], + @"url": [request.request.URL absoluteString] ?: [NSNull null], + @"headers": headers, + @"data": body ? body : [NSNull null] + }]; +} + +- (void)didObserveResponse:(ResponseInfo)response +{ + NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse*)response.response; + + NSMutableArray *> *headers = [NSMutableArray new]; + for (NSString *key in [httpResponse.allHeaderFields allKeys]) { + NSDictionary *header = @{ + @"key": key, + @"value": httpResponse.allHeaderFields[key] + }; + [headers addObject: header]; + } + + NSString *body = response.body; + + [self send:@"newResponse" + sonarObject:@{ + @"id": @(response.identifier), + @"timestamp": @(response.timestamp), + @"status": @(httpResponse.statusCode), + @"reason": [NSHTTPURLResponse localizedStringForStatusCode: httpResponse.statusCode] ?: [NSNull null], + @"headers": headers, + @"data": body ? body : [NSNull null] + }]; + +} + +@end + +#endif diff --git a/iOS/Podfile b/iOS/Podfile new file mode 100644 index 000000000..056604147 --- /dev/null +++ b/iOS/Podfile @@ -0,0 +1,20 @@ +# Uncomment the next line to define a global platform for your project +platform :ios, '9.0' + +target 'SonarKit' do + # Uncomment the next line if you're using Swift or would like to use dynamic frameworks + # use_frameworks! + + project 'SonarKit.xcodeproj' + + # Pods for SonarKit + + # Third party deps podspec link + pod 'EasyWSClient', :podspec => 'third-party-podspecs/EasyWSClient.podspec' + pod 'DoubleConversion', :podspec => 'third-party-podspecs/DoubleConversion.podspec' + pod 'glog', :podspec => 'third-party-podspecs/glog.podspec' + pod 'Folly', :podspec => 'third-party-podspecs/Folly.podspec' + pod 'Sonar', :podspec => '../xplat/Sonar/SonarKitCPP.podspec' + pod 'CocoaAsyncSocket' + pod 'PeerTalk', :git => 'https://github.com/rsms/peertalk' +end diff --git a/iOS/Sample/AppDelegate.h b/iOS/Sample/AppDelegate.h new file mode 100644 index 000000000..ea28a10f5 --- /dev/null +++ b/iOS/Sample/AppDelegate.h @@ -0,0 +1,11 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +#import + +@interface AppDelegate : UIResponder +@end diff --git a/iOS/Sample/AppDelegate.mm b/iOS/Sample/AppDelegate.mm new file mode 100644 index 000000000..e6a14051b --- /dev/null +++ b/iOS/Sample/AppDelegate.mm @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +#import "AppDelegate.h" + +#import +#import +#import +#import +#import + +#import "MainViewController.h" +#import "RootViewController.h" + +#if !FB_SONARKIT_ENABLED +#error "Sample need to be run with SonarKit enabled in order to properly interact with Sonar. SonarKit is enabled by default if its a debug build." +#endif + +@implementation AppDelegate { + UIWindow *_window; +} + +- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions +{ + _window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; + + SonarClient *client = [SonarClient sharedClient]; + + SKDescriptorMapper *layoutDescriptorMapper = [[SKDescriptorMapper alloc] initWithDefaults]; + [SonarKitLayoutComponentKitSupport setUpWithDescriptorMapper: layoutDescriptorMapper]; + [client addPlugin: [[SonarKitLayoutPlugin alloc] initWithRootNode: application + withDescriptorMapper: layoutDescriptorMapper]]; + + [[SonarClient sharedClient] addPlugin: [[SonarKitNetworkPlugin alloc] initWithNetworkAdapter:[SKIOSNetworkAdapter new]]]; + [[SonarClient sharedClient] start]; + + UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryBoard" bundle:nil]; + MainViewController *mainViewController = [storyboard instantiateViewControllerWithIdentifier:@"MainViewController"]; + + UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController: mainViewController]; + navigationController.navigationBar.topItem.title = @"Sample"; + navigationController.navigationBar.translucent = NO; + + [_window setRootViewController: [[UINavigationController alloc] initWithRootViewController: mainViewController]]; + [_window makeKeyAndVisible]; + return YES; +} + +@end diff --git a/iOS/Sample/Icons.xcassets/AppIcon.appiconset/Contents.json b/iOS/Sample/Icons.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 000000000..63acba97d --- /dev/null +++ b/iOS/Sample/Icons.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,62 @@ +{ + "images" : [ + { + "size" : "20x20", + "idiom" : "iphone", + "filename" : "icon_20pt@2x.png", + "scale" : "2x" + }, + { + "size" : "20x20", + "idiom" : "iphone", + "filename" : "icon_20pt@3x.png", + "scale" : "3x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "icon_29pt@2x.png", + "scale" : "2x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "icon_29pt@3x.png", + "scale" : "3x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "icon_40pt@2x.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "icon_40pt@3x.png", + "scale" : "3x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "icon_60pt@2x.png", + "scale" : "2x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "icon_60pt@3x.png", + "scale" : "3x" + }, + { + "size" : "1024x1024", + "idiom" : "ios-marketing", + "filename" : "icon_83.5@2x.png", + "scale" : "1x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/iOS/Sample/Icons.xcassets/AppIcon.appiconset/icon_20pt@2x.png b/iOS/Sample/Icons.xcassets/AppIcon.appiconset/icon_20pt@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..aa46fa5e199250d4bb7870966af8c98fb765fcc0 GIT binary patch literal 2220 zcmV;d2vhfoP)Px-W=TXrR9Fd}SV?GIWfVU5zSpFANtzBw)4^iJ(v{U}wQh-iE`WBuOHqY{8RSqnv!01RvwB_CLuGeiQsi*~mAw z7`!lt26YKuZOo$b)-hN`f{YWgilTL_Aek115*DgSKt!qn&4BfBKnlF5sOhMxzBJpC zeK8W8`Ju<66+GjVD@HXdSfSk{8-R>228}Bmt{t(l!k+z@cCbU|m9p>SN~!8I<`o`_ z&7M)}3oA$?K5XIKDjKul_FD2-mv`6aI<`?;)5I12AusW<+DMC5@Z?ZIkldlozpX<$ za~Dwoib??_G9C`#CG(|7w~3@ls$o+hwV*Mb`I0hmj+uI)11HKWz=)~!L&xzd7^|Xt zQU$f7y*EI^I(+2G3E8=KQmeN(-<6BMEy&!J4#pY)+khNE83;b|By0YxTZ#|BO*+p@ z2+pBsaLqibNG<0{wRwPS*q0M056J`5QzrL!Hpt}cXXoU*PcO*wEzZsc)YB?Ul^Q-I z0~v&*F`gPr$$Ae*U0XTh30!}uh*6P$F5RMXrKOEjjvjwp-gy7Gyn6bOj7;=pko8bO z76q0%bw)gT<-?%qV<41YCGAg9b=Cn!S8ytwCJ^*T-HyEE`)J;NkmZHGEG;j{`ExUJ`^KV7ZE4Bq*ht~4#_fM>m;C(0 z@3OQoz%Dl*d1bsy-^pvwf5M3Cwm6hY**KLUs~d1E!+FROs9qzJr=Hs>$6h%sn>M%V z>e@g5>lHb3>U(LXqq*O@|CBo=8XdEdT0k7W8aP96Thu`br2H_4M%vV;*%-m@8m~>|LBrIjE$Gq(6AtSi zdj_H2YB!bl-u^}oJoBJjyF4$~uPn;-nMJuV(~)kQmG+V#xtLY1uH@v=4+=>&{(bZa zTo>tGbYqN%G3p$r!VJO;*nXkg<*M@94wlQLh76FA3-$#{dn@2h@ejdDq)X(}Tdp}$U>pKIg0 zJCD2FDjZcEhGPxn;Gy9^P9A@xUYMXntOYe1yngB|2n;otQT$aQo2JIsfrqt{B{Fkq zPTHM20NGbNDl&9X^6D?Bl`Pj)Mb|GXNPD*<7J%1JT_}_(7xK1k+oU;aLCsfAcaDNu<%l1ruv`$Bt=f;KHE0)qSgfyx4_%ZLF~E>`-z5 zp#ia77BoB$Qp+T+{B$%vF(s4R8t!s^LZCf-4OZ?9W$|`j7MGcjS5YAmfcXzbE^i^l0@izUX``Xx~?7~ptp z6xGzM!FdJJVJfY$N!hb^OjbH8a`XDUbeGLe_5C%#8O|X1vsj_Tr)|xqhz+V|uo;&D z6Rv)XBM0KpzwSMd&kK4SvBn!nBOQ_Pv8HU?Gp3bkciPf!cVy5X=%10T))*4y{$thH zN^bzq5fF zwWz*yjU#rfb+xCu$LGZXQ>>DbWw{^DT~^DG6|z6P?K~@2+QJ}JT{q^w4#>{H(uEhg z<#UmRs@?}nFpWhWbn|#Uf>%n7xS9AkN#sP9dRifFKx;*{I8GUp@Ii(vCB%W+eXyE= z6^t@>pd`E*fT#k8I3)}~%4WO=<+y^i7&?ySp*DJ`L&7|0TI7Q%4%D;=-uxrL+6quD zZ&4l3V2yrloM#X`>81c$%4m8wt1EzLk)!91Y;zaKQ>|No-)K?#Js14_WFKObk$ uP7X@Zl;GuEGNzgfLdn!I7_*=P^!^1y6h%dq*WKR$0000Px^Q%OWYRA>dgTiuIYR~29P-no-WCX-C;v}u#{BW*)16}9*ULMy)1B8s5Y2mb_1 zK?1%?MGB&Vi1;L;BKXt?pR6cCDHPNSrASL_E2bd{`DmI>Cdtg)nR~Cl-&*T;&c5f| z`A8J^%{^6ZnmSxA0|G(a8!kJ&Z7#hKK=q z(k>0pF3a-<@#?xs6=IDAc?VeTGVx=?8dG*WLjF;S$?ym~B1%$nEI_S40xm5{*_=;W z3D_6#p3jVj6#A}HmpAkp`fj_0I{G4+I)TY+k`Bt*B3`s@pD{#aZXIkHLDd=K#`=`q zB@fk^7||?&XIEQ{^8$66xD)m*eJDXTuHc~UaADP61SzL-^!te6baKRsYq}Ya`*H^n zUH1Eh9Fl++5B(YUr(vaU@=h6hE&`y_THuF{TQ>A>wx9ZJqI4S=DbM-AdBnzJeSy?` z)!(!Sek@vUKK-youBprj!)*w}ld@nbOMu$f_jQQ8W(l#yr3JH-==mMh=< zVU!C9DI2dr$)=%2AEqomY~69!%hk1RtzKqROLxV|_jd8*Z7K042dL#l(@Rq>7AKBR z%*D6_FrgH5QE;xVz5b?s=;)mFXJ@Q8)3ep98@BSnhOMp)Ffc^vS+~pN1FsoC(|>D1 zz|4JD=9*eTsqY()+Cd}ZhKB$v6N0{*@PG#WF-K1oDIyvUH|*q3KWE2|FNJP#T)n<- zZ@zZM{{G@=d-Ijcwz<|p;yu9No46$Ig-KPmT;Hi7iFmil5CSt&lamF?sFNi z-}9Knmi=6?CIM^bQAQtiM>k_))7swoJ@)8lAMh{xUwP?md*L^4*yXe9*6Z|O+W7o1Ii>9rR`3Qp|FugST$wOxzks?f2YHz9zS8< z`T1AuU$w72^RSKk11yL`8;)W&Qc;89e$t0z(I2{HytzCwpa@>H zPK3!t@TC*-teUs1V8u(E{k%fDI9xh=EqiW`JpRQ;?7P4E5*ECe!iJ zG>kZbEnM%}GOsW6rzaRlO+OpGlPtaxXp9K2|ddjUIkN?z0W-O^=EN!2^)?adD1COQc`|(OVVu&&x4fW zAE-knpVNrF!_Jy@dn3Diam8-nHpK)gd-U(7&F!7F+4+&Z{@05@#z*ltji=<(dFILI z%ZH%}lcv6EA^c{4mH`+{tzD22R#Ww7Ffai=CBmC5}Jo#U=sB~;b$a89o5}$mhgPk*WQU1kFYCP=P z`{&l}FMm2^ufKZAjvPN|hi==yt8k7zxM(l`{$If4t}K(>!O~Z0=`^na$|aLdN!3?f zGf2=sq*K0*2YKD1AlyICbo+MtjaB>c$vC2~&~2M9GJbq`9KUPK#B~5fQBtD-!fRf=b`f!;QOgU3#957wWD_w$;4A znDX2|KmW7W?84cdx1t~W^!?V~gBY{}qwg&m@w*XjYH-Nda)|vDhdf0`j4CO=anB2? z`=2Ob+)xxC?klPDUZ5zB7m1D_>tLiu80lYp|3zAF+h+Pbd*~BO9*caFI!|95S>mSO zi77oXsu@fr^CUCq41qXoiRTHCXEOdNF~GACPtB92OrJs@B0K%oHGAicvr^xZKKj@_ zSo>q;7bcbE%X3J-6N?sIM21FQ;9VOEs3rNcH}Xz&lQ!|$=Kg^%JJs*kCgT(2jU`S3;Uov z7nbmOKYjJZbM}p=ht|i`y>fX4kC>P3JRUR8pSkJ}BYYsaasl_^4qw0$+<^%PS?$9G zlzsDw->Ni{ZAk+lfT$F~2X!NN1}^eLNAkP%(6o0SyaqS1W5CvQJqlcHG;poQ=8pGw zW;f|?TD<-uzS@~IEuvgi2Jxn!8}~Ycf_3NaGrPr0yOqzhh$LgO?iv0@n25-`-{VU^ zB%Kv?9{Qv{TOb#OX^eQv{2YgTr^VAy2!9!(M+lxY8^N2+rxJvkit3k{Xe1DcxQ?oo zG~6+v$yVdaw$jU0UM#THq6;MQ6<$N1iMM`v@C4bz#uWkohT{!;`|VS{XhcW*$fV!9e9`Va ze9TANHJSkfEQ%iqiPwO{;IJrx9|M38q!4CN#0;V8!?~uisMn8rvI9H0)2e!?fd@Hv z6jZko+HciXmRAv6{raV?mznsGV>H}fQ1T4EqM2lwP#t;17x+as4TrLI+{E^sRshLR zw6^ATIk&f83%1}k*37P6Uq+$0wTqxc=_96I(3pCV`V@>=PhFpd49>rSL!Gb5L#roo6v9!@vFW3;1oQg5HwZz-MZ2*wvUlG-ZG+7lSn%p=x;+Ky8`Bk-{IZG0S@Wpg=@wD2Iv>7H zio($cS8wFu3zMb*-Q}oy)p*K}`{~*3OH0GWreH zK{K=D={J2>)Sa?F`_Nx5qKaEIgG~MD5mGmHTDqdC=R+C>5|eVb(;N3~acQ5ue|~j3 zVnez)=-9b;mu+_MvK>4$Z~GS(Y_>m}v0+CH%=m>coYDtJL^~_-8acmjvtL0nF4iMs z=4=TJTuKx>UdUX4qItqz#E>+OLL((W&z5ex&8}TNV}qOc5n+J(Tw1+um+X4X5Jbsf z<`-t|$X!Rk$Ks&GL^;|KTlkOLI%Jt3Cxs^)-5z6Y%fU{&D#3iG<(i?MEERI*z(&`G82uagAzafm{K>BmX9MHZ!L4ixCQxC@R>wD`#mu4r%u-n9ynx&?_Ip*=}nZ?RcuGO@(`Dai)vOS zjiP9#F`JrapJEdwj(GKx#yc%AbjFXUpQTI&4A4P9x#)DeGqy0lX!ksD*!Jx1#{xo3 zw6(ziw=4ZHMtn`1E811VPUeuytT~E%-ONKkJ?@L zVK+8=Ga;I73^p8%E_dTkeietPVk)WnNQ2k&FukEs827FW+NT9NIL**JSIKZLUH(); ze*gYMw*SO}UBh$pd*`p(2L2jnr?#=qg+@gprA?gkj!Ql${Y4Kc+q8JyH2Xb1TFU@7 z+dmIGY;j1Sx&R1_L3ky2RWqO&?7I)zzT^9CV{_e>KUlHrR|oN;U?_kZlQV?ojv*|m zv4ec#$L!N%CFE|4f+-=^$@K$2^cfR7qUB4xIBDopv+hW?B#K4xv5&s_RYki$lcnCe{@Ue4l4tyk$?;B$GeX2UuD&=6 zjo4{po7aqw3>=i#h$~hHl`5#~d8`p|)*0H; zqhZ0P+Jv6V3Y|iqc_^j`LDRqX=hv_TZY2apa5a$uD^sCV2 zk%o1~!j5Skj;myOns_Q`TfcFMWgZmGF z5AkG)cEtCYqEQ2agW(|1W;{)OPx@j!8s8RA>dgT3v`;R~26OXEHOHNt&c-k|rjN*kY|vY%3@!q725yN_`SvEj~!`(I@|2EDEBfkG6=~x8hGNNULd^G{4Q?%w%q6?!B(>TkAV}-!pe6 zlNQ`}&RuKoz1Fw>_Bm&tbEosnmtPuNw()puoleI<(ZqxPKib&bzJEZ`#Dh+2x8rZ$ z0IN_Pk3rVBHBSdH5DL&k4jTQoHxd;F)HDWJ@i`w|1RE^^r-vFSI#74P2v*Z5)O7iN z1eVY(&y`tG!37OVTj>|C5lO8;lE4uL%h9mN zvFx`9vq=@X=9FyoJM4Ovqw7;smgacmaYqIqHet@^I6?{zffxBv@}Ov#AEk{PXyWO! zTImQUYaRo2zwL>8#TK&=!}1~Q@F3cPWqVAKvq_2E-BpKL!Wm>G2e zU4Y<}_~v4i0eM7htf-b371BsG4_O)BfJet69Nvs*-wZV2vO?_II8Mr-(1KiLe`vP*!6&Wj_pA=zN;QV1Fn6lNr1IAKF*G{jh!FQ%5Jn)fujj?2W&@YcKusANKaYmK~-aL3g{c zTx!RiR{+qjdEtq|PhFrGXj5u{;NB$QN)XEJr3oV(Q(`6y5cYfwa_7%n-89f%ziXd- z_!y7jaAd#v>0j;7e>iQ!^`7-Qa8ba3ta)bE$1<~AvKZUAbh~v%R4LG!2YfUc0j+t> zPp3%S`P0{@Pqs#Ty{>)jJ16Y97rtr_etwUwjaL13Gi>~s6t8`#c}bPAZUlsZX$KS} zT<&kU&*6ZssBlD~*YFN;;oT)!-xi(O(YJ3s`q4qPcgwOSeq{X~*0I0L|UyB)iD=0?um9y#{01NOb= zzvLIQepWV?WuQ!2^l*I`-|>M=jJXf&Y?2YoO}0tk2qVDBE8C!caEC)`cIoVDh))7; zt2e(eYfnG-xa~jMb6DJ_va(FP+j7bScEP88$btuDpy7eC5HvDT#vl_F4_a5hc#ELX zKyjf8zU!qOt&Q!%xvL!cAYTi+=IrSoowR))={j;$bvz1tpgiCs`26TX3CfF+mMYys zHn!OsgFFi&%NP?L4I-obbnMi>&upU`Hctcvya`sE%=q?fqnmp-`dTk*hy`sB;P@MpSkzzKcLZ+uK6|q=CtlHCmwV= z4VmW_kJPoe$L-q6^^v{yr_=V|H&5F`kABp*hhtK}K{t^3nwjK5P(%NU>rNaIZUKum9zW{qU*Z*~*e%p>NSneDMM6 z^s$jB*M!=q@HOHBRNP(|xySCa%mJjpb8!civo)<{YF;w+Sj{){um&4QqTB0sd-mR2 ztM;=WzXIR3Y&&NAcHcw$7%22{(D$V5A;I`K^_@}4h>wI}7*8QlD4>b5lVh71k}hb? z14B5X!ow5HYp#x!zbYEo;TvpE>~#@96-ETGWgsmV z6eOr0#7kQ9nBxI;@YxhN+&FjYhMjuzoTjGIoxWq5nZ<6&(TP)N!~r#0o_rpKEY20# z77t1lpNO$^j%oCnoadYa7x`P@rEItoHsBZlI=+No{{8Fr&8H4>;>!C=cINF%cJ`gi zcJ7^Pd>T6Q)-_x6>sDje9RZf^0yr(>7UT50kN>LJX*mv?u_olihorZG&nnr_<`%oQ zzBaVM4R;nFW)U>rM1XFm`KuI&MTJ;V^r9OvI-dpenOk|o5D4jnw=JDk@0woQD*a8$r;WQAD) zRz?0ezO#y_u29i$Rj|^pP4{6#8I8vpoD1o_o51^;)d4Q`TR&o5yS!ot4h*eVUC4zE zibkhvduf;}DJ0UD2(&C@h3XiTi?3L+c{*@Ne36$p-_%PP(@{lD2gR$9TQy(7w!D1Z zcJIQk9OX)=Btl=jXgd*6J9r~|;=@DeNe6hrV@05c7IKBgD89L2fEo(JM_nXw4UingbRZC{r&(h?bLz z98z?uYdaTb(A%=zxHhu)uUzEQKVNCU5dPpi5ACZ#kqpcQ%}jI52QlHNjn5_3Z=j-Z zguW&%He|~&s(3uml0gciPp4ckdA#$vbKf4LFLsh6zVl8eo=0JfKrl+7aK?AeHaoXqvkQRVx{XF1d+*dG zyKwQW4Tm@5-A>{O8x#lJ5v6N*yN3^G&By45@9;5v12Iy}NwTX67!~+|C^~ zzjL0iNjm<3JvTdVvoo`RXstl70oYmLI(uCCp4&oRDLsGW@}G-9{KY;|At z+Y7MpHCbvHL=ZyfDAp?mE1fZ=4G3?Qnj(^|Li^F&UUg7LFn)Kaf~a@R${4 zKrMONhi*2l4*HEHjC+&rPoj{m1&>q_Ayr|x?9MpmbRy6KA|o}J&*ria#p{lR`CWF;y@zf0e&6GI0&b_Rt_~d3 z&(myl%6U1;%Al8(e76>jQzo(qtPCqgr~{k?qDG7nf_$6fX+fwGZMoUt5d+ z9LqppfH&QgWQ+(VH3T4vnQ$s3qQX(pJNMpcd-wXo`Ebp!L|0c=?dBlvqaoMv`Mtb~ zD}Sg*$Nv{db)kK?E&IX2*%-mD3jS($g;D%uI!!)zMj5G##6x!x%^0T=I_5KS3>=%Q z^Y;|T!#_*SEY8~E!Y-yC|I?%=w+{ZjhBiYFR)q;1jK&yxXgF;!5~ok>gz7gUZF$9o zcSa}=blJ)Tx~!bfse*08s0=gM=u?YG@#PtZkT=m7&+i5>?D8MGoNfNW%f(`*mWM#} zH_9tb5^y<~_wM8tF!2h3LP~;z(^xL)JeRuj^*L2^LtZi%7cY6>Xl&YijRk(Ae7rBx z1uQ(pa?Y0ix}v}C#8`7BRZxv61Cw6J`CKI*Mnb;ArAh=50SZGwqAy-F^pVJr=3;|6 z6(||W*BIn;u{Wnu1m^&)ibmnLe=%sw15nuEL~$5gyCNZtsHo-7u8{H5A@5+~6?mYP zZ)g>5@l{0=7x-~|$$?NRg2Py44oO5oRCocsU0cjt*Hzwg`LDj@ckDP$6W3`jYO1CxP=P>Dk#GskL#6Tn6;DWg zC+-F&_u1z%Grv23@Y#RfOVRfB_EM+QNuX%rLH~am;v$wH zi60$*-gxKjua88kR4fPVm9;GSW`U_|#i%?qY6Dx0lYEGevCDOg+I7MgsJFVqrhR+x zeR61U>ej7r%o~xQheo_}%)c+da4x<|z6z`Gb-13~kTab2hLm7c8wd+tMHX$w+v}Kr z`~wYBA3*Mo*tlLU4^$)zmVn$;J)$h8?To{deaQkeJDik%%-pDe5xR-pR<#>wxO|vQ z%Lq~s4DzABHx9jQ$MnmWD5{{C^dF;B#fKk_7!)StWAogUis74}?^D~*1YTjO;?o-f zd$ZyKkHhy+J~r&80M1+)dXB%)hs?V@XqlXNP_h?bKV1w4K-O!}gw+9+cg}2=% z9{2AUq1|4y=`9=uHq#o9$Jgv?a1NM%pY^InI+BmMNbm)iYLeu^uVx7{5NJ^!i#)TN zGmAEbua>?kxD1+;o8pQ#En5C9Z_4gb{#}g{fCv;Qc?&AaX-1`@8cp<#eQAQ0d_%3; z6&BEvm%?7mXwZ^Z|0G)aEP2^6SKINd4eS*E|8WrsH1}B_i*o!hmBJRO*t2 z#0Waw9}=o9BVk*)m+wjt0W>sp1DSj0w&2_T>&sAK6>I>P|LQmir@|pRWB$J8){;lD z6toTpF+2g6E2gLlEAx(BQn^h2niNSu=E=x+j$hZ;z~nU>gH^|yZGo|Fj~VF^UEW-y z+wtKeH^oxEP1?*qX09A4QGseFk3!TFkgfGtGzVA~tI&^rR>aKcN3w9Efx&LupJbtI z#oFV^Hi|VVzL|}~?jGlxf9+BX0m|U*k;Yu`(RVQQt!zb`{$TCRseFN=jhac2%OACD z`)9RTwstbs4t%YXDB4QzqYz(njc| zjw6M|up=ePKMH@{XWd_Y@8J2{?XRy}^`P2AI5elt;1t(Kqs%q)a$~xj8D5Ll;Q36> z#cBGtqn`GlL>1UI+gknR0IDkXB!BL;+zR;q^0%3*k^zPBj*t;Dw5l3ZA!2BRxT2*D z-PTX`O@&r*;72m_Km7R7^tmrSot9R5X>qximX`ZzINVF?*S6A)4>r=x4>r@~ z^S9FLuU<{>y}6#O%hzcbM^h}{B?4n51u)6L8b8PU>uYW!IS&>=jd(T3gP}^XQ3|5y zD)}lAB!oWB#C!sL=9eE!kA3`p_LZBp6D#R-S}R3qYhyRP^}Va@83u_uWVV3yOkRiwh|P~yz}QH$8tVZqllm?)EGof zFvOW_liiMzL0R&k%}cLK7uM-=)=jt9NzZ)lNxsj&aV>r2#aGhBv$rf>j|a>6*8PjE%|mNmo(#HJw0f92&O& z1!DJ{mA7a+QWKBoJ$?RnEp9tpSt9TNCJMg(cG!NdW)B7iS}|D0k_YwX7V>j>pEFn9 zO8V$WPoyvX)${53Uw^_L#_vXvp`ntO&NquQAvn7& z8PJlCSb3ma;g($$;6ydIW^SMR)u+?%zW6ig=!sq$4Bhv=%AZfgaI)qJ+h&xgRgx)- zVtmmjNBKwZbbdr?mTC&2I*E~*Y z3fH77tBdKk|Ku0a{SSBS24r9#fJ80klz+YeY(}>yv7m zHjI6p%xh*$I6`0_fp}S?)No(<#SXyWAKykQ8hS2r&^T%?&EawkKJV7^%`g9K z+8W;W8El}cqJcvl>^*D#w&o&JHSv)>ydnFjA_9VE;1OHbmXELnfnC^EwDhh1Cbc#2 z^0}L7XS-Os=x_d;$DVp9{ru-2O*?}vDZfXlg(Xu4g-7}tV)Lc ziT$vF9+XElbQB7c{6iN5dH7g2-5Q=x!?crnJ$rz&vY0;l^oP^aKlYLI@gMm}I&@@Z zRJ568cqsIxFTR|vpYNw$7mrP=?`#ttoWQjKOqLw%rS!^viQcf&55b|@b5lFej;4V!6q(ocWpsr30TJewYT zxc!i)^fL|r+NAU~_zoT4CE&H|Kcs6b9T(f7#cy77>{Nqy0i|MO{ z4gULyTfgZugE!`9F`cI$JQ~zs&<{L8w$S-^)s|&N<}NljHnwl_(oBY4I3V;FV;c{OH<~E;F4NLXu^!Hp(59koVi)=~$=6Uprx$l7k*%CN}^#v8P@29?qd3nf4GqT=Re;f?pZfK^~}?$yRvD; z-Q9Qob`t@RQ8i=9gW8+GgN{xvbYzbVz>jO{8>7#7W~*56McEjA>y1bOnEs77+UeRX z?k=Ri{fqxfx7VltL_^Sf{cifyryotbyW3oQg{h>I@cFV3*jO0wW0E2Eq8ouAs{&$P zVphcqxr4_)5)35%K?i);k^xUer}QCTXGl?4gN*Z(UkhFE6bs+q%AN-E-FUOCL`~KH(qM z-W*Tn#br$N3GB9X{P#ECO_$%j5w_ElPyYCmX=C@M8TcKW;}zN*OCE()_<1RYG&~ib ziJpYJQaRuXI-(=>V<4)TiNS(QZ=j$Kn0C`sDNyIlo=>U}wT-8gf%hhw{o}IjJO6Sv z3#R07=XdJ#VY_M=*zAp?)NGOaH2GU`%S)|%`9*UU!rVl0n4a-^0i#j|Ur*4IB!ZxH z<9to?k)dD|fhzUEt_1w!*=SpQfgF>l3Fs|=biKW3HI-`)wq|~0fek+TC*{v&L5CV$A(;6=^TX09_B~hY4+RI0@D3h2?Uwr* zP{V&-W?KFOi||!p!evX}6g-A2h!40-fMv89iv}(F;GS=obL<~9f8PGew~7Qx-cX5F z6|a!WDpPfVmb^4{A_67P6R4e#Z~~2!Xhj=7=+AUSp~n&iC2xZv>a)z8#4G~__603@ z^r3|{sqz*bnUI@R+cIbHBfg)ju$4{4a0b~>YbHrk6pAI^+DAkrD->W@R2O)1=3idm zj5hFO&3MP)yOl2$(5JHLg+Im`kGG*Nr$O6f*8KfyL2eC<&ae=9UNKuLK`xH!LaKiI zsAO|%J8f;*w`DfB(&qMd+TPr@PZ0*`^qEs>d1ck=87B%Ax+;!2kqrK3ZW>xqI4JqM zJ4Epgn!jp-NIaqC+KJ~bV^#5ujF0F*KTa%WnyxmP+@$hv*zz9(h2>zJ@)gv@$=Md zLKQ<$QSilkae0Y{wOdTT-CpmdtzG-xtu0PSP%{Voq-3c=t?5ePK26sQ{p~T82O~-; z{8FYE)`ytVZ&Ktdpy&euQY@j~DMi|IiJzJh`;bMVAmW?MF>poOaI7lP7zPV;*>kOOT-DWd{`b!f4|aqrSAXn3nBZg8ONk>)rI;#dq!GhL5jtwvYHh zJwCAGQjjHOBH)=&Ss2LB3|B=1BV@wsDxu>$HGRZ_KB&iaKC*T{MgEig+3jy$qudD+ z2@b&Qg@AmQfQ-izq+`eHzXx-)({0zU?xu?u-?J|t?^M7ULh)^f@xxvFlM3tCcWS2y zsY^`HS$T_kER^1}_MGpQe={U((cFi9hUdFuwpgvvK*^h#C?HtT*VYcFg~hwOaVMj< zH|%#}XWu?=-}%}!e@Ijip)Wq*5)Lp}S3s*MwOzj|P9ZaP_BKWS912WAOh9X*;Op19 zR4^q_83dJ)D2$O9X77oU2m1ot#;x7-#%t%&jqCmuBF;v}wHQH-u!&+vSU^kOHK`FS zjG^N)(2_?V-xNlt@$?yVr2le&ji*jf@HXWbF+kKwbKqbA87Liv>Dt=Sw7BG7TC01Q zeh*(@yztJ|^yUxWu}ih<_MxEv5X2%eW{D+x6?V{)cMW1hkMNp~%SP*Gzs{90mA9z! z7e#pL2L&IuzYYwS4^Y-6g?KtZykc~)OS#G5^`X-bq<7x96yVXjzqYlxo8CQlC3P=c z<;ik&b;Yiy7x=|H`>X~3Qor9%i;MoLL50o2i5CTel1IXpo);ndTz0Vhs~GOaf*>*< zIXZ*wqjMUJF;t36NU8&Qdop4B>T<3@}|(B)@rxEE*ihp2!Zk)hZzoCw382>u%GUi$&UAR zke=P0LAr9|ZC+)dkb0qVjs@A-yR2qlhD`W@K{-u>N4m0ST=I384# z4nihl9~fNw`TPJN@MxI5_<-+`M^B~Rg3IpZc58EozaLY=9?J(AIrtk=$&9VQinl(> zT;F|p9cIlRk(!MsG!+kv5qK_2o#58)ZGi_p{w4y&scx4I18DugtmRt5|RwbpY$XLyKZT z4kO`$LZO>?LZJ)*UT@qw9zJx`X7HLV5yec0!#TB~6&JV8C?=L9Uf}?{j<~>MpekH8 z4&*^gKI5KG{_@9fIjWeL&fr1$0x-M^fF(~|>ytg|1|AJJ7l&7^z>gkJ{bhYp;C=Jh z?(KH1xLf9G`oTjkXpvQwtMEh4oTPDp{1J!CLJVX$_5xK!g4USU1S{B}m_Qv{cvqGV zr_*+lTfKi^OUCqt7!xv!2mQ1WR-z-=>coh`DcX?mf?=OZ-tB7fAtPiUH%7%`2O z@nx~dTc0TO&_ubzbig4kPYqw+TojAReddvPd4qSi#TZG@;uK!+FSeS$I z5S=0)OcvULPN5IzMURPqeKsA9NS~z~hG?3+dS5 zllJ4ejdXqeQd6bW2ga$a%iw3^?JYlQ z8kf((@~CwjCvXyQAwa*i1gUoYoHQ zq)q!&`1a;C`=*Y4^lpdz-oV~AJNJh8HX^XZ_sZbk`2G^E7V@RK4`N={aNJW?9rvaV zXb#_)MpGXs8e;}^fo-LPd}1&BHS@Q>p9=-=Z7Ns($jGfXrj=g@6eZA6n^=CNHqMTARGX*vr@ZL zIfgGeD0zy#!;4@7>n9IAwSpJ6dzF8E%~g`3095hCkMHM3FB}1g9EuNcP4Eq06L%4%R!sAY zHIOmYXENxFY7IDqDH-&e#hiq@xo`t zD)GS9!cGCSi(<~=zX}wLY(?F50lsNaCFVL(nqvW$)iK^tYM#M z2Su4BqkrTh8?feA7|>6B$f|*dG&lLG{5SE3zX~r*50F1kXq5vN!W@EvaGPoDW@3Rk z!UE7tK73T&#(>9-4_iZj(*K9nP!A_}Aq@i+T@+yI_|1R-VVLvwy%BL*_NGI7*R5ZQ zp#x2{0j@Hv`T@pvVlZf1AaS-zg?cQk^koZ*#=*`0aKVNiJ!;2H<*&y>pU(=6_h$xh zfLSZ6Fjfxe7GGe5xM~4oUisHfXz;E09#DyTR33szAc{kMsjC)|zKd+$X$QvzrW0sG6%;hMpK06?>9@xGWoBmGK&5 z$w{MiJlpL*|N05dLi?3onsu#}n#jBW;`^%w2I*K(qe!D-H0G#5A)_bwn qz#FqtMPy14M{{nRCocsTuY2)*Hu05y{c|^Rabv(SC`Z7wsHJXu!3wM5{QKZ$ODo=1d0<7 z6BrUMY6x9j)V zYwf-6J@?%EK2_at%J=Pk&)IwJwf8yq_ug&ye*bgd7^Y~$;V|`jy#$FS9rFLDAueKx zlJxHQ51a2{@Mb_Z>SYD9Jr=Pp*SOl5r=@EJSHea9j)#eGJj78Sdy4u93leQQd`vpc z-QM(yk9Sv}ML6c2^Kre#gQKu3kW4|G8C4zqtpv@$TP{VzMhty8+#eq$5FkWGvWz$E zSseTa347bTh}8kTlKij}@d=Z`*+{b;1|JB4Po53FHin?txEBzs zh<<)J>JVb5lC>SqsCjEfdC1v#We?yi!75mW!9D^L&^3+IKPPCz!j#V#SswDfpp73m zsVSE2yrQnv@H4F z0rBCkSPtc}>-?GvrsOkC{&5J`ECucX@tNl!J4r8+Th)3Kqis8CTsWhpuq0tw>%x`n z!pX;^OFCMP=Lq9^{34=AMai++8>avpSD(8~axg1IhZ&l5F%mc=$HxcUx8OMOL!!Y8 z2cO_8vcf9@ihH=zPn3XHcC_p*kostE4qSmXg8=c-iC0ap2#g~k20)Sl0Fmh;>((}8 zY}nVx$a=zu=iI;~ROmT=25-rE?CKodVV^N;6^vsUpyEiXc%qBEt$>z9oU^C}qhhS!GD1p;v$gVnsxOx0`Jcp1y&UnbhC3>YteC91qK3;Ri zezTRgJs6D@7zKlfd$Fdg@2N17<7~nsOah;KnXajn#CWbZ>t#dcYkhhAT#tHr4TMFE zj+hu%uDVRaOnn$Hnqo;}xQ`EXs8dq?lIoXaf2>r@YuBI8I9O?OFMOg23o_Szlm_09 z!pSD&D0}*beWh1`O(n<3by?+oxn7N1UOa^J4(KQb8)h3iW>GEI)fbYJZF+8!>mcDr zZHA9z!wC0fd&9jn+}|T2x(Blv)8+6$FVEXNc^ai~%@= z0gN(Tc}v1{QvSROXAuZF>O+rhlwni_%c$h^8d#PQXA+rNV=DIHdnxT&@qY0OXVYt+ z|EcuIvDq|x#LqB0JA3KFmDP0T)_PjLd^f%S!jf8I{3x3*KiKd>@dF|DA;BggOJ zn-{FKZ*c9{>B4h{VeBg;NGQROG-1Y89%WokD93XLdSxH-^%8TXn2%P>&5%+0u9bvtSSXH5=*#Ob;8 zE5G%L^p(GTJ-zX#ucVJWKWnFe?Xyf-$@s~zm^95S&N5rC0JQAfyY7ZGH(PG54So{{(Ub7N~W?&2HF^r&kA)TA_-E& z4hg;70PXQT2rddYuB?rTIC<#g>G|}#U;S+QqrZGDEi4Vw-u{j~xfH8W+`!g!&s}*- zPL73KqkxzpY;cyW!OO(8j}UnQs+koW44_BD>O+InN|YpyT|sYNUJvUB6HlCbG`;y( zznVV%`q{L*ci#?aySf*X2y)I}gb$uS&w(RnK*Q*F41mrBZbRBh8Av<6-783%Z zB1s)C7V5%}KD3)*|DB=(<$=3!VOe}?)}mXC2h6|s#%KO++}CjpvZx($XAK)8zN0bK zskEPF94i?sV}E}a<+WINMC+x+bH~y%FP=^>ytI^l=I38XgPFL2=-@F;*QNJwq(6S+ zU+fS(YR}VN#gbo%Q|5#5!OuST#W!)-c=JODNucqZV7i|Z(Cd1&THLAn)IA-f2Xj2F z%J#TVh6?U+;cK_l_9elLJ=^ws1B*YfXWjjD`MtID-|t*Y@BH(-X*k$PPd~S4#XVdh zPd+-IZd_kUSKeP`EKlO#`C9>h?aitJ|Hq2vNfP05eSCNn*1mVKg6?dk^gsW8GkwPj zdHnPso&V_Kc-Il5Pd)#5`q#JKwI5anBP=F&$Mj*vO|t>eSLbBtwuOESf^@x>HSRck zAHxbA^k>r6-G2I;ul`5+`>%bk9c+r8M;8~;Cx7{zaoIKN!{r~3a#KWO2u}cqF#oI& zmCW@K<2X^^aEA1g22KuW-UBS?flAvPAC@{DK!@$j;Ar~R*Ds_$|MEA}-tNIKJiqk0 z7p;K)nCF+9eTeYQ(nTaEU$^$*^;mA?KLZ`ZCJY=r>Aw8SE`_`rOqyM@D z(*w0nzV@^~;u#Ndm^S~$ePB*1*DE$i77bE~ORCV4u#*m%>li~*Z6K)wR|8ZufX*g{ z;c>M}n&Y5nZDd^c@vZoB=IpD+E~GmXO-xlfxv&w+77GaU4)p_TdppW>&84+WUxn9}JH}F6S@gPah&J$}Z`{~>N`28w{X_Q6#x!}|pyRnX^lFBE~ zIoHDgu^Z>W%CR!2&r1YHfNX;qS3&7G^}Z$x(#s@?Jv2$~O!3jP+nj&<*2O6-nXBwHQ; z_O@Xtri|kLqBiSZ>AW!J(l(M`stl-yqkXgORvh5a@T$yz4pN^+iu&B zS9kgQ%gWXDbmQ_yx^KTEVD;uJp4=zoU%cXrV$}uG;*ivs3O2EzaC8<-V3L0$+pZlH z5;LHJnjWvW&|3Jo$$tAEE~VQyzM1A1j-=%)_tMJMjdb^hU0lcq0#7x4!r|#=V9(oS zKFV8C_<8=#6^PZsq=UW4LR#ZkCiA{rmtEfHI?kyes(U@@stBwO-x_gk75?Dun_h1# z8Y18-jr!FyP;1Itk}RgkpKqwr7_gYpkm!>RiH6wh<6gT5%U@T|_NaX8gQUcp=x@R4 zBSHw0>52`BRf0pZW?h@s3;pUd0(JiHAh2DAT#Re41-!(uzac z4?jyM0zh~X-Juna;{vNoQ}gp%8WpI-t36%wamUe^u&^&(vc<>ppRtUq1ghm#RYO0GcWt{*;rF4A~|3NSPYX3(;aVP#&I zGfF^CGBSU3TL4YqVe)Uh8za({i~u6!nX~?u0KT|HMSzROVuWNzp_lRDOy9h$xh@cw;KWJBkzx&pHv1|9Za4C?j9>6Y zWWL&=mE*x|-n3fGL461U-QPLcPwN|NX=8IOZQtKc_wVnd-R-@!XRo2fn`s57Yw3xl zC+%xdTk!UWM9`#bRWiYR9P#Z>{0dN_C@11YebI*|U&Vt%{%Qws%ly;_f9Z-ZTS$%j z>uub12Mt75K_00N)9pJq(zT1z|8lmrwvqPF?Ah1n{>7yTwPG1I`$GBxKoPxR)cfjv zXi+bA=6ZQmWU&oE1*UJdBVLl_cpa&ZamxwtVO2=f+1WMsW(d zxqO4){Q7E|u0ZYbh=u!m7+GOY`l#`OSYba+{$c2bVzKrQ%UG_GO@65 z!mg~`o%&<-&UV_~+2r?bRXp=%Jd+;I4_A!?9J-qHX~$(Ji6F#4uuRwZH2JFz-~>M} z!w5hbL88F{Cr~{4961K3=^HLCS1w=kcc7yvnoY=DuTfPzNZS}PWJdwu#{vmJ6d`kc z#5jEeS2&Vzkq$}SZ0%vt2x)UG!8e17gvp-$0tVx1;DIJSr8L_<6L2#N>CTY+GlNP( zj}2xgPo7G>K^819CW%|i>*?0*Wy3-dQogDgoFb5jETqph0qz4rv>>ODYdZ8{(Lx>?CC;3A?g^rxh@(u5?KI<5)=9 z)v})!7nkhK0N5R@p$2zXw$qOwFCtZ|JvDCVTsUq;8Iq^AAj<@l+0&yPk8B<_MU*>SrVFEkoF~c?$gTaxsbnaBTcH!E{dV9iKay79Jb_#g3UBy5ZckvA$*n$a%Km+V9@j zmm8{H+uVATYmTcvI84sJ@hl9YXpsEF)eV1;G3%1B13V4~99mB-Eu~{86cD2iw{6>3 zW6q^cP+UgwD+{CvfYd6J1Y6)sdaTL$#|oq$AzTBHZLCK~(-|xzNgyO<*!uc*Tl3_( zv-X4n--q9}?dvjom&-2{h--gnlF&&vBy@0-B+uwGF`|h(q-_KYX}WTSJ|;ll$sD1(3=g6Yq6TmlEZBk8Oi z&LY-jc!`C(C%qyYVQ8>F{)8Mz~j% zhuE?h7l;=YJDiu!Jdw^n`#A6K#@SChwzaiYF?1hIj`*V28RjFS@N*m2m7VZvS&zue zQODlKU_qflx^6J+!$+-mjpJSn_iS^I%%`WHJ)6#)n@d*H2Ws0}_V4I;M}XK)PSSzB z58RwzEoCR!W#8;Ggn;YH&++wt?Ql<$(%m|`q(h=1xcaa!UE|(|PjBwl=Nkd1PCcGZ zoZLyPtE*|{+N%8k<(RUaM*5Z5uK3|v@-af5b@1h`0mm*w`7zOE)shQZ%|=%4)?>^1pcuNNH08koL}Zznh~xD zP>=vq#tVB~&)`{I*8r-V;VT`IyM?sAxEJ6!u>JWf9N3%d?5ICL7fsR$f|LjH(fYF_ zO!C#RU9Igcs-FGSxp3UR)tNuRYa^2A#>3U!PT3geE>Y|5Vj_OVn#fCO^AfeMuf2}sKd`%%RcL)fdxbgNCb`P&=s$K_z4*! z?BaNh3H#a;d+jDJH9tcmpvQBB`pXmMjld6(|M){V7+0q#6by`_U?qXBcTLpCbVXMF zo}CSOg3Ke!2R=%jddbHIC*m_!pdbJ-V!!0W@tT0JDM7&O%l!TS+98?%hfZml0qROb ze~$VZ!hS_2>b5|Hi8wUEHd}!3J6VOzH%!bBrILF-rhz=7Szi3YCtJPQrCQzTk(&O9PirCZM*Vsd>g~nZYYqs-UW=lNna=B7_MVQ(-YoNOqX6fFEDJdp*E7LlO#~e z*5U&UJOd&oHZ)1!YkWF4kD2QYqihG*ybly6&p~ETNf;Yrk#5hhJSAZX-90Lt0HCnW z*fmSnAeYP38^vQ@2lF1u8P>QqORoyqcKf!CA;#U zA;}0(o@6Hx5SfZ#NyfklEe1tN+W1X-O@(Avg>!t_Ng^D}8}T7--zP3v;<(c?Xc6!BHS*05HuGf|sq}%RJNvTk61&qXyN1xLJJAlu7OHeb}dYNRFGY zIAXudr-e7czTz?_|Hh*nX2Vai2n7Q15xYz#D?mwzKG}!rB8j0~XR_9(SuXK2C|7Ba zfs_PLQM8a8Ha&WMh@bJ%vOjqKR=_-f%^<@m&645x3`A5i=i03| z^0mo`6&KUO1%N*0UPyK{7FPXRCod1eQS(m*>%>gy7lg!?&%)Sj6KYF@QcXUlh{toV1q$M6WfwCK?txF z5C{Q(h!i=Al%PmKGDrxJ1xVya015bkK#CHOKp;7Q5ebh$U?DpWpajRB$-F$%ujyBH zRo9E}`_}sQ+2`DQ>(OC9i{{joZz}O<4+)YQ@10tFUNjK0;MW1IZ=}w_=7J~m= z5Ozu-ds%SGb^~O*AiLzkLWrh<0MCJ z?V?>FCVc>jI#D{e88gjF2}!6tH6{DJyODw&i+9`hx~ilFG#Tr zx6Tmsx4XnKdD=j$2`1idsCS>$(7&4QRHFDAr9=J)Fn;Z#YZf&Gk&GOI!+7UFV5$gf zn}jD#YJhhmI_GTDuYy~d?9)IJWDIy?&a4xmeMuPN9$w?)GX@y-rvcdqp7u%h7@)oT zG5&cb*ndo<(!qGS1R*y>a0ffbnp0Wzfy1<5ZgsSH_PQ|isljcirB%OM|4|s(V}Y=! zP6>%q#&DuMT#`IplY1iMh6wHe9B+=5u*EyhR!55m$1pxpO>1%a?zj!RSn5fCVL_((%wEN66>(HP1uL?-*nref-bT?0c z=%aZCL5dDq?FV0jkK4~(dMZ3}Kh)oA@uR>_3KJK&A#SzS)n<2-I@ElN5E*~46t^UqZst&%Y57ZVP zuy

+5?B|C8vG8hvM&@Mf-Asu*GYjZ2&D^83u?GLD=F0wrsr*BKpw~Xq z|FHC6#h)ix3@_5srPGuK4l*1CLPD}0gKi4;n)wXH4_QJs4;8{__9hL8Zd$VJ1NL^I z2RCszh$aof@E^lO>gV)OavmGD-g%Z3g2sHv-@EZMkbE9|$aFf-2^BW*3|~llPBV6= zNYfRz>I_CQfp=%c$RG7pg?Iiuc(ho`hd=&!Sy>yE#g$Q6;<7v{%PR|Ib7Q+)yS!1Z zU5VxT<;`;S(ni_aE@c}5u*k7@2)w#;AH~m#GM8}{of&l?hUCz`ot$jsBkl?q&wg!! zEjLwo(>cXBh`sxbZA+ubQ&`0E{no|u z?O%Vh{Pu5LEZ@O$dy}&oKFsq}B~Mr6WO{5oebOe~a=H?Cd_ylxHyoG0v-n*f>fQf& zaGjg!f;L>^*inEf6cJ^>hBrw#|qV7{turYSj5?XIwN%QP}n`=y+Jd{rWc zU5!R_<-H$#R7?3Hq@eqi?_Mb{{K{{a|Nie^EZZAYzmR1{vD21q($3iPa1Xf5&)te& zJ}L0MGWx{t`Oz=eIyzZ|SkgZah?+}ws}1<2$22gg&N&7qq_*1UM!x%dfGvsEA zXZPOjZh6m#9xhM5?_5&u06_1VbF1Y;AAh2J_KP1XPrm=5^4d$6%GJxa(qsfC^IUNm z47j%|en(4pbdqHPhG2LpNGeZI>^ZlM6OK2Y$i%UWs=*Ce(Hec#h8Up7qX^qR9@iNU zZKBC;_9u*arb?d7t&Gs27>#V#Dx zyjSAa-UVUvA>n)*emiT3vse`}u}uMqGx-(fZpg)vUXKI97Ehz*l^)1za3u6VF{B+f zL*nc+Y-P#w#w*vd zcKqIwRWhDrWSTK3RVH=YP1IeSE%b?c6TADsuZk=CH=5 z#WPKQe|`=u6gZA^?P#;QmKJ#M#{Ra$*%$pCjO;q`hSY4QfaUJ2lkaHZgLy-~wb9Dj z-%j^l*}lD7E?+p=S=`wz<=yXpNBJxN;77{u`|J~CYkNI+*__QR^xco2HhFlB8Jx!m zB@K8@c;Y(Lk%x{NrUEN!kKb+JE#4NT#ao`^;5lBPf=ipyR^Je{_IbF zs{DnY`$X9t-74GMW#dYE7;DWhEV%E;#wG|je!{?U^-cqk4oCn|{gPljH{}d*J2(#A z7Y3r=v=|(u*`Njm6zW6{P+bX$A0%&G!51TzxJE8kZ=TSJ)`Z;lNI&?8-dDc#H=ir> zOPiR@vCH1Yr5oe6&&oBn4e9eN;}3n>MK`|D0$XG^oB{3xGIQY|yrBj*L*b&x>2REU zWWi}q@)?p-x)M5YL&~WcV#6q5iw7h0B|^w6vo~gXsbnjMgCF?tyUJhwd!H|B=k|2+ zMei8fU5j6CW`Su~iDhC~+^NldN?~%DhE2;7T4zG(ZD`_UmB{Og87JhzW+*gh)nCX- z?-cpjUJJ{cBdwlz`h5A>pMSorKD<+I<5n1Np=u^Oz7vk0&K~i3aK^_xXZ|b9t{z|j zY%YLt5wU7@0LL&BjZnB)%w(YsdN9_4lRpQ9E|p%p(J{YG*!f3Km!JGwpDUx)O&pVN zW6#nZlNqiWp+eUxqmNGKAvt@%u}+F#jL7@E6;qK0R6^ATE5kq_CPLV;al%P|oPGS$ zENt*eyrk)7MMC0?+K{+(C7i_H(wLqrZ{kE}>rO6LBEDIzpLqI_@?(GXxw5r)qik<) z;_hl*xw3{=!=q>&yf7|#jwRi zJjBYn2m{B7)~k2-OnRD|AN)1`>xn#b$XrC$9#@yo5bPnm()y1E; zDpf>qv%^JhnX96f2wdez7^O*C3balV*8nlZz+fY7T63QV){uWpKlSMk2v6+rcT%@3 zr}?}e{gcmqusr*jr%>dZ*j-P!wK)(zPW;R&%N4gOnPe`BxcjM7E%nP6;EjJTfBSOfz88=`^QBLhhaQ>3{cD_bVHP{j z6MbuAZt=>zfBe+ldmhXY!_#<=oVk46g-}gKfTyu>{>ZI;VV9Ru!6!h!ms>sSBvx67>!+*#V&EVpjq!NB%*SzB8vr_QXDC*J*z^7Q*3FYkKt z5pdp}wz9fZ{^HL*SHAL7{}ykKER=?fhY`%9KjCq5291w@kfy} zIUq|m*^GDkLU%WSSliBCnyr(1XrKL5J>>H?djn4ga522OzEi&T%fA)JzP&BnC+>XU z4BEweI%m(XmXCb$z2#G%`EdF0556aZIXUoqKl<+ShkxV)<-h!!7m+VKZp8aV9Q2OE z@VN0y{>MM}OPLJ@MAdByjhm(4&%)UWN)KoBLHdR>dMMA3xtnq5#;5JphWd8#(jE68 zJGlOg$9X$7M(UtF7n%Lrcu?@pr%#p7{)vy3Pk;U+Wnpo|uui01zj~|u)EECrncq28 zmKWCGXB;gZ1C1Uxe%5C6?EAm)Wk*2eY=nslcmGl0QS~{vu%E?+Bhw0ckUxB+$0E+p zkID!O;R0sM{QLs87lkj(F99x<#nEzET39LT*LKP`UwEnf>aTpWoO{PwdGbAv9%SZ@ z`j=N0%f`m7@|)j$y)3{N7I+@-etD297aZKjh@Y}CY|=$4XN!^D;n_U~xF6=fz!EU5%5Ov zM~`VOpK>^e5}N3rwY3Ta*@e z|AElT2wOY_v*t(?3m-(o+%hL%n>_ah%`xkJXcT%8$L7U_)8!xijsIMJ?W_Mgb<75w zdT6D5>{IX7dtLD+i2a(Nzm2)Ylhv`d@%NtxgVA!7F;2*ZMKL5kwj>W-)IuK9XcfXL zY%0_M0qy}pUgDCmoFU~C7t-MNL$ctj`Vx2l5Yi3O(jBQK?j|~v&Eo`U5hr3xqf_Od z{_Pja|NX|xW|;~6BhUW;?rh;2owqP~?*Ur1z_$v4v(aBSJP<7cc= zfOQi;N$lVm_`=*u`TKwEKbE&H&F)Fn_ka9-<;*)4aVdwF18_;_T*z*-YGZD3vy8<9 zCKZ^$XrUBw!buveX&R&~oAr%B_Yq=|y@bF$cnBS&A-H<9mbdy#d(sIg9TFm{C3J9| zjU8-euq+`LwuEsahPR+`NwaxlzWn2_{3mtKYW2w<{ysf3){`dQ!c5-`X~#IBaQJ3e z87IGbUMlV-Xh`-l2S5RI$0lgwzAO??h-n!jT^ z5Xgy^^3vDf2kE0rJWX4eTP(l%^^4^jFMK!rn!)<}KmK0bpWfZULkPt_oA~2-aE=JZ z${-yx5#k*oanjI~kc3JyU8Ao2<4EEkVT-$e2sukg^JR;gluKe*=Dy z#ZTDc@>%+#f4}(WaPx#`*}OUOi@)$cq=&gUZu{U5JYD7&cl1&KmA1K<7SCbgKiczP z7;X#5M9_Fm2(~pKrbO$$Y5dg9HZ|esvkozOBNb{BtK96daD%=Y+HXV3u-8yyKm(-n zhrIHUHc;d%uWy$B^Psjb@#{L+Ge(KjsEw2k z6+&a^CKTSlUb?CaiBK+OD>TpS;BXHx9*^S+e}W%0#>|C(hUq71wJBz70dk=5hvMJ< z^^4`=_h$1usPB6QzjfN-6E7ZzkKQ64y4S^_V{kp@L96!tfDsEBX^1Ozc96$Qk`tQG zko?9815cScr=+0j4+qmZ2!xy=*czQJZvFP%@lb+zZ8XP5h(&z~TUqOCZKQw&Gw!)E z!llzUUU-RGkKKOl-+dEq#Tj%I307+!sJ_c-i`(Be2FE?q=fO0@d=j!5caFIm2`A!3 zIOBH4e1=1Pp>@A?8de3vkNyh>rdbCaCLVHOmnS&UKW@LTpHHiHcIL{rUU;QE_s5>G z(tY91_HKFY`OZWjfcIR(gSHVVnuz_Q^o@9;iG;40H zoW>)>rG-_|Xcy;k$BuvQ$3FAVNz8qR z<(HfE#pBI*`gfqd!Fafn_!*P#A&)l7`6m|2&6_tgL$~nbw-E}*$CD#He+G`C5+~&C zPd&QC<4Qqnlb`3k>dV3H7$)UQaXV%*7;oZ-Mr`FT@LAB{OAg6&cy9?}4JX?y$mi$KHun{kCIh=443Q{8R<+Zq4Ib zc4;p@{xU2gHB2g`H3ziegfoaA1@4YXbbuqrjvSPr=#ND99gVHAgbtWw3qg2>MLgV% zXSnhO`Z;Ue8gyL0I|GKArl5+9ec6+-TK}EKAL=L_Gu5v8qiPvW+8x+G;rL@0ogT4Z zY=%Qzo%^gJ;Z9#LcEN?-;0ZfSjBK?`4Q|xXsY&TEPlo-JGcA}cX-H~^J8r}1?fOH< z^!0c_`?;Xr@F{g-7R3F=pL&P5iR;D3I z0R|W;a=RpOtfpP3I{1gdo3ZdHeP@UL)PWwP7i%tGE`# z<->@tk?!Kih8qeY06E!9JI1qn=nuKX64F)F?246rcQJkrxN6_dB_Z|@bSL8DI5$lp zxHeP#ofLoG$%+hwvgV`*u83xrGQU}$E_?PkGpet=QY8w<55B@p{q5kVoEw`PDCQ=L zc^lt?+|sgz;yNgD^PS23$wqym@sU??3`1tSR5U1lFb7k5_i z52MtWgi%7ZfkT7Mx)*a!L!L!W@ziyc_;JLGM9>(UVQd|3&5?8M>TG@muz71Y-ciDv zhWx>pgEo|}7*K|jo`UG~ddp6$&1^ z(b*es;Uo-Sr`h4B0bLYnj)d7JAs4!5C|AL2NHK+!khpwL=r{~p-646n_$@~n*PvpA1Unm8?<`XXVOBsi|&nK0Oc7Kx5{h%*+&gR~gdxIv5PgU@*o zAM6@3qs9q^(>8DwjSA81BXRZ_ws=q{tdoDg`1{X;DIm`}W#LA*-N*U@{H6Nx%5oVk zjLOb7e~Wv(#zV~2OSj7M@`m1G56fv)g50x;hC-_vH>glqsh$?^!`DR%rL*5O38P#bYV zEHaeP#(Bg2v>$wf?YM2@`dqnw?HWG4u%XK(e$Bl$`ofm}g%9DElVBK(gY`hZjk(3G zUvcjnf953pX>|yft2UavpwY+hy(ws0EDjtlY=*?GD(!`iMju#EU&)5HV4PjMdSR<<+`b-f9P*tdI@$VS|7eo<)aE`yEZR&+AUy%^B!20W zU#Whm4-C>PMi?Y7ap#l#jtjWrOz4;mD__G;ZNvC`Gq@VF1EB>{=>Z)ePN*dnlAK+< z23jJ)7cN?D{(i?{i8n?)3k}E>tbd9v?F1F+@c;!3#6Ov7QhLoYS zp)_%W8VRvTHX(6#RhVoIyBH`MjN=UCmEL3_pJ-gg?%I&MZuS|rtij!>>fF^2z##`G zBkx()1d_DusBpgPSlS|m*mSx;* z$BCcv9#BI_y`&vhKY7`#$GC`xT=A|@r(uoz1mcgZV4XP;OgpWA!veArF#wojrd8es zoFH#q)AUn1j={_VTPhJ0p2Z7u!6Q7;p@$@k##uZnk39D9%x5u8Y;EG*;uqg4SFT*a z2TX8wUHD4?78$#3*;jhVibnj9ZD#SOy?VI{DODudgO@2ETLg5XhiI&## zD&~lrmzGgj24|cQi{ee##!lUAEloI75bA6iV`ph`d8U_4VKvtL2G+&bZTR6BE@3O*N2`h$r-+ z4{hpdK0KPQvSPhQ*_v{iprbS22jlRV3CibKAJ(nJ~v3{gK30 zXQq9(+M@!w|g6spY^?ODgTL3PoMYQMctL3+q` z6EN;s)V&qdYuM5(|ES5ZYVEW~pW;rw#Oa!vhbp0PgoByFnX`hoGai0yc2AmY@;GpP zJ?@V2D|79Q6UFYh4Pi*RN!a4mhY9gJ50s8($Svc9TwHuYE^LOewcon+NjQ9u=fP0I zzc3LnOm`x5AWQ`$-nt}yC^Xby;Rb1VtTKCC&^{IvcS?rrDwGowAB_?1UxtIL-&K*)u*4T-ZEwzzy`KYdL| zT+NUhP!?0k7DyqkRfD^qI*1cWKUcJqhR`R2<{#+enJRxDyS%ts9)I#oSy&?D+t_gE z;H$j&WOzKBANZ?SO>^9acMyL>+Qr-!T{yZ7Wt+v4JsIn8(k3jr_PGG*k8e<2ZFW_<@E?TYE;b5`MLRUyLytkpxK1X1 z-^gI`glFh1BY$hG!or*3jf^3`64a(`P!JYkMP|w6U7H z*>7G4HIEnCm*-F8#A~ixp1)RZUcHMK$#S^h-7#DxW2Mh9%;D+R-H1PJtDwkAEhy+g z3kKz%v?hlva@#CRn)wWw@BZ`PR73_d8A_=uOW5M-?2{&RLuV8)VC)(A)M{cx9t4s>kE6+>&2ndyKi`)0S7^E&}1N?2vczKu`v%syAme> zfX#u#x1`okYpwO2vyH23cJGf=Z8O&FIcn;tJ>Aji#lK(7dxI6Rs zQ|(mXJQ^NUFJ>D*ABDU27^)rIBr92`Jc0(VlQ4VE>m zCma?R<1LNF-IcO*exqz*M)Q9SyLAI^W8EC#BV@-bHa`=gyIELs09N;M-)n#FcKmci zwyQ%(Cvm4g(b^3}-Id^Da0*o6hN03_Dt9DQ0)YD}uBPCgJcZQYqPZc@2*Xq&=K zKQ=jbc%G@x|KY(sUjtgi{cL{TVQmG)K6krpZQ+Xoc%^n{Yp(2WVK=Ua2vT^c)o7W| zi)ASM_jnn&6TVR;eMGbGCm4U&(Hbk*wN0512fG0{ILih*j=|bVO9M}GB*Ilt`U=s@ zWLtt^63=j9KOLwu8j4IyjbXtXHk8o36Xdzu3fuUs2tVG5{~Uw=*C78>$(^O!Wo>l} zKW)L;FdiOk<9{#N(Je^aqrw9P9k+Qa(w@T2xj7unQAmCsa(N~G|3W;uRz%%^&3IBS zG`v0WJ7fDnM@Yz~lUAZGknv16=)p=T0j+DAM5S!y$LNxd9MQ&WfAUVVR}au>!Ri91;4kSVFTBwzAS#Tb9eT3_XbOl=KrTa_P7 zEna1&AVd3Pv+q+xdSuz!FCOZ{axcff5H*Pe8z*Fo1a(On?`OiCAsOvMNRYug zNiiM@&Ffh#by%fZaQDwTL+AAMP#-xv-#UB}EwuLi3wJ>acS8ZIk_xQH@J`~_b+AL? ziI0OOZQxF_IX#xz4-Pd@)-<42Wk^+BG~7C3vm!%^cQ`Gx84mFWF@D}1Knmh7QqLl1 z8IT*%0G)TkkmEX1$TW^Ey1_u%?xutAB%svp!t{zK|} z5aZWbGy`K}B7Ej50(KWlbRGbdF48j5p6ye2@hRs62<4EZ4#SR3#6Y(JU(-Y#*Rc>{yw-!-8@@#J~UZ;H-oTFqRR{X6$}F zL&p-PtTroW%5aci+cBhMi#M8tQjJxRV4QGbbBEyp3T)eO%))&TfB!~@6K^<{F?S>! zn<7Z7lcx-m&q{y|4gtd%3x*gh(%VT|<&ZySZyrX{UKAt!>zf}}D4AxJVs*;ebvsZy zlJP!>9|cBAGJs(|G&7xamI}C&%(Mi5oRld|Jk~Y*6;A_73w4MYE92Qew8xK|k|vlk zRn|Hh$l|i!GtNf?-|7}?Empcp{s%bz_@sYkE%Vt03<6_!f>}Qm<&gYJI26=`YnK*- zgvlP-tA?F%GZCWEkJcaKgltjVfI;cw;zvj2hk$(`zj2!%+Pfd)&!4VDIFh%6(r;{fUks!uLdV_l$1#@$Ng67VV@B-5 z%QkYUXsPTVd0R5%=xopWt1^!OJ6Yk-V(n;;M1&07*qo IM6N<$f@$&1OaK4? literal 0 HcmV?d00001 diff --git a/iOS/Sample/Icons.xcassets/AppIcon.appiconset/icon_60pt@2x.png b/iOS/Sample/Icons.xcassets/AppIcon.appiconset/icon_60pt@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..3c26d5db680b44eecf49553c420f8afdb8dd09a2 GIT binary patch literal 11074 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 IM6N<$f@$&1OaK4? literal 0 HcmV?d00001 diff --git a/iOS/Sample/Icons.xcassets/AppIcon.appiconset/icon_60pt@3x.png b/iOS/Sample/Icons.xcassets/AppIcon.appiconset/icon_60pt@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..e4c7ae242d1f73400d296bf6c84b9aca7a44de41 GIT binary patch literal 19384 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 D^!rdz literal 0 HcmV?d00001 diff --git a/iOS/Sample/Icons.xcassets/AppIcon.appiconset/icon_83.5@2x.png b/iOS/Sample/Icons.xcassets/AppIcon.appiconset/icon_83.5@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..c96d517001e24de57654391764b9e8333c862c25 GIT binary patch literal 17580 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

7=iV$PZeAfO{M@=h5shdX5pwp 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 A`2YX_ literal 0 HcmV?d00001 diff --git a/iOS/Sample/Info.plist b/iOS/Sample/Info.plist new file mode 100644 index 000000000..c20d05686 --- /dev/null +++ b/iOS/Sample/Info.plist @@ -0,0 +1,43 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + com.facebook.sonar + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/iOS/Sample/MainStoryBoard.storyboard b/iOS/Sample/MainStoryBoard.storyboard new file mode 100644 index 000000000..352bad524 --- /dev/null +++ b/iOS/Sample/MainStoryBoard.storyboard @@ -0,0 +1,165 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/iOS/Sample/MainViewController.h b/iOS/Sample/MainViewController.h new file mode 100644 index 000000000..e5cfabd21 --- /dev/null +++ b/iOS/Sample/MainViewController.h @@ -0,0 +1,12 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +#import + +@interface MainViewController : UIViewController + +@end diff --git a/iOS/Sample/MainViewController.m b/iOS/Sample/MainViewController.m new file mode 100644 index 000000000..ac31bf779 --- /dev/null +++ b/iOS/Sample/MainViewController.m @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ + +#import "MainViewController.h" + +#import "NetworkViewController.h" +#import "RootViewController.h" + +@interface MainViewController () + +@end + +@implementation MainViewController + +- (void)viewDidLoad { + [super viewDidLoad]; + // Do any additional setup after loading the view. +} + +- (IBAction)tappedComponentKitLayout:(UIButton *)sender { + RootViewController *rootViewController = [RootViewController new]; + + [self.navigationController pushViewController:rootViewController animated:true]; +} + +- (IBAction)tappedNetworkInspector:(UIButton *)sender { + UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryBoard" bundle:nil]; + NetworkViewController *networkViewController = [storyboard instantiateViewControllerWithIdentifier:@"NetworkViewController"]; + + [self.navigationController pushViewController:networkViewController animated:true]; +} + +@end diff --git a/iOS/Sample/NetworkViewController.h b/iOS/Sample/NetworkViewController.h new file mode 100644 index 000000000..9f89e2a7f --- /dev/null +++ b/iOS/Sample/NetworkViewController.h @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ + +#import + +@interface NetworkViewController : UIViewController + +@end diff --git a/iOS/Sample/NetworkViewController.m b/iOS/Sample/NetworkViewController.m new file mode 100644 index 000000000..3696be0b1 --- /dev/null +++ b/iOS/Sample/NetworkViewController.m @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ + +#import "NetworkViewController.h" + +@interface NetworkViewController () + +@end + +@implementation NetworkViewController + +- (void)viewDidLoad { + [super viewDidLoad]; + self.navigationItem.title = @"Network"; +} + +- (IBAction)tappedGithubLitho:(UIButton *)sender { + [[[NSURLSession sharedSession] dataTaskWithURL:[NSURL URLWithString:@"https://raw.githubusercontent.com/facebook/litho/master/docs/static/logo.png"] completionHandler:^(NSData *_Nullable data, NSURLResponse *_Nullable response, NSError *_Nullable error) { + if (error && !data) { + return; + } + NSLog(@"Got Image"); + }] resume]; +} + +- (IBAction)tappedPOSTAPI:(UIButton *)sender { + NSString *post = @"https://demo9512366.mockable.io/SonarPost"; + NSURL *url = [NSURL URLWithString:post]; + NSMutableURLRequest *urlRequest = [NSMutableURLRequest requestWithURL: url]; + [urlRequest addValue:@"application/json" forHTTPHeaderField:@"Content-Type"]; + [urlRequest addValue:@"application/json" forHTTPHeaderField:@"Accept"]; + NSDictionary *mapData = [[NSDictionary alloc] initWithObjectsAndKeys: @"Sonar", @"app", + @"Its awesome", @"remarks", + nil]; + NSError *error = nil; + NSData *postData = [NSJSONSerialization dataWithJSONObject:mapData options:0 error:&error]; + [urlRequest setHTTPBody:postData]; + [urlRequest setHTTPMethod:@"POST"]; + __weak NetworkViewController *weakSelf = self; + [[[NSURLSession sharedSession] dataTaskWithRequest:urlRequest completionHandler:^(NSData *_Nullable data, NSURLResponse *_Nullable response, NSError *_Nullable error) { + + if (error || !data) { + UIAlertController *alertController = [weakSelf alertControllerForMessage:@"Received error in POST API response"]; + [weakSelf presentViewController:alertController animated:true completion:nil]; + return; + } + NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error]; + NSLog(@"MSG-POST: %@", dict[@"msg"]); + + UIAlertController *alertController = [weakSelf alertControllerForMessage:@"Received response from POST API"]; + [weakSelf presentViewController:alertController animated:true completion:nil]; + + }] resume]; +} + +- (IBAction)tappedGetAPI:(UIButton *)sender { + __weak NetworkViewController *weakSelf = self; + [[[NSURLSession sharedSession] dataTaskWithURL:[NSURL URLWithString:@"https://demo9512366.mockable.io/"] completionHandler:^(NSData *_Nullable data, NSURLResponse *_Nullable response, NSError *_Nullable error) { + if (error || !data) { + UIAlertController *alertController = [weakSelf alertControllerForMessage:@"Received error in GET API response"]; + [weakSelf presentViewController:alertController animated:true completion:nil]; + return; + } + NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error]; + NSLog(@"MSG-GET: %@", dict[@"msg"]); + UIAlertController *alertController = [weakSelf alertControllerForMessage:@"Received response from GET API"]; + [weakSelf presentViewController:alertController animated:true completion:nil]; + }] resume]; +} + + +- (UIAlertController *)alertControllerForMessage:(nonnull NSString *)msg { + UIAlertController *controller = [UIAlertController alertControllerWithTitle:@"Sonar" message:msg preferredStyle:UIAlertControllerStyleAlert]; + UIAlertAction *action = [UIAlertAction actionWithTitle:@"Ok" style:UIAlertActionStyleDefault handler:nil]; + [controller addAction:action]; + return controller; +} + +@end diff --git a/iOS/Sample/Podfile b/iOS/Sample/Podfile new file mode 100644 index 000000000..70f73b4a3 --- /dev/null +++ b/iOS/Sample/Podfile @@ -0,0 +1,31 @@ +project 'Sample.xcodeproj' + +# Uncomment the next line to define a global platform for your project +# platform :ios, '9.0' +swift_version = "4.1" + +target 'Sample' do + + pod 'EasyWSClient', :podspec => '../third-party-podspecs/EasyWSClient.podspec' + pod 'DoubleConversion', :podspec => '../third-party-podspecs/DoubleConversion.podspec' + pod 'glog', :podspec => '../third-party-podspecs/glog.podspec' + pod 'Folly', :podspec => '../third-party-podspecs/Folly.podspec' + pod 'PeerTalk', :git => 'https://github.com/rsms/peertalk' + pod 'ComponentKit', :podspec => '../third-party-podspecs/ComponentKit.podspec' + pod 'Yoga','~>1.8.1', :modular_headers => true + pod 'Sonar', :podspec => '../../xplat/Sonar/SonarKitCPP.podspec' + pod 'SonarKit', :podspec => '../SonarKit.podspec' + pod 'SonarKit/SonarKitLayoutComponentKitSupport', :podspec => '../SonarKit.podspec' + pod 'SonarKit/SKIOSNetworkPlugin', :podspec => '../SonarKit.podspec' + + post_install do |installer| + installer.pods_project.targets.each do |target| + if ['YogaKit'].include? target.name + target.build_configurations.each do |config| + config.build_settings['SWIFT_VERSION'] = swift_version + end + end + end + end + +end diff --git a/iOS/Sample/Podfile.lock b/iOS/Sample/Podfile.lock new file mode 100644 index 000000000..399025b3e --- /dev/null +++ b/iOS/Sample/Podfile.lock @@ -0,0 +1,128 @@ +PODS: + - boost-for-react-native (1.63.0) + - CocoaAsyncSocket (7.6.3) + - ComponentKit (0.21): + - Yoga + - DoubleConversion (3.0.0) + - EasyWSClient (1.0.0) + - Folly (2018.05.07.00): + - boost-for-react-native + - DoubleConversion + - glog + - glog (0.3.5) + - PeerTalk (0.0.2) + - Sonar (1.0.0): + - EasyWSClient + - Folly + - SonarKit (1.0.0): + - CocoaAsyncSocket (~> 7.6) + - Folly + - PeerTalk + - Sonar + - SonarKit/SKIOSNetworkPlugin (= 1.0.0) + - SonarKit/SonarKitLayoutComponentKitSupport (= 1.0.0) + - SonarKit/SonarKitLayoutPlugin (= 1.0.0) + - SonarKit/SonarKitNetworkPlugin (= 1.0.0) + - SonarKit/SonarKitNetworkPlugin (= 1.0.0) + - SonarKit/SKIOSNetworkPlugin (1.0.0): + - CocoaAsyncSocket (~> 7.6) + - Folly + - PeerTalk + - Sonar + - SonarKit/SonarKitNetworkPlugin + - SonarKit/SonarKitLayoutComponentKitSupport (1.0.0): + - CocoaAsyncSocket (~> 7.6) + - ComponentKit + - Folly + - PeerTalk + - Sonar + - SonarKit/SonarKitLayoutPlugin + - Yoga (= 1.8.1) + - SonarKit/SonarKitLayoutPlugin (1.0.0): + - CocoaAsyncSocket (~> 7.6) + - Folly + - PeerTalk + - Sonar + - Yoga (= 1.8.1) + - YogaKit (= 1.8.1) + - SonarKit/SonarKitNetworkPlugin (1.0.0): + - CocoaAsyncSocket (~> 7.6) + - Folly + - PeerTalk + - Sonar + - Yoga (1.8.1) + - YogaKit (1.8.1): + - Yoga (~> 1.8.1) + +DEPENDENCIES: + - ComponentKit (from `../third-party-podspecs/ComponentKit.podspec`) + - DoubleConversion (from `../third-party-podspecs/DoubleConversion.podspec`) + - EasyWSClient (from `../third-party-podspecs/EasyWSClient.podspec`) + - Folly (from `../third-party-podspecs/Folly.podspec`) + - glog (from `../third-party-podspecs/glog.podspec`) + - PeerTalk (from `https://github.com/rsms/peertalk`) + - Sonar (from `../../xplat/Sonar/SonarKitCPP.podspec`) + - SonarKit (from `../SonarKit.podspec`) + - SonarKit/SKIOSNetworkPlugin (from `../SonarKit.podspec`) + - SonarKit/SonarKitLayoutComponentKitSupport (from `../SonarKit.podspec`) + - Yoga (~> 1.8.1) + +SPEC REPOS: + https://github.com/cocoapods/specs.git: + - boost-for-react-native + - CocoaAsyncSocket + - Yoga + - YogaKit + +EXTERNAL SOURCES: + ComponentKit: + :podspec: "../third-party-podspecs/ComponentKit.podspec" + DoubleConversion: + :podspec: "../third-party-podspecs/DoubleConversion.podspec" + EasyWSClient: + :podspec: "../third-party-podspecs/EasyWSClient.podspec" + Folly: + :podspec: "../third-party-podspecs/Folly.podspec" + glog: + :podspec: "../third-party-podspecs/glog.podspec" + PeerTalk: + :git: https://github.com/rsms/peertalk + Sonar: + :podspec: "../../xplat/Sonar/SonarKitCPP.podspec" + SonarKit: + :podspec: "../SonarKit.podspec" + +CHECKOUT OPTIONS: + ComponentKit: + :commit: f801317e71f88fbb5a398cd726fc0375255f43ba + :git: https://github.com/facebook/ComponentKit.git + EasyWSClient: + :commit: 9b87dc488048900a8cd684f51ddc98143682dbc3 + :git: https://github.com/dhbaird/easywsclient.git + PeerTalk: + :commit: 588303b43efa5082d654b6f75d1b84a6ba4b5b9e + :git: https://github.com/rsms/peertalk + Sonar: + :commit: 26c298ad3401157ac2b7336218c1dde63260dc0c + :git: https://github.com/facebook/Sonar.git + SonarKit: + :commit: 26c298ad3401157ac2b7336218c1dde63260dc0c + :git: https://github.com/facebook/Sonar.git + +SPEC CHECKSUMS: + boost-for-react-native: 39c7adb57c4e60d6c5479dd8623128eb5b3f0f2c + CocoaAsyncSocket: eafaa68a7e0ec99ead0a7b35015e0bf25d2c8987 + ComponentKit: 7bd0ad508946aeb68dd52ed8739ced9846ff3671 + DoubleConversion: 310ccd7cdf00175c32883664f84fe026025604df + EasyWSClient: 7ec8effe7d86f6061a47d19a55355769c9edfd2f + Folly: 2d29ed217455246ae583ff1980f9ce882af31e80 + glog: f175af2df1f453be65bd355b287a07c842927a99 + PeerTalk: f5389c286e4d477e59b73dfbf25c5c70a2464761 + Sonar: 815b6c6357c78564d9132f6389605b285a06f052 + SonarKit: 29b45073b54d7f5db13e53b7afe6fb6f36c6bea7 + Yoga: e6f1fed82138c17da5332e15e5770abf0e9cc386 + YogaKit: bb90d11e297e06abef7e0cfb20e035a6bd00cdc4 + +PODFILE CHECKSUM: cab936292346d86ef8900c8f67d3c707dc421709 + +COCOAPODS: 1.5.2 \ No newline at end of file diff --git a/iOS/Sample/RootViewController.h b/iOS/Sample/RootViewController.h new file mode 100644 index 000000000..205e50499 --- /dev/null +++ b/iOS/Sample/RootViewController.h @@ -0,0 +1,12 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +#import + +@interface RootViewController : UIViewController + +@end diff --git a/iOS/Sample/RootViewController.mm b/iOS/Sample/RootViewController.mm new file mode 100644 index 000000000..e92ebea42 --- /dev/null +++ b/iOS/Sample/RootViewController.mm @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +#import "RootViewController.h" + +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import + +@interface RootViewController () + +@property (strong, nonatomic) CKComponentHostingView *rootCKHostingView; + +@end + +@implementation RootViewController + +- (instancetype)init +{ + if (self = [super init]) { + _rootCKHostingView = [[CKComponentHostingView alloc] + initWithComponentProvider:[self class] + sizeRangeProvider: + [CKComponentFlexibleSizeRangeProvider providerWithFlexibility:CKComponentSizeRangeFlexibleHeight]]; + + [self.view addSubview:_rootCKHostingView]; + [self loadViewIfNeeded]; + } + return self; +} + +- (void)viewDidLoad { + [super viewDidLoad]; + self.navigationItem.title = @"ComponentKit Layout"; + self.edgesForExtendedLayout = UIRectEdgeNone; +} + +- (void)viewDidLayoutSubviews +{ + [super viewDidLayoutSubviews]; + _rootCKHostingView.frame = self.view.bounds; +} + ++ (CKComponent *)componentForModel:(id)model context:(id)context { + return [CKBackgroundLayoutComponent + newWithComponent: + [CKFlexboxComponent + newWithView:{ + } + size:{} + style:{} + children: { + { + [CKButtonComponent + newWithAction:nil + options:{ + .titles = @"Purple", + .titleColors = UIColor.purpleColor, + } + ] + }, + { + [CKButtonComponent + newWithAction:nil + options:{ + .titles = @"Brown", + .titleColors = UIColor.brownColor, + } + ] + }, + { + [CKButtonComponent + newWithAction:nil + options:{ + .titles = @"Cyan", + .titleColors = UIColor.cyanColor, + } + ] + }, + }] + background: + [CKImageComponent + newWithImage:[UIImage imageNamed:@"sonarpattern"] + attributes:{} + size:{}]]; +} + +@end diff --git a/iOS/Sample/Sample.xcodeproj/project.pbxproj b/iOS/Sample/Sample.xcodeproj/project.pbxproj new file mode 100644 index 000000000..bbe9e8cf1 --- /dev/null +++ b/iOS/Sample/Sample.xcodeproj/project.pbxproj @@ -0,0 +1,480 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 50; + objects = { + +/* Begin PBXBuildFile section */ + 53D59DB320ABA18400207065 /* NetworkViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 53D59DAA20ABA18300207065 /* NetworkViewController.m */; }; + 53D59DB420ABA18400207065 /* AppDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = 53D59DAB20ABA18300207065 /* AppDelegate.mm */; }; + 53D59DB520ABA18400207065 /* MainViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 53D59DAD20ABA18300207065 /* MainViewController.m */; }; + 53D59DB620ABA18400207065 /* RootViewController.mm in Sources */ = {isa = PBXBuildFile; fileRef = 53D59DAF20ABA18300207065 /* RootViewController.mm */; }; + 53D59DB720ABA18400207065 /* MainStoryBoard.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 53D59DB020ABA18400207065 /* MainStoryBoard.storyboard */; }; + 53D59DB820ABA18400207065 /* Icons.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 53D59DB120ABA18400207065 /* Icons.xcassets */; }; + 53E0DE5420ABA0E4005682E1 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 53E0DE5320ABA0E4005682E1 /* main.m */; }; + B369CEA3B6F57057FAACAE2F /* libPods-Sample.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 27922CF99D8E609480377096 /* libPods-Sample.a */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 275FDB8D19C1C8C26A47DA09 /* Pods-Sample.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Sample.release.xcconfig"; path = "Pods/Target Support Files/Pods-Sample/Pods-Sample.release.xcconfig"; sourceTree = ""; }; + 27922CF99D8E609480377096 /* libPods-Sample.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Sample.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + 53D59DAA20ABA18300207065 /* NetworkViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NetworkViewController.m; sourceTree = SOURCE_ROOT; }; + 53D59DAB20ABA18300207065 /* AppDelegate.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = AppDelegate.mm; sourceTree = SOURCE_ROOT; }; + 53D59DAC20ABA18300207065 /* NetworkViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NetworkViewController.h; sourceTree = SOURCE_ROOT; }; + 53D59DAD20ABA18300207065 /* MainViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MainViewController.m; sourceTree = SOURCE_ROOT; }; + 53D59DAE20ABA18300207065 /* RootViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RootViewController.h; sourceTree = SOURCE_ROOT; }; + 53D59DAF20ABA18300207065 /* RootViewController.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = RootViewController.mm; sourceTree = SOURCE_ROOT; }; + 53D59DB020ABA18400207065 /* MainStoryBoard.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = MainStoryBoard.storyboard; sourceTree = SOURCE_ROOT; }; + 53D59DB120ABA18400207065 /* Icons.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Icons.xcassets; sourceTree = SOURCE_ROOT; }; + 53D59DB220ABA18400207065 /* MainViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MainViewController.h; sourceTree = SOURCE_ROOT; }; + 53D59DBA20ABA20300207065 /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 53E0DE4120ABA0E3005682E1 /* Sample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Sample.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 53E0DE5220ABA0E4005682E1 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = SOURCE_ROOT; }; + 53E0DE5320ABA0E4005682E1 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 7086E77977EF48ABCAE4DED7 /* Pods-Sample.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Sample.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Sample/Pods-Sample.debug.xcconfig"; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 53E0DE3E20ABA0E3005682E1 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + B369CEA3B6F57057FAACAE2F /* libPods-Sample.a in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 53D59DB920ABA19900207065 /* Sample */ = { + isa = PBXGroup; + children = ( + 53D59DBA20ABA20300207065 /* AppDelegate.h */, + 53D59DAB20ABA18300207065 /* AppDelegate.mm */, + 53D59DB120ABA18400207065 /* Icons.xcassets */, + 53D59DB020ABA18400207065 /* MainStoryBoard.storyboard */, + 53D59DB220ABA18400207065 /* MainViewController.h */, + 53D59DAD20ABA18300207065 /* MainViewController.m */, + 53D59DAC20ABA18300207065 /* NetworkViewController.h */, + 53D59DAA20ABA18300207065 /* NetworkViewController.m */, + 53D59DAE20ABA18300207065 /* RootViewController.h */, + 53D59DAF20ABA18300207065 /* RootViewController.mm */, + 53E0DE5220ABA0E4005682E1 /* Info.plist */, + 53E0DE5320ABA0E4005682E1 /* main.m */, + ); + name = Sample; + sourceTree = ""; + }; + 53E0DE3820ABA0E3005682E1 = { + isa = PBXGroup; + children = ( + 53D59DB920ABA19900207065 /* Sample */, + 53E0DE4220ABA0E3005682E1 /* Products */, + 71F5EB9E42BEADDCC04A205D /* Pods */, + E2FCEB633911AF4886EC0881 /* Frameworks */, + ); + sourceTree = ""; + }; + 53E0DE4220ABA0E3005682E1 /* Products */ = { + isa = PBXGroup; + children = ( + 53E0DE4120ABA0E3005682E1 /* Sample.app */, + ); + name = Products; + sourceTree = ""; + }; + 71F5EB9E42BEADDCC04A205D /* Pods */ = { + isa = PBXGroup; + children = ( + 7086E77977EF48ABCAE4DED7 /* Pods-Sample.debug.xcconfig */, + 275FDB8D19C1C8C26A47DA09 /* Pods-Sample.release.xcconfig */, + ); + name = Pods; + sourceTree = ""; + }; + E2FCEB633911AF4886EC0881 /* Frameworks */ = { + isa = PBXGroup; + children = ( + 27922CF99D8E609480377096 /* libPods-Sample.a */, + ); + name = Frameworks; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 53E0DE4020ABA0E3005682E1 /* Sample */ = { + isa = PBXNativeTarget; + buildConfigurationList = 53E0DE5720ABA0E4005682E1 /* Build configuration list for PBXNativeTarget "Sample" */; + buildPhases = ( + 88DDF414B12B2B557290B67B /* [CP] Check Pods Manifest.lock */, + 53E0DE3D20ABA0E3005682E1 /* Sources */, + 53E0DE3E20ABA0E3005682E1 /* Frameworks */, + 53E0DE3F20ABA0E3005682E1 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = Sample; + productName = Sample; + productReference = 53E0DE4120ABA0E3005682E1 /* Sample.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 53E0DE3920ABA0E3005682E1 /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0940; + ORGANIZATIONNAME = Facebook; + TargetAttributes = { + 53E0DE4020ABA0E3005682E1 = { + CreatedOnToolsVersion = 9.4; + }; + }; + }; + buildConfigurationList = 53E0DE3C20ABA0E3005682E1 /* Build configuration list for PBXProject "Sample" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 53E0DE3820ABA0E3005682E1; + productRefGroup = 53E0DE4220ABA0E3005682E1 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 53E0DE4020ABA0E3005682E1 /* Sample */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 53E0DE3F20ABA0E3005682E1 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 53D59DB820ABA18400207065 /* Icons.xcassets in Resources */, + 53D59DB720ABA18400207065 /* MainStoryBoard.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 88DDF414B12B2B557290B67B /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-Sample-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 53E0DE3D20ABA0E3005682E1 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 53E0DE5420ABA0E4005682E1 /* main.m in Sources */, + 53D59DB320ABA18400207065 /* NetworkViewController.m in Sources */, + 53D59DB420ABA18400207065 /* AppDelegate.mm in Sources */, + 53D59DB520ABA18400207065 /* MainViewController.m in Sources */, + 53D59DB620ABA18400207065 /* RootViewController.mm in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + 53E0DE5520ABA0E4005682E1 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 11.4; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + }; + name = Debug; + }; + 53E0DE5620ABA0E4005682E1 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 11.4; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 53E0DE5820ABA0E4005682E1 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7086E77977EF48ABCAE4DED7 /* Pods-Sample.debug.xcconfig */; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + GCC_NO_COMMON_BLOCKS = YES; + GCC_PREPROCESSOR_DEFINITIONS = ( + "$(inherited)", + "COCOAPODS=1", + "FB_SONARKIT_ENABLED=1", + ); + HEADER_SEARCH_PATHS = ( + "$(inherited)", + "\"${PODS_ROOT}/Headers/Public\"", + "\"${PODS_ROOT}/Headers/Public/CocoaAsyncSocket\"", + "\"${PODS_ROOT}/Headers/Public/ComponentKit\"", + "\"${PODS_ROOT}/Headers/Public/DoubleConversion\"", + "\"${PODS_ROOT}/Headers/Public/EasyWSClient\"", + "\"${PODS_ROOT}/Headers/Public/Folly\"", + "\"${PODS_ROOT}/Headers/Public/PeerTalk\"", + "\"${PODS_ROOT}/Headers/Public/Sonar\"/**", + "\"${PODS_ROOT}/Headers/Public/SonarKit\"", + "\"${PODS_ROOT}/Headers/Public/Yoga\"", + "\"${PODS_ROOT}/Headers/Public/boost-for-react-native\"", + "\"${PODS_ROOT}/Headers/Public/glog\"/**", + "\"${PODS_ROOT}/SonarKit\"/**", + ); + INFOPLIST_FILE = "$(SRCROOT)/Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 11.3; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + OTHER_CPLUSPLUSFLAGS = ( + "$(OTHER_CFLAGS)", + "-DFB_SONARKIT_ENABLED=1", + "-Wno-implicit-retain-self", + "-Wno-global-constructors", + ); + OTHER_LDFLAGS = ( + "$(inherited)", + "-ObjC", + "-l\"CocoaAsyncSocket\"", + "-l\"ComponentKit\"", + "-l\"DoubleConversion\"", + "-l\"EasyWSClient\"", + "-l\"Folly\"", + "-l\"PeerTalk\"", + "-l\"Sonar\"", + "-l\"SonarKit\"", + "-l\"Yoga\"", + "-l\"c++\"", + "-l\"glog\"", + "-l\"stdc++\"", + "-framework", + "\"CFNetwork\"", + "-framework", + "\"CoreText\"", + "-framework", + "\"Security\"", + "-framework", + "\"UIKit\"", + "-DFB_SONARKIT_ENABLED=1", + ); + PRODUCT_BUNDLE_IDENTIFIER = FB.Sample; + PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 53E0DE5920ABA0E4005682E1 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 275FDB8D19C1C8C26A47DA09 /* Pods-Sample.release.xcconfig */; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + GCC_NO_COMMON_BLOCKS = YES; + HEADER_SEARCH_PATHS = ( + "$(inherited)", + "\"${PODS_ROOT}/Headers/Public\"", + "\"${PODS_ROOT}/Headers/Public/CocoaAsyncSocket\"", + "\"${PODS_ROOT}/Headers/Public/ComponentKit\"", + "\"${PODS_ROOT}/Headers/Public/DoubleConversion\"", + "\"${PODS_ROOT}/Headers/Public/EasyWSClient\"", + "\"${PODS_ROOT}/Headers/Public/Folly\"", + "\"${PODS_ROOT}/Headers/Public/PeerTalk\"", + "\"${PODS_ROOT}/Headers/Public/Sonar\"/**", + "\"${PODS_ROOT}/Headers/Public/SonarKit\"", + "\"${PODS_ROOT}/Headers/Public/Yoga\"", + "\"${PODS_ROOT}/Headers/Public/boost-for-react-native\"", + "\"${PODS_ROOT}/Headers/Public/glog\"/**", + "\"${PODS_ROOT}/SonarKit\"/**", + ); + INFOPLIST_FILE = "$(SRCROOT)/Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 11.3; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + OTHER_CPLUSPLUSFLAGS = ( + "$(OTHER_CFLAGS)", + "-DFB_SONARKIT_ENABLED=1", + "-Wno-implicit-retain-self", + "-Wno-global-constructors", + ); + OTHER_LDFLAGS = ( + "$(inherited)", + "-ObjC", + "-l\"CocoaAsyncSocket\"", + "-l\"ComponentKit\"", + "-l\"DoubleConversion\"", + "-l\"EasyWSClient\"", + "-l\"Folly\"", + "-l\"PeerTalk\"", + "-l\"Sonar\"", + "-l\"SonarKit\"", + "-l\"Yoga\"", + "-l\"c++\"", + "-l\"glog\"", + "-l\"stdc++\"", + "-framework", + "\"CFNetwork\"", + "-framework", + "\"CoreText\"", + "-framework", + "\"Security\"", + "-framework", + "\"UIKit\"", + "-DFB_SONARKIT_ENABLED=1", + ); + PRODUCT_BUNDLE_IDENTIFIER = FB.Sample; + PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 53E0DE3C20ABA0E3005682E1 /* Build configuration list for PBXProject "Sample" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 53E0DE5520ABA0E4005682E1 /* Debug */, + 53E0DE5620ABA0E4005682E1 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 53E0DE5720ABA0E4005682E1 /* Build configuration list for PBXNativeTarget "Sample" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 53E0DE5820ABA0E4005682E1 /* Debug */, + 53E0DE5920ABA0E4005682E1 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 53E0DE3920ABA0E3005682E1 /* Project object */; +} diff --git a/iOS/Sample/main.m b/iOS/Sample/main.m new file mode 100644 index 000000000..017e75452 --- /dev/null +++ b/iOS/Sample/main.m @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +#import + +#import "AppDelegate.h" + +int main(int argc, char * argv[]) { + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } +} diff --git a/iOS/SonarKit.podspec b/iOS/SonarKit.podspec new file mode 100644 index 000000000..80136339f --- /dev/null +++ b/iOS/SonarKit.podspec @@ -0,0 +1,99 @@ +folly_compiler_flags = '-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1 -DFOLLY_HAVE_LIBGFLAGS=0 -DFOLLY_HAVE_LIBJEMALLOC=0 -DFOLLY_HAVE_PREADV=0 -DFOLLY_HAVE_PWRITEV=0 -DFOLLY_HAVE_TFO=0 -DFOLLY_USE_SYMBOLIZER=0' +yoga_version = '1.8.1' +yogakit_version = '1.8.1' + +Pod::Spec.new do |spec| + spec.name = 'SonarKit' + spec.version = '1.0.0' + spec.license = { :type => 'MIT' } + spec.homepage = 'https://github.com/facebook/Sonar' + spec.summary = 'Sonar iOS podspec' + spec.authors = 'Facebook' + # spec.prepare_command = 'mv src double-conversion' + spec.source = { :git => 'https://github.com/facebook/Sonar.git', + :branch=> "master" } + spec.module_name = 'SonarKit' + spec.dependency 'Folly' + spec.dependency 'Sonar' + spec.dependency 'CocoaAsyncSocket', '~> 7.6' + spec.dependency 'PeerTalk' + spec.source_files = 'iOS/FBDefines/*.{h,cpp,m,mm}', 'iOS/SonarKit/**/*.{h,cpp,m,mm}' + spec.public_header_files = 'iOS/SonarKit/CppBridge/*.{h}', + 'iOS/SonarKit/SonarClient.h', + 'iOS/SonarKit/SonarDeviceData.h', + 'iOS/SonarKit/SonarPlugin.h', + 'iOS/SonarKit/SonarResponder.h', + 'iOS/SonarKit/SonarConnection.h', + 'iOS/SonarKit/SKMacros.h' + + spec.private_header_files = 'iOS/Sample/' + spec.compiler_flags = '-DFB_SONARKIT_ENABLED=1 -DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1 -DFOLLY_HAVE_LIBGFLAGS=0 -DFOLLY_HAVE_LIBJEMALLOC=0 -DFOLLY_HAVE_PREADV=0 -DFOLLY_HAVE_PWRITEV=0 -DFOLLY_HAVE_TFO=0 -DFOLLY_USE_SYMBOLIZER=0' + spec.pod_target_xcconfig = { "USE_HEADERMAP" => "NO", + "CLANG_CXX_LANGUAGE_STANDARD" => "c++14", + "HEADER_SEARCH_PATHS" => "\"$(PODS_TARGET_SRCROOT)\"/** \"$(PODS_ROOT)/boost-for-react-native\" \"$(PODS_ROOT)/DoubleConversion\" \"$(PODS_ROOT)/ComponentKit\"/**" } + spec.platforms = { :ios => "8.0", :tvos => "9.2" } + + spec.subspec "SonarKitLayoutPlugin" do |ss| + ss.dependency "Yoga", yoga_version + ss.dependency 'YogaKit', yogakit_version + ss.compiler_flags = folly_compiler_flags + ss.public_header_files = 'iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/SonarKitLayoutPlugin.h', + 'iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/SKTouch.h', + 'iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/SKDescriptorMapper.h', + 'iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/SKNodeDescriptor.h', + 'iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/SKInvalidation.h', + 'iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/SKNamed.h', + 'iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/SKTapListener.h', + 'iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/SKObject.h', + 'iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/SKHighlightOverlay.h', + 'iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/UIColor+SKSonarValueCoder.h', + 'iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/utils/SKObjectHash.h', + 'iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/utils/SKSwizzle.h', + 'iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/utils/SKYogaKitHelper.h' + ss.source_files = 'iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutPlugin/**/*.{h,cpp,m,mm}' + end + + spec.subspec "SonarKitLayoutComponentKitSupport" do |ss| + ss.dependency "Yoga", yoga_version + ss.dependency "ComponentKit" + ss.dependency "SonarKit/SonarKitLayoutPlugin" + ss.public_header_files = 'iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutComponentKitSupport/SonarKitLayoutComponentKitSupport.h', + 'iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutComponentKitSupport/SKComponentLayoutWrapper.h' + + ss.source_files = "iOS/Plugins/SonarKitLayoutPlugin/SonarKitLayoutComponentKitSupport/**/*.{h,cpp,m,mm}" + ss.pod_target_xcconfig = { "USE_HEADERMAP" => "NO", + "CLANG_CXX_LANGUAGE_STANDARD" => "c++14", + "HEADER_SEARCH_PATHS" => "\"$(PODS_TARGET_SRCROOT)\"" } + end + + spec.subspec "SonarKitNetworkPlugin" do |ss| + ss.public_header_files = 'iOS/Plugins/SonarKitNetworkPlugin/SonarKitNetworkPlugin/SonarKitNetworkPlugin.h', + 'iOS/Plugins/SonarKitNetworkPlugin/SonarKitNetworkPlugin/SKBufferingPlugin.h', + 'iOS/Plugins/SonarKitNetworkPlugin/SonarKitNetworkPlugin/SKDispatchQueue.h', + 'iOS/Plugins/SonarKitNetworkPlugin/SonarKitNetworkPlugin/SKNetworkReporter.h' + ss.source_files = "iOS/Plugins/SonarKitNetworkPlugin/SonarKitNetworkPlugin/*.{h,cpp,m,mm}" + ss.pod_target_xcconfig = { "USE_HEADERMAP" => "NO", + "CLANG_CXX_LANGUAGE_STANDARD" => "c++14", + "HEADER_SEARCH_PATHS" => "\"$(PODS_TARGET_SRCROOT)\"" } + end + + spec.subspec "SonarKitNetworkPlugin" do |ss| + ss.public_header_files = 'iOS/Plugins/SonarKitNetworkPlugin/SonarKitNetworkPlugin/SonarKitNetworkPlugin.h', + 'iOS/Plugins/SonarKitNetworkPlugin/SonarKitNetworkPlugin/SKBufferingPlugin.h', + 'iOS/Plugins/SonarKitNetworkPlugin/SonarKitNetworkPlugin/SKDispatchQueue.h', + 'iOS/Plugins/SonarKitNetworkPlugin/SonarKitNetworkPlugin/SKNetworkReporter.h' + ss.source_files = "iOS/Plugins/SonarKitNetworkPlugin/SonarKitNetworkPlugin/*.{h,cpp,m,mm}" + ss.pod_target_xcconfig = { "USE_HEADERMAP" => "NO", + "CLANG_CXX_LANGUAGE_STANDARD" => "c++14", + "HEADER_SEARCH_PATHS" => "\"$(PODS_TARGET_SRCROOT)\"" } + end + + spec.subspec "SKIOSNetworkPlugin" do |ss| + ss.dependency 'SonarKit/SonarKitNetworkPlugin' + ss.public_header_files = 'iOS/Plugins/SonarKitNetworkPlugin/SKIOSNetworkPlugin/SKIOSNetworkAdapter.h' + ss.source_files = "iOS/Plugins/SonarKitNetworkPlugin/SKIOSNetworkPlugin/**/*.{h,cpp,m,mm}" + ss.pod_target_xcconfig = { "USE_HEADERMAP" => "NO", + "CLANG_CXX_LANGUAGE_STANDARD" => "c++14", + "HEADER_SEARCH_PATHS" => "\"$(PODS_TARGET_SRCROOT)\"" } + end +end diff --git a/iOS/SonarKit.xcodeproj/project.pbxproj b/iOS/SonarKit.xcodeproj/project.pbxproj new file mode 100644 index 000000000..bbcb046f2 --- /dev/null +++ b/iOS/SonarKit.xcodeproj/project.pbxproj @@ -0,0 +1,668 @@ + + + + + archiveVersion + 1 + classes + + + objectVersion + 46 + objects + + 1DD70E29AEDF69A200000000 + + isa + PBXFileReference + name + SonarKit-Debug.xcconfig + path + ../../buck-out/gen/Libraries/SonarKit/SonarKit-Debug.xcconfig + sourceTree + SOURCE_ROOT + explicitFileType + text.xcconfig + + 1DD70E2959CE208C00000000 + + isa + PBXFileReference + name + SonarKit-Profile.xcconfig + path + ../../buck-out/gen/Libraries/SonarKit/SonarKit-Profile.xcconfig + sourceTree + SOURCE_ROOT + explicitFileType + text.xcconfig + + 1DD70E29CD64CBEE00000000 + + isa + PBXFileReference + name + SonarKit-Release.xcconfig + path + ../../buck-out/gen/Libraries/SonarKit/SonarKit-Release.xcconfig + sourceTree + SOURCE_ROOT + explicitFileType + text.xcconfig + + B401C9792F7F325000000000 + + isa + PBXGroup + name + Buck (Do Not Modify) + sourceTree + ]]> + children + + 1DD70E29AEDF69A200000000 + 1DD70E2959CE208C00000000 + 1DD70E29CD64CBEE00000000 + + + B401C979B781F65D00000000 + + isa + PBXGroup + name + Configurations + sourceTree + ]]> + children + + B401C9792F7F325000000000 + + + 1DD70E291F97291900000000 + + isa + PBXFileReference + name + libSonarKit--916269148.a + path + libSonarKit--916269148.a + sourceTree + BUILT_PRODUCTS_DIR + explicitFileType + archive.ar + + B401C979C806358400000000 + + isa + PBXGroup + name + Products + sourceTree + ]]> + children + + 1DD70E291F97291900000000 + + + 1DD70E29001F47FB00000000 + + isa + PBXFileReference + name + BUCK + path + BUCK + sourceTree + SOURCE_ROOT + explicitFileType + text.script.python + + 1DD70E295D9C4C1E00000000 + + isa + PBXFileReference + name + SonarCppBridgingConnection.h + path + SonarKit/CppBridge/SonarCppBridgingConnection.h + sourceTree + SOURCE_ROOT + lastKnownFileType + sourcecode.c.h + + 1DD70E2955ED38AA00000000 + + isa + PBXFileReference + name + SonarCppBridgingConnection.mm + path + SonarKit/CppBridge/SonarCppBridgingConnection.mm + sourceTree + SOURCE_ROOT + lastKnownFileType + sourcecode.cpp.objcpp + + 1DD70E29B6F151F600000000 + + isa + PBXFileReference + name + SonarCppBridgingResponder.h + path + SonarKit/CppBridge/SonarCppBridgingResponder.h + sourceTree + SOURCE_ROOT + lastKnownFileType + sourcecode.c.h + + 1DD70E292738EDD200000000 + + isa + PBXFileReference + name + SonarCppBridgingResponder.mm + path + SonarKit/CppBridge/SonarCppBridgingResponder.mm + sourceTree + SOURCE_ROOT + lastKnownFileType + sourcecode.cpp.objcpp + + 1DD70E298E830C8000000000 + + isa + PBXFileReference + name + SonarCppWrapperPlugin.h + path + SonarKit/CppBridge/SonarCppWrapperPlugin.h + sourceTree + SOURCE_ROOT + lastKnownFileType + sourcecode.c.h + + B401C979DC3E2AEC00000000 + + isa + PBXGroup + name + CppBridge + path + SonarKit/CppBridge + sourceTree + SOURCE_ROOT + children + + 1DD70E295D9C4C1E00000000 + 1DD70E2955ED38AA00000000 + 1DD70E29B6F151F600000000 + 1DD70E292738EDD200000000 + 1DD70E298E830C8000000000 + + + 1DD70E29978C461B00000000 + + isa + PBXFileReference + name + SKPortForwardingCommon.h + path + SonarKit/Utilities/PortForwarding/SKPortForwardingCommon.h + sourceTree + SOURCE_ROOT + lastKnownFileType + sourcecode.c.h + + 1DD70E290DA3557300000000 + + isa + PBXFileReference + name + SKPortForwardingServer.h + path + SonarKit/Utilities/PortForwarding/SKPortForwardingServer.h + sourceTree + SOURCE_ROOT + lastKnownFileType + sourcecode.c.h + + 1DD70E290DA3557800000000 + + isa + PBXFileReference + name + SKPortForwardingServer.m + path + SonarKit/Utilities/PortForwarding/SKPortForwardingServer.m + sourceTree + SOURCE_ROOT + lastKnownFileType + sourcecode.c.objc + + B401C9797FE3A67E00000000 + + isa + PBXGroup + name + PortForwarding + path + SonarKit/Utilities/PortForwarding + sourceTree + SOURCE_ROOT + children + + 1DD70E29978C461B00000000 + 1DD70E290DA3557300000000 + 1DD70E290DA3557800000000 + + + B401C979BD78D6EA00000000 + + isa + PBXGroup + name + Utilities + path + SonarKit/Utilities + sourceTree + SOURCE_ROOT + children + + B401C9797FE3A67E00000000 + + + 1DD70E299D3D8CD900000000 + + isa + PBXFileReference + name + SKMacros.h + path + SonarKit/SKMacros.h + sourceTree + SOURCE_ROOT + lastKnownFileType + sourcecode.c.h + + 1DD70E29DD8668F300000000 + + isa + PBXFileReference + name + SKUtils.h + path + SonarKit/SKUtils.h + sourceTree + SOURCE_ROOT + lastKnownFileType + sourcecode.c.h + + 1DD70E29D346B67500000000 + + isa + PBXFileReference + name + SKUtils.mm + path + SonarKit/SKUtils.mm + sourceTree + SOURCE_ROOT + lastKnownFileType + sourcecode.cpp.objcpp + + 1DD70E297513814800000000 + + isa + PBXFileReference + name + SonarClient.h + path + SonarKit/SonarClient.h + sourceTree + SOURCE_ROOT + lastKnownFileType + sourcecode.c.h + + 1DD70E292D5CA8C000000000 + + isa + PBXFileReference + name + SonarClient.mm + path + SonarKit/SonarClient.mm + sourceTree + SOURCE_ROOT + lastKnownFileType + sourcecode.cpp.objcpp + + 1DD70E29D967BA1B00000000 + + isa + PBXFileReference + name + SonarConnection.h + path + SonarKit/SonarConnection.h + sourceTree + SOURCE_ROOT + lastKnownFileType + sourcecode.c.h + + 1DD70E29D016C2B000000000 + + isa + PBXFileReference + name + SonarPlugin.h + path + SonarKit/SonarPlugin.h + sourceTree + SOURCE_ROOT + lastKnownFileType + sourcecode.c.h + + 1DD70E29C331B05900000000 + + isa + PBXFileReference + name + SonarResponder.h + path + SonarKit/SonarResponder.h + sourceTree + SOURCE_ROOT + lastKnownFileType + sourcecode.c.h + + 1DD70E2969DE008400000000 + + isa + PBXFileReference + name + SonarUtil.m + path + SonarKit/SonarUtil.m + sourceTree + SOURCE_ROOT + lastKnownFileType + sourcecode.c.objc + + B401C979EAB5339800000000 + + isa + PBXGroup + name + Sources + sourceTree + ]]> + children + + B401C979DC3E2AEC00000000 + B401C979BD78D6EA00000000 + 1DD70E299D3D8CD900000000 + 1DD70E29DD8668F300000000 + 1DD70E29D346B67500000000 + 1DD70E297513814800000000 + 1DD70E292D5CA8C000000000 + 1DD70E29D967BA1B00000000 + 1DD70E29D016C2B000000000 + 1DD70E29C331B05900000000 + 1DD70E2969DE008400000000 + + + B401C9795F1632B300000000 + + isa + PBXGroup + name + SonarKit + sourceTree + ]]> + children + + 1DD70E29001F47FB00000000 + B401C979EAB5339800000000 + + + B401C979EFB6AC4600000000 + + isa + PBXGroup + name + mainGroup + sourceTree + ]]> + children + + B401C979B781F65D00000000 + B401C979C806358400000000 + B401C9795F1632B300000000 + + + E7A30F0455ED38AA00000000 + + isa + PBXBuildFile + fileRef + 1DD70E2955ED38AA00000000 + settings + + COMPILER_FLAGS + -stdlib=libc++ -D_LIBCPP_HAS_NO_STRONG_ENUMS=1 + + + E7A30F042738EDD200000000 + + isa + PBXBuildFile + fileRef + 1DD70E292738EDD200000000 + settings + + COMPILER_FLAGS + -stdlib=libc++ -D_LIBCPP_HAS_NO_STRONG_ENUMS=1 + + + E7A30F040DA3557800000000 + + isa + PBXBuildFile + fileRef + 1DD70E290DA3557800000000 + settings + + COMPILER_FLAGS + -stdlib=libc++ -D_LIBCPP_HAS_NO_STRONG_ENUMS=1 + + + E7A30F04D346B67500000000 + + isa + PBXBuildFile + fileRef + 1DD70E29D346B67500000000 + settings + + COMPILER_FLAGS + -stdlib=libc++ -D_LIBCPP_HAS_NO_STRONG_ENUMS=1 + + + E7A30F042D5CA8C000000000 + + isa + PBXBuildFile + fileRef + 1DD70E292D5CA8C000000000 + settings + + COMPILER_FLAGS + -stdlib=libc++ -D_LIBCPP_HAS_NO_STRONG_ENUMS=1 + + + E7A30F0469DE008400000000 + + isa + PBXBuildFile + fileRef + 1DD70E2969DE008400000000 + settings + + COMPILER_FLAGS + -stdlib=libc++ -D_LIBCPP_HAS_NO_STRONG_ENUMS=1 + + + 1870857F0000000000000000 + + isa + PBXSourcesBuildPhase + files + + E7A30F0455ED38AA00000000 + E7A30F042738EDD200000000 + E7A30F040DA3557800000000 + E7A30F04D346B67500000000 + E7A30F042D5CA8C000000000 + E7A30F0469DE008400000000 + + + 4952437303EDA63300000000 + + isa + XCBuildConfiguration + name + Debug + buildSettings + + + baseConfigurationReference + 1DD70E29AEDF69A200000000 + + 4952437350C7218900000000 + + isa + XCBuildConfiguration + name + Profile + buildSettings + + + baseConfigurationReference + 1DD70E2959CE208C00000000 + + 49524373A439BFE700000000 + + isa + XCBuildConfiguration + name + Release + buildSettings + + + baseConfigurationReference + 1DD70E29CD64CBEE00000000 + + 218C37090000000000000000 + + isa + XCConfigurationList + buildConfigurations + + 4952437303EDA63300000000 + 4952437350C7218900000000 + 49524373A439BFE700000000 + + defaultConfigurationIsVisible + + + E66DC04E5F1632B300000000 + + isa + PBXNativeTarget + name + SonarKit + productName + SonarKit--916269148 + productReference + 1DD70E291F97291900000000 + productType + com.apple.product-type.library.static + dependencies + + + buildPhases + + 1870857F0000000000000000 + + buildConfigurationList + 218C37090000000000000000 + + 4952437303EDA63300000001 + + isa + XCBuildConfiguration + name + Debug + buildSettings + + + + 4952437350C7218900000001 + + isa + XCBuildConfiguration + name + Profile + buildSettings + + + + 49524373A439BFE700000001 + + isa + XCBuildConfiguration + name + Release + buildSettings + + + + 218C37090000000000000001 + + isa + XCConfigurationList + buildConfigurations + + 4952437303EDA63300000001 + 4952437350C7218900000001 + 49524373A439BFE700000001 + + defaultConfigurationIsVisible + + + 96C847935F1632B300000000 + + isa + PBXProject + mainGroup + B401C979EFB6AC4600000000 + targets + + E66DC04E5F1632B300000000 + + buildConfigurationList + 218C37090000000000000001 + compatibilityVersion + Xcode 3.2 + attributes + + LastUpgradeCheck + 9999 + + + + rootObject + 96C847935F1632B300000000 + + \ No newline at end of file diff --git a/iOS/SonarKit/CppBridge/SonarCppBridgingConnection.h b/iOS/SonarKit/CppBridge/SonarCppBridgingConnection.h new file mode 100644 index 000000000..bafbee945 --- /dev/null +++ b/iOS/SonarKit/CppBridge/SonarCppBridgingConnection.h @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2004-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +#import +#import + +/** +SonarCppBridgingConnection is a simple ObjC wrapper around SonarConnection +that forwards messages to the underlying C++ connection. This class allows +pure Objective-C plugins to send messages to the underlying connection. +*/ +@interface SonarCppBridgingConnection : NSObject +- (instancetype)initWithCppConnection:(std::shared_ptr)conn; +@end diff --git a/iOS/SonarKit/CppBridge/SonarCppBridgingConnection.mm b/iOS/SonarKit/CppBridge/SonarCppBridgingConnection.mm new file mode 100644 index 000000000..031cdbca7 --- /dev/null +++ b/iOS/SonarKit/CppBridge/SonarCppBridgingConnection.mm @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +#import "SonarCppBridgingConnection.h" + +#import + +#import "SonarCppBridgingResponder.h" + +@implementation SonarCppBridgingConnection +{ + std::shared_ptr conn_; +} + +- (instancetype)initWithCppConnection:(std::shared_ptr)conn +{ + if (self = [super init]) { + conn_ = conn; + } + return self; +} + +#pragma mark - SonarConnection + +- (void)send:(NSString *)method withParams:(NSDictionary *)params +{ + conn_->send([method UTF8String], facebook::cxxutils::convertIdToFollyDynamic(params)); +} + +- (void)receive:(NSString *)method withBlock:(SonarReceiver)receiver +{ + const auto lambda = [receiver](const folly::dynamic &message, + std::unique_ptr responder) { + SonarCppBridgingResponder *const objCResponder = + [[SonarCppBridgingResponder alloc] initWithCppResponder:std::move(responder)]; + receiver(facebook::cxxutils::convertFollyDynamicToId(message), objCResponder); + }; + conn_->receive([method UTF8String], lambda); +} + +@end diff --git a/iOS/SonarKit/CppBridge/SonarCppBridgingResponder.h b/iOS/SonarKit/CppBridge/SonarCppBridgingResponder.h new file mode 100644 index 000000000..a9f9e6948 --- /dev/null +++ b/iOS/SonarKit/CppBridge/SonarCppBridgingResponder.h @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +#import +#import + +/** +SonarCppBridgingResponder is a simple ObjC wrapper around SonarResponder +that forwards messages to the underlying C++ responder. This class allows +pure Objective-C plugins to send messages to the underlying responder. +*/ +@interface SonarCppBridgingResponder : NSObject +- (instancetype)initWithCppResponder:(std::unique_ptr)responder; +@end diff --git a/iOS/SonarKit/CppBridge/SonarCppBridgingResponder.mm b/iOS/SonarKit/CppBridge/SonarCppBridgingResponder.mm new file mode 100644 index 000000000..0b3714fb4 --- /dev/null +++ b/iOS/SonarKit/CppBridge/SonarCppBridgingResponder.mm @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +#import "SonarCppBridgingResponder.h" + +#import + +@implementation SonarCppBridgingResponder { + std::unique_ptr responder_; +} + +- (instancetype)initWithCppResponder:(std::unique_ptr)responder +{ + if (!responder) { + return nil; + } + + if (self = [super init]) { + responder_ = std::move(responder); + } + + return self; +} + +#pragma mark - SonarResponder + +- (void)success:(NSDictionary *)response { responder_->success(facebook::cxxutils::convertIdToFollyDynamic(response)); } + +- (void)error:(NSDictionary *)response { responder_->error(facebook::cxxutils::convertIdToFollyDynamic(response)); } + +@end diff --git a/iOS/SonarKit/CppBridge/SonarCppWrapperPlugin.h b/iOS/SonarKit/CppBridge/SonarCppWrapperPlugin.h new file mode 100644 index 000000000..bf5db01fc --- /dev/null +++ b/iOS/SonarKit/CppBridge/SonarCppWrapperPlugin.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +#ifndef __OBJC__ +#error This header can only be included in .mm (ObjC++) files +#endif + +#import +#import +#import + +namespace facebook { +namespace sonar { + +using ObjCPlugin = NSObject *; + +/** +SonarCppWrapperPlugin is a simple C++ wrapper around Objective-C Sonar plugins +that can be passed to SonarClient. This class allows developers to write pure +Objective-C plugins if they want. +*/ +class SonarCppWrapperPlugin final : public facebook::sonar::SonarPlugin { +public: + // Under ARC copying objCPlugin *does* increment its retain count + SonarCppWrapperPlugin(ObjCPlugin objCPlugin) : _objCPlugin(objCPlugin) {} + + std::string identifier() const override { return [[_objCPlugin identifier] UTF8String]; } + + void didConnect(std::shared_ptr conn) override + { + SonarCppBridgingConnection *const bridgingConn = [[SonarCppBridgingConnection alloc] initWithCppConnection:conn]; + [_objCPlugin didConnect:bridgingConn]; + } + + void didDisconnect() override { [_objCPlugin didDisconnect]; } + + ObjCPlugin getObjCPlugin() { return _objCPlugin; } + +private: + ObjCPlugin _objCPlugin; +}; + +} // namespace sonar +} // namespace facebook diff --git a/iOS/SonarKit/FBDefines/FBMacros.h b/iOS/SonarKit/FBDefines/FBMacros.h new file mode 100644 index 000000000..68d86b082 --- /dev/null +++ b/iOS/SonarKit/FBDefines/FBMacros.h @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2004-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +#ifndef FB_SK_MACROS_H + #define FB_SK_MACROS_H + + #define FB_LINK_REQUIRE_(NAME, UNIQUE) + #define FB_LINKABLE(NAME) + #define FB_LINK_REQUIRE(NAME) + #define FB_LINK_REQUIRE_EXT(NAME) + +#endif diff --git a/iOS/SonarKit/SKMacros.h b/iOS/SonarKit/SKMacros.h new file mode 100644 index 000000000..9b21bf1ea --- /dev/null +++ b/iOS/SonarKit/SKMacros.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2004-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ + + #ifndef SKMACROS_H + #define SKMACROS_H + + #import + + #ifdef __cplusplus + # define SK_EXTERN_C_BEGIN extern "C" { + # define SK_EXTERN_C_END } + # define SK_EXTERN_C extern "C" + #else + # define SK_EXTERN_C_BEGIN + # define SK_EXTERN_C_END + # define SK_EXTERN_C extern + #endif + + #define SKLog(...) NSLog(__VA_ARGS__) + #define SKTrace(...) /*NSLog(__VA_ARGS__)*/ + +#endif diff --git a/iOS/SonarKit/SonarClient.h b/iOS/SonarKit/SonarClient.h new file mode 100644 index 000000000..a3fc4b9f5 --- /dev/null +++ b/iOS/SonarKit/SonarClient.h @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +#import + +#import "SonarPlugin.h" + +/** +Represents a connection between the Sonar desktop och client side. Manages the lifecycle of attached +plugin instances. +*/ +@interface SonarClient : NSObject + +/** +The shared singleton SonarClient instance. It is an error to call this on non-debug builds to avoid leaking data. +*/ ++ (instancetype)sharedClient; + +/** +Register a plugin with the client. +*/ +- (void)addPlugin:(NSObject *)plugin; + +/** +Unregister a plugin with the client. +*/ +- (void)removePlugin:(NSObject *)plugin; + +/** +Retrieve the plugin with a given identifier which was previously registered with this client. +*/ +- (NSObject *)pluginWithIdentifier:(NSString *)identifier; + +/** +Establish a connection to the Sonar desktop. +*/ +- (void)start; + +/** +Stop the connection to the Sonar desktop. +*/ +- (void)stop; + +// initializers are disabled. You must use `+[SonarClient sharedClient]` instance. +- (instancetype)init NS_UNAVAILABLE; ++ (instancetype)new NS_UNAVAILABLE; + +@end diff --git a/iOS/SonarKit/SonarClient.mm b/iOS/SonarKit/SonarClient.mm new file mode 100644 index 000000000..8f8834be3 --- /dev/null +++ b/iOS/SonarKit/SonarClient.mm @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +#if FB_SONARKIT_ENABLED + +#import "SonarClient.h" +#import "SonarCppWrapperPlugin.h" +#import +#include +#include +#import + +#if !TARGET_OS_SIMULATOR +#import "SKPortForwardingServer.h" +#endif + +using WrapperPlugin = facebook::sonar::SonarCppWrapperPlugin; + +@implementation SonarClient { + facebook::sonar::SonarClient *_cppClient; + folly::ScopedEventBaseThread eventBaseThread; +#if !TARGET_OS_SIMULATOR + SKPortForwardingServer *_server; +#endif +} + ++ (instancetype)sharedClient +{ + static SonarClient *sharedClient = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + sharedClient = [[self alloc] init]; + }); + return sharedClient; +} + +- (instancetype)init +{ + if (self = [super init]) { + UIDevice *device = [UIDevice currentDevice]; + NSString *deviceName = [device name]; + NSString *appName = [[NSBundle mainBundle] objectForInfoDictionaryKey:(NSString *)kCFBundleNameKey]; + NSString *deviceId = [[device identifierForVendor]UUIDString]; + NSString *appId = appName; + NSString *privateAppDirectory = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES)[0]; + +#if TARGET_OS_SIMULATOR + deviceName = [NSString stringWithFormat:@"%@ %@", [[UIDevice currentDevice] model], @"Simulator"]; +#endif + + facebook::sonar::SonarClient::init({ + { + "localhost", + "iOS", + [deviceName UTF8String], + [deviceId UTF8String], + [appName UTF8String], + [appId UTF8String], + [privateAppDirectory UTF8String], + }, + eventBaseThread.getEventBase(), + }); + _cppClient = facebook::sonar::SonarClient::instance(); + } + return self; +} + +- (void)refreshPlugins +{ + _cppClient->refreshPlugins(); +} + +- (void)addPlugin:(NSObject *)plugin +{ + _cppClient->addPlugin(std::make_shared(plugin)); +} + +- (void)removePlugin:(NSObject *)plugin +{ + _cppClient->removePlugin(std::make_shared(plugin)); +} + +- (NSObject *)pluginWithIdentifier:(NSString *)identifier +{ + auto cppPlugin = _cppClient->getPlugin([identifier UTF8String]); + if (auto wrapper = dynamic_cast(cppPlugin.get())) { + return wrapper->getObjCPlugin(); + } + return nil; +} + +- (void)start; +{ +#if !TARGET_OS_SIMULATOR + _server = [SKPortForwardingServer new]; + [_server forwardConnectionsFromPort:8088]; + [_server listenForMultiplexingChannelOnPort:8078]; +#endif + _cppClient->start(); +} + +- (void)stop +{ + _cppClient->stop(); +#if !TARGET_OS_SIMULATOR + [_server close]; + _server = nil; +#endif +} + +@end + +#endif diff --git a/iOS/SonarKit/SonarConnection.h b/iOS/SonarKit/SonarConnection.h new file mode 100644 index 000000000..ddf009d1e --- /dev/null +++ b/iOS/SonarKit/SonarConnection.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +#import + +@protocol SonarResponder; +@protocol SonarWebSocket; + +typedef void (^SonarReceiver)(NSDictionary*, id); + +/** +Represents a connection between the Desktop and mobile plugins with corresponding identifiers. +*/ +@protocol SonarConnection + +/** +Invoke a method on the Sonar desktop plugin with with a matching identifier. +*/ +- (void)send:(NSString *)method withParams:(NSDictionary *)params; + +/** +Register a receiver to be notified of incoming calls of the given method from the Sonar desktop +plugin with a matching identifier. +*/ +- (void)receive:(NSString *)method withBlock:(SonarReceiver)receiver; + +@end diff --git a/iOS/SonarKit/SonarPlugin.h b/iOS/SonarKit/SonarPlugin.h new file mode 100644 index 000000000..b82092f41 --- /dev/null +++ b/iOS/SonarKit/SonarPlugin.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2004-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ + +#import +#import "SKMacros.h" + +SK_EXTERN_C_BEGIN +void SonarPerformBlockOnMainThread(void(^block)()); +SK_EXTERN_C_END + +@protocol SonarConnection; + +@protocol SonarPlugin + +/** +The plugin's identifier. This should map to a javascript plugin with the same identifier to ensure +messages are sent correctly. +*/ +- (NSString *)identifier; + +/** +Called when a connection has been established between this plugin and the corresponding plugin on +the Sonar desktop app. The provided connection can be used to register method receivers as well +as send messages back to the desktop app. +*/ +- (void)didConnect:(id)connection; + +/** +Called when a plugin has been disconnected and the SonarConnection provided in didConnect is no +longer valid to use. +*/ +- (void)didDisconnect; + +@end diff --git a/iOS/SonarKit/SonarResponder.h b/iOS/SonarKit/SonarResponder.h new file mode 100644 index 000000000..eeea2a0cd --- /dev/null +++ b/iOS/SonarKit/SonarResponder.h @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +#import + +/** +Acts as a hook for providing return values to remote called from Sonar desktop plugins. +*/ +@protocol SonarResponder + +/** +Respond with a successful return value. +*/ +- (void)success:(NSDictionary *)response; + +/** +Respond with an error. +*/ +- (void)error:(NSDictionary *)response; + +@end diff --git a/iOS/SonarKit/SonarUtil.m b/iOS/SonarKit/SonarUtil.m new file mode 100644 index 000000000..73234e41a --- /dev/null +++ b/iOS/SonarKit/SonarUtil.m @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +#import +#import "SonarPlugin.h" + +void SonarPerformBlockOnMainThread(void(^block)()) +{ + if ([NSThread isMainThread]) { + block(); + } else { + dispatch_async(dispatch_get_main_queue(), block); + } +} diff --git a/iOS/SonarKit/Utilities/PortForwarding/SKPortForwardingCommon.h b/iOS/SonarKit/Utilities/PortForwarding/SKPortForwardingCommon.h new file mode 100644 index 000000000..13630dc81 --- /dev/null +++ b/iOS/SonarKit/Utilities/PortForwarding/SKPortForwardingCommon.h @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +#import + +enum { + SKPortForwardingFrameTypeOpenPipe = 201, + SKPortForwardingFrameTypeWriteToPipe = 202, + SKPortForwardingFrameTypeClosePipe = 203, +}; + +static dispatch_data_t NSDataToGCDData(NSData *data) { + __block NSData *retainedData = data; + return dispatch_data_create(data.bytes, data.length, nil, ^{ + retainedData = nil; + }); +} diff --git a/iOS/SonarKit/Utilities/PortForwarding/SKPortForwardingServer.h b/iOS/SonarKit/Utilities/PortForwarding/SKPortForwardingServer.h new file mode 100644 index 000000000..72d4514a7 --- /dev/null +++ b/iOS/SonarKit/Utilities/PortForwarding/SKPortForwardingServer.h @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +#import + +@interface SKPortForwardingServer : NSObject + +- (instancetype)init; + +- (void)listenForMultiplexingChannelOnPort:(NSUInteger)port; +- (void)forwardConnectionsFromPort:(NSUInteger)port; +- (void)close; + +@end diff --git a/iOS/SonarKit/Utilities/PortForwarding/SKPortForwardingServer.m b/iOS/SonarKit/Utilities/PortForwarding/SKPortForwardingServer.m new file mode 100644 index 000000000..7bb61075a --- /dev/null +++ b/iOS/SonarKit/Utilities/PortForwarding/SKPortForwardingServer.m @@ -0,0 +1,190 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +#import "SKPortForwardingServer.h" + +#import + +#import +#import + +#import "SKMacros.h" +#import "SKPortForwardingCommon.h" + +@interface SKPortForwardingServer () + +@property (nonatomic, weak) PTChannel *serverChannel; +@property (nonatomic, weak) PTChannel *peerChannel; + +@property (nonatomic, strong) GCDAsyncSocket *serverSocket; +@property (nonatomic, strong) NSMutableDictionary *clientSockets; +@property (nonatomic, assign) UInt32 lastClientSocketTag; +@property (nonatomic, strong) dispatch_queue_t socketQueue; +@property (nonatomic, strong) PTProtocol *protocol; + +@end + +@implementation SKPortForwardingServer + +- (instancetype)init +{ + if (self = [super init]) { + _socketQueue = dispatch_queue_create("SKPortForwardingServer", DISPATCH_QUEUE_SERIAL); + _lastClientSocketTag = 0; + _clientSockets = [NSMutableDictionary dictionary]; + _protocol = [[PTProtocol alloc] initWithDispatchQueue:_socketQueue]; + } + return self; +} + +- (void)dealloc +{ + [self close]; + [[NSNotificationCenter defaultCenter] removeObserver:self]; +} + +- (void)forwardConnectionsFromPort:(NSUInteger)port +{ + [self _forwardConnectionsFromPort:port reportError:YES]; + [[NSNotificationCenter defaultCenter] addObserverForName:UIApplicationDidBecomeActiveNotification object:nil queue:nil usingBlock:^(NSNotification *note) { + [self _forwardConnectionsFromPort:port reportError:NO]; + }]; +} + +- (void)_forwardConnectionsFromPort:(NSUInteger)port reportError:(BOOL)shouldReportError +{ + GCDAsyncSocket *serverSocket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:_socketQueue]; + NSError *listenError; + if ([serverSocket acceptOnPort:port error:&listenError]) { + self.serverSocket = serverSocket; + } else { + if (shouldReportError) { + SKLog(@"Failed to listen: %@", listenError); + } + } +} + +- (void)listenForMultiplexingChannelOnPort:(NSUInteger)port +{ + [self _listenForMultiplexingChannelOnPort:port reportError:YES]; + [[NSNotificationCenter defaultCenter] addObserverForName:UIApplicationDidBecomeActiveNotification object:nil queue:nil usingBlock:^(NSNotification *note) { + [self _listenForMultiplexingChannelOnPort:port reportError:NO]; + }]; +} + +- (void)_listenForMultiplexingChannelOnPort:(NSUInteger)port reportError:(BOOL)shouldReportError +{ + PTChannel *channel = [[PTChannel alloc] initWithProtocol:_protocol delegate:self]; + [channel listenOnPort:port IPv4Address:INADDR_LOOPBACK callback:^(NSError *error) { + if (error) { + if (shouldReportError) { + SKLog(@"Failed to listen on 127.0.0.1:%lu: %@", (unsigned long)port, error); + } + } else { + SKTrace(@"Listening on 127.0.0.1:%lu", (unsigned long)port); + self.serverChannel = channel; + } + }]; +} + +- (void)close +{ + if (self.serverChannel) { + [self.serverChannel close]; + self.serverChannel = nil; + } + [self.serverSocket disconnect]; +} + +#pragma mark - PTChannelDelegate + +- (void)ioFrameChannel:(PTChannel *)channel didAcceptConnection:(PTChannel *)otherChannel fromAddress:(PTAddress *)address { + // Cancel any other connection. We are FIFO, so the last connection + // established will cancel any previous connection and "take its place". + if (self.peerChannel) { + [self.peerChannel cancel]; + } + + // Weak pointer to current connection. Connection objects live by themselves + // (owned by its parent dispatch queue) until they are closed. + self.peerChannel = otherChannel; + self.peerChannel.userInfo = address; + SKTrace(@"Connected to %@", address); +} + +- (void)ioFrameChannel:(PTChannel *)channel didReceiveFrameOfType:(uint32_t)type tag:(uint32_t)tag payload:(PTData *)payload { + //NSLog(@"didReceiveFrameOfType: %u, %u, %@", type, tag, payload); + if (type == SKPortForwardingFrameTypeWriteToPipe) { + GCDAsyncSocket *sock = self.clientSockets[@(tag)]; + [sock writeData:[NSData dataWithBytes:payload.data length:payload.length] withTimeout:-1 tag:0]; + SKTrace(@"channel -> socket (%d), %zu bytes", tag, payload.length); + } + + if (type == SKPortForwardingFrameTypeClosePipe) { + GCDAsyncSocket *sock = self.clientSockets[@(tag)]; + [sock disconnectAfterWriting]; + } +} + +- (void)ioFrameChannel:(PTChannel *)channel didEndWithError:(NSError *)error { + for (GCDAsyncSocket *sock in [_clientSockets objectEnumerator]) { + [sock setDelegate:nil]; + [sock disconnect]; + } + [self.clientSockets removeAllObjects]; + SKTrace(@"Disconnected from %@, error = %@", channel.userInfo, error); +} + + +#pragma mark - GCDAsyncSocketDelegate + +- (void)socket:(GCDAsyncSocket *)sock didAcceptNewSocket:(GCDAsyncSocket *)newSocket +{ + dispatch_block_t block = ^() { + if (!self.peerChannel) { + [newSocket setDelegate:nil]; + [newSocket disconnect]; + } + + UInt32 tag = ++self->_lastClientSocketTag; + newSocket.userData = @(tag); + newSocket.delegate = self; + self.clientSockets[@(tag)] = newSocket; + [self.peerChannel sendFrameOfType:SKPortForwardingFrameTypeOpenPipe tag:self->_lastClientSocketTag withPayload:nil callback:^(NSError *error) { + SKTrace(@"open socket (%d), error = %@", (unsigned int)tag, error); + [newSocket readDataWithTimeout:-1 tag:0]; + }]; + }; + + if (_peerChannel) { + block(); + } else { + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), _socketQueue, block); + } +} + +- (void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)_ +{ + UInt32 tag = [[sock userData] unsignedIntValue]; + SKTrace(@"Incoming data on socket (%d) - %lu bytes", (unsigned int)tag, (unsigned long)data.length); + [_peerChannel sendFrameOfType:SKPortForwardingFrameTypeWriteToPipe tag:tag withPayload:NSDataToGCDData(data) callback:^(NSError *error) { + SKTrace(@"socket (%d) -> channel %lu bytes, error = %@", (unsigned int)tag, (unsigned long)data.length, error); + [sock readDataWithTimeout:-1 tag:_]; + }]; +} + +- (void)socketDidDisconnect:(GCDAsyncSocket *)sock withError:(NSError *)err +{ + UInt32 tag = [sock.userData unsignedIntValue]; + [_clientSockets removeObjectForKey:@(tag)]; + [_peerChannel sendFrameOfType:SKPortForwardingFrameTypeClosePipe tag:tag withPayload:nil callback:^(NSError *error) { + SKTrace(@"socket (%d) disconnected, err = %@, peer error = %@", (unsigned int)tag, err, error); + }]; +} + + +@end diff --git a/iOS/SonarKitTestUtils/BlockBasedSonarPlugin.h b/iOS/SonarKitTestUtils/BlockBasedSonarPlugin.h new file mode 100644 index 000000000..1810560a1 --- /dev/null +++ b/iOS/SonarKitTestUtils/BlockBasedSonarPlugin.h @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +#import + +#import + +@protocol SonarConnection; + +typedef void (^ConnectBlock)(id); +typedef void (^DisconnectBlock)(); + +@interface BlockBasedSonarPlugin : NSObject + +- (instancetype)initIdentifier:(NSString *)identifier connect:(ConnectBlock)connect disconnect:(DisconnectBlock)disconnect; + +@end diff --git a/iOS/SonarKitTestUtils/BlockBasedSonarPlugin.m b/iOS/SonarKitTestUtils/BlockBasedSonarPlugin.m new file mode 100644 index 000000000..3de673ef0 --- /dev/null +++ b/iOS/SonarKitTestUtils/BlockBasedSonarPlugin.m @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +#import "BlockBasedSonarPlugin.h" + +@implementation BlockBasedSonarPlugin +{ + NSString *_identifier; + ConnectBlock _connect; + DisconnectBlock _disconnect; +} + +- (instancetype)initIdentifier:(NSString *)identifier connect:(ConnectBlock)connect disconnect:(DisconnectBlock)disconnect +{ + if (self = [super init]) { + _identifier = identifier; + _connect = connect; + _disconnect = disconnect; + } + return self; +} + +- (NSString *)identifier +{ + return _identifier; +} + +- (void)didConnect:(id)connection +{ + if (_connect) { + _connect(connection); + } +} + +- (void)didDisconnect +{ + if (_connect) { + _disconnect(); + } +} + +@end diff --git a/iOS/SonarKitTestUtils/SonarClient+Testing.h b/iOS/SonarKitTestUtils/SonarClient+Testing.h new file mode 100644 index 000000000..b2314e880 --- /dev/null +++ b/iOS/SonarKitTestUtils/SonarClient+Testing.h @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +#ifndef __cplusplus +#error This header can only be included in .mm (ObjC++) files +#endif + +#import + +#import +#import + +@interface SonarClient (Testing) + +- (instancetype)initWithCppClient:(facebook::sonar::SonarClient *)cppClient; + +@end diff --git a/iOS/SonarKitTestUtils/SonarConnectionMock.h b/iOS/SonarKitTestUtils/SonarConnectionMock.h new file mode 100644 index 000000000..750a6a7c0 --- /dev/null +++ b/iOS/SonarKitTestUtils/SonarConnectionMock.h @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +#import + +#import + +@interface SonarConnectionMock : NSObject + +@property (nonatomic, assign, getter=isConnected) BOOL connected; +@property (nonatomic, readonly) NSDictionary *receivers; +@property (nonatomic, readonly) NSDictionary *> *sent; + +@end diff --git a/iOS/SonarKitTestUtils/SonarConnectionMock.m b/iOS/SonarKitTestUtils/SonarConnectionMock.m new file mode 100644 index 000000000..64f8c2eba --- /dev/null +++ b/iOS/SonarKitTestUtils/SonarConnectionMock.m @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +#import "SonarConnectionMock.h" + +@implementation SonarConnectionMock + +- (instancetype)init +{ + if (self = [super init]) { + _connected = YES; + _receivers = @{}; + _sent = @{}; + } + return self; +} + + +- (void)send:(NSString *)method withParams:(NSDictionary *)params +{ + if (_connected) { + NSMutableDictionary *newSent = [NSMutableDictionary new]; + [newSent addEntriesFromDictionary:_sent]; + if (newSent[method]) { + newSent[method] = [_sent[method] arrayByAddingObject:params]; + } else { + newSent[method] = @[params]; + } + _sent = newSent; + } +} + +- (void)receive:(NSString *)method withBlock:(SonarReceiver)receiver +{ + if (_connected) { + NSMutableDictionary *newReceivers = [NSMutableDictionary new]; + [newReceivers addEntriesFromDictionary:_receivers]; + newReceivers[method] = receiver; + _receivers = newReceivers; + } +} + +@end diff --git a/iOS/SonarKitTestUtils/SonarResponderMock.h b/iOS/SonarKitTestUtils/SonarResponderMock.h new file mode 100644 index 000000000..d3e50fc91 --- /dev/null +++ b/iOS/SonarKitTestUtils/SonarResponderMock.h @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +#import + +#import + +@interface SonarResponderMock : NSObject + +@property (nonatomic, readonly) NSArray *successes; +@property (nonatomic, readonly) NSArray *errors; + +@end diff --git a/iOS/SonarKitTestUtils/SonarResponderMock.m b/iOS/SonarKitTestUtils/SonarResponderMock.m new file mode 100644 index 000000000..bc2c5769d --- /dev/null +++ b/iOS/SonarKitTestUtils/SonarResponderMock.m @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +#import "SonarResponderMock.h" + +@implementation SonarResponderMock + +- (instancetype)init +{ + if (self = [super init]) { + _successes = @[]; + _errors = @[]; + } + return self; +} + +- (void)success:(NSDictionary *)response +{ + _successes = [_successes arrayByAddingObject:response]; +} + +- (void)error:(NSDictionary *)response +{ + _errors = [_errors arrayByAddingObject:response]; +} + +@end diff --git a/iOS/SonarKitTests/SonarCppBridgingTests.mm b/iOS/SonarKitTests/SonarCppBridgingTests.mm new file mode 100644 index 000000000..1d28998d4 --- /dev/null +++ b/iOS/SonarKitTests/SonarCppBridgingTests.mm @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +#import + +#if FB_SONARKIT_ENABLED + +#import +#import + +using facebook::sonar::SonarCppWrapperPlugin; + +@interface DummyPlugin : NSObject +@end + +@implementation DummyPlugin +- (NSString *)identifier { return @"Dummy"; } +- (void)didConnect:(id)connection {} +- (void)didDisconnect {} +@end + +@interface SonarCppBridgingTests : XCTestCase +@end + +@implementation SonarCppBridgingTests + +- (void)testCppWrapperRetainsObjCPlugin { + NSObject *dummyPlugin = [DummyPlugin new]; + auto retainCountBefore = CFGetRetainCount((void *)dummyPlugin); + SonarCppWrapperPlugin wrapperPlugin(dummyPlugin); + auto retainCountAfter = CFGetRetainCount((void *)dummyPlugin); + XCTAssertTrue(retainCountAfter > retainCountBefore); +} + +@end + +#endif diff --git a/iOS/scripts/ios-configure-glog.sh b/iOS/scripts/ios-configure-glog.sh new file mode 100644 index 000000000..e6a15febb --- /dev/null +++ b/iOS/scripts/ios-configure-glog.sh @@ -0,0 +1,41 @@ +#!/bin/bash +set -e + +PLATFORM_NAME="${PLATFORM_NAME:-iphoneos}" +CURRENT_ARCH="${CURRENT_ARCH:-armv7}" + +export CC="$(xcrun -find -sdk $PLATFORM_NAME cc) -arch $CURRENT_ARCH -isysroot $(xcrun -sdk $PLATFORM_NAME --show-sdk-path)" +export CXX="$CC" + +# Remove automake symlink if it exists +if [ -h "test-driver" ]; then + rm test-driver +fi + +./configure --host arm-apple-darwin + +# Fix build for tvOS +cat << EOF >> src/config.h + +/* Add in so we have Apple Target Conditionals */ +#ifdef __APPLE__ +#include +#include +#endif + +/* Special configuration for AppleTVOS */ +#if TARGET_OS_TV +#undef HAVE_SYSCALL_H +#undef HAVE_SYS_SYSCALL_H +#undef OS_MACOSX +#endif + +/* Special configuration for ucontext */ +#undef HAVE_UCONTEXT_H +#undef PC_FROM_UCONTEXT +#if defined(__x86_64__) +#define PC_FROM_UCONTEXT uc_mcontext->__ss.__rip +#elif defined(__i386__) +#define PC_FROM_UCONTEXT uc_mcontext->__ss.__eip +#endif +EOF diff --git a/iOS/third-party-podspecs/ComponentKit.podspec b/iOS/third-party-podspecs/ComponentKit.podspec new file mode 100644 index 000000000..d6e54476c --- /dev/null +++ b/iOS/third-party-podspecs/ComponentKit.podspec @@ -0,0 +1,21 @@ +Pod::Spec.new do |s| + s.name = 'ComponentKit' + s.version = '0.21' + s.license = 'BSD' + s.summary = 'A React-inspired view framework for iOS' + s.homepage = 'https://componentkit.org' + s.social_media_url = 'https://twitter.com/componentkit' + s.authors = 'adamjernst@fb.com' + s.source = { :git => 'https://github.com/facebook/ComponentKit.git'} + s.ios.deployment_target = '8.1' + s.requires_arc = true + + s.source_files = 'ComponentKit/**/*', 'ComponentTextKit/**/*' + s.frameworks = 'UIKit', 'CoreText' + s.library = 'c++' + s.xcconfig = { + 'CLANG_CXX_LANGUAGE_STANDARD' => 'gnu++14', + 'CLANG_CXX_LIBRARY' => 'libc++', + } + s.dependency 'Yoga' +end diff --git a/iOS/third-party-podspecs/DoubleConversion.podspec b/iOS/third-party-podspecs/DoubleConversion.podspec new file mode 100755 index 000000000..91f4f819b --- /dev/null +++ b/iOS/third-party-podspecs/DoubleConversion.podspec @@ -0,0 +1,18 @@ +Pod::Spec.new do |spec| + spec.name = 'DoubleConversion' + spec.version = '3.0.0' + spec.license = { :type => 'MIT' } + spec.homepage = 'https://github.com/google/double-conversion' + spec.summary = 'Efficient binary-decimal and decimal-binary conversion routines for IEEE doubles' + spec.authors = 'Google' + # spec.prepare_command = 'mv src double-conversion' + spec.source = { :git => 'https://github.com/google/double-conversion.git', + :tag => "v#{spec.version}" } + spec.module_name = 'DoubleConversion' + spec.source_files = 'double-conversion/*.{h,cc}' + spec.libraries = "stdc++" + spec.compiler_flags = '-std=c++1y' + # Pinning to the same version as React.podspec. + spec.platforms = { :ios => "8.0", :tvos => "9.2" } + +end diff --git a/iOS/third-party-podspecs/EasyWSClient.podspec b/iOS/third-party-podspecs/EasyWSClient.podspec new file mode 100644 index 000000000..0b3edeba9 --- /dev/null +++ b/iOS/third-party-podspecs/EasyWSClient.podspec @@ -0,0 +1,17 @@ +Pod::Spec.new do |spec| + spec.name = 'EasyWSClient' + spec.version = '1.0.0' + spec.license = { :type => 'MIT' } + spec.homepage = 'https://github.com/google/double-conversion' + spec.summary = 'Easywsclient is an easy and powerful WebSocket client to get your C++ code connected to a web stack right away.' + spec.authors = 'David Baird' + # spec.prepare_command = 'mv src double-conversion' + spec.source = { :git => 'https://github.com/dhbaird/easywsclient.git', :branch => 'master'} + spec.module_name = 'EasyWSClient' + spec.source_files = '*.{hpp,cpp}' + spec.libraries = "stdc++" + spec.compiler_flags = '-std=c++1y' + # Pinning to the same version as React.podspec. + spec.platforms = { :ios => "8.0", :tvos => "9.2" } + +end diff --git a/iOS/third-party-podspecs/Folly.podspec b/iOS/third-party-podspecs/Folly.podspec new file mode 100755 index 000000000..4732038d7 --- /dev/null +++ b/iOS/third-party-podspecs/Folly.podspec @@ -0,0 +1,95 @@ +Pod::Spec.new do |spec| + spec.name = 'Folly' + spec.version = '2018.05.07.00' + spec.license = { :type => 'Apache License, Version 2.0' } + spec.homepage = 'https://github.com/facebook/folly' + spec.summary = 'An open-source C++ library developed and used at Facebook.' + spec.authors = 'Facebook' + spec.source = { :git => 'https://github.com/facebook/folly.git', + :tag => "v#{spec.version}" } + spec.module_name = 'folly' + spec.dependency 'boost-for-react-native' + spec.dependency 'DoubleConversion' + spec.dependency 'glog' + spec.compiler_flags = '-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1 -DFOLLY_HAVE_LIBGFLAGS=0 -DFOLLY_HAVE_LIBJEMALLOC=0 -DFOLLY_HAVE_PREADV=0 -DFOLLY_HAVE_PWRITEV=0 -DFOLLY_HAVE_TFO=0 -DFOLLY_USE_SYMBOLIZER=0 -frtti + -fexceptions + -std=c++14 + -Wno-error + -Wno-unused-local-typedefs + -Wno-unused-variable + -Wno-sign-compare + -Wno-comment + -Wno-return-type + -Wno-global-constructors' + spec.source_files = 'folly/Executor.cpp', + 'folly/memory/detail/MallocImpl.cpp', + 'folly/String.cpp', + 'folly/*.cpp', + 'folly/ScopeGuard.h', + 'folly/lang/ColdClass.cpp', + 'folly/lang/Assume.h', + 'folly/lang/Assume.cpp' + + # workaround for https://github.com/facebook/react-native/issues/14326 + spec.preserve_paths = 'folly/*.h', + 'folly/portability/*.h', + 'folly/lang/*.h', + 'folly/functional/*.h', + 'folly/detail/*.h', + 'folly/hash/*.h', + 'folly/memory/*.h', + 'folly/**/*.h' + + spec.header_mappings_dir = 'folly' + spec.header_dir = 'folly' + spec.libraries = "stdc++" + spec.private_header_files = 'folly/portability/Stdlib.h', + 'folly/portability/Malloc.h', + 'folly/portability/Stdlib.h', + 'folly/portability/Stdio.h', + 'folly/portability/PThread.h' + spec.public_header_files = 'folly/portability/Config.h', + 'folly/Executor.h', + 'folly/Function.h', + 'folly/Utility.h', + 'folly/Portability.h', + 'folly/Traits.h', + 'folly/functional/Invoke.h', + 'folly/CPortability.h', + 'folly/dynamic.h', + 'folly/json_pointer.h', + 'folly/Expected.h', + 'folly/Preprocessor.h', + 'folly/Optional.h', + 'folly/Unit.h', + 'folly/Utility.h', + 'folly/lang/ColdClass.h', + 'folly/CppAttributes.h', + 'folly/json.h', + 'folly/Range.h', + 'folly/hash/SpookyHashV2.h', + 'folly/lang/Exception.h', + 'folly/portability/Constexpr.h', + 'folly/CpuId.h', + 'folly/Likely.h', + 'folly/detail/RangeCommon.h', + 'folly/detail/RangeSse42.h', + 'folly/portability/String.h', + 'folly/dynamic-inl.h', + 'folly/Conv.h', + 'folly/Demangle.h', + 'folly/FBString.h', + 'folly/hash/Hash.h', + 'folly/memory/Malloc.h', + 'folly/**/*.h', + 'folly/memory/detail/MallocImpl.h', + 'folly/String.h', + 'folly/*.h' + + spec.pod_target_xcconfig = { "USE_HEADERMAP" => "NO", + "CLANG_CXX_LANGUAGE_STANDARD" => "c++11", + "HEADER_SEARCH_PATHS" => "\"$(PODS_TARGET_SRCROOT)\" \"$(PODS_ROOT)/boost-for-react-native\" \"$(PODS_ROOT)/DoubleConversion\"" } + + # Pinning to the same version as React.podspec. + spec.platforms = { :ios => "8.0", :tvos => "10.0" } +end diff --git a/iOS/third-party-podspecs/glog.podspec b/iOS/third-party-podspecs/glog.podspec new file mode 100755 index 000000000..a68659fa0 --- /dev/null +++ b/iOS/third-party-podspecs/glog.podspec @@ -0,0 +1,41 @@ +Pod::Spec.new do |spec| + spec.name = 'glog' + spec.version = '0.3.5' + spec.license = { :type => 'Google', :file => 'COPYING' } + spec.homepage = 'https://github.com/google/glog' + spec.summary = 'Google logging module' + spec.authors = 'Google' + spec.prepare_command = File.read("../scripts/ios-configure-glog.sh") + spec.source = { :git => 'https://github.com/google/glog.git', + :tag => "v#{spec.version}" } + spec.module_name = 'glog' + spec.header_dir = 'glog' + spec.source_files = 'src/logging.cc', + 'src/utilities.h', + 'src/utilities.cc', + 'src/glog/*.h', + 'src/glog/*.cc', + 'src/base/mutex.h', + 'src/base/mutex.cc', + 'src/glog/*.h', + 'src/demangle.cc', + 'src/logging.cc', + 'src/raw_logging.cc', + 'src/signalhandler.cc', + 'src/symbolize.cc', + 'src/utilities.cc', + 'src/vlog_is_on.cc' + # workaround for https://github.com/facebook/react-native/issues/14326 + spec.preserve_paths = 'src/*.h', + 'src/base/*.h' + spec.exclude_files = "src/windows/**/*" + spec.libraries = "c++" + spec.pod_target_xcconfig = { "USE_HEADERMAP" => "NO", + "CLANG_CXX_LANGUAGE_STANDARD" => "c++11", + "HEADER_SEARCH_PATHS" => "$(PODS_TARGET_SRCROOT)/src" + } + spec.compiler_flags = '-std=c++1y' + spec.libraries = "stdc++" + spec.platforms = { :ios => "8.0", :tvos => "9.2" } + +end diff --git a/libs/easywsclient/AndroidManifest.xml b/libs/easywsclient/AndroidManifest.xml new file mode 100644 index 000000000..dd86bab56 --- /dev/null +++ b/libs/easywsclient/AndroidManifest.xml @@ -0,0 +1,4 @@ + + + diff --git a/libs/easywsclient/CMakeLists.txt b/libs/easywsclient/CMakeLists.txt new file mode 100644 index 000000000..7775f9db6 --- /dev/null +++ b/libs/easywsclient/CMakeLists.txt @@ -0,0 +1,13 @@ +cmake_minimum_required (VERSION 3.6.0) +set(PACKAGE_NAME "easywsclient") +include_directories(./) +set(SOURCES easywsclient.cpp) +add_compile_options( + -std=c++11 + -stdlib=libstdc++ + -Wall + ) + +add_library(${PACKAGE_NAME} SHARED ${SOURCES}) +install(TARGETS ${PACKAGE_NAME} DESTINATION ./build/) +target_link_libraries(${PACKAGE_NAME}) diff --git a/libs/easywsclient/build.gradle b/libs/easywsclient/build.gradle new file mode 100644 index 000000000..18878323c --- /dev/null +++ b/libs/easywsclient/build.gradle @@ -0,0 +1,34 @@ +apply plugin: 'com.android.library' + +android { + compileSdkVersion rootProject.compileSdkVersion + buildToolsVersion rootProject.buildToolsVersion + + defaultConfig { + minSdkVersion rootProject.minSdkVersion + targetSdkVersion rootProject.targetSdkVersion + + ndk { + abiFilters 'x86', 'x86_64', 'armeabi-v7a', 'arm64-v8a' + } + + externalNativeBuild { + cmake { + arguments '-DANDROID_TOOLCHAIN=clang', '-DANDROID_STL=c++_shared' + } + } + + } + + externalNativeBuild { + cmake { + path './CMakeLists.txt' + } + } + + sourceSets { + main { + manifest.srcFile './AndroidManifest.xml' + } + } +} diff --git a/libs/easywsclient/easywsclient.cpp b/libs/easywsclient/easywsclient.cpp new file mode 100644 index 000000000..0cd186ef5 --- /dev/null +++ b/libs/easywsclient/easywsclient.cpp @@ -0,0 +1,529 @@ + +#ifdef _WIN32 + #if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_WARNINGS) + #define _CRT_SECURE_NO_WARNINGS // _CRT_SECURE_NO_WARNINGS for sscanf errors in MSVC2013 Express + #endif + #ifndef WIN32_LEAN_AND_MEAN + #define WIN32_LEAN_AND_MEAN + #endif + #include + #include + #include + #pragma comment( lib, "ws2_32" ) + #include + #include + #include + #include + #include + #ifndef _SSIZE_T_DEFINED + typedef int ssize_t; + #define _SSIZE_T_DEFINED + #endif + #ifndef _SOCKET_T_DEFINED + typedef SOCKET socket_t; + #define _SOCKET_T_DEFINED + #endif + #ifndef snprintf + #define snprintf _snprintf_s + #endif + #if _MSC_VER >=1600 + // vs2010 or later + #include + #else + typedef __int8 int8_t; + typedef unsigned __int8 uint8_t; + typedef __int32 int32_t; + typedef unsigned __int32 uint32_t; + typedef __int64 int64_t; + typedef unsigned __int64 uint64_t; + #endif + #define socketerrno WSAGetLastError() + #define SOCKET_EAGAIN_EINPROGRESS WSAEINPROGRESS + #define SOCKET_EWOULDBLOCK WSAEWOULDBLOCK +#else + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #ifndef _SOCKET_T_DEFINED + typedef int socket_t; + #define _SOCKET_T_DEFINED + #endif + #ifndef INVALID_SOCKET + #define INVALID_SOCKET (-1) + #endif + #ifndef SOCKET_ERROR + #define SOCKET_ERROR (-1) + #endif + #define closesocket(s) ::close(s) + #include + #define socketerrno errno + #define SOCKET_EAGAIN_EINPROGRESS EAGAIN + #define SOCKET_EWOULDBLOCK EWOULDBLOCK +#endif + +#include +#include + +#include "easywsclient.hpp" + +using easywsclient::Callback_Imp; +using easywsclient::BytesCallback_Imp; + +namespace { // private module-only namespace + +socket_t hostname_connect(const std::string& hostname, int port) { + struct addrinfo hints; + struct addrinfo *result; + struct addrinfo *p; + int ret; + socket_t sockfd = INVALID_SOCKET; + char sport[16]; + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + snprintf(sport, 16, "%d", port); + if ((ret = getaddrinfo(hostname.c_str(), sport, &hints, &result)) != 0) + { + fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(ret)); + return 1; + } + for(p = result; p != NULL; p = p->ai_next) + { + sockfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol); + if (sockfd == INVALID_SOCKET) { continue; } + if (connect(sockfd, p->ai_addr, p->ai_addrlen) != SOCKET_ERROR) { + break; + } + closesocket(sockfd); + sockfd = INVALID_SOCKET; + } + freeaddrinfo(result); + return sockfd; +} + + +class _DummyWebSocket : public easywsclient::WebSocket +{ + public: + void poll(int timeout) { } + void send(const std::string& message) { } + void sendBinary(const std::string& message) { } + void sendBinary(const std::vector& message) { } + void sendPing() { } + void close() { } + readyStateValues getReadyState() const { return CLOSED; } + void _dispatch(Callback_Imp & callable) { } + void _dispatchBinary(BytesCallback_Imp& callable) { } +}; + + +class _RealWebSocket : public easywsclient::WebSocket +{ + public: + // http://tools.ietf.org/html/rfc6455#section-5.2 Base Framing Protocol + // + // 0 1 2 3 + // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + // +-+-+-+-+-------+-+-------------+-------------------------------+ + // |F|R|R|R| opcode|M| Payload len | Extended payload length | + // |I|S|S|S| (4) |A| (7) | (16/64) | + // |N|V|V|V| |S| | (if payload len==126/127) | + // | |1|2|3| |K| | | + // +-+-+-+-+-------+-+-------------+ - - - - - - - - - - - - - - - + + // | Extended payload length continued, if payload len == 127 | + // + - - - - - - - - - - - - - - - +-------------------------------+ + // | |Masking-key, if MASK set to 1 | + // +-------------------------------+-------------------------------+ + // | Masking-key (continued) | Payload Data | + // +-------------------------------- - - - - - - - - - - - - - - - + + // : Payload Data continued ... : + // + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + // | Payload Data continued ... | + // +---------------------------------------------------------------+ + struct wsheader_type { + unsigned header_size; + bool fin; + bool mask; + enum opcode_type { + CONTINUATION = 0x0, + TEXT_FRAME = 0x1, + BINARY_FRAME = 0x2, + CLOSE = 8, + PING = 9, + PONG = 0xa, + } opcode; + int N0; + uint64_t N; + uint8_t masking_key[4]; + }; + + std::vector rxbuf; + std::vector txbuf; + std::vector receivedData; + + socket_t sockfd; + readyStateValues readyState; + bool useMask; + + _RealWebSocket(socket_t sockfd, bool useMask) : sockfd(sockfd), readyState(OPEN), useMask(useMask) { + } + + readyStateValues getReadyState() const { + return readyState; + } + + void poll(int timeout) { // timeout in milliseconds + if (readyState == CLOSED) { + if (timeout > 0) { + timeval tv = { timeout/1000, (timeout%1000) * 1000 }; + select(0, NULL, NULL, NULL, &tv); + } + return; + } + if (timeout != 0) { + fd_set rfds; + fd_set wfds; + timeval tv = { timeout/1000, (timeout%1000) * 1000 }; + FD_ZERO(&rfds); + FD_ZERO(&wfds); + FD_SET(sockfd, &rfds); + if (txbuf.size()) { FD_SET(sockfd, &wfds); } + select(sockfd + 1, &rfds, &wfds, 0, timeout > 0 ? &tv : 0); + } + while (true) { + // FD_ISSET(0, &rfds) will be true + int N = rxbuf.size(); + ssize_t ret; + rxbuf.resize(N + 1500); + ret = recv(sockfd, (char*)&rxbuf[0] + N, 1500, 0); + if (false) { } + else if (ret < 0 && (socketerrno == SOCKET_EWOULDBLOCK || socketerrno == SOCKET_EAGAIN_EINPROGRESS)) { + rxbuf.resize(N); + break; + } + else if (ret <= 0) { + rxbuf.resize(N); + closesocket(sockfd); + readyState = CLOSED; + fputs(ret < 0 ? "Connection error!\n" : "Connection closed!\n", stderr); + break; + } + else { + rxbuf.resize(N + ret); + } + } + while (txbuf.size()) { + int ret = ::send(sockfd, (char*)&txbuf[0], txbuf.size(), 0); + if (false) { } // ?? + else if (ret < 0 && (socketerrno == SOCKET_EWOULDBLOCK || socketerrno == SOCKET_EAGAIN_EINPROGRESS)) { + break; + } + else if (ret <= 0) { + closesocket(sockfd); + readyState = CLOSED; + fputs(ret < 0 ? "Connection error!\n" : "Connection closed!\n", stderr); + break; + } + else { + txbuf.erase(txbuf.begin(), txbuf.begin() + ret); + } + } + if (!txbuf.size() && readyState == CLOSING) { + closesocket(sockfd); + readyState = CLOSED; + } + } + + // Callable must have signature: void(const std::string & message). + // Should work with C functions, C++ functors, and C++11 std::function and + // lambda: + //template + //void dispatch(Callable callable) + virtual void _dispatch(Callback_Imp & callable) { + struct CallbackAdapter : public BytesCallback_Imp + // Adapt void(const std::string&) to void(const std::string&) + { + Callback_Imp& callable; + CallbackAdapter(Callback_Imp& callable) : callable(callable) { } + void operator()(const std::vector& message) { + std::string stringMessage(message.begin(), message.end()); + callable(stringMessage); + } + }; + CallbackAdapter bytesCallback(callable); + _dispatchBinary(bytesCallback); + } + + virtual void _dispatchBinary(BytesCallback_Imp & callable) { + // TODO: consider acquiring a lock on rxbuf... + while (true) { + wsheader_type ws; + if (rxbuf.size() < 2) { return; /* Need at least 2 */ } + const uint8_t * data = (uint8_t *) &rxbuf[0]; // peek, but don't consume + ws.fin = (data[0] & 0x80) == 0x80; + ws.opcode = (wsheader_type::opcode_type) (data[0] & 0x0f); + ws.mask = (data[1] & 0x80) == 0x80; + ws.N0 = (data[1] & 0x7f); + ws.header_size = 2 + (ws.N0 == 126? 2 : 0) + (ws.N0 == 127? 8 : 0) + (ws.mask? 4 : 0); + if (rxbuf.size() < ws.header_size) { return; /* Need: ws.header_size - rxbuf.size() */ } + int i = 0; + if (ws.N0 < 126) { + ws.N = ws.N0; + i = 2; + } + else if (ws.N0 == 126) { + ws.N = 0; + ws.N |= ((uint64_t) data[2]) << 8; + ws.N |= ((uint64_t) data[3]) << 0; + i = 4; + } + else if (ws.N0 == 127) { + ws.N = 0; + ws.N |= ((uint64_t) data[2]) << 56; + ws.N |= ((uint64_t) data[3]) << 48; + ws.N |= ((uint64_t) data[4]) << 40; + ws.N |= ((uint64_t) data[5]) << 32; + ws.N |= ((uint64_t) data[6]) << 24; + ws.N |= ((uint64_t) data[7]) << 16; + ws.N |= ((uint64_t) data[8]) << 8; + ws.N |= ((uint64_t) data[9]) << 0; + i = 10; + } + if (ws.mask) { + ws.masking_key[0] = ((uint8_t) data[i+0]) << 0; + ws.masking_key[1] = ((uint8_t) data[i+1]) << 0; + ws.masking_key[2] = ((uint8_t) data[i+2]) << 0; + ws.masking_key[3] = ((uint8_t) data[i+3]) << 0; + } + else { + ws.masking_key[0] = 0; + ws.masking_key[1] = 0; + ws.masking_key[2] = 0; + ws.masking_key[3] = 0; + } + if (rxbuf.size() < ws.header_size+ws.N) { return; /* Need: ws.header_size+ws.N - rxbuf.size() */ } + + // We got a whole message, now do something with it: + if (false) { } + else if ( + ws.opcode == wsheader_type::TEXT_FRAME + || ws.opcode == wsheader_type::BINARY_FRAME + || ws.opcode == wsheader_type::CONTINUATION + ) { + if (ws.mask) { for (size_t i = 0; i != ws.N; ++i) { rxbuf[i+ws.header_size] ^= ws.masking_key[i&0x3]; } } + receivedData.insert(receivedData.end(), rxbuf.begin()+ws.header_size, rxbuf.begin()+ws.header_size+(size_t)ws.N);// just feed + if (ws.fin) { + callable((const std::vector) receivedData); + receivedData.erase(receivedData.begin(), receivedData.end()); + std::vector ().swap(receivedData);// free memory + } + } + else if (ws.opcode == wsheader_type::PING) { + if (ws.mask) { for (size_t i = 0; i != ws.N; ++i) { rxbuf[i+ws.header_size] ^= ws.masking_key[i&0x3]; } } + std::string data(rxbuf.begin()+ws.header_size, rxbuf.begin()+ws.header_size+(size_t)ws.N); + sendData(wsheader_type::PONG, data.size(), data.begin(), data.end()); + } + else if (ws.opcode == wsheader_type::PONG) { } + else if (ws.opcode == wsheader_type::CLOSE) { close(); } + else { fprintf(stderr, "ERROR: Got unexpected WebSocket message.\n"); close(); } + + rxbuf.erase(rxbuf.begin(), rxbuf.begin() + ws.header_size+(size_t)ws.N); + } + } + + void sendPing() { + std::string empty; + sendData(wsheader_type::PING, empty.size(), empty.begin(), empty.end()); + } + + void send(const std::string& message) { + sendData(wsheader_type::TEXT_FRAME, message.size(), message.begin(), message.end()); + } + + void sendBinary(const std::string& message) { + sendData(wsheader_type::BINARY_FRAME, message.size(), message.begin(), message.end()); + } + + void sendBinary(const std::vector& message) { + sendData(wsheader_type::BINARY_FRAME, message.size(), message.begin(), message.end()); + } + + template + void sendData(wsheader_type::opcode_type type, uint64_t message_size, Iterator message_begin, Iterator message_end) { + // TODO: + // Masking key should (must) be derived from a high quality random + // number generator, to mitigate attacks on non-WebSocket friendly + // middleware: + const uint8_t masking_key[4] = { 0x12, 0x34, 0x56, 0x78 }; + // TODO: consider acquiring a lock on txbuf... + if (readyState == CLOSING || readyState == CLOSED) { return; } + std::vector header; + header.assign(2 + (message_size >= 126 ? 2 : 0) + (message_size >= 65536 ? 6 : 0) + (useMask ? 4 : 0), 0); + header[0] = 0x80 | type; + if (false) { } + else if (message_size < 126) { + header[1] = (message_size & 0xff) | (useMask ? 0x80 : 0); + if (useMask) { + header[2] = masking_key[0]; + header[3] = masking_key[1]; + header[4] = masking_key[2]; + header[5] = masking_key[3]; + } + } + else if (message_size < 65536) { + header[1] = 126 | (useMask ? 0x80 : 0); + header[2] = (message_size >> 8) & 0xff; + header[3] = (message_size >> 0) & 0xff; + if (useMask) { + header[4] = masking_key[0]; + header[5] = masking_key[1]; + header[6] = masking_key[2]; + header[7] = masking_key[3]; + } + } + else { // TODO: run coverage testing here + header[1] = 127 | (useMask ? 0x80 : 0); + header[2] = (message_size >> 56) & 0xff; + header[3] = (message_size >> 48) & 0xff; + header[4] = (message_size >> 40) & 0xff; + header[5] = (message_size >> 32) & 0xff; + header[6] = (message_size >> 24) & 0xff; + header[7] = (message_size >> 16) & 0xff; + header[8] = (message_size >> 8) & 0xff; + header[9] = (message_size >> 0) & 0xff; + if (useMask) { + header[10] = masking_key[0]; + header[11] = masking_key[1]; + header[12] = masking_key[2]; + header[13] = masking_key[3]; + } + } + // N.B. - txbuf will keep growing until it can be transmitted over the socket: + txbuf.insert(txbuf.end(), header.begin(), header.end()); + txbuf.insert(txbuf.end(), message_begin, message_end); + if (useMask) { + size_t message_offset = txbuf.size() - message_size; + for (size_t i = 0; i != message_size; ++i) { + txbuf[message_offset + i] ^= masking_key[i&0x3]; + } + } + } + + void close() { + if(readyState == CLOSING || readyState == CLOSED) { return; } + readyState = CLOSING; + uint8_t closeFrame[6] = {0x88, 0x80, 0x00, 0x00, 0x00, 0x00}; // last 4 bytes are a masking key + std::vector header(closeFrame, closeFrame+6); + txbuf.insert(txbuf.end(), header.begin(), header.end()); + } + +}; + + +easywsclient::WebSocket::pointer from_url(const std::string& url, bool useMask, const std::string& origin) { + char host[128]; + int port; + char path[300]; + if (url.size() >= 300) { + fprintf(stderr, "ERROR: url size limit exceeded: %s\n", url.c_str()); + return NULL; + } + if (origin.size() >= 200) { + fprintf(stderr, "ERROR: origin size limit exceeded: %s\n", origin.c_str()); + return NULL; + } + if (false) { } + else if (sscanf(url.c_str(), "ws://%[^:/]:%d/%s", host, &port, path) == 3) { + } + else if (sscanf(url.c_str(), "ws://%[^:/]/%s", host, path) == 2) { + port = 80; + } + else if (sscanf(url.c_str(), "ws://%[^:/]:%d", host, &port) == 2) { + path[0] = '\0'; + } + else if (sscanf(url.c_str(), "ws://%[^:/]", host) == 1) { + port = 80; + path[0] = '\0'; + } + else { + fprintf(stderr, "ERROR: Could not parse WebSocket url: %s\n", url.c_str()); + return NULL; + } + //fprintf(stderr, "easywsclient: connecting: host=%s port=%d path=/%s\n", host, port, path); + socket_t sockfd = hostname_connect(host, port); + if (sockfd == INVALID_SOCKET) { + fprintf(stderr, "Unable to connect to %s:%d\n", host, port); + return NULL; + } + { + // XXX: this should be done non-blocking, + char line[256]; + int status; + int i; + snprintf(line, 256, "GET /%s HTTP/1.1\r\n", path); ::send(sockfd, line, strlen(line), 0); + if (port == 80) { + snprintf(line, 256, "Host: %s\r\n", host); ::send(sockfd, line, strlen(line), 0); + } + else { + snprintf(line, 256, "Host: %s:%d\r\n", host, port); ::send(sockfd, line, strlen(line), 0); + } + snprintf(line, 256, "Upgrade: websocket\r\n"); ::send(sockfd, line, strlen(line), 0); + snprintf(line, 256, "Connection: Upgrade\r\n"); ::send(sockfd, line, strlen(line), 0); + if (!origin.empty()) { + snprintf(line, 256, "Origin: %s\r\n", origin.c_str()); ::send(sockfd, line, strlen(line), 0); + } + snprintf(line, 256, "Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==\r\n"); ::send(sockfd, line, strlen(line), 0); + snprintf(line, 256, "Sec-WebSocket-Version: 13\r\n"); ::send(sockfd, line, strlen(line), 0); + snprintf(line, 256, "\r\n"); ::send(sockfd, line, strlen(line), 0); + for (i = 0; i < 2 || (i < 255 && line[i-2] != '\r' && line[i-1] != '\n'); ++i) { if (recv(sockfd, line+i, 1, 0) == 0) { return NULL; } } + line[i] = 0; + if (i == 255) { fprintf(stderr, "ERROR: Got invalid status line connecting to: %s\n", url.c_str()); return NULL; } + if (sscanf(line, "HTTP/1.1 %d", &status) != 1 || status != 101) { fprintf(stderr, "ERROR: Got bad status connecting to %s: %s", url.c_str(), line); return NULL; } + // TODO: verify response headers, + while (true) { + for (i = 0; i < 2 || (i < 255 && line[i-2] != '\r' && line[i-1] != '\n'); ++i) { if (recv(sockfd, line+i, 1, 0) == 0) { return NULL; } } + if (line[0] == '\r' && line[1] == '\n') { break; } + } + } + int flag = 1; + setsockopt(sockfd, 6, TCP_NODELAY, (char*) &flag, sizeof(flag)); // Disable Nagle's algorithm +#ifdef _WIN32 + u_long on = 1; + ioctlsocket(sockfd, FIONBIO, &on); +#else + fcntl(sockfd, F_SETFL, O_NONBLOCK); +#endif + //fprintf(stderr, "Connected to: %s\n", url.c_str()); + return easywsclient::WebSocket::pointer(new _RealWebSocket(sockfd, useMask)); +} + +} // end of module-only namespace + + + +namespace easywsclient { + +WebSocket::pointer WebSocket::create_dummy() { + static pointer dummy = pointer(new _DummyWebSocket); + return dummy; +} + + +WebSocket::pointer WebSocket::from_url(const std::string& url, const std::string& origin) { + return ::from_url(url, true, origin); +} + +WebSocket::pointer WebSocket::from_url_no_mask(const std::string& url, const std::string& origin) { + return ::from_url(url, false, origin); +} + + +} // namespace easywsclient diff --git a/libs/easywsclient/easywsclient.hpp b/libs/easywsclient/easywsclient.hpp new file mode 100644 index 000000000..08c4a7b58 --- /dev/null +++ b/libs/easywsclient/easywsclient.hpp @@ -0,0 +1,72 @@ +#ifndef EASYWSCLIENT_HPP_20120819_MIOFVASDTNUASZDQPLFD +#define EASYWSCLIENT_HPP_20120819_MIOFVASDTNUASZDQPLFD + +// This code comes from: +// https://github.com/dhbaird/easywsclient +// +// To get the latest version: +// wget https://raw.github.com/dhbaird/easywsclient/master/easywsclient.hpp +// wget https://raw.github.com/dhbaird/easywsclient/master/easywsclient.cpp + +#include +#include + +namespace easywsclient { + +struct Callback_Imp { virtual void operator()(const std::string& message) = 0; }; +struct BytesCallback_Imp { virtual void operator()(const std::vector& message) = 0; }; + +class WebSocket { + public: + typedef WebSocket * pointer; + typedef enum readyStateValues { CLOSING, CLOSED, CONNECTING, OPEN } readyStateValues; + + // Factories: + static pointer create_dummy(); + static pointer from_url(const std::string& url, const std::string& origin = std::string()); + static pointer from_url_no_mask(const std::string& url, const std::string& origin = std::string()); + + // Interfaces: + virtual ~WebSocket() { } + virtual void poll(int timeout = 0) = 0; // timeout in milliseconds + virtual void send(const std::string& message) = 0; + virtual void sendBinary(const std::string& message) = 0; + virtual void sendBinary(const std::vector& message) = 0; + virtual void sendPing() = 0; + virtual void close() = 0; + virtual readyStateValues getReadyState() const = 0; + + template + void dispatch(Callable callable) + // For callbacks that accept a string argument. + { // N.B. this is compatible with both C++11 lambdas, functors and C function pointers + struct _Callback : public Callback_Imp { + Callable& callable; + _Callback(Callable& callable) : callable(callable) { } + void operator()(const std::string& message) { callable(message); } + }; + _Callback callback(callable); + _dispatch(callback); + } + + template + void dispatchBinary(Callable callable) + // For callbacks that accept a std::vector argument. + { // N.B. this is compatible with both C++11 lambdas, functors and C function pointers + struct _Callback : public BytesCallback_Imp { + Callable& callable; + _Callback(Callable& callable) : callable(callable) { } + void operator()(const std::vector& message) { callable(message); } + }; + _Callback callback(callable); + _dispatchBinary(callback); + } + + protected: + virtual void _dispatch(Callback_Imp& callable) = 0; + virtual void _dispatchBinary(BytesCallback_Imp& callable) = 0; +}; + +} // namespace easywsclient + +#endif /* EASYWSCLIENT_HPP_20120819_MIOFVASDTNUASZDQPLFD */ diff --git a/libs/fbjni/build.gradle b/libs/fbjni/build.gradle new file mode 100644 index 000000000..f4aa91810 --- /dev/null +++ b/libs/fbjni/build.gradle @@ -0,0 +1,33 @@ +apply plugin: 'com.android.library' + +android { + compileSdkVersion rootProject.compileSdkVersion + buildToolsVersion rootProject.buildToolsVersion + + defaultConfig { + minSdkVersion rootProject.minSdkVersion + targetSdkVersion rootProject.targetSdkVersion + + ndk { + abiFilters 'x86', 'x86_64', 'armeabi-v7a', 'arm64-v8a' + } + + externalNativeBuild { + cmake { + arguments '-DANDROID_TOOLCHAIN=clang' + } + } + } + externalNativeBuild { + cmake { + path './src/main/cpp/CMakeLists.txt' + } + } +} + +dependencies { + // compileOnly dependencies + compileOnly deps.jsr305 + compileOnly deps.inferAnnotations + compileOnly 'com.facebook.litho:litho-annotations:0.15.0' +} diff --git a/libs/fbjni/src/main/AndroidManifest.xml b/libs/fbjni/src/main/AndroidManifest.xml new file mode 100644 index 000000000..8e81b59db --- /dev/null +++ b/libs/fbjni/src/main/AndroidManifest.xml @@ -0,0 +1,14 @@ + + + + + + diff --git a/libs/fbjni/src/main/cpp/CMakeLists.txt b/libs/fbjni/src/main/cpp/CMakeLists.txt new file mode 100644 index 000000000..161471866 --- /dev/null +++ b/libs/fbjni/src/main/cpp/CMakeLists.txt @@ -0,0 +1,33 @@ +# +# Copyright (c) 2014-present, Facebook, Inc. +# +# This source code is licensed under the MIT license found in the +# LICENSE file in the root directory of this source tree. +# + +cmake_minimum_required(VERSION 3.6.0) + +set(CMAKE_VERBOSE_MAKEFILE on) + +add_compile_options( + -fno-omit-frame-pointer + -fexceptions + -Wall + -std=c++11 + -DDISABLE_CPUCAP + -DDISABLE_XPLAT) + +file(GLOB fb_SRC + *.cpp + jni/*.cpp + lyra/*.cpp) + +set(libjnihack_DIR ../../../../jni-hack/) + +add_library(fb SHARED + ${fb_SRC}) + +target_include_directories(fb PRIVATE + include ${libjnihack_DIR}) + +target_link_libraries(fb log) diff --git a/libs/fbjni/src/main/cpp/assert.cpp b/libs/fbjni/src/main/cpp/assert.cpp new file mode 100644 index 000000000..aaa999e13 --- /dev/null +++ b/libs/fbjni/src/main/cpp/assert.cpp @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2015-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +#include +#include + +#include +#include + +namespace facebook { + +#define ASSERT_BUF_SIZE 4096 +static char sAssertBuf[ASSERT_BUF_SIZE]; +static AssertHandler gAssertHandler; + +void assertInternal(const char* formatstr ...) { + va_list va_args; + va_start(va_args, formatstr); + vsnprintf(sAssertBuf, sizeof(sAssertBuf), formatstr, va_args); + va_end(va_args); + if (gAssertHandler != NULL) { + gAssertHandler(sAssertBuf); + } + FBLOG(LOG_FATAL, "fbassert", "%s", sAssertBuf); + // crash at this specific address so that we can find our crashes easier + *(int*)0xdeadb00c = 0; + // let the compiler know we won't reach the end of the function + __builtin_unreachable(); +} + +void setAssertHandler(AssertHandler assertHandler) { + gAssertHandler = assertHandler; +} + +} // namespace facebook diff --git a/libs/fbjni/src/main/cpp/include/jni/Countable.h b/libs/fbjni/src/main/cpp/include/jni/Countable.h new file mode 100644 index 000000000..0b07e3228 --- /dev/null +++ b/libs/fbjni/src/main/cpp/include/jni/Countable.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2015-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +#pragma once + +#include + +#include +#include +#include + +namespace facebook { +namespace jni { + +FBEXPORT const RefPtr& countableFromJava(JNIEnv* env, jobject obj); + +template RefPtr extractRefPtr(JNIEnv* env, jobject obj) { + return static_cast>(countableFromJava(env, obj)); +} + +template RefPtr extractPossiblyNullRefPtr(JNIEnv* env, jobject obj) { + return obj ? extractRefPtr(env, obj) : nullptr; +} + +FBEXPORT void setCountableForJava(JNIEnv* env, jobject obj, RefPtr&& countable); + +void CountableOnLoad(JNIEnv* env); + +} } + diff --git a/libs/fbjni/src/main/cpp/include/jni/GlobalReference.h b/libs/fbjni/src/main/cpp/include/jni/GlobalReference.h new file mode 100644 index 000000000..1cac8a889 --- /dev/null +++ b/libs/fbjni/src/main/cpp/include/jni/GlobalReference.h @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2015-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +#pragma once + +#include +#include + +#include + +#include + +namespace facebook { namespace jni { + +template +class GlobalReference { + static_assert(std::is_convertible::value, + "GlobalReference instantiated with type that is not " + "convertible to jobject"); + + public: + explicit GlobalReference(T globalReference) : + reference_(globalReference? Environment::current()->NewGlobalRef(globalReference) : nullptr) { + } + + ~GlobalReference() { + reset(); + } + + GlobalReference() : + reference_(nullptr) { + } + + // enable move constructor and assignment + GlobalReference(GlobalReference&& rhs) : + reference_(std::move(rhs.reference_)) { + rhs.reference_ = nullptr; + } + + GlobalReference& operator=(GlobalReference&& rhs) { + if (this != &rhs) { + reset(); + reference_ = std::move(rhs.reference_); + rhs.reference_ = nullptr; + } + return *this; + } + + GlobalReference(const GlobalReference& rhs) : + reference_{} { + reset(rhs.get()); + } + + GlobalReference& operator=(const GlobalReference& rhs) { + if (this == &rhs) { + return *this; + } + reset(rhs.get()); + return *this; + } + + explicit operator bool() const { + return (reference_ != nullptr); + } + + T get() const { + return reinterpret_cast(reference_); + } + + void reset(T globalReference = nullptr) { + if (reference_) { + Environment::current()->DeleteGlobalRef(reference_); + } + if (globalReference) { + reference_ = Environment::current()->NewGlobalRef(globalReference); + } else { + reference_ = nullptr; + } + } + + private: + jobject reference_; +}; + +}} diff --git a/libs/fbjni/src/main/cpp/include/jni/LocalReference.h b/libs/fbjni/src/main/cpp/include/jni/LocalReference.h new file mode 100644 index 000000000..20955eac7 --- /dev/null +++ b/libs/fbjni/src/main/cpp/include/jni/LocalReference.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2015-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +#pragma once + +#include +#include + +#include + +#include + +namespace facebook { +namespace jni { + +template +struct LocalReferenceDeleter { + static_assert(std::is_convertible::value, + "LocalReferenceDeleter instantiated with type that is not convertible to jobject"); + void operator()(T localReference) { + if (localReference != nullptr) { + Environment::current()->DeleteLocalRef(localReference); + } + } + }; + +template +using LocalReference = + std::unique_ptr::type, LocalReferenceDeleter>; + +} } diff --git a/libs/fbjni/src/main/cpp/include/jni/LocalString.h b/libs/fbjni/src/main/cpp/include/jni/LocalString.h new file mode 100644 index 000000000..77f0696b5 --- /dev/null +++ b/libs/fbjni/src/main/cpp/include/jni/LocalString.h @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2015-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +#pragma once + +#include + +#include + +#include + +namespace facebook { +namespace jni { + +namespace detail { + +void utf8ToModifiedUTF8(const uint8_t* bytes, size_t len, uint8_t* modified, size_t modifiedLength); +size_t modifiedLength(const std::string& str); +size_t modifiedLength(const uint8_t* str, size_t* length); +std::string modifiedUTF8ToUTF8(const uint8_t* modified, size_t len) noexcept; +std::string utf16toUTF8(const uint16_t* utf16Bytes, size_t len) noexcept; + +} + +// JNI represents strings encoded with modified version of UTF-8. The difference between UTF-8 and +// Modified UTF-8 is that the latter support only 1-byte, 2-byte, and 3-byte formats. Supplementary +// character (4 bytes in unicode) needs to be represented in the form of surrogate pairs. To create +// a Modified UTF-8 surrogate pair that Dalvik would understand we take 4-byte unicode character, +// encode it with UTF-16 which gives us two 2 byte chars (surrogate pair) and then we encode each +// pair as UTF-8. This result in 2 x 3 byte characters. To convert modified UTF-8 to standard +// UTF-8, this mus tbe reversed. +// +// The second difference is that Modified UTF-8 is encoding NUL byte in 2-byte format. +// +// In order to avoid complex error handling, only a minimum of validity checking is done to avoid +// crashing. If the input is invalid, the output may be invalid as well. +// +// Relevant links: +// - http://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/functions.html +// - https://docs.oracle.com/javase/6/docs/api/java/io/DataInput.html#modified-utf-8 + +class FBEXPORT LocalString { +public: + // Assumes UTF8 encoding and make a required convertion to modified UTF-8 when the string + // contains unicode supplementary characters. + explicit LocalString(const std::string& str); + explicit LocalString(const char* str); + jstring string() const { + return m_string; + } + ~LocalString(); +private: + jstring m_string; +}; + +// JString to UTF16 extractor using RAII idiom +class JStringUtf16Extractor { +public: + JStringUtf16Extractor(JNIEnv* env, jstring javaString) + : env_(env) + , javaString_(javaString) + , utf16String_(nullptr) { + if (env_ && javaString_) { + utf16String_ = env_->GetStringCritical(javaString_, nullptr); + } + } + + ~JStringUtf16Extractor() { + if (utf16String_) { + env_->ReleaseStringCritical(javaString_, utf16String_); + } + } + + operator const jchar* () const { + return utf16String_; + } + +private: + JNIEnv* env_; + jstring javaString_; + const jchar* utf16String_; +}; + +// The string from JNI is converted to standard UTF-8 if the string contains supplementary +// characters. +FBEXPORT std::string fromJString(JNIEnv* env, jstring str); + +} } diff --git a/libs/fbjni/src/main/cpp/include/jni/Registration.h b/libs/fbjni/src/main/cpp/include/jni/Registration.h new file mode 100644 index 000000000..600c32c0c --- /dev/null +++ b/libs/fbjni/src/main/cpp/include/jni/Registration.h @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2015-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +#pragma once +#include +#include +#include + +namespace facebook { +namespace jni { + +static inline void registerNatives(JNIEnv* env, jclass cls, std::initializer_list methods) { + auto result = env->RegisterNatives(cls, methods.begin(), methods.size()); + FBASSERT(result == 0); +} + +static inline void registerNatives(JNIEnv* env, const char* cls, std::initializer_list list) { + registerNatives(env, env->FindClass(cls), list); +} + +} } diff --git a/libs/fbjni/src/main/cpp/include/jni/WeakReference.h b/libs/fbjni/src/main/cpp/include/jni/WeakReference.h new file mode 100644 index 000000000..e8bad1ace --- /dev/null +++ b/libs/fbjni/src/main/cpp/include/jni/WeakReference.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2015-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +#pragma once +#include +#include +#include +#include +#include + + +namespace facebook { +namespace jni { + +class FBEXPORT WeakReference : public Countable { +public: + typedef RefPtr Ptr; + WeakReference(jobject strongRef); + ~WeakReference(); + jweak weakRef() { + return m_weakReference; + } + +private: + jweak m_weakReference; +}; + +// This class is intended to take a weak reference and turn it into a strong +// local reference. Consequently, it should only be allocated on the stack. +class FBEXPORT ResolvedWeakReference : public noncopyable { +public: + ResolvedWeakReference(jobject weakRef); + ResolvedWeakReference(const RefPtr& weakRef); + ~ResolvedWeakReference(); + + operator jobject () { + return m_strongReference; + } + + explicit operator bool () { + return m_strongReference != nullptr; + } + +private: + jobject m_strongReference; +}; + +} } + diff --git a/libs/fbjni/src/main/cpp/include/jni/jni_helpers.h b/libs/fbjni/src/main/cpp/include/jni/jni_helpers.h new file mode 100644 index 000000000..b740d830b --- /dev/null +++ b/libs/fbjni/src/main/cpp/include/jni/jni_helpers.h @@ -0,0 +1,137 @@ +/* + * Copyright (c) 2015-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +#pragma once + +#include + +#include + +namespace facebook { + +/** + * Instructs the JNI environment to throw an exception. + * + * @param pEnv JNI environment + * @param szClassName class name to throw + * @param szFmt sprintf-style format string + * @param ... sprintf-style args + * @return 0 on success; a negative value on failure + */ +FBEXPORT jint throwException(JNIEnv* pEnv, const char* szClassName, const char* szFmt, va_list va_args); + +/** + * Instructs the JNI environment to throw a NoClassDefFoundError. + * + * @param pEnv JNI environment + * @param szFmt sprintf-style format string + * @param ... sprintf-style args + * @return 0 on success; a negative value on failure + */ +FBEXPORT jint throwNoClassDefError(JNIEnv* pEnv, const char* szFmt, ...); + +/** + * Instructs the JNI environment to throw a RuntimeException. + * + * @param pEnv JNI environment + * @param szFmt sprintf-style format string + * @param ... sprintf-style args + * @return 0 on success; a negative value on failure + */ +FBEXPORT jint throwRuntimeException(JNIEnv* pEnv, const char* szFmt, ...); + +/** + * Instructs the JNI environment to throw a IllegalArgumentException. + * + * @param pEnv JNI environment + * @param szFmt sprintf-style format string + * @param ... sprintf-style args + * @return 0 on success; a negative value on failure + */ +FBEXPORT jint throwIllegalArgumentException(JNIEnv* pEnv, const char* szFmt, ...); + +/** + * Instructs the JNI environment to throw a IllegalStateException. + * + * @param pEnv JNI environment + * @param szFmt sprintf-style format string + * @param ... sprintf-style args + * @return 0 on success; a negative value on failure + */ +FBEXPORT jint throwIllegalStateException(JNIEnv* pEnv, const char* szFmt, ...); + +/** + * Instructs the JNI environment to throw an IOException. + * + * @param pEnv JNI environment + * @param szFmt sprintf-style format string + * @param ... sprintf-style args + * @return 0 on success; a negative value on failure + */ +FBEXPORT jint throwIOException(JNIEnv* pEnv, const char* szFmt, ...); + +/** + * Instructs the JNI environment to throw an AssertionError. + * + * @param pEnv JNI environment + * @param szFmt sprintf-style format string + * @param ... sprintf-style args + * @return 0 on success; a negative value on failure + */ +FBEXPORT jint throwAssertionError(JNIEnv* pEnv, const char* szFmt, ...); + +/** + * Instructs the JNI environment to throw an OutOfMemoryError. + * + * @param pEnv JNI environment + * @param szFmt sprintf-style format string + * @param ... sprintf-style args + * @return 0 on success; a negative value on failure + */ +FBEXPORT jint throwOutOfMemoryError(JNIEnv* pEnv, const char* szFmt, ...); + +/** + * Finds the specified class. If it's not found, instructs the JNI environment to throw an + * exception. + * + * @param pEnv JNI environment + * @param szClassName the classname to find in JNI format (e.g. "java/lang/String") + * @return the class or NULL if not found (in which case a pending exception will be queued). This + * returns a global reference (JNIEnv::NewGlobalRef). + */ +FBEXPORT jclass findClassOrThrow(JNIEnv *pEnv, const char* szClassName); + +/** + * Finds the specified field of the specified class. If it's not found, instructs the JNI + * environment to throw an exception. + * + * @param pEnv JNI environment + * @param clazz the class to lookup the field in + * @param szFieldName the name of the field to find + * @param szSig the signature of the field + * @return the field or NULL if not found (in which case a pending exception will be queued) + */ +FBEXPORT jfieldID getFieldIdOrThrow(JNIEnv* pEnv, jclass clazz, const char* szFieldName, const char* szSig); + +/** + * Finds the specified method of the specified class. If it's not found, instructs the JNI + * environment to throw an exception. + * + * @param pEnv JNI environment + * @param clazz the class to lookup the method in + * @param szMethodName the name of the method to find + * @param szSig the signature of the method + * @return the method or NULL if not found (in which case a pending exception will be queued) + */ +FBEXPORT jmethodID getMethodIdOrThrow( + JNIEnv* pEnv, + jclass clazz, + const char* szMethodName, + const char* szSig); + +} // namespace facebook + diff --git a/libs/fbjni/src/main/cpp/jni/ByteBuffer.cpp b/libs/fbjni/src/main/cpp/jni/ByteBuffer.cpp new file mode 100644 index 000000000..b41a9d309 --- /dev/null +++ b/libs/fbjni/src/main/cpp/jni/ByteBuffer.cpp @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2016-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +#include + +#include + +#include + +namespace facebook { +namespace jni { + +namespace { +local_ref createEmpty() { + static auto cls = JByteBuffer::javaClassStatic(); + static auto meth = cls->getStaticMethod("allocateDirect"); + return meth(cls, 0); +} +} + +local_ref JByteBuffer::wrapBytes(uint8_t* data, size_t size) { + // env->NewDirectByteBuffer requires that size is positive. Android's + // dalvik returns an invalid result and Android's art aborts if size == 0. + // Workaround this by using a slow path through Java in that case. + if (!size) { + return createEmpty(); + } + auto res = adopt_local(static_cast(Environment::current()->NewDirectByteBuffer(data, size))); + FACEBOOK_JNI_THROW_PENDING_EXCEPTION(); + if (!res) { + throw std::runtime_error("Direct byte buffers are unsupported."); + } + return res; +} + +uint8_t* JByteBuffer::getDirectBytes() const { + if (!self()) { + throwNewJavaException("java/lang/NullPointerException", "java.lang.NullPointerException"); + } + void* bytes = Environment::current()->GetDirectBufferAddress(self()); + FACEBOOK_JNI_THROW_PENDING_EXCEPTION(); + if (!bytes) { + throw std::runtime_error( + isDirect() ? + "Attempt to get direct bytes of non-direct byte buffer." : + "Error getting direct bytes of byte buffer."); + } + return static_cast(bytes); +} + +size_t JByteBuffer::getDirectSize() const { + if (!self()) { + throwNewJavaException("java/lang/NullPointerException", "java.lang.NullPointerException"); + } + int size = Environment::current()->GetDirectBufferCapacity(self()); + FACEBOOK_JNI_THROW_PENDING_EXCEPTION(); + if (size < 0) { + throw std::runtime_error( + isDirect() ? + "Attempt to get direct size of non-direct byte buffer." : + "Error getting direct size of byte buffer."); + } + return static_cast(size); +} + +bool JByteBuffer::isDirect() const { + static auto meth = javaClassStatic()->getMethod("isDirect"); + return meth(self()); +} + +}} diff --git a/libs/fbjni/src/main/cpp/jni/Countable.cpp b/libs/fbjni/src/main/cpp/jni/Countable.cpp new file mode 100644 index 000000000..4e84a9f0e --- /dev/null +++ b/libs/fbjni/src/main/cpp/jni/Countable.cpp @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2015-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +#include +#include +#include +#include + +namespace facebook { +namespace jni { + +static jfieldID gCountableNativePtr; + +static RefPtr* rawCountableFromJava(JNIEnv* env, jobject obj) { + FBASSERT(obj); + return reinterpret_cast*>(env->GetLongField(obj, gCountableNativePtr)); +} + +const RefPtr& countableFromJava(JNIEnv* env, jobject obj) { + FBASSERT(obj); + return *rawCountableFromJava(env, obj); +} + +void setCountableForJava(JNIEnv* env, jobject obj, RefPtr&& countable) { + int oldValue = env->GetLongField(obj, gCountableNativePtr); + FBASSERTMSGF(oldValue == 0, "Cannot reinitialize object; expected nullptr, got %x", oldValue); + + FBASSERT(countable); + uintptr_t fieldValue = (uintptr_t) new RefPtr(std::move(countable)); + env->SetLongField(obj, gCountableNativePtr, fieldValue); +} + +/** + * NB: THREAD SAFETY (this comment also exists at Countable.java) + * + * This method deletes the corresponding native object on whatever thread the method is called + * on. In the common case when this is called by Countable#finalize(), this will be called on the + * system finalizer thread. If you manually call dispose on the Java object, the native object + * will be deleted synchronously on that thread. + */ +void dispose(JNIEnv* env, jobject obj) { + // Grab the pointer + RefPtr* countable = rawCountableFromJava(env, obj); + if (!countable) { + // That was easy. + return; + } + + // Clear out the old value to avoid double-frees + env->SetLongField(obj, gCountableNativePtr, 0); + + delete countable; +} + +void CountableOnLoad(JNIEnv* env) { + jclass countable = env->FindClass("com/facebook/jni/Countable"); + gCountableNativePtr = env->GetFieldID(countable, "mInstance", "J"); + registerNatives(env, countable, { + { "dispose", "()V", (void*) dispose }, + }); +} + +} } diff --git a/libs/fbjni/src/main/cpp/jni/Environment.cpp b/libs/fbjni/src/main/cpp/jni/Environment.cpp new file mode 100644 index 000000000..5be18b20f --- /dev/null +++ b/libs/fbjni/src/main/cpp/jni/Environment.cpp @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2015-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +#include +#include +#include +#include +#include +#include +#include + +#include + +namespace facebook { +namespace jni { + +namespace { +StaticInitialized> g_env; +JavaVM* g_vm = nullptr; + +struct JThreadScopeSupport : JavaClass { + static auto constexpr kJavaDescriptor = "Lcom/facebook/jni/ThreadScopeSupport;"; + + // These reinterpret_casts are a totally dangerous pattern. Don't use them. Use HybridData instead. + static void runStdFunction(std::function&& func) { + static auto method = javaClassStatic()->getStaticMethod("runStdFunction"); + method(javaClassStatic(), reinterpret_cast(&func)); + } + + static void runStdFunctionImpl(alias_ref, jlong ptr) { + (*reinterpret_cast*>(ptr))(); + } + + static void OnLoad() { + // We need the javaClassStatic so that the class lookup is cached and that + // runStdFunction can be called from a ThreadScope-attached thread. + javaClassStatic()->registerNatives({ + makeNativeMethod("runStdFunctionImpl", runStdFunctionImpl), + }); + } +}; +} + +/* static */ +JNIEnv* Environment::current() { + JNIEnv* env = g_env->get(); + if ((env == nullptr) && (g_vm != nullptr)) { + if (g_vm->GetEnv((void**) &env, JNI_VERSION_1_6) != JNI_OK) { + FBLOGE("Error retrieving JNI Environment, thread is probably not attached to JVM"); + // TODO(cjhopman): This should throw an exception. + env = nullptr; + } else { + g_env->reset(env); + } + } + return env; +} + +/* static */ +void Environment::detachCurrentThread() { + auto env = g_env->get(); + if (env) { + FBASSERT(g_vm); + g_vm->DetachCurrentThread(); + g_env->reset(); + } +} + +struct EnvironmentInitializer { + EnvironmentInitializer(JavaVM* vm) { + FBASSERT(!g_vm); + FBASSERT(vm); + g_vm = vm; + g_env.initialize([] (void*) {}); + } +}; + +/* static */ +void Environment::initialize(JavaVM* vm) { + static EnvironmentInitializer init(vm); +} + +/* static */ +JNIEnv* Environment::ensureCurrentThreadIsAttached() { + auto env = g_env->get(); + if (!env) { + FBASSERT(g_vm); + g_vm->AttachCurrentThread(&env, nullptr); + g_env->reset(env); + } + return env; +} + +ThreadScope::ThreadScope() + : attachedWithThisScope_(false) { + JNIEnv* env = nullptr; + if (g_vm->GetEnv((void**) &env, JNI_VERSION_1_6) != JNI_EDETACHED) { + return; + } + env = facebook::jni::Environment::ensureCurrentThreadIsAttached(); + FBASSERT(env); + attachedWithThisScope_ = true; +} + +ThreadScope::~ThreadScope() { + if (attachedWithThisScope_) { + Environment::detachCurrentThread(); + } +} + +/* static */ +void ThreadScope::OnLoad() { + // These classes are required for ScopeWithClassLoader. Ensure they are looked up when loading. + JThreadScopeSupport::OnLoad(); +} + +/* static */ +void ThreadScope::WithClassLoader(std::function&& runnable) { + // TODO(cjhopman): If the classloader is already available in this scope, we + // shouldn't have to jump through java. + ThreadScope ts; + JThreadScopeSupport::runStdFunction(std::move(runnable)); +} + +} } + diff --git a/libs/fbjni/src/main/cpp/jni/Exceptions.cpp b/libs/fbjni/src/main/cpp/jni/Exceptions.cpp new file mode 100644 index 000000000..a425dc476 --- /dev/null +++ b/libs/fbjni/src/main/cpp/jni/Exceptions.cpp @@ -0,0 +1,283 @@ +/* + * Copyright (c) 2015-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + + +namespace facebook { +namespace jni { + +namespace { +class JRuntimeException : public JavaClass { + public: + static auto constexpr kJavaDescriptor = "Ljava/lang/RuntimeException;"; + + static local_ref create(const char* str) { + return newInstance(make_jstring(str)); + } + + static local_ref create() { + return newInstance(); + } +}; + +class JIOException : public JavaClass { + public: + static auto constexpr kJavaDescriptor = "Ljava/io/IOException;"; + + static local_ref create(const char* str) { + return newInstance(make_jstring(str)); + } +}; + +class JOutOfMemoryError : public JavaClass { + public: + static auto constexpr kJavaDescriptor = "Ljava/lang/OutOfMemoryError;"; + + static local_ref create(const char* str) { + return newInstance(make_jstring(str)); + } +}; + +class JArrayIndexOutOfBoundsException : public JavaClass { + public: + static auto constexpr kJavaDescriptor = "Ljava/lang/ArrayIndexOutOfBoundsException;"; + + static local_ref create(const char* str) { + return newInstance(make_jstring(str)); + } +}; + +class JUnknownCppException : public JavaClass { + public: + static auto constexpr kJavaDescriptor = "Lcom/facebook/jni/UnknownCppException;"; + + static local_ref create() { + return newInstance(); + } + + static local_ref create(const char* str) { + return newInstance(make_jstring(str)); + } +}; + +class JCppSystemErrorException : public JavaClass { + public: + static auto constexpr kJavaDescriptor = "Lcom/facebook/jni/CppSystemErrorException;"; + + static local_ref create(const std::system_error& e) { + return newInstance(make_jstring(e.what()), e.code().value()); + } +}; + +// Exception throwing & translating functions ////////////////////////////////////////////////////// + +// Functions that throw Java exceptions + +void setJavaExceptionAndAbortOnFailure(alias_ref throwable) { + auto env = Environment::current(); + if (throwable) { + env->Throw(throwable.get()); + } + if (env->ExceptionCheck() != JNI_TRUE) { + std::abort(); + } +} + +} + +// Functions that throw C++ exceptions + +// TODO(T6618159) Take a stack dump here to save context if it results in a crash when propagated +void throwPendingJniExceptionAsCppException() { + JNIEnv* env = Environment::current(); + if (env->ExceptionCheck() == JNI_FALSE) { + return; + } + + auto throwable = adopt_local(env->ExceptionOccurred()); + if (!throwable) { + throw std::runtime_error("Unable to get pending JNI exception."); + } + env->ExceptionClear(); + + throw JniException(throwable); +} + +void throwCppExceptionIf(bool condition) { + if (!condition) { + return; + } + + auto env = Environment::current(); + if (env->ExceptionCheck() == JNI_TRUE) { + throwPendingJniExceptionAsCppException(); + return; + } + + throw JniException(); +} + +void throwNewJavaException(jthrowable throwable) { + throw JniException(wrap_alias(throwable)); +} + +void throwNewJavaException(const char* throwableName, const char* msg) { + // If anything of the fbjni calls fail, an exception of a suitable + // form will be thrown, which is what we want. + auto throwableClass = findClassLocal(throwableName); + auto throwable = throwableClass->newObject( + throwableClass->getConstructor(), + make_jstring(msg).release()); + throwNewJavaException(throwable.get()); +} + +// Translate C++ to Java Exception + +namespace { + +// The implementation std::rethrow_if_nested uses a dynamic_cast to determine +// if the exception is a nested_exception. If the exception is from a library +// built with -fno-rtti, then that will crash. This avoids that. +void rethrow_if_nested() { + try { + throw; + } catch (const std::nested_exception& e) { + e.rethrow_nested(); + } catch (...) { + } +} + +// For each exception in the chain of the currently handled exception, func +// will be called with that exception as the currently handled exception (in +// reverse order, i.e. innermost first). +void denest(std::function func) { + try { + throw; + } catch (const std::exception& e) { + try { + rethrow_if_nested(); + } catch (...) { + denest(func); + } + func(); + } catch (...) { + func(); + } +} +} + +void translatePendingCppExceptionToJavaException() noexcept { + local_ref previous; + auto func = [&previous] () { + local_ref current; + try { + throw; + } catch(const JniException& ex) { + current = ex.getThrowable(); + } catch(const std::ios_base::failure& ex) { + current = JIOException::create(ex.what()); + } catch(const std::bad_alloc& ex) { + current = JOutOfMemoryError::create(ex.what()); + } catch(const std::out_of_range& ex) { + current = JArrayIndexOutOfBoundsException::create(ex.what()); + } catch(const std::system_error& ex) { + current = JCppSystemErrorException::create(ex); + } catch(const std::runtime_error& ex) { + current = JRuntimeException::create(ex.what()); + } catch(const std::exception& ex) { + current = JCppException::create(ex.what()); + } catch(const char* msg) { + current = JUnknownCppException::create(msg); + } catch(...) { + current = JUnknownCppException::create(); + } + if (previous) { + current->initCause(previous); + } + previous = current; + }; + + try { + denest(func); + setJavaExceptionAndAbortOnFailure(previous); + } catch (std::exception& e) { + FBLOGE("unexpected exception in translatePendingCppExceptionToJavaException: %s", e.what()); + // rethrow the exception and let the noexcept handling abort. + throw; + } catch (...) { + FBLOGE("unexpected exception in translatePendingCppExceptionToJavaException"); + throw; + } +} + +// JniException //////////////////////////////////////////////////////////////////////////////////// + +const std::string JniException::kExceptionMessageFailure_ = "Unable to get exception message."; + +JniException::JniException() : JniException(JRuntimeException::create()) { } + +JniException::JniException(alias_ref throwable) : isMessageExtracted_(false) { + throwable_ = make_global(throwable); +} + +JniException::JniException(JniException &&rhs) + : throwable_(std::move(rhs.throwable_)), + what_(std::move(rhs.what_)), + isMessageExtracted_(rhs.isMessageExtracted_) { +} + +JniException::JniException(const JniException &rhs) + : what_(rhs.what_), isMessageExtracted_(rhs.isMessageExtracted_) { + throwable_ = make_global(rhs.throwable_); +} + +JniException::~JniException() { + ThreadScope ts; + throwable_.reset(); +} + +local_ref JniException::getThrowable() const noexcept { + return make_local(throwable_); +} + +// TODO 6900503: consider making this thread-safe. +void JniException::populateWhat() const noexcept { + ThreadScope ts; + try { + what_ = throwable_->toString(); + isMessageExtracted_ = true; + } catch(...) { + what_ = kExceptionMessageFailure_; + } +} + +const char* JniException::what() const noexcept { + if (!isMessageExtracted_) { + populateWhat(); + } + return what_.c_str(); +} + +void JniException::setJavaException() const noexcept { + setJavaExceptionAndAbortOnFailure(throwable_); +} + +}} diff --git a/libs/fbjni/src/main/cpp/jni/Hybrid.cpp b/libs/fbjni/src/main/cpp/jni/Hybrid.cpp new file mode 100644 index 000000000..45d5bff0b --- /dev/null +++ b/libs/fbjni/src/main/cpp/jni/Hybrid.cpp @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2015-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +#include "fb/fbjni.h" + + +namespace facebook { +namespace jni { + +namespace detail { + +void HybridData::setNativePointer(std::unique_ptr new_value) { + static auto pointerField = getClass()->getField("mNativePointer"); + auto* old_value = reinterpret_cast(getFieldValue(pointerField)); + if (new_value) { + // Modify should only ever be called once with a non-null + // new_value. If this happens again it's a programmer error, so + // blow up. + FBASSERTMSGF(old_value == 0, "Attempt to set C++ native pointer twice"); + } else if (old_value == 0) { + return; + } + // delete on a null pointer is defined to be a noop. + delete old_value; + // This releases ownership from the unique_ptr, and passes the pointer, and + // ownership of it, to HybridData which is managed by the java GC. The + // finalizer on hybridData calls resetNative which will delete the object, if + // resetNative has not already been called. + setFieldValue(pointerField, reinterpret_cast(new_value.release())); +} + +BaseHybridClass* HybridData::getNativePointer() { + static auto pointerField = getClass()->getField("mNativePointer"); + auto* value = reinterpret_cast(getFieldValue(pointerField)); + if (!value) { + throwNewJavaException("java/lang/NullPointerException", "java.lang.NullPointerException"); + } + return value; +} + +local_ref HybridData::create() { + return newInstance(); +} + +} + +namespace { +void resetNative(alias_ref jthis) { + jthis->setNativePointer(nullptr); +} +} + +void HybridDataOnLoad() { + registerNatives("com/facebook/jni/HybridData", { + makeNativeMethod("resetNative", resetNative), + }); +} + +}} diff --git a/libs/fbjni/src/main/cpp/jni/JThrowable.cpp b/libs/fbjni/src/main/cpp/jni/JThrowable.cpp new file mode 100644 index 000000000..cb2c8ae55 --- /dev/null +++ b/libs/fbjni/src/main/cpp/jni/JThrowable.cpp @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2015-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +#include "fb/fbjni.h" +#include + +std::string JThrowable::getStackTrace() const { + static auto getStackTraceMethod = javaClassStatic() + ->getMethod()>("getStackTrace"); + + std::ostringstream os; + + auto stackTrace = getStackTraceMethod(self()); + for (size_t i = 0; i < stackTrace->size(); ++i) { + os << facebook::jni::adopt_local((*stackTrace)[i])->toString() << ' '; + } + + return os.str(); +} diff --git a/libs/fbjni/src/main/cpp/jni/LocalString.cpp b/libs/fbjni/src/main/cpp/jni/LocalString.cpp new file mode 100644 index 000000000..aca121438 --- /dev/null +++ b/libs/fbjni/src/main/cpp/jni/LocalString.cpp @@ -0,0 +1,310 @@ +/* + * Copyright (c) 2015-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +#include +#include +#include + +#include + +namespace facebook { +namespace jni { + +namespace { + +const uint16_t kUtf8OneByteBoundary = 0x80; +const uint16_t kUtf8TwoBytesBoundary = 0x800; +const uint16_t kUtf16HighSubLowBoundary = 0xD800; +const uint16_t kUtf16HighSubHighBoundary = 0xDC00; +const uint16_t kUtf16LowSubHighBoundary = 0xE000; + +inline void encode3ByteUTF8(char32_t code, uint8_t* out) { + FBASSERTMSGF((code & 0xffff0000) == 0, "3 byte utf-8 encodings only valid for up to 16 bits"); + + out[0] = 0xE0 | (code >> 12); + out[1] = 0x80 | ((code >> 6) & 0x3F); + out[2] = 0x80 | (code & 0x3F); +} + +inline char32_t decode3ByteUTF8(const uint8_t* in) { + return (((in[0] & 0x0f) << 12) | + ((in[1] & 0x3f) << 6) | + ( in[2] & 0x3f)); +} + +inline void encode4ByteUTF8(char32_t code, std::string& out, size_t offset) { + FBASSERTMSGF((code & 0xfff80000) == 0, "4 byte utf-8 encodings only valid for up to 21 bits"); + + out[offset] = (char) (0xF0 | (code >> 18)); + out[offset + 1] = (char) (0x80 | ((code >> 12) & 0x3F)); + out[offset + 2] = (char) (0x80 | ((code >> 6) & 0x3F)); + out[offset + 3] = (char) (0x80 | (code & 0x3F)); +} + +template +inline bool isFourByteUTF8Encoding(const T* utf8) { + return ((*utf8 & 0xF8) == 0xF0); +} + +} + +namespace detail { + +size_t modifiedLength(const std::string& str) { + // Scan for supplementary characters + size_t j = 0; + for (size_t i = 0; i < str.size(); ) { + if (str[i] == 0) { + i += 1; + j += 2; + } else if (i + 4 > str.size() || + !isFourByteUTF8Encoding(&(str[i]))) { + // See the code in utf8ToModifiedUTF8 for what's happening here. + i += 1; + j += 1; + } else { + i += 4; + j += 6; + } + } + + return j; +} + +// returns modified utf8 length; *length is set to strlen(str) +size_t modifiedLength(const uint8_t* str, size_t* length) { + // NUL-terminated: Scan for length and supplementary characters + size_t i = 0; + size_t j = 0; + while (str[i] != 0) { + if (str[i + 1] == 0 || + str[i + 2] == 0 || + str[i + 3] == 0 || + !isFourByteUTF8Encoding(&(str[i]))) { + i += 1; + j += 1; + } else { + i += 4; + j += 6; + } + } + + *length = i; + return j; +} + +void utf8ToModifiedUTF8(const uint8_t* utf8, size_t len, uint8_t* modified, size_t modifiedBufLen) +{ + size_t j = 0; + for (size_t i = 0; i < len; ) { + FBASSERTMSGF(j < modifiedBufLen, "output buffer is too short"); + if (utf8[i] == 0) { + FBASSERTMSGF(j + 1 < modifiedBufLen, "output buffer is too short"); + modified[j] = 0xc0; + modified[j + 1] = 0x80; + i += 1; + j += 2; + continue; + } + + if (i + 4 > len || + !isFourByteUTF8Encoding(utf8 + i)) { + // If the input is too short for this to be a four-byte + // encoding, or it isn't one for real, just copy it on through. + modified[j] = utf8[i]; + i++; + j++; + continue; + } + + // Convert 4 bytes of input to 2 * 3 bytes of output + char32_t code = (((utf8[i] & 0x07) << 18) | + ((utf8[i + 1] & 0x3f) << 12) | + ((utf8[i + 2] & 0x3f) << 6) | + ( utf8[i + 3] & 0x3f)); + char32_t first; + char32_t second; + + if (code > 0x10ffff) { + // These could be valid utf-8, but cannot be represented as modified UTF-8, due to the 20-bit + // limit on that representation. Encode two replacement characters, so the expected output + // length lines up. + const char32_t kUnicodeReplacementChar = 0xfffd; + first = kUnicodeReplacementChar; + second = kUnicodeReplacementChar; + } else { + // split into surrogate pair + first = ((code - 0x010000) >> 10) | 0xd800; + second = ((code - 0x010000) & 0x3ff) | 0xdc00; + } + + // encode each as a 3 byte surrogate value + FBASSERTMSGF(j + 5 < modifiedBufLen, "output buffer is too short"); + encode3ByteUTF8(first, modified + j); + encode3ByteUTF8(second, modified + j + 3); + i += 4; + j += 6; + } + + FBASSERTMSGF(j < modifiedBufLen, "output buffer is too short"); + modified[j++] = '\0'; +} + +std::string modifiedUTF8ToUTF8(const uint8_t* modified, size_t len) noexcept { + // Converting from modified utf8 to utf8 will always shrink, so this will always be sufficient + std::string utf8(len, 0); + size_t j = 0; + for (size_t i = 0; i < len; ) { + // surrogate pair: 1101 10xx xxxx xxxx 1101 11xx xxxx xxxx + // encoded pair: 1110 1101 1010 xxxx 10xx xxxx 1110 1101 1011 xxxx 10xx xxxx + + if (len >= i + 6 && + modified[i] == 0xed && + (modified[i + 1] & 0xf0) == 0xa0 && + modified[i + 3] == 0xed && + (modified[i + 4] & 0xf0) == 0xb0) { + // Valid surrogate pair + char32_t pair1 = decode3ByteUTF8(modified + i); + char32_t pair2 = decode3ByteUTF8(modified + i + 3); + char32_t ch = 0x10000 + (((pair1 & 0x3ff) << 10) | + ( pair2 & 0x3ff)); + encode4ByteUTF8(ch, utf8, j); + i += 6; + j += 4; + continue; + } else if (len >= i + 2 && + modified[i] == 0xc0 && + modified[i + 1] == 0x80) { + utf8[j] = 0; + i += 2; + j += 1; + continue; + } + + // copy one byte. This might be a one, two, or three-byte encoding. It might be an invalid + // encoding of some sort, but garbage in garbage out is ok. + + utf8[j] = (char) modified[i]; + i++; + j++; + } + + utf8.resize(j); + + return utf8; +} + +// Calculate how many bytes are needed to convert an UTF16 string into UTF8 +// UTF16 string +size_t utf16toUTF8Length(const uint16_t* utf16String, size_t utf16StringLen) { + if (!utf16String || utf16StringLen == 0) { + return 0; + } + + uint32_t utf8StringLen = 0; + auto utf16StringEnd = utf16String + utf16StringLen; + auto idx16 = utf16String; + while (idx16 < utf16StringEnd) { + auto ch = *idx16++; + if (ch < kUtf8OneByteBoundary) { + utf8StringLen++; + } else if (ch < kUtf8TwoBytesBoundary) { + utf8StringLen += 2; + } else if ( + (ch >= kUtf16HighSubLowBoundary) && (ch < kUtf16HighSubHighBoundary) && + (idx16 < utf16StringEnd) && + (*idx16 >= kUtf16HighSubHighBoundary) && (*idx16 < kUtf16LowSubHighBoundary)) { + utf8StringLen += 4; + idx16++; + } else { + utf8StringLen += 3; + } + } + + return utf8StringLen; +} + +std::string utf16toUTF8(const uint16_t* utf16String, size_t utf16StringLen) noexcept { + if (!utf16String || utf16StringLen <= 0) { + return ""; + } + + std::string utf8String(utf16toUTF8Length(utf16String, utf16StringLen), '\0'); + auto idx8 = utf8String.begin(); + auto idx16 = utf16String; + auto utf16StringEnd = utf16String + utf16StringLen; + while (idx16 < utf16StringEnd) { + auto ch = *idx16++; + if (ch < kUtf8OneByteBoundary) { + *idx8++ = (ch & 0x7F); + } else if (ch < kUtf8TwoBytesBoundary) { + *idx8++ = 0b11000000 | (ch >> 6); + *idx8++ = 0b10000000 | (ch & 0x3F); + } else if ( + (ch >= kUtf16HighSubLowBoundary) && (ch < kUtf16HighSubHighBoundary) && + (idx16 < utf16StringEnd) && + (*idx16 >= kUtf16HighSubHighBoundary) && (*idx16 < kUtf16LowSubHighBoundary)) { + auto ch2 = *idx16++; + uint8_t trunc_byte = (((ch >> 6) & 0x0F) + 1); + *idx8++ = 0b11110000 | (trunc_byte >> 2); + *idx8++ = 0b10000000 | ((trunc_byte & 0x03) << 4) | ((ch >> 2) & 0x0F); + *idx8++ = 0b10000000 | ((ch & 0x03) << 4) | ((ch2 >> 6) & 0x0F); + *idx8++ = 0b10000000 | (ch2 & 0x3F); + } else { + *idx8++ = 0b11100000 | (ch >> 12); + *idx8++ = 0b10000000 | ((ch >> 6) & 0x3F); + *idx8++ = 0b10000000 | (ch & 0x3F); + } + } + + return utf8String; +} + +} + +LocalString::LocalString(const std::string& str) +{ + size_t modlen = detail::modifiedLength(str); + if (modlen == str.size()) { + // no supplementary characters, build jstring from input buffer + m_string = Environment::current()->NewStringUTF(str.data()); + return; + } + auto modified = std::vector(modlen + 1); // allocate extra byte for \0 + detail::utf8ToModifiedUTF8( + reinterpret_cast(str.data()), str.size(), + reinterpret_cast(modified.data()), modified.size()); + m_string = Environment::current()->NewStringUTF(modified.data()); +} + +LocalString::LocalString(const char* str) +{ + size_t len; + size_t modlen = detail::modifiedLength(reinterpret_cast(str), &len); + if (modlen == len) { + // no supplementary characters, build jstring from input buffer + m_string = Environment::current()->NewStringUTF(str); + return; + } + auto modified = std::vector(modlen + 1); // allocate extra byte for \0 + detail::utf8ToModifiedUTF8( + reinterpret_cast(str), len, + reinterpret_cast(modified.data()), modified.size()); + m_string = Environment::current()->NewStringUTF(modified.data()); +} + +LocalString::~LocalString() { + Environment::current()->DeleteLocalRef(m_string); +} + +std::string fromJString(JNIEnv* env, jstring str) { + auto utf16String = JStringUtf16Extractor(env, str); + auto length = env->GetStringLength(str); + return detail::utf16toUTF8(utf16String, length); +} + +} } diff --git a/libs/fbjni/src/main/cpp/jni/OnLoad.cpp b/libs/fbjni/src/main/cpp/jni/OnLoad.cpp new file mode 100644 index 000000000..9ba476055 --- /dev/null +++ b/libs/fbjni/src/main/cpp/jni/OnLoad.cpp @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2015-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +#include +#include +#include +#include + +using namespace facebook::jni; + +void initialize_fbjni() { + CountableOnLoad(Environment::current()); + HybridDataOnLoad(); + JNativeRunnable::OnLoad(); + ThreadScope::OnLoad(); +} diff --git a/libs/fbjni/src/main/cpp/jni/References.cpp b/libs/fbjni/src/main/cpp/jni/References.cpp new file mode 100644 index 000000000..e838de1f0 --- /dev/null +++ b/libs/fbjni/src/main/cpp/jni/References.cpp @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2015-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +#include + +namespace facebook { +namespace jni { + +JniLocalScope::JniLocalScope(JNIEnv* env, jint capacity) + : env_(env) { + hasFrame_ = false; + auto pushResult = env->PushLocalFrame(capacity); + FACEBOOK_JNI_THROW_EXCEPTION_IF(pushResult < 0); + hasFrame_ = true; +} + +JniLocalScope::~JniLocalScope() { + if (hasFrame_) { + env_->PopLocalFrame(nullptr); + } +} + +namespace internal { + +// Default implementation always returns true. +// Platform-specific sources can override this. +bool doesGetObjectRefTypeWork() __attribute__ ((weak)); +bool doesGetObjectRefTypeWork() { + return true; +} + +} + +} +} diff --git a/libs/fbjni/src/main/cpp/jni/WeakReference.cpp b/libs/fbjni/src/main/cpp/jni/WeakReference.cpp new file mode 100644 index 000000000..ad0e0f1c7 --- /dev/null +++ b/libs/fbjni/src/main/cpp/jni/WeakReference.cpp @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2015-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +#include +#include + +namespace facebook { +namespace jni { + +WeakReference::WeakReference(jobject strongRef) : + m_weakReference(Environment::current()->NewWeakGlobalRef(strongRef)) +{ +} + +WeakReference::~WeakReference() { + auto env = Environment::current(); + FBASSERTMSGF(env, "Attempt to delete jni::WeakReference from non-JNI thread"); + env->DeleteWeakGlobalRef(m_weakReference); +} + +ResolvedWeakReference::ResolvedWeakReference(jobject weakRef) : + m_strongReference(Environment::current()->NewLocalRef(weakRef)) +{ +} + +ResolvedWeakReference::ResolvedWeakReference(const RefPtr& weakRef) : + m_strongReference(Environment::current()->NewLocalRef(weakRef->weakRef())) +{ +} + +ResolvedWeakReference::~ResolvedWeakReference() { + if (m_strongReference) + Environment::current()->DeleteLocalRef(m_strongReference); +} + +} } + diff --git a/libs/fbjni/src/main/cpp/jni/fbjni.cpp b/libs/fbjni/src/main/cpp/jni/fbjni.cpp new file mode 100644 index 000000000..d07d62ffa --- /dev/null +++ b/libs/fbjni/src/main/cpp/jni/fbjni.cpp @@ -0,0 +1,194 @@ +/* + * Copyright (c) 2015-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +#include + +#include +#include +#include +#include + +namespace facebook { +namespace jni { + +jint initialize(JavaVM* vm, std::function&& init_fn) noexcept { + static std::once_flag flag{}; + // TODO (t7832883): DTRT when we have exception pointers + static auto error_msg = std::string{"Failed to initialize fbjni"}; + static auto error_occured = false; + + std::call_once(flag, [vm] { + try { + Environment::initialize(vm); + } catch (std::exception& ex) { + error_occured = true; + try { + error_msg = std::string{"Failed to initialize fbjni: "} + ex.what(); + } catch (...) { + // Ignore, we already have a fall back message + } + } catch (...) { + error_occured = true; + } + }); + + try { + if (error_occured) { + throw std::runtime_error(error_msg); + } + + init_fn(); + } catch (const std::exception& e) { + FBLOGE("error %s", e.what()); + translatePendingCppExceptionToJavaException(); + } catch (...) { + translatePendingCppExceptionToJavaException(); + // So Java will handle the translated exception, fall through and + // return a good version number. + } + return JNI_VERSION_1_6; +} + +alias_ref findClassStatic(const char* name) { + const auto env = internal::getEnv(); + if (!env) { + throw std::runtime_error("Unable to retrieve JNIEnv*."); + } + auto cls = env->FindClass(name); + FACEBOOK_JNI_THROW_EXCEPTION_IF(!cls); + auto leaking_ref = (jclass)env->NewGlobalRef(cls); + FACEBOOK_JNI_THROW_EXCEPTION_IF(!leaking_ref); + return wrap_alias(leaking_ref); +} + +local_ref findClassLocal(const char* name) { + const auto env = internal::getEnv(); + if (!env) { + throw std::runtime_error("Unable to retrieve JNIEnv*."); + } + auto cls = env->FindClass(name); + FACEBOOK_JNI_THROW_EXCEPTION_IF(!cls); + return adopt_local(cls); +} + + +// jstring ///////////////////////////////////////////////////////////////////////////////////////// + +std::string JString::toStdString() const { + const auto env = internal::getEnv(); + auto utf16String = JStringUtf16Extractor(env, self()); + auto length = env->GetStringLength(self()); + return detail::utf16toUTF8(utf16String, length); +} + +local_ref make_jstring(const char* utf8) { + if (!utf8) { + return {}; + } + const auto env = internal::getEnv(); + size_t len; + size_t modlen = detail::modifiedLength(reinterpret_cast(utf8), &len); + jstring result; + if (modlen == len) { + // The only difference between utf8 and modifiedUTF8 is in encoding 4-byte UTF8 chars + // and '\0' that is encoded on 2 bytes. + // + // Since modifiedUTF8-encoded string can be no shorter than it's UTF8 conterpart we + // know that if those two strings are of the same length we don't need to do any + // conversion -> no 4-byte chars nor '\0'. + result = env->NewStringUTF(utf8); + } else { + auto modified = std::vector(modlen + 1); // allocate extra byte for \0 + detail::utf8ToModifiedUTF8( + reinterpret_cast(utf8), len, + reinterpret_cast(modified.data()), modified.size()); + result = env->NewStringUTF(modified.data()); + } + FACEBOOK_JNI_THROW_PENDING_EXCEPTION(); + return adopt_local(result); +} + + +// JniPrimitiveArrayFunctions ////////////////////////////////////////////////////////////////////// + +#pragma push_macro("DEFINE_PRIMITIVE_METHODS") +#undef DEFINE_PRIMITIVE_METHODS +#define DEFINE_PRIMITIVE_METHODS(TYPE, NAME, SMALLNAME) \ + \ +template<> \ +FBEXPORT \ +TYPE* JPrimitiveArray::getElements(jboolean* isCopy) { \ + auto env = internal::getEnv(); \ + TYPE* res = env->Get ## NAME ## ArrayElements(self(), isCopy); \ + FACEBOOK_JNI_THROW_PENDING_EXCEPTION(); \ + return res; \ +} \ + \ +template<> \ +FBEXPORT \ +void JPrimitiveArray::releaseElements( \ + TYPE* elements, jint mode) { \ + auto env = internal::getEnv(); \ + env->Release ## NAME ## ArrayElements(self(), elements, mode); \ + FACEBOOK_JNI_THROW_PENDING_EXCEPTION(); \ +} \ + \ +template<> \ +FBEXPORT \ +void JPrimitiveArray::getRegion( \ + jsize start, jsize length, TYPE* buf) { \ + auto env = internal::getEnv(); \ + env->Get ## NAME ## ArrayRegion(self(), start, length, buf); \ + FACEBOOK_JNI_THROW_PENDING_EXCEPTION(); \ +} \ + \ +template<> \ +FBEXPORT \ +void JPrimitiveArray::setRegion( \ + jsize start, jsize length, const TYPE* elements) { \ + auto env = internal::getEnv(); \ + env->Set ## NAME ## ArrayRegion(self(), start, length, elements); \ + FACEBOOK_JNI_THROW_PENDING_EXCEPTION(); \ +} \ + \ +FBEXPORT \ +local_ref make_ ## SMALLNAME ## _array(jsize size) { \ + auto array = internal::getEnv()->New ## NAME ## Array(size); \ + FACEBOOK_JNI_THROW_EXCEPTION_IF(!array); \ + return adopt_local(array); \ +} \ + \ +template<> \ +FBEXPORT \ +local_ref JArray ## NAME::newArray(size_t count) { \ + return make_ ## SMALLNAME ## _array(count); \ +} \ + \ + +DEFINE_PRIMITIVE_METHODS(jboolean, Boolean, boolean) +DEFINE_PRIMITIVE_METHODS(jbyte, Byte, byte) +DEFINE_PRIMITIVE_METHODS(jchar, Char, char) +DEFINE_PRIMITIVE_METHODS(jshort, Short, short) +DEFINE_PRIMITIVE_METHODS(jint, Int, int) +DEFINE_PRIMITIVE_METHODS(jlong, Long, long) +DEFINE_PRIMITIVE_METHODS(jfloat, Float, float) +DEFINE_PRIMITIVE_METHODS(jdouble, Double, double) +#pragma pop_macro("DEFINE_PRIMITIVE_METHODS") + +// Internal debug ///////////////////////////////////////////////////////////////////////////////// + +namespace internal { + +FBEXPORT ReferenceStats g_reference_stats; + +FBEXPORT void facebook::jni::internal::ReferenceStats::reset() noexcept { + locals_deleted = globals_deleted = weaks_deleted = 0; +} + +} + +}} diff --git a/libs/fbjni/src/main/cpp/jni/jni_helpers.cpp b/libs/fbjni/src/main/cpp/jni/jni_helpers.cpp new file mode 100644 index 000000000..c1bfb5cd8 --- /dev/null +++ b/libs/fbjni/src/main/cpp/jni/jni_helpers.cpp @@ -0,0 +1,195 @@ +/* + * Copyright (c) 2015-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +#include +#include +#include + +#include + +#define MSG_SIZE 1024 + +namespace facebook { + +/** + * Instructs the JNI environment to throw an exception. + * + * @param pEnv JNI environment + * @param szClassName class name to throw + * @param szFmt sprintf-style format string + * @param ... sprintf-style args + * @return 0 on success; a negative value on failure + */ +jint throwException(JNIEnv* pEnv, const char* szClassName, const char* szFmt, va_list va_args) { + char szMsg[MSG_SIZE]; + vsnprintf(szMsg, MSG_SIZE, szFmt, va_args); + jclass exClass = pEnv->FindClass(szClassName); + return pEnv->ThrowNew(exClass, szMsg); +} + +/** + * Instructs the JNI environment to throw a NoClassDefFoundError. + * + * @param pEnv JNI environment + * @param szFmt sprintf-style format string + * @param ... sprintf-style args + * @return 0 on success; a negative value on failure + */ +jint throwNoClassDefError(JNIEnv* pEnv, const char* szFmt, ...) { + va_list va_args; + va_start(va_args, szFmt); + jint ret = throwException(pEnv, "java/lang/NoClassDefFoundError", szFmt, va_args); + va_end(va_args); + return ret; +} + +/** + * Instructs the JNI environment to throw a RuntimeException. + * + * @param pEnv JNI environment + * @param szFmt sprintf-style format string + * @param ... sprintf-style args + * @return 0 on success; a negative value on failure + */ +jint throwRuntimeException(JNIEnv* pEnv, const char* szFmt, ...) { + va_list va_args; + va_start(va_args, szFmt); + jint ret = throwException(pEnv, "java/lang/RuntimeException", szFmt, va_args); + va_end(va_args); + return ret; +} + +/** + * Instructs the JNI environment to throw an IllegalArgumentException. + * + * @param pEnv JNI environment + * @param szFmt sprintf-style format string + * @param ... sprintf-style args + * @return 0 on success; a negative value on failure + */ +jint throwIllegalArgumentException(JNIEnv* pEnv, const char* szFmt, ...) { + va_list va_args; + va_start(va_args, szFmt); + jint ret = throwException(pEnv, "java/lang/IllegalArgumentException", szFmt, va_args); + va_end(va_args); + return ret; +} + +/** + * Instructs the JNI environment to throw an IllegalStateException. + * + * @param pEnv JNI environment + * @param szFmt sprintf-style format string + * @param ... sprintf-style args + * @return 0 on success; a negative value on failure + */ +jint throwIllegalStateException(JNIEnv* pEnv, const char* szFmt, ...) { + va_list va_args; + va_start(va_args, szFmt); + jint ret = throwException(pEnv, "java/lang/IllegalStateException", szFmt, va_args); + va_end(va_args); + return ret; +} + +/** + * Instructs the JNI environment to throw an OutOfMemoryError. + * + * @param pEnv JNI environment + * @param szFmt sprintf-style format string + * @param ... sprintf-style args + * @return 0 on success; a negative value on failure + */ +jint throwOutOfMemoryError(JNIEnv* pEnv, const char* szFmt, ...) { + va_list va_args; + va_start(va_args, szFmt); + jint ret = throwException(pEnv, "java/lang/OutOfMemoryError", szFmt, va_args); + va_end(va_args); + return ret; +} + +/** + * Instructs the JNI environment to throw an AssertionError. + * + * @param pEnv JNI environment + * @param szFmt sprintf-style format string + * @param ... sprintf-style args + * @return 0 on success; a negative value on failure + */ +jint throwAssertionError(JNIEnv* pEnv, const char* szFmt, ...) { + va_list va_args; + va_start(va_args, szFmt); + jint ret = throwException(pEnv, "java/lang/AssertionError", szFmt, va_args); + va_end(va_args); + return ret; +} + +/** + * Instructs the JNI environment to throw an IOException. + * + * @param pEnv JNI environment + * @param szFmt sprintf-style format string + * @param ... sprintf-style args + * @return 0 on success; a negative value on failure + */ +jint throwIOException(JNIEnv* pEnv, const char* szFmt, ...) { + va_list va_args; + va_start(va_args, szFmt); + jint ret = throwException(pEnv, "java/io/IOException", szFmt, va_args); + va_end(va_args); + return ret; +} + +/** + * Finds the specified class. If it's not found, instructs the JNI environment to throw an + * exception. + * + * @param pEnv JNI environment + * @param szClassName the classname to find in JNI format (e.g. "java/lang/String") + * @return the class or NULL if not found (in which case a pending exception will be queued). This + * returns a global reference (JNIEnv::NewGlobalRef). + */ +jclass findClassOrThrow(JNIEnv* pEnv, const char* szClassName) { + jclass clazz = pEnv->FindClass(szClassName); + if (!clazz) { + return NULL; + } + return (jclass) pEnv->NewGlobalRef(clazz); +} + +/** + * Finds the specified field of the specified class. If it's not found, instructs the JNI + * environment to throw an exception. + * + * @param pEnv JNI environment + * @param clazz the class to lookup the field in + * @param szFieldName the name of the field to find + * @param szSig the signature of the field + * @return the field or NULL if not found (in which case a pending exception will be queued) + */ +jfieldID getFieldIdOrThrow(JNIEnv* pEnv, jclass clazz, const char* szFieldName, const char* szSig) { + return pEnv->GetFieldID(clazz, szFieldName, szSig); +} + +/** + * Finds the specified method of the specified class. If it's not found, instructs the JNI + * environment to throw an exception. + * + * @param pEnv JNI environment + * @param clazz the class to lookup the method in + * @param szMethodName the name of the method to find + * @param szSig the signature of the method + * @return the method or NULL if not found (in which case a pending exception will be queued) + */ +jmethodID getMethodIdOrThrow( + JNIEnv* pEnv, + jclass clazz, + const char* szMethodName, + const char* szSig) { + return pEnv->GetMethodID(clazz, szMethodName, szSig); +} + +} // namespace facebook diff --git a/libs/fbjni/src/main/cpp/log.cpp b/libs/fbjni/src/main/cpp/log.cpp new file mode 100644 index 000000000..5504ebf60 --- /dev/null +++ b/libs/fbjni/src/main/cpp/log.cpp @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2015-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +#include +#include +#include +#include + +#define LOG_BUFFER_SIZE 4096 +static LogHandler gLogHandler; + +void setLogHandler(LogHandler logHandler) { + gLogHandler = logHandler; +} + +int fb_printLog(int prio, const char *tag, const char *fmt, ...) { + char logBuffer[LOG_BUFFER_SIZE]; + + va_list va_args; + va_start(va_args, fmt); + int result = vsnprintf(logBuffer, sizeof(logBuffer), fmt, va_args); + va_end(va_args); + if (gLogHandler != NULL) { + gLogHandler(prio, tag, logBuffer); + } + __android_log_write(prio, tag, logBuffer); + return result; +} + +void logPrintByDelims(int priority, const char* tag, const char* delims, + const char* msg, ...) +{ + va_list ap; + char buf[32768]; + char* context; + char* tok; + + va_start(ap, msg); + vsnprintf(buf, sizeof(buf), msg, ap); + va_end(ap); + + tok = strtok_r(buf, delims, &context); + + if (!tok) { + return; + } + + do { + __android_log_write(priority, tag, tok); + } while ((tok = strtok_r(NULL, delims, &context))); +} + +#ifndef ANDROID + +// Implementations of the basic android logging functions for non-android platforms. + +static char logTagChar(int prio) { + switch (prio) { + default: + case ANDROID_LOG_UNKNOWN: + case ANDROID_LOG_DEFAULT: + case ANDROID_LOG_SILENT: + return ' '; + case ANDROID_LOG_VERBOSE: + return 'V'; + case ANDROID_LOG_DEBUG: + return 'D'; + case ANDROID_LOG_INFO: + return 'I'; + case ANDROID_LOG_WARN: + return 'W'; + case ANDROID_LOG_ERROR: + return 'E'; + case ANDROID_LOG_FATAL: + return 'F'; + } +} + +int __android_log_write(int prio, const char *tag, const char *text) { + return fprintf(stderr, "[%c/%.16s] %s\n", logTagChar(prio), tag, text); +} + +int __android_log_print(int prio, const char *tag, const char *fmt, ...) { + va_list ap; + va_start(ap, fmt); + + int res = fprintf(stderr, "[%c/%.16s] ", logTagChar(prio), tag); + res += vfprintf(stderr, "%s\n", ap); + + va_end(ap); + return res; +} + +#endif diff --git a/libs/fbjni/src/main/cpp/lyra/lyra.cpp b/libs/fbjni/src/main/cpp/lyra/lyra.cpp new file mode 100644 index 000000000..23da86cc8 --- /dev/null +++ b/libs/fbjni/src/main/cpp/lyra/lyra.cpp @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2004-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +#include + +#include +#include +#include + +#include +#include + +using namespace std; + +namespace facebook { +namespace lyra { + +namespace { + +class IosFlagsSaver { + ios_base& ios_; + ios_base::fmtflags flags_; + + public: + IosFlagsSaver(ios_base& ios) + : ios_(ios), + flags_(ios.flags()) + {} + + ~IosFlagsSaver() { + ios_.flags(flags_); + } +}; + +struct BacktraceState { + size_t skip; + vector& stackTrace; +}; + +_Unwind_Reason_Code unwindCallback(struct _Unwind_Context* context, void* arg) { + BacktraceState* state = reinterpret_cast(arg); + auto absoluteProgramCounter = + reinterpret_cast(_Unwind_GetIP(context)); + + if (state->skip > 0) { + --state->skip; + return _URC_NO_REASON; + } + + if (state->stackTrace.size() == state->stackTrace.capacity()) { + return _URC_END_OF_STACK; + } + + state->stackTrace.push_back(absoluteProgramCounter); + + return _URC_NO_REASON; +} + +void captureBacktrace(size_t skip, vector& stackTrace) { + // Beware of a bug on some platforms, which makes the trace loop until the + // buffer is full when it reaches a noexcept function. It seems to be fixed in + // newer versions of gcc. https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56846 + // TODO(t10738439): Investigate workaround for the stack trace bug + BacktraceState state = {skip, stackTrace}; + _Unwind_Backtrace(unwindCallback, &state); +} +} + +void getStackTrace(vector& stackTrace, size_t skip) { + stackTrace.clear(); + captureBacktrace(skip + 1, stackTrace); +} + +// TODO(t10737622): Improve on-device symbolification +void getStackTraceSymbols(vector& symbols, + const vector& trace) { + symbols.clear(); + symbols.reserve(trace.size()); + + for (size_t i = 0; i < trace.size(); ++i) { + Dl_info info; + if (dladdr(trace[i], &info)) { + symbols.emplace_back(trace[i], info.dli_fbase, info.dli_saddr, + info.dli_fname ? info.dli_fname : "", + info.dli_sname ? info.dli_sname : ""); + } + } +} + +ostream& operator<<(ostream& out, const StackTraceElement& elm) { + IosFlagsSaver flags{out}; + + // TODO(t10748683): Add build id to the output + out << "{dso=" << elm.libraryName() << " offset=" << hex + << showbase << elm.libraryOffset(); + + if (!elm.functionName().empty()) { + out << " func=" << elm.functionName() << "()+" << elm.functionOffset(); + } + + out << " build-id=" << hex << setw(8) << 0 + << "}"; + + return out; +} + +// TODO(t10737667): The implement a tool that parse the stack trace and +// symbolicate it +ostream& operator<<(ostream& out, const vector& trace) { + IosFlagsSaver flags{out}; + + auto i = 0; + out << "Backtrace:\n"; + for (auto& elm : trace) { + out << " #" << dec << setfill('0') << setw(2) << i++ << " " << elm << '\n'; + } + + return out; +} +} +} diff --git a/libs/fbjni/src/main/cpp/onload.cpp b/libs/fbjni/src/main/cpp/onload.cpp new file mode 100644 index 000000000..f7b1e5d89 --- /dev/null +++ b/libs/fbjni/src/main/cpp/onload.cpp @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2015-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +#include +#ifndef DISABLE_CPUCAP +#include +#endif +#include + +using namespace facebook::jni; + +void initialize_xplatinit(); +void initialize_fbjni(); + +JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved) { + return facebook::jni::initialize(vm, [] { + initialize_fbjni(); +#ifndef DISABLE_XPLAT + initialize_xplatinit(); +#endif +#ifndef DISABLE_CPUCAP + initialize_cpucapabilities(); +#endif + }); +} diff --git a/libs/fbjni/src/main/java/com/facebook/jni/Countable.java b/libs/fbjni/src/main/java/com/facebook/jni/Countable.java new file mode 100644 index 000000000..4e4280b52 --- /dev/null +++ b/libs/fbjni/src/main/java/com/facebook/jni/Countable.java @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2004-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +package com.facebook.jni; + +import com.facebook.proguard.annotations.DoNotStrip; + +/** + * A Java Object that has native memory allocated corresponding to this instance. + * + *

NB: THREAD SAFETY (this comment also exists at Countable.cpp) + * + *

{@link #dispose} deletes the corresponding native object on whatever thread the method is + * called on. In the common case when this is called by Countable#finalize(), this will be called on + * the system finalizer thread. If you manually call dispose on the Java object, the native object + * will be deleted synchronously on that thread. + */ +@DoNotStrip +public class Countable { + + // Private C++ instance + @DoNotStrip private long mInstance = 0; + + public native void dispose(); + + protected void finalize() throws Throwable { + dispose(); + super.finalize(); + } +} diff --git a/libs/fbjni/src/main/java/com/facebook/jni/CppException.java b/libs/fbjni/src/main/java/com/facebook/jni/CppException.java new file mode 100644 index 000000000..1d3f7f7e6 --- /dev/null +++ b/libs/fbjni/src/main/java/com/facebook/jni/CppException.java @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2015-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +package com.facebook.jni; + +import com.facebook.proguard.annotations.DoNotStrip; + +@DoNotStrip +public class CppException extends RuntimeException { + @DoNotStrip + public CppException(String message) { + super(message); + } +} diff --git a/libs/fbjni/src/main/java/com/facebook/jni/CppSystemErrorException.java b/libs/fbjni/src/main/java/com/facebook/jni/CppSystemErrorException.java new file mode 100644 index 000000000..c4c08cf43 --- /dev/null +++ b/libs/fbjni/src/main/java/com/facebook/jni/CppSystemErrorException.java @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2015-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +package com.facebook.jni; + +import com.facebook.proguard.annotations.DoNotStrip; + +@DoNotStrip +public class CppSystemErrorException extends CppException { + int errorCode; + + @DoNotStrip + public CppSystemErrorException(String message, int errorCode) { + super(message); + this.errorCode = errorCode; + } + + public int getErrorCode() { + return errorCode; + } +} diff --git a/libs/fbjni/src/main/java/com/facebook/jni/HybridData.java b/libs/fbjni/src/main/java/com/facebook/jni/HybridData.java new file mode 100644 index 000000000..ed9e43cca --- /dev/null +++ b/libs/fbjni/src/main/java/com/facebook/jni/HybridData.java @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2004-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +package com.facebook.jni; + +import com.facebook.proguard.annotations.DoNotStrip; + +/** + * This object holds a native C++ member for hybrid Java/C++ objects. + * + *

NB: THREAD SAFETY + * + *

{@link #dispose} deletes the corresponding native object on whatever thread the method is + * called on. In the common case when this is called by HybridData#finalize(), this will be called + * on the system finalizer thread. If you manually call resetNative() on the Java object, the C++ + * object will be deleted synchronously on that thread. + */ +@DoNotStrip +public class HybridData { + + // Private C++ instance + @DoNotStrip private long mNativePointer = 0; + + /** + * To explicitly delete the instance, call resetNative(). If the C++ instance is referenced after + * this is called, a NullPointerException will be thrown. resetNative() may be called multiple + * times safely. Because {@link #finalize} calls resetNative, the instance will not leak if this + * is not called, but timing of deletion and the thread the C++ dtor is called on will be at the + * whim of the Java GC. If you want to control the thread and timing of the destructor, you should + * call resetNative() explicitly. + */ + public native void resetNative(); + + protected void finalize() throws Throwable { + resetNative(); + super.finalize(); + } + + public boolean isValid() { + return mNativePointer != 0; + } +} diff --git a/libs/fbjni/src/main/java/com/facebook/jni/IteratorHelper.java b/libs/fbjni/src/main/java/com/facebook/jni/IteratorHelper.java new file mode 100644 index 000000000..3a12ec090 --- /dev/null +++ b/libs/fbjni/src/main/java/com/facebook/jni/IteratorHelper.java @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2015-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +package com.facebook.jni; + +import com.facebook.proguard.annotations.DoNotStrip; +import java.util.Iterator; +import javax.annotation.Nullable; + +/** + * To iterate over an Iterator from C++ requires two calls per entry: hasNext() and next(). This + * helper reduces it to one call and one field get per entry. It does not use a generic argument, + * since in C++, the types will be erased, anyway. This is *not* a {@link java.util.Iterator}. + */ +@DoNotStrip +public class IteratorHelper { + private final Iterator mIterator; + + // This is private, but accessed via JNI. + @DoNotStrip private @Nullable Object mElement; + + @DoNotStrip + public IteratorHelper(Iterator iterator) { + mIterator = iterator; + } + + @DoNotStrip + public IteratorHelper(Iterable iterable) { + mIterator = iterable.iterator(); + } + + /** + * Moves the helper to the next entry in the map, if any. Returns true iff there is an entry to + * read. + */ + @DoNotStrip + boolean hasNext() { + if (mIterator.hasNext()) { + mElement = mIterator.next(); + return true; + } else { + mElement = null; + return false; + } + } +} diff --git a/libs/fbjni/src/main/java/com/facebook/jni/MapIteratorHelper.java b/libs/fbjni/src/main/java/com/facebook/jni/MapIteratorHelper.java new file mode 100644 index 000000000..f9f44da69 --- /dev/null +++ b/libs/fbjni/src/main/java/com/facebook/jni/MapIteratorHelper.java @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2015-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +package com.facebook.jni; + +import com.facebook.proguard.annotations.DoNotStrip; +import java.util.Iterator; +import java.util.Map; +import javax.annotation.Nullable; + +/** + * To iterate over a Map from C++ requires four calls per entry: hasNext(), next(), getKey(), + * getValue(). This helper reduces it to one call and two field gets per entry. It does not use a + * generic argument, since in C++, the types will be erased, anyway. This is *not* a {@link + * java.util.Iterator}. + */ +@DoNotStrip +public class MapIteratorHelper { + @DoNotStrip private final Iterator mIterator; + @DoNotStrip private @Nullable Object mKey; + @DoNotStrip private @Nullable Object mValue; + + @DoNotStrip + public MapIteratorHelper(Map map) { + mIterator = map.entrySet().iterator(); + } + + /** + * Moves the helper to the next entry in the map, if any. Returns true iff there is an entry to + * read. + */ + @DoNotStrip + boolean hasNext() { + if (mIterator.hasNext()) { + Map.Entry entry = mIterator.next(); + mKey = entry.getKey(); + mValue = entry.getValue(); + return true; + } else { + mKey = null; + mValue = null; + return false; + } + } +} diff --git a/libs/fbjni/src/main/java/com/facebook/jni/NativeRunnable.java b/libs/fbjni/src/main/java/com/facebook/jni/NativeRunnable.java new file mode 100644 index 000000000..ecc3fc14e --- /dev/null +++ b/libs/fbjni/src/main/java/com/facebook/jni/NativeRunnable.java @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2015-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +package com.facebook.jni; + +import com.facebook.proguard.annotations.DoNotStrip; + +/** A Runnable that has a native run implementation. */ +@DoNotStrip +public class NativeRunnable implements Runnable { + + private final HybridData mHybridData; + + private NativeRunnable(HybridData hybridData) { + mHybridData = hybridData; + } + + public native void run(); +} diff --git a/libs/fbjni/src/main/java/com/facebook/jni/ThreadScopeSupport.java b/libs/fbjni/src/main/java/com/facebook/jni/ThreadScopeSupport.java new file mode 100644 index 000000000..a23b46aff --- /dev/null +++ b/libs/fbjni/src/main/java/com/facebook/jni/ThreadScopeSupport.java @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2004-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +package com.facebook.jni; + +import com.facebook.proguard.annotations.DoNotStrip; + +@DoNotStrip +public class ThreadScopeSupport { + // This is just used for ThreadScope::withClassLoader to have a java function + // in the stack so that jni has access to the correct classloader. + @DoNotStrip + private static void runStdFunction(long ptr) { + runStdFunctionImpl(ptr); + } + + private static native void runStdFunctionImpl(long ptr); +} diff --git a/libs/fbjni/src/main/java/com/facebook/jni/UnknownCppException.java b/libs/fbjni/src/main/java/com/facebook/jni/UnknownCppException.java new file mode 100644 index 000000000..4ffc63acb --- /dev/null +++ b/libs/fbjni/src/main/java/com/facebook/jni/UnknownCppException.java @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2015-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +package com.facebook.jni; + +import com.facebook.proguard.annotations.DoNotStrip; + +@DoNotStrip +public class UnknownCppException extends CppException { + @DoNotStrip + public UnknownCppException() { + super("Unknown"); + } + + @DoNotStrip + public UnknownCppException(String message) { + super(message); + } +} diff --git a/libs/fbjni/src/main/java/com/facebook/jni/fbjni.pro b/libs/fbjni/src/main/java/com/facebook/jni/fbjni.pro new file mode 100644 index 000000000..5b5b6454d --- /dev/null +++ b/libs/fbjni/src/main/java/com/facebook/jni/fbjni.pro @@ -0,0 +1,11 @@ +# For common use cases for the hybrid pattern, keep symbols which may +# be referenced only from C++. + +-keepclassmembers class * { + com.facebook.jni.HybridData *; + (com.facebook.jni.HybridData); +} + +-keepclasseswithmembers class * { + com.facebook.jni.HybridData *; +} diff --git a/libs/folly b/libs/folly new file mode 160000 index 000000000..711b3fdc6 --- /dev/null +++ b/libs/folly @@ -0,0 +1 @@ +Subproject commit 711b3fdc69f5ed8db5d21008551e0e9cb2cbc566 diff --git a/libs/jni-hack/README.md b/libs/jni-hack/README.md new file mode 100644 index 000000000..c30486ead --- /dev/null +++ b/libs/jni-hack/README.md @@ -0,0 +1 @@ +This buck module exists so that targets that need to be built against both 1) Android (where we can and should use the Android NDK jni headers) and 2) the host platform(generally for local unit tests) can depend on a single target and get the right jni header for whatever platform they're building against automatically. diff --git a/libs/jni-hack/jni.h b/libs/jni-hack/jni.h new file mode 100644 index 000000000..66e424d1e --- /dev/null +++ b/libs/jni-hack/jni.h @@ -0,0 +1,14 @@ +/* + * Copyright (c) 2014-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +#pragma once + +#ifdef __ANDROID__ +#include_next +#else +#include "real/jni.h" +#endif diff --git a/libs/jni-hack/real/jni.h b/libs/jni-hack/real/jni.h new file mode 100644 index 000000000..b3d111240 --- /dev/null +++ b/libs/jni-hack/real/jni.h @@ -0,0 +1,1132 @@ +/* + * Copyright (c) 2006-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. + * + */ +/* + * JNI specification, as defined by Sun: + * http://java.sun.com/javase/6/docs/technotes/guides/jni/spec/jniTOC.html + * + * Everything here is expected to be VM-neutral. + */ + +#ifndef JNI_H_ +#define JNI_H_ + +#include +#include + +/* Primitive types that match up with Java equivalents. */ +typedef uint8_t jboolean; /* unsigned 8 bits */ +typedef int8_t jbyte; /* signed 8 bits */ +typedef uint16_t jchar; /* unsigned 16 bits */ +typedef int16_t jshort; /* signed 16 bits */ +typedef int32_t jint; /* signed 32 bits */ +typedef int64_t jlong; /* signed 64 bits */ +typedef float jfloat; /* 32-bit IEEE 754 */ +typedef double jdouble; /* 64-bit IEEE 754 */ + +/* "cardinal indices and sizes" */ +typedef jint jsize; + +#ifdef __cplusplus +/* + * Reference types, in C++ + */ +class _jobject {}; +class _jclass : public _jobject {}; +class _jstring : public _jobject {}; +class _jarray : public _jobject {}; +class _jobjectArray : public _jarray {}; +class _jbooleanArray : public _jarray {}; +class _jbyteArray : public _jarray {}; +class _jcharArray : public _jarray {}; +class _jshortArray : public _jarray {}; +class _jintArray : public _jarray {}; +class _jlongArray : public _jarray {}; +class _jfloatArray : public _jarray {}; +class _jdoubleArray : public _jarray {}; +class _jthrowable : public _jobject {}; + +typedef _jobject* jobject; +typedef _jclass* jclass; +typedef _jstring* jstring; +typedef _jarray* jarray; +typedef _jobjectArray* jobjectArray; +typedef _jbooleanArray* jbooleanArray; +typedef _jbyteArray* jbyteArray; +typedef _jcharArray* jcharArray; +typedef _jshortArray* jshortArray; +typedef _jintArray* jintArray; +typedef _jlongArray* jlongArray; +typedef _jfloatArray* jfloatArray; +typedef _jdoubleArray* jdoubleArray; +typedef _jthrowable* jthrowable; +typedef _jobject* jweak; + + +#else /* not __cplusplus */ + +/* + * Reference types, in C. + */ +typedef void* jobject; +typedef jobject jclass; +typedef jobject jstring; +typedef jobject jarray; +typedef jarray jobjectArray; +typedef jarray jbooleanArray; +typedef jarray jbyteArray; +typedef jarray jcharArray; +typedef jarray jshortArray; +typedef jarray jintArray; +typedef jarray jlongArray; +typedef jarray jfloatArray; +typedef jarray jdoubleArray; +typedef jobject jthrowable; +typedef jobject jweak; + +#endif /* not __cplusplus */ + +struct _jfieldID; /* opaque structure */ +typedef struct _jfieldID* jfieldID; /* field IDs */ + +struct _jmethodID; /* opaque structure */ +typedef struct _jmethodID* jmethodID; /* method IDs */ + +struct JNIInvokeInterface; + +typedef union jvalue { + jboolean z; + jbyte b; + jchar c; + jshort s; + jint i; + jlong j; + jfloat f; + jdouble d; + jobject l; +} jvalue; + +typedef enum jobjectRefType { + JNIInvalidRefType = 0, + JNILocalRefType = 1, + JNIGlobalRefType = 2, + JNIWeakGlobalRefType = 3 +} jobjectRefType; + +typedef struct { + const char* name; + const char* signature; + void* fnPtr; +} JNINativeMethod; + +struct _JNIEnv; +struct _JavaVM; +typedef const struct JNINativeInterface* C_JNIEnv; + +#if defined(__cplusplus) +typedef _JNIEnv JNIEnv; +typedef _JavaVM JavaVM; +#else +typedef const struct JNINativeInterface* JNIEnv; +typedef const struct JNIInvokeInterface* JavaVM; +#endif + +/* + * Table of interface function pointers. + */ +struct JNINativeInterface { + void* reserved0; + void* reserved1; + void* reserved2; + void* reserved3; + + jint (*GetVersion)(JNIEnv *); + + jclass (*DefineClass)(JNIEnv*, const char*, jobject, const jbyte*, + jsize); + jclass (*FindClass)(JNIEnv*, const char*); + + jmethodID (*FromReflectedMethod)(JNIEnv*, jobject); + jfieldID (*FromReflectedField)(JNIEnv*, jobject); + /* spec doesn't show jboolean parameter */ + jobject (*ToReflectedMethod)(JNIEnv*, jclass, jmethodID, jboolean); + + jclass (*GetSuperclass)(JNIEnv*, jclass); + jboolean (*IsAssignableFrom)(JNIEnv*, jclass, jclass); + + /* spec doesn't show jboolean parameter */ + jobject (*ToReflectedField)(JNIEnv*, jclass, jfieldID, jboolean); + + jint (*Throw)(JNIEnv*, jthrowable); + jint (*ThrowNew)(JNIEnv *, jclass, const char *); + jthrowable (*ExceptionOccurred)(JNIEnv*); + void (*ExceptionDescribe)(JNIEnv*); + void (*ExceptionClear)(JNIEnv*); + void (*FatalError)(JNIEnv*, const char*); + + jint (*PushLocalFrame)(JNIEnv*, jint); + jobject (*PopLocalFrame)(JNIEnv*, jobject); + + jobject (*NewGlobalRef)(JNIEnv*, jobject); + void (*DeleteGlobalRef)(JNIEnv*, jobject); + void (*DeleteLocalRef)(JNIEnv*, jobject); + jboolean (*IsSameObject)(JNIEnv*, jobject, jobject); + + jobject (*NewLocalRef)(JNIEnv*, jobject); + jint (*EnsureLocalCapacity)(JNIEnv*, jint); + + jobject (*AllocObject)(JNIEnv*, jclass); + jobject (*NewObject)(JNIEnv*, jclass, jmethodID, ...); + jobject (*NewObjectV)(JNIEnv*, jclass, jmethodID, va_list); + jobject (*NewObjectA)(JNIEnv*, jclass, jmethodID, jvalue*); + + jclass (*GetObjectClass)(JNIEnv*, jobject); + jboolean (*IsInstanceOf)(JNIEnv*, jobject, jclass); + jmethodID (*GetMethodID)(JNIEnv*, jclass, const char*, const char*); + + jobject (*CallObjectMethod)(JNIEnv*, jobject, jmethodID, ...); + jobject (*CallObjectMethodV)(JNIEnv*, jobject, jmethodID, va_list); + jobject (*CallObjectMethodA)(JNIEnv*, jobject, jmethodID, jvalue*); + jboolean (*CallBooleanMethod)(JNIEnv*, jobject, jmethodID, ...); + jboolean (*CallBooleanMethodV)(JNIEnv*, jobject, jmethodID, va_list); + jboolean (*CallBooleanMethodA)(JNIEnv*, jobject, jmethodID, jvalue*); + jbyte (*CallByteMethod)(JNIEnv*, jobject, jmethodID, ...); + jbyte (*CallByteMethodV)(JNIEnv*, jobject, jmethodID, va_list); + jbyte (*CallByteMethodA)(JNIEnv*, jobject, jmethodID, jvalue*); + jchar (*CallCharMethod)(JNIEnv*, jobject, jmethodID, ...); + jchar (*CallCharMethodV)(JNIEnv*, jobject, jmethodID, va_list); + jchar (*CallCharMethodA)(JNIEnv*, jobject, jmethodID, jvalue*); + jshort (*CallShortMethod)(JNIEnv*, jobject, jmethodID, ...); + jshort (*CallShortMethodV)(JNIEnv*, jobject, jmethodID, va_list); + jshort (*CallShortMethodA)(JNIEnv*, jobject, jmethodID, jvalue*); + jint (*CallIntMethod)(JNIEnv*, jobject, jmethodID, ...); + jint (*CallIntMethodV)(JNIEnv*, jobject, jmethodID, va_list); + jint (*CallIntMethodA)(JNIEnv*, jobject, jmethodID, jvalue*); + jlong (*CallLongMethod)(JNIEnv*, jobject, jmethodID, ...); + jlong (*CallLongMethodV)(JNIEnv*, jobject, jmethodID, va_list); + jlong (*CallLongMethodA)(JNIEnv*, jobject, jmethodID, jvalue*); + jfloat (*CallFloatMethod)(JNIEnv*, jobject, jmethodID, ...); + jfloat (*CallFloatMethodV)(JNIEnv*, jobject, jmethodID, va_list); + jfloat (*CallFloatMethodA)(JNIEnv*, jobject, jmethodID, jvalue*); + jdouble (*CallDoubleMethod)(JNIEnv*, jobject, jmethodID, ...); + jdouble (*CallDoubleMethodV)(JNIEnv*, jobject, jmethodID, va_list); + jdouble (*CallDoubleMethodA)(JNIEnv*, jobject, jmethodID, jvalue*); + void (*CallVoidMethod)(JNIEnv*, jobject, jmethodID, ...); + void (*CallVoidMethodV)(JNIEnv*, jobject, jmethodID, va_list); + void (*CallVoidMethodA)(JNIEnv*, jobject, jmethodID, jvalue*); + + jobject (*CallNonvirtualObjectMethod)(JNIEnv*, jobject, jclass, + jmethodID, ...); + jobject (*CallNonvirtualObjectMethodV)(JNIEnv*, jobject, jclass, + jmethodID, va_list); + jobject (*CallNonvirtualObjectMethodA)(JNIEnv*, jobject, jclass, + jmethodID, jvalue*); + jboolean (*CallNonvirtualBooleanMethod)(JNIEnv*, jobject, jclass, + jmethodID, ...); + jboolean (*CallNonvirtualBooleanMethodV)(JNIEnv*, jobject, jclass, + jmethodID, va_list); + jboolean (*CallNonvirtualBooleanMethodA)(JNIEnv*, jobject, jclass, + jmethodID, jvalue*); + jbyte (*CallNonvirtualByteMethod)(JNIEnv*, jobject, jclass, + jmethodID, ...); + jbyte (*CallNonvirtualByteMethodV)(JNIEnv*, jobject, jclass, + jmethodID, va_list); + jbyte (*CallNonvirtualByteMethodA)(JNIEnv*, jobject, jclass, + jmethodID, jvalue*); + jchar (*CallNonvirtualCharMethod)(JNIEnv*, jobject, jclass, + jmethodID, ...); + jchar (*CallNonvirtualCharMethodV)(JNIEnv*, jobject, jclass, + jmethodID, va_list); + jchar (*CallNonvirtualCharMethodA)(JNIEnv*, jobject, jclass, + jmethodID, jvalue*); + jshort (*CallNonvirtualShortMethod)(JNIEnv*, jobject, jclass, + jmethodID, ...); + jshort (*CallNonvirtualShortMethodV)(JNIEnv*, jobject, jclass, + jmethodID, va_list); + jshort (*CallNonvirtualShortMethodA)(JNIEnv*, jobject, jclass, + jmethodID, jvalue*); + jint (*CallNonvirtualIntMethod)(JNIEnv*, jobject, jclass, + jmethodID, ...); + jint (*CallNonvirtualIntMethodV)(JNIEnv*, jobject, jclass, + jmethodID, va_list); + jint (*CallNonvirtualIntMethodA)(JNIEnv*, jobject, jclass, + jmethodID, jvalue*); + jlong (*CallNonvirtualLongMethod)(JNIEnv*, jobject, jclass, + jmethodID, ...); + jlong (*CallNonvirtualLongMethodV)(JNIEnv*, jobject, jclass, + jmethodID, va_list); + jlong (*CallNonvirtualLongMethodA)(JNIEnv*, jobject, jclass, + jmethodID, jvalue*); + jfloat (*CallNonvirtualFloatMethod)(JNIEnv*, jobject, jclass, + jmethodID, ...); + jfloat (*CallNonvirtualFloatMethodV)(JNIEnv*, jobject, jclass, + jmethodID, va_list); + jfloat (*CallNonvirtualFloatMethodA)(JNIEnv*, jobject, jclass, + jmethodID, jvalue*); + jdouble (*CallNonvirtualDoubleMethod)(JNIEnv*, jobject, jclass, + jmethodID, ...); + jdouble (*CallNonvirtualDoubleMethodV)(JNIEnv*, jobject, jclass, + jmethodID, va_list); + jdouble (*CallNonvirtualDoubleMethodA)(JNIEnv*, jobject, jclass, + jmethodID, jvalue*); + void (*CallNonvirtualVoidMethod)(JNIEnv*, jobject, jclass, + jmethodID, ...); + void (*CallNonvirtualVoidMethodV)(JNIEnv*, jobject, jclass, + jmethodID, va_list); + void (*CallNonvirtualVoidMethodA)(JNIEnv*, jobject, jclass, + jmethodID, jvalue*); + + jfieldID (*GetFieldID)(JNIEnv*, jclass, const char*, const char*); + + jobject (*GetObjectField)(JNIEnv*, jobject, jfieldID); + jboolean (*GetBooleanField)(JNIEnv*, jobject, jfieldID); + jbyte (*GetByteField)(JNIEnv*, jobject, jfieldID); + jchar (*GetCharField)(JNIEnv*, jobject, jfieldID); + jshort (*GetShortField)(JNIEnv*, jobject, jfieldID); + jint (*GetIntField)(JNIEnv*, jobject, jfieldID); + jlong (*GetLongField)(JNIEnv*, jobject, jfieldID); + jfloat (*GetFloatField)(JNIEnv*, jobject, jfieldID); + jdouble (*GetDoubleField)(JNIEnv*, jobject, jfieldID); + + void (*SetObjectField)(JNIEnv*, jobject, jfieldID, jobject); + void (*SetBooleanField)(JNIEnv*, jobject, jfieldID, jboolean); + void (*SetByteField)(JNIEnv*, jobject, jfieldID, jbyte); + void (*SetCharField)(JNIEnv*, jobject, jfieldID, jchar); + void (*SetShortField)(JNIEnv*, jobject, jfieldID, jshort); + void (*SetIntField)(JNIEnv*, jobject, jfieldID, jint); + void (*SetLongField)(JNIEnv*, jobject, jfieldID, jlong); + void (*SetFloatField)(JNIEnv*, jobject, jfieldID, jfloat); + void (*SetDoubleField)(JNIEnv*, jobject, jfieldID, jdouble); + + jmethodID (*GetStaticMethodID)(JNIEnv*, jclass, const char*, const char*); + + jobject (*CallStaticObjectMethod)(JNIEnv*, jclass, jmethodID, ...); + jobject (*CallStaticObjectMethodV)(JNIEnv*, jclass, jmethodID, va_list); + jobject (*CallStaticObjectMethodA)(JNIEnv*, jclass, jmethodID, jvalue*); + jboolean (*CallStaticBooleanMethod)(JNIEnv*, jclass, jmethodID, ...); + jboolean (*CallStaticBooleanMethodV)(JNIEnv*, jclass, jmethodID, + va_list); + jboolean (*CallStaticBooleanMethodA)(JNIEnv*, jclass, jmethodID, + jvalue*); + jbyte (*CallStaticByteMethod)(JNIEnv*, jclass, jmethodID, ...); + jbyte (*CallStaticByteMethodV)(JNIEnv*, jclass, jmethodID, va_list); + jbyte (*CallStaticByteMethodA)(JNIEnv*, jclass, jmethodID, jvalue*); + jchar (*CallStaticCharMethod)(JNIEnv*, jclass, jmethodID, ...); + jchar (*CallStaticCharMethodV)(JNIEnv*, jclass, jmethodID, va_list); + jchar (*CallStaticCharMethodA)(JNIEnv*, jclass, jmethodID, jvalue*); + jshort (*CallStaticShortMethod)(JNIEnv*, jclass, jmethodID, ...); + jshort (*CallStaticShortMethodV)(JNIEnv*, jclass, jmethodID, va_list); + jshort (*CallStaticShortMethodA)(JNIEnv*, jclass, jmethodID, jvalue*); + jint (*CallStaticIntMethod)(JNIEnv*, jclass, jmethodID, ...); + jint (*CallStaticIntMethodV)(JNIEnv*, jclass, jmethodID, va_list); + jint (*CallStaticIntMethodA)(JNIEnv*, jclass, jmethodID, jvalue*); + jlong (*CallStaticLongMethod)(JNIEnv*, jclass, jmethodID, ...); + jlong (*CallStaticLongMethodV)(JNIEnv*, jclass, jmethodID, va_list); + jlong (*CallStaticLongMethodA)(JNIEnv*, jclass, jmethodID, jvalue*); + jfloat (*CallStaticFloatMethod)(JNIEnv*, jclass, jmethodID, ...); + jfloat (*CallStaticFloatMethodV)(JNIEnv*, jclass, jmethodID, va_list); + jfloat (*CallStaticFloatMethodA)(JNIEnv*, jclass, jmethodID, jvalue*); + jdouble (*CallStaticDoubleMethod)(JNIEnv*, jclass, jmethodID, ...); + jdouble (*CallStaticDoubleMethodV)(JNIEnv*, jclass, jmethodID, va_list); + jdouble (*CallStaticDoubleMethodA)(JNIEnv*, jclass, jmethodID, jvalue*); + void (*CallStaticVoidMethod)(JNIEnv*, jclass, jmethodID, ...); + void (*CallStaticVoidMethodV)(JNIEnv*, jclass, jmethodID, va_list); + void (*CallStaticVoidMethodA)(JNIEnv*, jclass, jmethodID, jvalue*); + + jfieldID (*GetStaticFieldID)(JNIEnv*, jclass, const char*, + const char*); + + jobject (*GetStaticObjectField)(JNIEnv*, jclass, jfieldID); + jboolean (*GetStaticBooleanField)(JNIEnv*, jclass, jfieldID); + jbyte (*GetStaticByteField)(JNIEnv*, jclass, jfieldID); + jchar (*GetStaticCharField)(JNIEnv*, jclass, jfieldID); + jshort (*GetStaticShortField)(JNIEnv*, jclass, jfieldID); + jint (*GetStaticIntField)(JNIEnv*, jclass, jfieldID); + jlong (*GetStaticLongField)(JNIEnv*, jclass, jfieldID); + jfloat (*GetStaticFloatField)(JNIEnv*, jclass, jfieldID); + jdouble (*GetStaticDoubleField)(JNIEnv*, jclass, jfieldID); + + void (*SetStaticObjectField)(JNIEnv*, jclass, jfieldID, jobject); + void (*SetStaticBooleanField)(JNIEnv*, jclass, jfieldID, jboolean); + void (*SetStaticByteField)(JNIEnv*, jclass, jfieldID, jbyte); + void (*SetStaticCharField)(JNIEnv*, jclass, jfieldID, jchar); + void (*SetStaticShortField)(JNIEnv*, jclass, jfieldID, jshort); + void (*SetStaticIntField)(JNIEnv*, jclass, jfieldID, jint); + void (*SetStaticLongField)(JNIEnv*, jclass, jfieldID, jlong); + void (*SetStaticFloatField)(JNIEnv*, jclass, jfieldID, jfloat); + void (*SetStaticDoubleField)(JNIEnv*, jclass, jfieldID, jdouble); + + jstring (*NewString)(JNIEnv*, const jchar*, jsize); + jsize (*GetStringLength)(JNIEnv*, jstring); + const jchar* (*GetStringChars)(JNIEnv*, jstring, jboolean*); + void (*ReleaseStringChars)(JNIEnv*, jstring, const jchar*); + jstring (*NewStringUTF)(JNIEnv*, const char*); + jsize (*GetStringUTFLength)(JNIEnv*, jstring); + /* JNI spec says this returns const jbyte*, but that's inconsistent */ + const char* (*GetStringUTFChars)(JNIEnv*, jstring, jboolean*); + void (*ReleaseStringUTFChars)(JNIEnv*, jstring, const char*); + jsize (*GetArrayLength)(JNIEnv*, jarray); + jobjectArray (*NewObjectArray)(JNIEnv*, jsize, jclass, jobject); + jobject (*GetObjectArrayElement)(JNIEnv*, jobjectArray, jsize); + void (*SetObjectArrayElement)(JNIEnv*, jobjectArray, jsize, jobject); + + jbooleanArray (*NewBooleanArray)(JNIEnv*, jsize); + jbyteArray (*NewByteArray)(JNIEnv*, jsize); + jcharArray (*NewCharArray)(JNIEnv*, jsize); + jshortArray (*NewShortArray)(JNIEnv*, jsize); + jintArray (*NewIntArray)(JNIEnv*, jsize); + jlongArray (*NewLongArray)(JNIEnv*, jsize); + jfloatArray (*NewFloatArray)(JNIEnv*, jsize); + jdoubleArray (*NewDoubleArray)(JNIEnv*, jsize); + + jboolean* (*GetBooleanArrayElements)(JNIEnv*, jbooleanArray, jboolean*); + jbyte* (*GetByteArrayElements)(JNIEnv*, jbyteArray, jboolean*); + jchar* (*GetCharArrayElements)(JNIEnv*, jcharArray, jboolean*); + jshort* (*GetShortArrayElements)(JNIEnv*, jshortArray, jboolean*); + jint* (*GetIntArrayElements)(JNIEnv*, jintArray, jboolean*); + jlong* (*GetLongArrayElements)(JNIEnv*, jlongArray, jboolean*); + jfloat* (*GetFloatArrayElements)(JNIEnv*, jfloatArray, jboolean*); + jdouble* (*GetDoubleArrayElements)(JNIEnv*, jdoubleArray, jboolean*); + + void (*ReleaseBooleanArrayElements)(JNIEnv*, jbooleanArray, + jboolean*, jint); + void (*ReleaseByteArrayElements)(JNIEnv*, jbyteArray, + jbyte*, jint); + void (*ReleaseCharArrayElements)(JNIEnv*, jcharArray, + jchar*, jint); + void (*ReleaseShortArrayElements)(JNIEnv*, jshortArray, + jshort*, jint); + void (*ReleaseIntArrayElements)(JNIEnv*, jintArray, + jint*, jint); + void (*ReleaseLongArrayElements)(JNIEnv*, jlongArray, + jlong*, jint); + void (*ReleaseFloatArrayElements)(JNIEnv*, jfloatArray, + jfloat*, jint); + void (*ReleaseDoubleArrayElements)(JNIEnv*, jdoubleArray, + jdouble*, jint); + + void (*GetBooleanArrayRegion)(JNIEnv*, jbooleanArray, + jsize, jsize, jboolean*); + void (*GetByteArrayRegion)(JNIEnv*, jbyteArray, + jsize, jsize, jbyte*); + void (*GetCharArrayRegion)(JNIEnv*, jcharArray, + jsize, jsize, jchar*); + void (*GetShortArrayRegion)(JNIEnv*, jshortArray, + jsize, jsize, jshort*); + void (*GetIntArrayRegion)(JNIEnv*, jintArray, + jsize, jsize, jint*); + void (*GetLongArrayRegion)(JNIEnv*, jlongArray, + jsize, jsize, jlong*); + void (*GetFloatArrayRegion)(JNIEnv*, jfloatArray, + jsize, jsize, jfloat*); + void (*GetDoubleArrayRegion)(JNIEnv*, jdoubleArray, + jsize, jsize, jdouble*); + + /* spec shows these without const; some jni.h do, some don't */ + void (*SetBooleanArrayRegion)(JNIEnv*, jbooleanArray, + jsize, jsize, const jboolean*); + void (*SetByteArrayRegion)(JNIEnv*, jbyteArray, + jsize, jsize, const jbyte*); + void (*SetCharArrayRegion)(JNIEnv*, jcharArray, + jsize, jsize, const jchar*); + void (*SetShortArrayRegion)(JNIEnv*, jshortArray, + jsize, jsize, const jshort*); + void (*SetIntArrayRegion)(JNIEnv*, jintArray, + jsize, jsize, const jint*); + void (*SetLongArrayRegion)(JNIEnv*, jlongArray, + jsize, jsize, const jlong*); + void (*SetFloatArrayRegion)(JNIEnv*, jfloatArray, + jsize, jsize, const jfloat*); + void (*SetDoubleArrayRegion)(JNIEnv*, jdoubleArray, + jsize, jsize, const jdouble*); + + jint (*RegisterNatives)(JNIEnv*, jclass, const JNINativeMethod*, + jint); + jint (*UnregisterNatives)(JNIEnv*, jclass); + jint (*MonitorEnter)(JNIEnv*, jobject); + jint (*MonitorExit)(JNIEnv*, jobject); + jint (*GetJavaVM)(JNIEnv*, JavaVM**); + + void (*GetStringRegion)(JNIEnv*, jstring, jsize, jsize, jchar*); + void (*GetStringUTFRegion)(JNIEnv*, jstring, jsize, jsize, char*); + + void* (*GetPrimitiveArrayCritical)(JNIEnv*, jarray, jboolean*); + void (*ReleasePrimitiveArrayCritical)(JNIEnv*, jarray, void*, jint); + + const jchar* (*GetStringCritical)(JNIEnv*, jstring, jboolean*); + void (*ReleaseStringCritical)(JNIEnv*, jstring, const jchar*); + + jweak (*NewWeakGlobalRef)(JNIEnv*, jobject); + void (*DeleteWeakGlobalRef)(JNIEnv*, jweak); + + jboolean (*ExceptionCheck)(JNIEnv*); + + jobject (*NewDirectByteBuffer)(JNIEnv*, void*, jlong); + void* (*GetDirectBufferAddress)(JNIEnv*, jobject); + jlong (*GetDirectBufferCapacity)(JNIEnv*, jobject); + + /* added in JNI 1.6 */ + jobjectRefType (*GetObjectRefType)(JNIEnv*, jobject); +}; + +/* + * C++ object wrapper. + * + * This is usually overlaid on a C struct whose first element is a + * JNINativeInterface*. We rely somewhat on compiler behavior. + */ +struct _JNIEnv { + /* do not rename this; it does not seem to be entirely opaque */ + const struct JNINativeInterface* functions; + +#if defined(__cplusplus) + + jint GetVersion() + { return functions->GetVersion(this); } + + jclass DefineClass(const char *name, jobject loader, const jbyte* buf, + jsize bufLen) + { return functions->DefineClass(this, name, loader, buf, bufLen); } + + jclass FindClass(const char* name) + { return functions->FindClass(this, name); } + + jmethodID FromReflectedMethod(jobject method) + { return functions->FromReflectedMethod(this, method); } + + jfieldID FromReflectedField(jobject field) + { return functions->FromReflectedField(this, field); } + + jobject ToReflectedMethod(jclass cls, jmethodID methodID, jboolean isStatic) + { return functions->ToReflectedMethod(this, cls, methodID, isStatic); } + + jclass GetSuperclass(jclass clazz) + { return functions->GetSuperclass(this, clazz); } + + jboolean IsAssignableFrom(jclass clazz1, jclass clazz2) + { return functions->IsAssignableFrom(this, clazz1, clazz2); } + + jobject ToReflectedField(jclass cls, jfieldID fieldID, jboolean isStatic) + { return functions->ToReflectedField(this, cls, fieldID, isStatic); } + + jint Throw(jthrowable obj) + { return functions->Throw(this, obj); } + + jint ThrowNew(jclass clazz, const char* message) + { return functions->ThrowNew(this, clazz, message); } + + jthrowable ExceptionOccurred() + { return functions->ExceptionOccurred(this); } + + void ExceptionDescribe() + { functions->ExceptionDescribe(this); } + + void ExceptionClear() + { functions->ExceptionClear(this); } + + void FatalError(const char* msg) + { functions->FatalError(this, msg); } + + jint PushLocalFrame(jint capacity) + { return functions->PushLocalFrame(this, capacity); } + + jobject PopLocalFrame(jobject result) + { return functions->PopLocalFrame(this, result); } + + jobject NewGlobalRef(jobject obj) + { return functions->NewGlobalRef(this, obj); } + + void DeleteGlobalRef(jobject globalRef) + { functions->DeleteGlobalRef(this, globalRef); } + + void DeleteLocalRef(jobject localRef) + { functions->DeleteLocalRef(this, localRef); } + + jboolean IsSameObject(jobject ref1, jobject ref2) + { return functions->IsSameObject(this, ref1, ref2); } + + jobject NewLocalRef(jobject ref) + { return functions->NewLocalRef(this, ref); } + + jint EnsureLocalCapacity(jint capacity) + { return functions->EnsureLocalCapacity(this, capacity); } + + jobject AllocObject(jclass clazz) + { return functions->AllocObject(this, clazz); } + + jobject NewObject(jclass clazz, jmethodID methodID, ...) + { + va_list args; + va_start(args, methodID); + jobject result = functions->NewObjectV(this, clazz, methodID, args); + va_end(args); + return result; + } + + jobject NewObjectV(jclass clazz, jmethodID methodID, va_list args) + { return functions->NewObjectV(this, clazz, methodID, args); } + + jobject NewObjectA(jclass clazz, jmethodID methodID, jvalue* args) + { return functions->NewObjectA(this, clazz, methodID, args); } + + jclass GetObjectClass(jobject obj) + { return functions->GetObjectClass(this, obj); } + + jboolean IsInstanceOf(jobject obj, jclass clazz) + { return functions->IsInstanceOf(this, obj, clazz); } + + jmethodID GetMethodID(jclass clazz, const char* name, const char* sig) + { return functions->GetMethodID(this, clazz, name, sig); } + +#define CALL_TYPE_METHOD(_jtype, _jname) \ + _jtype Call##_jname##Method(jobject obj, jmethodID methodID, ...) \ + { \ + _jtype result; \ + va_list args; \ + va_start(args, methodID); \ + result = functions->Call##_jname##MethodV(this, obj, methodID, \ + args); \ + va_end(args); \ + return result; \ + } +#define CALL_TYPE_METHODV(_jtype, _jname) \ + _jtype Call##_jname##MethodV(jobject obj, jmethodID methodID, \ + va_list args) \ + { return functions->Call##_jname##MethodV(this, obj, methodID, args); } +#define CALL_TYPE_METHODA(_jtype, _jname) \ + _jtype Call##_jname##MethodA(jobject obj, jmethodID methodID, \ + jvalue* args) \ + { return functions->Call##_jname##MethodA(this, obj, methodID, args); } + +#define CALL_TYPE(_jtype, _jname) \ + CALL_TYPE_METHOD(_jtype, _jname) \ + CALL_TYPE_METHODV(_jtype, _jname) \ + CALL_TYPE_METHODA(_jtype, _jname) + + CALL_TYPE(jobject, Object) + CALL_TYPE(jboolean, Boolean) + CALL_TYPE(jbyte, Byte) + CALL_TYPE(jchar, Char) + CALL_TYPE(jshort, Short) + CALL_TYPE(jint, Int) + CALL_TYPE(jlong, Long) + CALL_TYPE(jfloat, Float) + CALL_TYPE(jdouble, Double) + + void CallVoidMethod(jobject obj, jmethodID methodID, ...) + { + va_list args; + va_start(args, methodID); + functions->CallVoidMethodV(this, obj, methodID, args); + va_end(args); + } + void CallVoidMethodV(jobject obj, jmethodID methodID, va_list args) + { functions->CallVoidMethodV(this, obj, methodID, args); } + void CallVoidMethodA(jobject obj, jmethodID methodID, jvalue* args) + { functions->CallVoidMethodA(this, obj, methodID, args); } + +#define CALL_NONVIRT_TYPE_METHOD(_jtype, _jname) \ + _jtype CallNonvirtual##_jname##Method(jobject obj, jclass clazz, \ + jmethodID methodID, ...) \ + { \ + _jtype result; \ + va_list args; \ + va_start(args, methodID); \ + result = functions->CallNonvirtual##_jname##MethodV(this, obj, \ + clazz, methodID, args); \ + va_end(args); \ + return result; \ + } +#define CALL_NONVIRT_TYPE_METHODV(_jtype, _jname) \ + _jtype CallNonvirtual##_jname##MethodV(jobject obj, jclass clazz, \ + jmethodID methodID, va_list args) \ + { return functions->CallNonvirtual##_jname##MethodV(this, obj, clazz, \ + methodID, args); } +#define CALL_NONVIRT_TYPE_METHODA(_jtype, _jname) \ + _jtype CallNonvirtual##_jname##MethodA(jobject obj, jclass clazz, \ + jmethodID methodID, jvalue* args) \ + { return functions->CallNonvirtual##_jname##MethodA(this, obj, clazz, \ + methodID, args); } + +#define CALL_NONVIRT_TYPE(_jtype, _jname) \ + CALL_NONVIRT_TYPE_METHOD(_jtype, _jname) \ + CALL_NONVIRT_TYPE_METHODV(_jtype, _jname) \ + CALL_NONVIRT_TYPE_METHODA(_jtype, _jname) + + CALL_NONVIRT_TYPE(jobject, Object) + CALL_NONVIRT_TYPE(jboolean, Boolean) + CALL_NONVIRT_TYPE(jbyte, Byte) + CALL_NONVIRT_TYPE(jchar, Char) + CALL_NONVIRT_TYPE(jshort, Short) + CALL_NONVIRT_TYPE(jint, Int) + CALL_NONVIRT_TYPE(jlong, Long) + CALL_NONVIRT_TYPE(jfloat, Float) + CALL_NONVIRT_TYPE(jdouble, Double) + + void CallNonvirtualVoidMethod(jobject obj, jclass clazz, + jmethodID methodID, ...) + { + va_list args; + va_start(args, methodID); + functions->CallNonvirtualVoidMethodV(this, obj, clazz, methodID, args); + va_end(args); + } + void CallNonvirtualVoidMethodV(jobject obj, jclass clazz, + jmethodID methodID, va_list args) + { functions->CallNonvirtualVoidMethodV(this, obj, clazz, methodID, args); } + void CallNonvirtualVoidMethodA(jobject obj, jclass clazz, + jmethodID methodID, jvalue* args) + { functions->CallNonvirtualVoidMethodA(this, obj, clazz, methodID, args); } + + jfieldID GetFieldID(jclass clazz, const char* name, const char* sig) + { return functions->GetFieldID(this, clazz, name, sig); } + + jobject GetObjectField(jobject obj, jfieldID fieldID) + { return functions->GetObjectField(this, obj, fieldID); } + jboolean GetBooleanField(jobject obj, jfieldID fieldID) + { return functions->GetBooleanField(this, obj, fieldID); } + jbyte GetByteField(jobject obj, jfieldID fieldID) + { return functions->GetByteField(this, obj, fieldID); } + jchar GetCharField(jobject obj, jfieldID fieldID) + { return functions->GetCharField(this, obj, fieldID); } + jshort GetShortField(jobject obj, jfieldID fieldID) + { return functions->GetShortField(this, obj, fieldID); } + jint GetIntField(jobject obj, jfieldID fieldID) + { return functions->GetIntField(this, obj, fieldID); } + jlong GetLongField(jobject obj, jfieldID fieldID) + { return functions->GetLongField(this, obj, fieldID); } + jfloat GetFloatField(jobject obj, jfieldID fieldID) + { return functions->GetFloatField(this, obj, fieldID); } + jdouble GetDoubleField(jobject obj, jfieldID fieldID) + { return functions->GetDoubleField(this, obj, fieldID); } + + void SetObjectField(jobject obj, jfieldID fieldID, jobject value) + { functions->SetObjectField(this, obj, fieldID, value); } + void SetBooleanField(jobject obj, jfieldID fieldID, jboolean value) + { functions->SetBooleanField(this, obj, fieldID, value); } + void SetByteField(jobject obj, jfieldID fieldID, jbyte value) + { functions->SetByteField(this, obj, fieldID, value); } + void SetCharField(jobject obj, jfieldID fieldID, jchar value) + { functions->SetCharField(this, obj, fieldID, value); } + void SetShortField(jobject obj, jfieldID fieldID, jshort value) + { functions->SetShortField(this, obj, fieldID, value); } + void SetIntField(jobject obj, jfieldID fieldID, jint value) + { functions->SetIntField(this, obj, fieldID, value); } + void SetLongField(jobject obj, jfieldID fieldID, jlong value) + { functions->SetLongField(this, obj, fieldID, value); } + void SetFloatField(jobject obj, jfieldID fieldID, jfloat value) + { functions->SetFloatField(this, obj, fieldID, value); } + void SetDoubleField(jobject obj, jfieldID fieldID, jdouble value) + { functions->SetDoubleField(this, obj, fieldID, value); } + + jmethodID GetStaticMethodID(jclass clazz, const char* name, const char* sig) + { return functions->GetStaticMethodID(this, clazz, name, sig); } + +#define CALL_STATIC_TYPE_METHOD(_jtype, _jname) \ + _jtype CallStatic##_jname##Method(jclass clazz, jmethodID methodID, \ + ...) \ + { \ + _jtype result; \ + va_list args; \ + va_start(args, methodID); \ + result = functions->CallStatic##_jname##MethodV(this, clazz, \ + methodID, args); \ + va_end(args); \ + return result; \ + } +#define CALL_STATIC_TYPE_METHODV(_jtype, _jname) \ + _jtype CallStatic##_jname##MethodV(jclass clazz, jmethodID methodID, \ + va_list args) \ + { return functions->CallStatic##_jname##MethodV(this, clazz, methodID, \ + args); } +#define CALL_STATIC_TYPE_METHODA(_jtype, _jname) \ + _jtype CallStatic##_jname##MethodA(jclass clazz, jmethodID methodID, \ + jvalue* args) \ + { return functions->CallStatic##_jname##MethodA(this, clazz, methodID, \ + args); } + +#define CALL_STATIC_TYPE(_jtype, _jname) \ + CALL_STATIC_TYPE_METHOD(_jtype, _jname) \ + CALL_STATIC_TYPE_METHODV(_jtype, _jname) \ + CALL_STATIC_TYPE_METHODA(_jtype, _jname) + + CALL_STATIC_TYPE(jobject, Object) + CALL_STATIC_TYPE(jboolean, Boolean) + CALL_STATIC_TYPE(jbyte, Byte) + CALL_STATIC_TYPE(jchar, Char) + CALL_STATIC_TYPE(jshort, Short) + CALL_STATIC_TYPE(jint, Int) + CALL_STATIC_TYPE(jlong, Long) + CALL_STATIC_TYPE(jfloat, Float) + CALL_STATIC_TYPE(jdouble, Double) + + void CallStaticVoidMethod(jclass clazz, jmethodID methodID, ...) + { + va_list args; + va_start(args, methodID); + functions->CallStaticVoidMethodV(this, clazz, methodID, args); + va_end(args); + } + void CallStaticVoidMethodV(jclass clazz, jmethodID methodID, va_list args) + { functions->CallStaticVoidMethodV(this, clazz, methodID, args); } + void CallStaticVoidMethodA(jclass clazz, jmethodID methodID, jvalue* args) + { functions->CallStaticVoidMethodA(this, clazz, methodID, args); } + + jfieldID GetStaticFieldID(jclass clazz, const char* name, const char* sig) + { return functions->GetStaticFieldID(this, clazz, name, sig); } + + jobject GetStaticObjectField(jclass clazz, jfieldID fieldID) + { return functions->GetStaticObjectField(this, clazz, fieldID); } + jboolean GetStaticBooleanField(jclass clazz, jfieldID fieldID) + { return functions->GetStaticBooleanField(this, clazz, fieldID); } + jbyte GetStaticByteField(jclass clazz, jfieldID fieldID) + { return functions->GetStaticByteField(this, clazz, fieldID); } + jchar GetStaticCharField(jclass clazz, jfieldID fieldID) + { return functions->GetStaticCharField(this, clazz, fieldID); } + jshort GetStaticShortField(jclass clazz, jfieldID fieldID) + { return functions->GetStaticShortField(this, clazz, fieldID); } + jint GetStaticIntField(jclass clazz, jfieldID fieldID) + { return functions->GetStaticIntField(this, clazz, fieldID); } + jlong GetStaticLongField(jclass clazz, jfieldID fieldID) + { return functions->GetStaticLongField(this, clazz, fieldID); } + jfloat GetStaticFloatField(jclass clazz, jfieldID fieldID) + { return functions->GetStaticFloatField(this, clazz, fieldID); } + jdouble GetStaticDoubleField(jclass clazz, jfieldID fieldID) + { return functions->GetStaticDoubleField(this, clazz, fieldID); } + + void SetStaticObjectField(jclass clazz, jfieldID fieldID, jobject value) + { functions->SetStaticObjectField(this, clazz, fieldID, value); } + void SetStaticBooleanField(jclass clazz, jfieldID fieldID, jboolean value) + { functions->SetStaticBooleanField(this, clazz, fieldID, value); } + void SetStaticByteField(jclass clazz, jfieldID fieldID, jbyte value) + { functions->SetStaticByteField(this, clazz, fieldID, value); } + void SetStaticCharField(jclass clazz, jfieldID fieldID, jchar value) + { functions->SetStaticCharField(this, clazz, fieldID, value); } + void SetStaticShortField(jclass clazz, jfieldID fieldID, jshort value) + { functions->SetStaticShortField(this, clazz, fieldID, value); } + void SetStaticIntField(jclass clazz, jfieldID fieldID, jint value) + { functions->SetStaticIntField(this, clazz, fieldID, value); } + void SetStaticLongField(jclass clazz, jfieldID fieldID, jlong value) + { functions->SetStaticLongField(this, clazz, fieldID, value); } + void SetStaticFloatField(jclass clazz, jfieldID fieldID, jfloat value) + { functions->SetStaticFloatField(this, clazz, fieldID, value); } + void SetStaticDoubleField(jclass clazz, jfieldID fieldID, jdouble value) + { functions->SetStaticDoubleField(this, clazz, fieldID, value); } + + jstring NewString(const jchar* unicodeChars, jsize len) + { return functions->NewString(this, unicodeChars, len); } + + jsize GetStringLength(jstring string) + { return functions->GetStringLength(this, string); } + + const jchar* GetStringChars(jstring string, jboolean* isCopy) + { return functions->GetStringChars(this, string, isCopy); } + + void ReleaseStringChars(jstring string, const jchar* chars) + { functions->ReleaseStringChars(this, string, chars); } + + jstring NewStringUTF(const char* bytes) + { return functions->NewStringUTF(this, bytes); } + + jsize GetStringUTFLength(jstring string) + { return functions->GetStringUTFLength(this, string); } + + const char* GetStringUTFChars(jstring string, jboolean* isCopy) + { return functions->GetStringUTFChars(this, string, isCopy); } + + void ReleaseStringUTFChars(jstring string, const char* utf) + { functions->ReleaseStringUTFChars(this, string, utf); } + + jsize GetArrayLength(jarray array) + { return functions->GetArrayLength(this, array); } + + jobjectArray NewObjectArray(jsize length, jclass elementClass, + jobject initialElement) + { return functions->NewObjectArray(this, length, elementClass, + initialElement); } + + jobject GetObjectArrayElement(jobjectArray array, jsize index) + { return functions->GetObjectArrayElement(this, array, index); } + + void SetObjectArrayElement(jobjectArray array, jsize index, jobject value) + { functions->SetObjectArrayElement(this, array, index, value); } + + jbooleanArray NewBooleanArray(jsize length) + { return functions->NewBooleanArray(this, length); } + jbyteArray NewByteArray(jsize length) + { return functions->NewByteArray(this, length); } + jcharArray NewCharArray(jsize length) + { return functions->NewCharArray(this, length); } + jshortArray NewShortArray(jsize length) + { return functions->NewShortArray(this, length); } + jintArray NewIntArray(jsize length) + { return functions->NewIntArray(this, length); } + jlongArray NewLongArray(jsize length) + { return functions->NewLongArray(this, length); } + jfloatArray NewFloatArray(jsize length) + { return functions->NewFloatArray(this, length); } + jdoubleArray NewDoubleArray(jsize length) + { return functions->NewDoubleArray(this, length); } + + jboolean* GetBooleanArrayElements(jbooleanArray array, jboolean* isCopy) + { return functions->GetBooleanArrayElements(this, array, isCopy); } + jbyte* GetByteArrayElements(jbyteArray array, jboolean* isCopy) + { return functions->GetByteArrayElements(this, array, isCopy); } + jchar* GetCharArrayElements(jcharArray array, jboolean* isCopy) + { return functions->GetCharArrayElements(this, array, isCopy); } + jshort* GetShortArrayElements(jshortArray array, jboolean* isCopy) + { return functions->GetShortArrayElements(this, array, isCopy); } + jint* GetIntArrayElements(jintArray array, jboolean* isCopy) + { return functions->GetIntArrayElements(this, array, isCopy); } + jlong* GetLongArrayElements(jlongArray array, jboolean* isCopy) + { return functions->GetLongArrayElements(this, array, isCopy); } + jfloat* GetFloatArrayElements(jfloatArray array, jboolean* isCopy) + { return functions->GetFloatArrayElements(this, array, isCopy); } + jdouble* GetDoubleArrayElements(jdoubleArray array, jboolean* isCopy) + { return functions->GetDoubleArrayElements(this, array, isCopy); } + + void ReleaseBooleanArrayElements(jbooleanArray array, jboolean* elems, + jint mode) + { functions->ReleaseBooleanArrayElements(this, array, elems, mode); } + void ReleaseByteArrayElements(jbyteArray array, jbyte* elems, + jint mode) + { functions->ReleaseByteArrayElements(this, array, elems, mode); } + void ReleaseCharArrayElements(jcharArray array, jchar* elems, + jint mode) + { functions->ReleaseCharArrayElements(this, array, elems, mode); } + void ReleaseShortArrayElements(jshortArray array, jshort* elems, + jint mode) + { functions->ReleaseShortArrayElements(this, array, elems, mode); } + void ReleaseIntArrayElements(jintArray array, jint* elems, + jint mode) + { functions->ReleaseIntArrayElements(this, array, elems, mode); } + void ReleaseLongArrayElements(jlongArray array, jlong* elems, + jint mode) + { functions->ReleaseLongArrayElements(this, array, elems, mode); } + void ReleaseFloatArrayElements(jfloatArray array, jfloat* elems, + jint mode) + { functions->ReleaseFloatArrayElements(this, array, elems, mode); } + void ReleaseDoubleArrayElements(jdoubleArray array, jdouble* elems, + jint mode) + { functions->ReleaseDoubleArrayElements(this, array, elems, mode); } + + void GetBooleanArrayRegion(jbooleanArray array, jsize start, jsize len, + jboolean* buf) + { functions->GetBooleanArrayRegion(this, array, start, len, buf); } + void GetByteArrayRegion(jbyteArray array, jsize start, jsize len, + jbyte* buf) + { functions->GetByteArrayRegion(this, array, start, len, buf); } + void GetCharArrayRegion(jcharArray array, jsize start, jsize len, + jchar* buf) + { functions->GetCharArrayRegion(this, array, start, len, buf); } + void GetShortArrayRegion(jshortArray array, jsize start, jsize len, + jshort* buf) + { functions->GetShortArrayRegion(this, array, start, len, buf); } + void GetIntArrayRegion(jintArray array, jsize start, jsize len, + jint* buf) + { functions->GetIntArrayRegion(this, array, start, len, buf); } + void GetLongArrayRegion(jlongArray array, jsize start, jsize len, + jlong* buf) + { functions->GetLongArrayRegion(this, array, start, len, buf); } + void GetFloatArrayRegion(jfloatArray array, jsize start, jsize len, + jfloat* buf) + { functions->GetFloatArrayRegion(this, array, start, len, buf); } + void GetDoubleArrayRegion(jdoubleArray array, jsize start, jsize len, + jdouble* buf) + { functions->GetDoubleArrayRegion(this, array, start, len, buf); } + + void SetBooleanArrayRegion(jbooleanArray array, jsize start, jsize len, + const jboolean* buf) + { functions->SetBooleanArrayRegion(this, array, start, len, buf); } + void SetByteArrayRegion(jbyteArray array, jsize start, jsize len, + const jbyte* buf) + { functions->SetByteArrayRegion(this, array, start, len, buf); } + void SetCharArrayRegion(jcharArray array, jsize start, jsize len, + const jchar* buf) + { functions->SetCharArrayRegion(this, array, start, len, buf); } + void SetShortArrayRegion(jshortArray array, jsize start, jsize len, + const jshort* buf) + { functions->SetShortArrayRegion(this, array, start, len, buf); } + void SetIntArrayRegion(jintArray array, jsize start, jsize len, + const jint* buf) + { functions->SetIntArrayRegion(this, array, start, len, buf); } + void SetLongArrayRegion(jlongArray array, jsize start, jsize len, + const jlong* buf) + { functions->SetLongArrayRegion(this, array, start, len, buf); } + void SetFloatArrayRegion(jfloatArray array, jsize start, jsize len, + const jfloat* buf) + { functions->SetFloatArrayRegion(this, array, start, len, buf); } + void SetDoubleArrayRegion(jdoubleArray array, jsize start, jsize len, + const jdouble* buf) + { functions->SetDoubleArrayRegion(this, array, start, len, buf); } + + jint RegisterNatives(jclass clazz, const JNINativeMethod* methods, + jint nMethods) + { return functions->RegisterNatives(this, clazz, methods, nMethods); } + + jint UnregisterNatives(jclass clazz) + { return functions->UnregisterNatives(this, clazz); } + + jint MonitorEnter(jobject obj) + { return functions->MonitorEnter(this, obj); } + + jint MonitorExit(jobject obj) + { return functions->MonitorExit(this, obj); } + + jint GetJavaVM(JavaVM** vm) + { return functions->GetJavaVM(this, vm); } + + void GetStringRegion(jstring str, jsize start, jsize len, jchar* buf) + { functions->GetStringRegion(this, str, start, len, buf); } + + void GetStringUTFRegion(jstring str, jsize start, jsize len, char* buf) + { return functions->GetStringUTFRegion(this, str, start, len, buf); } + + void* GetPrimitiveArrayCritical(jarray array, jboolean* isCopy) + { return functions->GetPrimitiveArrayCritical(this, array, isCopy); } + + void ReleasePrimitiveArrayCritical(jarray array, void* carray, jint mode) + { functions->ReleasePrimitiveArrayCritical(this, array, carray, mode); } + + const jchar* GetStringCritical(jstring string, jboolean* isCopy) + { return functions->GetStringCritical(this, string, isCopy); } + + void ReleaseStringCritical(jstring string, const jchar* carray) + { functions->ReleaseStringCritical(this, string, carray); } + + jweak NewWeakGlobalRef(jobject obj) + { return functions->NewWeakGlobalRef(this, obj); } + + void DeleteWeakGlobalRef(jweak obj) + { functions->DeleteWeakGlobalRef(this, obj); } + + jboolean ExceptionCheck() + { return functions->ExceptionCheck(this); } + + jobject NewDirectByteBuffer(void* address, jlong capacity) + { return functions->NewDirectByteBuffer(this, address, capacity); } + + void* GetDirectBufferAddress(jobject buf) + { return functions->GetDirectBufferAddress(this, buf); } + + jlong GetDirectBufferCapacity(jobject buf) + { return functions->GetDirectBufferCapacity(this, buf); } + + /* added in JNI 1.6 */ + jobjectRefType GetObjectRefType(jobject obj) + { return functions->GetObjectRefType(this, obj); } +#endif /*__cplusplus*/ +}; + + +/* + * JNI invocation interface. + */ +struct JNIInvokeInterface { + void* reserved0; + void* reserved1; + void* reserved2; + + jint (*DestroyJavaVM)(JavaVM*); + jint (*AttachCurrentThread)(JavaVM*, JNIEnv**, void*); + jint (*DetachCurrentThread)(JavaVM*); + jint (*GetEnv)(JavaVM*, void**, jint); + jint (*AttachCurrentThreadAsDaemon)(JavaVM*, JNIEnv**, void*); +}; + +/* + * C++ version. + */ +struct _JavaVM { + const struct JNIInvokeInterface* functions; + +#if defined(__cplusplus) + jint DestroyJavaVM() + { return functions->DestroyJavaVM(this); } + jint AttachCurrentThread(JNIEnv** p_env, void* thr_args) + { return functions->AttachCurrentThread(this, p_env, thr_args); } + jint DetachCurrentThread() + { return functions->DetachCurrentThread(this); } + jint GetEnv(void** env, jint version) + { return functions->GetEnv(this, env, version); } + jint AttachCurrentThreadAsDaemon(JNIEnv** p_env, void* thr_args) + { return functions->AttachCurrentThreadAsDaemon(this, p_env, thr_args); } +#endif /*__cplusplus*/ +}; + +struct JavaVMAttachArgs { + jint version; /* must be >= JNI_VERSION_1_2 */ + const char* name; /* NULL or name of thread as modified UTF-8 str */ + jobject group; /* global ref of a ThreadGroup object, or NULL */ +}; +typedef struct JavaVMAttachArgs JavaVMAttachArgs; + +/* + * JNI 1.2+ initialization. (As of 1.6, the pre-1.2 structures are no + * longer supported.) + */ +typedef struct JavaVMOption { + const char* optionString; + void* extraInfo; +} JavaVMOption; + +typedef struct JavaVMInitArgs { + jint version; /* use JNI_VERSION_1_2 or later */ + + jint nOptions; + JavaVMOption* options; + jboolean ignoreUnrecognized; +} JavaVMInitArgs; + +#ifdef __cplusplus +extern "C" { +#endif +/* + * VM initialization functions. + * + * Note these are the only symbols exported for JNI by the VM. + */ +jint JNI_GetDefaultJavaVMInitArgs(void*); +jint JNI_CreateJavaVM(JavaVM**, JNIEnv**, void*); +jint JNI_GetCreatedJavaVMs(JavaVM**, jsize, jsize*); + +#define JNIIMPORT +#define JNIEXPORT __attribute__ ((visibility ("default"))) +#define JNICALL + +/* + * Prototypes for functions exported by loadable shared libs. These are + * called by JNI, not provided by JNI. + */ +JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved); +JNIEXPORT void JNI_OnUnload(JavaVM* vm, void* reserved); + +#ifdef __cplusplus +} +#endif + + +/* + * Manifest constants. + */ +#define JNI_FALSE 0 +#define JNI_TRUE 1 + +#define JNI_VERSION_1_1 0x00010001 +#define JNI_VERSION_1_2 0x00010002 +#define JNI_VERSION_1_4 0x00010004 +#define JNI_VERSION_1_6 0x00010006 + +#define JNI_OK (0) /* no error */ +#define JNI_ERR (-1) /* generic error */ +#define JNI_EDETACHED (-2) /* thread detached from the VM */ +#define JNI_EVERSION (-3) /* JNI version error */ + +#define JNI_COMMIT 1 /* copy content, do not free buffer */ +#define JNI_ABORT 2 /* free buffer w/o copying back */ + +#endif /* JNI_H_ */ diff --git a/local.properties b/local.properties new file mode 100644 index 000000000..323ad260c --- /dev/null +++ b/local.properties @@ -0,0 +1,12 @@ +## This file is automatically generated by Android Studio. +# Do not modify this file -- YOUR CHANGES WILL BE ERASED! +# +# This file must *NOT* be checked into Version Control Systems, +# as it contains information specific to your local configuration. +# +# Location of the SDK. This is only used by Gradle. +# For customization when using a Version Control System, please read the +# header note. +#Tue May 29 22:12:21 BST 2018 +ndk.dir=/opt/android_sdk/ndk-bundle +sdk.dir=/opt/android_sdk diff --git a/package.json b/package.json new file mode 100644 index 000000000..e4c78c4d7 --- /dev/null +++ b/package.json @@ -0,0 +1,86 @@ +{ + "name": "sonar", + "private": true, + "version": "0.6.6", + "versionDate": "2018-4-12", + "description": "Mobile development tool", + "productName": "Sonar", + "author": "Facebook Inc", + "main": "src/index.js", + "icon": "icon.png", + "category": "facebook-intern", + "privileged": true, + "build": { + "appId": "sonar", + "productName": "Sonar", + "artifactName": "Sonar.${ext}", + "mac": { + "category": "public.app-category.developer-tools" + }, + "win": { + "publisherName": "Facebook, Inc." + } + }, + "devDependencies": { + "babel-eslint": "^8.2.1", + "electron": "^2.0.1", + "electron-builder": "^19.49.0", + "eslint": "^4.15.0", + "eslint-config-fbjs": "^2.0.1", + "eslint-plugin-babel": "^4.1.2", + "eslint-plugin-flowtype": "^2.41.0", + "eslint-plugin-header": "^1.2.0", + "eslint-plugin-jsx-a11y": "^6.0.3", + "eslint-plugin-prettier": "^2.4.0", + "eslint-plugin-react": "^7.5.1", + "eslint-plugin-relay": "^0.0.20", + "flow-bin": "^0.69.0", + "glob": "^7.1.2", + "prettier": "1.12.1" + }, + "dependencies": { + "JSONStream": "^1.3.1", + "adbkit-fb": "2.10.1", + "ansi-to-html": "^0.6.3", + "chalk": "^2.3.0", + "codemirror": "^5.25.0", + "dashify": "^1.0.0", + "deep-equal": "^1.0.1", + "detect-port": "^1.1.1", + "electron-devtools-installer": "^2.2.0", + "express": "^4.15.2", + "fs-extra": "^5.0.0", + "invariant": "^2.2.2", + "jest": "^22.2.1", + "mkdirp": "^0.5.1", + "openssl-wrapper": "^0.3.4", + "prop-types": "^15.6.0", + "react": "16", + "react-color": "^2.11.7", + "react-devtools-core": "3.1.0", + "react-dom": "16", + "react-redux": "^5.0.7", + "react-test-renderer": "^16", + "react-virtualized": "^9.13.0", + "redux": "^4.0.0", + "rsocket-core": "^0.0.6", + "rsocket-tcp-server": "^0.0.6", + "socket.io": "^2.0.4", + "string-natural-compare": "^2.0.2", + "tmp": "^0.0.33", + "websocket": "^1.0.24", + "ws": "^4.0.0", + "yargs": "^11.0.0" + }, + "scripts": { + "postinstall": "node node_modules/electron/install.js && node scripts/yarn-install.js", + "rm-dist": "rm -rf dist", + "rm-modules": "rm -rf node_modules static/node_modules", + "rm-temp": "rm -rf $TMPDIR/jest* $TMPDIR/react-native-packager*", + "reset": "yarn cache clean && yarn rm-dist && yarn rm-modules && yarn rm-temp", + "start": "NODE_ENV=development node scripts/start-dev-server.js", + "build": "yarn rm-dist && NODE_ENV=production node scripts/build-release.js $@", + "fix": "eslint . --fix", + "lint": "eslint . && flow check" + } +} diff --git a/scripts/build-release.js b/scripts/build-release.js new file mode 100755 index 000000000..07e150010 --- /dev/null +++ b/scripts/build-release.js @@ -0,0 +1,205 @@ +/** + * Copyright 2018-present Facebook. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * @format + */ +const path = require('path'); +const tmp = require('tmp'); +const fs = require('fs-extra'); +const builder = require('electron-builder'); +const Platform = builder.Platform; +const metro = require('../static/node_modules/metro'); +const compilePlugins = require('../static/compilePlugins'); + +function generateManifest(versionNumber) { + const filePath = path.join(__dirname, '..', 'dist'); + if (!fs.existsSync(filePath)) { + fs.mkdirSync(filePath); + } + fs.writeFileSync( + path.join(__dirname, '../dist/manifest.json'), + JSON.stringify({ + package: 'com.facebook.sonar', + version_name: versionNumber, + }), + ); +} + +function buildFolder() { + // eslint-disable-next-line no-console + console.log('Creating build directory'); + return new Promise((resolve, reject) => { + tmp.dir((err, buildFolder) => { + if (err) { + reject(err); + } else { + resolve(buildFolder); + } + }); + }).catch(die); +} + +function modifyPackageManifest(buildFolder) { + // eslint-disable-next-line no-console + console.log('Creating package.json manifest'); + const manifest = require('../package.json'); + const manifestStatic = require('../static/package.json'); + + // The manifest's dependencies are bundled with the final app by + // electron-builder. We want to bundle the dependencies from the static-folder + // because all dependencies from the root-folder are already bundled by metro. + manifest.dependencies = manifestStatic.dependencies; + manifest.main = 'index.js'; + + const BUILD_NUMBER_ARG = 'build-number='; + const buildNumber = ( + process.argv.find(arg => arg.startsWith(BUILD_NUMBER_ARG)) || '' + ).replace(BUILD_NUMBER_ARG, ''); + if (buildNumber) { + manifest.version = [ + ...manifest.version.split('.').slice(0, 2), + buildNumber, + ].join('.'); + } + + return new Promise((resolve, reject) => { + fs.writeFile( + path.join(buildFolder, 'package.json'), + JSON.stringify(manifest, null, ' '), + err => { + if (err) { + reject(err); + } else { + resolve(manifest.version); + } + }, + ); + }).catch(die); +} + +function buildDist(buildFolder) { + const targetsRaw = []; + targetsRaw.push(Platform.MAC.createTarget(['zip'])); + if (process.argv.slice(2).indexOf('macOnly') === -1) { + targetsRaw.push(Platform.LINUX.createTarget(['dir'])); + targetsRaw.push(Platform.WINDOWS.createTarget(['dir'])); + } + + if (!targetsRaw.length) { + throw new Error('No targets specified. eg. --osx pkg,dmg --linux tar.gz'); + } + + // merge all target maps into a single map + let targetsMerged = []; + for (const target of targetsRaw) { + targetsMerged = targetsMerged.concat(Array.from(target)); + } + const targets = new Map(targetsMerged); + + const electronDownload = {}; + if (process.env.electron_config_cache) { + electronDownload.cache = process.env.electron_config_cache; + } + + return builder + .build({ + appDir: buildFolder, + config: { + appId: `com.facebook.sonar`, + directories: { + buildResources: path.join(__dirname, '..', 'static'), + output: path.join(__dirname, '..', 'dist'), + }, + electronDownload, + npmRebuild: false, + asarUnpack: 'PortForwardingMacApp.app/**/*', + }, + projectDir: buildFolder, + targets, + }) + .catch(die); +} + +function die(err) { + console.error(err.stack); + process.exit(1); +} + +function compile(buildFolder) { + // eslint-disable-next-line no-console + console.log( + 'Building main bundle', + path.join(__dirname, '..', 'src', 'init.js'), + ); + return metro + .runBuild({ + config: { + getProjectRoots: () => [path.join(__dirname, '..')], + getTransformModulePath: () => + path.join(__dirname, '..', 'static', 'transforms', 'index.js'), + }, + resetCache: true, + dev: false, + entry: path.join(__dirname, '..', 'src', 'init.js'), + out: path.join(buildFolder, 'bundle.js'), + }) + .catch(die); +} + +function copyStaticFolder(buildFolder) { + return new Promise((resolve, reject) => { + fs.copy( + path.join(__dirname, '..', 'static'), + buildFolder, + { + dereference: true, + }, + err => { + if (err) { + reject(err); + } else { + resolve(); + } + }, + ); + }).catch(die); +} + +function compileDefaultPlugins(buildFolder) { + const defaultPluginFolder = 'defaultPlugins'; + const defaultPluginDir = path.join(buildFolder, defaultPluginFolder); + return compilePlugins( + null, + [ + path.join(__dirname, '..', 'src', 'plugins'), + path.join(__dirname, '..', 'src', 'fb', 'plugins'), + ], + defaultPluginDir, + ).then(defaultPlugins => + fs.writeFileSync( + path.join(defaultPluginDir, 'index.json'), + JSON.stringify( + defaultPlugins.map(plugin => ({ + ...plugin, + out: path.join(defaultPluginFolder, path.parse(plugin.out).base), + })), + ), + ), + ); +} + +(async () => { + const dir = await buildFolder(); + // eslint-disable-next-line no-console + console.log('Created build directory', dir); + await copyStaticFolder(dir); + await compileDefaultPlugins(dir); + await compile(dir); + const versionNumber = await modifyPackageManifest(dir); + generateManifest(versionNumber); + await buildDist(dir); + // eslint-disable-next-line no-console + console.log('✨ Done'); + process.exit(); +})(); diff --git a/scripts/eslint.sh b/scripts/eslint.sh new file mode 100755 index 000000000..ea28635f7 --- /dev/null +++ b/scripts/eslint.sh @@ -0,0 +1,30 @@ +#!/bin/bash +set -e + +# This script is used by `arc lint`. + +THIS_DIR=$(cd -P "$(dirname "${BASH_SOURCE[0]}")" && pwd) +ROOT_DIR=$(cd "$THIS_DIR" && hg root) + +cd "$ROOT_DIR/xplat/sonar" + +# Sonar's Electron dependency downloads itself via a post-install script. +# When running in Sandcastle or devservers, the module install will fail +# because we can't reach the internet. Setting the fwdproxy is dangerous, so +# the next best thing is to install the modules with `--ignore-scripts`. +# However, we can't run `install-node-modules.sh` like this all of the time. +# `install-node-modules.sh` uses its args as keys for the "yarn watchman check" +# cache. So if we run `install-node-modules.sh` outside of this script without +# the flag, but then this script runs it with the flag, we're going to +# invalidate the cache. + +# If `node_modules` exists, we can't tell if it was created with +# `--ignore-scripts` or not, so we play it safe, and avoid touching it. +if [[ ! -d "node_modules" ]]; then + "$ROOT_DIR/xplat/third-party/yarn/install-node-modules.sh" --ignore-scripts +fi + +exec \ + "$ROOT_DIR/xplat/third-party/node/bin/node" \ + "$ROOT_DIR/xplat/sonar/node_modules/.bin/eslint" \ + "$@" diff --git a/scripts/flow.sh b/scripts/flow.sh new file mode 100755 index 000000000..0f6bbb1fa --- /dev/null +++ b/scripts/flow.sh @@ -0,0 +1,31 @@ +#!/bin/bash +set -e + +# This script is used by `arc lint`. + +THIS_DIR=$(cd -P "$(dirname "${BASH_SOURCE[0]}")" && pwd) +ROOT_DIR=$(cd "$THIS_DIR" && hg root) + +cd "$ROOT_DIR/xplat/sonar" + +# Sonar's Electron dependency downloads itself via a post-install script. +# When running in Sandcastle or devservers, the module install will fail +# because we can't reach the internet. Setting the fwdproxy is dangerous, so +# the next best thing is to install the modules with `--ignore-scripts`. +# However, we can't run `install-node-modules.sh` like this all of the time. +# `install-node-modules.sh` uses its args as keys for the "yarn watchman check" +# cache. So if we run `install-node-modules.sh` outside of this script without +# the flag, but then this script runs it with the flag, we're going to +# invalidate the cache. + +# If `node_modules` exists, we can't tell if it was created with +# `--ignore-scripts` or not, so we play it safe, and avoid touching it. +if [[ ! -d "node_modules" ]]; then + "$ROOT_DIR/xplat/third-party/yarn/install-node-modules.sh" --ignore-scripts +fi + +# Prefer the internal version of Flow, which should be in the PATH - but +# fallback to the OSS version (this is needed in Sandcastle). +FLOW_BINARY="$(which flow 2>/dev/null || echo "$ROOT_DIR/xplat/sonar/node_modules/.bin/flow")" + +exec "$FLOW_BINARY" "$@" diff --git a/scripts/install-dependencies.sh b/scripts/install-dependencies.sh new file mode 100755 index 000000000..5d90c2ef8 --- /dev/null +++ b/scripts/install-dependencies.sh @@ -0,0 +1,29 @@ +#!/bin/sh + +set -e + +main () { + local -r THIS_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) + ROOT_DIR=$(cd "$THIS_DIR" && hg root) + source "$ROOT_DIR/xplat/sonar/scripts/setup-env.sh" + + # save current cursor location + printf "Ensuring correct dependencies..." + + PREV_DIR="`pwd`" + + # install dependencies + cd "$INFINITY_DIR" + "$INSTALL_NODE_MODULES" + + # ensure electron gets installed + node node_modules/electron/install.js + + # go back + cd "$PREV_DIR" + + # remove correct dependencies log + printf "\r" +} + +main diff --git a/scripts/metro-transform.js b/scripts/metro-transform.js new file mode 100644 index 000000000..fae367ee4 --- /dev/null +++ b/scripts/metro-transform.js @@ -0,0 +1,63 @@ +/** + * Copyright 2018-present Facebook. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * @format + */ + +const generate = require('babel-generator').default; +const babylon = require('babylon'); +const babel = require('babel-core'); +const metro = require('metro'); + +exports.transform = function({ + filename, + options, + src, + plugins: defaultPlugins, +}) { + const presets = []; + + let ast = babylon.parse(src, { + filename, + plugins: ['jsx', 'flow', 'classProperties', 'objectRestSpread'], + sourceType: filename.includes('node_modules') ? 'script' : 'module', + }); + + // run babel + const plugins = [ + ...defaultPlugins, + require('./babel-plugins/electron-requires.js'), + require('./babel-plugins/dynamic-requires.js'), + ]; + if (!filename.includes('node_modules')) { + plugins.unshift(require('babel-plugin-transform-es2015-modules-commonjs')); + } + ast = babel.transformFromAst(ast, src, { + babelrc: !filename.includes('node_modules'), + code: false, + comments: false, + compact: false, + filename, + plugins, + presets, + sourceMaps: true, + }).ast; + + const result = generate( + ast, + { + filename, + sourceFileName: filename, + sourceMaps: true, + }, + src, + ); + + return { + ast, + code: result.code, + filename, + map: result.rawMappings.map(metro.sourceMaps.compactMapping), + }; +}; diff --git a/scripts/public-build.json b/scripts/public-build.json new file mode 100644 index 000000000..40db5cde3 --- /dev/null +++ b/scripts/public-build.json @@ -0,0 +1,20 @@ +{ + "command": "SandcastleUniversalCommand", + "args": { + "name": "Release public Sonar build", + "oncall": "danielbuechele", + "steps": [ + { + "name": "sonar_release_public_build", + "required": true, + "shell": "cd ../xplat/sonar/scripts && ./public-build.sh" + } + ] + }, + "alias": "sonar_release_public_build", + "capabilities": { + "vcs": "fbcode-fbsource", + "type": "lego" + }, + "hash": "master" +} diff --git a/scripts/public-build.sh b/scripts/public-build.sh new file mode 100755 index 000000000..59b3d6843 --- /dev/null +++ b/scripts/public-build.sh @@ -0,0 +1,46 @@ +#!/bin/bash +TOKEN=$(secrets_tool get SONAR_GITHUB_TOKEN) +GITHUB_ORG="facebook" +GITHUB_REPO="Sonar" + +cd ../../ || exit + +function jsonValue() { + python -c 'import json,sys;obj=json.load(sys.stdin);print obj["'$1'"]' || echo '' +} + +git -c http.proxy=fwdproxy:8080 -c https.proxy=fwdproxy:8080 clone https://github.com/facebook/Sonar.git sonar-public +cp sonar/scripts/sandcastle-build.sh sonar-public/scripts/sandcastle-build.sh +cd sonar-public/scripts && ./sandcastle-build.sh "$(git rev-list HEAD --count || echo 0)" + +VERSION=$(plutil -p ./sonar-public/dist/mac/Sonar.app/Contents/Info.plist | awk '/CFBundleShortVersionString/ {print substr($3, 2, length($3)-2)}') + +RELEASE_JSON=$(curl $(fwdproxy-config curl) --silent --data '{ + "tag_name": "v'$VERSION'", + "target_commitish": "master", + "name": "v'$VERSION'", + "body": "", + "draft": false, + "prerelease": false +}' https://api.github.com/repos/$GITHUB_ORG/$GITHUB_REPO/releases?access_token=$TOKEN) + +RELEASE_ID=$(echo $RELEASE_JSON | jsonValue id) + +if [ -z "${RELEASE_ID}" ]; then + echo $RELEASE_JSON + exit 1 +fi + +echo "Created GitHub release ID: $RELEASE_ID" +UPLOAD_URL=$(echo $RELEASE_JSON | jsonValue upload_url| sed -e 's#{?name,label}##') +ASSET_JSON=$(curl $(fwdproxy-config curl) --silent $UPLOAD_URL'?access_token='$TOKEN'&name=Sonar.zip' --header 'Content-Type: application/zip' --upload-file ./sonar-public/dist/Sonar.zip -X POST) + +DOWNLOAD_URL=$(echo $ASSET_JSON | jsonValue browser_download_url) + +if [ -z "${DOWNLOAD_URL}" ]; then + echo $ASSET_JSON + exit 1 +fi + +echo "Released Sonar v$VERSION" +echo "Download: $DOWNLOAD_URL" diff --git a/scripts/setup-env.sh b/scripts/setup-env.sh new file mode 100755 index 000000000..a3882b90e --- /dev/null +++ b/scripts/setup-env.sh @@ -0,0 +1,15 @@ +#!/bin/sh + +set -e + +main () { + local -r THIS_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) + ROOT_DIR=$(cd "$THIS_DIR" && hg root) + + source "$ROOT_DIR/xplat/js/env-utils/setup_env_vars.sh" + + export SONAR_DIR="$ROOT_DIR/xplat/infinity" + export PATH="$SONAR_DIR/node_modules/.bin:$ROOT_DIR/xplat/third-party/node/bin:$ROOT_DIR/xplat/third-party/yarn:$PATH" +} + +main diff --git a/scripts/start-dev-server.js b/scripts/start-dev-server.js new file mode 100644 index 000000000..807d640ff --- /dev/null +++ b/scripts/start-dev-server.js @@ -0,0 +1,176 @@ +/** + * Copyright 2018-present Facebook. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * @format + */ +const electronBinary = require('electron'); +const codeFrame = require('babel-code-frame'); +const socketIo = require('socket.io'); +const express = require('express'); +const detect = require('detect-port'); +const child = require('child_process'); +const Convert = require('ansi-to-html'); +const chalk = require('chalk'); +const http = require('http'); +const path = require('path'); +const metro = require('../static/node_modules/metro'); +const fs = require('fs'); + +const convertAnsi = new Convert(); + +const DEFAULT_PORT = process.env.PORT || 3000; +const STATIC_DIR = path.join(__dirname, '..', 'static'); + +function launchElectron({bundleURL, electronURL}) { + const args = [ + path.join(STATIC_DIR, 'index.js'), + '--remote-debugging-port=9222', + '--dynamicPlugins=~/fbsource/xplat/sonar/src/plugins,~/fbsource/xplat/sonar/src/fb/plugins', + ]; + + const proc = child.spawn(electronBinary, args, { + cwd: STATIC_DIR, + env: { + ...process.env, + SONAR_ROOT: process.cwd(), + BUNDLE_URL: bundleURL, + ELECTRON_URL: electronURL, + }, + stdio: 'inherit', + }); + + proc.on('close', () => { + process.exit(); + }); + + process.on('exit', () => { + proc.kill(); + }); +} + +function startMetroServer(port) { + return metro.runServer({ + port, + watch: true, + config: { + getProjectRoots: () => [path.join(__dirname, '..')], + getTransformModulePath: () => + path.join(__dirname, '..', 'static', 'transforms', 'index.js'), + }, + }); +} + +function startAssetServer(port) { + const app = express(); + + app.use((req, res, next) => { + if (knownErrors[req.url] != null) { + delete knownErrors[req.url]; + outputScreen(); + } + next(); + }); + + app.get('/', (req, res) => { + fs.readFile(path.join(STATIC_DIR, 'index.dev.html'), (err, content) => { + res.end(content); + }); + }); + + app.use(express.static(STATIC_DIR)); + + app.use(function(err, req, res, next) { + knownErrors[req.url] = err; + outputScreen(); + res.status(500).send('Something broke, check the console!'); + }); + + const server = http.createServer(app); + + return new Promise((resolve, reject) => { + server.listen(port, () => resolve(server)); + }); +} + +function addWebsocket(server) { + const io = socketIo(server); + + // notify connected clients that there's errors in the console + io.on('connection', client => { + if (hasErrors()) { + client.emit('hasErrors', convertAnsi.toHtml(buildErrorScreen())); + } + }); + + // refresh the app on changes to the src folder + // this can be removed once metroServer notifies us about file changes + fs.watch(path.join(__dirname, '..', 'src'), () => { + io.emit('refresh'); + }); + + return io; +} + +const knownErrors = {}; + +function hasErrors() { + return Object.keys(knownErrors).length > 0; +} + +function buildErrorScreen() { + const lines = [ + chalk.red(`✖ Found ${Object.keys(knownErrors).length} errors`), + '', + ]; + + for (const url in knownErrors) { + const err = knownErrors[url]; + + if (err.filename != null && err.lineNumber != null && err.column != null) { + lines.push(chalk.inverse(err.filename)); + lines.push(); + lines.push(err.message); + lines.push( + codeFrame( + fs.readFileSync(err.filename, 'utf8'), + err.lineNumber, + err.column, + ), + ); + } else { + lines.push(err.stack); + } + + lines.push(''); + } + + return lines.join('\n'); +} + +function outputScreen(socket) { + // output screen + if (hasErrors()) { + const errorScreen = buildErrorScreen(); + console.error(errorScreen); + + // notify live clients of errors + socket.emit('hasErrors', convertAnsi.toHtml(errorScreen)); + } else { + // eslint-disable-next-line no-console + console.log(chalk.green('✔ No known errors')); + } +} + +(async () => { + const assetServerPort = await detect(DEFAULT_PORT); + const assetServer = await startAssetServer(assetServerPort); + const socket = addWebsocket(assetServer); + const metroServerPort = await detect(DEFAULT_PORT + 1); + await startMetroServer(metroServerPort); + outputScreen(socket); + launchElectron({ + bundleURL: `http://localhost:${metroServerPort}/src/init.bundle`, + electronURL: `http://localhost:${assetServerPort}/index.dev.html`, + }); +})(); diff --git a/scripts/yarn-install.js b/scripts/yarn-install.js new file mode 100644 index 000000000..03a6989e1 --- /dev/null +++ b/scripts/yarn-install.js @@ -0,0 +1,48 @@ +/** + * Copyright 2018-present Facebook. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * @format + */ + +const glob = require('glob'); +const path = require('path'); +const {spawn} = require('child_process'); +const PACKAGES = ['static', 'src/plugins/*', 'src/fb/plugins/*']; +const YARN_PATH = + process.argv.length > 2 ? path.join(__dirname, process.argv[2]) : 'yarn'; + +Promise.all( + PACKAGES.map( + pattern => + new Promise((resolve, reject) => { + glob( + path.join(__dirname, '..', pattern, 'package.json'), + (err, matches) => { + if (err) { + reject(err); + } else { + resolve(matches); + } + }, + ); + }), + ), +) + .then(packages => + Promise.all( + packages.reduce((acc, cv) => acc.concat(cv), []).map( + pkg => + new Promise(resolve => { + const cwd = pkg.replace('/package.json', ''); + const yarn = spawn(YARN_PATH, ['--mutex', 'file'], { + cwd, + }); + yarn.stderr.on('data', e => console.error(e.toString())); + yarn.on('close', code => resolve(code)); + }), + ), + ), + ) + // eslint-disable-next-line + .then(() => console.log('📦 Installed all dependencies!')); diff --git a/settings.gradle b/settings.gradle new file mode 100644 index 000000000..f004675f2 --- /dev/null +++ b/settings.gradle @@ -0,0 +1,29 @@ +/* + * This file was generated by the Gradle 'init' task. + * + * The settings file is used to specify which projects to include in your build. + * + * Detailed information about configuring a multi-project build in Gradle can be found + * in the user guide at https://docs.gradle.org/4.7/userguide/multi_project_builds.html + */ + +rootProject.name = 'sonar-kit' + +include ':android' +include ':folly' +include ':fbjni' +include ':easywsclient' +include ':sonarcpp' +include ':sample' +include ':doubleconversion' +include ':glog' + + +project(':fbjni').projectDir = file('libs/fbjni') +project(':easywsclient').projectDir = file('libs/easywsclient') +project(':sonarcpp').projectDir = file('xplat') +project(':sample').projectDir = file('android/sample') +project(':android').projectDir = file('android') +project(':doubleconversion').projectDir = file('android/build/third-party-ndk/double-conversion/') +project(':glog').projectDir = file('android/build/third-party-ndk/glog/') +project(':folly').projectDir = file('android/build/third-party-ndk/folly/') diff --git a/src/App.js b/src/App.js new file mode 100644 index 000000000..74e0bcbd6 --- /dev/null +++ b/src/App.js @@ -0,0 +1,363 @@ +/** + * Copyright 2018-present Facebook. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * @format + */ +import {ErrorBoundary, FlexColumn, FlexRow} from 'sonar'; +import {connect} from 'react-redux'; +import {toggleBugDialogVisible} from './reducers/application.js'; +import {setupMenu, activateMenuItems} from './MenuBar.js'; +import {devicePlugins} from './device-plugins/index.js'; +import WelcomeScreen from './chrome/WelcomeScreen.js'; +import SonarTitleBar from './chrome/SonarTitleBar.js'; +import BaseDevice from './devices/BaseDevice.js'; +import MainSidebar from './chrome/MainSidebar.js'; +import {SonarBasePlugin} from './plugin.js'; +import {Server, Client} from './server.js'; +import * as reducers from './reducers.js'; +import React from 'react'; +import BugReporter from './fb-stubs/BugReporter.js'; +import ErrorReporter from './fb-stubs/ErrorReporter.js'; +import BugReporterDialog from './chrome/BugReporterDialog.js'; +import ErrorBar from './chrome/ErrorBar.js'; +import Logger from './fb-stubs/Logger.js'; +import PluginContainer from './PluginContainer.js'; +import PluginManager from './chrome/PluginManager.js'; +const electron = require('electron'); +const yargs = require('yargs'); + +export type {Client}; + +export type StatePluginInfo = { + plugin: ?SonarBasePlugin<>, + state: Object, +}; + +export type StateClientPlugins = { + [pluginKey: string]: StatePluginInfo, +}; + +export type StatePlugins = { + [appKey: string]: StateClientPlugins, +}; + +export type State = { + activePluginKey: ?string, + activeAppKey: ?string, + plugins: StatePlugins, + error: ?string, + server: Server, +}; + +type Props = { + devices: Array, + leftSidebarVisible: boolean, + bugDialogVisible: boolean, + pluginManagerVisible: boolean, + toggleBugDialogVisible: (visible?: boolean) => void, +}; + +export class App extends React.Component { + constructor() { + performance.mark('init'); + super(); + this.initTracking(); + + this.logger = new Logger(); + + this.state = { + activeAppKey: null, + activePluginKey: null, + error: null, + devices: {}, + plugins: {}, + server: this.initServer(), + }; + + this.errorReporter = new ErrorReporter(this.logger.scribeLogger); + this.bugReporter = new BugReporter(this.logger); + this.commandLineArgs = yargs.parse(electron.remote.process.argv); + + setupMenu(this.sendKeyboardAction); + } + + errorReporter: ErrorReporter; + bugReporter: BugReporter; + logger: Logger; + commandLineArgs: Object; + _hasActivatedPreferredPlugin: boolean = false; + + componentDidMount() { + this.logger.trackTimeSince('init'); + + // close socket before reloading + window.addEventListener('beforeunload', () => { + this.state.server.close(); + }); + } + + componentDidUpdate(prevProps: Props) { + if (prevProps.devices !== this.props.devices) { + this.ensurePluginSelected(); + } + } + + toJSON() { + return null; + } + + initServer(): Server { + const server = new Server(this); + + server.addListener('new-client', client => { + client.addListener('close', () => { + this.setState(state => + reducers.TeardownClient(this, state, {appKey: client.id}), + ); + if (this.state.activeAppKey === client.id) { + setTimeout(this.ensurePluginSelected); + } + }); + + client.addListener('plugins-change', () => { + this.setState({}, this.ensurePluginSelected); + }); + }); + + server.addListener('clients-change', () => { + this.setState({}, this.ensurePluginSelected); + }); + + server.addListener('error', err => { + if (err.code === 'EADDRINUSE') { + this.setState({ + error: + "Couldn't start websocket server. " + + 'Looks like you have multiple copies of Sonar running.', + }); + } else { + // unknown error + this.setState({ + error: err.message, + }); + } + }); + + return server; + } + + initTracking = () => { + electron.ipcRenderer.on('trackUsage', () => { + // check if there's a plugin currently active + const {activeAppKey, activePluginKey} = this.state; + if (activeAppKey == null || activePluginKey == null) { + return; + } + + // app plugins + const client = this.getClient(activeAppKey); + if (client) { + this.logger.track('usage', 'ping', { + app: client.query.app, + device: client.query.device, + os: client.query.os, + plugin: activePluginKey, + }); + return; + } + + // device plugins + const device: ?BaseDevice = this.getDevice(activeAppKey); + if (device) { + this.logger.track('usage', 'ping', { + os: device.os, + plugin: activePluginKey, + device: device.title, + }); + } + }); + }; + + sendKeyboardAction = (action: string) => { + const {activeAppKey, activePluginKey} = this.state; + + if (activeAppKey != null && activePluginKey != null) { + const clientPlugins = this.state.plugins[activeAppKey]; + const pluginInfo = clientPlugins && clientPlugins[activePluginKey]; + const plugin = pluginInfo && pluginInfo.plugin; + if (plugin && typeof plugin.onKeyboardAction === 'function') { + plugin.onKeyboardAction(action); + } + } + }; + + getDevice = (id: string): ?BaseDevice => { + this.props.devices.find((device: BaseDevice) => device.serial === id); + }; + + ensurePluginSelected = () => { + // check if we need to rehydrate this client as it may have been previously active + const {activeAppKey, activePluginKey, server} = this.state; + const {devices} = this.props; + + if (!this._hasActivatedPreferredPlugin) { + for (const connection of server.connections.values()) { + const {client} = connection; + const {plugins} = client; + + for (const plugin of plugins) { + if (plugin !== this.commandLineArgs.plugin) { + continue; + } + + this._hasActivatedPreferredPlugin = true; + this.onActivatePlugin(client.id, plugin); + return; + } + } + + if (devices.length > 0) { + const device = devices[0]; + for (const plugin of devicePlugins) { + if (plugin.id !== this.commandLineArgs.plugin) { + continue; + } + + this._hasActivatedPreferredPlugin = true; + this.onActivatePlugin(device.serial, plugin.id); + return; + } + } + } + + if (activeAppKey != null && activePluginKey != null) { + const client = this.getClient(activeAppKey); + if (client != null && client.plugins.includes(activePluginKey)) { + this.onActivatePlugin(client.id, activePluginKey); + return; + } + + const device: ?BaseDevice = this.getDevice(activeAppKey); + if (device != null) { + this.onActivatePlugin(device.serial, activePluginKey); + return; + } + } else { + // No plugin selected, let's select one + const deviceList = ((Object.values(devices): any): Array); + if (deviceList.length > 0) { + const device = deviceList[0]; + this.onActivatePlugin(device.serial, devicePlugins[0].id); + return; + } + + const connections = Array.from(server.connections.values()); + if (connections.length > 0) { + const client = connections[0].client; + const plugins = client.plugins; + if (plugins.length > 0) { + this.onActivatePlugin(client.id, client.plugins[0]); + return; + } + } + } + }; + + getClient(appKey: ?string): ?Client { + if (appKey == null) { + return null; + } + + const info = this.state.server.connections.get(appKey); + if (info != null) { + return info.client; + } + } + + onActivatePlugin = (appKey: string, pluginKey: string) => { + activateMenuItems(pluginKey); + + this.setState(state => + reducers.ActivatePlugin(this, state, { + appKey, + pluginKey, + }), + ); + }; + + render() { + const {state} = this; + const hasDevices = + this.props.devices.length > 0 || state.server.connections.size > 0; + let mainView = null; + + const {activeAppKey, activePluginKey} = state; + if (activeAppKey != null && activePluginKey != null) { + const clientPlugins = state.plugins[activeAppKey]; + const pluginInfo = clientPlugins && clientPlugins[activePluginKey]; + const plugin = pluginInfo && pluginInfo.plugin; + if (plugin) { + mainView = this.props.pluginManagerVisible ? ( + + ) : ( + + + + ); + } + } + + return ( + + + {this.props.bugDialogVisible && ( + this.props.toggleBugDialogVisible(false)} + /> + )} + {hasDevices ? ( + + {this.props.leftSidebarVisible && ( + + )} + {mainView} + + ) : this.props.pluginManagerVisible ? ( + + ) : ( + + )} + + + ); + } +} + +export default connect( + ({ + application: {pluginManagerVisible, bugDialogVisible, leftSidebarVisible}, + devices, + }) => ({ + pluginManagerVisible, + bugDialogVisible, + leftSidebarVisible, + devices, + }), + {toggleBugDialogVisible}, +)(App); diff --git a/src/MenuBar.js b/src/MenuBar.js new file mode 100644 index 000000000..020e49f57 --- /dev/null +++ b/src/MenuBar.js @@ -0,0 +1,361 @@ +/** + * Copyright 2018-present Facebook. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * @format + */ + +import type {SonarBasePlugin} from './plugin.js'; + +import {devicePlugins} from './device-plugins/index.js'; +import { + isProduction, + loadsDynamicPlugins, + toggleDynamicPluginLoading, +} from './utils/dynamicPluginLoading.js'; +import plugins from './plugins/index.js'; +import electron from 'electron'; + +export type DefaultKeyboardAction = 'clear' | 'goToBottom' | 'createPaste'; +export type TopLevelMenu = 'Edit' | 'View' | 'Window' | 'Help'; + +type MenuItem = {| + label?: string, + accelerator?: string, + role?: string, + click?: Function, + submenu?: Array, + type?: string, + enabled?: boolean, +|}; + +export type KeyboardAction = {| + action: string, + label: string, + accelerator?: string, + topLevelMenu: TopLevelMenu, +|}; + +const defaultKeyboardActions: Array = [ + { + label: 'Clear', + accelerator: 'CmdOrCtrl+K', + topLevelMenu: 'View', + action: 'clear', + }, + { + label: 'Go To Bottom', + accelerator: 'CmdOrCtrl+B', + topLevelMenu: 'View', + action: 'goToBottom', + }, + { + label: 'Create Paste', + topLevelMenu: 'Edit', + action: 'createPaste', + }, +]; + +export type KeyboardActions = Array; + +const menuItems: Map = new Map(); + +export function setupMenu(actionHandler: (action: string) => void) { + const template = getTemplate(electron.remote.app, electron.remote.shell); + + // collect all keyboard actions from all plugins + const registeredActions: Set = new Set( + [...devicePlugins, ...plugins] + .map((plugin: Class>) => plugin.keyboardActions || []) + .reduce((acc: KeyboardActions, cv) => acc.concat(cv), []) + .map( + (action: DefaultKeyboardAction | KeyboardAction) => + typeof action === 'string' + ? defaultKeyboardActions.find(a => a.action === action) + : action, + ), + ); + + // add keyboard actions to + registeredActions.forEach(keyboardAction => { + if (keyboardAction != null) { + appendMenuItem(template, actionHandler, keyboardAction); + } + }); + + // create actual menu instance + const applicationMenu = electron.remote.Menu.buildFromTemplate(template); + + // add menu items to map, so we can modify them easily later + registeredActions.forEach(keyboardAction => { + if (keyboardAction != null) { + const {topLevelMenu, label, action} = keyboardAction; + const menu = applicationMenu.items.find( + menuItem => menuItem.label === topLevelMenu, + ); + const menuItem = menu.submenu.items.find( + menuItem => menuItem.label === label, + ); + menuItems.set(action, menuItem); + } + }); + + // update menubar + electron.remote.Menu.setApplicationMenu(applicationMenu); +} + +function appendMenuItem( + template: Array, + actionHandler: (action: string) => void, + item: ?KeyboardAction, +) { + const keyboardAction = item; + if (keyboardAction == null) { + return; + } + const itemIndex = template.findIndex( + menu => menu.label === keyboardAction.topLevelMenu, + ); + if (itemIndex > -1 && template[itemIndex].submenu != null) { + template[itemIndex].submenu.push({ + click: () => actionHandler(keyboardAction.action), + label: keyboardAction.label, + accelerator: keyboardAction.accelerator, + enabled: false, + }); + } +} + +export function activateMenuItems(activePluginKey: ?string) { + const activePlugin: ?Class> = [ + ...devicePlugins, + ...plugins, + ].find((plugin: Class>) => plugin.id === activePluginKey); + + // disable all keyboard actions + for (const item of menuItems) { + item[1].enabled = false; + } + + // enable keyboard actions for the current plugin + if (activePlugin != null && activePlugin.keyboardActions != null) { + (activePlugin.keyboardActions || []).forEach(keyboardAction => { + const action = + typeof keyboardAction === 'string' + ? keyboardAction + : keyboardAction.action; + const item = menuItems.get(action); + if (item != null) { + item.enabled = true; + } + }); + } + + // set the application menu again to make sure it updates + electron.remote.Menu.setApplicationMenu( + electron.remote.Menu.getApplicationMenu(), + ); +} + +function getTemplate(app: Object, shell: Object): Array { + const template = [ + { + label: 'Edit', + submenu: [ + { + label: 'Undo', + accelerator: 'CmdOrCtrl+Z', + role: 'undo', + }, + { + label: 'Redo', + accelerator: 'Shift+CmdOrCtrl+Z', + role: 'redo', + }, + { + type: 'separator', + }, + { + label: 'Cut', + accelerator: 'CmdOrCtrl+X', + role: 'cut', + }, + { + label: 'Copy', + accelerator: 'CmdOrCtrl+C', + role: 'copy', + }, + { + label: 'Paste', + accelerator: 'CmdOrCtrl+V', + role: 'paste', + }, + { + label: 'Select All', + accelerator: 'CmdOrCtrl+A', + role: 'selectall', + }, + ], + }, + { + label: 'View', + submenu: [ + { + label: 'Reload', + accelerator: 'CmdOrCtrl+R', + click: function(item: Object, focusedWindow: Object) { + if (focusedWindow) { + focusedWindow.reload(); + } + }, + }, + { + label: 'Toggle Full Screen', + accelerator: (function() { + if (process.platform === 'darwin') { + return 'Ctrl+Command+F'; + } else { + return 'F11'; + } + })(), + click: function(item: Object, focusedWindow: Object) { + if (focusedWindow) { + focusedWindow.setFullScreen(!focusedWindow.isFullScreen()); + } + }, + }, + { + label: 'Toggle Developer Tools', + accelerator: (function() { + if (process.platform === 'darwin') { + return 'Alt+Command+I'; + } else { + return 'Ctrl+Shift+I'; + } + })(), + click: function(item: Object, focusedWindow: Object) { + if (focusedWindow) { + focusedWindow.toggleDevTools(); + } + }, + }, + { + type: 'separator', + }, + ], + }, + { + label: 'Window', + role: 'window', + submenu: [ + { + label: 'Minimize', + accelerator: 'CmdOrCtrl+M', + role: 'minimize', + }, + { + label: 'Close', + accelerator: 'CmdOrCtrl+W', + role: 'close', + }, + ], + }, + { + label: 'Help', + role: 'help', + submenu: [ + { + label: 'Getting started', + click: function() { + shell.openExternal('https://fbsonar.com/docs/getting-started.html'); + }, + }, + { + label: 'Create plugins', + click: function() { + shell.openExternal('https://fbsonar.com/docs/create-plugin.html'); + }, + }, + { + label: 'Report problems', + click: function() { + shell.openExternal('https://github.com/facebook/Sonar/issues'); + }, + }, + ], + }, + ]; + + if (process.platform === 'darwin') { + const name = app.getName(); + template.unshift({ + label: name, + submenu: [ + { + label: 'About ' + name, + role: 'about', + }, + { + type: 'separator', + }, + { + label: 'Services', + role: 'services', + submenu: [], + }, + { + type: 'separator', + }, + { + label: 'Hide ' + name, + accelerator: 'Command+H', + role: 'hide', + }, + { + label: 'Hide Others', + accelerator: 'Command+Shift+H', + role: 'hideothers', + }, + { + label: 'Show All', + role: 'unhide', + }, + { + type: 'separator', + }, + { + label: `Restart in ${ + loadsDynamicPlugins() ? 'Production' : 'Development' + } Mode`, + enabled: isProduction(), + click: function() { + toggleDynamicPluginLoading(); + }, + }, + { + label: 'Quit', + accelerator: 'Command+Q', + click: function() { + app.quit(); + }, + }, + ], + }); + const windowMenu = template.find(function(m: Object) { + return m.role === 'window'; + }); + if (windowMenu) { + windowMenu.submenu.push( + { + type: 'separator', + }, + { + label: 'Bring All to Front', + role: 'front', + }, + ); + } + } + + return template; +} diff --git a/src/PluginContainer.js b/src/PluginContainer.js new file mode 100644 index 000000000..6a0851057 --- /dev/null +++ b/src/PluginContainer.js @@ -0,0 +1,128 @@ +/** + * Copyright 2018-present Facebook. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * @format + */ +import {Component, FlexColumn, Sidebar, colors} from 'sonar'; +import Intro from './ui/components/intro/intro.js'; +import {connect} from 'react-redux'; +import { + toggleRightSidebarAvailable, + toggleRightSidebarVisible, +} from './reducers/application.js'; +import type {SonarBasePlugin} from './plugin.js'; +import type LogManager from './fb-stubs/Logger'; + +type Props = { + plugin: SonarBasePlugin<>, + state?: any, + logger: LogManager, + rightSidebarVisible: boolean, + rightSidebarAvailable: boolean, + toggleRightSidebarVisible: (available: ?boolean) => void, + toggleRightSidebarAvailable: (available: ?boolean) => void, +}; + +type State = { + showIntro: boolean, +}; + +class PluginContainer extends Component { + state = { + showIntro: + typeof this.props.plugin.renderIntro === 'function' && + window.localStorage.getItem( + `${this.props.plugin.constructor.id}.introShown`, + ) !== 'true', + }; + + _sidebar: ?React$Node; + + static Container = FlexColumn.extends({ + width: 0, + flexGrow: 1, + flexShrink: 1, + backgroundColor: colors.white, + }); + + componentWillUnmount() { + performance.mark(`init_${this.props.plugin.constructor.id}`); + } + + componentDidMount() { + this.props.logger.trackTimeSince( + `init_${this.props.plugin.constructor.id}`, + ); + } + + componentDidUpdate(prevProps: Props) { + if (prevProps.plugin !== this.props.plugin) { + this.props.logger.trackTimeSince( + `init_${this.props.plugin.constructor.id}`, + ); + } + } + + componentWillUpdate(nextProps: Props) { + if (this.props.plugin !== nextProps.plugin) { + performance.mark(`init_${nextProps.plugin.constructor.id}`); + } + let sidebarContent; + if (typeof nextProps.plugin.renderSidebar === 'function') { + sidebarContent = nextProps.plugin.renderSidebar(); + } + + if (sidebarContent == null) { + this._sidebar = null; + nextProps.toggleRightSidebarAvailable(false); + } else { + this._sidebar = ( + + {sidebarContent} + + ); + nextProps.toggleRightSidebarAvailable(true); + } + } + + onDismissIntro = () => { + const {plugin} = this.props; + window.localStorage.setItem(`${plugin.constructor.id}.introShown`, 'true'); + this.setState({ + showIntro: false, + }); + }; + + render() { + const {plugin} = this.props; + + return [ + + {this.state.showIntro ? ( + + {typeof plugin.renderIntro === 'function' && plugin.renderIntro()} + + ) : ( + plugin.render() + )} + , + this.props.rightSidebarVisible === false ? null : this._sidebar, + ]; + } +} + +export default connect( + ({application: {rightSidebarVisible, rightSidebarAvailable}}) => ({ + rightSidebarVisible, + rightSidebarAvailable, + }), + { + toggleRightSidebarAvailable, + toggleRightSidebarVisible, + }, +)(PluginContainer); diff --git a/src/chrome/AutoUpdateVersion.js b/src/chrome/AutoUpdateVersion.js new file mode 100644 index 000000000..9f57d8854 --- /dev/null +++ b/src/chrome/AutoUpdateVersion.js @@ -0,0 +1,103 @@ +/** + * Copyright 2018-present Facebook. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * @format + */ + +import {FlexRow, Text, colors, LoadingIndicator, Glyph, Component} from 'sonar'; +import {remote} from 'electron'; +import {isProduction} from '../utils/dynamicPluginLoading'; +import config from '../fb-stubs/config.js'; +const version = remote.app.getVersion(); + +const VersionText = Text.extends({ + color: colors.light50, + marginLeft: 4, + marginTop: 2, +}); + +const Container = FlexRow.extends({ + alignItems: 'center', +}); + +type State = { + updater: + | 'error' + | 'checking-for-update' + | 'update-available' + | 'update-not-available' + | 'update-downloaded', + error?: string, +}; + +export default class AutoUpdateVersion extends Component<{}, State> { + state = { + updater: 'update-not-available', + }; + + componentDidMount() { + if (isProduction()) { + remote.autoUpdater.setFeedURL( + `${config.updateServer}?version=${version}`, + ); + + remote.autoUpdater.on('update-downloaded', () => { + this.setState({updater: 'update-downloaded'}); + + remote.dialog.showMessageBox( + { + title: 'Update available', + message: 'A new version of Sonar is available!', + detail: `You have Sonar ${version} which is outdated. Update to the latest version now.`, + buttons: ['Install and Restart'], + }, + () => { + remote.autoUpdater.quitAndInstall(); + }, + ); + }); + + remote.autoUpdater.on('error', error => { + this.setState({updater: 'error', error: error.toString()}); + }); + + remote.autoUpdater.on('checking-for-update', () => { + this.setState({updater: 'checking-for-update'}); + }); + + remote.autoUpdater.on('update-available', error => { + this.setState({updater: 'update-available'}); + }); + + remote.autoUpdater.on('update-not-available', error => { + this.setState({updater: 'update-not-available'}); + }); + + remote.autoUpdater.checkForUpdates(); + } + } + + render() { + return ( + + {this.state.updater === 'update-available' && ( + + + + )} + {this.state.updater === 'error' && ( + + + + )} + {this.state.updater === 'update-downloaded' && ( + + + + )} + {isProduction() && {version}} + + ); + } +} diff --git a/src/chrome/BugReporterDialog.js b/src/chrome/BugReporterDialog.js new file mode 100644 index 000000000..37c9ba030 --- /dev/null +++ b/src/chrome/BugReporterDialog.js @@ -0,0 +1,239 @@ +/** + * Copyright 2018-present Facebook. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * @format + */ + +import type BugReporter from '../fb-stubs/BugReporter.js'; +import {Component} from 'react'; +import { + Button, + colors, + Link, + Input, + FlexColumn, + FlexRow, + Textarea, + Text, + FlexCenter, + styled, +} from 'sonar'; + +const Container = FlexColumn.extends({ + padding: 10, +}); + +const textareaStyle = { + margin: 0, + marginBottom: 10, +}; + +const DialogContainer = styled.view({ + width: 400, + height: 300, + position: 'absolute', + left: '50%', + marginLeft: -200, + top: 40, + zIndex: 999999, + backgroundColor: '#fff', + border: '1px solid #ddd', + borderTop: 'none', + borderBottomLeftRadius: 5, + borderBottomRightRadius: 5, + boxShadow: '0 1px 10px rgba(0, 0, 0, 0.1)', +}); + +const TitleInput = Input.extends({ + ...textareaStyle, + height: 30, +}); + +const DescriptionTextarea = Textarea.extends({ + ...textareaStyle, + flexGrow: 1, +}); + +const SubmitButtonContainer = styled.view({ + marginLeft: 'auto', +}); + +const Footer = FlexRow.extends({ + lineHeight: '24px', +}); + +const CloseDoneButton = Button.extends({ + width: 50, + margin: '10px auto', +}); + +type State = { + description: string, + title: string, + submitting: boolean, + success: false | number, // false if not created, id of bug if it's been created + error: ?string, +}; + +type Props = { + bugReporter: BugReporter, + close: () => void, +}; + +const DEFAULT_DESCRIPTION = `Thanks for taking the time to provide feedback! +Please fill out the following information to make addressing your issue easier. + +What device platform are you using? ios/android +What sort of device are you using? emulator/physical +What app are you trying to use? wilde, fb4a, lite etc +Describe your problem in as much detail as possible: `; + +export default class BugReporterDialog extends Component { + constructor(props: Props) { + super(props); + + this.state = { + description: DEFAULT_DESCRIPTION, + title: '', + submitting: false, + success: false, + error: null, + }; + } + + titleRef: HTMLElement; + descriptionRef: HTMLElement; + + onDescriptionChange = (e: SyntheticInputEvent) => { + this.setState({description: e.target.value}); + }; + + onTitleChange = (e: SyntheticInputEvent) => { + this.setState({title: e.target.value}); + }; + + onSubmit = () => { + // validate fields + const {title, description} = this.state; + if (!title) { + this.setState({ + error: 'Title required.', + }); + this.titleRef.focus(); + return; + } + if (!description) { + this.setState({ + error: 'Description required.', + }); + this.descriptionRef.focus(); + return; + } + + this.setState( + { + error: null, + submitting: true, + }, + () => { + // this will be called before the next repaint + requestAnimationFrame(() => { + // we have to call this again to ensure a repaint has actually happened + // as requestAnimationFrame is called BEFORE a repaint, not after which + // means we have to queue up twice to actually ensure a repaint has + // happened + requestAnimationFrame(() => { + this.props.bugReporter + .report(title, description) + .then((id: number) => { + this.setState({ + submitting: false, + success: id, + }); + }) + .catch(err => { + this.setState({ + error: err.message, + submitting: false, + }); + }); + }); + }); + }, + ); + }; + + setTitleRef = (ref: HTMLElement) => { + this.titleRef = ref; + }; + + setDescriptionRef = (ref: HTMLElement) => { + this.descriptionRef = ref; + }; + + onCancel = () => { + this.props.close(); + }; + + render() { + let content; + + const {title, success, error, description} = this.state; + + if (success) { + content = ( + + + + Bug + + + + {success} + + + + created. Thank you for the report! + + + Close + + + ); + } else { + content = ( + + + + + +

+ {error != null && {error}} + + + + +
+ + ); + } + + return {content}; + } +} diff --git a/src/chrome/DevicesButton.js b/src/chrome/DevicesButton.js new file mode 100644 index 000000000..4f5f420e4 --- /dev/null +++ b/src/chrome/DevicesButton.js @@ -0,0 +1,291 @@ +/** + * Copyright 2018-present Facebook. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * @format + */ + +import {Component, styled, Glyph, Button, colors} from 'sonar'; +import {connect} from 'react-redux'; +import BaseDevice from '../devices/BaseDevice.js'; +import child_process from 'child_process'; +import DevicesList from './DevicesList.js'; + +const adb = require('adbkit-fb'); + +const Light = styled.view( + { + width: 10, + height: 10, + borderRadius: '999em', + backgroundColor: props => (props.active ? '#70f754' : colors.light20), + border: props => `1px solid ${props.active ? '#52d936' : colors.light30}`, + }, + { + ignoreAttributes: ['active'], + }, +); + +type Props = {| + devices: Array, +|}; + +type Emulator = {| + name: string, + os?: string, + isRunning: boolean, +|}; + +type State = { + androidEmulators: Array, + iOSSimulators: Array, + popoverVisible: boolean, +}; + +type IOSSimulatorList = { + devices: { + [os: string]: Array<{ + state: 'Shutdown' | 'Booted', + availability: string, + name: string, + udid: string, + os?: string, + }>, + }, +}; + +class DevicesButton extends Component { + state = { + androidEmulators: [], + iOSSimulators: [], + popoverVisible: false, + }; + + client = adb.createClient(); + _iOSSimulatorRefreshInterval: ?number; + + componentDidMount() { + this.updateEmulatorState(this.openMenuWhenNoDevicesConnected); + this.fetchIOSSimulators(); + this._iOSSimulatorRefreshInterval = window.setInterval( + this.fetchIOSSimulators, + 5000, + ); + + this.client.trackDevices().then(tracker => { + tracker.on('add', () => this.updateEmulatorState()); + tracker.on('remove', () => this.updateEmulatorState()); + tracker.on('end', () => this.updateEmulatorState()); + }); + } + + componentWillUnmount() { + if (this._iOSSimulatorRefreshInterval != null) { + window.clearInterval(this._iOSSimulatorRefreshInterval); + } + } + + fetchIOSSimulators = () => { + child_process.exec( + 'xcrun simctl list devices --json', + (err: ?Error, data: ?string) => { + if (data != null && err == null) { + const devicesList: IOSSimulatorList = JSON.parse(data); + const iOSSimulators = Object.keys(devicesList.devices) + .map(os => + devicesList.devices[os].map(device => { + device.os = os; + return device; + }), + ) + .reduce((acc, cv) => acc.concat(cv), []) + .filter(device => device.state === 'Booted') + .map(device => ({ + name: device.name, + os: device.os, + isRunning: true, + })); + this.setState({iOSSimulators}); + } + }, + ); + }; + + openMenuWhenNoDevicesConnected = () => { + const numberOfEmulators = this.state.androidEmulators.filter( + e => e.isRunning, + ).length; + const numberOfDevices = Object.values(this.props.devices).length; + if (numberOfEmulators + numberOfDevices === 0) { + this.setState({popoverVisible: true}); + } + }; + + updateEmulatorState = async (cb?: Function) => { + try { + const devices = await this.getEmulatorNames(); + const ports = await this.getRunningEmulatorPorts(); + const runningDevices = await Promise.all( + ports.map(port => this.getRunningName(port)), + ); + this.setState( + { + androidEmulators: devices.map(name => ({ + name, + isRunning: runningDevices.indexOf(name) > -1, + })), + }, + cb, + ); + } catch (e) { + console.error(e); + } + }; + + getEmulatorNames(): Promise> { + return new Promise((resolve, reject) => { + child_process.exec( + '/opt/android_sdk/tools/emulator -list-avds', + (error: ?Error, data: ?string) => { + if (error == null && data != null) { + resolve(data.split('\n').filter(name => name !== '')); + } else { + reject(error); + } + }, + ); + }); + } + + getRunningEmulatorPorts(): Promise> { + const EMULATOR_PREFIX = 'emulator-'; + return adb + .createClient() + .listDevices() + .then((devices: Array<{id: string}>) => + devices + .filter(d => d.id.startsWith(EMULATOR_PREFIX)) + .map(d => d.id.replace(EMULATOR_PREFIX, '')), + ) + .catch((e: Error) => { + return []; + }); + } + + getRunningName(port: string): Promise { + return new Promise((resolve, reject) => { + child_process.exec( + `echo "avd name" | nc -w 1 localhost ${port}`, + (error: ?Error, data: ?string) => { + if (error == null && data != null) { + const match = data.trim().match(/(.*)\r\nOK$/); + resolve(match != null && match.length > 0 ? match[1] : null); + } else { + reject(error); + } + }, + ); + }); + } + + launchEmulator = (name: string) => { + child_process.exec( + `/opt/android_sdk/tools/emulator @${name}`, + this.updateEmulatorState, + ); + }; + + createEmualtor = () => {}; + + onClick = () => { + this.setState({popoverVisible: !this.state.popoverVisible}); + this.updateEmulatorState(); + this.fetchIOSSimulators(); + }; + + onDismissPopover = () => { + this.setState({popoverVisible: false}); + }; + + render() { + let text = 'No devices running'; + let glyph = 'minus-circle'; + + const runnningEmulators = this.state.androidEmulators.filter( + emulator => emulator.isRunning, + ); + + const numberOfRunningDevices = + runnningEmulators.length + this.state.iOSSimulators.length; + + if (numberOfRunningDevices > 0) { + text = `${numberOfRunningDevices} device${ + numberOfRunningDevices > 1 ? 's' : '' + } running`; + glyph = 'mobile'; + } + + const connectedDevices = this.props.devices; + + return ( + + ); + } +} + +export default connect(({devices}) => ({ + devices, +}))(DevicesButton); diff --git a/src/chrome/DevicesList.js b/src/chrome/DevicesList.js new file mode 100644 index 000000000..388ab385b --- /dev/null +++ b/src/chrome/DevicesList.js @@ -0,0 +1,142 @@ +/** + * Copyright 2018-present Facebook. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * @format + */ + +import { + PureComponent, + FlexRow, + FlexBox, + Text, + Button, + Popover, + styled, + colors, +} from 'sonar'; + +const Heading = Text.extends({ + display: 'block', + backgroundColor: colors.white, + color: colors.light30, + fontSize: 11, + fontWeight: 600, + lineHeight: '21px', + padding: '4px 8px 0', +}); + +const PopoverItem = FlexRow.extends({ + alignItems: 'center', + borderBottom: `1px solid ${colors.light05}`, + height: 50, + '&:last-child': { + borderBottom: 'none', + }, +}); + +const ItemTitle = Text.extends({ + display: 'block', + fontSize: 14, + fontWeight: 400, + lineHeight: '120%', + textOverflow: 'ellipsis', + overflow: 'hidden', + whiteSpace: 'nowrap', + marginBottom: 1, +}); + +const ItemSubtitle = Text.extends({ + display: 'block', + fontWeight: 400, + fontSize: 11, + color: colors.light30, + lineHeight: '14px', + textOverflow: 'ellipsis', + overflow: 'hidden', + whiteSpace: 'nowrap', +}); + +const ItemImage = FlexBox.extends({ + alignItems: 'center', + justifyContent: 'center', + width: 40, + flexShrink: 0, +}); + +const ItemContent = styled.view({ + minWidth: 0, + paddingRight: 5, + flexGrow: 1, +}); + +const Section = styled.view({ + maxWidth: 260, + borderBottom: `1px solid ${colors.light05}`, + '&:last-child': { + borderBottom: 'none', + }, +}); + +const Action = Button.extends({ + border: `1px solid ${colors.macOSTitleBarButtonBorder}`, + background: 'transparent', + color: colors.macOSTitleBarIconSelected, + marginRight: 8, + marginLeft: 4, + lineHeight: '22px', + '&:hover': { + background: 'transparent', + }, + '&:active': { + background: 'transparent', + border: `1px solid ${colors.macOSTitleBarButtonBorder}`, + }, +}); + +type Props = {| + sections: Array<{ + title: string, + items: Array<{ + title: string, + subtitle: string, + onClick?: Function, + icon?: React.Element<*>, + }>, + }>, + onDismiss: Function, +|}; + +export default class DevicesList extends PureComponent { + render() { + return ( + + {this.props.sections.map(section => { + if (section.items.length > 0) { + return ( +
+ {section.title} + {section.items.map(item => ( + + {item.icon} + + {item.title} + {item.subtitle} + + {item.onClick && ( + + Run + + )} + + ))} +
+ ); + } else { + return null; + } + })} +
+ ); + } +} diff --git a/src/chrome/ErrorBar.js b/src/chrome/ErrorBar.js new file mode 100644 index 000000000..9bfcfd4e1 --- /dev/null +++ b/src/chrome/ErrorBar.js @@ -0,0 +1,28 @@ +/** + * Copyright 2018-present Facebook. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * @format + */ + +import {styled, colors} from 'sonar'; + +const ErrorBarContainer = styled.view({ + backgroundColor: colors.cherry, + bottom: 0, + color: '#fff', + left: 0, + lineHeight: '26px', + position: 'absolute', + right: 0, + textAlign: 'center', + zIndex: 2, +}); + +export default function ErrorBar(props: {|text: ?string|}) { + if (props.text == null) { + return null; + } else { + return {props.text}; + } +} diff --git a/src/chrome/MainSidebar.js b/src/chrome/MainSidebar.js new file mode 100644 index 000000000..699934f8b --- /dev/null +++ b/src/chrome/MainSidebar.js @@ -0,0 +1,305 @@ +/** + * Copyright 2018-present Facebook. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * @format + */ + +import type {SonarBasePlugin} from '../plugin.js'; +import type {Client} from '../server.js'; + +import { + Component, + Sidebar, + FlexBox, + ClickableList, + ClickableListItem, + colors, + brandColors, + Text, + Glyph, +} from 'sonar'; +import {devicePlugins} from '../device-plugins/index.js'; +import type BaseDevice from '../devices/BaseDevice.js'; +import PropTypes from 'prop-types'; +import plugins from '../plugins/index.js'; + +const CustomClickableListItem = ClickableListItem.extends({ + paddingLeft: 10, + display: 'flex', + alignItems: 'center', + marginBottom: 2, +}); + +const SidebarHeader = FlexBox.extends({ + display: 'block', + alignItems: 'center', + padding: 3, + color: colors.macOSSidebarSectionTitle, + fontSize: 11, + fontWeight: 500, + marginLeft: 7, + textOverflow: 'ellipsis', + overflow: 'hidden', + whiteSpace: 'nowrap', + flexShrink: 0, +}); + +const PluginShape = FlexBox.extends( + { + marginRight: 5, + backgroundColor: props => props.backgroundColor, + borderRadius: 3, + flexShrink: 0, + width: 18, + height: 18, + justifyContent: 'center', + alignItems: 'center', + }, + { + ignoreAttributes: ['backgroundColor'], + }, +); + +const PluginName = Text.extends({ + minWidth: 0, + textOverflow: 'ellipsis', + whiteSpace: 'nowrap', + overflow: 'hidden', +}); + +function PluginIcon({ + backgroundColor, + name, + color, +}: { + backgroundColor: string, + name: string, + color: string, +}) { + return ( + + + + ); +} + +class PluginSidebarListItem extends Component<{ + activePluginKey: ?string, + activeAppKey: ?string, + onActivatePlugin: (appKey: string, pluginKey: string) => void, + appKey: string, + appName?: string, + isActive: boolean, + Plugin: Class>, + windowFocused: boolean, +}> { + onClick = () => { + const {props} = this; + props.onActivatePlugin(props.appKey, props.Plugin.id); + }; + + render() { + const {isActive, Plugin, windowFocused, appKey, appName} = this.props; + + let iconColor; + if (appName != null) { + iconColor = brandColors[appName]; + } + + if (iconColor == null) { + const pluginColors = [ + colors.seaFoam, + colors.teal, + colors.lime, + colors.lemon, + colors.orange, + colors.tomato, + colors.cherry, + colors.pink, + colors.grape, + ]; + + iconColor = pluginColors[parseInt(appKey, 36) % pluginColors.length]; + } + + return ( + + + {Plugin.title} + + ); + } +} + +function PluginSidebarList(props: {| + activePluginKey: ?string, + activeAppKey: ?string, + onActivatePlugin: (appKey: string, pluginKey: string) => void, + appKey: string, + appName?: string, + enabledPlugins: Array>>, + windowFocused: boolean, +|}) { + if (props.enabledPlugins.length === 0) { + return No available plugins for this device; + } + + return ( + + {props.enabledPlugins.map(Plugin => { + const isActive = + props.activeAppKey === props.appKey && + props.activePluginKey === Plugin.id; + return ( + + ); + })} + + ); +} + +function AppSidebarInfo(props: {| + client: Client, + appKey: string, + activePluginKey: ?string, + activeAppKey: ?string, + onActivatePlugin: (appKey: string, pluginKey: string) => void, + windowFocused: boolean, +|}): any { + const {appKey, client, windowFocused} = props; + + let enabledPlugins = []; + for (const Plugin of plugins) { + if (client.supportsPlugin(Plugin)) { + enabledPlugins.push(Plugin); + } + } + enabledPlugins = enabledPlugins.sort((a, b) => { + return (a.title || '').localeCompare(b.title); + }); + + return [ + {`${client.query.app} (${ + client.query.os + }) - ${client.query.device}`}, + , + ]; +} + +type MainSidebarProps = {| + activePluginKey: ?string, + activeAppKey: ?string, + onActivatePlugin: (appKey: string, pluginKey: string) => void, + devices: Array, + server: Server, +|}; + +export default class MainSidebar extends Component { + static contextTypes = { + windowIsFocused: PropTypes.bool, + }; + + render() { + const connections = Array.from(this.props.server.connections.values()).sort( + (a, b) => { + return (a.client.query.app || '').localeCompare(b.client.query.app); + }, + ); + + const sidebarContent = connections.map(conn => { + const {client} = conn; + + return ( + + ); + }); + + let {devices} = this.props; + devices = devices.sort((a, b) => { + return (a.title || '').localeCompare(b.title); + }); + + for (const device of devices) { + let enabledPlugins = []; + for (const DevicePlugin of devicePlugins) { + if (device.supportsPlugin(DevicePlugin)) { + enabledPlugins.push(DevicePlugin); + } + } + enabledPlugins = enabledPlugins.sort((a, b) => { + return (a.title || '').localeCompare(b.title); + }); + + sidebarContent.unshift([ + {device.title}, + , + ]); + } + + return ( + + {sidebarContent} + + ); + } +} diff --git a/src/chrome/PluginManager.js b/src/chrome/PluginManager.js new file mode 100644 index 000000000..d4cc6c23e --- /dev/null +++ b/src/chrome/PluginManager.js @@ -0,0 +1,404 @@ +/** + * Copyright 2018-present Facebook. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * @format + */ + +import { + PureComponent, + Button, + FlexColumn, + FlexBox, + Text, + LoadingIndicator, + ButtonGroup, + colors, + Glyph, + FlexRow, + styled, + Searchable, +} from 'sonar'; +const {spawn} = require('child_process'); +const path = require('path'); +const {app, shell} = require('electron').remote; + +const SONAR_PLUGIN_PATH = path.join(app.getPath('home'), '.sonar'); +const DYNAMIC_PLUGINS = JSON.parse(window.process.env.PLUGINS || '[]'); + +type NPMModule = { + name: string, + version: string, + description?: string, + error?: Object, +}; + +type Status = + | 'installed' + | 'outdated' + | 'install' + | 'remove' + | 'update' + | 'uninstalled' + | 'uptodate'; + +type PluginT = { + name: string, + version?: string, + description?: string, + status: Status, + managed?: boolean, + entry?: string, + rootDir?: string, +}; + +type Props = { + searchTerm: string, +}; +type State = { + plugins: { + [name: string]: PluginT, + }, + restartRequired: boolean, + searchCompleted: boolean, +}; + +const Container = FlexBox.extends({ + width: '100%', + flexGrow: 1, + background: colors.light02, + overflowY: 'scroll', +}); + +const Title = Text.extends({ + fontWeight: 500, +}); + +const Plugin = FlexColumn.extends({ + backgroundColor: colors.white, + borderRadius: 4, + padding: 15, + margin: '0 15px 25px', + boxShadow: '0 1px 2px rgba(0,0,0,0.05)', +}); + +const SectionTitle = styled.text({ + fontWeight: 'bold', + fontSize: 24, + margin: 15, + marginLeft: 20, +}); + +const Loading = FlexBox.extends({ + padding: 50, + alignItems: 'center', + justifyContent: 'center', +}); + +const RestartRequired = FlexBox.extends({ + textAlign: 'center', + justifyContent: 'center', + fontWeight: 500, + color: colors.white, + padding: 12, + backgroundColor: colors.green, + cursor: 'pointer', +}); + +const TitleRow = FlexRow.extends({ + alignItems: 'center', + marginBottom: 10, + fontSize: '1.1em', +}); + +const Description = FlexRow.extends({ + marginBottom: 15, + lineHeight: '130%', +}); + +const PluginGlyph = Glyph.extends({ + marginRight: 5, +}); + +const PluginLoading = LoadingIndicator.extends({ + marginLeft: 5, + marginTop: 5, +}); + +const getLatestVersion = (name: string): Promise => { + return fetch(`http://registry.npmjs.org/${name}/latest`).then(res => + res.json(), + ); +}; + +const getPluginList = (): Promise> => { + return fetch( + 'http://registry.npmjs.org/-/v1/search?text=keywords:sonar&size=250', + ) + .then(res => res.json()) + .then(res => res.objects.map(o => o.package)); +}; + +const sortByName = (a: PluginT, b: PluginT): 1 | -1 => + a.name > b.name ? 1 : -1; + +const INSTALLED = ['installed', 'outdated', 'uptodate']; + +class PluginItem extends PureComponent< + { + plugin: PluginT, + onChangeState: (action: Status) => void, + }, + { + working: boolean, + }, +> { + state = { + working: false, + }; + + npmAction = (action: Status) => { + const {name, status: initialStatus} = this.props.plugin; + this.setState({working: true}); + const npm = spawn('npm', [action, name], { + cwd: SONAR_PLUGIN_PATH, + }); + + npm.stderr.on('data', e => { + console.error(e.toString()); + }); + + npm.on('close', code => { + this.setState({working: false}); + const newStatus = action === 'remove' ? 'uninstalled' : 'uptodate'; + this.props.onChangeState(code !== 0 ? initialStatus : newStatus); + }); + }; + + render() { + const { + entry, + status, + version, + description, + managed, + name, + rootDir, + } = this.props.plugin; + + return ( + + + + {name} +   + {version} + + {description && {description}} + + {managed ? ( + + This plugin is not managed by Sonar, but loaded from{' '} + + {rootDir} + + + ) : ( + + {status === 'outdated' && ( + + )} + {INSTALLED.includes(status) ? ( + + ) : ( + + )} + + + )} + {this.state.working && } + + + ); + } +} + +class PluginManager extends PureComponent { + state = { + plugins: DYNAMIC_PLUGINS.reduce((acc, plugin) => { + acc[plugin.name] = { + ...plugin, + managed: !(plugin.entry, '').startsWith(SONAR_PLUGIN_PATH), + status: 'installed', + }; + return acc; + }, {}), + restartRequired: false, + searchCompleted: false, + }; + + componentDidMount() { + Promise.all( + Object.keys(this.state.plugins) + .filter(name => this.state.plugins[name].managed) + .map(getLatestVersion), + ).then((res: Array) => { + const updates = {}; + res.forEach(plugin => { + if ( + plugin.error == null && + this.state.plugins[plugin.name].version !== plugin.version + ) { + updates[plugin.name] = { + ...plugin, + ...this.state.plugins[plugin.name], + status: 'outdated', + }; + } + }); + this.setState({ + plugins: { + ...this.state.plugins, + ...updates, + }, + }); + }); + + getPluginList().then(pluginList => { + const plugins = {...this.state.plugins}; + pluginList.forEach(plugin => { + if (plugins[plugin.name] != null) { + plugins[plugin.name] = { + ...plugin, + ...plugins[plugin.name], + status: + plugin.version === plugins[plugin.name].version + ? 'uptodate' + : 'outdated', + }; + } else { + plugins[plugin.name] = { + ...plugin, + status: 'uninstalled', + }; + } + }); + this.setState({ + plugins, + searchCompleted: true, + }); + }); + } + + onChangePluginState = (name: string, status: Status) => { + this.setState({ + plugins: { + ...this.state.plugins, + [name]: { + ...this.state.plugins[name], + status, + }, + }, + restartRequired: true, + }); + }; + + relaunch() { + app.relaunch(); + app.exit(0); + } + + render() { + // $FlowFixMe + const plugins: Array = Object.values(this.state.plugins); + const availablePlugins = plugins.filter( + ({status}) => !INSTALLED.includes(status), + ); + return ( + + + {this.state.restartRequired && ( + + +   Restart Required: Click to Restart + + )} + Installed Plugins + {plugins + .filter( + ({status, name}) => + INSTALLED.includes(status) && + name.indexOf(this.props.searchTerm) > -1, + ) + .sort(sortByName) + .map((plugin: PluginT) => ( + + this.onChangePluginState(plugin.name, action) + } + /> + ))} + Available Plugins + {availablePlugins + .filter(({name}) => name.indexOf(this.props.searchTerm) > -1) + .sort(sortByName) + .map((plugin: PluginT) => ( + + this.onChangePluginState(plugin.name, action) + } + /> + ))} + {!this.state.searchCompleted && ( + + + + )} + + + ); + } +} + +const SearchablePluginManager = Searchable(PluginManager); + +export default class extends PureComponent<{}> { + render() { + return ( + + + + ); + } +} diff --git a/src/chrome/Popover.js b/src/chrome/Popover.js new file mode 100644 index 000000000..32d0d5ccd --- /dev/null +++ b/src/chrome/Popover.js @@ -0,0 +1,196 @@ +/** + * Copyright 2018-present Facebook. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * @format + */ + +import { + PureComponent, + FlexColumn, + FlexRow, + FlexBox, + Text, + Button, + styled, + colors, +} from 'sonar'; + +const Anchor = styled.image({ + zIndex: 6, + position: 'absolute', + bottom: 0, + left: '50%', + transform: 'translate(-50%, calc(100% + 2px))', +}); + +const PopoverContainer = FlexColumn.extends({ + backgroundColor: colors.white, + borderRadius: 7, + border: '1px solid rgba(0,0,0,0.3)', + boxShadow: '0 2px 10px 0 rgba(0,0,0,0.3)', + position: 'absolute', + zIndex: 5, + minWidth: 240, + bottom: 0, + marginTop: 15, + left: '50%', + transform: 'translate(-50%, calc(100% + 15px))', + overflow: 'hidden', + '&::before': { + content: '""', + display: 'block', + position: 'absolute', + left: '50%', + transform: 'translateX(-50%)', + height: 13, + top: -13, + width: 26, + backgroundColor: colors.white, + }, +}); + +const Heading = Text.extends({ + display: 'block', + backgroundColor: colors.white, + color: colors.light30, + fontSize: 11, + fontWeight: 600, + lineHeight: '21px', + padding: '4px 8px 0', +}); + +const PopoverItem = FlexRow.extends({ + alignItems: 'center', + borderBottom: `1px solid ${colors.light05}`, + height: 50, + '&:last-child': { + borderBottom: 'none', + }, +}); + +const ItemTitle = Text.extends({ + display: 'block', + fontSize: 14, + fontWeight: 400, + lineHeight: '120%', + textOverflow: 'ellipsis', + overflow: 'hidden', + whiteSpace: 'nowrap', + marginBottom: 1, +}); + +const ItemSubtitle = Text.extends({ + display: 'block', + fontWeight: 400, + fontSize: 11, + color: colors.light30, + lineHeight: '14px', + textOverflow: 'ellipsis', + overflow: 'hidden', + whiteSpace: 'nowrap', +}); + +const ItemImage = FlexBox.extends({ + alignItems: 'center', + justifyContent: 'center', + width: 40, + flexShrink: 0, +}); + +const ItemContent = styled.view({ + minWidth: 0, + paddingRight: 5, + flexGrow: 1, +}); + +const Section = styled.view({ + borderBottom: `1px solid ${colors.light05}`, + '&:last-child': { + borderBottom: 'none', + }, +}); + +const Action = Button.extends({ + border: `1px solid ${colors.macOSTitleBarButtonBorder}`, + background: 'transparent', + color: colors.macOSTitleBarIconSelected, + marginRight: 8, + lineHeight: '22px', + '&:hover': { + background: 'transparent', + }, + '&:active': { + background: 'transparent', + border: `1px solid ${colors.macOSTitleBarButtonBorder}`, + }, +}); + +type Props = {| + sections: Array<{ + title: string, + items: Array<{ + title: string, + subtitle: string, + onClick?: Function, + icon?: React.Element<*>, + }>, + }>, + onDismiss: Function, +|}; + +export default class Popover extends PureComponent { + _ref: ?Element; + + componentDidMount() { + window.document.addEventListener('click', this.handleClick); + } + + componentWillUnmount() { + window.document.addEventListener('click', this.handleClick); + } + + handleClick = (e: SyntheticMouseEvent<>) => { + // $FlowFixMe + if (this._ref && !this._ref.contains(e.target)) { + this.props.onDismiss(); + } + }; + + _setRef = (ref: ?Element) => { + this._ref = ref; + }; + + render() { + return [ + , + + {this.props.sections.map(section => { + if (section.items.length > 0) { + return ( +
+ {section.title} + {section.items.map(item => ( + + {item.icon} + + {item.title} + {item.subtitle} + + {item.onClick && ( + + Run + + )} + + ))} +
+ ); + } else { + return null; + } + })} +
, + ]; + } +} diff --git a/src/chrome/SonarTitleBar.js b/src/chrome/SonarTitleBar.js new file mode 100644 index 000000000..bfb7ac999 --- /dev/null +++ b/src/chrome/SonarTitleBar.js @@ -0,0 +1,157 @@ +/** + * Copyright 2018-present Facebook. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * @format + */ + +import { + colors, + Button, + ButtonGroup, + FlexRow, + FlexBox, + Component, + Spacer, + Glyph, + GK, +} from 'sonar'; +import { + loadsDynamicPlugins, + dynamicPluginPath, +} from '../utils/dynamicPluginLoading.js'; +import {connect} from 'react-redux'; +import { + toggleBugDialogVisible, + toggleLeftSidebarVisible, + toggleRightSidebarVisible, + togglePluginManagerVisible, +} from '../reducers/application.js'; +import DevicesButton from './DevicesButton.js'; +import Version from './Version.js'; +import AutoUpdateVersion from './AutoUpdateVersion.js'; +import config from '../fb-stubs/config.js'; + +const TitleBar = FlexRow.extends( + { + background: props => + props.focused + ? `linear-gradient(to bottom, ${ + colors.macOSTitleBarBackgroundTop + } 0%, ${colors.macOSTitleBarBackgroundBottom} 100%)` + : colors.macOSTitleBarBackgroundBlur, + borderBottom: props => + `1px solid ${ + props.focused + ? colors.macOSTitleBarBorder + : colors.macOSTitleBarBorderBlur + }`, + height: 38, + flexShrink: 0, + width: '100%', + alignItems: 'center', + paddingLeft: 80, + paddingRight: 10, + justifyContent: 'space-between', + // $FlowFixMe + WebkitAppRegion: 'drag', + }, + { + ignoreAttributes: ['focused'], + }, +); + +const Icon = FlexBox.extends({ + marginRight: 3, +}); + +type Props = {| + windowIsFocused: boolean, + leftSidebarVisible: boolean, + rightSidebarVisible: boolean, + rightSidebarAvailable: boolean, + pluginManagerVisible: boolean, + toggleBugDialogVisible: (visible?: boolean) => void, + toggleLeftSidebarVisible: (visible?: boolean) => void, + toggleRightSidebarVisible: (visible?: boolean) => void, + togglePluginManagerVisible: (visible?: boolean) => void, +|}; + +class SonarTitleBar extends Component { + render() { + return ( + + + + {loadsDynamicPlugins() && ( + + + + )} + {process.platform === 'darwin' ? : } + {config.bugReportButtonVisible && ( + } + /> + + ); + } + }; +} diff --git a/src/device-plugins/cpu/index.js b/src/device-plugins/cpu/index.js new file mode 100644 index 000000000..5d0f83e48 --- /dev/null +++ b/src/device-plugins/cpu/index.js @@ -0,0 +1,323 @@ +/** + * Copyright 2018-present Facebook. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * @format + */ + +import {SonarDevicePlugin} from 'sonar'; +var adb = require('adbkit-fb'); + +import { + FlexColumn, + FlexRow, + Button, + Toolbar, + Text, + ManagedTable, + colors, +} from 'sonar'; + +type ADBClient = any; +type AndroidDevice = any; +type TableRows = any; + +// we keep vairable name with underline for to physical path mappings on device +type CPUFrequency = {| + cpu_id: number, + scaling_cur_freq: number, + scaling_min_freq: number, + scaling_max_freq: number, + cpuinfo_max_freq: number, + cpuinfo_min_freq: number, +|}; + +type CPUState = {| + cpuFreq: Array, + cpuCount: number, + monitoring: boolean, +|}; + +type ShellCallBack = (output: string) => void; + +const ColumnSizes = { + cpu_id: '10%', + scaling_cur_freq: 'flex', + scaling_min_freq: 'flex', + scaling_max_freq: 'flex', + cpuinfo_min_freq: 'flex', + cpuinfo_max_freq: 'flex', +}; + +const Columns = { + cpu_id: { + value: 'CPU ID', + resizable: true, + }, + scaling_cur_freq: { + value: 'Scaling Current', + resizable: true, + }, + scaling_min_freq: { + value: 'Scaling MIN', + resizable: true, + }, + scaling_max_freq: { + value: 'Scaling MAX', + resizable: true, + }, + cpuinfo_min_freq: { + value: 'MIN Frequency', + resizable: true, + }, + cpuinfo_max_freq: { + value: 'MAX Frequency', + resizable: true, + }, +}; + +// check if str is a number +function isNormalInteger(str) { + let n = Math.floor(Number(str)); + return String(n) === str && n >= 0; +} + +// format frequency to MHz, GHz +function formatFrequency(freq) { + if (freq == -1) { + return 'N/A'; + } else if (freq == -2) { + return 'off'; + } else if (freq > 1000 * 1000) { + return (freq / 1000 / 1000).toFixed(2) + ' GHz'; + } else { + return freq / 1000 + ' MHz'; + } +} + +export default class CPUFrequencyTable extends SonarDevicePlugin { + static id = 'DeviceCPU'; + static title = 'CPU'; + static icon = 'underline'; + + adbClient: ADBClient; + intervalID: ?IntervalID; + device: AndroidDevice; + + init() { + this.setState({ + cpuFreq: [], + cpuCount: 0, + monitoring: false, + }); + + this.adbClient = this.device.adb; + + // check how many cores we have on this device + this.executeShell((output: string) => { + let idx = output.indexOf('-'); + let cpuFreq = []; + let count = parseInt(output.substring(idx + 1), 10) + 1; + for (let i = 0; i < count; ++i) { + cpuFreq[i] = { + cpu_id: i, + scaling_cur_freq: -1, + scaling_min_freq: -1, + scaling_max_freq: -1, + cpuinfo_min_freq: -1, + cpuinfo_max_freq: -1, + }; + } + this.setState({ + cpuCount: count, + cpuFreq: cpuFreq, + }); + }, 'cat /sys/devices/system/cpu/possible'); + } + + executeShell = (callback: ShellCallBack, command: string) => { + this.adbClient + .shell(this.device.serial, command) + .then(adb.util.readAll) + .then(function(output) { + return callback(output.toString().trim()); + }); + }; + + updateCoreFrequency = (core: number, type: string) => { + this.executeShell((output: string) => { + let cpuFreq = this.state.cpuFreq; + let newFreq = isNormalInteger(output) ? parseInt(output, 10) : -1; + + // update table only if frequency changed + if (cpuFreq[core][type] != newFreq) { + cpuFreq[core][type] = newFreq; + if (type == 'scaling_cur_freq' && cpuFreq[core][type] < 0) { + // cannot find current freq means offline + cpuFreq[core][type] = -2; + } + + this.setState({ + cpuFreq: cpuFreq, + }); + } + }, 'cat /sys/devices/system/cpu/cpu' + core + '/cpufreq/' + type); + }; + + readCoreFrequency = (core: number) => { + let freq = this.state.cpuFreq[core]; + if (freq.cpuinfo_max_freq < 0) { + this.updateCoreFrequency(core, 'cpuinfo_max_freq'); + } + if (freq.cpuinfo_min_freq < 0) { + this.updateCoreFrequency(core, 'cpuinfo_min_freq'); + } + this.updateCoreFrequency(core, 'scaling_cur_freq'); + this.updateCoreFrequency(core, 'scaling_min_freq'); + this.updateCoreFrequency(core, 'scaling_max_freq'); + }; + + onStartMonitor = () => { + if (this.intervalID) { + return; + } + + this.intervalID = setInterval(() => { + for (let i = 0; i < this.state.cpuCount; ++i) { + this.readCoreFrequency(i); + } + }, 500); + + this.setState({ + monitoring: true, + }); + }; + + onStopMonitor = () => { + if (!this.intervalID) { + return; + } else { + clearInterval(this.intervalID); + this.intervalID = null; + this.setState({ + monitoring: false, + }); + this.cleanup(); + } + }; + + cleanup = () => { + let cpuFreq = this.state.cpuFreq; + for (let i = 0; i < this.state.cpuCount; ++i) { + cpuFreq[i].scaling_cur_freq = -1; + cpuFreq[i].scaling_min_freq = -1; + cpuFreq[i].scaling_max_freq = -1; + // we don't cleanup cpuinfo_min_freq, cpuinfo_max_freq + // because usually they are fixed (hardware) + } + this.setState({ + cpuFreq: cpuFreq, + }); + }; + + teardown = () => { + this.cleanup(); + }; + + buildRow = (freq: CPUFrequency) => { + let style = {}; + if (freq.scaling_cur_freq == -2) { + style = { + style: { + backgroundColor: colors.blueTint30, + color: colors.white, + fontWeight: 700, + }, + }; + } else if ( + freq.scaling_min_freq != freq.cpuinfo_min_freq && + freq.scaling_min_freq > 0 && + freq.cpuinfo_min_freq > 0 + ) { + style = { + style: { + backgroundColor: colors.redTint, + color: colors.red, + fontWeight: 700, + }, + }; + } else if ( + freq.scaling_max_freq != freq.cpuinfo_max_freq && + freq.scaling_max_freq > 0 && + freq.cpuinfo_max_freq > 0 + ) { + style = { + style: { + backgroundColor: colors.yellowTint, + color: colors.yellow, + fontWeight: 700, + }, + }; + } + + return { + columns: { + cpu_id: {value: CPU_{freq.cpu_id}}, + scaling_cur_freq: { + value: {formatFrequency(freq.scaling_cur_freq)}, + }, + scaling_min_freq: { + value: {formatFrequency(freq.scaling_min_freq)}, + }, + scaling_max_freq: { + value: {formatFrequency(freq.scaling_max_freq)}, + }, + cpuinfo_min_freq: { + value: {formatFrequency(freq.cpuinfo_min_freq)}, + }, + cpuinfo_max_freq: { + value: {formatFrequency(freq.cpuinfo_max_freq)}, + }, + }, + key: freq.cpu_id, + style, + }; + }; + + frequencyRows = (cpuFreqs: Array): TableRows => { + let rows = []; + for (const cpuFreq of cpuFreqs) { + rows.push(this.buildRow(cpuFreq)); + } + return rows; + }; + + render() { + return ( + + + + {this.state.monitoring ? ( + + ) : ( + + )} + + + + + ); + } +} diff --git a/src/device-plugins/index.js b/src/device-plugins/index.js new file mode 100644 index 000000000..8d831f5d7 --- /dev/null +++ b/src/device-plugins/index.js @@ -0,0 +1,22 @@ +/** + * Copyright 2018-present Facebook. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * @format + */ +import {GK} from 'sonar'; +import logs from './logs/index.js'; +import cpu from './cpu/index.js'; +import screen from './screen/index.js'; + +const plugins = [logs]; + +if (GK.get('sonar_uiperf')) { + plugins.push(cpu); +} + +if (GK.get('sonar_screen_plugin')) { + plugins.push(screen); +} + +export const devicePlugins = plugins; diff --git a/src/device-plugins/logs/LogTable.js b/src/device-plugins/logs/LogTable.js new file mode 100644 index 000000000..919c1a735 --- /dev/null +++ b/src/device-plugins/logs/LogTable.js @@ -0,0 +1,562 @@ +/** + * Copyright 2018-present Facebook. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * @format + */ + +import type { + TableBodyRow, + TableColumnOrder, + TableColumnSizes, + TableColumns, +} from 'sonar'; +import type {Counter} from './LogWatcher.js'; +import type {DeviceLogEntry} from '../../devices/BaseDevice.js'; + +import { + Text, + ManagedTable, + Button, + colors, + FlexCenter, + LoadingIndicator, + ContextMenu, + FlexColumn, + Glyph, +} from 'sonar'; +import {SonarDevicePlugin, SearchableTable} from 'sonar'; +import textContent from '../../utils/textContent.js'; +import createPaste from '../../utils/createPaste.js'; +import LogWatcher from './LogWatcher'; + +const LOG_WATCHER_LOCAL_STORAGE_KEY = 'LOG_WATCHER_LOCAL_STORAGE_KEY'; + +type Entries = Array<{ + row: TableBodyRow, + entry: DeviceLogEntry, +}>; + +type LogsState = {| + initialising: boolean, + rows: Array, + entries: Entries, + key2entry: {[key: string]: DeviceLogEntry}, + highlightedRows: Array, + counters: Array, +|}; + +const Icon = Glyph.extends({ + marginTop: 5, +}); + +function getLineCount(str: string): number { + let count = 1; + for (let i = 0; i < str.length; i++) { + if (str[i] === '\n') { + count++; + } + } + return count; +} + +function keepKeys(obj, keys) { + const result = {}; + for (const key in obj) { + if (keys.includes(key)) { + result[key] = obj[key]; + } + } + return result; +} + +const COLUMN_SIZE = { + type: 32, + time: 120, + pid: 60, + tid: 60, + tag: 120, + app: 200, + message: 'flex', +}; + +const COLUMNS = { + type: { + value: '', + }, + time: { + value: 'Time', + }, + pid: { + value: 'PID', + }, + tid: { + value: 'TID', + }, + tag: { + value: 'Tag', + }, + app: { + value: 'App', + }, + message: { + value: 'Message', + }, +}; + +const INITIAL_COLUMN_ORDER = [ + { + key: 'type', + visible: true, + }, + { + key: 'time', + visible: false, + }, + { + key: 'pid', + visible: false, + }, + { + key: 'tid', + visible: false, + }, + { + key: 'tag', + visible: true, + }, + { + key: 'app', + visible: true, + }, + { + key: 'message', + visible: true, + }, +]; + +const LOG_TYPES: { + [level: string]: { + label: string, + color: string, + icon?: React.Node, + style?: Object, + }, +} = { + verbose: { + label: 'Verbose', + color: colors.purple, + }, + debug: { + label: 'Debug', + color: colors.grey, + }, + info: { + label: 'Info', + icon: , + color: colors.cyan, + }, + warn: { + label: 'Warn', + style: { + backgroundColor: colors.yellowTint, + color: colors.yellow, + fontWeight: 500, + }, + icon: , + color: colors.yellow, + }, + error: { + label: 'Error', + style: { + backgroundColor: colors.redTint, + color: colors.red, + fontWeight: 500, + }, + icon: , + color: colors.red, + }, + fatal: { + label: 'Fatal', + style: { + backgroundColor: colors.redTint, + color: colors.red, + fontWeight: 700, + }, + icon: , + color: colors.red, + }, +}; + +const DEFAULT_FILTERS = [ + { + type: 'enum', + enum: Object.keys(LOG_TYPES).map(value => ({ + label: LOG_TYPES[value].label, + value, + })), + key: 'type', + value: [], + persistent: true, + }, +]; + +const NonSelectableText = Text.extends({ + alignSelf: 'baseline', + userSelect: 'none', + lineHeight: '130%', + marginTop: 6, +}); + +const LogCount = NonSelectableText.extends( + { + backgroundColor: props => props.color, + borderRadius: '999em', + fontSize: 11, + display: 'flex', + justifyContent: 'center', + alignItems: 'center', + marginTop: 4, + width: 16, + height: 16, + color: colors.white, + }, + { + ignoreAttributes: ['color'], + }, +); + +const HiddenScrollText = NonSelectableText.extends({ + '&::-webkit-scrollbar': { + display: 'none', + }, +}); + +function pad(chunk: mixed, len: number): string { + let str = String(chunk); + while (str.length < len) { + str = `0${str}`; + } + return str; +} + +export default class LogTable extends SonarDevicePlugin { + static id = 'DeviceLogs'; + static title = 'Logs'; + static icon = 'arrow-right'; + static keyboardActions = ['clear', 'goToBottom', 'createPaste']; + + onKeyboardAction = (action: string) => { + if (action === 'clear') { + this.clearLogs(); + } else if (action === 'goToBottom') { + this.goToBottom(); + } else if (action === 'createPaste') { + this.createPaste(); + } + }; + + restoreSavedCounters = (): Array => { + const savedCounters = + window.localStorage.getItem(LOG_WATCHER_LOCAL_STORAGE_KEY) || '[]'; + return JSON.parse(savedCounters).map((counter: Counter) => ({ + ...counter, + expression: new RegExp(counter.label, 'gi'), + count: 0, + })); + }; + + state = { + rows: [], + entries: [], + key2entry: {}, + initialising: true, + highlightedRows: [], + counters: this.restoreSavedCounters(), + }; + + tableRef: ?ManagedTable; + columns: TableColumns; + columnSizes: TableColumnSizes; + columnOrder: TableColumnOrder; + + init() { + let batch: Entries = []; + let queued = false; + let counter = 0; + + const supportedColumns = this.device.supportedColumns(); + this.columns = keepKeys(COLUMNS, supportedColumns); + this.columnSizes = keepKeys(COLUMN_SIZE, supportedColumns); + this.columnOrder = INITIAL_COLUMN_ORDER.filter(obj => + supportedColumns.includes(obj.key), + ); + + this.device.addLogListener((entry: DeviceLogEntry) => { + const {icon, style} = + LOG_TYPES[(entry.type: string)] || LOG_TYPES.verbose; + + // clean message + const message = entry.message.trim(); + entry.type === 'error'; + + let counterUpdated = false; + const counters = this.state.counters.map(counter => { + if (message.match(counter.expression)) { + counterUpdated = true; + if (counter.notify) { + new window.Notification(`${counter.label}`, { + body: 'The watched log message appeared', + }); + } + return { + ...counter, + count: counter.count + 1, + }; + } else { + return counter; + } + }); + if (counterUpdated) { + this.setState({counters}); + } + + // build the item, it will either be batched or added straight away + const item = { + entry, + row: { + columns: { + type: { + value: icon, + }, + time: { + value: ( + + {entry.date.toTimeString().split(' ')[0] + + '.' + + pad(entry.date.getMilliseconds(), 3)} + + ), + }, + message: { + value: {message}, + }, + tag: { + value: ( + {entry.tag} + ), + isFilterable: true, + }, + pid: { + value: ( + + {String(entry.pid)} + + ), + isFilterable: true, + }, + tid: { + value: ( + + {String(entry.tid)} + + ), + isFilterable: true, + }, + app: { + value: ( + {entry.app} + ), + isFilterable: true, + }, + }, + height: getLineCount(message) * 15 + 10, // 15px per line height + 8px padding + style, + type: entry.type, + filterValue: entry.message, + key: String(counter++), + }, + }; + + // batch up logs to be processed every 250ms, if we have lots of log + // messages coming in, then calling an setState 200+ times is actually + // pretty expensive + batch.push(item); + + if (!queued) { + queued = true; + + setTimeout(() => { + const thisBatch = batch; + batch = []; + queued = false; + + // update rows/entries + this.setState(state => { + const rows = [...state.rows]; + const entries = [...state.entries]; + const key2entry = {...state.key2entry}; + + for (let i = 0; i < thisBatch.length; i++) { + const {entry, row} = thisBatch[i]; + entries.push({row, entry}); + key2entry[row.key] = entry; + + let previousEntry: ?DeviceLogEntry = null; + + if (i > 0) { + previousEntry = thisBatch[i - 1].entry; + } else if (state.rows.length > 0 && state.entries.length > 0) { + previousEntry = state.entries[state.entries.length - 1].entry; + } + + this.addRowIfNeeded(rows, row, entry, previousEntry); + } + + return { + entries, + rows, + key2entry, + }; + }); + }, 100); + } + }); + + setTimeout(() => { + this.setState({ + initialising: false, + }); + }, 2000); + } + + addRowIfNeeded( + rows: Array, + row: TableBodyRow, + entry: DeviceLogEntry, + previousEntry: ?DeviceLogEntry, + ) { + const previousRow = rows.length > 0 ? rows[rows.length - 1] : null; + if ( + previousRow && + previousEntry && + entry.message === previousEntry.message && + entry.tag === previousEntry.tag && + previousRow.type != null + ) { + const count = (previousRow.columns.time.value.props.count || 1) + 1; + previousRow.columns.type.value = ( + {count} + ); + } else { + rows.push(row); + } + } + + clearLogs = () => { + this.setState({ + entries: [], + rows: [], + highlightedRows: [], + key2entry: {}, + counters: this.state.counters.map(counter => ({ + ...counter, + count: 0, + })), + }); + }; + + createPaste = () => { + let paste = ''; + const mapFn = row => + Object.keys(COLUMNS) + .map(key => textContent(row.columns[key].value)) + .join('\t'); + + if (this.state.highlightedRows.length > 0) { + // create paste from selection + paste = this.state.rows + .filter(row => this.state.highlightedRows.indexOf(row.key) > -1) + .map(mapFn) + .join('\n'); + } else { + // create paste with all rows + paste = this.state.rows.map(mapFn).join('\n'); + } + createPaste(paste); + }; + + setTableRef = (ref: React.ElementRef<*>) => { + this.tableRef = ref; + }; + + goToBottom = () => { + if (this.tableRef != null) { + this.tableRef.scrollToBottom(); + } + }; + + onRowHighlighted = (highlightedRows: Array) => { + this.setState({ + ...this.state, + highlightedRows, + }); + }; + + renderSidebar = () => { + return ( + + this.setState({counters}, () => + window.localStorage.setItem( + LOG_WATCHER_LOCAL_STORAGE_KEY, + JSON.stringify(this.state.counters), + ), + ) + } + /> + ); + }; + + static ContextMenu = ContextMenu.extends({ + flex: 1, + }); + + render() { + const {initialising, highlightedRows, rows} = this.state; + + const contextMenuItems = [ + { + type: 'separator', + }, + { + label: 'Clear all', + click: this.clearLogs, + }, + ]; + return initialising ? ( + + + + ) : ( + + Clear Logs} + /> + + ); + } +} diff --git a/src/device-plugins/logs/LogWatcher.js b/src/device-plugins/logs/LogWatcher.js new file mode 100644 index 000000000..5c005a348 --- /dev/null +++ b/src/device-plugins/logs/LogWatcher.js @@ -0,0 +1,216 @@ +/** + * Copyright 2018-present Facebook. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * @format + */ + +import { + PureComponent, + FlexColumn, + Panel, + Input, + Toolbar, + Text, + ManagedTable, + Button, + colors, +} from 'sonar'; + +export type Counter = { + expression: RegExp, + count: number, + notify: boolean, + label: string, +}; + +type Props = {| + onChange: (counters: Array) => void, + counters: Array, +|}; + +type State = { + input: string, + highlightedRow: ?string, +}; + +const ColumnSizes = { + expression: '70%', + count: '15%', + notify: 'flex', +}; + +const Columns = { + expression: { + value: 'Expression', + resizable: false, + }, + count: { + value: 'Count', + resizable: false, + }, + notify: { + value: 'Notify', + resizable: false, + }, +}; + +const Count = Text.extends({ + alignSelf: 'center', + background: colors.macOSHighlightActive, + color: colors.white, + fontSize: 12, + fontWeight: 500, + textAlign: 'center', + borderRadius: '999em', + padding: '4px 9px 3px', + lineHeight: '100%', + marginLeft: 'auto', +}); + +const Checkbox = Input.extends({ + lineHeight: '100%', + padding: 0, + margin: 0, + height: 'auto', + alignSelf: 'center', +}); + +const ExpressionInput = Input.extends({ + flexGrow: 1, +}); + +const WatcherPanel = Panel.extends({ + minHeight: 200, +}); + +export default class LogWatcher extends PureComponent { + state = { + input: '', + highlightedRow: null, + }; + + _inputRef: ?HTMLInputElement; + + onAdd = () => { + if ( + this.props.counters.findIndex(({label}) => label === this.state.input) > + -1 + ) { + // prevent duplicates + return; + } + this.props.onChange([ + ...this.props.counters, + { + label: this.state.input, + expression: new RegExp(this.state.input, 'gi'), + notify: false, + count: 0, + }, + ]); + this.setState({input: ''}); + }; + + onChange = (e: SyntheticInputEvent) => { + this.setState({ + input: e.target.value, + }); + }; + + resetCount = (index: number) => { + const newCounters = [...this.props.counters]; + newCounters[index] = { + ...newCounters[index], + count: 0, + }; + this.props.onChange(newCounters); + }; + + buildRows = () => { + return this.props.counters.map(({label, count, notify}, i) => ({ + columns: { + expression: { + value: {label}, + }, + count: { + value: this.resetCount(i)}>{count}, + }, + notify: { + value: ( + this.setNotification(i, !notify)} + /> + ), + }, + }, + key: label, + })); + }; + + setNotification = (index: number, notify: boolean) => { + const newCounters: Array = [...this.props.counters]; + newCounters[index] = { + ...newCounters[index], + notify, + }; + this.props.onChange(newCounters); + }; + + onRowHighlighted = (rows: Array) => { + this.setState({ + highlightedRow: rows.length === 1 ? rows[0] : null, + }); + }; + + onKeyDown = (e: SyntheticKeyboardEvent<>) => { + if ( + (e.key === 'Delete' || e.key === 'Backspace') && + this.state.highlightedRow != null + ) { + this.props.onChange( + this.props.counters.filter( + ({label}) => label !== this.state.highlightedRow, + ), + ); + } + }; + + onSubmit = (e: SyntheticKeyboardEvent<>) => { + if (e.key === 'Enter') { + this.onAdd(); + } + }; + + render() { + return ( + + + + + + + + + + ); + } +} diff --git a/src/device-plugins/logs/index.js b/src/device-plugins/logs/index.js new file mode 100644 index 000000000..262450342 --- /dev/null +++ b/src/device-plugins/logs/index.js @@ -0,0 +1,8 @@ +/** + * Copyright 2018-present Facebook. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * @format + */ +import LogTable from './LogTable.js'; +export default LogTable; diff --git a/src/device-plugins/screen/index.js b/src/device-plugins/screen/index.js new file mode 100644 index 000000000..086f566da --- /dev/null +++ b/src/device-plugins/screen/index.js @@ -0,0 +1,282 @@ +/** + * Copyright 2018-present Facebook. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * @format + */ + +import {SonarDevicePlugin} from 'sonar'; + +import { + Button, + FlexColumn, + FlexRow, + LoadingIndicator, + styled, + colors, + Component, +} from 'sonar'; + +const os = require('os'); +const fs = require('fs'); +const adb = require('adbkit-fb'); +const path = require('path'); +const exec = require('child_process').exec; +const SCREENSHOT_FILE_NAME = 'screen.png'; +const VIDEO_FILE_NAME = 'video.mp4'; +const SCREENSHOT_PATH = path.join( + os.homedir(), + '/.sonar/', + SCREENSHOT_FILE_NAME, +); +const VIDEO_PATH = path.join(os.homedir(), '.sonar', VIDEO_FILE_NAME); + +type AndroidDevice = any; +type AdbClient = any; +type PullTransfer = any; + +type State = {| + pullingData: boolean, + recording: boolean, + recordingEnabled: boolean, + capturingScreenshot: boolean, +|}; + +const BigButton = Button.extends({ + height: 200, + width: 200, + flexGrow: 1, + fontSize: 24, +}); + +const ButtonContainer = FlexRow.extends({ + alignItems: 'center', + justifyContent: 'space-around', + padding: 20, +}); + +const LoadingSpinnerContainer = FlexRow.extends({ + flexGrow: 1, + padding: 24, + justifyContent: 'center', + alignItems: 'center', +}); + +const LoadingSpinnerText = styled.text({ + fontSize: 24, + marginLeft: 12, + color: colors.grey, +}); + +class LoadingSpinner extends Component<{}, {}> { + render() { + return ( + + + Pulling files from device... + + ); + } +} + +function openFile(path: string): Promise<*> { + return new Promise((resolve, reject) => { + exec(`${getOpenCommand()} ${path}`, (error, stdout, stderr) => { + if (error) { + reject(error); + } else { + resolve(path); + } + }); + }); +} + +function getOpenCommand(): string { + //TODO: TESTED ONLY ON MAC! + switch (os.platform()) { + case 'win32': + return 'start'; + case 'linux': + return 'xdg-open'; + default: + return 'open'; + } +} + +function writePngStreamToFile(stream: PullTransfer): Promise { + return new Promise((resolve, reject) => { + stream.on('end', () => { + resolve(SCREENSHOT_PATH); + }); + stream.on('error', reject); + stream.pipe(fs.createWriteStream(SCREENSHOT_PATH)); + }); +} + +export default class ScreenPlugin extends SonarDevicePlugin { + static id = 'DeviceScreen'; + static title = 'Screen'; + static icon = 'mobile'; + + device: AndroidDevice; + adbClient: AdbClient; + + init() { + this.adbClient = this.device.adb; + + this.executeShell( + `[ ! -f /system/bin/screenrecord ] && echo "File does not exist"`, + ).then(output => { + if (output) { + console.error( + 'screenrecord util does not exist. Most likely it is an emulator which does not support screen recording via adb', + ); + this.setState({ + recordingEnabled: false, + }); + } else { + this.setState({ + recordingEnabled: true, + }); + } + }); + } + + captureScreenshot = () => { + return this.adbClient + .screencap(this.device.serial) + .then(writePngStreamToFile) + .then(openFile) + .catch(error => { + //TODO: proper logging? + console.error(error); + }); + }; + + pullFromDevice = (src: string, dst: string): Promise => { + return new Promise((resolve, reject) => { + return this.adbClient.pull(this.device.serial, src).then(stream => { + stream.on('end', () => { + resolve(dst); + }); + stream.on('error', reject); + stream.pipe(fs.createWriteStream(dst)); + }); + }); + }; + + onRecordingClicked = () => { + if (this.state.recording) { + this.stopRecording(); + } else { + this.startRecording(); + } + }; + + onScreenshotClicked = () => { + var self = this; + this.setState({ + capturingScreenshot: true, + }); + this.captureScreenshot().then(() => { + self.setState({ + capturingScreenshot: false, + }); + }); + }; + + startRecording = () => { + const self = this; + this.setState({ + recording: true, + }); + this.executeShell(`screenrecord --bugreport /sdcard/${VIDEO_FILE_NAME}`) + .then(output => { + if (output) { + throw output; + } + }) + .then(() => { + self.setState({ + recording: false, + pullingData: true, + }); + }) + .then((): Promise => { + return self.pullFromDevice(`/sdcard/${VIDEO_FILE_NAME}`, VIDEO_PATH); + }) + .then(openFile) + .then(() => { + self.executeShell(`rm /sdcard/${VIDEO_FILE_NAME}`); + }) + .then(() => { + self.setState({ + pullingData: false, + }); + }) + .catch(error => { + console.error(`unable to capture video: ${error}`); + self.setState({ + recording: false, + pullingData: false, + }); + }); + }; + + stopRecording = () => { + this.executeShell(`pgrep 'screenrecord' -L 2`); + }; + + executeShell = (command: string): Promise => { + return this.adbClient + .shell(this.device.serial, command) + .then(adb.util.readAll) + .then(output => { + return new Promise((resolve, reject) => { + resolve(output.toString().trim()); + }); + }); + }; + + getLoadingSpinner = () => { + return this.state.pullingData ? : null; + }; + + render() { + const recordingEnabled = + this.state.recordingEnabled && + !this.state.capturingScreenshot && + !this.state.pullingData; + const screenshotEnabled = + !this.state.recording && + !this.state.capturingScreenshot && + !this.state.pullingData; + return ( + + + + {!this.state.recording ? 'Record screen' : 'Stop recording'} + + + Take screenshot + + + {this.getLoadingSpinner()} + + ); + } +} diff --git a/src/devices/AndroidDevice.js b/src/devices/AndroidDevice.js new file mode 100644 index 000000000..bb37e88f7 --- /dev/null +++ b/src/devices/AndroidDevice.js @@ -0,0 +1,95 @@ +/** + * Copyright 2018-present Facebook. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * @format + */ + +import type {DeviceType, DeviceShell, DeviceLogListener} from './BaseDevice.js'; + +import {Priority} from 'adbkit-logcat-fb'; +import child_process from 'child_process'; + +// TODO +import BaseDevice from './BaseDevice.js'; + +type ADBClient = any; + +export default class AndroidDevice extends BaseDevice { + constructor( + serial: string, + deviceType: DeviceType, + title: string, + adb: ADBClient, + ) { + super(serial, deviceType, title); + this.adb = adb; + if (deviceType == 'physical') { + this.supportedPlugins.push('DeviceCPU'); + } + } + + supportedPlugins = [ + 'DeviceLogs', + 'DeviceShell', + 'DeviceFiles', + 'DeviceScreen', + ]; + icon = 'icons/android.svg'; + os = 'Android'; + adb: ADBClient; + pidAppMapping: {[key: number]: string} = {}; + + supportedColumns(): Array { + return ['date', 'pid', 'tid', 'tag', 'message', 'type', 'time']; + } + + addLogListener(callback: DeviceLogListener) { + this.adb.openLogcat(this.serial).then(reader => { + reader.on('entry', async entry => { + let type = 'unknown'; + if (entry.priority === Priority.VERBOSE) { + type = 'verbose'; + } + if (entry.priority === Priority.DEBUG) { + type = 'debug'; + } + if (entry.priority === Priority.INFO) { + type = 'info'; + } + if (entry.priority === Priority.WARN) { + type = 'warn'; + } + if (entry.priority === Priority.ERROR) { + type = 'error'; + } + if (entry.priority === Priority.FATAL) { + type = 'fatal'; + } + + callback({ + tag: entry.tag, + pid: entry.pid, + tid: entry.tid, + message: entry.message, + date: entry.date, + type, + }); + }); + }); + } + + reverse(): Promise { + if (this.deviceType === 'physical') { + return this.adb + .reverse(this.serial, 'tcp:8088', 'tcp:8088') + .then(_ => this.adb.reverse(this.serial, 'tcp:8089', 'tcp:8089')); + } else { + return Promise.resolve(); + } + } + + spawnShell(): DeviceShell { + return child_process.spawn('adb', ['-s', this.serial, 'shell', '-t', '-t']); + } +} diff --git a/src/devices/BaseDevice.js b/src/devices/BaseDevice.js new file mode 100644 index 000000000..effb9d06a --- /dev/null +++ b/src/devices/BaseDevice.js @@ -0,0 +1,78 @@ +/** + * Copyright 2018-present Facebook. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * @format + */ + +import type stream from 'stream'; +import {SonarDevicePlugin} from 'sonar'; + +export type DeviceLogEntry = { + date: Date, + pid: number, + tid: number, + app?: string, + type: 'unknown' | 'verbose' | 'debug' | 'info' | 'warn' | 'error' | 'fatal', + tag: string, + message: string, +}; + +export type DeviceShell = { + stdout: stream.Readable, + stderr: stream.Readable, + stdin: stream.Writable, +}; + +export type DeviceLogListener = (entry: DeviceLogEntry) => void; + +export type DeviceType = 'emulator' | 'physical'; + +export default class BaseDevice { + constructor(serial: string, deviceType: DeviceType, title: string) { + this.serial = serial; + this.title = title; + this.deviceType = deviceType; + } + + // operating system of this device + os: string; + + // human readable name for this device + title: string; + + // type of this device + deviceType: DeviceType; + + // serial number for this device + serial: string; + + // supported device plugins for this platform + supportedPlugins: Array = []; + + // possible src of icon to display next to the device title + icon: ?string; + + supportsPlugin(DevicePlugin: Class>) { + return this.supportedPlugins.includes(DevicePlugin.id); + } + + // ensure that we don't serialise devices + toJSON() { + return null; + } + + teardown() {} + + supportedColumns(): Array { + throw new Error('unimplemented'); + } + + addLogListener(listener: DeviceLogListener) { + throw new Error('unimplemented'); + } + + spawnShell(): DeviceShell { + throw new Error('unimplemented'); + } +} diff --git a/src/devices/IOSDevice.js b/src/devices/IOSDevice.js new file mode 100644 index 000000000..03fda8456 --- /dev/null +++ b/src/devices/IOSDevice.js @@ -0,0 +1,162 @@ +/** + * Copyright 2018-present Facebook. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * @format + */ + +import type { + DeviceType, + DeviceLogEntry, + DeviceLogListener, +} from './BaseDevice.js'; +import child_process from 'child_process'; +import BaseDevice from './BaseDevice.js'; +import JSONStream from 'JSONStream'; +import {Transform} from 'stream'; + +type RawLogEntry = { + activityID: string, // Number in string format + eventMessage: string, + eventType: string, + machTimestamp: number, + processID: number, + processImagePath: string, + processImageUUID: string, + processUniqueID: number, + senderImagePath: string, + senderImageUUID: string, + senderProgramCounter: number, + threadID: number, + timestamp: string, // "2017-09-27 16:21:15.771213-0400" + timezoneName: string, + traceID: string, +}; + +export default class IOSDevice extends BaseDevice { + supportedPlugins = ['DeviceLogs']; + icon = 'icons/ios.svg'; + os = 'iOS'; + + log: any; + buffer: string; + + constructor(serial: string, deviceType: DeviceType, title: string) { + super(serial, deviceType, title); + + this.buffer = ''; + this.log = null; + } + + teardown() { + if (this.log) { + this.log.kill(); + } + } + + supportedColumns(): Array { + return ['date', 'pid', 'tid', 'tag', 'message', 'type', 'time']; + } + + addLogListener(callback: DeviceLogListener) { + if (!this.log) { + this.log = child_process.spawn( + 'xcrun', + [ + 'simctl', + 'spawn', + 'booted', + 'log', + 'stream', + '--style', + 'json', + '--predicate', + 'senderImagePath contains "Containers"', + '--info', + '--debug', + ], + {}, + ); + + this.log.on('error', err => { + console.error(err); + }); + + this.log.stderr.on('data', data => { + console.error(data.toString()); + }); + + this.log.on('exit', () => { + this.log = null; + }); + } + + this.log.stdout + .pipe(new StripLogPrefix()) + .pipe(JSONStream.parse('*')) + .on('data', (data: RawLogEntry) => { + callback(IOSDevice.parseLogEntry(data)); + }); + } + + static parseLogEntry(entry: RawLogEntry): DeviceLogEntry { + let type = 'unknown'; + if (entry.eventMessage.indexOf('[debug]') !== -1) { + type = 'debug'; + } else if (entry.eventMessage.indexOf('[info]') !== -1) { + type = 'info'; + } else if (entry.eventMessage.indexOf('[warn]') !== -1) { + type = 'warn'; + } else if (entry.eventMessage.indexOf('[error]') !== -1) { + type = 'error'; + } + + // remove timestamp in front of message + entry.eventMessage = entry.eventMessage.replace( + /^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\.\d{3} /, + '', + ); + + // remove type from mesage + entry.eventMessage = entry.eventMessage.replace( + /^\[(debug|info|warn|error)\]/, + '', + ); + + const tags = entry.processImagePath.split('/'); + const tag = tags[tags.length - 1]; + + return { + date: new Date(entry.timestamp), + pid: entry.processID, + tid: entry.threadID, + tag, + message: entry.eventMessage, + type, + }; + } +} + +// Used to strip the initial output of the logging utility where it prints out settings. +// We know the log stream is json so it starts with an open brace. +class StripLogPrefix extends Transform { + passedPrefix = false; + + _transform( + data: any, + encoding: string, + callback: (err?: Error, data?: any) => void, + ) { + if (this.passedPrefix) { + this.push(data); + } else { + const dataString = data.toString(); + const index = dataString.indexOf('['); + if (index >= 0) { + this.push(dataString.substring(index)); + this.passedPrefix = true; + } + } + callback(); + } +} diff --git a/src/devices/OculusDevice.js b/src/devices/OculusDevice.js new file mode 100644 index 000000000..ad549541f --- /dev/null +++ b/src/devices/OculusDevice.js @@ -0,0 +1,142 @@ +/** + * Copyright 2018-present Facebook. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * @format + */ + +import type { + DeviceType, + DeviceLogEntry, + DeviceLogListener, +} from './BaseDevice.js'; + +import fs from 'fs-extra'; +import os from 'os'; +import path from 'path'; + +import BaseDevice from './BaseDevice.js'; + +function getLogsPath(fileName: ?string): string { + const dir = '/AppData/Local/Oculus/'; + if (fileName) { + return path.join(os.homedir(), dir, fileName); + } + return path.join(os.homedir(), dir); +} + +export default class OculusDevice extends BaseDevice { + supportedPlugins = ['DeviceLogs']; + icon = 'icons/oculus.png'; + os = 'Oculus'; + + watcher: any; + processedFileMap: {}; + watchedFile: ?string; + timer: TimeoutID; + + constructor(serial: string, deviceType: DeviceType, title: string) { + super(serial, deviceType, title); + + this.watcher = null; + this.processedFileMap = {}; + } + + teardown() { + clearTimeout(this.timer); + const file = this.watchedFile; + if (file) { + fs.unwatchFile(path.join(getLogsPath(), file)); + } + } + + supportedColumns(): Array { + return ['date', 'tag', 'message', 'type', 'time']; + } + + mapLogLevel(type: string): $PropertyType { + switch (type) { + case 'WARNING': + return 'warn'; + case '!ERROR!': + return 'error'; + case 'DEBUG': + return 'debug'; + case 'INFO': + return 'info'; + default: + return 'verbose'; + } + } + + processText(text: Buffer, callback: DeviceLogListener) { + text + .toString() + .split('\r\n') + .forEach(line => { + const regex = /(.*){(\S+)}\s*\[([\w :.\\]+)\](.*)/; + const match = regex.exec(line); + if (match && match.length === 5) { + callback({ + tid: 0, + pid: 0, + date: new Date(Date.parse(match[1])), + type: this.mapLogLevel(match[2]), + tag: match[3], + message: match[4], + }); + } else if (line.trim() === '') { + // skip + } else { + callback({ + tid: 0, + pid: 0, + date: new Date(), + type: 'verbose', + tag: 'failed-parse', + message: line, + }); + } + }); + } + + addLogListener = (callback: DeviceLogListener) => { + this.setupListener(callback); + }; + + async setupListener(callback: DeviceLogListener) { + const files = await fs.readdir(getLogsPath()); + this.watchedFile = files + .filter(file => file.startsWith('Service_')) + .sort() + .pop(); + this.watch(callback); + this.timer = setTimeout(() => this.checkForNewLog(callback), 5000); + } + + watch(callback: DeviceLogListener) { + const filePath = getLogsPath(this.watchedFile); + fs.watchFile(filePath, async (current, previous) => { + const readLen = current.size - previous.size; + const buffer = new Buffer(readLen); + const fd = await fs.open(filePath, 'r'); + await fs.read(fd, buffer, 0, readLen, previous.size); + this.processText(buffer, callback); + }); + } + + async checkForNewLog(callback: DeviceLogListener) { + const files = await fs.readdir(getLogsPath()); + const latestLog = files + .filter(file => file.startsWith('Service_')) + .sort() + .pop(); + if (this.watchedFile !== latestLog) { + const oldFilePath = getLogsPath(this.watchedFile); + fs.unwatchFile(oldFilePath); + this.watchedFile = latestLog; + this.watch(callback); + } + this.timer = setTimeout(() => this.checkForNewLog(callback), 5000); + } +} diff --git a/src/dispatcher/androidDevice.js b/src/dispatcher/androidDevice.js new file mode 100644 index 000000000..5a9cc0eee --- /dev/null +++ b/src/dispatcher/androidDevice.js @@ -0,0 +1,97 @@ +/** + * Copyright 2018-present Facebook. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * @format + */ + +import AndroidDevice from '../devices/AndroidDevice'; +import type {Store} from '../reducers/index.js'; +import type BaseDevice from '../devices/BaseDevice'; +const adb = require('adbkit-fb'); + +function createDecive(client, device): Promise { + return new Promise((resolve, reject) => { + const type = + device.type !== 'device' || device.id.startsWith('emulator') + ? 'emulator' + : 'physical'; + client.getProperties(device.id).then(props => { + const androidDevice = new AndroidDevice( + device.id, + type, + props['ro.product.model'], + client, + ); + androidDevice.reverse(); + resolve(androidDevice); + }); + }); +} + +export default (store: Store) => { + const client = adb.createClient(); + + client + .trackDevices() + .then(tracker => { + tracker.on('error', err => { + if (err.message === 'Connection closed') { + // adb server has shutdown, remove all android devices + const {devices} = store.getState(); + const deviceIDsToRemove: Array = devices + .filter((device: BaseDevice) => device instanceof AndroidDevice) + .map((device: BaseDevice) => device.serial); + + store.dispatch({ + type: 'UNREGISTER_DEVICES', + payload: new Set(deviceIDsToRemove), + }); + console.error( + 'adb server shutdown. Run `adb start-server` and restart Sonar.', + ); + } else { + throw err; + } + }); + + tracker.on('add', async device => { + const androidDevice = await createDecive(client, device); + if (device.type !== 'offline') { + store.dispatch({ + type: 'REGISTER_DEVICE', + payload: androidDevice, + }); + } + }); + + tracker.on('change', async device => { + if (device.type === 'offline') { + store.dispatch({ + type: 'UNREGISTER_DEVICES', + payload: new Set([device.id]), + }); + } else { + const androidDevice = await createDecive(client, device); + store.dispatch({ + type: 'REGISTER_DEVICE', + payload: androidDevice, + }); + } + }); + + tracker.on('remove', device => { + store.dispatch({ + type: 'UNREGISTER_DEVICES', + payload: new Set([device.id]), + }); + }); + }) + .catch(err => { + if (err.code === 'ECONNREFUSED') { + // adb server isn't running + } else { + throw err; + } + }); +}; diff --git a/src/dispatcher/application.js b/src/dispatcher/application.js new file mode 100644 index 000000000..0a4190347 --- /dev/null +++ b/src/dispatcher/application.js @@ -0,0 +1,25 @@ +/** + * Copyright 2018-present Facebook. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * @format + */ + +import {remote} from 'electron'; +import type {Store} from '../reducers/index.js'; + +export default (store: Store) => { + const currentWindow = remote.getCurrentWindow(); + currentWindow.on('focus', () => + store.dispatch({ + type: 'windowIsFocused', + payload: true, + }), + ); + currentWindow.on('blur', () => + store.dispatch({ + type: 'windowIsFocused', + payload: false, + }), + ); +}; diff --git a/src/dispatcher/iOSDevice.js b/src/dispatcher/iOSDevice.js new file mode 100644 index 000000000..74070c24e --- /dev/null +++ b/src/dispatcher/iOSDevice.js @@ -0,0 +1,99 @@ +/** + * Copyright 2018-present Facebook. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * @format + */ + +import type {ChildProcess} from 'child_process'; +import type {Store} from '../reducers/index.js'; +import child_process from 'child_process'; +import IOSDevice from '../devices/IOSDevice'; + +type iOSSimulatorDevice = {| + state: 'Booted' | 'Shutdown' | 'Shutting Down', + availability: string, + name: string, + udid: string, +|}; + +type IOSDeviceMap = {[id: string]: Array}; + +// start port forwarding server for real device connections +const portForwarder: ChildProcess = child_process.exec( + 'PortForwardingMacApp.app/Contents/MacOS/PortForwardingMacApp -portForward=8088 -multiplexChannelPort=8078', +); +window.addEventListener('beforeunload', () => { + portForwarder.kill(); +}); + +function querySimulatorDevices(): Promise { + return new Promise((resolve, reject) => { + child_process.execFile( + 'xcrun', + ['simctl', 'list', 'devices', '--json'], + {encoding: 'utf8'}, + (err, stdout) => { + if (err) { + console.error('Failed to load iOS devices', err); + return resolve({}); + } + + try { + const {devices} = JSON.parse(stdout.toString()); + resolve(devices); + } catch (err) { + console.error('Failed to parse iOS device list', err); + resolve({}); + } + }, + ); + }); +} + +export default (store: Store) => { + // monitoring iOS devices only available on MacOS. + if (process.platform !== 'darwin') { + return; + } + setInterval(() => { + const {devices} = store.getState(); + querySimulatorDevices().then((simulatorDevices: IOSDeviceMap) => { + const simulators: Array = Object.values( + simulatorDevices, + // $FlowFixMe + ).reduce((acc, cv) => acc.concat(cv), []); + + const currentDeviceIDs: Set = new Set( + devices + .filter(device => device instanceof IOSDevice) + .map(device => device.serial), + ); + + const deviceIDsToRemove = new Set(); + simulators.forEach((simulator: iOSSimulatorDevice) => { + const isRunning = + simulator.state === 'Booted' && + simulator.availability === '(available)'; + + if (isRunning && !currentDeviceIDs.has(simulator.udid)) { + // create device + store.dispatch({ + type: 'REGISTER_DEVICE', + payload: new IOSDevice(simulator.udid, 'emulator', simulator.name), + }); + } else if (!isRunning && currentDeviceIDs.has(simulator.udid)) { + deviceIDsToRemove.add(simulator.udid); + // delete device + } + }); + + if (deviceIDsToRemove.size > 0) { + store.dispatch({ + type: 'UNREGISTER_DEVICES', + payload: deviceIDsToRemove, + }); + } + }); + }, 3000); +}; diff --git a/src/dispatcher/index.js b/src/dispatcher/index.js new file mode 100644 index 000000000..dc22d6de5 --- /dev/null +++ b/src/dispatcher/index.js @@ -0,0 +1,14 @@ +/** + * Copyright 2018-present Facebook. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * @format + */ + +import androidDevice from './androidDevice'; +import iOSDevice from './iOSDevice'; +import application from './application'; +import type {Store} from '../reducers/index.js'; + +export default (store: Store) => + [application, androidDevice, iOSDevice].forEach(fn => fn(store)); diff --git a/src/fb-stubs/BugReporter.js b/src/fb-stubs/BugReporter.js new file mode 100644 index 000000000..ac7d2961c --- /dev/null +++ b/src/fb-stubs/BugReporter.js @@ -0,0 +1,15 @@ +/** + * Copyright 2018-present Facebook. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * @format + */ + +import LogManager from './Logger'; + +export default class BugReporter { + constructor(logManager: LogManager) {} + async report(title: string, body: string): Promise { + return Promise.resolve(-1); + } +} diff --git a/src/fb-stubs/ErrorReporter.js b/src/fb-stubs/ErrorReporter.js new file mode 100644 index 000000000..330a43aab --- /dev/null +++ b/src/fb-stubs/ErrorReporter.js @@ -0,0 +1,21 @@ +/** + * Copyright 2018-present Facebook. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * @format + */ + +export function cleanStack(stack: string, loc: ?string) {} +import type ScribeLogger from './ScribeLogger'; + +export type ObjectError = + | Error + | { + message: string, + stack?: string, + }; + +export default class ErrorReporter { + constructor(scribeLogger: ScribeLogger) {} + report(err: ObjectError) {} +} diff --git a/src/fb-stubs/GK.js b/src/fb-stubs/GK.js new file mode 100644 index 000000000..e41b6b81c --- /dev/null +++ b/src/fb-stubs/GK.js @@ -0,0 +1,16 @@ +/** + * Copyright 2018-present Facebook. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * @format + */ + +export type GKID = string; + +export default class GK { + static init() {} + + static get(id: GKID): boolean { + return false; + } +} diff --git a/src/fb-stubs/Logger.js b/src/fb-stubs/Logger.js new file mode 100644 index 000000000..a426239dc --- /dev/null +++ b/src/fb-stubs/Logger.js @@ -0,0 +1,40 @@ +/** + * Copyright 2018-present Facebook. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * @format + */ + +export type LogTypes = 'error' | 'warn' | 'info' | 'debug'; +export type TrackType = 'duration' | 'usage' | 'performance'; +import ScribeLogger from './ScribeLogger'; + +export default class LogManager { + constructor() { + this.scribeLogger = new ScribeLogger(this); + } + + scribeLogger: ScribeLogger; + + track(type: TrackType, event: string, data: ?any) {} + + trackTimeSince(mark: string, eventName: ?string) {} + + info(data: any, category: string) { + // eslint-disable-next-line + console.info(data, category); + } + + warn(data: any, category: string) { + console.warn(data, category); + } + + error(data: any, category: string) { + console.error(data, category); + } + + debug(data: any, category: string) { + // eslint-disable-next-line + console.debug(data, category); + } +} diff --git a/src/fb-stubs/ScribeLogger.js b/src/fb-stubs/ScribeLogger.js new file mode 100644 index 000000000..84b308388 --- /dev/null +++ b/src/fb-stubs/ScribeLogger.js @@ -0,0 +1,18 @@ +/** + * Copyright 2018-present Facebook. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * @format + */ + +export type ScribeMessage = {| + category: string, + message: string, +|}; + +import type Logger from './Logger.js'; + +export default class ScribeLogger { + constructor(logger: Logger) {} + send(message: ScribeMessage) {} +} diff --git a/src/fb-stubs/config.js b/src/fb-stubs/config.js new file mode 100644 index 000000000..3b1bd3181 --- /dev/null +++ b/src/fb-stubs/config.js @@ -0,0 +1,11 @@ +/** + * Copyright 2018-present Facebook. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * @format + */ + +export default { + updateServer: 'https://www.facebook.com/sonar/public/latest.json', + bugReportButtonVisible: false, +}; diff --git a/src/fb-stubs/constants.js b/src/fb-stubs/constants.js new file mode 100644 index 000000000..8e7d04fba --- /dev/null +++ b/src/fb-stubs/constants.js @@ -0,0 +1,19 @@ +/** + * Copyright 2018-present Facebook. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * @format + */ + +export const GRAPH_APP_ID = ''; +export const GRAPH_CLIENT_TOKEN = ''; +export const GRAPH_ACCESS_TOKEN = ''; + +// this provides elevated access to scribe. we really shouldn't be exposing this. +// need to investigate how to abstract the scribe logging so it's safe. +export const GRAPH_SECRET = ''; +export const GRAPH_SECRET_ACCESS_TOKEN = ''; + +// Provides access to Insights Validation ednpoint on interngraph +export const INSIGHT_INTERN_APP_ID = ''; +export const INSIGHT_INTERN_APP_TOKEN = ''; diff --git a/src/index.js b/src/index.js new file mode 100644 index 000000000..776db0f76 --- /dev/null +++ b/src/index.js @@ -0,0 +1,21 @@ +/** + * Copyright 2018-present Facebook. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * @format + */ + +export {default as styled} from './ui/styled/index.js'; +export * from './ui/index.js'; +export * from './utils/index.js'; + +export {default as GK} from './fb-stubs/GK.js'; +export {SonarBasePlugin, SonarPlugin, SonarDevicePlugin} from './plugin.js'; +export {createTablePlugin} from './createTablePlugin.js'; + +export * from './init.js'; +export {default} from './init.js'; + +export {default as AndroidDevice} from './devices/AndroidDevice.js'; +export {default as Device} from './devices/BaseDevice.js'; +export {default as IOSDevice} from './devices/IOSDevice.js'; diff --git a/src/init.js b/src/init.js new file mode 100644 index 000000000..97f52223b --- /dev/null +++ b/src/init.js @@ -0,0 +1,48 @@ +/** + * Copyright 2018-present Facebook. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * @format + */ + +import {Provider} from 'react-redux'; +import ReactDOM from 'react-dom'; +import {ContextMenuProvider} from 'sonar'; +import {precachedIcons} from './utils/icons.js'; +import GK from './fb-stubs/GK.js'; +import App from './App.js'; +import {createStore} from 'redux'; +import reducers from './reducers/index.js'; +import dispatcher from './dispatcher/index.js'; +const path = require('path'); + +const store = createStore( + reducers, + window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__(), +); + +dispatcher(store); + +GK.init(); + +const AppFrame = () => ( + + + + + +); + +// $FlowFixMe: this element exists! +ReactDOM.render(, document.getElementById('root')); +// $FlowFixMe: service workers exist! +navigator.serviceWorker + .register( + process.env.NODE_ENV === 'production' + ? path.join(__dirname, 'serviceWorker.js') + : './serviceWorker.js', + ) + .then(r => { + (r.installing || r.active).postMessage({precachedIcons}); + }) + .catch(console.error); diff --git a/src/plugin.js b/src/plugin.js new file mode 100644 index 000000000..f9d5be19e --- /dev/null +++ b/src/plugin.js @@ -0,0 +1,241 @@ +/** + * Copyright 2018-present Facebook. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * @format + */ + +import type {KeyboardActions} from './MenuBar.js'; +import type {App} from './App.js'; +import type {Client} from './server.js'; + +import BaseDevice from './devices/BaseDevice.js'; +import {AndroidDevice, IOSDevice} from 'sonar'; + +const invariant = require('invariant'); + +export type PluginClient = {| + send: (method: string, params?: Object) => void, + call: (method: string, params?: Object) => Promise, + subscribe: (method: string, callback: (params: any) => void) => void, +|}; + +type PluginTarget = BaseDevice | Client; + +/** + * This is a wrapper for a plugin instance and state. We have a special toJSON method that removes the plugin + * instance and any state if it's not set to be persisted. + */ +export class PluginStateContainer { + constructor(plugin: SonarBasePlugin<>, state: Object) { + this.plugin = plugin; + this.state = state; + } + + plugin: ?SonarBasePlugin<>; + state: Object; + + toJSON() { + return { + plugin: null, + state: this.plugin != null ? this.state : null, + }; + } +} + +export class SonarBasePlugin { + constructor() { + // $FlowFixMe: this is fine + this.state = {}; + } + + static title: string = 'Unknown'; + static id: string = 'Unknown'; + static icon: string = 'apps'; + static persist: boolean = true; + static keyboardActions: ?KeyboardActions; + static screenshot: ?string; + + // forbid instance properties that should be static + title: empty; + id: empty; + persist: empty; + + namespaceKey: string; + reducers: { + [actionName: string]: (state: State, actionData: Object) => $Shape, + } = {}; + app: App; + state: State; + renderSidebar: ?() => ?React.Element<*>; + renderIntro: ?() => ?React.Element<*>; + onKeyboardAction: ?(action: string) => void; + + toJSON() { + return null; + } + + // methods to be overriden by plugins + init(): void {} + teardown(): void {} + // methods to be overridden by subclasses + _init(): void {} + _teardown(): void {} + _setup(target: PluginTarget, app: App) { + this.app = app; + } + + setState( + state: $Shape | ((state: State) => $Shape), + callback?: () => void, + ) { + if (typeof state === 'function') { + state = state(this.state); + } + this.state = Object.assign({}, this.state, state); + + const pluginKey = this.constructor.id; + const namespaceKey = this.namespaceKey; + const appState = this.app.state; + + // update app state + this.app.setState( + { + plugins: { + ...appState.plugins, + [namespaceKey]: { + ...(appState.plugins[namespaceKey] || {}), + [pluginKey]: new PluginStateContainer(this, this.state), + }, + }, + }, + callback, + ); + } + + dispatchAction(actionData: Actions) { + // $FlowFixMe + const action = this.reducers[actionData.type]; + if (!action) { + // $FlowFixMe + throw new ReferenceError(`Unknown action ${actionData.type}`); + } + + if (typeof action === 'function') { + this.setState(action.call(this, this.state, actionData)); + } else { + // $FlowFixMe + throw new TypeError(`Reducer ${actionData.type} isn't a function`); + } + } + + render(): any { + return null; + } +} + +export class SonarDevicePlugin< + State: Object = any, + Actions = any, +> extends SonarBasePlugin { + device: BaseDevice; + + _setup(target: PluginTarget, app: App) { + invariant(target instanceof BaseDevice, 'expected instanceof Client'); + const device: BaseDevice = target; + + this.namespaceKey = device.serial; + this.device = device; + super._setup(device, app); + } + + _teardown() { + this.teardown(); + } + + _init() { + this.init(); + } +} + +export class SonarPlugin< + State: Object = any, + Actions = any, +> extends SonarBasePlugin { + constructor() { + super(); + this.subscriptions = []; + } + + subscriptions: Array<{ + method: string, + callback: Function, + }>; + + client: PluginClient; + realClient: Client; + + getDevice(): ?BaseDevice { + return this.realClient.getDevice(); + } + + getAndroidDevice(): AndroidDevice { + const device = this.getDevice(); + invariant( + device != null && device instanceof AndroidDevice, + 'expected android device', + ); + return device; + } + + getIOSDevice() { + const device = this.getDevice(); + invariant( + device != null && device instanceof IOSDevice, + 'expected ios device', + ); + return device; + } + + _setup(target: any, app: App) { + /* We have to type the above as `any` since if we import the actual Client we have an + unresolvable dependency cycle */ + + const realClient: Client = target; + const id: string = this.constructor.id; + + this.namespaceKey = realClient.id; + this.realClient = realClient; + this.client = { + call: (method, params) => realClient.call(id, method, params), + send: (method, params) => realClient.send(id, method, params), + subscribe: (method, callback) => { + this.subscriptions.push({ + method, + callback, + }); + realClient.subscribe(id, method, callback); + }, + }; + + super._setup(realClient, app); + } + + _teardown() { + // automatically unsubscribe subscriptions + for (const {method, callback} of this.subscriptions) { + this.realClient.unsubscribe(this.constructor.id, method, callback); + } + + // run plugin teardown + this.teardown(); + if (this.realClient.connected) { + this.realClient.rawSend('deinit', {plugin: this.constructor.id}); + } + } + + _init() { + this.realClient.rawSend('init', {plugin: this.constructor.id}); + this.init(); + } +} diff --git a/src/plugins/index.js b/src/plugins/index.js new file mode 100644 index 000000000..1c9c3b377 --- /dev/null +++ b/src/plugins/index.js @@ -0,0 +1,72 @@ +/** + * Copyright 2018-present Facebook. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * @format + */ + +import {GK} from 'sonar'; +import React from 'react'; +import ReactDOM from 'react-dom'; +import * as Sonar from 'sonar'; +import {SonarBasePlugin} from '../plugin.js'; + +const plugins = new Map(); + +// expose Sonar and exact globally for dynamically loaded plugins +window.React = React; +window.ReactDOM = ReactDOM; +window.Sonar = Sonar; + +const addIfNotAdded = plugin => { + if (!plugins.has(plugin.name)) { + plugins.set(plugin.name, plugin); + } +}; + +let disabledPlugins = []; +try { + disabledPlugins = + JSON.parse(window.process.env.CONFIG || '{}').disabledPlugins || []; +} catch (e) { + console.error(e); +} + +// Load dynamic plugins +try { + JSON.parse(window.process.env.PLUGINS || '[]').forEach(addIfNotAdded); +} catch (e) { + console.error(e); +} + +// DefaultPlugins that are included in the bundle. +// List of defaultPlugins is written at build time +let bundledPlugins = []; +try { + bundledPlugins = window.electronRequire('./defaultPlugins/index.json'); +} catch (e) {} +bundledPlugins + .map(plugin => ({ + ...plugin, + out: './' + plugin.out, + })) + .forEach(addIfNotAdded); + +export default Array.from(plugins.values()) + .map(plugin => { + if ( + (plugin.gatekeeper && !GK.get(plugin.gatekeeper)) || + disabledPlugins.indexOf(plugin.name) > -1 + ) { + return null; + } else { + try { + return window.electronRequire(plugin.out); + } catch (e) { + console.error(plugin, e); + return null; + } + } + }) + .filter(Boolean) + .filter(plugin => plugin.prototype instanceof SonarBasePlugin); diff --git a/src/plugins/layout/index.js b/src/plugins/layout/index.js new file mode 100644 index 000000000..65da5dd74 --- /dev/null +++ b/src/plugins/layout/index.js @@ -0,0 +1,576 @@ +/** + * Copyright 2018-present Facebook. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * @format + */ + +import type {ElementID, Element, ElementSearchResultSet} from 'sonar'; +import { + colors, + Glyph, + GK, + FlexRow, + FlexColumn, + Toolbar, + SonarPlugin, + ElementsInspector, + InspectorSidebar, + LoadingIndicator, + styled, + Component, + SearchBox, + SearchInput, + SearchIcon, +} from 'sonar'; + +// $FlowFixMe +import debounce from 'lodash.debounce'; + +export type InspectorState = {| + initialised: boolean, + selected: ?ElementID, + root: ?ElementID, + elements: {[key: ElementID]: Element}, + isSearchActive: boolean, + searchResults: ?ElementSearchResultSet, + outstandingSearchQuery: ?string, +|}; + +type SelectElementArgs = {| + key: ElementID, +|}; + +type ExpandElementArgs = {| + key: ElementID, + expand: boolean, +|}; + +type ExpandElementsArgs = {| + elements: Array, +|}; + +type UpdateElementsArgs = {| + elements: Array<$Shape>, +|}; + +type SetRootArgs = {| + root: ElementID, +|}; + +type GetNodesResult = {| + elements: Array, +|}; + +type SearchResultTree = {| + id: string, + isMatch: Boolean, + children: ?Array, + element: Element, +|}; + +const LoadingSpinner = LoadingIndicator.extends({ + marginRight: 4, + marginLeft: 3, + marginTop: -1, +}); + +const Center = FlexRow.extends({ + alignItems: 'center', + justifyContent: 'center', +}); + +const SearchIconContainer = styled.view({ + marginRight: 9, + marginTop: -3, + marginLeft: 4, +}); + +class LayoutSearchInput extends Component< + { + onSubmit: string => void, + }, + { + value: string, + }, +> { + static TextInput = styled.textInput({ + width: '100%', + marginLeft: 6, + }); + + state = { + value: '', + }; + + timer: TimeoutID; + + onChange = (e: SyntheticInputEvent<>) => { + clearTimeout(this.timer); + this.setState({ + value: e.target.value, + }); + this.timer = setTimeout(() => this.props.onSubmit(this.state.value), 200); + }; + + onKeyDown = (e: SyntheticKeyboardEvent<>) => { + if (e.key === 'Enter') { + this.props.onSubmit(this.state.value); + } + }; + + render() { + return ( + + ); + } +} + +export default class Layout extends SonarPlugin { + static title = 'Layout'; + static id = 'Inspector'; + static icon = 'target'; + + state = { + elements: {}, + initialised: false, + isSearchActive: false, + root: null, + selected: null, + searchResults: null, + outstandingSearchQuery: null, + }; + + reducers = { + SelectElement(state: InspectorState, {key}: SelectElementArgs) { + return { + selected: key, + }; + }, + + ExpandElement(state: InspectorState, {expand, key}: ExpandElementArgs) { + return { + elements: { + ...state.elements, + [key]: { + ...state.elements[key], + expanded: expand, + }, + }, + }; + }, + + ExpandElements(state: InspectorState, {elements}: ExpandElementsArgs) { + const expandedSet = new Set(elements); + const newState = { + elements: { + ...state.elements, + }, + }; + for (const key of Object.keys(state.elements)) { + newState.elements[key] = { + ...newState.elements[key], + expanded: expandedSet.has(key), + }; + } + return newState; + }, + + UpdateElements(state: InspectorState, {elements}: UpdateElementsArgs) { + const updatedElements = state.elements; + + for (const element of elements) { + const current = updatedElements[element.id] || {}; + // $FlowFixMe + updatedElements[element.id] = { + ...current, + ...element, + }; + } + + return {elements: updatedElements}; + }, + + SetRoot(state: InspectorState, {root}: SetRootArgs) { + return {root}; + }, + + SetSearchActive( + state: InspectorState, + {isSearchActive}: {isSearchActive: boolean}, + ) { + return {isSearchActive}; + }, + }; + + search(query: string) { + if (!query) { + return; + } + this.setState({ + outstandingSearchQuery: query, + }); + this.client + .call('getSearchResults', {query: query}) + .then(response => this.displaySearchResults(response)); + } + + executeCommand(command: string) { + return this.client.call('executeCommand', { + command: command, + context: this.state.selected, + }); + } + + /** + * When opening the inspector for the first time, expand all elements that contain only 1 child + * recursively. + */ + async performInitialExpand(element: Element): Promise { + if (!element.children.length) { + // element has no children so we're as deep as we can be + return; + } + + this.dispatchAction({expand: true, key: element.id, type: 'ExpandElement'}); + + return this.getChildren(element.id).then((elements: Array) => { + this.dispatchAction({elements, type: 'UpdateElements'}); + + if (element.children.length >= 2) { + // element has two or more children so we can stop expanding + return; + } + + return this.performInitialExpand( + this.state.elements[element.children[0]], + ); + }); + } + + displaySearchResults({ + results, + query, + }: { + results: SearchResultTree, + query: string, + }) { + const elements = this.getElementsFromSearchResultTree(results); + const idsToExpand = elements + .filter(x => x.hasChildren) + .map(x => x.element.id); + + const finishedSearching = query === this.state.outstandingSearchQuery; + + this.dispatchAction({ + elements: elements.map(x => x.element), + type: 'UpdateElements', + }); + this.dispatchAction({ + elements: idsToExpand, + type: 'ExpandElements', + }); + this.setState({ + searchResults: { + matches: new Set( + elements.filter(x => x.isMatch).map(x => x.element.id), + ), + query: query, + }, + outstandingSearchQuery: finishedSearching + ? null + : this.state.outstandingSearchQuery, + }); + } + + getElementsFromSearchResultTree(tree: SearchResultTree) { + if (!tree) { + return []; + } + var elements = [ + { + id: tree.id, + isMatch: tree.isMatch, + hasChildren: Boolean(tree.children), + element: tree.element, + }, + ]; + if (tree.children) { + for (const child of tree.children) { + elements = elements.concat(this.getElementsFromSearchResultTree(child)); + } + } + return elements; + } + + init() { + performance.mark('LayoutInspectorInitialize'); + this.client.call('getRoot').then((element: Element) => { + this.dispatchAction({elements: [element], type: 'UpdateElements'}); + this.dispatchAction({root: element.id, type: 'SetRoot'}); + this.performInitialExpand(element).then(() => { + this.app.logger.trackTimeSince('LayoutInspectorInitialize'); + this.setState({initialised: true}); + }); + }); + + this.client.subscribe( + 'invalidate', + ({nodes}: {nodes: Array<{id: ElementID}>}) => { + this.invalidate(nodes.map(node => node.id)).then( + (elements: Array) => { + this.dispatchAction({elements, type: 'UpdateElements'}); + }, + ); + }, + ); + + this.client.subscribe('select', ({path}: {path: Array}) => { + this.getNodesAndDirectChildren(path).then((elements: Array) => { + const selected = path[path.length - 1]; + + this.dispatchAction({elements, type: 'UpdateElements'}); + this.dispatchAction({key: selected, type: 'SelectElement'}); + this.dispatchAction({isSearchActive: false, type: 'SetSearchActive'}); + + for (const key of path) { + this.dispatchAction({expand: true, key, type: 'ExpandElement'}); + } + + this.client.send('setHighlighted', {id: selected}); + this.client.send('setSearchActive', {active: false}); + }); + }); + } + + invalidate(ids: Array): Promise> { + if (ids.length === 0) { + return Promise.resolve([]); + } + + return this.getNodes(ids, true).then((elements: Array) => { + const children = elements + .filter(element => { + const prev = this.state.elements[element.id]; + return prev && prev.expanded; + }) + .map(element => element.children) + .reduce((acc, val) => acc.concat(val), []); + + return Promise.all([elements, this.invalidate(children)]).then(arr => { + return arr.reduce((acc, val) => acc.concat(val), []); + }); + }); + } + + getNodesAndDirectChildren(ids: Array): Promise> { + return this.getNodes(ids, false).then((elements: Array) => { + const children = elements + .map(element => element.children) + .reduce((acc, val) => acc.concat(val), []); + + return Promise.all([elements, this.getNodes(children, false)]).then( + arr => { + return arr.reduce((acc, val) => acc.concat(val), []); + }, + ); + }); + } + + getChildren(key: ElementID): Promise> { + return this.getNodes(this.state.elements[key].children, false); + } + + getNodes( + ids: Array = [], + force: boolean, + ): Promise> { + if (!force) { + ids = ids.filter(id => { + return this.state.elements[id] === undefined; + }); + } + + if (ids.length > 0) { + performance.mark('LayoutInspectorGetNodes'); + return this.client + .call('getNodes', {ids}) + .then(({elements}: GetNodesResult) => { + this.app.logger.trackTimeSince('LayoutInspectorGetNodes'); + return Promise.resolve(elements); + }); + } else { + return Promise.resolve([]); + } + } + + isExpanded(key: ElementID): boolean { + return this.state.elements[key].expanded; + } + + expandElement = (key: ElementID): Promise> => { + const expand = !this.isExpanded(key); + return this.setElementExpanded(key, expand); + }; + + setElementExpanded = ( + key: ElementID, + expand: boolean, + ): Promise> => { + this.dispatchAction({expand, key, type: 'ExpandElement'}); + performance.mark('LayoutInspectorExpandElement'); + if (expand) { + return this.getChildren(key).then((elements: Array) => { + this.app.logger.trackTimeSince('LayoutInspectorExpandElement'); + this.dispatchAction({elements, type: 'UpdateElements'}); + return Promise.resolve(elements); + }); + } else { + return Promise.resolve([]); + } + }; + + deepExpandElement = async (key: ElementID) => { + const expand = !this.isExpanded(key); + if (!expand) { + // we never deep unexpand + return this.setElementExpanded(key, false); + } + + // queue of keys to open + const keys = [key]; + + // amount of elements we've expanded, we stop at 100 just to be safe + let count = 0; + + while (keys.length && count < 100) { + const key = keys.shift(); + + // expand current element + const children = await this.setElementExpanded(key, true); + + // and add it's children to the queue + for (const child of children) { + keys.push(child.id); + } + + count++; + } + }; + + onElementExpanded = (key: ElementID, deep: boolean) => { + if (deep) { + this.deepExpandElement(key); + } else { + this.expandElement(key); + } + this.app.logger.track('usage', 'layout:element-expanded', { + id: key, + deep: deep, + }); + }; + + onFindClick = () => { + const isSearchActive = !this.state.isSearchActive; + this.dispatchAction({isSearchActive, type: 'SetSearchActive'}); + this.client.send('setSearchActive', {active: isSearchActive}); + }; + + onElementSelected = debounce((key: ElementID) => { + this.dispatchAction({key, type: 'SelectElement'}); + this.client.send('setHighlighted', {id: key}); + this.getNodes([key], true).then((elements: Array) => { + this.dispatchAction({elements, type: 'UpdateElements'}); + }); + }); + + onElementHovered = debounce((key: ?ElementID) => { + this.client.send('setHighlighted', {id: key}); + }); + + onDataValueChanged = (path: Array, value: any) => { + this.client.send('setData', {id: this.state.selected, path, value}); + this.app.logger.track('usage', 'layout:value-changed', { + id: this.state.selected, + value: value, + path: path, + }); + }; + + renderSidebar = () => { + return this.state.selected != null ? ( + + ) : null; + }; + + render() { + const { + initialised, + selected, + root, + elements, + isSearchActive, + outstandingSearchQuery, + } = this.state; + + return ( + + + + + + {GK.get('sonar_layout_search') && ( + + + + {outstandingSearchQuery && } + + )} + + + {initialised ? ( + + ) : ( +
+ +
+ )} +
+
+ ); + } +} diff --git a/src/plugins/layout/package.json b/src/plugins/layout/package.json new file mode 100644 index 000000000..8f1b4378c --- /dev/null +++ b/src/plugins/layout/package.json @@ -0,0 +1,9 @@ +{ + "name": "sonar-plugin-layout", + "version": "1.0.0", + "main": "index.js", + "license": "MIT", + "dependencies": { + "lodash.debounce": "^4.0.8" + } +} diff --git a/src/plugins/layout/yarn.lock b/src/plugins/layout/yarn.lock new file mode 100644 index 000000000..d1a61d5bd --- /dev/null +++ b/src/plugins/layout/yarn.lock @@ -0,0 +1,7 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +lodash.debounce@^4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" diff --git a/src/plugins/network/RequestDetails.js b/src/plugins/network/RequestDetails.js new file mode 100644 index 000000000..736b71d92 --- /dev/null +++ b/src/plugins/network/RequestDetails.js @@ -0,0 +1,539 @@ +/** + * Copyright 2018-present Facebook. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * @format + */ + +// $FlowFixMe +import pako from 'pako'; +import type {Request, Response, Header} from './index.js'; + +import { + Component, + FlexColumn, + ManagedTable, + ManagedDataInspector, + Text, + Panel, + styled, + colors, +} from 'sonar'; +import {getHeaderValue} from './index.js'; + +import querystring from 'querystring'; + +const WrappingText = Text.extends({ + wordWrap: 'break-word', + width: '100%', + lineHeight: '125%', + padding: '3px 0', +}); + +const KeyValueColumnSizes = { + key: '30%', + value: 'flex', +}; + +const KeyValueColumns = { + key: { + value: 'Key', + resizable: false, + }, + value: { + value: 'Value', + resizable: false, + }, +}; + +type RequestDetailsProps = { + request: Request, + response: ?Response, +}; + +function decodeBody(container: Request | Response): string { + if (!container.data) { + return ''; + } + const b64Decoded = atob(container.data); + const encodingHeader = container.headers.find( + header => header.key === 'Content-Encoding', + ); + + return encodingHeader && encodingHeader.value === 'gzip' + ? decompress(b64Decoded) + : b64Decoded; +} + +function decompress(body: string): string { + const charArray = body.split('').map(x => x.charCodeAt(0)); + + const byteArray = new Uint8Array(charArray); + + let data; + try { + if (body) { + data = pako.inflate(byteArray); + } else { + return body; + } + } catch (e) { + // Sometimes Content-Encoding is 'gzip' but the body is already decompressed. + // Assume this is the case when decompression fails. + return body; + } + + return String.fromCharCode.apply(null, new Uint8Array(data)); +} + +export default class RequestDetails extends Component { + static Container = FlexColumn.extends({ + height: '100%', + overflow: 'auto', + }); + + urlColumns = (url: URL) => { + return [ + { + columns: { + key: {value: Full URL}, + value: { + value: {url.href}, + }, + }, + copyText: url.href, + key: 'url', + }, + { + columns: { + key: {value: Host}, + value: { + value: {url.host}, + }, + }, + copyText: url.host, + key: 'host', + }, + { + columns: { + key: {value: Path}, + value: { + value: {url.pathname}, + }, + }, + copyText: url.pathname, + key: 'path', + }, + { + columns: { + key: {value: Query String}, + value: { + value: {url.search}, + }, + }, + copyText: url.search, + key: 'query', + }, + ]; + }; + + render() { + const {request, response} = this.props; + const url = new URL(request.url); + + return ( + + + + + + {url.search ? ( + + + + ) : null} + + {request.headers.length > 0 ? ( + + + + ) : null} + + {request.data != null ? ( + + + + ) : null} + + {response + ? [ + response.headers.length > 0 ? ( + + + + ) : null, + + + , + ] + : null} + + ); + } +} + +class QueryInspector extends Component<{queryParams: URLSearchParams}> { + render() { + const {queryParams} = this.props; + + const rows = []; + for (const kv of queryParams.entries()) { + rows.push({ + columns: { + key: { + value: {kv[0]}, + }, + value: { + value: {kv[1]}, + }, + }, + copyText: kv[1], + key: kv[0], + }); + } + + return rows.length > 0 ? ( + + ) : null; + } +} + +type HeaderInspectorProps = { + headers: Array
, +}; + +type HeaderInspectorState = { + computedHeaders: Object, +}; + +class HeaderInspector extends Component< + HeaderInspectorProps, + HeaderInspectorState, +> { + render() { + const computedHeaders = this.props.headers.reduce((sum, header) => { + return {...sum, [header.key]: header.value}; + }, {}); + + const rows = []; + for (const key in computedHeaders) { + rows.push({ + columns: { + key: { + value: {key}, + }, + value: { + value: {computedHeaders[key]}, + }, + }, + copyText: computedHeaders[key], + key, + }); + } + + return rows.length > 0 ? ( + + ) : null; + } +} + +const BodyContainer = styled.view({ + paddingTop: 10, + paddingBottom: 20, +}); + +type BodyFormatter = { + formatRequest?: (request: Request) => any, + formatResponse?: (request: Request, response: Response) => any, +}; + +class RequestBodyInspector extends Component<{ + request: Request, +}> { + render() { + const {request} = this.props; + let component; + try { + for (const formatter of BodyFormatters) { + if (formatter.formatRequest) { + component = formatter.formatRequest(request); + if (component) { + break; + } + } + } + } catch (e) {} + + if (component == null && request.data != null) { + component = {decodeBody(request)}; + } + + if (component == null) { + return null; + } + + return {component}; + } +} + +class ResponseBodyInspector extends Component<{ + response: Response, + request: Request, +}> { + render() { + const {request, response} = this.props; + + let component; + try { + for (const formatter of BodyFormatters) { + if (formatter.formatResponse) { + component = formatter.formatResponse(request, response); + if (component) { + break; + } + } + } + } catch (e) {} + + component = component || {decodeBody(response)}; + + return {component}; + } +} + +const MediaContainer = FlexColumn.extends({ + alignItems: 'center', + justifyContent: 'center', + width: '100%', +}); + +type ImageWithSizeProps = { + src: string, +}; + +type ImageWithSizeState = { + width: number, + height: number, +}; + +class ImageWithSize extends Component { + static Image = styled.image({ + objectFit: 'scale-down', + maxWidth: 500, + maxHeight: 500, + marginBottom: 10, + }); + + static Text = Text.extends({ + color: colors.dark70, + fontSize: 14, + }); + + constructor(props, context) { + super(props, context); + this.state = { + width: 0, + height: 0, + }; + } + + componentDidMount() { + const image = new Image(); + image.src = this.props.src; + image.onload = () => { + image.width; + image.height; + this.setState({ + width: image.width, + height: image.height, + }); + }; + } + + render() { + return ( + + + + {this.state.width} x {this.state.height} + + + ); + } +} + +class ImageFormatter { + formatResponse = (request: Request, response: Response) => { + if (getHeaderValue(response.headers, 'content-type').startsWith('image')) { + return ; + } + }; +} + +class VideoFormatter { + static Video = styled.customHTMLTag('video', { + maxWidth: 500, + maxHeight: 500, + }); + + formatResponse = (request: Request, response: Response) => { + const contentType = getHeaderValue(response.headers, 'content-type'); + if (contentType.startsWith('video')) { + return ( + + + + + + ); + } + }; +} + +class JSONFormatter { + formatRequest = (request: Request) => { + return this.format( + decodeBody(request), + getHeaderValue(request.headers, 'content-type'), + ); + }; + + formatResponse = (request: Request, response: Response) => { + return this.format( + decodeBody(response), + getHeaderValue(response.headers, 'content-type'), + ); + }; + + format = (body: string, contentType: string) => { + if ( + contentType.startsWith('application/json') || + contentType.startsWith('text/javascript') || + contentType.startsWith('application/x-fb-flatbuffer') + ) { + try { + const data = JSON.parse(body); + return ( + + ); + } catch (SyntaxError) { + // Multiple top level JSON roots, map them one by one + const roots = body.split('\n'); + return ( + JSON.parse(json))} + /> + ); + } + } + }; +} + +class LogEventFormatter { + formatRequest = (request: Request) => { + if (request.url.indexOf('logging_client_event') > 0) { + const data = querystring.parse(decodeBody(request)); + if (data.message) { + data.message = JSON.parse(data.message); + } + return ; + } + }; +} + +class GraphQLBatchFormatter { + formatRequest = (request: Request) => { + if (request.url.indexOf('graphqlbatch') > 0) { + const data = querystring.parse(decodeBody(request)); + if (data.queries) { + data.queries = JSON.parse(data.queries); + } + return ; + } + }; +} + +class GraphQLFormatter { + formatRequest = (request: Request) => { + if (request.url.indexOf('graphql') > 0) { + const data = querystring.parse(decodeBody(request)); + if (data.variables) { + data.variables = JSON.parse(data.variables); + } + if (data.query_params) { + data.query_params = JSON.parse(data.query_params); + } + return ; + } + }; +} + +class FormUrlencodedFormatter { + formatRequest = (request: Request) => { + const contentType = getHeaderValue(request.headers, 'content-type'); + if (contentType.startsWith('application/x-www-form-urlencoded')) { + return ( + + ); + } + }; +} + +const BodyFormatters: Array = [ + new ImageFormatter(), + new VideoFormatter(), + new LogEventFormatter(), + new GraphQLBatchFormatter(), + new GraphQLFormatter(), + new JSONFormatter(), + new FormUrlencodedFormatter(), +]; diff --git a/src/plugins/network/index.js b/src/plugins/network/index.js new file mode 100644 index 000000000..316d41668 --- /dev/null +++ b/src/plugins/network/index.js @@ -0,0 +1,411 @@ +/** + * Copyright 2018-present Facebook. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * @format + */ + +import type {TableHighlightedRows, TableRows} from 'sonar'; + +import { + ContextMenu, + FlexColumn, + Button, + Text, + Glyph, + colors, + PureComponent, +} from 'sonar'; + +import {SonarPlugin, SearchableTable} from 'sonar'; +import RequestDetails from './RequestDetails.js'; + +import {URL} from 'url'; +// $FlowFixMe +import sortBy from 'lodash.sortby'; + +type RequestId = string; + +type State = {| + requests: {[id: RequestId]: Request}, + responses: {[id: RequestId]: Response}, + selectedIds: Array, +|}; + +export type Request = {| + id: RequestId, + timestamp: number, + method: string, + url: string, + headers: Array
, + data: ?string, +|}; + +export type Response = {| + id: RequestId, + timestamp: number, + status: number, + reason: string, + headers: Array
, + data: ?string, +|}; + +export type Header = {| + key: string, + value: string, +|}; + +const COLUMN_SIZE = { + domain: 'flex', + method: 100, + status: 70, + size: 100, + duration: 100, +}; + +const COLUMNS = { + domain: { + value: 'Domain', + }, + method: { + value: 'Method', + }, + status: { + value: 'Status', + }, + size: { + value: 'Size', + }, + duration: { + value: 'Duration', + }, +}; + +export function getHeaderValue(headers: Array
, key: string) { + for (const header of headers) { + if (header.key.toLowerCase() === key.toLowerCase()) { + return header.value; + } + } + return ''; +} + +export function formatBytes(count: number): string { + if (count > 1024 * 1024) { + return (count / (1024.0 * 1024)).toFixed(1) + ' MB'; + } + if (count > 1024) { + return (count / 1024.0).toFixed(1) + ' kB'; + } + return count + ' B'; +} + +const TextEllipsis = Text.extends({ + overflowX: 'hidden', + textOverflow: 'ellipsis', + maxWidth: '100%', + lineHeight: '18px', + paddingTop: 4, +}); + +export default class extends SonarPlugin { + static title = 'Network'; + static id = 'Network'; + static icon = 'internet'; + static keyboardActions = ['clear']; + + onKeyboardAction = (action: string) => { + if (action === 'clear') { + this.clearLogs(); + } + }; + + state = { + requests: {}, + responses: {}, + selectedIds: [], + }; + + init() { + this.client.subscribe('newRequest', (request: Request) => { + this.dispatchAction({request, type: 'NewRequest'}); + }); + this.client.subscribe('newResponse', (response: Response) => { + this.dispatchAction({response, type: 'NewResponse'}); + }); + } + + reducers = { + NewRequest(state: State, {request}: {request: Request}) { + return { + requests: {...state.requests, [request.id]: request}, + responses: state.responses, + }; + }, + + NewResponse(state: State, {response}: {response: Response}) { + return { + requests: state.requests, + responses: {...state.responses, [response.id]: response}, + }; + }, + + Clear(state: State) { + return { + requests: {}, + responses: {}, + }; + }, + }; + + onRowHighlighted = (selectedIds: Array) => + this.setState({selectedIds}); + + clearLogs = () => { + this.setState({selectedIds: []}); + this.dispatchAction({type: 'Clear'}); + }; + + renderSidebar = () => { + const {selectedIds, requests, responses} = this.state; + const selectedId = selectedIds.length === 1 ? selectedIds[0] : null; + + return selectedId != null ? ( + + ) : null; + }; + + render() { + return ( + + + + ); + } +} + +type NetworkTableProps = {| + requests: {[id: RequestId]: Request}, + responses: {[id: RequestId]: Response}, + clear: () => void, + onRowHighlighted: (keys: TableHighlightedRows) => void, +|}; + +type NetworkTableState = {| + sortedRows: TableRows, +|}; + +class NetworkTable extends PureComponent { + static ContextMenu = ContextMenu.extends({ + flex: 1, + }); + + state = { + sortedRows: [], + }; + + componentWillReceiveProps(nextProps: NetworkTableProps) { + if (Object.keys(nextProps.requests).length === 0) { + // cleared + this.setState({sortedRows: []}); + } else if (this.props.requests !== nextProps.requests) { + // new request + for (const requestId in nextProps.requests) { + if (this.props.requests[requestId] == null) { + this.buildRow(nextProps.requests[requestId], null); + break; + } + } + } else if (this.props.responses !== nextProps.responses) { + // new response + for (const responseId in nextProps.responses) { + if (this.props.responses[responseId] == null) { + this.buildRow( + nextProps.requests[responseId], + nextProps.responses[responseId], + ); + break; + } + } + } + } + + buildRow(request: Request, response: ?Response) { + if (request == null) { + return; + } + const url = new URL(request.url); + const domain = url.host + url.pathname; + const friendlyName = getHeaderValue(request.headers, 'X-FB-Friendly-Name'); + + const newRow = { + columns: { + domain: { + value: ( + {friendlyName ? friendlyName : domain} + ), + isFilterable: true, + }, + method: { + value: {request.method}, + isFilterable: true, + }, + status: { + value: ( + + {response ? response.status : undefined} + + ), + isFilterable: true, + }, + size: { + value: , + }, + duration: { + value: , + }, + }, + key: request.id, + filterValue: `${request.method} ${request.url}`, + sortKey: request.timestamp, + copyText: request.url, + highlightOnHover: true, + }; + + let rows; + if (response == null) { + rows = [...this.state.sortedRows, newRow]; + } else { + const index = this.state.sortedRows.findIndex(r => r.key === request.id); + if (index > -1) { + rows = [...this.state.sortedRows]; + rows[index] = newRow; + } + } + + this.setState({ + sortedRows: sortBy(rows, x => x.sortKey), + }); + } + + contextMenuItems = [ + { + type: 'separator', + }, + { + label: 'Clear all', + click: this.props.clear, + }, + ]; + + render() { + return ( + + Clear Table} + /> + + ); + } +} + +const Icon = Glyph.extends({ + marginTop: -3, + marginRight: 3, +}); + +class StatusColumn extends PureComponent<{ + children?: number, +}> { + render() { + const {children} = this.props; + let glyph; + + if (children != null && children >= 400 && children < 600) { + glyph = ; + } + + return ( + + {glyph} + {children} + + ); + } +} + +class DurationColumn extends PureComponent<{ + request: Request, + response: ?Response, +}> { + static Text = Text.extends({ + flex: 1, + textAlign: 'right', + paddingRight: 10, + }); + + render() { + const {request, response} = this.props; + const duration = response + ? response.timestamp - request.timestamp + : undefined; + return ( + + {duration != null ? duration.toLocaleString() + 'ms' : ''} + + ); + } +} + +class SizeColumn extends PureComponent<{ + response: ?Response, +}> { + static Text = Text.extends({ + flex: 1, + textAlign: 'right', + paddingRight: 10, + }); + + render() { + const {response} = this.props; + if (response) { + const text = formatBytes(this.getResponseLength(response)); + return {text}; + } else { + return null; + } + } + + getResponseLength(response) { + let length = 0; + const lengthString = response.headers + ? getHeaderValue(response.headers, 'content-length') + : undefined; + if (lengthString != null && lengthString != '') { + length = parseInt(lengthString, 10); + } else if (response.data) { + length = atob(response.data).length; + } + return length; + } +} diff --git a/src/plugins/network/package.json b/src/plugins/network/package.json new file mode 100644 index 000000000..eec4a9850 --- /dev/null +++ b/src/plugins/network/package.json @@ -0,0 +1,10 @@ +{ + "name": "sonar-plugin-network", + "version": "1.0.0", + "main": "index.js", + "license": "MIT", + "dependencies": { + "lodash.sortby": "^4.7.0", + "pako": "^1.0.6" + } +} diff --git a/src/plugins/network/yarn.lock b/src/plugins/network/yarn.lock new file mode 100644 index 000000000..3ff62dddc --- /dev/null +++ b/src/plugins/network/yarn.lock @@ -0,0 +1,11 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +lodash.sortby@^4.7.0: + version "4.7.0" + resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438" + +pako@^1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.6.tgz#0101211baa70c4bca4a0f63f2206e97b7dfaf258" diff --git a/src/reducers.js b/src/reducers.js new file mode 100644 index 000000000..9fa1df651 --- /dev/null +++ b/src/reducers.js @@ -0,0 +1,184 @@ +/** + * Copyright 2018-present Facebook. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * @format + */ + +import type { + App, + State, + StatePluginInfo, + StatePlugins, + StateClientPlugins, +} from './App.js'; +import type {SonarBasePlugin} from 'sonar'; +import {devicePlugins} from './device-plugins/index.js'; +import {SonarPlugin, SonarDevicePlugin} from 'sonar'; +import {PluginStateContainer} from './plugin.js'; +import BaseDevice from './devices/BaseDevice.js'; +import plugins from './plugins/index.js'; +import {Client} from './server.js'; + +const invariant = require('invariant'); + +type ActivatePluginAction = {| + appKey: string, + pluginKey: string, +|}; + +type TeardownClientAction = {| + appKey: string, +|}; + +export function ActivatePlugin( + app: App, + state: State, + {appKey, pluginKey}: ActivatePluginAction, +) { + const {activePluginKey, activeAppKey} = state; + + // get currently active plugin + const activeClientPlugins: ?StateClientPlugins = + activeAppKey != null ? state.plugins[activeAppKey] : null; + const activePluginInfo: ?StatePluginInfo = + activePluginKey != null && activeClientPlugins + ? activeClientPlugins[activePluginKey] + : null; + + // check if this plugin is already active + if ( + activePluginKey === pluginKey && + activeAppKey === appKey && + activePluginInfo && + activePluginInfo.plugin + ) { + // this is a noop + return state; + } + + // produce new plugins object + const newPluginsState: StatePlugins = { + ...state.plugins, + }; + + // check if the currently active plugin needs to be torn down after being deactivated + if ( + activeAppKey != null && + activePluginKey != null && + activePluginInfo && + activeClientPlugins + ) { + const activePlugin: ?SonarBasePlugin<> = activePluginInfo.plugin; + if (activePlugin && !activePlugin.constructor.persist) { + // teardown the currently active plugin + activePlugin._teardown(); + + // and remove it's plugin instance so next time it's made active it'll be reloaded + newPluginsState[activeAppKey] = { + ...activeClientPlugins, + [activePluginKey]: { + plugin: null, + state: activePluginInfo.state, + }, + }; + } + } + + // get the plugin state associated with the new client + const newClientPluginsState: StateClientPlugins = { + ...(newPluginsState[appKey] || {}), + }; + newPluginsState[appKey] = newClientPluginsState; + + // find the Plugin constructor with this key + let Plugin: Class>; + for (const FindPlugin of plugins) { + if (FindPlugin.id === pluginKey) { + Plugin = FindPlugin; + } + } + for (const FindPlugin of devicePlugins) { + if (FindPlugin.id === pluginKey) { + Plugin = FindPlugin; + } + } + invariant(Plugin, 'expected plugin'); + + // get target, this could be an app connection or a device + const clientInfo = state.server.connections.get(appKey); + let target: void | Client | BaseDevice; + if (clientInfo) { + target = clientInfo.client; + invariant( + // $FlowFixMe prototype not known + Plugin.prototype instanceof SonarPlugin, + 'expected plugin to be an app Plugin', + ); + } else { + target = app.props.devices.find( + (device: BaseDevice) => device.serial === appKey, + ); + invariant( + // $FlowFixMe prototype not known + Plugin.prototype instanceof SonarDevicePlugin, + 'expected plugin to be DevicePlugin', + ); + } + invariant(target, 'expected target'); + + // initialise the client if it hasn't alreadu been + const thisPluginState: ?StatePluginInfo = newClientPluginsState[pluginKey]; + if (!thisPluginState || !thisPluginState.plugin) { + const plugin = new Plugin(); + + // setup plugin, this is to avoid consumers having to pass args to super + plugin._setup(target, app); + + // if we already have state for this plugin then rehydrate it + if (thisPluginState && thisPluginState.state) { + plugin.state = thisPluginState.state; + } + + // init plugin - setup broadcasts, initial messages etc + plugin._init(); + + newClientPluginsState[pluginKey] = new PluginStateContainer( + plugin, + plugin.state, + ); + } + + return { + activeAppKey: appKey, + activePluginKey: pluginKey, + plugins: newPluginsState, + }; +} + +export function TeardownClient( + app: App, + state: State, + {appKey}: TeardownClientAction, +) { + const allPlugins: StatePlugins = {...state.plugins}; + + // teardown all plugins + const clientPlugins: StateClientPlugins = allPlugins[appKey]; + for (const pluginKey in clientPlugins) { + const {plugin} = clientPlugins[pluginKey]; + if (plugin) { + plugin._teardown(); + } + } + + // remove this client + delete allPlugins[appKey]; + + return { + activeAppKey: state.activeAppKey === appKey ? null : state.activeAppKey, + activePluginKey: + state.activeAppKey === appKey ? null : state.activePluginKey, + plugins: allPlugins, + }; +} diff --git a/src/reducers/application.js b/src/reducers/application.js new file mode 100644 index 000000000..357dccff4 --- /dev/null +++ b/src/reducers/application.js @@ -0,0 +1,88 @@ +/** + * Copyright 2018-present Facebook. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * @format + */ + +import {remote} from 'electron'; + +export type State = { + leftSidebarVisible: boolean, + rightSidebarVisible: boolean, + rightSidebarAvailable: boolean, + bugDialogVisible: boolean, + windowIsFocused: boolean, + pluginManagerVisible: boolean, +}; + +type ActionType = + | 'leftSidebarVisible' + | 'rightSidebarVisible' + | 'rightSidebarAvailable' + | 'bugDialogVisible' + | 'windowIsFocused' + | 'pluginManagerVisible'; + +export type Action = { + type: ActionType, + payload?: boolean, +}; + +const INITAL_STATE: State = { + leftSidebarVisible: true, + rightSidebarVisible: true, + rightSidebarAvailable: false, + bugDialogVisible: false, + windowIsFocused: remote.getCurrentWindow().isFocused(), + pluginManagerVisible: false, +}; + +export default function reducer( + state: State = INITAL_STATE, + action: Action, +): State { + const newValue = + typeof action.payload === 'undefined' + ? !state[action.type] + : action.payload; + if (state[action.type] === newValue) { + // value hasn't changed, do nothing + return state; + } else { + return { + ...state, + [action.type]: newValue, + }; + } +} + +export const toggleAction = (type: ActionType, payload?: boolean): Action => ({ + type, + payload, +}); + +export const toggleBugDialogVisible = (payload?: boolean): Action => ({ + type: 'bugDialogVisible', + payload, +}); + +export const toggleLeftSidebarVisible = (payload?: boolean): Action => ({ + type: 'leftSidebarVisible', + payload, +}); + +export const toggleRightSidebarVisible = (payload?: boolean): Action => ({ + type: 'rightSidebarVisible', + payload, +}); + +export const toggleRightSidebarAvailable = (payload?: boolean): Action => ({ + type: 'rightSidebarAvailable', + payload, +}); + +export const togglePluginManagerVisible = (payload?: boolean): Action => ({ + type: 'pluginManagerVisible', + payload, +}); diff --git a/src/reducers/devices.js b/src/reducers/devices.js new file mode 100644 index 000000000..17e2a8d05 --- /dev/null +++ b/src/reducers/devices.js @@ -0,0 +1,39 @@ +/** + * Copyright 2018-present Facebook. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * @format + */ + +import type BaseDevice from '../devices/BaseDevice'; +export type State = Array; + +export type Action = + | { + type: 'UNREGISTER_DEVICES', + payload: Set, + } + | { + type: 'REGISTER_DEVICE', + payload: BaseDevice, + }; + +const INITAL_STATE: State = []; + +export default function reducer( + state: State = INITAL_STATE, + action: Action, +): State { + switch (action.type) { + case 'REGISTER_DEVICE': { + const {payload} = action; + return state.concat(payload); + } + case 'UNREGISTER_DEVICES': { + const {payload} = action; + return state.filter((device: BaseDevice) => !payload.has(device.serial)); + } + default: + return state; + } +} diff --git a/src/reducers/index.js b/src/reducers/index.js new file mode 100644 index 000000000..de34adb89 --- /dev/null +++ b/src/reducers/index.js @@ -0,0 +1,29 @@ +/** + * Copyright 2018-present Facebook. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * @format + */ + +import {combineReducers} from 'redux'; +import application from './application.js'; +import devices from './devices.js'; +import type { + State as ApplicationState, + Action as ApplicationAction, +} from './application.js'; +import type { + State as DevicesState, + Action as DevicesAction, +} from './devices.js'; +import type {Store as ReduxStore} from 'redux'; + +export type Store = ReduxStore< + { + application: ApplicationState, + devices: DevicesState, + }, + ApplicationAction | DevicesAction, +>; + +export default combineReducers({application, devices}); diff --git a/src/server.js b/src/server.js new file mode 100644 index 000000000..664905b23 --- /dev/null +++ b/src/server.js @@ -0,0 +1,520 @@ +/** + * Copyright 2018-present Facebook. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * @format + */ + +import type BaseDevice from './devices/BaseDevice.js'; +import type {App} from './App.js'; +import type {SonarPlugin} from './plugin.js'; +import plugins from './plugins/index.js'; +import CertificateProvider from './utils/CertificateProvider'; +import type {SecureServerConfig} from './utils/CertificateProvider'; + +import {RSocketServer, ReactiveSocket, PartialResponder} from 'rsocket-core'; +import RSocketTCPServer from 'rsocket-tcp-server'; +const tls = require('tls'); +const net = require('net'); + +const EventEmitter = (require('events'): any); + +const invariant = require('invariant'); + +const SECURE_PORT = 8088; +const INSECURE_PORT = 8089; + +type RSocket = {| + fireAndForget(payload: {data: string}): void, + connectionStatus(): any, + close(): void, +|}; + +type ClientInfo = {| + connection: ?ReactiveSocket, + client: Client, +|}; + +type Plugins = Array; + +type ClientQuery = {| + app: string, + os: string, + device: string, + device_id: ?string, +|}; + +type RequestMetadata = {method: string, id: number, params: ?Object}; + +export class Client extends EventEmitter { + constructor(app: App, id: string, query: ClientQuery, conn: ReactiveSocket) { + super(); + + this.connected = true; + this.plugins = []; + this.connection = conn; + this.id = id; + this.query = query; + this.messageIdCounter = 0; + this.app = app; + + this.broadcastCallbacks = new Map(); + this.requestCallbacks = new Map(); + + const client = this; + this.responder = { + fireAndForget: (payload: {data: string}) => { + client.onMessage(payload.data); + }, + }; + + conn.connectionStatus().subscribe({ + onNext(payload) { + if (payload.kind == 'ERROR' || payload.kind == 'CLOSED') { + client.connected = false; + } + }, + onSubscribe(subscription) { + subscription.request(Number.MAX_SAFE_INTEGER); + }, + }); + } + + on: ((event: 'plugins-change', callback: () => void) => void) & + ((event: 'close', callback: () => void) => void); + + app: App; + connected: boolean; + id: string; + query: ClientQuery; + messageIdCounter: number; + plugins: Plugins; + connection: ReactiveSocket; + responder: PartialResponder; + + broadcastCallbacks: Map>>; + + requestCallbacks: Map< + number, + {| + resolve: (data: any) => void, + reject: (err: Error) => void, + metadata: RequestMetadata, + |}, + >; + + getDevice(): ?BaseDevice { + const {device_id} = this.query; + + if (device_id == null) { + return null; + } else { + return this.app.getDevice(device_id); + } + } + + supportsPlugin(Plugin: Class>): boolean { + return this.plugins.includes(Plugin.id); + } + + getFirstSupportedPlugin(): ?string { + for (const Plugin of plugins) { + if (this.supportsPlugin(Plugin)) { + return Plugin.id; + } + } + } + + async init() { + await this.getPlugins(); + } + + // get the supported plugins + async getPlugins(): Promise { + const plugins = await this.rawCall('getPlugins').then(data => data.plugins); + this.plugins = plugins; + return plugins; + } + + // get the plugins, and update the UI + async refreshPlugins() { + await this.getPlugins(); + this.emit('plugins-change'); + } + + onMessage(msg: string) { + if (typeof msg !== 'string') { + return; + } + + let rawData; + try { + rawData = JSON.parse(msg); + } catch (err) { + this.app.logger.error(`Invalid JSON: ${msg}`, 'clientMessage'); + return; + } + + const data: {| + id?: number, + method?: string, + params?: Object, + success?: Object, + error?: Object, + |} = rawData; + + this.app.logger.info(data, 'message:receive'); + + const {id, method} = data; + + if (id == null) { + const {error} = data; + if (error != null) { + this.app.logger.error(error.stacktrace || error.message, 'deviceError'); + this.app.errorReporter.report({ + message: error.message, + stack: error.stacktrace, + }); + } else if (method === 'refreshPlugins') { + this.refreshPlugins(); + } else if (method === 'execute') { + const params = data.params; + invariant(params, 'expected params'); + + const apiCallbacks = this.broadcastCallbacks.get(params.api); + if (!apiCallbacks) { + return; + } + + const methodCallbacks: ?Set = apiCallbacks.get(params.method); + if (methodCallbacks) { + for (const callback of methodCallbacks) { + callback(params.params); + } + } + } + return; + } + + const callbacks = this.requestCallbacks.get(id); + if (!callbacks) { + return; + } + this.requestCallbacks.delete(id); + this.finishTimingRequestResponse(callbacks.metadata); + + if (data.success) { + callbacks.resolve(data.success); + } else if (data.error) { + callbacks.reject(data.error); + } else { + // ??? + } + } + + toJSON() { + return null; + } + + subscribe( + api: ?string = null, + method: string, + callback: (params: Object) => void, + ) { + let apiCallbacks = this.broadcastCallbacks.get(api); + if (!apiCallbacks) { + apiCallbacks = new Map(); + this.broadcastCallbacks.set(api, apiCallbacks); + } + + let methodCallbacks = apiCallbacks.get(method); + if (!methodCallbacks) { + methodCallbacks = new Set(); + apiCallbacks.set(method, methodCallbacks); + } + methodCallbacks.add(callback); + } + + unsubscribe(api: ?string = null, method: string, callback: Function) { + const apiCallbacks = this.broadcastCallbacks.get(api); + if (!apiCallbacks) { + return; + } + + const methodCallbacks = apiCallbacks.get(method); + if (!methodCallbacks) { + return; + } + methodCallbacks.delete(callback); + } + + rawCall(method: string, params?: Object): Promise { + return new Promise((resolve, reject) => { + const id = this.messageIdCounter++; + const metadata: RequestMetadata = { + method, + id, + params, + }; + this.requestCallbacks.set(id, {reject, resolve, metadata}); + + const data = { + id, + method, + params, + }; + + this.app.logger.info(data, 'message:call'); + this.startTimingRequestResponse({method, id, params}); + this.connection.fireAndForget({data: JSON.stringify(data)}); + }); + } + + startTimingRequestResponse(data: RequestMetadata) { + performance.mark(this.getPerformanceMark(data)); + } + + finishTimingRequestResponse(data: RequestMetadata) { + const mark = this.getPerformanceMark(data); + const logEventName = this.getLogEventName(data); + this.app.logger.trackTimeSince(mark, logEventName); + } + + getPerformanceMark(data: RequestMetadata): string { + const {method, id} = data; + return `request_response_${method}_${id}`; + } + + getLogEventName(data: RequestMetadata): string { + const {method, params} = data; + return params && params.api && params.method + ? `request_response_${method}_${params.api}_${params.method}` + : `request_response_${method}`; + } + + rawSend(method: string, params?: Object): void { + const data = { + method, + params, + }; + this.app.logger.info(data, 'message:send'); + this.connection.fireAndForget({data: JSON.stringify(data)}); + } + + call(api: string, method: string, params?: Object): Promise { + return this.rawCall('execute', {api, method, params}); + } + + send(api: string, method: string, params?: Object): void { + return this.rawSend('execute', {api, method, params}); + } +} + +export class Server extends EventEmitter { + connections: Map; + secureServer: RSocketServer; + insecureServer: RSocketServer; + certificateProvider: CertificateProvider; + app: App; + + constructor(app: App) { + super(); + this.app = app; + this.connections = new Map(); + this.certificateProvider = new CertificateProvider(this, app.logger); + this.init(); + } + + on: ((event: 'new-client', callback: (client: Client) => void) => void) & + ((event: 'error', callback: (err: Error) => void) => void) & + ((event: 'clients-change', callback: () => void) => void); + + init() { + if (process.env.NODE_ENV === 'test') { + this.app.logger.warn( + "rsocket server has not been started as we're in test mode", + 'server', + ); + return; + } + + this.certificateProvider + .loadSecureServerConfig() + .then( + options => (this.secureServer = this.startServer(SECURE_PORT, options)), + ); + this.insecureServer = this.startServer(INSECURE_PORT); + } + + startServer(port: number, sslConfig?: SecureServerConfig) { + const server = this; + const serverFactory = onConnect => { + const transportServer = sslConfig + ? tls.createServer(sslConfig, socket => { + onConnect(socket); + }) + : net.createServer(onConnect); + transportServer + .on('error', err => { + server.emit('error', err); + server.app.logger.error( + `Error opening server on port ${port}`, + 'server', + ); + }) + .on('listening', () => { + server.app.logger.warn( + `${ + sslConfig ? 'Secure' : 'Certificate' + } server started on port ${port}`, + 'server', + ); + }); + return transportServer; + }; + const rsServer = new RSocketServer({ + getRequestHandler: sslConfig + ? this._trustedRequestHandler + : this._untrustedRequestHandler, + transport: new RSocketTCPServer({ + port: port, + serverFactory: serverFactory, + }), + }); + + rsServer.start(); + return rsServer; + } + + _trustedRequestHandler = (conn: RSocket, connectRequest: {data: string}) => { + const server = this; + + const client = this.addConnection(conn, connectRequest.data); + + conn.connectionStatus().subscribe({ + onNext(payload) { + if (payload.kind == 'ERROR' || payload.kind == 'CLOSED') { + server.app.logger.warn( + `Device disconnected ${client.id}`, + 'connection', + ); + server.removeConnection(client.id); + } + }, + onSubscribe(subscription) { + subscription.request(Number.MAX_SAFE_INTEGER); + }, + }); + + return client.responder; + }; + + _untrustedRequestHandler = ( + conn: RSocket, + connectRequest: {data: string}, + ) => { + const connectionParameters = JSON.parse(connectRequest.data); + + return { + fireAndForget: (payload: {data: string}) => { + if (typeof payload.data !== 'string') { + return; + } + + let rawData; + try { + rawData = JSON.parse(payload.data); + } catch (err) { + this.app.logger.error( + `Invalid JSON: ${payload.data}`, + 'clientMessage', + ); + return; + } + + const json: {| + method: 'signCertificate', + csr: string, + destination: string, + |} = rawData; + if (json.method === 'signCertificate') { + this.app.logger.warn('CSR received from device', 'server'); + const {csr, destination} = json; + this.certificateProvider.processCertificateSigningRequest( + csr, + connectionParameters.os, + destination + ); + } + }, + }; + }; + + close() { + this.secureServer.stop(); + this.insecureServer.stop(); + } + + toJSON() { + return null; + } + + addConnection(conn: ReactiveSocket, queryString: string): Client { + const query = JSON.parse(queryString); + invariant(query, 'expected query'); + + this.app.logger.warn(`Device connected: ${queryString}`, 'connection'); + + const id = `${query.app}-${query.os}-${query.device}`; + const client = new Client(this.app, id, query, conn); + + const info = { + client, + connection: conn, + }; + + client.init().then(() => { + this.app.logger.info( + `Device client initialised: ${id}. Supported plugins: ${client.plugins.join( + ', ', + )}`, + 'connection', + ); + + /* If a device gets disconnected without being cleaned up properly, + * sonar won't be aware until it attempts to reconnect. + * When it does we need to terminate the zombie connection. + */ + if (this.connections.has(id)) { + const connectionInfo = this.connections.get(id); + connectionInfo && + connectionInfo.connection && + connectionInfo.connection.close(); + this.removeConnection(id); + } + + this.connections.set(id, info); + this.emit('new-client', client); + this.emit('clients-change'); + client.emit('plugins-change'); + }); + + return client; + } + + attachFakeClient(client: Client) { + this.connections.set(client.id, { + client, + connection: null, + }); + } + + removeConnection(id: string) { + const info = this.connections.get(id); + if (info) { + info.client.emit('close'); + this.connections.delete(id); + this.emit('clients-change'); + } + } +} diff --git a/src/ui/components/Block.js b/src/ui/components/Block.js new file mode 100644 index 000000000..4c7eec6f9 --- /dev/null +++ b/src/ui/components/Block.js @@ -0,0 +1,12 @@ +/** + * Copyright 2018-present Facebook. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * @format + */ + +import styled from '../styled/index.js'; + +export default styled.view({ + display: 'block', +}); diff --git a/src/ui/components/Box.js b/src/ui/components/Box.js new file mode 100644 index 000000000..e0712484e --- /dev/null +++ b/src/ui/components/Box.js @@ -0,0 +1,15 @@ +/** + * Copyright 2018-present Facebook. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * @format + */ + +import FlexBox from './FlexBox.js'; + +export default FlexBox.extends({ + height: '100%', + overflow: 'auto', + position: 'relative', + width: '100%', +}); diff --git a/src/ui/components/Button.js b/src/ui/components/Button.js new file mode 100644 index 000000000..384d1b2e8 --- /dev/null +++ b/src/ui/components/Button.js @@ -0,0 +1,363 @@ +/** + * Copyright 2018-present Facebook. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * @format + */ + +import Glyph from './Glyph.js'; +import styled from '../styled/index.js'; +import type {StyledComponent} from '../styled/index.js'; +import {findDOMNode} from 'react-dom'; +import PropTypes from 'prop-types'; +import {colors} from './colors.js'; +import {connect} from 'react-redux'; +import electron from 'electron'; + +const borderColor = props => { + if (!props.windowIsFocused) { + return colors.macOSTitleBarButtonBorderBlur; + } else if (props.type === 'danger') { + return colors.red; + } else { + return colors.macOSTitleBarButtonBorder; + } +}; +const borderBottomColor = props => { + if (!props.windowIsFocused) { + return colors.macOSTitleBarButtonBorderBlur; + } else if (props.type === 'danger') { + return colors.red; + } else { + return colors.macOSTitleBarButtonBorderBottom; + } +}; + +const StyledButton = styled.view( + { + backgroundColor: props => { + if (!props.windowIsFocused) { + return colors.macOSTitleBarButtonBackgroundBlur; + } else { + return colors.white; + } + }, + backgroundImage: props => + props.windowIsFocused + ? `linear-gradient(to bottom, transparent 0%,${ + colors.macOSTitleBarButtonBackground + } 100%)` + : 'none', + borderStyle: 'solid', + borderWidth: 1, + borderColor, + borderBottomColor, + fontSize: props => (props.compact === true ? 11 : '1em'), + color: props => { + if (props.type === 'danger' && props.windowIsFocused) { + return colors.red; + } else if (props.disabled) { + return colors.macOSTitleBarIconBlur; + } else { + return colors.light50; + } + }, + borderRadius: 4, + position: 'relative', + padding: '0 6px', + height: props => (props.compact === true ? 24 : 28), + margin: 0, + marginLeft: props => (props.inButtonGroup === true ? 0 : 10), + minWidth: 34, + display: 'inline-flex', + alignItems: 'center', + justifyContent: 'center', + flexShrink: 0, + + boxShadow: props => + props.pulse && props.windowIsFocused + ? `0 0 0 ${colors.macOSTitleBarIconSelected}` + : '', + animation: props => + props.pulse && props.windowIsFocused ? 'pulse 1s infinite' : '', + + '&:not(:first-child)': { + borderTopLeftRadius: props => (props.inButtonGroup === true ? 0 : 4), + borderBottomLeftRadius: props => (props.inButtonGroup === true ? 0 : 4), + }, + + '&:not(:last-child)': { + borderTopRightRadius: props => (props.inButtonGroup === true ? 0 : 4), + borderBottomRightRadius: props => (props.inButtonGroup === true ? 0 : 4), + borderRight: props => (props.inButtonGroup === true ? 0 : ''), + }, + + '&:first-of-type': { + marginLeft: 0, + }, + + '&:active': { + borderColor: colors.macOSTitleBarButtonBorder, + borderBottomColor: colors.macOSTitleBarButtonBorderBottom, + background: `linear-gradient(to bottom, ${ + colors.macOSTitleBarButtonBackgroundActiveHighlight + } 1px, ${colors.macOSTitleBarButtonBackgroundActive} 0%, ${ + colors.macOSTitleBarButtonBorderBlur + } 100%)`, + }, + + '&:disabled': { + borderColor, + borderBottomColor, + pointerEvents: 'none', + }, + + '&:hover::before': { + content: props => (props.dropdown ? "''" : ''), + position: 'absolute', + bottom: 1, + right: 2, + borderStyle: 'solid', + borderWidth: '4px 3px 0 3px', + borderColor: props => + `${colors.macOSTitleBarIcon} transparent transparent transparent`, + }, + }, + { + ignoreAttributes: [ + 'dispatch', + 'compact', + 'large', + 'windowIsFocused', + 'inButtonGroup', + 'danger', + 'pulse', + ], + }, +); + +const Icon = Glyph.extends( + { + marginRight: props => (props.hasText ? 3 : 0), + }, + { + ignoreAttributes: ['hasText', 'type'], + }, +); + +type Props = { + /** + * onClick handler. + */ + onClick?: (event: SyntheticMouseEvent<>) => void, + /** + * Whether this button is disabled. + */ + disabled?: boolean, + /** + * Whether this button is large. Increases padding and line-height. + */ + large?: boolean, + /** + * Whether this button is compact. Decreases padding and line-height. + */ + compact?: boolean, + /** + * Type of button. + */ + type?: 'primary' | 'success' | 'warning' | 'danger', + /** + * Children. + */ + children?: React$Node, + /** + * Dropdown menu template shown on click. + */ + dropdown?: Array, + /** + * Name of the icon dispalyed next to the text + */ + icon?: string, + iconSize?: number, + /** + * For toggle buttons, if the button is selected + */ + selected?: boolean, + /** + * Button is pulsing + */ + pulse?: boolean, + /** + * URL to open in the browser on click + */ + href?: string, +}; + +type State = { + active: boolean, +}; + +/** + * Simple button. + * + * **Usage** + * + * ```jsx + * import {Button} from 'sonar'; + * + * ``` + * + * @example Default button + * + * @example Primary button + * + * @example Success button + * + * @example Warning button + * + * @example Danger button + * + * @example Default solid button + * + * @example Primary solid button + * + * @example Success solid button + * + * @example Warning solid button + * + * @example Danger solid button + * + * @example Compact button + * + * @example Large button + * + * @example Disabled button + * + */ +class Button extends styled.StylableComponent< + Props & {windowIsFocused: boolean}, + State, +> { + static contextTypes = { + inButtonGroup: PropTypes.bool, + }; + + state = { + active: false, + }; + + _ref: ?Element | ?Text; + + onMouseDown = () => this.setState({active: true}); + onMouseUp = () => this.setState({active: false}); + + onClick = (e: SyntheticMouseEvent<>) => { + if (this.props.disabled === true) { + return; + } + if (this.props.dropdown) { + const menu = electron.remote.Menu.buildFromTemplate(this.props.dropdown); + const position = {}; + if (this._ref != null && this._ref instanceof Element) { + const {left, bottom} = this._ref.getBoundingClientRect(); + position.x = parseInt(left, 10); + position.y = parseInt(bottom + 6, 10); + } + menu.popup(electron.remote.getCurrentWindow(), { + async: true, + ...position, + }); + } + if (this.props.onClick) { + this.props.onClick(e); + } + if (this.props.href != null) { + electron.shell.openExternal(this.props.href); + } + }; + + setRef = (ref: ?React.ElementRef) => { + this._ref = findDOMNode(ref); + }; + + render() { + const { + icon, + children, + selected, + iconSize, + windowIsFocused, + ...props + } = this.props; + const {active} = this.state; + + let color = colors.macOSTitleBarIcon; + if (props.disabled === true) { + color = colors.macOSTitleBarIconBlur; + } else if (windowIsFocused && selected === true) { + color = colors.macOSTitleBarIconSelected; + } else if (!windowIsFocused && (selected == null || selected === false)) { + color = colors.macOSTitleBarIconBlur; + } else if (!windowIsFocused && selected === true) { + color = colors.macOSTitleBarIconSelectedBlur; + } else if (selected == null && active) { + color = colors.macOSTitleBarIconActive; + } else if (props.type === 'danger') { + color = colors.red; + } + + let iconComponent; + if (icon != null) { + iconComponent = ( + + ); + } + + return ( + + {iconComponent} + {children} + {this.props.pulse === true && ( + \ No newline at end of file diff --git a/static/icons/componentkit-logo.png b/static/icons/componentkit-logo.png new file mode 100644 index 0000000000000000000000000000000000000000..3b675db662d43839ea46e0c340fe208b669ffaef GIT binary patch literal 4436 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 literal 0 HcmV?d00001 diff --git a/static/icons/componentscript-logo.png b/static/icons/componentscript-logo.png new file mode 100755 index 0000000000000000000000000000000000000000..49cd42c5c4c41f9258180fd02ae3ae6bfaa8ba3c GIT binary patch literal 7062 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 Ab^rhX literal 0 HcmV?d00001 diff --git a/static/icons/ios.svg b/static/icons/ios.svg new file mode 100644 index 000000000..8635d3a3e --- /dev/null +++ b/static/icons/ios.svg @@ -0,0 +1,9 @@ + \ No newline at end of file diff --git a/static/icons/litho-logo.png b/static/icons/litho-logo.png new file mode 100644 index 0000000000000000000000000000000000000000..16ac3a2ef41d081b07fb9837ba60de54d9df2331 GIT binary patch literal 812 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=Ea{HEjtmSN`?>!lvNA9*J@#~Q z45?sz8+|bEvV*|f!XT}S_X7BJ>nC{Uw+4Nbwq^X==$5tgp2MQ4586Up_A~7GY9284 zK(F^dhN6zD)e{vqwo6|2Sh-cq>*ie9DO*#P-n009Z%<`*xUm^izCB<3UHy8|^8%T% zeWvD2Klb%))}t?oPI=&-*#=x7laQ=?y7%E+3pW%$mNSUV4*a-D8mhtKY`1NmZ1% zd51|tak-;1=YoZsQhS~-oW6PS!8947IATW`wfn8zS7-0A*?oG3+kw)awnZ5?iY(u~ z6Z3KT_G0#J#-Lr#UgegQaj_WOx33EqDt#Rhv-j_zqZjK!Pp+^3xnEwGXQ$%tz^aMw zR1Yx5U4Og%&6WJWtIq8`vG~t}ugj`Ae;nOpd3%1_n>e++pG z81GFUy%@W!J-oa8zL~l`f37RR6J`GFbxGIj{{s0u)z%pm=M=k`KlwMChb#ZG1o~%t z!t)s#T@1w^xa+cn6m}dr#yE+&M_t2W?~{fHLelIWdw&+f7C91qp$xw zB8n+kHpKoh$AQ0T;TcyFGp=;vHvp0fH( h@rQE%_?q9m_x_%`aii8y5SaWKJYD@<);T3K0RZhHc^Uu! literal 0 HcmV?d00001 diff --git a/static/icons/oculus.png b/static/icons/oculus.png new file mode 100644 index 0000000000000000000000000000000000000000..4ae24d938a7a15c5ccfa4013e30403842d94181d GIT binary patch literal 1818 zcmchY`Ck$S0L8%yGqsiCfhI0BMZ`Qv$Taf^&phxxS;k~h*-Ar2)I2_A9?PSdXyQDw zz`XIIQt`%xFbOqu#xk?K70FVku6;iH8}`F{-}l@5?Y#^y4=2S#8ixP?fTD}@dGBw` z{Z|J;-~6NFbo(~|qrIK%0d>4%a{vHH=yKl9Hx9T|@+t@H2OhxsdiBZnebvK)-F>~# z>dM-3W;fp%nZZL;P^o_nbm(7K%*as>$o!p0(@WiwrPqLkeP8d%VeO7-bN(`-iwkcV zSoBIwUz0p;KAVrt|GE0f^Mwt|uIR0e+K@I%w~T_!kz~OB?*YJrwt)XHrkKfy!*H5Uq zX%6>)&XTq?drnxrSssb;?zy5ASiX*Sdr@_+YA;@A@VQ&mA|ZJ=Et%5);xSEN#xTJk z;U37i5c3D9#7ms1*~ku@M4kxdc50&^r9bj?+pLev3jN!5o|3|~NMf2Z-%egS8iy@5 zI$eq`C=eBen+yl|bV|x#^Jbuu^ppf%v4u^oQaol8VpiQFK{Rapcn_ z2qr+Wcqa}@_|s*wf)1k+)TyMWi$F~8pg*$zJ(>~ph-|Rvi0Mvdv8Ev#62kS3S`;6f zps$#AX%ZpN^rRU`1nCzhpA4)FB>*Q%3)lzZrJ=;}8a`aw9r8i#tOrD)Bx_8RE}_c6 z(^8^G;OkoW%%=#DVeA@mtgzkP#42#KI)9~;`2)P~s$N%PF9L5!SF^!dhZ`Qc%CWq8 z-QKt|8FeS#8K1YmCt7*uXsi85l2HVB7M5GO@YQ(>cjkMog55l8&5(TZ?=!dNF3jo7 zDG_UhGu{d&(_NtxCMrZv&NF=w|J)p@G(WTEhzeau4VfgN}2_Mj!+5FLs)E+)pX`!ev2Y$CZ@~sPYah z!jx2Jk7$y8j_Rv?uPG{b=+eI3zV4*2QjX_0)P#;oK1b7NYu8zfhXG4AqH{WV-9i?e z*ZII{q^5~zDulXcS|I}R4$P1&Au(MV9q`I` zJ(Dkkcc%(x-ao}IIjVY5eO{-otAA1?zH5FTwmaU~X-EbJ-;L-HUEPdNQ*lC=K#kmq-Ew)?FeqgeWBCt!4!*pGpJ%%zkpd7o;#Lg8Tt*rCH?ZR4ZoM@89* zw_TQ7x9U{Kd$c5%bAIivnV8*})~P=|GkVMKC*+sdg%*@^Bu*_-jCNgdEvl)Gv~mhp zohqOi^AjphF5+Gt)BT(()z*vUJ5}NL5q+}B7q8Jygu%%9r||h+!}m||_u^vqIGmrr zt86z(dGOj|VQ()>uH_Sy!wWNr2ot1(#JvMAf3=V**+fAvQ@^wN`gT>jwg1Qs5Bn?w zr1@TR@!;`eO0D?1Xjs2hHEWSj0Z0 zdl3TBs8OHmvkj|gK<5P&6YH-vR(#+k?%+5I!%b~5Z8~2xbZi8(gKRGMurko3DL(j& z4%V58G}UFABd=)y>je}$Nn5DlV}=5EhCGzrpnPOi@Wx$$W31efW~f`AERsWkQjAEv z2ZC*HZG9cBO10aO1^%v>klCpF+3b#Z_JJ11U}MN?6j5|>p-MN2=XIaIZD8c_rF1us z{%&mhVPW6}U+FI!iH6J2@$IC;p#OK||7){tll%KSkYDFUVax%oZ)XQ^!FZgnv%i@7 E4>qPJPyhe` literal 0 HcmV?d00001 diff --git a/static/icons/sidebar_bottom.svg b/static/icons/sidebar_bottom.svg new file mode 100644 index 000000000..8dec72ea8 --- /dev/null +++ b/static/icons/sidebar_bottom.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/static/icons/sidebar_left.svg b/static/icons/sidebar_left.svg new file mode 100644 index 000000000..89eb13ed5 --- /dev/null +++ b/static/icons/sidebar_left.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/static/icons/sidebar_right.svg b/static/icons/sidebar_right.svg new file mode 100644 index 000000000..a24c3734f --- /dev/null +++ b/static/icons/sidebar_right.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/static/index.dev.html b/static/index.dev.html new file mode 100644 index 000000000..4d3c64525 --- /dev/null +++ b/static/index.dev.html @@ -0,0 +1,110 @@ + + + + + + + + + Sonar + + + + +

+ +
+
Loading...
+
+ + + + + + + diff --git a/static/index.html b/static/index.html new file mode 100644 index 000000000..a2e80969a --- /dev/null +++ b/static/index.html @@ -0,0 +1,18 @@ + + + + + + + + + Sonar + + +
+ + + + diff --git a/static/index.js b/static/index.js new file mode 100644 index 000000000..0c33d8c5e --- /dev/null +++ b/static/index.js @@ -0,0 +1,156 @@ +/** + * Copyright 2018-present Facebook. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * @format + */ +const {app, BrowserWindow} = require('electron'); +const path = require('path'); +const url = require('url'); +const fs = require('fs'); +const yargs = require('yargs'); +const compilePlugins = require('./compilePlugins.js'); + +// ensure .sonar folder and config exist +const sonarDir = path.join(require('os').homedir(), '.sonar'); +if (!fs.existsSync(sonarDir)) { + fs.mkdirSync(sonarDir); +} + +const configPath = path.join(sonarDir, 'config.json'); +let config = {pluginPaths: [], disabledPlugins: [], lastWindowPosition: {}}; + +try { + config = { + ...config, + ...JSON.parse(fs.readFileSync(configPath)), + }; +} catch (e) { + fs.writeFileSync(configPath, JSON.stringify(config)); +} + +const pluginPaths = config.pluginPaths.concat( + (yargs.argv.dynamicPlugins || '').split(',').filter(Boolean), +); + +process.env.CONFIG = JSON.stringify({ + ...config, + pluginPaths, +}); + +// possible reference to main app window +let win; +let appReady = false; +let pluginsCompiled = false; + +// tracking +setInterval(() => { + if (win && win.isFocused()) { + win.webContents.send('trackUsage'); + } +}, 60 * 1000); + +compilePlugins( + () => { + if (win) { + win.reload(); + } + }, + pluginPaths, + path.join(require('os').homedir(), '.sonar', 'plugins'), +).then(dynamicPlugins => { + process.env.PLUGINS = JSON.stringify(dynamicPlugins); + pluginsCompiled = true; + tryCreateWindow(); +}); + +// check if we already have an instance of this app open +const isSecondInstance = app.makeSingleInstance( + (commandLine, workingDirectory) => { + // someone tried to run a second instance, we should focus our window + if (win) { + if (win.isMinimized()) { + win.restore(); + } + + win.focus(); + } + }, +); + +// if this is a second instance then quit the app to prevent collisions +if (isSecondInstance) { + app.quit(); +} + +// quit app once all windows are closed +app.on('window-all-closed', () => { + appReady = false; + app.quit(); +}); + +app.on('ready', function() { + appReady = true; + app.commandLine.appendSwitch('scroll-bounce'); + tryCreateWindow(); + // if in development install the react devtools extension + if (process.env.NODE_ENV === 'development') { + const { + default: installExtension, + REACT_DEVELOPER_TOOLS, + REDUX_DEVTOOLS, + } = require('electron-devtools-installer'); + installExtension(REACT_DEVELOPER_TOOLS.id); + installExtension(REDUX_DEVTOOLS.id); + } +}); +function tryCreateWindow() { + if (appReady && pluginsCompiled) { + win = new BrowserWindow({ + show: false, + title: 'Sonar', + width: config.lastWindowPosition.width || 1400, + height: config.lastWindowPosition.height || 1000, + minWidth: 800, + minHeight: 600, + center: true, + fullscreenable: false, + backgroundThrottling: false, + titleBarStyle: 'hiddenInset', + webPreferences: { + webSecurity: false, + scrollBounce: true, + experimentalFeatures: true, + }, + }); + win.once('ready-to-show', () => win.show()); + win.once('close', ({sender}) => { + const [x, y] = sender.getPosition(); + const [width, height] = sender.getSize(); + // save window position and size + fs.writeFileSync( + configPath, + JSON.stringify({ + ...config, + lastWindowPosition: { + x, + y, + width, + height, + }, + }), + ); + }); + if (config.lastWindowPosition.x && config.lastWindowPosition.y) { + win.setPosition(config.lastWindowPosition.x, config.lastWindowPosition.y); + } + const entryUrl = + process.env.ELECTRON_URL || + url.format({ + pathname: path.join(__dirname, 'index.html'), + protocol: 'file:', + slashes: true, + }); + win.loadURL(entryUrl); + } +} diff --git a/static/package.json b/static/package.json new file mode 100644 index 000000000..77c68eaf0 --- /dev/null +++ b/static/package.json @@ -0,0 +1,17 @@ +{ + "name": "sonar-static", + "version": "1.0.0", + "main": "index.js", + "license": "MIT", + "dependencies": { + "@babel/core": "^7.0.0-beta.40", + "@babel/generator": "^7.0.0-beta.40", + "babel-plugin-transform-class-properties": "^7.0.0-beta.3", + "babel-plugin-transform-es2015-modules-commonjs": "^7.0.0-beta.3", + "babel-plugin-transform-flow-strip-types": "^7.0.0-beta.3", + "babel-plugin-transform-object-rest-spread": "^7.0.0-beta.3", + "babel-preset-react": "^7.0.0-beta.3", + "babylon": "^7.0.0-beta.40", + "metro": "^0.28.0" + } +} diff --git a/static/pattern.gif b/static/pattern.gif new file mode 100644 index 0000000000000000000000000000000000000000..ea19bf64cd08fb2f01c4289f3bcc05c59fdbf30b GIT binary patch literal 4822 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 { + if (e.data.precachedIcons) { + caches.open(CACHE_NAME).then(cache => cache.addAll(e.data.precachedIcons)); + } +}); + +self.addEventListener('fetch', function(event) { + if (event.request.url.startsWith('https://external.xx.fbcdn.net/assets/')) { + event.respondWith( + // Cache falling back to the network + caches.match(event.request).then(cacheResponse => { + return ( + cacheResponse || + fetch(event.request).then(response => { + const clone = response.clone(); + // write to cache + caches + .open(CACHE_NAME) + .then(cache => cache.put(event.request, clone)); + return response; + }) + ); + }), + ); + } +}); diff --git a/static/style.css b/static/style.css new file mode 100644 index 000000000..57a1ce4d6 --- /dev/null +++ b/static/style.css @@ -0,0 +1,158 @@ +/* http://meyerweb.com/eric/tools/css/reset/ + v2.0 | 20110126 + License: none (public domain) +*/ + +html, +body, +div, +span, +applet, +object, +iframe, +h1, +h2, +h3, +h4, +h5, +h6, +p, +blockquote, +pre, +a, +abbr, +acronym, +address, +big, +cite, +code, +del, +dfn, +em, +img, +ins, +kbd, +q, +s, +samp, +small, +strike, +strong, +sub, +sup, +tt, +var, +b, +u, +i, +center, +dl, +dt, +dd, +ol, +ul, +li, +fieldset, +form, +label, +legend, +table, +caption, +tbody, +tfoot, +thead, +tr, +th, +td, +article, +aside, +canvas, +details, +embed, +figure, +figcaption, +footer, +header, +hgroup, +menu, +nav, +output, +ruby, +section, +summary, +time, +mark, +audio, +video { + margin: 0; + padding: 0; + border: 0; + font-size: 100%; + font: inherit; + vertical-align: baseline; +} +/* HTML5 display-role reset for older browsers */ +article, +aside, +details, +figcaption, +figure, +footer, +header, +hgroup, +menu, +nav, +section { + display: block; +} +body { + line-height: 1; +} +ol, +ul { + list-style: none; +} +blockquote, +q { + quotes: none; +} +blockquote:before, +blockquote:after, +q:before, +q:after { + content: ''; + content: none; +} +table { + border-collapse: collapse; + border-spacing: 0; +} +*:active, +*:focus { + outline: none; +} +/**/ + +html, +body, +#root { + height: 100%; + width: 100%; +} + +body { + font-family: system-ui; + font-size: 13px; + user-select: none; + -webkit-user-select: none; + cursor: default; + overflow: hidden; +} + +* { + box-sizing: border-box; +} + +#root { + overflow: hidden; +} diff --git a/static/transforms/dynamic-requires.js b/static/transforms/dynamic-requires.js new file mode 100644 index 000000000..c78f54379 --- /dev/null +++ b/static/transforms/dynamic-requires.js @@ -0,0 +1,31 @@ +/** + * Copyright 2018-present Facebook. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * @format + */ +function isDynamicRequire(node) { + return ( + node.type === 'CallExpression' && + node.callee.type === 'Identifier' && + node.callee.name === 'require' && + (node.arguments.length !== 1 || node.arguments[0].type !== 'StringLiteral') + ); +} + +module.exports = function(babel) { + const t = babel.types; + + return { + name: 'replace-dynamic-requires', + visitor: { + CallExpression(path) { + if (!isDynamicRequire(path.node)) { + return; + } + + path.replaceWith(t.identifier('triggerDynamicRequireError')); + }, + }, + }; +}; diff --git a/static/transforms/electron-requires.js b/static/transforms/electron-requires.js new file mode 100644 index 000000000..26a12ebdb --- /dev/null +++ b/static/transforms/electron-requires.js @@ -0,0 +1,87 @@ +/** + * Copyright 2018-present Facebook. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * @format + */ + +const BUILTINS = [ + 'electron', + 'buffer', + 'child_process', + 'crypto', + 'dgram', + 'dns', + 'fs', + 'http', + 'https', + 'net', + 'os', + 'readline', + 'stream', + 'string_decoder', + 'tls', + 'tty', + 'zlib', + 'constants', + 'events', + 'url', + 'assert', + 'util', + 'path', + 'punycode', + 'querystring', + 'cluster', + 'console', + 'module', + 'process', + 'vm', + 'domain', + 'v8', + 'repl', + 'timers', +]; + +const IGNORED_MODULES = [ + 'bufferutil', + 'utf-8-validate', + 'spawn-sync', + './src/logcat', + './src/monkey', + './src/adb', +]; + +function isRequire(node) { + return ( + node.type === 'CallExpression' && + node.callee.type === 'Identifier' && + node.callee.name === 'require' && + node.arguments.length === 1 && + node.arguments[0].type === 'StringLiteral' + ); +} + +module.exports = function(babel) { + const t = babel.types; + + return { + name: 'infinity-import-react', + visitor: { + CallExpression(path) { + if (!isRequire(path.node)) { + return; + } + + const source = path.node.arguments[0].value; + + if (BUILTINS.includes(source)) { + path.node.callee.name = 'electronRequire'; + } + + if (IGNORED_MODULES.includes(source)) { + path.replaceWith(t.identifier('triggerReferenceError')); + } + }, + }, + }; +}; diff --git a/static/transforms/fb-stubs.js b/static/transforms/fb-stubs.js new file mode 100644 index 000000000..e106ad3d4 --- /dev/null +++ b/static/transforms/fb-stubs.js @@ -0,0 +1,45 @@ +/** + * Copyright 2018-present Facebook. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * @format + */ + +const fs = require('fs'); +const path = require('path'); +const replaceFBStubs = fs.existsSync( + path.join(__dirname, '..', '..', 'src', 'fb'), +); + +const requireFromFolder = (folder, path) => + new RegExp(folder + '/[A-Za-z0-9.-_]+(.js)?$', 'g').test(path); + +module.exports = function(babel) { + return { + name: 'replace-dynamic-requires', + visitor: { + CallExpression(path) { + if ( + replaceFBStubs && + path.node.type === 'CallExpression' && + path.node.callee.type === 'Identifier' && + path.node.callee.name === 'require' && + path.node.arguments.length > 0 + ) { + if (requireFromFolder('fb', path.node.arguments[0].value)) { + throw new Error( + 'Do not requrie directly from fb/, but rather from fb-stubs/ to not break flow-typing and make sure stubs are uptodate.', + ); + } else if ( + requireFromFolder('fb-stubs', path.node.arguments[0].value) + ) { + path.node.arguments[0].value = path.node.arguments[0].value.replace( + '/fb-stubs/', + '/fb/', + ); + } + } + }, + }, + }; +}; diff --git a/static/transforms/import-react.js b/static/transforms/import-react.js new file mode 100644 index 000000000..002e22528 --- /dev/null +++ b/static/transforms/import-react.js @@ -0,0 +1,51 @@ +/** + * Copyright 2018-present Facebook. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * @format + */ + +module.exports = function(babel) { + const t = babel.types; + + return { + name: 'infinity-import-react', + visitor: { + Program: { + exit(path, state) { + if (state.get('NEEDS_REACT')) { + path.unshiftContainer('body', [ + t.variableDeclaration('var', [ + t.variableDeclarator( + t.identifier('React'), + t.callExpression(t.identifier('require'), [ + t.stringLiteral('react'), + ]), + ), + ]), + ]); + } + }, + }, + + ReferencedIdentifier(path, state) { + // mark react as needing to be imported + if (path.node.name === 'React' && !path.scope.getBinding('React')) { + state.set('NEEDS_REACT', true); + } + + // replace Buffer with require('buffer') + if (path.node.name === 'Buffer' && !path.scope.getBinding('Buffer')) { + path.replaceWith( + t.memberExpression( + t.callExpression(t.identifier('require'), [ + t.stringLiteral('buffer'), + ]), + t.identifier('Buffer'), + ), + ); + } + }, + }, + }; +}; diff --git a/static/transforms/index.js b/static/transforms/index.js new file mode 100644 index 000000000..09b9f3081 --- /dev/null +++ b/static/transforms/index.js @@ -0,0 +1,64 @@ +/** + * Copyright 2018-present Facebook. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * @format + */ + +const generate = require('@babel/generator').default; +const babylon = require('babylon'); +const babel = require('@babel/core'); +const metro = require('metro'); + +exports.transform = function({filename, options, src}) { + const presets = [require('../node_modules/babel-preset-react')]; + const isSonarPlugin = !__dirname.startsWith(options.projectRoot); + + let ast = babylon.parse(src, { + filename, + plugins: ['jsx', 'flow', 'classProperties', 'objectRestSpread'], + sourceType: 'module', + }); + + // run babel + const plugins = [ + require('../node_modules/babel-plugin-transform-object-rest-spread'), + require('../node_modules/babel-plugin-transform-class-properties'), + require('../node_modules/babel-plugin-transform-flow-strip-types'), + require('./electron-requires.js'), + require('./fb-stubs.js'), + require('./dynamic-requires.js'), + ]; + if (isSonarPlugin) { + plugins.push(require('./sonar-requires.js')); + } else { + plugins.push(require('./import-react.js')); + } + plugins.unshift(require('babel-plugin-transform-es2015-modules-commonjs')); + + ast = babel.transformFromAst(ast, src, { + babelrc: !filename.includes('node_modules'), + code: false, + comments: false, + compact: false, + filename, + plugins, + presets, + sourceMaps: true, + }).ast; + const result = generate( + ast, + { + filename, + sourceFileName: filename, + sourceMaps: true, + }, + src, + ); + return { + ast, + code: result.code, + filename, + map: result.rawMappings.map(metro.sourceMaps.compactMapping), + }; +}; diff --git a/static/transforms/sonar-requires.js b/static/transforms/sonar-requires.js new file mode 100644 index 000000000..33466f85a --- /dev/null +++ b/static/transforms/sonar-requires.js @@ -0,0 +1,64 @@ +/** + * Copyright 2018-present Facebook. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * @format + */ + +// do not apply this transform for these paths +const EXCLUDE_PATHS = [ + '/node_modules/react-devtools-core/', + 'relay-devtools/DevtoolsUI', +]; + +function isExcludedPath(path) { + for (const epath of EXCLUDE_PATHS) { + if (path.indexOf(epath) > -1) { + return true; + } + } + return false; +} // $FlowFixMe +module.exports = ({types: t}) => ({ + visitor: { + // $FlowFixMe + CallExpression(path, state) { + if (isExcludedPath(state.file.opts.filename)) { + return; + } + const node = path.node; + const args = node.arguments || []; + if ( + node.callee.name === 'require' && + args.length === 1 && + t.isStringLiteral(args[0]) && + args[0].value === 'sonar' + ) { + path.replaceWith(t.identifier('window.Sonar')); + } else if ( + node.callee.name === 'require' && + args.length > 0 && + t.isStringLiteral(args[0]) && + args[0].value === 'react' + ) { + path.replaceWith(t.identifier('window.React')); + } else if ( + node.callee.name === 'require' && + args.length > 0 && + t.isStringLiteral(args[0]) && + args[0].value === 'react-dom' + ) { + path.replaceWith(t.identifier('window.ReactDOM')); + } + }, + Identifier(path, state) { + if ( + path.node.name === 'React' && + path.parentPath.node.id !== path.node && + !isExcludedPath(state.file.opts.filename) + ) { + path.replaceWith(t.identifier('window.React')); + } + }, + }, +}); diff --git a/static/uiperf/screenshot.png b/static/uiperf/screenshot.png new file mode 100644 index 0000000000000000000000000000000000000000..5cbc1bad0f56640394ff68d78ce9b12705768036 GIT binary patch literal 33585 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.vis-content{position:relative}.vis-panel .vis-shadow{position:absolute;width:100%;height:1px;box-shadow:0 0 10px rgba(0,0,0,.8)}.vis-panel .vis-shadow.vis-top{top:-1px;left:0}.vis-panel .vis-shadow.vis-bottom{bottom:-1px;left:0}.vis-graph-group0{fill:#4f81bd;fill-opacity:0;stroke-width:2px;stroke:#4f81bd}.vis-graph-group1{fill:#f79646;fill-opacity:0;stroke-width:2px;stroke:#f79646}.vis-graph-group2{fill:#8c51cf;fill-opacity:0;stroke-width:2px;stroke:#8c51cf}.vis-graph-group3{fill:#75c841;fill-opacity:0;stroke-width:2px;stroke:#75c841}.vis-graph-group4{fill:#ff0100;fill-opacity:0;stroke-width:2px;stroke:#ff0100}.vis-graph-group5{fill:#37d8e6;fill-opacity:0;stroke-width:2px;stroke:#37d8e6}.vis-graph-group6{fill:#042662;fill-opacity:0;stroke-width:2px;stroke:#042662}.vis-graph-group7{fill:#00ff26;fill-opacity:0;stroke-width:2px;stroke:#00ff26}.vis-graph-group8{fill:#f0f;fill-opacity:0;stroke-width:2px;stroke:#f0f}.vis-graph-group9{fill:#8f3938;fill-opacity:0;stroke-width:2px;stroke:#8f3938}.vis-timeline .vis-fill{fill-opacity:.1;stroke:none}.vis-timeline .vis-bar{fill-opacity:.5;stroke-width:1px}.vis-timeline .vis-point{stroke-width:2px;fill-opacity:1}.vis-timeline .vis-legend-background{stroke-width:1px;fill-opacity:.9;fill:#fff;stroke:#c2c2c2}.vis-timeline .vis-outline{stroke-width:1px;fill-opacity:1;fill:#fff;stroke:#e5e5e5}.vis-timeline .vis-icon-fill{fill-opacity:.3;stroke:none}.vis-time-axis{position:relative;overflow:hidden}.vis-time-axis.vis-foreground{top:0;left:0;width:100%}.vis-time-axis.vis-background{position:absolute;top:0;left:0;width:100%;height:100%}.vis-time-axis .vis-text{position:absolute;color:#4d4d4d;padding:3px;overflow:hidden;box-sizing:border-box;white-space:nowrap}.vis-time-axis .vis-text.vis-measure{position:absolute;padding-left:0;padding-right:0;margin-left:0;margin-right:0;visibility:hidden}.vis-time-axis .vis-grid.vis-vertical{position:absolute;border-left:1px solid}.vis-time-axis .vis-grid.vis-vertical-rtl{position:absolute;border-right:1px solid}.vis-time-axis .vis-grid.vis-minor{border-color:#e5e5e5}.vis-time-axis .vis-grid.vis-major{border-color:#bfbfbf}.vis-timeline{position:relative;border:1px solid #bfbfbf;overflow:hidden;padding:0;margin:0;box-sizing:border-box} \ No newline at end of file diff --git a/static/yarn.lock b/static/yarn.lock new file mode 100644 index 000000000..e828e1596 --- /dev/null +++ b/static/yarn.lock @@ -0,0 +1,3115 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@babel/code-frame@7.0.0-beta.40": + version "7.0.0-beta.40" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.0.0-beta.40.tgz#37e2b0cf7c56026b4b21d3927cadf81adec32ac6" + dependencies: + "@babel/highlight" "7.0.0-beta.40" + +"@babel/core@^7.0.0-beta", "@babel/core@^7.0.0-beta.40": + version "7.0.0-beta.40" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.0.0-beta.40.tgz#455464dd81d499fd97d32b473f0331f74379a33f" + dependencies: + "@babel/code-frame" "7.0.0-beta.40" + "@babel/generator" "7.0.0-beta.40" + "@babel/helpers" "7.0.0-beta.40" + "@babel/template" "7.0.0-beta.40" + "@babel/traverse" "7.0.0-beta.40" + "@babel/types" "7.0.0-beta.40" + babylon "7.0.0-beta.40" + convert-source-map "^1.1.0" + debug "^3.0.1" + json5 "^0.5.0" + lodash "^4.2.0" + micromatch "^2.3.11" + resolve "^1.3.2" + source-map "^0.5.0" + +"@babel/generator@7.0.0-beta.40", "@babel/generator@^7.0.0-beta", "@babel/generator@^7.0.0-beta.40": + version "7.0.0-beta.40" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.0.0-beta.40.tgz#ab61f9556f4f71dbd1138949c795bb9a21e302ea" + dependencies: + "@babel/types" "7.0.0-beta.40" + jsesc "^2.5.1" + lodash "^4.2.0" + source-map "^0.5.0" + trim-right "^1.0.1" + +"@babel/helper-annotate-as-pure@7.0.0-beta.40": + version "7.0.0-beta.40" + resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.0.0-beta.40.tgz#095dd4c70b231eba17ebf61c3434e6f9d71bd574" + dependencies: + "@babel/types" "7.0.0-beta.40" + +"@babel/helper-builder-react-jsx@7.0.0-beta.40": + version "7.0.0-beta.40" + resolved "https://registry.yarnpkg.com/@babel/helper-builder-react-jsx/-/helper-builder-react-jsx-7.0.0-beta.40.tgz#2a171b6c4939c6cd0bdc38cca261d1f3b32cedb1" + dependencies: + "@babel/types" "7.0.0-beta.40" + esutils "^2.0.0" + +"@babel/helper-call-delegate@7.0.0-beta.40": + version "7.0.0-beta.40" + resolved "https://registry.yarnpkg.com/@babel/helper-call-delegate/-/helper-call-delegate-7.0.0-beta.40.tgz#5d5000d0bf76c68ee6866961e0b7eb6e9ed52438" + dependencies: + "@babel/helper-hoist-variables" "7.0.0-beta.40" + "@babel/traverse" "7.0.0-beta.40" + "@babel/types" "7.0.0-beta.40" + +"@babel/helper-define-map@7.0.0-beta.40": + version "7.0.0-beta.40" + resolved "https://registry.yarnpkg.com/@babel/helper-define-map/-/helper-define-map-7.0.0-beta.40.tgz#ad64c548dd98e7746305852f113ed04dc74329c0" + dependencies: + "@babel/helper-function-name" "7.0.0-beta.40" + "@babel/types" "7.0.0-beta.40" + lodash "^4.2.0" + +"@babel/helper-function-name@7.0.0-beta.40": + version "7.0.0-beta.40" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.0.0-beta.40.tgz#9d033341ab16517f40d43a73f2d81fc431ccd7b6" + dependencies: + "@babel/helper-get-function-arity" "7.0.0-beta.40" + "@babel/template" "7.0.0-beta.40" + "@babel/types" "7.0.0-beta.40" + +"@babel/helper-get-function-arity@7.0.0-beta.40": + version "7.0.0-beta.40" + resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0-beta.40.tgz#ac0419cf067b0ec16453e1274f03878195791c6e" + dependencies: + "@babel/types" "7.0.0-beta.40" + +"@babel/helper-hoist-variables@7.0.0-beta.40": + version "7.0.0-beta.40" + resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.0.0-beta.40.tgz#59d47fd133782d60db89af0d18083ad3c9f4801c" + dependencies: + "@babel/types" "7.0.0-beta.40" + +"@babel/helper-module-imports@7.0.0-beta.40": + version "7.0.0-beta.40" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.0.0-beta.40.tgz#251cbb6404599282e8f7356a5b32c9381bef5d2d" + dependencies: + "@babel/types" "7.0.0-beta.40" + lodash "^4.2.0" + +"@babel/helper-module-transforms@7.0.0-beta.40": + version "7.0.0-beta.40" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.0.0-beta.40.tgz#e5240afd47bd98f6ae65874b9ae508533abfee76" + dependencies: + "@babel/helper-module-imports" "7.0.0-beta.40" + "@babel/helper-simple-access" "7.0.0-beta.40" + "@babel/template" "7.0.0-beta.40" + "@babel/types" "7.0.0-beta.40" + lodash "^4.2.0" + +"@babel/helper-optimise-call-expression@7.0.0-beta.40": + version "7.0.0-beta.40" + resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.0.0-beta.40.tgz#f0e7f70d455bff8ab6a248a84f0221098fa468ac" + dependencies: + "@babel/types" "7.0.0-beta.40" + +"@babel/helper-remap-async-to-generator@^7.0.0-beta": + version "7.0.0-beta.40" + resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.0.0-beta.40.tgz#33414d1cc160ebf0991ebc60afebe36b08feae05" + dependencies: + "@babel/helper-annotate-as-pure" "7.0.0-beta.40" + "@babel/helper-wrap-function" "7.0.0-beta.40" + "@babel/template" "7.0.0-beta.40" + "@babel/traverse" "7.0.0-beta.40" + "@babel/types" "7.0.0-beta.40" + +"@babel/helper-replace-supers@7.0.0-beta.40": + version "7.0.0-beta.40" + resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.0.0-beta.40.tgz#2ab0c9e7fa17d313745f1634ce6b7bccaa5dd5fe" + dependencies: + "@babel/helper-optimise-call-expression" "7.0.0-beta.40" + "@babel/template" "7.0.0-beta.40" + "@babel/traverse" "7.0.0-beta.40" + "@babel/types" "7.0.0-beta.40" + +"@babel/helper-simple-access@7.0.0-beta.40": + version "7.0.0-beta.40" + resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.0.0-beta.40.tgz#018f765090a3d25153778958969f235dc6ce5b57" + dependencies: + "@babel/template" "7.0.0-beta.40" + "@babel/types" "7.0.0-beta.40" + lodash "^4.2.0" + +"@babel/helper-wrap-function@7.0.0-beta.40": + version "7.0.0-beta.40" + resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.0.0-beta.40.tgz#4db4630cdaf4fd47fa2c45b5b7a9ecc33ff3f2be" + dependencies: + "@babel/helper-function-name" "7.0.0-beta.40" + "@babel/template" "7.0.0-beta.40" + "@babel/traverse" "7.0.0-beta.40" + "@babel/types" "7.0.0-beta.40" + +"@babel/helpers@7.0.0-beta.40": + version "7.0.0-beta.40" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.0.0-beta.40.tgz#82f8e144f56b2896b1d624ca88ac4603023ececd" + dependencies: + "@babel/template" "7.0.0-beta.40" + "@babel/traverse" "7.0.0-beta.40" + "@babel/types" "7.0.0-beta.40" + +"@babel/highlight@7.0.0-beta.40": + version "7.0.0-beta.40" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.0.0-beta.40.tgz#b43d67d76bf46e1d10d227f68cddcd263786b255" + dependencies: + chalk "^2.0.0" + esutils "^2.0.2" + js-tokens "^3.0.0" + +"@babel/plugin-check-constants@^7.0.0-beta": + version "7.0.0-beta.38" + resolved "https://registry.yarnpkg.com/@babel/plugin-check-constants/-/plugin-check-constants-7.0.0-beta.38.tgz#bbda6306d45a4f097ccb416c0b52d6503f6502cf" + +"@babel/plugin-external-helpers@^7.0.0-beta": + version "7.0.0-beta.40" + resolved "https://registry.yarnpkg.com/@babel/plugin-external-helpers/-/plugin-external-helpers-7.0.0-beta.40.tgz#9f08717d1016918a60d497ad9e35c44b3489a45c" + +"@babel/plugin-proposal-class-properties@^7.0.0-beta": + version "7.0.0-beta.40" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.0.0-beta.40.tgz#ee0549729e9f44603efa17523b459ea3021458dc" + dependencies: + "@babel/helper-function-name" "7.0.0-beta.40" + "@babel/plugin-syntax-class-properties" "7.0.0-beta.40" + +"@babel/plugin-proposal-object-rest-spread@^7.0.0-beta": + version "7.0.0-beta.40" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.0.0-beta.40.tgz#ce35d2240908e52706a612eb26d67db667cd700f" + dependencies: + "@babel/plugin-syntax-object-rest-spread" "7.0.0-beta.40" + +"@babel/plugin-syntax-class-properties@7.0.0-beta.40": + version "7.0.0-beta.40" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.0.0-beta.40.tgz#ff82c04c6d97cdb947dc64e3f3d4bc791e85a16f" + +"@babel/plugin-syntax-dynamic-import@^7.0.0-beta": + version "7.0.0-beta.40" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.0.0-beta.40.tgz#5d9b58d4fbe1dfabbd44dee2eb267c466d7e9b87" + +"@babel/plugin-syntax-flow@7.0.0-beta.40": + version "7.0.0-beta.40" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.0.0-beta.40.tgz#2326da177cd83ad3d12e8324ad003edb702c384c" + +"@babel/plugin-syntax-jsx@7.0.0-beta.40": + version "7.0.0-beta.40" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.0.0-beta.40.tgz#db44d52ff06f784be22f2659e694cc2cf97f99f9" + +"@babel/plugin-syntax-object-rest-spread@7.0.0-beta.40": + version "7.0.0-beta.40" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.0.0-beta.40.tgz#d5e04536062e4df685c203ae48bb19bfe2cf235c" + +"@babel/plugin-transform-arrow-functions@^7.0.0-beta": + version "7.0.0-beta.40" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.0.0-beta.40.tgz#0842045b16835d6da0c334d0b09d575852f27962" + +"@babel/plugin-transform-block-scoping@^7.0.0-beta": + version "7.0.0-beta.40" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.0.0-beta.40.tgz#23197ee6f696b7e5ace884f0dc5434df20d7dd97" + dependencies: + lodash "^4.2.0" + +"@babel/plugin-transform-classes@^7.0.0-beta": + version "7.0.0-beta.40" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.0.0-beta.40.tgz#c7a752009df4bb0f77179027daa0783f9a036b0b" + dependencies: + "@babel/helper-annotate-as-pure" "7.0.0-beta.40" + "@babel/helper-define-map" "7.0.0-beta.40" + "@babel/helper-function-name" "7.0.0-beta.40" + "@babel/helper-optimise-call-expression" "7.0.0-beta.40" + "@babel/helper-replace-supers" "7.0.0-beta.40" + globals "^11.1.0" + +"@babel/plugin-transform-computed-properties@^7.0.0-beta": + version "7.0.0-beta.40" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.0.0-beta.40.tgz#e4bd53455d9f96882cc8e9923895d71690f6969e" + +"@babel/plugin-transform-destructuring@^7.0.0-beta": + version "7.0.0-beta.40" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.0.0-beta.40.tgz#503a4719eb9ed8c933b50d4ec3f106ed371852ee" + +"@babel/plugin-transform-flow-strip-types@^7.0.0-beta": + version "7.0.0-beta.40" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.0.0-beta.40.tgz#fe3afe922de6dfbd21d9f53f01cbe1bac89e0423" + dependencies: + "@babel/plugin-syntax-flow" "7.0.0-beta.40" + +"@babel/plugin-transform-for-of@^7.0.0-beta": + version "7.0.0-beta.40" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.0.0-beta.40.tgz#67920d749bac4840ceeae9907d918dad33908244" + +"@babel/plugin-transform-function-name@^7.0.0-beta": + version "7.0.0-beta.40" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.0.0-beta.40.tgz#37b5ca4f90fba207d359c0be3af5bfecdc737a3d" + dependencies: + "@babel/helper-function-name" "7.0.0-beta.40" + +"@babel/plugin-transform-literals@^7.0.0-beta": + version "7.0.0-beta.40" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.0.0-beta.40.tgz#a6bf8808f97accf42a171b27a133802aa0650d3e" + +"@babel/plugin-transform-modules-commonjs@^7.0.0-beta": + version "7.0.0-beta.40" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.0.0-beta.40.tgz#a85f8c311f498a94a45531cc4ed5ff98b338a70a" + dependencies: + "@babel/helper-module-transforms" "7.0.0-beta.40" + "@babel/helper-simple-access" "7.0.0-beta.40" + +"@babel/plugin-transform-object-assign@^7.0.0-beta": + version "7.0.0-beta.40" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-assign/-/plugin-transform-object-assign-7.0.0-beta.40.tgz#c201c0e46befd15cf5439db07df7d7470ac943be" + +"@babel/plugin-transform-parameters@^7.0.0-beta": + version "7.0.0-beta.40" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.0.0-beta.40.tgz#efa366fab0dcbd0221b46aa2662c324b4b414d1d" + dependencies: + "@babel/helper-call-delegate" "7.0.0-beta.40" + "@babel/helper-get-function-arity" "7.0.0-beta.40" + +"@babel/plugin-transform-react-display-name@^7.0.0-beta": + version "7.0.0-beta.40" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.0.0-beta.40.tgz#2e9aba5d74da8ecee00d6d4bf68c833955355e4c" + +"@babel/plugin-transform-react-jsx-source@^7.0.0-beta": + version "7.0.0-beta.40" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.0.0-beta.40.tgz#7e62fe33f3e46c7f0d81d187d9c9aa348daa6488" + dependencies: + "@babel/plugin-syntax-jsx" "7.0.0-beta.40" + +"@babel/plugin-transform-react-jsx@^7.0.0-beta": + version "7.0.0-beta.40" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.0.0-beta.40.tgz#93af0b0ef691cda86ab52d912b50f72eb538349d" + dependencies: + "@babel/helper-builder-react-jsx" "7.0.0-beta.40" + "@babel/plugin-syntax-jsx" "7.0.0-beta.40" + +"@babel/plugin-transform-regenerator@^7.0.0-beta": + version "7.0.0-beta.40" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.0.0-beta.40.tgz#f8a89ce89a0fae8e9cdfc2f2768104811517374a" + dependencies: + regenerator-transform "^0.12.3" + +"@babel/plugin-transform-shorthand-properties@^7.0.0-beta": + version "7.0.0-beta.40" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.0.0-beta.40.tgz#421835237b0fcab0e67c941726d95dfc543514f4" + +"@babel/plugin-transform-spread@^7.0.0-beta": + version "7.0.0-beta.40" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.0.0-beta.40.tgz#881578938e5750137301750bef7fdd0e01be76be" + +"@babel/plugin-transform-template-literals@^7.0.0-beta": + version "7.0.0-beta.40" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.0.0-beta.40.tgz#5ef3377d1294aee39b913768a1f884806a45393b" + dependencies: + "@babel/helper-annotate-as-pure" "7.0.0-beta.40" + +"@babel/template@7.0.0-beta.40", "@babel/template@^7.0.0-beta": + version "7.0.0-beta.40" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.0.0-beta.40.tgz#034988c6424eb5c3268fe6a608626de1f4410fc8" + dependencies: + "@babel/code-frame" "7.0.0-beta.40" + "@babel/types" "7.0.0-beta.40" + babylon "7.0.0-beta.40" + lodash "^4.2.0" + +"@babel/traverse@7.0.0-beta.40", "@babel/traverse@^7.0.0-beta": + version "7.0.0-beta.40" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.0.0-beta.40.tgz#d140e449b2e093ef9fe1a2eecc28421ffb4e521e" + dependencies: + "@babel/code-frame" "7.0.0-beta.40" + "@babel/generator" "7.0.0-beta.40" + "@babel/helper-function-name" "7.0.0-beta.40" + "@babel/types" "7.0.0-beta.40" + babylon "7.0.0-beta.40" + debug "^3.0.1" + globals "^11.1.0" + invariant "^2.2.0" + lodash "^4.2.0" + +"@babel/types@7.0.0-beta.40", "@babel/types@^7.0.0-beta": + version "7.0.0-beta.40" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.0.0-beta.40.tgz#25c3d7aae14126abe05fcb098c65a66b6d6b8c14" + dependencies: + esutils "^2.0.2" + lodash "^4.2.0" + to-fast-properties "^2.0.0" + +abbrev@1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" + +absolute-path@^0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/absolute-path/-/absolute-path-0.0.0.tgz#a78762fbdadfb5297be99b15d35a785b2f095bf7" + +ajv@^4.9.1: + version "4.11.8" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-4.11.8.tgz#82ffb02b29e662ae53bdc20af15947706739c536" + dependencies: + co "^4.6.0" + json-stable-stringify "^1.0.1" + +ajv@^5.1.0: + version "5.5.2" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-5.5.2.tgz#73b5eeca3fab653e3d3f9422b341ad42205dc965" + dependencies: + co "^4.6.0" + fast-deep-equal "^1.0.0" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.3.0" + +ansi-regex@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" + +ansi-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" + +ansi-styles@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" + +ansi-styles@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" + dependencies: + color-convert "^1.9.0" + +anymatch@^1.3.0: + version "1.3.2" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-1.3.2.tgz#553dcb8f91e3c889845dfdba34c77721b90b9d7a" + dependencies: + micromatch "^2.1.5" + normalize-path "^2.0.0" + +aproba@^1.0.3: + version "1.2.0" + resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" + +are-we-there-yet@~1.1.2: + version "1.1.4" + resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.4.tgz#bb5dca382bb94f05e15194373d16fd3ba1ca110d" + dependencies: + delegates "^1.0.0" + readable-stream "^2.0.6" + +arr-diff@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-2.0.0.tgz#8f3b827f955a8bd669697e4a4256ac3ceae356cf" + dependencies: + arr-flatten "^1.0.1" + +arr-flatten@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1" + +array-unique@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.2.1.tgz#a1d97ccafcbc2625cc70fadceb36a50c58b01a53" + +asap@~2.0.3: + version "2.0.6" + resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46" + +asn1@~0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.3.tgz#dac8787713c9966849fc8180777ebe9c1ddf3b86" + +assert-plus@1.0.0, assert-plus@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" + +assert-plus@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-0.2.0.tgz#d74e1b87e7affc0db8aadb7021f3fe48101ab234" + +async@^2.4.0: + version "2.6.0" + resolved "https://registry.yarnpkg.com/async/-/async-2.6.0.tgz#61a29abb6fcc026fea77e56d1c6ec53a795951f4" + dependencies: + lodash "^4.14.0" + +asynckit@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" + +aws-sign2@~0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.6.0.tgz#14342dd38dbcc94d0e5b87d763cd63612c0e794f" + +aws-sign2@~0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" + +aws4@^1.2.1, aws4@^1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.6.0.tgz#83ef5ca860b2b32e4a0deedee8c771b9db57471e" + +babel-code-frame@7.0.0-beta.3: + version "7.0.0-beta.3" + resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-7.0.0-beta.3.tgz#1614a91b2ba0e3848559f410bbacd030726899c9" + dependencies: + chalk "^2.0.0" + esutils "^2.0.2" + js-tokens "^3.0.0" + +babel-code-frame@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b" + dependencies: + chalk "^1.1.3" + esutils "^2.0.2" + js-tokens "^3.0.2" + +babel-core@^6.24.1, babel-core@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-6.26.0.tgz#af32f78b31a6fcef119c87b0fd8d9753f03a0bb8" + dependencies: + babel-code-frame "^6.26.0" + babel-generator "^6.26.0" + babel-helpers "^6.24.1" + babel-messages "^6.23.0" + babel-register "^6.26.0" + babel-runtime "^6.26.0" + babel-template "^6.26.0" + babel-traverse "^6.26.0" + babel-types "^6.26.0" + babylon "^6.18.0" + convert-source-map "^1.5.0" + debug "^2.6.8" + json5 "^0.5.1" + lodash "^4.17.4" + minimatch "^3.0.4" + path-is-absolute "^1.0.1" + private "^0.1.7" + slash "^1.0.0" + source-map "^0.5.6" + +babel-generator@^6.26.0: + version "6.26.1" + resolved "https://registry.yarnpkg.com/babel-generator/-/babel-generator-6.26.1.tgz#1844408d3b8f0d35a404ea7ac180f087a601bd90" + dependencies: + babel-messages "^6.23.0" + babel-runtime "^6.26.0" + babel-types "^6.26.0" + detect-indent "^4.0.0" + jsesc "^1.3.0" + lodash "^4.17.4" + source-map "^0.5.7" + trim-right "^1.0.1" + +babel-helper-builder-react-jsx@7.0.0-beta.3: + version "7.0.0-beta.3" + resolved "https://registry.yarnpkg.com/babel-helper-builder-react-jsx/-/babel-helper-builder-react-jsx-7.0.0-beta.3.tgz#a3ff5d2427c4aec5af6b4376e7a5103c67508f8e" + dependencies: + babel-types "7.0.0-beta.3" + esutils "^2.0.0" + +babel-helper-builder-react-jsx@^6.24.1: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-helper-builder-react-jsx/-/babel-helper-builder-react-jsx-6.26.0.tgz#39ff8313b75c8b65dceff1f31d383e0ff2a408a0" + dependencies: + babel-runtime "^6.26.0" + babel-types "^6.26.0" + esutils "^2.0.2" + +babel-helper-call-delegate@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz#ece6aacddc76e41c3461f88bfc575bd0daa2df8d" + dependencies: + babel-helper-hoist-variables "^6.24.1" + babel-runtime "^6.22.0" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-helper-define-map@^6.24.1: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-helper-define-map/-/babel-helper-define-map-6.26.0.tgz#a5f56dab41a25f97ecb498c7ebaca9819f95be5f" + dependencies: + babel-helper-function-name "^6.24.1" + babel-runtime "^6.26.0" + babel-types "^6.26.0" + lodash "^4.17.4" + +babel-helper-function-name@7.0.0-beta.3: + version "7.0.0-beta.3" + resolved "https://registry.yarnpkg.com/babel-helper-function-name/-/babel-helper-function-name-7.0.0-beta.3.tgz#e86dd2eb2c09e06e392e79e203fc02427b24c871" + dependencies: + babel-helper-get-function-arity "7.0.0-beta.3" + babel-template "7.0.0-beta.3" + babel-traverse "7.0.0-beta.3" + babel-types "7.0.0-beta.3" + +babel-helper-function-name@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz#d3475b8c03ed98242a25b48351ab18399d3580a9" + dependencies: + babel-helper-get-function-arity "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-helper-get-function-arity@7.0.0-beta.3: + version "7.0.0-beta.3" + resolved "https://registry.yarnpkg.com/babel-helper-get-function-arity/-/babel-helper-get-function-arity-7.0.0-beta.3.tgz#61a47709318a31bc2db872f4be9b4c8447198be8" + dependencies: + babel-types "7.0.0-beta.3" + +babel-helper-get-function-arity@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.24.1.tgz#8f7782aa93407c41d3aa50908f89b031b1b6853d" + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-helper-hoist-variables@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.24.1.tgz#1ecb27689c9d25513eadbc9914a73f5408be7a76" + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-helper-module-imports@7.0.0-beta.3: + version "7.0.0-beta.3" + resolved "https://registry.yarnpkg.com/babel-helper-module-imports/-/babel-helper-module-imports-7.0.0-beta.3.tgz#e15764e3af9c8e11810c09f78f498a2bdc71585a" + dependencies: + babel-types "7.0.0-beta.3" + lodash "^4.2.0" + +babel-helper-module-transforms@7.0.0-beta.3: + version "7.0.0-beta.3" + resolved "https://registry.yarnpkg.com/babel-helper-module-transforms/-/babel-helper-module-transforms-7.0.0-beta.3.tgz#42ccfa323e2d3aaaf0f743e66c2e7a292dc064f7" + dependencies: + babel-helper-module-imports "7.0.0-beta.3" + babel-helper-simple-access "7.0.0-beta.3" + babel-template "7.0.0-beta.3" + babel-types "7.0.0-beta.3" + lodash "^4.2.0" + +babel-helper-optimise-call-expression@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.24.1.tgz#f7a13427ba9f73f8f4fa993c54a97882d1244257" + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-helper-regex@^6.24.1: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-helper-regex/-/babel-helper-regex-6.26.0.tgz#325c59f902f82f24b74faceed0363954f6495e72" + dependencies: + babel-runtime "^6.26.0" + babel-types "^6.26.0" + lodash "^4.17.4" + +babel-helper-replace-supers@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-replace-supers/-/babel-helper-replace-supers-6.24.1.tgz#bf6dbfe43938d17369a213ca8a8bf74b6a90ab1a" + dependencies: + babel-helper-optimise-call-expression "^6.24.1" + babel-messages "^6.23.0" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-helper-simple-access@7.0.0-beta.3: + version "7.0.0-beta.3" + resolved "https://registry.yarnpkg.com/babel-helper-simple-access/-/babel-helper-simple-access-7.0.0-beta.3.tgz#dee94c31289fca79076f7ced2d751a06e430756c" + dependencies: + babel-template "7.0.0-beta.3" + babel-types "7.0.0-beta.3" + lodash "^4.2.0" + +babel-helpers@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helpers/-/babel-helpers-6.24.1.tgz#3471de9caec388e5c850e597e58a26ddf37602b2" + dependencies: + babel-runtime "^6.22.0" + babel-template "^6.24.1" + +babel-messages@^6.23.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-messages/-/babel-messages-6.23.0.tgz#f3cdf4703858035b2a2951c6ec5edf6c62f2630e" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-check-es2015-constants@^6.5.0, babel-plugin-check-es2015-constants@^6.8.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz#35157b101426fd2ffd3da3f75c7d1e91835bbf8a" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-external-helpers@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-external-helpers/-/babel-plugin-external-helpers-6.22.0.tgz#2285f48b02bd5dede85175caf8c62e86adccefa1" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-react-transform@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/babel-plugin-react-transform/-/babel-plugin-react-transform-3.0.0.tgz#402f25137b7bb66e9b54ead75557dfbc7ecaaa74" + dependencies: + lodash "^4.6.1" + +babel-plugin-syntax-async-functions@^6.5.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz#cad9cad1191b5ad634bf30ae0872391e0647be95" + +babel-plugin-syntax-class-properties@7.0.0-beta.3: + version "7.0.0-beta.3" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-class-properties/-/babel-plugin-syntax-class-properties-7.0.0-beta.3.tgz#84480d42dc9ec49f5f8e1e62fb435151cbbe11a3" + +babel-plugin-syntax-class-properties@^6.5.0, babel-plugin-syntax-class-properties@^6.8.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-class-properties/-/babel-plugin-syntax-class-properties-6.13.0.tgz#d7eb23b79a317f8543962c505b827c7d6cac27de" + +babel-plugin-syntax-dynamic-import@^6.18.0: + version "6.18.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-dynamic-import/-/babel-plugin-syntax-dynamic-import-6.18.0.tgz#8d6a26229c83745a9982a441051572caa179b1da" + +babel-plugin-syntax-flow@7.0.0-beta.3: + version "7.0.0-beta.3" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-flow/-/babel-plugin-syntax-flow-7.0.0-beta.3.tgz#b96eceea4ffa380b95ccb21e8c75a556bffce879" + +babel-plugin-syntax-flow@^6.18.0, babel-plugin-syntax-flow@^6.5.0, babel-plugin-syntax-flow@^6.8.0: + version "6.18.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-flow/-/babel-plugin-syntax-flow-6.18.0.tgz#4c3ab20a2af26aa20cd25995c398c4eb70310c8d" + +babel-plugin-syntax-jsx@7.0.0-beta.3: + version "7.0.0-beta.3" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-7.0.0-beta.3.tgz#e45983c652a50d3647dfa4acd9db5567c0c2b701" + +babel-plugin-syntax-jsx@^6.5.0, babel-plugin-syntax-jsx@^6.8.0: + version "6.18.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz#0af32a9a6e13ca7a3fd5069e62d7b0f58d0d8946" + +babel-plugin-syntax-object-rest-spread@7.0.0-beta.3: + version "7.0.0-beta.3" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-7.0.0-beta.3.tgz#7f781c180899dafd88f132f69472397549be48e5" + +babel-plugin-syntax-object-rest-spread@^6.8.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz#fd6536f2bce13836ffa3a5458c4903a597bb3bf5" + +babel-plugin-syntax-trailing-function-commas@^6.5.0, babel-plugin-syntax-trailing-function-commas@^6.8.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz#ba0360937f8d06e40180a43fe0d5616fff532cf3" + +babel-plugin-transform-class-properties@^6.5.0, babel-plugin-transform-class-properties@^6.8.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-class-properties/-/babel-plugin-transform-class-properties-6.24.1.tgz#6a79763ea61d33d36f37b611aa9def81a81b46ac" + dependencies: + babel-helper-function-name "^6.24.1" + babel-plugin-syntax-class-properties "^6.8.0" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + +babel-plugin-transform-class-properties@^7.0.0-beta.3: + version "7.0.0-beta.3" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-class-properties/-/babel-plugin-transform-class-properties-7.0.0-beta.3.tgz#d7cf0e431512262499421d53582969503f24581a" + dependencies: + babel-helper-function-name "7.0.0-beta.3" + babel-plugin-syntax-class-properties "7.0.0-beta.3" + babel-template "7.0.0-beta.3" + +babel-plugin-transform-es2015-arrow-functions@^6.5.0, babel-plugin-transform-es2015-arrow-functions@^6.8.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz#452692cb711d5f79dc7f85e440ce41b9f244d221" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-block-scoped-functions@^6.8.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-block-scoped-functions/-/babel-plugin-transform-es2015-block-scoped-functions-6.22.0.tgz#bbc51b49f964d70cb8d8e0b94e820246ce3a6141" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-block-scoping@^6.5.0, babel-plugin-transform-es2015-block-scoping@^6.8.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.26.0.tgz#d70f5299c1308d05c12f463813b0a09e73b1895f" + dependencies: + babel-runtime "^6.26.0" + babel-template "^6.26.0" + babel-traverse "^6.26.0" + babel-types "^6.26.0" + lodash "^4.17.4" + +babel-plugin-transform-es2015-classes@^6.5.0, babel-plugin-transform-es2015-classes@^6.8.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.24.1.tgz#5a4c58a50c9c9461e564b4b2a3bfabc97a2584db" + dependencies: + babel-helper-define-map "^6.24.1" + babel-helper-function-name "^6.24.1" + babel-helper-optimise-call-expression "^6.24.1" + babel-helper-replace-supers "^6.24.1" + babel-messages "^6.23.0" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-computed-properties@^6.5.0, babel-plugin-transform-es2015-computed-properties@^6.8.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.24.1.tgz#6fe2a8d16895d5634f4cd999b6d3480a308159b3" + dependencies: + babel-runtime "^6.22.0" + babel-template "^6.24.1" + +babel-plugin-transform-es2015-destructuring@6.x, babel-plugin-transform-es2015-destructuring@^6.5.0, babel-plugin-transform-es2015-destructuring@^6.8.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz#997bb1f1ab967f682d2b0876fe358d60e765c56d" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-for-of@^6.5.0, babel-plugin-transform-es2015-for-of@^6.8.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.23.0.tgz#f47c95b2b613df1d3ecc2fdb7573623c75248691" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-function-name@6.x, babel-plugin-transform-es2015-function-name@^6.5.0, babel-plugin-transform-es2015-function-name@^6.8.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.24.1.tgz#834c89853bc36b1af0f3a4c5dbaa94fd8eacaa8b" + dependencies: + babel-helper-function-name "^6.24.1" + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-literals@^6.5.0, babel-plugin-transform-es2015-literals@^6.8.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-6.22.0.tgz#4f54a02d6cd66cf915280019a31d31925377ca2e" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-modules-commonjs@6.x, babel-plugin-transform-es2015-modules-commonjs@^6.5.0, babel-plugin-transform-es2015-modules-commonjs@^6.8.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.0.tgz#0d8394029b7dc6abe1a97ef181e00758dd2e5d8a" + dependencies: + babel-plugin-transform-strict-mode "^6.24.1" + babel-runtime "^6.26.0" + babel-template "^6.26.0" + babel-types "^6.26.0" + +babel-plugin-transform-es2015-modules-commonjs@^7.0.0-beta.3: + version "7.0.0-beta.3" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-7.0.0-beta.3.tgz#d53ae18f16e0b6a50ab65cdafbe3fa51a22f39b5" + dependencies: + babel-helper-module-transforms "7.0.0-beta.3" + babel-helper-simple-access "7.0.0-beta.3" + babel-types "7.0.0-beta.3" + +babel-plugin-transform-es2015-object-super@^6.8.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.24.1.tgz#24cef69ae21cb83a7f8603dad021f572eb278f8d" + dependencies: + babel-helper-replace-supers "^6.24.1" + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-parameters@6.x, babel-plugin-transform-es2015-parameters@^6.5.0, babel-plugin-transform-es2015-parameters@^6.8.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.24.1.tgz#57ac351ab49caf14a97cd13b09f66fdf0a625f2b" + dependencies: + babel-helper-call-delegate "^6.24.1" + babel-helper-get-function-arity "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-shorthand-properties@6.x, babel-plugin-transform-es2015-shorthand-properties@^6.5.0, babel-plugin-transform-es2015-shorthand-properties@^6.8.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.24.1.tgz#24f875d6721c87661bbd99a4622e51f14de38aa0" + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-spread@6.x, babel-plugin-transform-es2015-spread@^6.5.0, babel-plugin-transform-es2015-spread@^6.8.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.22.0.tgz#d6d68a99f89aedc4536c81a542e8dd9f1746f8d1" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-sticky-regex@6.x: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.24.1.tgz#00c1cdb1aca71112cdf0cf6126c2ed6b457ccdbc" + dependencies: + babel-helper-regex "^6.24.1" + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-template-literals@^6.5.0, babel-plugin-transform-es2015-template-literals@^6.8.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-6.22.0.tgz#a84b3450f7e9f8f1f6839d6d687da84bb1236d8d" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-unicode-regex@6.x: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.24.1.tgz#d38b12f42ea7323f729387f18a7c5ae1faeb35e9" + dependencies: + babel-helper-regex "^6.24.1" + babel-runtime "^6.22.0" + regexpu-core "^2.0.0" + +babel-plugin-transform-es3-member-expression-literals@^6.8.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es3-member-expression-literals/-/babel-plugin-transform-es3-member-expression-literals-6.22.0.tgz#733d3444f3ecc41bef8ed1a6a4e09657b8969ebb" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es3-property-literals@^6.8.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es3-property-literals/-/babel-plugin-transform-es3-property-literals-6.22.0.tgz#b2078d5842e22abf40f73e8cde9cd3711abd5758" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-flow-strip-types@^6.5.0, babel-plugin-transform-flow-strip-types@^6.8.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-flow-strip-types/-/babel-plugin-transform-flow-strip-types-6.22.0.tgz#84cb672935d43714fdc32bce84568d87441cf7cf" + dependencies: + babel-plugin-syntax-flow "^6.18.0" + babel-runtime "^6.22.0" + +babel-plugin-transform-flow-strip-types@^7.0.0-beta.3: + version "7.0.0-beta.3" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-flow-strip-types/-/babel-plugin-transform-flow-strip-types-7.0.0-beta.3.tgz#40d7c030895dc9811e7dd09997ee96df6054eed6" + dependencies: + babel-plugin-syntax-flow "7.0.0-beta.3" + +babel-plugin-transform-object-assign@^6.5.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-object-assign/-/babel-plugin-transform-object-assign-6.22.0.tgz#f99d2f66f1a0b0d498e346c5359684740caa20ba" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-object-rest-spread@^6.5.0, babel-plugin-transform-object-rest-spread@^6.8.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-object-rest-spread/-/babel-plugin-transform-object-rest-spread-6.26.0.tgz#0f36692d50fef6b7e2d4b3ac1478137a963b7b06" + dependencies: + babel-plugin-syntax-object-rest-spread "^6.8.0" + babel-runtime "^6.26.0" + +babel-plugin-transform-object-rest-spread@^7.0.0-beta.3: + version "7.0.0-beta.3" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-object-rest-spread/-/babel-plugin-transform-object-rest-spread-7.0.0-beta.3.tgz#5c409f3cd70819dbb3382d2056971c5ebe01393a" + dependencies: + babel-plugin-syntax-object-rest-spread "7.0.0-beta.3" + +babel-plugin-transform-react-display-name@7.0.0-beta.3: + version "7.0.0-beta.3" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-react-display-name/-/babel-plugin-transform-react-display-name-7.0.0-beta.3.tgz#9bec4984d868bf37e5184ed22bb66c44db61d612" + +babel-plugin-transform-react-display-name@^6.5.0, babel-plugin-transform-react-display-name@^6.8.0: + version "6.25.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-react-display-name/-/babel-plugin-transform-react-display-name-6.25.0.tgz#67e2bf1f1e9c93ab08db96792e05392bf2cc28d1" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-react-jsx-self@7.0.0-beta.3: + version "7.0.0-beta.3" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-react-jsx-self/-/babel-plugin-transform-react-jsx-self-7.0.0-beta.3.tgz#33bc0b66b090661409d308e6020d6835f8cfe611" + dependencies: + babel-plugin-syntax-jsx "7.0.0-beta.3" + +babel-plugin-transform-react-jsx-source@7.0.0-beta.3: + version "7.0.0-beta.3" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-react-jsx-source/-/babel-plugin-transform-react-jsx-source-7.0.0-beta.3.tgz#e5b1015a8eb107e51d64aace7677b2621c87f2ed" + dependencies: + babel-plugin-syntax-jsx "7.0.0-beta.3" + +babel-plugin-transform-react-jsx-source@^6.5.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-react-jsx-source/-/babel-plugin-transform-react-jsx-source-6.22.0.tgz#66ac12153f5cd2d17b3c19268f4bf0197f44ecd6" + dependencies: + babel-plugin-syntax-jsx "^6.8.0" + babel-runtime "^6.22.0" + +babel-plugin-transform-react-jsx@7.0.0-beta.3: + version "7.0.0-beta.3" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-react-jsx/-/babel-plugin-transform-react-jsx-7.0.0-beta.3.tgz#61af93962a3e6938ae8aeca10bb544f8b231ee7b" + dependencies: + babel-helper-builder-react-jsx "7.0.0-beta.3" + babel-plugin-syntax-jsx "7.0.0-beta.3" + +babel-plugin-transform-react-jsx@^6.5.0, babel-plugin-transform-react-jsx@^6.8.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-react-jsx/-/babel-plugin-transform-react-jsx-6.24.1.tgz#840a028e7df460dfc3a2d29f0c0d91f6376e66a3" + dependencies: + babel-helper-builder-react-jsx "^6.24.1" + babel-plugin-syntax-jsx "^6.8.0" + babel-runtime "^6.22.0" + +babel-plugin-transform-regenerator@^6.5.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.26.0.tgz#e0703696fbde27f0a3efcacf8b4dca2f7b3a8f2f" + dependencies: + regenerator-transform "^0.10.0" + +babel-plugin-transform-strict-mode@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz#d5faf7aa578a65bbe591cf5edae04a0c67020758" + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-preset-es2015-node@^6.1.1: + version "6.1.1" + resolved "https://registry.yarnpkg.com/babel-preset-es2015-node/-/babel-preset-es2015-node-6.1.1.tgz#60b23157024b0cfebf3a63554cb05ee035b4e55f" + dependencies: + babel-plugin-transform-es2015-destructuring "6.x" + babel-plugin-transform-es2015-function-name "6.x" + babel-plugin-transform-es2015-modules-commonjs "6.x" + babel-plugin-transform-es2015-parameters "6.x" + babel-plugin-transform-es2015-shorthand-properties "6.x" + babel-plugin-transform-es2015-spread "6.x" + babel-plugin-transform-es2015-sticky-regex "6.x" + babel-plugin-transform-es2015-unicode-regex "6.x" + semver "5.x" + +babel-preset-fbjs@^2.1.4: + version "2.1.4" + resolved "https://registry.yarnpkg.com/babel-preset-fbjs/-/babel-preset-fbjs-2.1.4.tgz#22f358e6654073acf61e47a052a777d7bccf03af" + dependencies: + babel-plugin-check-es2015-constants "^6.8.0" + babel-plugin-syntax-class-properties "^6.8.0" + babel-plugin-syntax-flow "^6.8.0" + babel-plugin-syntax-jsx "^6.8.0" + babel-plugin-syntax-object-rest-spread "^6.8.0" + babel-plugin-syntax-trailing-function-commas "^6.8.0" + babel-plugin-transform-class-properties "^6.8.0" + babel-plugin-transform-es2015-arrow-functions "^6.8.0" + babel-plugin-transform-es2015-block-scoped-functions "^6.8.0" + babel-plugin-transform-es2015-block-scoping "^6.8.0" + babel-plugin-transform-es2015-classes "^6.8.0" + babel-plugin-transform-es2015-computed-properties "^6.8.0" + babel-plugin-transform-es2015-destructuring "^6.8.0" + babel-plugin-transform-es2015-for-of "^6.8.0" + babel-plugin-transform-es2015-function-name "^6.8.0" + babel-plugin-transform-es2015-literals "^6.8.0" + babel-plugin-transform-es2015-modules-commonjs "^6.8.0" + babel-plugin-transform-es2015-object-super "^6.8.0" + babel-plugin-transform-es2015-parameters "^6.8.0" + babel-plugin-transform-es2015-shorthand-properties "^6.8.0" + babel-plugin-transform-es2015-spread "^6.8.0" + babel-plugin-transform-es2015-template-literals "^6.8.0" + babel-plugin-transform-es3-member-expression-literals "^6.8.0" + babel-plugin-transform-es3-property-literals "^6.8.0" + babel-plugin-transform-flow-strip-types "^6.8.0" + babel-plugin-transform-object-rest-spread "^6.8.0" + babel-plugin-transform-react-display-name "^6.8.0" + babel-plugin-transform-react-jsx "^6.8.0" + +babel-preset-react-native@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/babel-preset-react-native/-/babel-preset-react-native-4.0.0.tgz#3df80dd33a453888cdd33bdb87224d17a5d73959" + dependencies: + babel-plugin-check-es2015-constants "^6.5.0" + babel-plugin-react-transform "^3.0.0" + babel-plugin-syntax-async-functions "^6.5.0" + babel-plugin-syntax-class-properties "^6.5.0" + babel-plugin-syntax-dynamic-import "^6.18.0" + babel-plugin-syntax-flow "^6.5.0" + babel-plugin-syntax-jsx "^6.5.0" + babel-plugin-syntax-trailing-function-commas "^6.5.0" + babel-plugin-transform-class-properties "^6.5.0" + babel-plugin-transform-es2015-arrow-functions "^6.5.0" + babel-plugin-transform-es2015-block-scoping "^6.5.0" + babel-plugin-transform-es2015-classes "^6.5.0" + babel-plugin-transform-es2015-computed-properties "^6.5.0" + babel-plugin-transform-es2015-destructuring "^6.5.0" + babel-plugin-transform-es2015-for-of "^6.5.0" + babel-plugin-transform-es2015-function-name "^6.5.0" + babel-plugin-transform-es2015-literals "^6.5.0" + babel-plugin-transform-es2015-modules-commonjs "^6.5.0" + babel-plugin-transform-es2015-parameters "^6.5.0" + babel-plugin-transform-es2015-shorthand-properties "^6.5.0" + babel-plugin-transform-es2015-spread "^6.5.0" + babel-plugin-transform-es2015-template-literals "^6.5.0" + babel-plugin-transform-flow-strip-types "^6.5.0" + babel-plugin-transform-object-assign "^6.5.0" + babel-plugin-transform-object-rest-spread "^6.5.0" + babel-plugin-transform-react-display-name "^6.5.0" + babel-plugin-transform-react-jsx "^6.5.0" + babel-plugin-transform-react-jsx-source "^6.5.0" + babel-plugin-transform-regenerator "^6.5.0" + babel-template "^6.24.1" + react-transform-hmr "^1.0.4" + +babel-preset-react@^7.0.0-beta.3: + version "7.0.0-beta.3" + resolved "https://registry.yarnpkg.com/babel-preset-react/-/babel-preset-react-7.0.0-beta.3.tgz#3a6453e0a5e6156d9528590b629a70ecd9d50226" + dependencies: + babel-plugin-syntax-jsx "7.0.0-beta.3" + babel-plugin-transform-react-display-name "7.0.0-beta.3" + babel-plugin-transform-react-jsx "7.0.0-beta.3" + babel-plugin-transform-react-jsx-self "7.0.0-beta.3" + babel-plugin-transform-react-jsx-source "7.0.0-beta.3" + +babel-register@^6.24.1, babel-register@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-register/-/babel-register-6.26.0.tgz#6ed021173e2fcb486d7acb45c6009a856f647071" + dependencies: + babel-core "^6.26.0" + babel-runtime "^6.26.0" + core-js "^2.5.0" + home-or-tmp "^2.0.0" + lodash "^4.17.4" + mkdirp "^0.5.1" + source-map-support "^0.4.15" + +babel-runtime@^6.18.0, babel-runtime@^6.22.0, babel-runtime@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe" + dependencies: + core-js "^2.4.0" + regenerator-runtime "^0.11.0" + +babel-template@7.0.0-beta.3: + version "7.0.0-beta.3" + resolved "https://registry.yarnpkg.com/babel-template/-/babel-template-7.0.0-beta.3.tgz#ebb877b6070ce9912b0d0c22fcad3372165913a8" + dependencies: + babel-code-frame "7.0.0-beta.3" + babel-traverse "7.0.0-beta.3" + babel-types "7.0.0-beta.3" + babylon "7.0.0-beta.27" + lodash "^4.2.0" + +babel-template@^6.24.1, babel-template@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-template/-/babel-template-6.26.0.tgz#de03e2d16396b069f46dd9fff8521fb1a0e35e02" + dependencies: + babel-runtime "^6.26.0" + babel-traverse "^6.26.0" + babel-types "^6.26.0" + babylon "^6.18.0" + lodash "^4.17.4" + +babel-traverse@7.0.0-beta.3: + version "7.0.0-beta.3" + resolved "https://registry.yarnpkg.com/babel-traverse/-/babel-traverse-7.0.0-beta.3.tgz#3cf0a45d53d934d85275d8770775d7944fc7c199" + dependencies: + babel-code-frame "7.0.0-beta.3" + babel-helper-function-name "7.0.0-beta.3" + babel-types "7.0.0-beta.3" + babylon "7.0.0-beta.27" + debug "^3.0.1" + globals "^10.0.0" + invariant "^2.2.0" + lodash "^4.2.0" + +babel-traverse@^6.24.1, babel-traverse@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-traverse/-/babel-traverse-6.26.0.tgz#46a9cbd7edcc62c8e5c064e2d2d8d0f4035766ee" + dependencies: + babel-code-frame "^6.26.0" + babel-messages "^6.23.0" + babel-runtime "^6.26.0" + babel-types "^6.26.0" + babylon "^6.18.0" + debug "^2.6.8" + globals "^9.18.0" + invariant "^2.2.2" + lodash "^4.17.4" + +babel-types@7.0.0-beta.3: + version "7.0.0-beta.3" + resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-7.0.0-beta.3.tgz#cd927ca70e0ae8ab05f4aab83778cfb3e6eb20b4" + dependencies: + esutils "^2.0.2" + lodash "^4.2.0" + to-fast-properties "^2.0.0" + +babel-types@^6.19.0, babel-types@^6.24.1, babel-types@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-6.26.0.tgz#a3b073f94ab49eb6fa55cd65227a334380632497" + dependencies: + babel-runtime "^6.26.0" + esutils "^2.0.2" + lodash "^4.17.4" + to-fast-properties "^1.0.3" + +babylon@7.0.0-beta.27: + version "7.0.0-beta.27" + resolved "https://registry.yarnpkg.com/babylon/-/babylon-7.0.0-beta.27.tgz#b6edd30ef30619e2f630eb52585fdda84e6542cd" + +babylon@7.0.0-beta.40, babylon@^7.0.0-beta, babylon@^7.0.0-beta.40: + version "7.0.0-beta.40" + resolved "https://registry.yarnpkg.com/babylon/-/babylon-7.0.0-beta.40.tgz#91fc8cd56d5eb98b28e6fde41045f2957779940a" + +babylon@^6.18.0: + version "6.18.0" + resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.18.0.tgz#af2f3b88fa6f5c1e4c634d1a0f8eac4f55b395e3" + +balanced-match@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" + +bcrypt-pbkdf@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz#63bc5dcb61331b92bc05fd528953c33462a06f8d" + dependencies: + tweetnacl "^0.14.3" + +block-stream@*: + version "0.0.9" + resolved "https://registry.yarnpkg.com/block-stream/-/block-stream-0.0.9.tgz#13ebfe778a03205cfe03751481ebb4b3300c126a" + dependencies: + inherits "~2.0.0" + +boom@2.x.x: + version "2.10.1" + resolved "https://registry.yarnpkg.com/boom/-/boom-2.10.1.tgz#39c8918ceff5799f83f9492a848f625add0c766f" + dependencies: + hoek "2.x.x" + +boom@4.x.x: + version "4.3.1" + resolved "https://registry.yarnpkg.com/boom/-/boom-4.3.1.tgz#4f8a3005cb4a7e3889f749030fd25b96e01d2e31" + dependencies: + hoek "4.x.x" + +boom@5.x.x: + version "5.2.0" + resolved "https://registry.yarnpkg.com/boom/-/boom-5.2.0.tgz#5dd9da6ee3a5f302077436290cb717d3f4a54e02" + dependencies: + hoek "4.x.x" + +brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +braces@^1.8.2: + version "1.8.5" + resolved "https://registry.yarnpkg.com/braces/-/braces-1.8.5.tgz#ba77962e12dff969d6b76711e914b737857bf6a7" + dependencies: + expand-range "^1.8.1" + preserve "^0.2.0" + repeat-element "^1.1.2" + +bser@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/bser/-/bser-2.0.0.tgz#9ac78d3ed5d915804fd87acb158bc797147a1719" + dependencies: + node-int64 "^0.4.0" + +builtin-modules@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f" + +camelcase@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd" + +caseless@~0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" + +chalk@^1.1.1, chalk@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" + dependencies: + ansi-styles "^2.2.1" + escape-string-regexp "^1.0.2" + has-ansi "^2.0.0" + strip-ansi "^3.0.0" + supports-color "^2.0.0" + +chalk@^2.0.0: + version "2.3.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.3.2.tgz#250dc96b07491bfd601e648d66ddf5f60c7a5c65" + dependencies: + ansi-styles "^3.2.1" + escape-string-regexp "^1.0.5" + supports-color "^5.3.0" + +cliui@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-3.2.0.tgz#120601537a916d29940f934da3b48d585a39213d" + dependencies: + string-width "^1.0.1" + strip-ansi "^3.0.1" + wrap-ansi "^2.0.0" + +co@^4.6.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" + +code-point-at@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" + +color-convert@^1.9.0: + version "1.9.1" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.1.tgz#c1261107aeb2f294ebffec9ed9ecad529a6097ed" + dependencies: + color-name "^1.1.1" + +color-name@^1.1.1: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" + +combined-stream@1.0.6, combined-stream@^1.0.5, combined-stream@~1.0.5: + version "1.0.6" + resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.6.tgz#723e7df6e801ac5613113a7e445a9b69cb632818" + dependencies: + delayed-stream "~1.0.0" + +commander@~2.13.0: + version "2.13.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.13.0.tgz#6964bca67685df7c1f1430c584f07d7597885b9c" + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + +concat-stream@^1.6.0: + version "1.6.1" + resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.1.tgz#261b8f518301f1d834e36342b9fea095d2620a26" + dependencies: + inherits "^2.0.3" + readable-stream "^2.2.2" + typedarray "^0.0.6" + +connect@^3.6.5: + version "3.6.6" + resolved "https://registry.yarnpkg.com/connect/-/connect-3.6.6.tgz#09eff6c55af7236e137135a72574858b6786f524" + dependencies: + debug "2.6.9" + finalhandler "1.1.0" + parseurl "~1.3.2" + utils-merge "1.0.1" + +console-control-strings@^1.0.0, console-control-strings@~1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" + +convert-source-map@^1.1.0, convert-source-map@^1.5.0: + version "1.5.1" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.5.1.tgz#b8278097b9bc229365de5c62cf5fcaed8b5599e5" + +core-js@^1.0.0: + version "1.2.7" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-1.2.7.tgz#652294c14651db28fa93bd2d5ff2983a4f08c636" + +core-js@^2.2.2, core-js@^2.4.0, core-js@^2.5.0: + version "2.5.3" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.5.3.tgz#8acc38345824f16d8365b7c9b4259168e8ed603e" + +core-util-is@1.0.2, core-util-is@~1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" + +cross-spawn@^5.0.1: + version "5.1.0" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449" + dependencies: + lru-cache "^4.0.1" + shebang-command "^1.2.0" + which "^1.2.9" + +cryptiles@2.x.x: + version "2.0.5" + resolved "https://registry.yarnpkg.com/cryptiles/-/cryptiles-2.0.5.tgz#3bdfecdc608147c1c67202fa291e7dca59eaa3b8" + dependencies: + boom "2.x.x" + +cryptiles@3.x.x: + version "3.1.2" + resolved "https://registry.yarnpkg.com/cryptiles/-/cryptiles-3.1.2.tgz#a89fbb220f5ce25ec56e8c4aa8a4fd7b5b0d29fe" + dependencies: + boom "5.x.x" + +dashdash@^1.12.0: + version "1.14.1" + resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" + dependencies: + assert-plus "^1.0.0" + +debug@2.6.9, debug@^2.2.0, debug@^2.6.8: + version "2.6.9" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" + dependencies: + ms "2.0.0" + +debug@^3.0.1: + version "3.1.0" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" + dependencies: + ms "2.0.0" + +decamelize@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" + +deep-extend@~0.4.0: + version "0.4.2" + resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.4.2.tgz#48b699c27e334bf89f10892be432f6e4c7d34a7f" + +delayed-stream@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" + +delegates@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" + +denodeify@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/denodeify/-/denodeify-1.2.1.tgz#3a36287f5034e699e7577901052c2e6c94251631" + +detect-indent@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-4.0.0.tgz#f76d064352cdf43a1cb6ce619c4ee3a9475de208" + dependencies: + repeating "^2.0.0" + +detect-libc@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b" + +detect-newline@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-2.1.0.tgz#f41f1c10be4b00e87b5f13da680759f2c5bfd3e2" + +dom-walk@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/dom-walk/-/dom-walk-0.1.1.tgz#672226dc74c8f799ad35307df936aba11acd6018" + +ecc-jsbn@~0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz#0fc73a9ed5f0d53c38193398523ef7e543777505" + dependencies: + jsbn "~0.1.0" + +ee-first@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" + +encodeurl@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" + +encoding@^0.1.11: + version "0.1.12" + resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.12.tgz#538b66f3ee62cd1ab51ec323829d1f9480c74beb" + dependencies: + iconv-lite "~0.4.13" + +error-ex@^1.2.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.1.tgz#f855a86ce61adc4e8621c3cda21e7a7612c3a8dc" + dependencies: + is-arrayish "^0.2.1" + +escape-html@~1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" + +escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + +esutils@^2.0.0, esutils@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b" + +eventemitter3@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-3.0.1.tgz#4ce66c3fc5b5a6b9f2245e359e1938f1ab10f960" + +exec-sh@^0.2.0: + version "0.2.1" + resolved "https://registry.yarnpkg.com/exec-sh/-/exec-sh-0.2.1.tgz#163b98a6e89e6b65b47c2a28d215bc1f63989c38" + dependencies: + merge "^1.1.3" + +execa@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-0.7.0.tgz#944becd34cc41ee32a63a9faf27ad5a65fc59777" + dependencies: + cross-spawn "^5.0.1" + get-stream "^3.0.0" + is-stream "^1.1.0" + npm-run-path "^2.0.0" + p-finally "^1.0.0" + signal-exit "^3.0.0" + strip-eof "^1.0.0" + +expand-brackets@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-0.1.5.tgz#df07284e342a807cd733ac5af72411e581d1177b" + dependencies: + is-posix-bracket "^0.1.0" + +expand-range@^1.8.1: + version "1.8.2" + resolved "https://registry.yarnpkg.com/expand-range/-/expand-range-1.8.2.tgz#a299effd335fe2721ebae8e257ec79644fc85337" + dependencies: + fill-range "^2.1.0" + +extend@~3.0.0, extend@~3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.1.tgz#a755ea7bc1adfcc5a31ce7e762dbaadc5e636444" + +extglob@^0.3.1: + version "0.3.2" + resolved "https://registry.yarnpkg.com/extglob/-/extglob-0.3.2.tgz#2e18ff3d2f49ab2765cec9023f011daa8d8349a1" + dependencies: + is-extglob "^1.0.0" + +extsprintf@1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" + +extsprintf@^1.2.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f" + +fast-deep-equal@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz#c053477817c86b51daa853c81e059b733d023614" + +fast-json-stable-stringify@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2" + +fb-watchman@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/fb-watchman/-/fb-watchman-2.0.0.tgz#54e9abf7dfa2f26cd9b1636c588c1afc05de5d58" + dependencies: + bser "^2.0.0" + +fbjs@^0.8.14: + version "0.8.16" + resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.8.16.tgz#5e67432f550dc41b572bf55847b8aca64e5337db" + dependencies: + core-js "^1.0.0" + isomorphic-fetch "^2.1.1" + loose-envify "^1.0.0" + object-assign "^4.1.0" + promise "^7.1.1" + setimmediate "^1.0.5" + ua-parser-js "^0.7.9" + +filename-regex@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/filename-regex/-/filename-regex-2.0.1.tgz#c1c4b9bee3e09725ddb106b75c1e301fe2f18b26" + +fill-range@^2.1.0: + version "2.2.3" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-2.2.3.tgz#50b77dfd7e469bc7492470963699fe7a8485a723" + dependencies: + is-number "^2.1.0" + isobject "^2.0.0" + randomatic "^1.1.3" + repeat-element "^1.1.2" + repeat-string "^1.5.2" + +finalhandler@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.0.tgz#ce0b6855b45853e791b2fcc680046d88253dd7f5" + dependencies: + debug "2.6.9" + encodeurl "~1.0.1" + escape-html "~1.0.3" + on-finished "~2.3.0" + parseurl "~1.3.2" + statuses "~1.3.1" + unpipe "~1.0.0" + +find-up@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" + dependencies: + locate-path "^2.0.0" + +for-in@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" + +for-own@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/for-own/-/for-own-0.1.5.tgz#5265c681a4f294dabbf17c9509b6763aa84510ce" + dependencies: + for-in "^1.0.1" + +forever-agent@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" + +form-data@~2.1.1: + version "2.1.4" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.1.4.tgz#33c183acf193276ecaa98143a69e94bfee1750d1" + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.5" + mime-types "^2.1.12" + +form-data@~2.3.1: + version "2.3.2" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.2.tgz#4970498be604c20c005d4f5c23aecd21d6b49099" + dependencies: + asynckit "^0.4.0" + combined-stream "1.0.6" + mime-types "^2.1.12" + +fs-extra@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-1.0.0.tgz#cd3ce5f7e7cb6145883fcae3191e9877f8587950" + dependencies: + graceful-fs "^4.1.2" + jsonfile "^2.1.0" + klaw "^1.0.0" + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + +fsevents@^1.1.1: + version "1.1.3" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.1.3.tgz#11f82318f5fe7bb2cd22965a108e9306208216d8" + dependencies: + nan "^2.3.0" + node-pre-gyp "^0.6.39" + +fstream-ignore@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/fstream-ignore/-/fstream-ignore-1.0.5.tgz#9c31dae34767018fe1d249b24dada67d092da105" + dependencies: + fstream "^1.0.0" + inherits "2" + minimatch "^3.0.0" + +fstream@^1.0.0, fstream@^1.0.10, fstream@^1.0.2: + version "1.0.11" + resolved "https://registry.yarnpkg.com/fstream/-/fstream-1.0.11.tgz#5c1fb1f117477114f0632a0eb4b71b3cb0fd3171" + dependencies: + graceful-fs "^4.1.2" + inherits "~2.0.0" + mkdirp ">=0.5 0" + rimraf "2" + +gauge@~2.7.3: + version "2.7.4" + resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7" + dependencies: + aproba "^1.0.3" + console-control-strings "^1.0.0" + has-unicode "^2.0.0" + object-assign "^4.1.0" + signal-exit "^3.0.0" + string-width "^1.0.1" + strip-ansi "^3.0.1" + wide-align "^1.1.0" + +get-caller-file@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.2.tgz#f702e63127e7e231c160a80c1554acb70d5047e5" + +get-stream@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" + +getpass@^0.1.1: + version "0.1.7" + resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" + dependencies: + assert-plus "^1.0.0" + +glob-base@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/glob-base/-/glob-base-0.3.0.tgz#dbb164f6221b1c0b1ccf82aea328b497df0ea3c4" + dependencies: + glob-parent "^2.0.0" + is-glob "^2.0.0" + +glob-parent@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-2.0.0.tgz#81383d72db054fcccf5336daa902f182f6edbb28" + dependencies: + is-glob "^2.0.0" + +glob@^7.0.5: + version "7.1.2" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15" + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + +global@^4.3.0: + version "4.3.2" + resolved "https://registry.yarnpkg.com/global/-/global-4.3.2.tgz#e76989268a6c74c38908b1305b10fc0e394e9d0f" + dependencies: + min-document "^2.19.0" + process "~0.5.1" + +globals@^10.0.0: + version "10.4.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-10.4.0.tgz#5c477388b128a9e4c5c5d01c7a2aca68c68b2da7" + +globals@^11.1.0: + version "11.3.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-11.3.0.tgz#e04fdb7b9796d8adac9c8f64c14837b2313378b0" + +globals@^9.18.0: + version "9.18.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-9.18.0.tgz#aa3896b3e69b487f17e31ed2143d69a8e30c2d8a" + +graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.3, graceful-fs@^4.1.6, graceful-fs@^4.1.9: + version "4.1.11" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658" + +har-schema@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-1.0.5.tgz#d263135f43307c02c602afc8fe95970c0151369e" + +har-schema@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" + +har-validator@~4.2.1: + version "4.2.1" + resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-4.2.1.tgz#33481d0f1bbff600dd203d75812a6a5fba002e2a" + dependencies: + ajv "^4.9.1" + har-schema "^1.0.5" + +har-validator@~5.0.3: + version "5.0.3" + resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.0.3.tgz#ba402c266194f15956ef15e0fcf242993f6a7dfd" + dependencies: + ajv "^5.1.0" + har-schema "^2.0.0" + +has-ansi@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" + dependencies: + ansi-regex "^2.0.0" + +has-flag@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" + +has-unicode@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" + +hawk@3.1.3, hawk@~3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/hawk/-/hawk-3.1.3.tgz#078444bd7c1640b0fe540d2c9b73d59678e8e1c4" + dependencies: + boom "2.x.x" + cryptiles "2.x.x" + hoek "2.x.x" + sntp "1.x.x" + +hawk@~6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/hawk/-/hawk-6.0.2.tgz#af4d914eb065f9b5ce4d9d11c1cb2126eecc3038" + dependencies: + boom "4.x.x" + cryptiles "3.x.x" + hoek "4.x.x" + sntp "2.x.x" + +hoek@2.x.x: + version "2.16.3" + resolved "https://registry.yarnpkg.com/hoek/-/hoek-2.16.3.tgz#20bb7403d3cea398e91dc4710a8ff1b8274a25ed" + +hoek@4.x.x: + version "4.2.1" + resolved "https://registry.yarnpkg.com/hoek/-/hoek-4.2.1.tgz#9634502aa12c445dd5a7c5734b572bb8738aacbb" + +home-or-tmp@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/home-or-tmp/-/home-or-tmp-2.0.0.tgz#e36c3f2d2cae7d746a857e38d18d5f32a7882db8" + dependencies: + os-homedir "^1.0.0" + os-tmpdir "^1.0.1" + +hosted-git-info@^2.1.4: + version "2.5.0" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.5.0.tgz#6d60e34b3abbc8313062c3b798ef8d901a07af3c" + +http-signature@~1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.1.1.tgz#df72e267066cd0ac67fb76adf8e134a8fbcf91bf" + dependencies: + assert-plus "^0.2.0" + jsprim "^1.2.2" + sshpk "^1.7.0" + +http-signature@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" + dependencies: + assert-plus "^1.0.0" + jsprim "^1.2.2" + sshpk "^1.7.0" + +iconv-lite@~0.4.13: + version "0.4.19" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.19.tgz#f7468f60135f5e5dad3399c0a81be9a1603a082b" + +image-size@^0.6.0: + version "0.6.2" + resolved "https://registry.yarnpkg.com/image-size/-/image-size-0.6.2.tgz#8ee316d4298b028b965091b673d5f1537adee5b4" + +imurmurhash@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2, inherits@^2.0.3, inherits@~2.0.0, inherits@~2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" + +ini@~1.3.0: + version "1.3.5" + resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" + +invariant@^2.2.0, invariant@^2.2.2: + version "2.2.3" + resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.3.tgz#1a827dfde7dcbd7c323f0ca826be8fa7c5e9d688" + dependencies: + loose-envify "^1.0.0" + +invert-kv@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-1.0.0.tgz#104a8e4aaca6d3d8cd157a8ef8bfab2d7a3ffdb6" + +is-arrayish@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" + +is-buffer@^1.1.5: + version "1.1.6" + resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" + +is-builtin-module@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-builtin-module/-/is-builtin-module-1.0.0.tgz#540572d34f7ac3119f8f76c30cbc1b1e037affbe" + dependencies: + builtin-modules "^1.0.0" + +is-dotfile@^1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/is-dotfile/-/is-dotfile-1.0.3.tgz#a6a2f32ffd2dfb04f5ca25ecd0f6b83cf798a1e1" + +is-equal-shallow@^0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz#2238098fc221de0bcfa5d9eac4c45d638aa1c534" + dependencies: + is-primitive "^2.0.0" + +is-extendable@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" + +is-extglob@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-1.0.0.tgz#ac468177c4943405a092fc8f29760c6ffc6206c0" + +is-finite@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-finite/-/is-finite-1.0.2.tgz#cc6677695602be550ef11e8b4aa6305342b6d0aa" + dependencies: + number-is-nan "^1.0.0" + +is-fullwidth-code-point@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" + dependencies: + number-is-nan "^1.0.0" + +is-fullwidth-code-point@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" + +is-glob@^2.0.0, is-glob@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-2.0.1.tgz#d096f926a3ded5600f3fdfd91198cb0888c2d863" + dependencies: + is-extglob "^1.0.0" + +is-number@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-2.1.0.tgz#01fcbbb393463a548f2f466cce16dece49db908f" + dependencies: + kind-of "^3.0.2" + +is-number@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" + dependencies: + kind-of "^3.0.2" + +is-posix-bracket@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz#3334dc79774368e92f016e6fbc0a88f5cd6e6bc4" + +is-primitive@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-primitive/-/is-primitive-2.0.0.tgz#207bab91638499c07b2adf240a41a87210034575" + +is-stream@^1.0.1, is-stream@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" + +is-typedarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" + +isarray@1.0.0, isarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + +isobject@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" + dependencies: + isarray "1.0.0" + +isomorphic-fetch@^2.1.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz#611ae1acf14f5e81f729507472819fe9733558a9" + dependencies: + node-fetch "^1.0.1" + whatwg-fetch ">=0.10.0" + +isstream@~0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" + +jest-docblock@22.4.0, jest-docblock@^22.4.0: + version "22.4.0" + resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-22.4.0.tgz#dbf1877e2550070cfc4d9b07a55775a0483159b8" + dependencies: + detect-newline "^2.1.0" + +jest-haste-map@22.4.2: + version "22.4.2" + resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-22.4.2.tgz#a90178e66146d4378bb076345a949071f3b015b4" + dependencies: + fb-watchman "^2.0.0" + graceful-fs "^4.1.11" + jest-docblock "^22.4.0" + jest-serializer "^22.4.0" + jest-worker "^22.2.2" + micromatch "^2.3.11" + sane "^2.0.0" + +jest-serializer@^22.4.0: + version "22.4.0" + resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-22.4.0.tgz#b5d145b98c4b0d2c20ab686609adbb81fe23b566" + +jest-worker@22.2.2, jest-worker@^22.2.2: + version "22.2.2" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-22.2.2.tgz#c1f5dc39976884b81f68ec50cb8532b2cbab3390" + dependencies: + merge-stream "^1.0.1" + +js-tokens@^3.0.0, js-tokens@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" + +jsbn@~0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" + +jsesc@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-1.3.0.tgz#46c3fec8c1892b12b0833db9bc7622176dbab34b" + +jsesc@^2.5.1: + version "2.5.1" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.1.tgz#e421a2a8e20d6b0819df28908f782526b96dd1fe" + +jsesc@~0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" + +json-schema-traverse@^0.3.0: + version "0.3.1" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz#349a6d44c53a51de89b40805c5d5e59b417d3340" + +json-schema@0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" + +json-stable-stringify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz#9a759d39c5f2ff503fd5300646ed445f88c4f9af" + dependencies: + jsonify "~0.0.0" + +json-stringify-safe@~5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" + +json5@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/json5/-/json5-0.4.0.tgz#054352e4c4c80c86c0923877d449de176a732c8d" + +json5@^0.5.0, json5@^0.5.1: + version "0.5.1" + resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821" + +jsonfile@^2.1.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-2.4.0.tgz#3736a2b428b87bbda0cc83b53fa3d633a35c2ae8" + optionalDependencies: + graceful-fs "^4.1.6" + +jsonify@~0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73" + +jsprim@^1.2.2: + version "1.4.1" + resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" + dependencies: + assert-plus "1.0.0" + extsprintf "1.3.0" + json-schema "0.2.3" + verror "1.10.0" + +kind-of@^3.0.2: + version "3.2.2" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" + dependencies: + is-buffer "^1.1.5" + +kind-of@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-4.0.0.tgz#20813df3d712928b207378691a45066fae72dd57" + dependencies: + is-buffer "^1.1.5" + +klaw@^1.0.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/klaw/-/klaw-1.3.1.tgz#4088433b46b3b1ba259d78785d8e96f73ba02439" + optionalDependencies: + graceful-fs "^4.1.9" + +lcid@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/lcid/-/lcid-1.0.0.tgz#308accafa0bc483a3867b4b6f2b9506251d1b835" + dependencies: + invert-kv "^1.0.0" + +left-pad@^1.1.3: + version "1.2.0" + resolved "https://registry.yarnpkg.com/left-pad/-/left-pad-1.2.0.tgz#d30a73c6b8201d8f7d8e7956ba9616087a68e0ee" + +load-json-file@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-2.0.0.tgz#7947e42149af80d696cbf797bcaabcfe1fe29ca8" + dependencies: + graceful-fs "^4.1.2" + parse-json "^2.2.0" + pify "^2.0.0" + strip-bom "^3.0.0" + +locate-path@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" + dependencies: + p-locate "^2.0.0" + path-exists "^3.0.0" + +lodash.throttle@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/lodash.throttle/-/lodash.throttle-4.1.1.tgz#c23e91b710242ac70c37f1e1cda9274cc39bf2f4" + +lodash@^4.14.0, lodash@^4.17.4, lodash@^4.2.0, lodash@^4.6.1: + version "4.17.5" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.5.tgz#99a92d65c0272debe8c96b6057bc8fbfa3bed511" + +loose-envify@^1.0.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.3.1.tgz#d1a8ad33fa9ce0e713d65fdd0ac8b748d478c848" + dependencies: + js-tokens "^3.0.0" + +lru-cache@^4.0.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.1.tgz#622e32e82488b49279114a4f9ecf45e7cd6bba55" + dependencies: + pseudomap "^1.0.2" + yallist "^2.1.2" + +makeerror@1.0.x: + version "1.0.11" + resolved "https://registry.yarnpkg.com/makeerror/-/makeerror-1.0.11.tgz#e01a5c9109f2af79660e4e8b9587790184f5a96c" + dependencies: + tmpl "1.0.x" + +mem@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/mem/-/mem-1.1.0.tgz#5edd52b485ca1d900fe64895505399a0dfa45f76" + dependencies: + mimic-fn "^1.0.0" + +merge-stream@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-1.0.1.tgz#4041202d508a342ba00174008df0c251b8c135e1" + dependencies: + readable-stream "^2.0.1" + +merge@^1.1.3: + version "1.2.0" + resolved "https://registry.yarnpkg.com/merge/-/merge-1.2.0.tgz#7531e39d4949c281a66b8c5a6e0265e8b05894da" + +metro-babylon7@0.28.0: + version "0.28.0" + resolved "https://registry.yarnpkg.com/metro-babylon7/-/metro-babylon7-0.28.0.tgz#cf9701ffdc1992d1562b4cb667d9692164950df4" + dependencies: + babylon "^7.0.0-beta" + +metro-cache@0.28.0: + version "0.28.0" + resolved "https://registry.yarnpkg.com/metro-cache/-/metro-cache-0.28.0.tgz#c5164a361985fc0294059fccdf4ea824e3173c1d" + dependencies: + jest-serializer "^22.4.0" + mkdirp "^0.5.1" + +metro-core@0.28.0: + version "0.28.0" + resolved "https://registry.yarnpkg.com/metro-core/-/metro-core-0.28.0.tgz#e1ced4cf07ca8fb5196a6e5ca853b5d893f06038" + dependencies: + lodash.throttle "^4.1.1" + +metro-minify-uglify@0.28.0: + version "0.28.0" + resolved "https://registry.yarnpkg.com/metro-minify-uglify/-/metro-minify-uglify-0.28.0.tgz#c9aecb8e893430d2fd58e00cf799c00b99dc0f79" + dependencies: + uglify-es "^3.1.9" + +metro-resolver@0.28.0: + version "0.28.0" + resolved "https://registry.yarnpkg.com/metro-resolver/-/metro-resolver-0.28.0.tgz#813802d60fc762772927c81d02e01c7eec84bad8" + dependencies: + absolute-path "^0.0.0" + +metro-source-map@0.28.0: + version "0.28.0" + resolved "https://registry.yarnpkg.com/metro-source-map/-/metro-source-map-0.28.0.tgz#ec8c3161d8516ad3c4e7149f2c3d4802f4fd6fa2" + dependencies: + source-map "^0.5.6" + +metro@^0.28.0: + version "0.28.0" + resolved "https://registry.yarnpkg.com/metro/-/metro-0.28.0.tgz#22999c96c3129682a76acd4e1f2adc17f7d77cac" + dependencies: + "@babel/core" "^7.0.0-beta" + "@babel/generator" "^7.0.0-beta" + "@babel/helper-remap-async-to-generator" "^7.0.0-beta" + "@babel/plugin-check-constants" "^7.0.0-beta" + "@babel/plugin-external-helpers" "^7.0.0-beta" + "@babel/plugin-proposal-class-properties" "^7.0.0-beta" + "@babel/plugin-proposal-object-rest-spread" "^7.0.0-beta" + "@babel/plugin-syntax-dynamic-import" "^7.0.0-beta" + "@babel/plugin-transform-arrow-functions" "^7.0.0-beta" + "@babel/plugin-transform-block-scoping" "^7.0.0-beta" + "@babel/plugin-transform-classes" "^7.0.0-beta" + "@babel/plugin-transform-computed-properties" "^7.0.0-beta" + "@babel/plugin-transform-destructuring" "^7.0.0-beta" + "@babel/plugin-transform-flow-strip-types" "^7.0.0-beta" + "@babel/plugin-transform-for-of" "^7.0.0-beta" + "@babel/plugin-transform-function-name" "^7.0.0-beta" + "@babel/plugin-transform-literals" "^7.0.0-beta" + "@babel/plugin-transform-modules-commonjs" "^7.0.0-beta" + "@babel/plugin-transform-object-assign" "^7.0.0-beta" + "@babel/plugin-transform-parameters" "^7.0.0-beta" + "@babel/plugin-transform-react-display-name" "^7.0.0-beta" + "@babel/plugin-transform-react-jsx" "^7.0.0-beta" + "@babel/plugin-transform-react-jsx-source" "^7.0.0-beta" + "@babel/plugin-transform-regenerator" "^7.0.0-beta" + "@babel/plugin-transform-shorthand-properties" "^7.0.0-beta" + "@babel/plugin-transform-spread" "^7.0.0-beta" + "@babel/plugin-transform-template-literals" "^7.0.0-beta" + "@babel/template" "^7.0.0-beta" + "@babel/traverse" "^7.0.0-beta" + "@babel/types" "^7.0.0-beta" + absolute-path "^0.0.0" + async "^2.4.0" + babel-core "^6.24.1" + babel-generator "^6.26.0" + babel-plugin-external-helpers "^6.22.0" + babel-preset-es2015-node "^6.1.1" + babel-preset-fbjs "^2.1.4" + babel-preset-react-native "^4.0.0" + babel-register "^6.24.1" + babylon "^6.18.0" + chalk "^1.1.1" + concat-stream "^1.6.0" + connect "^3.6.5" + core-js "^2.2.2" + debug "^2.2.0" + denodeify "^1.2.1" + eventemitter3 "^3.0.0" + fbjs "^0.8.14" + fs-extra "^1.0.0" + graceful-fs "^4.1.3" + image-size "^0.6.0" + jest-docblock "22.4.0" + jest-haste-map "22.4.2" + jest-worker "22.2.2" + json-stable-stringify "^1.0.1" + json5 "^0.4.0" + left-pad "^1.1.3" + lodash.throttle "^4.1.1" + merge-stream "^1.0.1" + metro-babylon7 "0.28.0" + metro-cache "0.28.0" + metro-core "0.28.0" + metro-minify-uglify "0.28.0" + metro-resolver "0.28.0" + metro-source-map "0.28.0" + mime-types "2.1.11" + mkdirp "^0.5.1" + request "^2.79.0" + rimraf "^2.5.4" + serialize-error "^2.1.0" + source-map "^0.5.6" + temp "0.8.3" + throat "^4.1.0" + wordwrap "^1.0.0" + write-file-atomic "^1.2.0" + ws "^1.1.0" + xpipe "^1.0.5" + yargs "^9.0.0" + +micromatch@^2.1.5, micromatch@^2.3.11: + version "2.3.11" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-2.3.11.tgz#86677c97d1720b363431d04d0d15293bd38c1565" + dependencies: + arr-diff "^2.0.0" + array-unique "^0.2.1" + braces "^1.8.2" + expand-brackets "^0.1.4" + extglob "^0.3.1" + filename-regex "^2.0.0" + is-extglob "^1.0.0" + is-glob "^2.0.1" + kind-of "^3.0.2" + normalize-path "^2.0.1" + object.omit "^2.0.0" + parse-glob "^3.0.4" + regex-cache "^0.4.2" + +mime-db@~1.23.0: + version "1.23.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.23.0.tgz#a31b4070adaea27d732ea333740a64d0ec9a6659" + +mime-db@~1.33.0: + version "1.33.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.33.0.tgz#a3492050a5cb9b63450541e39d9788d2272783db" + +mime-types@2.1.11: + version "2.1.11" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.11.tgz#c259c471bda808a85d6cd193b430a5fae4473b3c" + dependencies: + mime-db "~1.23.0" + +mime-types@^2.1.12, mime-types@~2.1.17, mime-types@~2.1.7: + version "2.1.18" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.18.tgz#6f323f60a83d11146f831ff11fd66e2fe5503bb8" + dependencies: + mime-db "~1.33.0" + +mimic-fn@^1.0.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022" + +min-document@^2.19.0: + version "2.19.0" + resolved "https://registry.yarnpkg.com/min-document/-/min-document-2.19.0.tgz#7bd282e3f5842ed295bb748cdd9f1ffa2c824685" + dependencies: + dom-walk "^0.1.0" + +minimatch@^3.0.0, minimatch@^3.0.2, minimatch@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" + dependencies: + brace-expansion "^1.1.7" + +minimist@0.0.8: + version "0.0.8" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" + +minimist@^1.1.1, minimist@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" + +"mkdirp@>=0.5 0", mkdirp@^0.5.1: + version "0.5.1" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" + dependencies: + minimist "0.0.8" + +ms@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + +nan@^2.3.0: + version "2.9.2" + resolved "https://registry.yarnpkg.com/nan/-/nan-2.9.2.tgz#f564d75f5f8f36a6d9456cca7a6c4fe488ab7866" + +node-fetch@^1.0.1: + version "1.7.3" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-1.7.3.tgz#980f6f72d85211a5347c6b2bc18c5b84c3eb47ef" + dependencies: + encoding "^0.1.11" + is-stream "^1.0.1" + +node-int64@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" + +node-pre-gyp@^0.6.39: + version "0.6.39" + resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.6.39.tgz#c00e96860b23c0e1420ac7befc5044e1d78d8649" + dependencies: + detect-libc "^1.0.2" + hawk "3.1.3" + mkdirp "^0.5.1" + nopt "^4.0.1" + npmlog "^4.0.2" + rc "^1.1.7" + request "2.81.0" + rimraf "^2.6.1" + semver "^5.3.0" + tar "^2.2.1" + tar-pack "^3.4.0" + +nopt@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.1.tgz#d0d4685afd5415193c8c7505602d0d17cd64474d" + dependencies: + abbrev "1" + osenv "^0.1.4" + +normalize-package-data@^2.3.2: + version "2.4.0" + resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.4.0.tgz#12f95a307d58352075a04907b84ac8be98ac012f" + dependencies: + hosted-git-info "^2.1.4" + is-builtin-module "^1.0.0" + semver "2 || 3 || 4 || 5" + validate-npm-package-license "^3.0.1" + +normalize-path@^2.0.0, normalize-path@^2.0.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" + dependencies: + remove-trailing-separator "^1.0.1" + +npm-run-path@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f" + dependencies: + path-key "^2.0.0" + +npmlog@^4.0.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" + dependencies: + are-we-there-yet "~1.1.2" + console-control-strings "~1.1.0" + gauge "~2.7.3" + set-blocking "~2.0.0" + +number-is-nan@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" + +oauth-sign@~0.8.1, oauth-sign@~0.8.2: + version "0.8.2" + resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.8.2.tgz#46a6ab7f0aead8deae9ec0565780b7d4efeb9d43" + +object-assign@^4.1.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + +object.omit@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/object.omit/-/object.omit-2.0.1.tgz#1a9c744829f39dbb858c76ca3579ae2a54ebd1fa" + dependencies: + for-own "^0.1.4" + is-extendable "^0.1.1" + +on-finished@~2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" + dependencies: + ee-first "1.1.1" + +once@^1.3.0, once@^1.3.3: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + dependencies: + wrappy "1" + +options@>=0.0.5: + version "0.0.6" + resolved "https://registry.yarnpkg.com/options/-/options-0.0.6.tgz#ec22d312806bb53e731773e7cdaefcf1c643128f" + +os-homedir@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" + +os-locale@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-2.1.0.tgz#42bc2900a6b5b8bd17376c8e882b65afccf24bf2" + dependencies: + execa "^0.7.0" + lcid "^1.0.0" + mem "^1.1.0" + +os-tmpdir@^1.0.0, os-tmpdir@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" + +osenv@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.5.tgz#85cdfafaeb28e8677f416e287592b5f3f49ea410" + dependencies: + os-homedir "^1.0.0" + os-tmpdir "^1.0.0" + +p-finally@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" + +p-limit@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.2.0.tgz#0e92b6bedcb59f022c13d0f1949dc82d15909f1c" + dependencies: + p-try "^1.0.0" + +p-locate@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" + dependencies: + p-limit "^1.1.0" + +p-try@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" + +parse-glob@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/parse-glob/-/parse-glob-3.0.4.tgz#b2c376cfb11f35513badd173ef0bb6e3a388391c" + dependencies: + glob-base "^0.3.0" + is-dotfile "^1.0.0" + is-extglob "^1.0.0" + is-glob "^2.0.0" + +parse-json@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9" + dependencies: + error-ex "^1.2.0" + +parseurl@~1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.2.tgz#fc289d4ed8993119460c156253262cdc8de65bf3" + +path-exists@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" + +path-is-absolute@^1.0.0, path-is-absolute@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + +path-key@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" + +path-parse@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.5.tgz#3c1adf871ea9cd6c9431b6ea2bd74a0ff055c4c1" + +path-type@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-2.0.0.tgz#f012ccb8415b7096fc2daa1054c3d72389594c73" + dependencies: + pify "^2.0.0" + +performance-now@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-0.2.0.tgz#33ef30c5c77d4ea21c5a53869d91b56d8f2555e5" + +performance-now@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" + +pify@^2.0.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" + +preserve@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b" + +private@^0.1.6, private@^0.1.7: + version "0.1.8" + resolved "https://registry.yarnpkg.com/private/-/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff" + +process-nextick-args@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.0.tgz#a37d732f4271b4ab1ad070d35508e8290788ffaa" + +process@~0.5.1: + version "0.5.2" + resolved "https://registry.yarnpkg.com/process/-/process-0.5.2.tgz#1638d8a8e34c2f440a91db95ab9aeb677fc185cf" + +promise@^7.1.1: + version "7.3.1" + resolved "https://registry.yarnpkg.com/promise/-/promise-7.3.1.tgz#064b72602b18f90f29192b8b1bc418ffd1ebd3bf" + dependencies: + asap "~2.0.3" + +pseudomap@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" + +punycode@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" + +qs@~6.4.0: + version "6.4.0" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.4.0.tgz#13e26d28ad6b0ffaa91312cd3bf708ed351e7233" + +qs@~6.5.1: + version "6.5.1" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.1.tgz#349cdf6eef89ec45c12d7d5eb3fc0c870343a6d8" + +randomatic@^1.1.3: + version "1.1.7" + resolved "https://registry.yarnpkg.com/randomatic/-/randomatic-1.1.7.tgz#c7abe9cc8b87c0baa876b19fde83fd464797e38c" + dependencies: + is-number "^3.0.0" + kind-of "^4.0.0" + +rc@^1.1.7: + version "1.2.5" + resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.5.tgz#275cd687f6e3b36cc756baa26dfee80a790301fd" + dependencies: + deep-extend "~0.4.0" + ini "~1.3.0" + minimist "^1.2.0" + strip-json-comments "~2.0.1" + +react-deep-force-update@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/react-deep-force-update/-/react-deep-force-update-1.1.1.tgz#bcd31478027b64b3339f108921ab520b4313dc2c" + +react-proxy@^1.1.7: + version "1.1.8" + resolved "https://registry.yarnpkg.com/react-proxy/-/react-proxy-1.1.8.tgz#9dbfd9d927528c3aa9f444e4558c37830ab8c26a" + dependencies: + lodash "^4.6.1" + react-deep-force-update "^1.0.0" + +react-transform-hmr@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/react-transform-hmr/-/react-transform-hmr-1.0.4.tgz#e1a40bd0aaefc72e8dfd7a7cda09af85066397bb" + dependencies: + global "^4.3.0" + react-proxy "^1.1.7" + +read-pkg-up@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-2.0.0.tgz#6b72a8048984e0c41e79510fd5e9fa99b3b549be" + dependencies: + find-up "^2.0.0" + read-pkg "^2.0.0" + +read-pkg@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-2.0.0.tgz#8ef1c0623c6a6db0dc6713c4bfac46332b2368f8" + dependencies: + load-json-file "^2.0.0" + normalize-package-data "^2.3.2" + path-type "^2.0.0" + +readable-stream@^2.0.1, readable-stream@^2.0.6, readable-stream@^2.1.4, readable-stream@^2.2.2: + version "2.3.5" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.5.tgz#b4f85003a938cbb6ecbce2a124fb1012bd1a838d" + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.3" + isarray "~1.0.0" + process-nextick-args "~2.0.0" + safe-buffer "~5.1.1" + string_decoder "~1.0.3" + util-deprecate "~1.0.1" + +regenerate@^1.2.1: + version "1.3.3" + resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.3.3.tgz#0c336d3980553d755c39b586ae3b20aa49c82b7f" + +regenerator-runtime@^0.11.0: + version "0.11.1" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9" + +regenerator-transform@^0.10.0: + version "0.10.1" + resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.10.1.tgz#1e4996837231da8b7f3cf4114d71b5691a0680dd" + dependencies: + babel-runtime "^6.18.0" + babel-types "^6.19.0" + private "^0.1.6" + +regenerator-transform@^0.12.3: + version "0.12.3" + resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.12.3.tgz#459adfb64f6a27164ab991b7873f45ab969eca8b" + dependencies: + private "^0.1.6" + +regex-cache@^0.4.2: + version "0.4.4" + resolved "https://registry.yarnpkg.com/regex-cache/-/regex-cache-0.4.4.tgz#75bdc58a2a1496cec48a12835bc54c8d562336dd" + dependencies: + is-equal-shallow "^0.1.3" + +regexpu-core@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-2.0.0.tgz#49d038837b8dcf8bfa5b9a42139938e6ea2ae240" + dependencies: + regenerate "^1.2.1" + regjsgen "^0.2.0" + regjsparser "^0.1.4" + +regjsgen@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.2.0.tgz#6c016adeac554f75823fe37ac05b92d5a4edb1f7" + +regjsparser@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.1.5.tgz#7ee8f84dc6fa792d3fd0ae228d24bd949ead205c" + dependencies: + jsesc "~0.5.0" + +remove-trailing-separator@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" + +repeat-element@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.2.tgz#ef089a178d1483baae4d93eb98b4f9e4e11d990a" + +repeat-string@^1.5.2: + version "1.6.1" + resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" + +repeating@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/repeating/-/repeating-2.0.1.tgz#5214c53a926d3552707527fbab415dbc08d06dda" + dependencies: + is-finite "^1.0.0" + +request@2.81.0: + version "2.81.0" + resolved "https://registry.yarnpkg.com/request/-/request-2.81.0.tgz#c6928946a0e06c5f8d6f8a9333469ffda46298a0" + dependencies: + aws-sign2 "~0.6.0" + aws4 "^1.2.1" + caseless "~0.12.0" + combined-stream "~1.0.5" + extend "~3.0.0" + forever-agent "~0.6.1" + form-data "~2.1.1" + har-validator "~4.2.1" + hawk "~3.1.3" + http-signature "~1.1.0" + is-typedarray "~1.0.0" + isstream "~0.1.2" + json-stringify-safe "~5.0.1" + mime-types "~2.1.7" + oauth-sign "~0.8.1" + performance-now "^0.2.0" + qs "~6.4.0" + safe-buffer "^5.0.1" + stringstream "~0.0.4" + tough-cookie "~2.3.0" + tunnel-agent "^0.6.0" + uuid "^3.0.0" + +request@^2.79.0: + version "2.83.0" + resolved "https://registry.yarnpkg.com/request/-/request-2.83.0.tgz#ca0b65da02ed62935887808e6f510381034e3356" + dependencies: + aws-sign2 "~0.7.0" + aws4 "^1.6.0" + caseless "~0.12.0" + combined-stream "~1.0.5" + extend "~3.0.1" + forever-agent "~0.6.1" + form-data "~2.3.1" + har-validator "~5.0.3" + hawk "~6.0.2" + http-signature "~1.2.0" + is-typedarray "~1.0.0" + isstream "~0.1.2" + json-stringify-safe "~5.0.1" + mime-types "~2.1.17" + oauth-sign "~0.8.2" + performance-now "^2.1.0" + qs "~6.5.1" + safe-buffer "^5.1.1" + stringstream "~0.0.5" + tough-cookie "~2.3.3" + tunnel-agent "^0.6.0" + uuid "^3.1.0" + +require-directory@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" + +require-main-filename@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1" + +resolve@^1.3.2: + version "1.5.0" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.5.0.tgz#1f09acce796c9a762579f31b2c1cc4c3cddf9f36" + dependencies: + path-parse "^1.0.5" + +rimraf@2, rimraf@^2.5.1, rimraf@^2.5.4, rimraf@^2.6.1: + version "2.6.2" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.2.tgz#2ed8150d24a16ea8651e6d6ef0f47c4158ce7a36" + dependencies: + glob "^7.0.5" + +rimraf@~2.2.6: + version "2.2.8" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.2.8.tgz#e439be2aaee327321952730f99a8929e4fc50582" + +safe-buffer@^5.0.1, safe-buffer@^5.1.1, safe-buffer@~5.1.0, safe-buffer@~5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853" + +sane@^2.0.0: + version "2.4.1" + resolved "https://registry.yarnpkg.com/sane/-/sane-2.4.1.tgz#29f991208cf28636720efdc584293e7fd66663a5" + dependencies: + anymatch "^1.3.0" + exec-sh "^0.2.0" + fb-watchman "^2.0.0" + minimatch "^3.0.2" + minimist "^1.1.1" + walker "~1.0.5" + watch "~0.18.0" + optionalDependencies: + fsevents "^1.1.1" + +"semver@2 || 3 || 4 || 5", semver@5.x, semver@^5.3.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.0.tgz#dc4bbc7a6ca9d916dee5d43516f0092b58f7b8ab" + +serialize-error@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/serialize-error/-/serialize-error-2.1.0.tgz#50b679d5635cdf84667bdc8e59af4e5b81d5f60a" + +set-blocking@^2.0.0, set-blocking@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" + +setimmediate@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" + +shebang-command@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" + dependencies: + shebang-regex "^1.0.0" + +shebang-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" + +signal-exit@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" + +slash@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55" + +slide@^1.1.5: + version "1.1.6" + resolved "https://registry.yarnpkg.com/slide/-/slide-1.1.6.tgz#56eb027d65b4d2dce6cb2e2d32c4d4afc9e1d707" + +sntp@1.x.x: + version "1.0.9" + resolved "https://registry.yarnpkg.com/sntp/-/sntp-1.0.9.tgz#6541184cc90aeea6c6e7b35e2659082443c66198" + dependencies: + hoek "2.x.x" + +sntp@2.x.x: + version "2.1.0" + resolved "https://registry.yarnpkg.com/sntp/-/sntp-2.1.0.tgz#2c6cec14fedc2222739caf9b5c3d85d1cc5a2cc8" + dependencies: + hoek "4.x.x" + +source-map-support@^0.4.15: + version "0.4.18" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.4.18.tgz#0286a6de8be42641338594e97ccea75f0a2c585f" + dependencies: + source-map "^0.5.6" + +source-map@^0.5.0, source-map@^0.5.6, source-map@^0.5.7: + version "0.5.7" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" + +source-map@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + +spdx-correct@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.0.0.tgz#05a5b4d7153a195bc92c3c425b69f3b2a9524c82" + dependencies: + spdx-expression-parse "^3.0.0" + spdx-license-ids "^3.0.0" + +spdx-exceptions@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.1.0.tgz#2c7ae61056c714a5b9b9b2b2af7d311ef5c78fe9" + +spdx-expression-parse@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz#99e119b7a5da00e05491c9fa338b7904823b41d0" + dependencies: + spdx-exceptions "^2.1.0" + spdx-license-ids "^3.0.0" + +spdx-license-ids@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.0.tgz#7a7cd28470cc6d3a1cfe6d66886f6bc430d3ac87" + +sshpk@^1.7.0: + version "1.13.1" + resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.13.1.tgz#512df6da6287144316dc4c18fe1cf1d940739be3" + dependencies: + asn1 "~0.2.3" + assert-plus "^1.0.0" + dashdash "^1.12.0" + getpass "^0.1.1" + optionalDependencies: + bcrypt-pbkdf "^1.0.0" + ecc-jsbn "~0.1.1" + jsbn "~0.1.0" + tweetnacl "~0.14.0" + +statuses@~1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.3.1.tgz#faf51b9eb74aaef3b3acf4ad5f61abf24cb7b93e" + +string-width@^1.0.1, string-width@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" + dependencies: + code-point-at "^1.0.0" + is-fullwidth-code-point "^1.0.0" + strip-ansi "^3.0.0" + +string-width@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" + dependencies: + is-fullwidth-code-point "^2.0.0" + strip-ansi "^4.0.0" + +string_decoder@~1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.0.3.tgz#0fc67d7c141825de94282dd536bec6b9bce860ab" + dependencies: + safe-buffer "~5.1.0" + +stringstream@~0.0.4, stringstream@~0.0.5: + version "0.0.5" + resolved "https://registry.yarnpkg.com/stringstream/-/stringstream-0.0.5.tgz#4e484cd4de5a0bbbee18e46307710a8a81621878" + +strip-ansi@^3.0.0, strip-ansi@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" + dependencies: + ansi-regex "^2.0.0" + +strip-ansi@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" + dependencies: + ansi-regex "^3.0.0" + +strip-bom@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" + +strip-eof@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" + +strip-json-comments@~2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" + +supports-color@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" + +supports-color@^5.3.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.3.0.tgz#5b24ac15db80fa927cf5227a4a33fd3c4c7676c0" + dependencies: + has-flag "^3.0.0" + +tar-pack@^3.4.0: + version "3.4.1" + resolved "https://registry.yarnpkg.com/tar-pack/-/tar-pack-3.4.1.tgz#e1dbc03a9b9d3ba07e896ad027317eb679a10a1f" + dependencies: + debug "^2.2.0" + fstream "^1.0.10" + fstream-ignore "^1.0.5" + once "^1.3.3" + readable-stream "^2.1.4" + rimraf "^2.5.1" + tar "^2.2.1" + uid-number "^0.0.6" + +tar@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/tar/-/tar-2.2.1.tgz#8e4d2a256c0e2185c6b18ad694aec968b83cb1d1" + dependencies: + block-stream "*" + fstream "^1.0.2" + inherits "2" + +temp@0.8.3: + version "0.8.3" + resolved "https://registry.yarnpkg.com/temp/-/temp-0.8.3.tgz#e0c6bc4d26b903124410e4fed81103014dfc1f59" + dependencies: + os-tmpdir "^1.0.0" + rimraf "~2.2.6" + +throat@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/throat/-/throat-4.1.0.tgz#89037cbc92c56ab18926e6ba4cbb200e15672a6a" + +tmpl@1.0.x: + version "1.0.4" + resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.4.tgz#23640dd7b42d00433911140820e5cf440e521dd1" + +to-fast-properties@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-1.0.3.tgz#b83571fa4d8c25b82e231b06e3a3055de4ca1a47" + +to-fast-properties@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" + +tough-cookie@~2.3.0, tough-cookie@~2.3.3: + version "2.3.4" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.4.tgz#ec60cee38ac675063ffc97a5c18970578ee83655" + dependencies: + punycode "^1.4.1" + +trim-right@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003" + +tunnel-agent@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" + dependencies: + safe-buffer "^5.0.1" + +tweetnacl@^0.14.3, tweetnacl@~0.14.0: + version "0.14.5" + resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" + +typedarray@^0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" + +ua-parser-js@^0.7.9: + version "0.7.17" + resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.17.tgz#e9ec5f9498b9ec910e7ae3ac626a805c4d09ecac" + +uglify-es@^3.1.9: + version "3.3.9" + resolved "https://registry.yarnpkg.com/uglify-es/-/uglify-es-3.3.9.tgz#0c1c4f0700bed8dbc124cdb304d2592ca203e677" + dependencies: + commander "~2.13.0" + source-map "~0.6.1" + +uid-number@^0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/uid-number/-/uid-number-0.0.6.tgz#0ea10e8035e8eb5b8e4449f06da1c730663baa81" + +ultron@1.0.x: + version "1.0.2" + resolved "https://registry.yarnpkg.com/ultron/-/ultron-1.0.2.tgz#ace116ab557cd197386a4e88f4685378c8b2e4fa" + +unpipe@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" + +util-deprecate@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + +utils-merge@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" + +uuid@^3.0.0, uuid@^3.1.0: + version "3.2.1" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.2.1.tgz#12c528bb9d58d0b9265d9a2f6f0fe8be17ff1f14" + +validate-npm-package-license@^3.0.1: + version "3.0.3" + resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.3.tgz#81643bcbef1bdfecd4623793dc4648948ba98338" + dependencies: + spdx-correct "^3.0.0" + spdx-expression-parse "^3.0.0" + +verror@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" + dependencies: + assert-plus "^1.0.0" + core-util-is "1.0.2" + extsprintf "^1.2.0" + +walker@~1.0.5: + version "1.0.7" + resolved "https://registry.yarnpkg.com/walker/-/walker-1.0.7.tgz#2f7f9b8fd10d677262b18a884e28d19618e028fb" + dependencies: + makeerror "1.0.x" + +watch@~0.18.0: + version "0.18.0" + resolved "https://registry.yarnpkg.com/watch/-/watch-0.18.0.tgz#28095476c6df7c90c963138990c0a5423eb4b986" + dependencies: + exec-sh "^0.2.0" + minimist "^1.2.0" + +whatwg-fetch@>=0.10.0: + version "2.0.3" + resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-2.0.3.tgz#9c84ec2dcf68187ff00bc64e1274b442176e1c84" + +which-module@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" + +which@^1.2.9: + version "1.3.0" + resolved "https://registry.yarnpkg.com/which/-/which-1.3.0.tgz#ff04bdfc010ee547d780bec38e1ac1c2777d253a" + dependencies: + isexe "^2.0.0" + +wide-align@^1.1.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.2.tgz#571e0f1b0604636ebc0dfc21b0339bbe31341710" + dependencies: + string-width "^1.0.2" + +wordwrap@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" + +wrap-ansi@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85" + dependencies: + string-width "^1.0.1" + strip-ansi "^3.0.1" + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + +write-file-atomic@^1.2.0: + version "1.3.4" + resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-1.3.4.tgz#f807a4f0b1d9e913ae7a48112e6cc3af1991b45f" + dependencies: + graceful-fs "^4.1.11" + imurmurhash "^0.1.4" + slide "^1.1.5" + +ws@^1.1.0: + version "1.1.5" + resolved "https://registry.yarnpkg.com/ws/-/ws-1.1.5.tgz#cbd9e6e75e09fc5d2c90015f21f0c40875e0dd51" + dependencies: + options ">=0.0.5" + ultron "1.0.x" + +xpipe@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/xpipe/-/xpipe-1.0.5.tgz#8dd8bf45fc3f7f55f0e054b878f43a62614dafdf" + +y18n@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.1.tgz#6d15fba884c08679c0d77e88e7759e811e07fa41" + +yallist@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" + +yargs-parser@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-7.0.0.tgz#8d0ac42f16ea55debd332caf4c4038b3e3f5dfd9" + dependencies: + camelcase "^4.1.0" + +yargs@^9.0.0: + version "9.0.1" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-9.0.1.tgz#52acc23feecac34042078ee78c0c007f5085db4c" + dependencies: + camelcase "^4.1.0" + cliui "^3.2.0" + decamelize "^1.1.1" + get-caller-file "^1.0.1" + os-locale "^2.0.0" + read-pkg-up "^2.0.0" + require-directory "^2.1.1" + require-main-filename "^1.0.1" + set-blocking "^2.0.0" + string-width "^2.0.0" + which-module "^2.0.0" + y18n "^3.2.1" + yargs-parser "^7.0.0" diff --git a/website/.gitignore b/website/.gitignore new file mode 100644 index 000000000..aeedda9bf --- /dev/null +++ b/website/.gitignore @@ -0,0 +1,11 @@ +node_modules +.DS_Store +lib/core/metadata.js +lib/core/MetadataBlog.js +website/translated_docs +website/build/ +website/yarn.lock +website/node_modules + +website/i18n/* +!website/i18n/en.json diff --git a/website/blog/2016-03-11-blog-post.md b/website/blog/2016-03-11-blog-post.md new file mode 100755 index 000000000..cf2ba2960 --- /dev/null +++ b/website/blog/2016-03-11-blog-post.md @@ -0,0 +1,18 @@ +--- +title: Blog Title +author: Blog Author +authorURL: http://twitter.com/ +authorFBID: 100002976521003 +--- + +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus elementum massa eget nulla aliquet sagittis. Proin odio tortor, vulputate ut odio in, ultrices ultricies augue. Cras ornare ultrices lorem malesuada iaculis. Etiam sit amet libero tempor, pulvinar mauris sed, sollicitudin sapien. + + + +Mauris vestibulum ullamcorper nibh, ut semper purus pulvinar ut. Donec volutpat orci sit amet mauris malesuada, non pulvinar augue aliquam. Vestibulum ultricies at urna ut suscipit. Morbi iaculis, erat at imperdiet semper, ipsum nulla sodales erat, eget tincidunt justo dui quis justo. Pellentesque dictum bibendum diam at aliquet. Sed pulvinar, dolor quis finibus ornare, eros odio facilisis erat, eu rhoncus nunc dui sed ex. Nunc gravida dui massa, sed ornare arcu tincidunt sit amet. Maecenas efficitur sapien neque, a laoreet libero feugiat ut. + +Nulla facilisi. Maecenas sodales nec purus eget posuere. Sed sapien quam, pretium a risus in, porttitor dapibus erat. Sed sit amet fringilla ipsum, eget iaculis augue. Integer sollicitudin tortor quis ultricies aliquam. Suspendisse fringilla nunc in tellus cursus, at placerat tellus scelerisque. Sed tempus elit a sollicitudin rhoncus. Nulla facilisi. Morbi nec dolor dolor. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Cras et aliquet lectus. Pellentesque sit amet eros nisi. Quisque ac sapien in sapien congue accumsan. Nullam in posuere ante. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Proin lacinia leo a nibh fringilla pharetra. + +Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Proin venenatis lectus dui, vel ultrices ante bibendum hendrerit. Aenean egestas feugiat dui id hendrerit. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Curabitur in tellus laoreet, eleifend nunc id, viverra leo. Proin vulputate non dolor vel vulputate. Curabitur pretium lobortis felis, sit amet finibus lorem suscipit ut. Sed non mollis risus. Duis sagittis, mi in euismod tincidunt, nunc mauris vestibulum urna, at euismod est elit quis erat. Phasellus accumsan vitae neque eu placerat. In elementum arcu nec tellus imperdiet, eget maximus nulla sodales. Curabitur eu sapien eget nisl sodales fermentum. + +Phasellus pulvinar ex id commodo imperdiet. Praesent odio nibh, sollicitudin sit amet faucibus id, placerat at metus. Donec vitae eros vitae tortor hendrerit finibus. Interdum et malesuada fames ac ante ipsum primis in faucibus. Quisque vitae purus dolor. Duis suscipit ac nulla et finibus. Phasellus ac sem sed dui dictum gravida. Phasellus eleifend vestibulum facilisis. Integer pharetra nec enim vitae mattis. Duis auctor, lectus quis condimentum bibendum, nunc dolor aliquam massa, id bibendum orci velit quis magna. Ut volutpat nulla nunc, sed interdum magna condimentum non. Sed urna metus, scelerisque vitae consectetur a, feugiat quis magna. Donec dignissim ornare nisl, eget tempor risus malesuada quis. diff --git a/website/blog/2017-04-10-blog-post-two.md b/website/blog/2017-04-10-blog-post-two.md new file mode 100644 index 000000000..3ab4637bd --- /dev/null +++ b/website/blog/2017-04-10-blog-post-two.md @@ -0,0 +1,18 @@ +--- +title: New Blog Post +author: Blog Author +authorURL: http://twitter.com/ +authorFBID: 100002976521003 +--- + +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus elementum massa eget nulla aliquet sagittis. Proin odio tortor, vulputate ut odio in, ultrices ultricies augue. Cras ornare ultrices lorem malesuada iaculis. Etiam sit amet libero tempor, pulvinar mauris sed, sollicitudin sapien. + + + +Mauris vestibulum ullamcorper nibh, ut semper purus pulvinar ut. Donec volutpat orci sit amet mauris malesuada, non pulvinar augue aliquam. Vestibulum ultricies at urna ut suscipit. Morbi iaculis, erat at imperdiet semper, ipsum nulla sodales erat, eget tincidunt justo dui quis justo. Pellentesque dictum bibendum diam at aliquet. Sed pulvinar, dolor quis finibus ornare, eros odio facilisis erat, eu rhoncus nunc dui sed ex. Nunc gravida dui massa, sed ornare arcu tincidunt sit amet. Maecenas efficitur sapien neque, a laoreet libero feugiat ut. + +Nulla facilisi. Maecenas sodales nec purus eget posuere. Sed sapien quam, pretium a risus in, porttitor dapibus erat. Sed sit amet fringilla ipsum, eget iaculis augue. Integer sollicitudin tortor quis ultricies aliquam. Suspendisse fringilla nunc in tellus cursus, at placerat tellus scelerisque. Sed tempus elit a sollicitudin rhoncus. Nulla facilisi. Morbi nec dolor dolor. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Cras et aliquet lectus. Pellentesque sit amet eros nisi. Quisque ac sapien in sapien congue accumsan. Nullam in posuere ante. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Proin lacinia leo a nibh fringilla pharetra. + +Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Proin venenatis lectus dui, vel ultrices ante bibendum hendrerit. Aenean egestas feugiat dui id hendrerit. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Curabitur in tellus laoreet, eleifend nunc id, viverra leo. Proin vulputate non dolor vel vulputate. Curabitur pretium lobortis felis, sit amet finibus lorem suscipit ut. Sed non mollis risus. Duis sagittis, mi in euismod tincidunt, nunc mauris vestibulum urna, at euismod est elit quis erat. Phasellus accumsan vitae neque eu placerat. In elementum arcu nec tellus imperdiet, eget maximus nulla sodales. Curabitur eu sapien eget nisl sodales fermentum. + +Phasellus pulvinar ex id commodo imperdiet. Praesent odio nibh, sollicitudin sit amet faucibus id, placerat at metus. Donec vitae eros vitae tortor hendrerit finibus. Interdum et malesuada fames ac ante ipsum primis in faucibus. Quisque vitae purus dolor. Duis suscipit ac nulla et finibus. Phasellus ac sem sed dui dictum gravida. Phasellus eleifend vestibulum facilisis. Integer pharetra nec enim vitae mattis. Duis auctor, lectus quis condimentum bibendum, nunc dolor aliquam massa, id bibendum orci velit quis magna. Ut volutpat nulla nunc, sed interdum magna condimentum non. Sed urna metus, scelerisque vitae consectetur a, feugiat quis magna. Donec dignissim ornare nisl, eget tempor risus malesuada quis. diff --git a/website/blog/2017-09-25-testing-rss.md b/website/blog/2017-09-25-testing-rss.md new file mode 100644 index 000000000..b7ff8129c --- /dev/null +++ b/website/blog/2017-09-25-testing-rss.md @@ -0,0 +1,11 @@ +--- +title: Adding RSS Support - RSS Truncation Test +author: Eric Nakagawa +authorURL: http://twitter.com/ericnakagawa +authorFBID: 661277173 +--- +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 + +This should be truncated. + +This line should never render in XML. diff --git a/website/blog/2017-09-26-adding-rss.md b/website/blog/2017-09-26-adding-rss.md new file mode 100644 index 000000000..eeb4f0477 --- /dev/null +++ b/website/blog/2017-09-26-adding-rss.md @@ -0,0 +1,10 @@ +--- +title: Adding RSS Support +author: Eric Nakagawa +authorURL: http://twitter.com/ericnakagawa +authorFBID: 661277173 +--- + +This is a test post. + +A whole bunch of other information. diff --git a/website/blog/2017-10-24-new-version-1.0.0.md b/website/blog/2017-10-24-new-version-1.0.0.md new file mode 100644 index 000000000..60761c02d --- /dev/null +++ b/website/blog/2017-10-24-new-version-1.0.0.md @@ -0,0 +1,8 @@ +--- +title: New Version 1.0.0 +author: Eric Nakagawa +authorURL: http://twitter.com/ericnakagawa +authorFBID: 661277173 +--- + +This blog post will test file name parsing issues when periods are present. diff --git a/website/core/Footer.js b/website/core/Footer.js new file mode 100644 index 000000000..1b187d243 --- /dev/null +++ b/website/core/Footer.js @@ -0,0 +1,82 @@ +/** + * Copyright 2018-present Facebook. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * @format + */ + +const React = require('react'); + +class Footer extends React.Component { + docUrl(doc, language) { + const baseUrl = this.props.config.baseUrl; + return baseUrl + 'docs/' + (language ? language + '/' : '') + doc; + } + + pageUrl(doc, language) { + const baseUrl = this.props.config.baseUrl; + return baseUrl + (language ? language + '/' : '') + doc; + } + + render() { + return ( + + ); + } +} + +module.exports = Footer; diff --git a/website/i18n/en.json b/website/i18n/en.json new file mode 100644 index 000000000..b4c0cff11 --- /dev/null +++ b/website/i18n/en.json @@ -0,0 +1,46 @@ +{ + "_comment": "This file is auto-generated by write-translations.js", + "localized-strings": { + "next": "Next", + "previous": "Previous", + "tagline": "Extensible mobile app debugging", + "communicating": "Device Communication", + "Device Communication": "Device Communication", + "create-plugin": "Mobile Setup", + "Mobile Setup": "Mobile Setup", + "create-table-plugin": "Create Table Plugin", + "Create Table Plugin": "Create Table Plugin", + "error-handling": "Error Handling", + "Error Handling": "Error Handling", + "getting-started": "Getting Started", + "Getting Started": "Getting Started", + "js-setup": "JavaScript Setup", + "JavaScript Setup": "JavaScript Setup", + "layout-plugin": "Layout Inspector", + "logs-plugin": "Logs", + "network-plugin": "Network", + "send-data": "Sending Data to Plugins", + "Send Data": "Send Data", + "stetho": "Stetho Guidance", + "Stetho Guidance": "Stetho Guidance", + "styling-components": "Styling Components", + "Styling Components": "Styling Components", + "testing": "Testing", + "Testing": "Testing", + "ui-components": "UI Components", + "UI Components": "UI Components", + "understand": "Understanding Sonar", + "Understanding Sonar": "Understanding Sonar", + "Docs": "Docs", + "GitHub": "GitHub", + "Using Sonar": "Using Sonar", + "Built-in Plugins": "Built-in Plugins", + "Plugins: Desktop part": "Plugins: Desktop part", + "Plugins: Mobile part": "Plugins: Mobile part" + }, + "pages-strings": { + "Help Translate|recruit community translators for your project": "Help Translate", + "Edit this Doc|recruitment message asking to edit the doc source": "Edit", + "Translate this Doc|recruitment message asking to translate the docs": "Translate" + } +} diff --git a/website/package.json b/website/package.json new file mode 100644 index 000000000..f5822c33b --- /dev/null +++ b/website/package.json @@ -0,0 +1,14 @@ +{ + "scripts": { + "examples": "docusaurus-examples", + "start": "docusaurus-start", + "build": "docusaurus-build", + "publish-gh-pages": "docusaurus-publish", + "write-translations": "docusaurus-write-translations", + "version": "docusaurus-version", + "rename-version": "docusaurus-rename-version" + }, + "devDependencies": { + "docusaurus": "^1.0.9" + } +} diff --git a/website/pages/docs/en/index.js b/website/pages/docs/en/index.js new file mode 100644 index 000000000..f8ce11168 --- /dev/null +++ b/website/pages/docs/en/index.js @@ -0,0 +1,22 @@ +/** + * Copyright 2018-present Facebook. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * @format + */ + +const React = require('react'); + +class Docs extends React.Component { + render() { + return ( +

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≤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%0A|oH^ahQ2MMNbh$}p6F)_zhd-czm{qko_aE^O zo6#x)FN=x-fhQQNSLfd?-*_!x4C&aavh@{2d8O`i`!g;a{$4qgJ}r$sMKb*#33E)^ z1{Nu=D<^w6qII|+=9YcGRxr$=Ej3pG(kLXR#pO+Azaog8JW;w@uFOLRDPJ5H_IsebQn-fm+z(R)Z@a*Uw}*gK(F zTb)n=KWjE2UHE27=9NG-1igc>P6Cp$Y2K%g$xLynb{87{h67*{s)sia>v5jIN z^eoal0qpJ2G{V;nl<{PKrCAItzRt#TKHVhDa78LVcfW-_r$AobpDq)atkkm-c<;bGz=BRv?ThlEZb`&NkSC z7zt4eS{g`FH)>ddblJ@RAGY2yD6TH(7EXc&ceh|6K!CyB3GVK}3GVLh8r*`ryEDiT z+}+(_aEEX5-uv9Tb?cj-r)qZ9*=O(W)vH%`6TWxfoHQ4`3UGYjWIppeqipJM(BSb| zy@}ZihEJ~O$a$EwcuDcS{t$B?{nM%fqeaqqXPGY_`Qimk^>H=f=p0oq>a3aw=&i4r zb7#bsCC=rCZRu4}X4FJYi%<+ZI5oAdQSbXKA7yw^wc`;{+2tT);A3{q1Uc7qtTl05 zE~kqQ{T~@rzRK@*+>}9U?~T;KYB7>C4`uK)568&tyUZ&KtS;7%+hlFF!g2i zEn5}xir*aR+}{V+Lk@Bv_2rDDp!pP(ZUeuO@2=k$t{3KGkHmjbxr7`yy%)|Dct5)@ z@?)<@g#2SFMIL-IZ`-$@ic%+fZ_7twMm}gTy{Tpev4lfeUm(>uG`~Q?So^^_gzPS% z4a$=?6yvPa5fW{uIpiwBkDpG!2C=0Hmg@2|Hoh{e`OE|yLi?o%d8wi|oTMIGF-iW) zsLr9KudM;sn7Mn&Cckpc>&V6IQG)bU{TONbV|d89shuoy_m=i(^4f-LMg&8qd2&i> zcqc5s;l{#TX_UmND$^3A)!`K$axMF~B7d@(WGj(CO`6CSF2S-_t-Tfuw*G4E%o5$t z@P%X~q4-zS?+`C6DWURZ$8xu?4T|E8J*=9{DTf5YpXVxz zU4Ithy*k`kyj>=FMO?y^uN?3Xgxg^4G4YZ){+kBc_sHa^W?39{4gPutL>roXmJ$my=ZaKFM~a`QL?=g4=!anSiiTHF