feat(slam): add rtabmap_ros
@@ -0,0 +1 @@
|
||||
Libraries
|
||||
@@ -0,0 +1,76 @@
|
||||
//
|
||||
// AppDelegate.swift
|
||||
// GLKittutorial
|
||||
//
|
||||
// Created by Mathieu Labbe on 2020-12-28.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
import ARKit
|
||||
|
||||
func setDefaultsFromSettingsBundle() {
|
||||
|
||||
let plistFiles = ["Root", "Mapping", "Assembling"]
|
||||
|
||||
for plistName in plistFiles {
|
||||
//Read PreferenceSpecifiers from Root.plist in Settings.Bundle
|
||||
if let settingsURL = Bundle.main.url(forResource: plistName, withExtension: "plist", subdirectory: "Settings.bundle"),
|
||||
let settingsPlist = NSDictionary(contentsOf: settingsURL),
|
||||
let preferences = settingsPlist["PreferenceSpecifiers"] as? [NSDictionary] {
|
||||
|
||||
for prefSpecification in preferences {
|
||||
|
||||
if let key = prefSpecification["Key"] as? String, let value = prefSpecification["DefaultValue"] {
|
||||
|
||||
//If key doesn't exists in userDefaults then register it, else keep original value
|
||||
if UserDefaults.standard.value(forKey: key) == nil {
|
||||
|
||||
UserDefaults.standard.set(value, forKey: key)
|
||||
NSLog("registerDefaultsFromSettingsBundle: Set following to UserDefaults - (key: \(key), value: \(value), type: \(type(of: value)))")
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
NSLog("registerDefaultsFromSettingsBundle: Could not find Settings.bundle")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@main
|
||||
class AppDelegate: UIResponder, UIApplicationDelegate {
|
||||
|
||||
var window: UIWindow?
|
||||
|
||||
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
|
||||
|
||||
// Always set Version to default
|
||||
let defaults = UserDefaults.standard
|
||||
defaults.removeObject(forKey: "Version")
|
||||
|
||||
setDefaultsFromSettingsBundle()
|
||||
|
||||
// Override point for customization after application launch.
|
||||
if !ARWorldTrackingConfiguration.supportsFrameSemantics(.sceneDepth) {
|
||||
// Ensure that the device supports scene depth and present
|
||||
// an error-message view controller, if not.
|
||||
let storyboard = UIStoryboard(name: "Main", bundle: nil)
|
||||
window?.rootViewController = storyboard.instantiateViewController(withIdentifier: "unsupportedDeviceMessage")
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// MARK: UISceneSession Lifecycle
|
||||
|
||||
func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
|
||||
// Called when a new scene session is being created.
|
||||
// Use this method to select a configuration to create the new scene with.
|
||||
return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
|
||||
}
|
||||
|
||||
func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set<UISceneSession>) {
|
||||
// Called when the user discards a scene session.
|
||||
// If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
|
||||
// Use this method to release any resources that were specific to the discarded scenes, as they will not return.
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"colors" : [
|
||||
{
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "RTAB-Map40-1.png",
|
||||
"idiom" : "iphone",
|
||||
"scale" : "2x",
|
||||
"size" : "20x20"
|
||||
},
|
||||
{
|
||||
"filename" : "RTAB-Map60.png",
|
||||
"idiom" : "iphone",
|
||||
"scale" : "3x",
|
||||
"size" : "20x20"
|
||||
},
|
||||
{
|
||||
"filename" : "RTAB-Map58-1.png",
|
||||
"idiom" : "iphone",
|
||||
"scale" : "2x",
|
||||
"size" : "29x29"
|
||||
},
|
||||
{
|
||||
"filename" : "RTAB-Map87.png",
|
||||
"idiom" : "iphone",
|
||||
"scale" : "3x",
|
||||
"size" : "29x29"
|
||||
},
|
||||
{
|
||||
"filename" : "RTAB-Map80-1.png",
|
||||
"idiom" : "iphone",
|
||||
"scale" : "2x",
|
||||
"size" : "40x40"
|
||||
},
|
||||
{
|
||||
"filename" : "RTAB-Map120-1.png",
|
||||
"idiom" : "iphone",
|
||||
"scale" : "3x",
|
||||
"size" : "40x40"
|
||||
},
|
||||
{
|
||||
"filename" : "RTAB-Map120.png",
|
||||
"idiom" : "iphone",
|
||||
"scale" : "2x",
|
||||
"size" : "60x60"
|
||||
},
|
||||
{
|
||||
"filename" : "RTAB-Map180.png",
|
||||
"idiom" : "iphone",
|
||||
"scale" : "3x",
|
||||
"size" : "60x60"
|
||||
},
|
||||
{
|
||||
"filename" : "RTAB-Map20.png",
|
||||
"idiom" : "ipad",
|
||||
"scale" : "1x",
|
||||
"size" : "20x20"
|
||||
},
|
||||
{
|
||||
"filename" : "RTAB-Map40.png",
|
||||
"idiom" : "ipad",
|
||||
"scale" : "2x",
|
||||
"size" : "20x20"
|
||||
},
|
||||
{
|
||||
"filename" : "RTAB-Map29.png",
|
||||
"idiom" : "ipad",
|
||||
"scale" : "1x",
|
||||
"size" : "29x29"
|
||||
},
|
||||
{
|
||||
"filename" : "RTAB-Map58.png",
|
||||
"idiom" : "ipad",
|
||||
"scale" : "2x",
|
||||
"size" : "29x29"
|
||||
},
|
||||
{
|
||||
"filename" : "RTAB-Map40-2.png",
|
||||
"idiom" : "ipad",
|
||||
"scale" : "1x",
|
||||
"size" : "40x40"
|
||||
},
|
||||
{
|
||||
"filename" : "RTAB-Map80.png",
|
||||
"idiom" : "ipad",
|
||||
"scale" : "2x",
|
||||
"size" : "40x40"
|
||||
},
|
||||
{
|
||||
"filename" : "RTAB-Map76.png",
|
||||
"idiom" : "ipad",
|
||||
"scale" : "1x",
|
||||
"size" : "76x76"
|
||||
},
|
||||
{
|
||||
"filename" : "RTAB-Map152.png",
|
||||
"idiom" : "ipad",
|
||||
"scale" : "2x",
|
||||
"size" : "76x76"
|
||||
},
|
||||
{
|
||||
"filename" : "RTAB-Map167.png",
|
||||
"idiom" : "ipad",
|
||||
"scale" : "2x",
|
||||
"size" : "83.5x83.5"
|
||||
},
|
||||
{
|
||||
"filename" : "RTAB-Map1024.png",
|
||||
"idiom" : "ios-marketing",
|
||||
"scale" : "1x",
|
||||
"size" : "1024x1024"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
|
After Width: | Height: | Size: 442 KiB |
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 23 KiB |
|
After Width: | Height: | Size: 26 KiB |
|
After Width: | Height: | Size: 26 KiB |
|
After Width: | Height: | Size: 5.3 KiB |
|
After Width: | Height: | Size: 5.8 KiB |
|
After Width: | Height: | Size: 14 KiB |
|
After Width: | Height: | Size: 14 KiB |
|
After Width: | Height: | Size: 14 KiB |
|
After Width: | Height: | Size: 7.0 KiB |
|
After Width: | Height: | Size: 7.0 KiB |
|
After Width: | Height: | Size: 6.7 KiB |
|
After Width: | Height: | Size: 7.8 KiB |
|
After Width: | Height: | Size: 7.8 KiB |
|
After Width: | Height: | Size: 7.8 KiB |
|
After Width: | Height: | Size: 8.5 KiB |
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="19455" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
|
||||
<device id="retina6_1" orientation="portrait" appearance="light"/>
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="19454"/>
|
||||
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<scenes>
|
||||
<!--View Controller-->
|
||||
<scene sceneID="EHf-IW-A2E">
|
||||
<objects>
|
||||
<viewController id="01J-lp-oVM" sceneMemberID="viewController">
|
||||
<view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
|
||||
<rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="DqX-Vd-Tpo" userLabel="ViewButton">
|
||||
<rect key="frame" x="342" y="799.5" width="52" height="40.5"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="52" id="m5V-wG-7GI"/>
|
||||
<constraint firstAttribute="height" constant="44" id="pbH-yg-ZHL"/>
|
||||
</constraints>
|
||||
<color key="tintColor" white="0.33333333333333331" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<state key="normal" backgroundImage="eye" catalog="system">
|
||||
<color key="titleColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
</state>
|
||||
</button>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" spacing="20" translatesAutoresizingMaskIntoConstraints="NO" id="Ybb-6v-Prf">
|
||||
<rect key="frame" x="254" y="64" width="140" height="60"/>
|
||||
<subviews>
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="qpg-QD-geo" userLabel="LibraryButton">
|
||||
<rect key="frame" x="0.0" y="1" width="60" height="57.5"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="60" id="MMK-i4-ipl"/>
|
||||
<constraint firstAttribute="width" constant="60" id="MSB-kf-WKH"/>
|
||||
</constraints>
|
||||
<color key="tintColor" white="0.33333333333333331" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<state key="normal" backgroundImage="folder" catalog="system">
|
||||
<color key="titleColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
</state>
|
||||
</button>
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Xjn-gQ-W57" userLabel="MenuButton">
|
||||
<rect key="frame" x="80" y="0.5" width="60" height="59"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="60" id="h7m-oO-bNI"/>
|
||||
<constraint firstAttribute="width" constant="60" id="q9I-XS-C8P"/>
|
||||
</constraints>
|
||||
<color key="tintColor" white="0.33333333333333331" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<state key="normal" backgroundImage="ellipsis.circle" catalog="system"/>
|
||||
</button>
|
||||
</subviews>
|
||||
</stackView>
|
||||
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="RTAB-Map1024" translatesAutoresizingMaskIntoConstraints="NO" id="TNo-z5-pM0">
|
||||
<rect key="frame" x="177" y="418" width="60" height="60"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="60" id="Lio-4G-f3t"/>
|
||||
<constraint firstAttribute="height" constant="60" id="Q5D-zG-PAv"/>
|
||||
</constraints>
|
||||
</imageView>
|
||||
</subviews>
|
||||
<viewLayoutGuide key="safeArea" id="6Tk-OE-BBY"/>
|
||||
<color key="backgroundColor" white="0.0" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<constraints>
|
||||
<constraint firstItem="TNo-z5-pM0" firstAttribute="centerY" secondItem="Ze5-6b-2t3" secondAttribute="centerY" id="4fp-du-TTg"/>
|
||||
<constraint firstItem="Ybb-6v-Prf" firstAttribute="top" secondItem="6Tk-OE-BBY" secondAttribute="top" constant="20" id="Dcs-0a-Uhe"/>
|
||||
<constraint firstItem="6Tk-OE-BBY" firstAttribute="trailing" secondItem="DqX-Vd-Tpo" secondAttribute="trailing" constant="20" id="TTR-AB-iCr"/>
|
||||
<constraint firstItem="6Tk-OE-BBY" firstAttribute="trailing" secondItem="Ybb-6v-Prf" secondAttribute="trailing" constant="20" id="YPK-bW-6AC"/>
|
||||
<constraint firstItem="6Tk-OE-BBY" firstAttribute="bottom" secondItem="DqX-Vd-Tpo" secondAttribute="bottom" constant="20" id="cnW-a0-bhz"/>
|
||||
<constraint firstItem="TNo-z5-pM0" firstAttribute="centerX" secondItem="Ze5-6b-2t3" secondAttribute="centerX" id="epw-Qw-hdY"/>
|
||||
</constraints>
|
||||
</view>
|
||||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="52.173913043478265" y="375"/>
|
||||
</scene>
|
||||
</scenes>
|
||||
<resources>
|
||||
<image name="RTAB-Map1024" width="591" height="649"/>
|
||||
<image name="ellipsis.circle" catalog="system" width="128" height="121"/>
|
||||
<image name="eye" catalog="system" width="128" height="81"/>
|
||||
<image name="folder" catalog="system" width="128" height="97"/>
|
||||
</resources>
|
||||
</document>
|
||||
@@ -0,0 +1,354 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="32700.99.1234" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="zah-iI-EPt">
|
||||
<device id="retina6_12" orientation="portrait" appearance="light"/>
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="22684"/>
|
||||
<capability name="Image references" minToolsVersion="12.0"/>
|
||||
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
|
||||
<capability name="System colors in document resources" minToolsVersion="11.0"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<scenes>
|
||||
<!--GLKit View Controller-->
|
||||
<scene sceneID="1cO-Jt-3GG">
|
||||
<objects>
|
||||
<glkViewController preferredFramesPerSecond="30" id="zah-iI-EPt" customClass="ViewController" customModule="RTABMapApp" customModuleProvider="target" sceneMemberID="viewController">
|
||||
<glkView key="view" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" drawableDepthFormat="24" enableSetNeedsDisplay="NO" id="sqF-4e-2HU">
|
||||
<rect key="frame" x="0.0" y="0.0" width="393" height="852"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="30" translatesAutoresizingMaskIntoConstraints="NO" id="kPv-DO-hpd">
|
||||
<rect key="frame" x="323" y="261" width="60" height="330"/>
|
||||
<subviews>
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="mJN-Ru-yPg" userLabel="StopButton">
|
||||
<rect key="frame" x="0.0" y="1" width="60" height="58.666666666666671"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="60" id="g9J-0P-CmQ"/>
|
||||
<constraint firstAttribute="width" constant="60" id="m06-eJ-dIn"/>
|
||||
</constraints>
|
||||
<color key="tintColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<state key="normal" backgroundImage="stop.circle" catalog="system"/>
|
||||
<connections>
|
||||
<action selector="stopAction:" destination="zah-iI-EPt" eventType="touchUpInside" id="3iJ-xb-gzb"/>
|
||||
</connections>
|
||||
</button>
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="7Lv-u6-mGh" userLabel="RecordButton">
|
||||
<rect key="frame" x="0.0" y="91" width="60" height="58.666666666666686"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="60" id="DQI-eQ-v3X"/>
|
||||
<constraint firstAttribute="width" constant="60" id="Oeu-YT-wMz"/>
|
||||
</constraints>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="18"/>
|
||||
<color key="tintColor" systemColor="systemRedColor"/>
|
||||
<inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="0.0" maxY="20"/>
|
||||
<state key="normal" backgroundImage="record.circle" catalog="system"/>
|
||||
<connections>
|
||||
<action selector="recordAction:" destination="zah-iI-EPt" eventType="touchUpInside" id="dzY-yL-YBg"/>
|
||||
</connections>
|
||||
</button>
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="lFB-Lm-zFS" userLabel="AddMeasureButton">
|
||||
<rect key="frame" x="0.0" y="181.33333333333334" width="60" height="57.999999999999972"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="60" id="Wtb-vg-lgB"/>
|
||||
<constraint firstAttribute="height" constant="60" id="p0E-BN-poT"/>
|
||||
</constraints>
|
||||
<color key="tintColor" systemColor="systemYellowColor"/>
|
||||
<inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
|
||||
<state key="normal" backgroundImage="plus.viewfinder" catalog="system"/>
|
||||
<connections>
|
||||
<action selector="addMeasureAction:" destination="zah-iI-EPt" eventType="touchUpInside" id="lUX-tm-SgY"/>
|
||||
</connections>
|
||||
</button>
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="c1k-0i-64A" userLabel="RemoveMeasureButton">
|
||||
<rect key="frame" x="0.0" y="271" width="60" height="58.666666666666686"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="60" id="0gd-nd-i5y"/>
|
||||
<constraint firstAttribute="width" constant="60" id="mSi-rI-NoN"/>
|
||||
</constraints>
|
||||
<color key="tintColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
|
||||
<state key="normal" backgroundImage="minus.circle" catalog="system"/>
|
||||
<connections>
|
||||
<action selector="removeMeasureAction:" destination="zah-iI-EPt" eventType="touchUpInside" id="2RW-qr-kvb"/>
|
||||
</connections>
|
||||
</button>
|
||||
</subviews>
|
||||
</stackView>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" spacing="20" translatesAutoresizingMaskIntoConstraints="NO" id="ozY-dg-YOd">
|
||||
<rect key="frame" x="233" y="79" width="140" height="60"/>
|
||||
<subviews>
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="9kh-4C-KyP" userLabel="LibraryButton">
|
||||
<rect key="frame" x="0.0" y="1.6666666666666643" width="60" height="57"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="60" id="Ekq-3J-kUL"/>
|
||||
<constraint firstAttribute="height" constant="60" id="fqe-e7-0uk"/>
|
||||
</constraints>
|
||||
<color key="tintColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<state key="normal" backgroundImage="folder" catalog="system">
|
||||
<color key="titleColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
</state>
|
||||
<connections>
|
||||
<action selector="libraryAction:" destination="zah-iI-EPt" eventType="touchUpInside" id="WOh-uA-T5h"/>
|
||||
</connections>
|
||||
</button>
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="y53-OI-O76" userLabel="MenuButton">
|
||||
<rect key="frame" x="80" y="1" width="60" height="58.666666666666671"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="60" id="L5T-8h-ale"/>
|
||||
<constraint firstAttribute="width" constant="60" id="pLI-ns-KHQ"/>
|
||||
</constraints>
|
||||
<color key="tintColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<state key="normal" backgroundImage="ellipsis.circle" catalog="system"/>
|
||||
</button>
|
||||
</subviews>
|
||||
</stackView>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="wordWrap" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="KlF-4H-k6I">
|
||||
<rect key="frame" x="16" y="79" width="31" height="14.333333333333329"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="12"/>
|
||||
<color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="012-W3-dOS" userLabel="CloseVisualization">
|
||||
<rect key="frame" x="111.33333333333333" y="772" width="170.33333333333337" height="22"/>
|
||||
<color key="tintColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<state key="normal" title="Close Visualization" image="xmark.square" catalog="system">
|
||||
<color key="titleColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
</state>
|
||||
<connections>
|
||||
<action selector="closeVisualizationAction:" destination="zah-iI-EPt" eventType="touchUpInside" id="DqP-oy-XPe"/>
|
||||
</connections>
|
||||
</button>
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="9oq-op-NGV" userLabel="StopCamera">
|
||||
<rect key="frame" x="134.33333333333334" y="771" width="124.33333333333334" height="22"/>
|
||||
<color key="tintColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<state key="normal" title="Stop Camera" image="xmark.square" catalog="system">
|
||||
<color key="titleColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
</state>
|
||||
<connections>
|
||||
<action selector="stopCameraAction:" destination="zah-iI-EPt" eventType="touchUpInside" id="YZq-pZ-8Te"/>
|
||||
</connections>
|
||||
</button>
|
||||
<button opaque="NO" contentMode="scaleAspectFit" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Jj4-ow-MwD" userLabel="NewScanButtonLarge">
|
||||
<rect key="frame" x="86.333333333333329" y="407" width="220.66666666666669" height="38.333333333333314"/>
|
||||
<color key="tintColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<state key="normal" title="New Mapping Session">
|
||||
<color key="titleColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<imageReference key="image" image="plus.app" catalog="system" symbolScale="large"/>
|
||||
<preferredSymbolConfiguration key="preferredSymbolConfiguration" configurationType="font">
|
||||
<fontDescription key="fontDescription" style="UICTFontTextStyleTitle1"/>
|
||||
</preferredSymbolConfiguration>
|
||||
</state>
|
||||
<connections>
|
||||
<action selector="newScanAction:" destination="zah-iI-EPt" eventType="touchUpInside" id="jL9-xF-V9K"/>
|
||||
</connections>
|
||||
</button>
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="3Sc-lx-YKH">
|
||||
<rect key="frame" x="234" y="155" width="149" height="23.666666666666657"/>
|
||||
<color key="tintColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<state key="normal" title="Export OBJ-PLY" image="square.and.arrow.up" catalog="system"/>
|
||||
<connections>
|
||||
<action selector="exportOBJPLYAction:" destination="zah-iI-EPt" eventType="touchUpInside" id="md0-pv-zlf"/>
|
||||
</connections>
|
||||
</button>
|
||||
<slider opaque="NO" contentMode="scaleToFill" placeholderIntrinsicWidth="114" placeholderIntrinsicHeight="30" contentHorizontalAlignment="center" contentVerticalAlignment="center" value="80" minValue="0.0" maxValue="120" translatesAutoresizingMaskIntoConstraints="NO" id="30J-Tx-NRW" userLabel="OrthoClipDistanceSlider">
|
||||
<rect key="frame" x="-2" y="682" width="122" height="31"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="118" id="dsv-im-K52"/>
|
||||
</constraints>
|
||||
<connections>
|
||||
<action selector="clipDistanceAction:" destination="zah-iI-EPt" eventType="valueChanged" id="iKj-nz-0KW"/>
|
||||
</connections>
|
||||
</slider>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Toast Label" textAlignment="center" lineBreakMode="wordWrap" numberOfLines="4" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="JMv-UE-cvK" userLabel="ToastLabel">
|
||||
<rect key="frame" x="51" y="637.33333333333337" width="291" height="20.333333333333371"/>
|
||||
<accessibility key="accessibilityConfiguration">
|
||||
<accessibilityTraits key="traits" staticText="YES" notEnabled="YES"/>
|
||||
</accessibility>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<slider opaque="NO" contentMode="scaleToFill" placeholderIntrinsicWidth="114" placeholderIntrinsicHeight="30" contentHorizontalAlignment="center" contentVerticalAlignment="center" value="90" minValue="0.0" maxValue="180" translatesAutoresizingMaskIntoConstraints="NO" id="Z1x-Af-hdf" userLabel="GridRotationSlider">
|
||||
<rect key="frame" x="132" y="727" width="122" height="31"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="118" id="KDl-lP-Jj7"/>
|
||||
</constraints>
|
||||
<connections>
|
||||
<action selector="rotateGridAction:" destination="zah-iI-EPt" eventType="valueChanged" id="eiC-QR-TYH"/>
|
||||
</connections>
|
||||
</slider>
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="aWA-YQ-w5B" userLabel="TeleportButton">
|
||||
<rect key="frame" x="10" y="396.66666666666669" width="62.666666666666671" height="60"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="60" id="fe3-pR-D97"/>
|
||||
<constraint firstAttribute="width" constant="60" id="t1H-Yp-Ayy"/>
|
||||
</constraints>
|
||||
<color key="tintColor" systemColor="systemGreenColor"/>
|
||||
<inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
|
||||
<state key="normal" backgroundImage="accessibility.badge.arrow.up.right" catalog="system"/>
|
||||
<connections>
|
||||
<action selector="teleportButtonAction:" destination="zah-iI-EPt" eventType="touchUpInside" id="acD-kc-XA8"/>
|
||||
</connections>
|
||||
</button>
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="773-n4-lob" userLabel="ViewButton">
|
||||
<rect key="frame" x="321" y="756.33333333333337" width="52" height="40"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="52" id="epT-x2-WRc"/>
|
||||
<constraint firstAttribute="height" constant="44" id="wAe-I1-qhs"/>
|
||||
</constraints>
|
||||
<color key="tintColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<state key="normal" backgroundImage="eye" catalog="system">
|
||||
<color key="titleColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
</state>
|
||||
</button>
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Z7f-kc-Rob" userLabel="MeasuringModeButton">
|
||||
<rect key="frame" x="293" y="687.33333333333337" width="80" height="32.333333333333371"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" secondItem="Z7f-kc-Rob" secondAttribute="height" multiplier="52:27" id="78b-kS-OdV"/>
|
||||
<constraint firstAttribute="width" constant="80" id="PFZ-dH-x12"/>
|
||||
</constraints>
|
||||
<color key="tintColor" systemColor="systemYellowColor"/>
|
||||
<inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
|
||||
<state key="normal" backgroundImage="ruler" catalog="system"/>
|
||||
<connections>
|
||||
<action selector="startMeasuring:" destination="zah-iI-EPt" eventType="touchUpInside" id="uAe-Qu-Wwb"/>
|
||||
</connections>
|
||||
</button>
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="wOV-tT-ZlN" userLabel="StopMeasuring">
|
||||
<rect key="frame" x="123.33333333333333" y="771" width="146.33333333333343" height="22"/>
|
||||
<color key="tintColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<state key="normal" title="Stop Measuring" image="xmark.square" catalog="system">
|
||||
<color key="titleColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
</state>
|
||||
<connections>
|
||||
<action selector="stopCameraAction:" destination="zah-iI-EPt" eventType="touchUpInside" id="UY3-Dh-T9g"/>
|
||||
</connections>
|
||||
</button>
|
||||
</subviews>
|
||||
<viewLayoutGuide key="safeArea" id="qAR-pI-uT2"/>
|
||||
<constraints>
|
||||
<constraint firstItem="KlF-4H-k6I" firstAttribute="leading" secondItem="qAR-pI-uT2" secondAttribute="leading" constant="16" id="14l-HO-Yqo"/>
|
||||
<constraint firstItem="kPv-DO-hpd" firstAttribute="centerY" secondItem="sqF-4e-2HU" secondAttribute="centerY" id="4S8-5c-tBm"/>
|
||||
<constraint firstItem="qAR-pI-uT2" firstAttribute="trailing" secondItem="773-n4-lob" secondAttribute="trailing" constant="20" id="6TZ-Iy-b1B"/>
|
||||
<constraint firstItem="773-n4-lob" firstAttribute="top" secondItem="Z7f-kc-Rob" secondAttribute="bottom" constant="30" id="7cF-fT-hfI"/>
|
||||
<constraint firstItem="JMv-UE-cvK" firstAttribute="leading" secondItem="sqF-4e-2HU" secondAttribute="leadingMargin" constant="35" id="Awg-pU-JkT"/>
|
||||
<constraint firstItem="KlF-4H-k6I" firstAttribute="top" secondItem="qAR-pI-uT2" secondAttribute="top" constant="20" id="CS3-Rk-Wxs"/>
|
||||
<constraint firstItem="012-W3-dOS" firstAttribute="centerX" secondItem="sqF-4e-2HU" secondAttribute="centerX" id="IsC-yB-kNs"/>
|
||||
<constraint firstItem="qAR-pI-uT2" firstAttribute="bottom" secondItem="wOV-tT-ZlN" secondAttribute="bottom" constant="25" id="Kab-84-pPU"/>
|
||||
<constraint firstItem="JMv-UE-cvK" firstAttribute="centerX" secondItem="sqF-4e-2HU" secondAttribute="centerX" id="NIf-UH-gZ7"/>
|
||||
<constraint firstItem="Jj4-ow-MwD" firstAttribute="centerX" secondItem="sqF-4e-2HU" secondAttribute="centerX" id="OLx-LR-8xj"/>
|
||||
<constraint firstItem="aWA-YQ-w5B" firstAttribute="leading" secondItem="sqF-4e-2HU" secondAttribute="leading" constant="10" id="Rlo-Ir-NqY"/>
|
||||
<constraint firstItem="012-W3-dOS" firstAttribute="top" secondItem="Z1x-Af-hdf" secondAttribute="bottom" constant="15" id="RpS-k0-btM"/>
|
||||
<constraint firstItem="ozY-dg-YOd" firstAttribute="top" secondItem="qAR-pI-uT2" secondAttribute="top" constant="20" id="TFT-we-noh"/>
|
||||
<constraint firstItem="qAR-pI-uT2" firstAttribute="trailing" secondItem="Z7f-kc-Rob" secondAttribute="trailing" constant="20" id="Tbc-4P-ryD"/>
|
||||
<constraint firstItem="aWA-YQ-w5B" firstAttribute="centerY" secondItem="sqF-4e-2HU" secondAttribute="centerY" id="YXX-yd-QGL"/>
|
||||
<constraint firstAttribute="trailingMargin" secondItem="JMv-UE-cvK" secondAttribute="trailing" constant="35" id="Ya5-GD-1rM"/>
|
||||
<constraint firstItem="30J-Tx-NRW" firstAttribute="leading" secondItem="sqF-4e-2HU" secondAttribute="leading" id="ZBG-GX-P1X"/>
|
||||
<constraint firstItem="wOV-tT-ZlN" firstAttribute="centerX" secondItem="sqF-4e-2HU" secondAttribute="centerX" id="aPp-NO-q0A"/>
|
||||
<constraint firstItem="3Sc-lx-YKH" firstAttribute="top" secondItem="ozY-dg-YOd" secondAttribute="bottom" constant="16" id="abR-Tj-Nua"/>
|
||||
<constraint firstItem="qAR-pI-uT2" firstAttribute="bottom" secondItem="012-W3-dOS" secondAttribute="bottom" constant="24" id="dcl-mV-bH1"/>
|
||||
<constraint firstItem="9oq-op-NGV" firstAttribute="centerX" secondItem="sqF-4e-2HU" secondAttribute="centerX" id="g5b-gW-Amg"/>
|
||||
<constraint firstItem="qAR-pI-uT2" firstAttribute="bottom" secondItem="773-n4-lob" secondAttribute="bottom" constant="20" id="h09-nI-8yH"/>
|
||||
<constraint firstItem="9oq-op-NGV" firstAttribute="top" secondItem="JMv-UE-cvK" secondAttribute="bottom" constant="113.33" id="icg-DR-ZpX"/>
|
||||
<constraint firstItem="qAR-pI-uT2" firstAttribute="bottom" secondItem="9oq-op-NGV" secondAttribute="bottom" constant="25" id="lFI-66-D3N"/>
|
||||
<constraint firstAttribute="trailing" secondItem="kPv-DO-hpd" secondAttribute="trailing" constant="10" id="lFv-p3-LIS"/>
|
||||
<constraint firstItem="qAR-pI-uT2" firstAttribute="trailing" secondItem="ozY-dg-YOd" secondAttribute="trailing" constant="20" id="ov4-d2-OMy"/>
|
||||
<constraint firstItem="012-W3-dOS" firstAttribute="top" secondItem="30J-Tx-NRW" secondAttribute="bottom" constant="60" id="tbj-nG-nfI"/>
|
||||
<constraint firstItem="Z1x-Af-hdf" firstAttribute="leading" secondItem="30J-Tx-NRW" secondAttribute="trailing" constant="16" id="uMj-kM-hlH"/>
|
||||
<constraint firstItem="qAR-pI-uT2" firstAttribute="trailing" secondItem="3Sc-lx-YKH" secondAttribute="trailing" constant="10" id="v2K-Dp-Kyn"/>
|
||||
<constraint firstItem="Jj4-ow-MwD" firstAttribute="centerY" secondItem="sqF-4e-2HU" secondAttribute="centerY" id="vmc-4u-BtF"/>
|
||||
</constraints>
|
||||
<connections>
|
||||
<outlet property="delegate" destination="zah-iI-EPt" id="zXM-3t-Cw4"/>
|
||||
</connections>
|
||||
</glkView>
|
||||
<connections>
|
||||
<outlet property="addMeasureButton" destination="lFB-Lm-zFS" id="iOG-iO-mMQ"/>
|
||||
<outlet property="closeVisualizationButton" destination="012-W3-dOS" id="qSV-q9-eOP"/>
|
||||
<outlet property="exportOBJPLYButton" destination="3Sc-lx-YKH" id="ZvS-VQ-nsg"/>
|
||||
<outlet property="libraryButton" destination="9kh-4C-KyP" id="Mvv-uQ-kmi"/>
|
||||
<outlet property="measuringModeButton" destination="Z7f-kc-Rob" id="C0D-Pc-wdr"/>
|
||||
<outlet property="menuButton" destination="y53-OI-O76" id="v3g-JB-SsY"/>
|
||||
<outlet property="newScanButtonLarge" destination="Jj4-ow-MwD" id="0Hv-3K-Xjh"/>
|
||||
<outlet property="orthoDistanceSlider" destination="30J-Tx-NRW" id="4J1-8u-tDY"/>
|
||||
<outlet property="orthoGridSlider" destination="Z1x-Af-hdf" id="Zsn-xz-jn0"/>
|
||||
<outlet property="recordButton" destination="7Lv-u6-mGh" id="xTu-EK-FH2"/>
|
||||
<outlet property="removeMeasureButton" destination="c1k-0i-64A" id="E9z-yH-Vye"/>
|
||||
<outlet property="statusLabel" destination="KlF-4H-k6I" id="NmA-K5-UOw"/>
|
||||
<outlet property="stopButton" destination="mJN-Ru-yPg" id="DND-gz-jLg"/>
|
||||
<outlet property="stopCameraButton" destination="9oq-op-NGV" id="sxO-jc-luC"/>
|
||||
<outlet property="stopMeasuringButton" destination="wOV-tT-ZlN" id="iK5-hG-9q0"/>
|
||||
<outlet property="teleportButton" destination="aWA-YQ-w5B" id="KTE-cK-RCI"/>
|
||||
<outlet property="toastLabel" destination="JMv-UE-cvK" id="9a7-QF-h02"/>
|
||||
<outlet property="viewButton" destination="773-n4-lob" id="deU-Na-mBk"/>
|
||||
</connections>
|
||||
</glkViewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="plN-WG-seA" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="-235.87786259541983" y="-586.61971830985919"/>
|
||||
</scene>
|
||||
<!--Unsupported View Controller-->
|
||||
<scene sceneID="sJB-xy-u63">
|
||||
<objects>
|
||||
<viewController storyboardIdentifier="unsupportedDeviceMessage" id="v3G-nW-gVc" userLabel="Unsupported View Controller" sceneMemberID="viewController">
|
||||
<view key="view" contentMode="scaleToFill" id="hzM-1k-POo">
|
||||
<rect key="frame" x="0.0" y="0.0" width="393" height="852"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Unsupported Device" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" enabled="NO" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="kZt-ct-4KD">
|
||||
<rect key="frame" x="21" y="352.33333333333331" width="351.33333333333331" height="33.666666666666686"/>
|
||||
<fontDescription key="fontDescription" style="UICTFontTextStyleTitle1"/>
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" enabled="NO" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="4Js-Hw-3QU">
|
||||
<rect key="frame" x="21" y="394" width="351.33333333333331" height="64.333333333333314"/>
|
||||
<string key="text">This app requires a LiDAR-capable device, such as the second-generation iPad Pro 11-inch and fourth-generation iPad Pro 12.9-inch.</string>
|
||||
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
</subviews>
|
||||
<viewLayoutGuide key="safeArea" id="Wfl-Ts-arS"/>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
<constraints>
|
||||
<constraint firstItem="kZt-ct-4KD" firstAttribute="centerX" secondItem="hzM-1k-POo" secondAttribute="centerX" id="5BV-Ql-eBq"/>
|
||||
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="4Js-Hw-3QU" secondAttribute="trailing" constant="20" symbolic="YES" id="5Sg-eL-Yhf"/>
|
||||
<constraint firstItem="4Js-Hw-3QU" firstAttribute="centerY" secondItem="hzM-1k-POo" secondAttribute="centerY" id="M1k-d1-BNV"/>
|
||||
<constraint firstItem="4Js-Hw-3QU" firstAttribute="top" secondItem="kZt-ct-4KD" secondAttribute="bottom" constant="8" symbolic="YES" id="PjQ-ik-Z1B"/>
|
||||
<constraint firstItem="kZt-ct-4KD" firstAttribute="width" secondItem="4Js-Hw-3QU" secondAttribute="width" id="aQe-nl-Pyq"/>
|
||||
<constraint firstItem="4Js-Hw-3QU" firstAttribute="centerX" secondItem="hzM-1k-POo" secondAttribute="centerX" id="cww-hm-oLb"/>
|
||||
<constraint firstItem="4Js-Hw-3QU" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="hzM-1k-POo" secondAttribute="leading" constant="20" symbolic="YES" id="jfM-fP-rth"/>
|
||||
</constraints>
|
||||
</view>
|
||||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="jam-V0-csO" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="476" y="-586"/>
|
||||
</scene>
|
||||
</scenes>
|
||||
<resources>
|
||||
<image name="accessibility.badge.arrow.up.right" catalog="system" width="128" height="114"/>
|
||||
<image name="ellipsis.circle" catalog="system" width="128" height="123"/>
|
||||
<image name="eye" catalog="system" width="128" height="79"/>
|
||||
<image name="folder" catalog="system" width="128" height="96"/>
|
||||
<image name="minus.circle" catalog="system" width="128" height="123"/>
|
||||
<image name="plus.app" catalog="system" width="128" height="114"/>
|
||||
<image name="plus.viewfinder" catalog="system" width="128" height="115"/>
|
||||
<image name="record.circle" catalog="system" width="128" height="123"/>
|
||||
<image name="ruler" catalog="system" width="128" height="57"/>
|
||||
<image name="square.and.arrow.up" catalog="system" width="108" height="128"/>
|
||||
<image name="stop.circle" catalog="system" width="128" height="123"/>
|
||||
<image name="xmark.square" catalog="system" width="128" height="114"/>
|
||||
<systemColor name="systemGreenColor">
|
||||
<color red="0.20392156859999999" green="0.78039215689999997" blue="0.34901960780000002" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</systemColor>
|
||||
<systemColor name="systemRedColor">
|
||||
<color red="1" green="0.23137254900000001" blue="0.18823529410000001" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</systemColor>
|
||||
<systemColor name="systemYellowColor">
|
||||
<color red="1" green="0.80000000000000004" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</systemColor>
|
||||
</resources>
|
||||
</document>
|
||||
@@ -0,0 +1,194 @@
|
||||
/**
|
||||
* Copyright (c) 2017 Razeware LLC
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Notwithstanding the foregoing, you may not use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, create a derivative work, and/or sell copies of the
|
||||
* Software in any work that is designed, intended, or marketed for pedagogical or
|
||||
* instructional purposes related to programming, coding, application development,
|
||||
* or information technology. Permission for such use, copying, modification,
|
||||
* merger, publication, distribution, sublicensing, creation of derivative works,
|
||||
* or sale is expressly withheld.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
|
||||
import UIKit
|
||||
|
||||
protocol DatabaseViewDelegate: class {
|
||||
func databaseShared(databaseURL: URL)
|
||||
func databaseRenamed(databaseURL: URL)
|
||||
func databaseDeleted(databaseURL: URL)
|
||||
}
|
||||
|
||||
class DatabaseView: UIView {
|
||||
|
||||
private var coverImageView: UIImageView!
|
||||
private var indicatorView: UIActivityIndicatorView!
|
||||
private var valueObservation: NSKeyValueObservation!
|
||||
private var textLabel: UILabel!
|
||||
private var databaseURL: URL!
|
||||
public var delegate: DatabaseViewDelegate!
|
||||
|
||||
required init?(coder aDecoder: NSCoder) {
|
||||
super.init(coder: aDecoder)
|
||||
commonInit(databasePath: "NA")
|
||||
}
|
||||
|
||||
init(frame: CGRect, databaseURL: URL) {
|
||||
super.init(frame: frame)
|
||||
self.databaseURL = databaseURL
|
||||
commonInit(databasePath: databaseURL.path)
|
||||
if let image = ViewController.previewImages[databaseURL.path]
|
||||
{
|
||||
self.coverImageView.image = image
|
||||
}
|
||||
else
|
||||
{
|
||||
DispatchQueue.global().async {
|
||||
let downloadedImage = getPreviewImage(databasePath: databaseURL.path)
|
||||
DispatchQueue.main.async {
|
||||
self.coverImageView.image = downloadedImage
|
||||
ViewController.previewImages[databaseURL.path] = downloadedImage
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func commonInit(databasePath: String) {
|
||||
|
||||
// Setup the background
|
||||
backgroundColor = .black
|
||||
// Create the cover image view
|
||||
coverImageView = UIImageView()
|
||||
coverImageView.translatesAutoresizingMaskIntoConstraints = false
|
||||
|
||||
valueObservation = coverImageView.observe(\.image, options: [.new]) { [unowned self] observed, change in
|
||||
if change.newValue is UIImage {
|
||||
self.indicatorView.stopAnimating()
|
||||
}
|
||||
}
|
||||
|
||||
//Text Label
|
||||
textLabel = UILabel()
|
||||
textLabel.numberOfLines = 0
|
||||
textLabel.text =
|
||||
URL(fileURLWithPath: databasePath).lastPathComponent + "\n" +
|
||||
URL(fileURLWithPath: databasePath).fileSizeString + "\n" +
|
||||
(try! URL(fileURLWithPath: databasePath).resourceValues(forKeys: [.contentModificationDateKey]).contentModificationDate!.getFormattedDate(format: "yyyy-MM-dd HH:mm:ss"))
|
||||
textLabel.textColor = .white
|
||||
textLabel.textAlignment = .left
|
||||
|
||||
//Stack View
|
||||
let stackView = UIStackView()
|
||||
stackView.axis = NSLayoutConstraint.Axis.horizontal
|
||||
stackView.distribution = UIStackView.Distribution.fill
|
||||
stackView.alignment = UIStackView.Alignment.center
|
||||
stackView.spacing = 8.0
|
||||
|
||||
stackView.addArrangedSubview(coverImageView)
|
||||
stackView.addArrangedSubview(textLabel)
|
||||
stackView.translatesAutoresizingMaskIntoConstraints = false
|
||||
|
||||
addSubview(stackView)
|
||||
|
||||
// Create the indicator view
|
||||
indicatorView = UIActivityIndicatorView()
|
||||
indicatorView.translatesAutoresizingMaskIntoConstraints = false
|
||||
indicatorView.style = .whiteLarge
|
||||
indicatorView.startAnimating()
|
||||
addSubview(indicatorView)
|
||||
|
||||
NSLayoutConstraint.activate([
|
||||
stackView.leftAnchor.constraint(equalTo: self.leftAnchor),
|
||||
stackView.rightAnchor.constraint(equalTo: self.rightAnchor),
|
||||
stackView.topAnchor.constraint(equalTo: self.topAnchor),
|
||||
stackView.bottomAnchor.constraint(equalTo: self.bottomAnchor),
|
||||
stackView.leadingAnchor.constraint(equalTo: self.leadingAnchor),
|
||||
coverImageView.widthAnchor.constraint(equalToConstant: 180 - 5),
|
||||
indicatorView.centerXAnchor.constraint(equalTo: coverImageView.centerXAnchor),
|
||||
indicatorView.centerYAnchor.constraint(equalTo: coverImageView.centerYAnchor)
|
||||
])
|
||||
|
||||
let interaction = UIContextMenuInteraction(delegate: self)
|
||||
self.addInteraction(interaction)
|
||||
}
|
||||
|
||||
func highlightDatabase(_ didHighlightView: Bool) {
|
||||
if didHighlightView == true {
|
||||
backgroundColor = .white
|
||||
textLabel.textColor = .black
|
||||
} else {
|
||||
backgroundColor = .black
|
||||
textLabel.textColor = .white
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension URL {
|
||||
var attributes: [FileAttributeKey : Any]? {
|
||||
do {
|
||||
return try FileManager.default.attributesOfItem(atPath: path)
|
||||
} catch let error as NSError {
|
||||
print("FileAttribute error: \(error)")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var fileSize: UInt64 {
|
||||
return attributes?[.size] as? UInt64 ?? UInt64(0)
|
||||
}
|
||||
|
||||
var fileSizeString: String {
|
||||
return ByteCountFormatter.string(fromByteCount: Int64(fileSize), countStyle: .file)
|
||||
}
|
||||
|
||||
var creationDate: Date? {
|
||||
return attributes?[.creationDate] as? Date
|
||||
}
|
||||
}
|
||||
|
||||
extension DatabaseView: UIContextMenuInteractionDelegate {
|
||||
|
||||
func contextMenuInteraction(_ interaction: UIContextMenuInteraction, configurationForMenuAtLocation location: CGPoint) -> UIContextMenuConfiguration? {
|
||||
return UIContextMenuConfiguration(identifier: nil, previewProvider: nil) { suggestedActions in
|
||||
|
||||
// Create an action for sharing
|
||||
let share = UIAction(title: "Share", image: UIImage(systemName: "square.and.arrow.up")) { action in
|
||||
// Show system share sheet
|
||||
self.delegate?.databaseShared(databaseURL: self.databaseURL)
|
||||
}
|
||||
|
||||
// Create an action for renaming
|
||||
let rename = UIAction(title: "Rename", image: UIImage(systemName: "square.and.pencil")) { action in
|
||||
// Perform renaming
|
||||
self.delegate?.databaseRenamed(databaseURL: self.databaseURL)
|
||||
}
|
||||
|
||||
// Here we specify the "destructive" attribute to show that it’s destructive in nature
|
||||
let delete = UIAction(title: "Delete", image: UIImage(systemName: "trash"), attributes: .destructive) { action in
|
||||
// Perform delete
|
||||
self.delegate?.databaseDeleted(databaseURL: self.databaseURL)
|
||||
}
|
||||
|
||||
// Create and return a UIMenu with all of the actions as children
|
||||
return UIMenu(title: "", children: [share, rename, delete])
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "RTAB-Map1024.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
|
After Width: | Height: | Size: 58 KiB |
@@ -0,0 +1,80 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>$(DEVELOPMENT_LANGUAGE)</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>$(EXECUTABLE_NAME)</string>
|
||||
<key>CFBundleIcons</key>
|
||||
<dict/>
|
||||
<key>CFBundleIcons~ipad</key>
|
||||
<dict/>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>RTAB-Map</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>$(MARKETING_VERSION)</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>$(CURRENT_PROJECT_VERSION)</string>
|
||||
<key>LSRequiresIPhoneOS</key>
|
||||
<true/>
|
||||
<key>LSSupportsOpeningDocumentsInPlace</key>
|
||||
<true/>
|
||||
<key>NSCameraUsageDescription</key>
|
||||
<string>The camera is used for scanning (ideally with LiDAR).</string>
|
||||
<key>NSLocationWhenInUseUsageDescription</key>
|
||||
<string>The GPS is used when GPS option is enabled in Settings->Mapping...</string>
|
||||
<key>UIApplicationSceneManifest</key>
|
||||
<dict>
|
||||
<key>UIApplicationSupportsMultipleScenes</key>
|
||||
<false/>
|
||||
<key>UISceneConfigurations</key>
|
||||
<dict>
|
||||
<key>UIWindowSceneSessionRoleApplication</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>UISceneConfigurationName</key>
|
||||
<string>Default Configuration</string>
|
||||
<key>UISceneDelegateClassName</key>
|
||||
<string>$(PRODUCT_MODULE_NAME).SceneDelegate</string>
|
||||
<key>UISceneStoryboardFile</key>
|
||||
<string>Main</string>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>UIApplicationSupportsIndirectInputEvents</key>
|
||||
<true/>
|
||||
<key>UIFileSharingEnabled</key>
|
||||
<true/>
|
||||
<key>UILaunchStoryboardName</key>
|
||||
<string>LaunchScreen</string>
|
||||
<key>UIMainStoryboardFile</key>
|
||||
<string>Main</string>
|
||||
<key>UIRequiredDeviceCapabilities</key>
|
||||
<array>
|
||||
<string>armv7</string>
|
||||
<string>opengles-2</string>
|
||||
<string>arkit</string>
|
||||
</array>
|
||||
<key>UISupportedInterfaceOrientations</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationPortrait</string>
|
||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
</array>
|
||||
<key>UISupportedInterfaceOrientations~ipad</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationPortrait</string>
|
||||
<string>UIInterfaceOrientationPortraitUpsideDown</string>
|
||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -0,0 +1,689 @@
|
||||
//
|
||||
// PCLWrapper.cpp
|
||||
// ThreeDScanner
|
||||
//
|
||||
// Created by Steven Roach on 2/9/18.
|
||||
// Copyright © 2018 Steven Roach. All rights reserved.
|
||||
//
|
||||
|
||||
#include "NativeWrapper.hpp"
|
||||
#include "RTABMapApp.h"
|
||||
#include <rtabmap/core/DBDriverSqlite3.h>
|
||||
|
||||
inline RTABMapApp *native(const void *object) {
|
||||
return (RTABMapApp *)object;
|
||||
}
|
||||
|
||||
const void * createNativeApplication()
|
||||
{
|
||||
RTABMapApp *app = new RTABMapApp();
|
||||
return (void *)app;
|
||||
}
|
||||
|
||||
void setupCallbacksNative(const void *object, void * classPtr,
|
||||
void(*progressCallback)(void*, int, int),
|
||||
void(*initCallback)(void *, int, const char*),
|
||||
void(*statsUpdatedCallback)(void *,
|
||||
int, int, int, int,
|
||||
float,
|
||||
int, int, int, int, int ,int,
|
||||
float,
|
||||
int,
|
||||
float,
|
||||
int,
|
||||
float, float, float, float,
|
||||
int, int,
|
||||
float, float, float, float, float, float),
|
||||
void(*cameraInfoEventCallback)(void *, int, const char*, const char*))
|
||||
{
|
||||
if(object)
|
||||
{
|
||||
native(object)->setupSwiftCallbacks(classPtr, progressCallback, initCallback, statsUpdatedCallback, cameraInfoEventCallback);
|
||||
}
|
||||
else
|
||||
{
|
||||
UERROR("object is null!");
|
||||
}
|
||||
}
|
||||
|
||||
void destroyNativeApplication(const void *object)
|
||||
{
|
||||
if(object)
|
||||
{
|
||||
delete native(object);
|
||||
}
|
||||
else
|
||||
{
|
||||
UERROR("object is null!");
|
||||
}
|
||||
}
|
||||
|
||||
void setScreenRotationNative(const void *object, int displayRotation)
|
||||
{
|
||||
if(object)
|
||||
{
|
||||
return native(object)->setScreenRotation(displayRotation, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
UERROR("object is null!");
|
||||
}
|
||||
}
|
||||
|
||||
int openDatabaseNative(const void *object, const char * databasePath, bool databaseInMemory, bool optimize, bool clearDatabase)
|
||||
{
|
||||
if(object)
|
||||
{
|
||||
return native(object)->openDatabase(databasePath, databaseInMemory, optimize, clearDatabase);
|
||||
}
|
||||
else
|
||||
{
|
||||
UERROR("object is null!");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
void saveNative(const void *object, const char * databasePath)
|
||||
{
|
||||
if(object)
|
||||
{
|
||||
return native(object)->save(databasePath);
|
||||
}
|
||||
else
|
||||
{
|
||||
UERROR("object is null!");
|
||||
}
|
||||
}
|
||||
|
||||
bool recoverNative(const void *object, const char * from, const char * to)
|
||||
{
|
||||
if(object)
|
||||
{
|
||||
return native(object)->recover(from, to);
|
||||
}
|
||||
else
|
||||
{
|
||||
UERROR("object is null!");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void cancelProcessingNative(const void *object)
|
||||
{
|
||||
if(object)
|
||||
{
|
||||
native(object)->cancelProcessing();
|
||||
}
|
||||
else
|
||||
{
|
||||
UERROR("object is null!");
|
||||
}
|
||||
}
|
||||
|
||||
int postProcessingNative(const void *object, int approach)
|
||||
{
|
||||
if(object)
|
||||
{
|
||||
return native(object)->postProcessing(approach);
|
||||
}
|
||||
else
|
||||
{
|
||||
UERROR("object is null!");
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
bool exportMeshNative(
|
||||
const void *object,
|
||||
float cloudVoxelSize,
|
||||
bool regenerateCloud,
|
||||
bool meshing,
|
||||
int textureSize,
|
||||
int textureCount,
|
||||
int normalK,
|
||||
bool optimized,
|
||||
float optimizedVoxelSize,
|
||||
int optimizedDepth,
|
||||
int optimizedMaxPolygons,
|
||||
float optimizedColorRadius,
|
||||
bool optimizedCleanWhitePolygons,
|
||||
int optimizedMinClusterSize,
|
||||
float optimizedMaxTextureDistance,
|
||||
int optimizedMinTextureClusterSize,
|
||||
int textureVertexColorPolicy,
|
||||
bool blockRendering)
|
||||
{
|
||||
if(object)
|
||||
{
|
||||
return native(object)->exportMesh(cloudVoxelSize, regenerateCloud, meshing, textureSize, textureCount, normalK, optimized, optimizedVoxelSize, optimizedDepth, optimizedMaxPolygons, optimizedColorRadius, optimizedCleanWhitePolygons, optimizedMinClusterSize, optimizedMaxTextureDistance, optimizedMinTextureClusterSize, textureVertexColorPolicy, blockRendering);
|
||||
}
|
||||
else
|
||||
{
|
||||
UERROR("object is null!");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool postExportationNative(const void *object, bool visualize)
|
||||
{
|
||||
if(object)
|
||||
{
|
||||
return native(object)->postExportation(visualize);
|
||||
}
|
||||
else
|
||||
{
|
||||
UERROR("object is null!");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool writeExportedMeshNative(const void *object, const char * directory, const char * name)
|
||||
{
|
||||
if(object)
|
||||
{
|
||||
return native(object)->writeExportedMesh(directory, name);
|
||||
}
|
||||
else
|
||||
{
|
||||
UERROR("object is null!");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void initGlContentNative(const void *object) {
|
||||
if(object)
|
||||
{
|
||||
native(object)->InitializeGLContent();
|
||||
}
|
||||
else
|
||||
{
|
||||
UERROR("object is null!");
|
||||
}
|
||||
}
|
||||
|
||||
void setupGraphicNative(const void *object, int width, int height) {
|
||||
if(object)
|
||||
{
|
||||
native(object)->SetViewPort(width, height);
|
||||
}
|
||||
else
|
||||
{
|
||||
UERROR("object is null!");
|
||||
}
|
||||
}
|
||||
|
||||
void onTouchEventNative(const void *object, int touch_count, int event, float x0, float y0, float x1,
|
||||
float y1) {
|
||||
if(object)
|
||||
{
|
||||
using namespace tango_gl;
|
||||
GestureCamera::TouchEvent touch_event =
|
||||
static_cast<GestureCamera::TouchEvent>(event);
|
||||
native(object)->OnTouchEvent(touch_count, touch_event, x0, y0, x1, y1);
|
||||
}
|
||||
else
|
||||
{
|
||||
UERROR("object is null!");
|
||||
}
|
||||
}
|
||||
|
||||
void setPausedMappingNative(const void *object, bool paused)
|
||||
{
|
||||
if(object)
|
||||
{
|
||||
return native(object)->setPausedMapping(paused);
|
||||
}
|
||||
else
|
||||
{
|
||||
UERROR("object is null!");
|
||||
}
|
||||
}
|
||||
|
||||
int renderNative(const void *object) {
|
||||
if(object)
|
||||
{
|
||||
return native(object)->Render();
|
||||
}
|
||||
else
|
||||
{
|
||||
UERROR("object is null!");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
bool startCameraNative(const void *object) {
|
||||
if(object)
|
||||
{
|
||||
return native(object)->startCamera();
|
||||
}
|
||||
else
|
||||
{
|
||||
UERROR("object is null!");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void stopCameraNative(const void *object) {
|
||||
if(object)
|
||||
{
|
||||
native(object)->stopCamera();
|
||||
}
|
||||
else
|
||||
{
|
||||
UERROR("object is null!");
|
||||
}
|
||||
}
|
||||
|
||||
void setCameraNative(const void *object, int type) {
|
||||
if(object)
|
||||
{
|
||||
native(object)->SetCameraType(tango_gl::GestureCamera::CameraType(type));
|
||||
}
|
||||
else
|
||||
{
|
||||
UERROR("object is null!");
|
||||
}
|
||||
}
|
||||
|
||||
void postOdometryEventNative(const void *object,
|
||||
float x, float y, float z, float qx, float qy, float qz, float qw,
|
||||
float fx, float fy, float cx, float cy,
|
||||
double stamp,
|
||||
const void * yPlane, const void * uPlane, const void * vPlane, int yPlaneLen, int rgbWidth, int rgbHeight, int rgbFormat,
|
||||
const void * depth, int depthLen, int depthWidth, int depthHeight, int depthFormat,
|
||||
const void * conf, int confLen, int confWidth, int confHeight, int confFormat,
|
||||
const void * points, int pointsLen, int pointsChannels,
|
||||
float vx, float vy, float vz, float vqx, float vqy, float vqz, float vqw,
|
||||
float p00, float p11, float p02, float p12, float p22, float p32, float p23,
|
||||
float t0, float t1, float t2, float t3, float t4, float t5, float t6, float t7)
|
||||
{
|
||||
if(object)
|
||||
{
|
||||
native(object)->postOdometryEvent(
|
||||
(qx==0.0f && qy==0.0f && qz==0.0f && qw==0.0f)?rtabmap::Transform():rtabmap::Transform(x,y,z,qx,qy,qz,qw),
|
||||
fx,fy,cx,cy, 0,0,0,0,
|
||||
rtabmap::Transform(), rtabmap::Transform(),
|
||||
stamp, 0,
|
||||
yPlane, uPlane, vPlane, yPlaneLen, rgbWidth, rgbHeight, rgbFormat,
|
||||
depth, depthLen, depthWidth, depthHeight, depthFormat,
|
||||
conf, confLen, confWidth, confHeight, confFormat,
|
||||
(const float *)points, pointsLen, pointsChannels,
|
||||
rtabmap::Transform(vx, vy, vz, vqx, vqy, vqz, vqw),
|
||||
p00, p11, p02, p12, p22, p32, p23,
|
||||
t0, t1, t2, t3, t4, t5, t6, t7);
|
||||
}
|
||||
else
|
||||
{
|
||||
UERROR("object is null!");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
ImageNative getPreviewImageNative(const char * databasePath)
|
||||
{
|
||||
ImageNative imageNative;
|
||||
imageNative.data = 0;
|
||||
imageNative.objectPtr = 0;
|
||||
rtabmap::DBDriverSqlite3 driver;
|
||||
if(driver.openConnection(databasePath))
|
||||
{
|
||||
cv::Mat image = driver.loadPreviewImage();
|
||||
if(image.empty())
|
||||
{
|
||||
return imageNative;
|
||||
}
|
||||
cv::Mat * imagePtr = new cv::Mat();
|
||||
// We should add alpha channel
|
||||
cv::cvtColor(image, *imagePtr, cv::COLOR_BGR2BGRA);
|
||||
std::vector<cv::Mat> channels;
|
||||
cv::split(*imagePtr, channels);
|
||||
channels.back() = cv::Scalar(255);
|
||||
cv::merge(channels, *imagePtr);
|
||||
imageNative.objectPtr = imagePtr;
|
||||
imageNative.data = imagePtr->data;
|
||||
imageNative.width = imagePtr->cols;
|
||||
imageNative.height = imagePtr->rows;
|
||||
imageNative.channels = imagePtr->channels();
|
||||
}
|
||||
return imageNative;
|
||||
}
|
||||
|
||||
void releasePreviewImageNative(ImageNative image)
|
||||
{
|
||||
if(image.objectPtr)
|
||||
{
|
||||
delete (cv::Mat*)image.objectPtr;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Parameters
|
||||
void setOnlineBlendingNative(const void *object, bool enabled)
|
||||
{
|
||||
if(object)
|
||||
native(object)->setOnlineBlending(enabled);
|
||||
else
|
||||
UERROR("object is null!");
|
||||
}
|
||||
void setMapCloudShownNative(const void *object, bool shown)
|
||||
{
|
||||
if(object)
|
||||
native(object)->setMapCloudShown(shown);
|
||||
else
|
||||
UERROR("object is null!");
|
||||
}
|
||||
void setOdomCloudShownNative(const void *object, bool shown)
|
||||
{
|
||||
if(object)
|
||||
native(object)->setOdomCloudShown(shown);
|
||||
else
|
||||
UERROR("object is null!");
|
||||
}
|
||||
void setMeshRenderingNative(const void *object, bool enabled, bool withTexture)
|
||||
{
|
||||
if(object)
|
||||
native(object)->setMeshRendering(enabled, withTexture);
|
||||
else
|
||||
UERROR("object is null!");
|
||||
}
|
||||
void setPointSizeNative(const void *object, float value)
|
||||
{
|
||||
if(object)
|
||||
native(object)->setPointSize(value);
|
||||
else
|
||||
UERROR("object is null!");
|
||||
}
|
||||
void setFOVNative(const void *object, float angle)
|
||||
{
|
||||
if(object)
|
||||
native(object)->setFOV(angle);
|
||||
else
|
||||
UERROR("object is null!");
|
||||
}
|
||||
void setOrthoCropFactorNative(const void *object, float value)
|
||||
{
|
||||
if(object)
|
||||
native(object)->setOrthoCropFactor(value);
|
||||
else
|
||||
UERROR("object is null!");
|
||||
}
|
||||
void setGridRotationNative(const void *object, float value)
|
||||
{
|
||||
if(object)
|
||||
native(object)->setGridRotation(value);
|
||||
else
|
||||
UERROR("object is null!");
|
||||
}
|
||||
void setLightingNative(const void *object, bool enabled)
|
||||
{
|
||||
if(object)
|
||||
native(object)->setLighting(enabled);
|
||||
else
|
||||
UERROR("object is null!");
|
||||
}
|
||||
void setBackfaceCullingNative(const void *object, bool enabled)
|
||||
{
|
||||
if(object)
|
||||
native(object)->setBackfaceCulling(enabled);
|
||||
else
|
||||
UERROR("object is null!");
|
||||
}
|
||||
void setWireframeNative(const void *object, bool enabled)
|
||||
{
|
||||
if(object)
|
||||
native(object)->setWireframe(enabled);
|
||||
else
|
||||
UERROR("object is null!");
|
||||
}
|
||||
void setTextureColorSeamsHiddenNative(const void *object, bool hidden)
|
||||
{
|
||||
if(object)
|
||||
native(object)->setTextureColorSeamsHidden(hidden);
|
||||
else
|
||||
UERROR("object is null!");
|
||||
}
|
||||
void setLocalizationModeNative(const void *object, bool enabled)
|
||||
{
|
||||
if(object)
|
||||
native(object)->setLocalizationMode(enabled);
|
||||
else
|
||||
UERROR("object is null!");
|
||||
}
|
||||
void setDataRecorderModeNative(const void *object, bool enabled)
|
||||
{
|
||||
if(object)
|
||||
native(object)->setDataRecorderMode(enabled);
|
||||
else
|
||||
UERROR("object is null!");
|
||||
}
|
||||
void setTrajectoryModeNative(const void *object, bool enabled)
|
||||
{
|
||||
if(object)
|
||||
native(object)->setTrajectoryMode(enabled);
|
||||
else
|
||||
UERROR("object is null!");
|
||||
}
|
||||
void setGraphOptimizationNative(const void *object, bool enabled)
|
||||
{
|
||||
if(object)
|
||||
native(object)->setGraphOptimization(enabled);
|
||||
else
|
||||
UERROR("object is null!");
|
||||
}
|
||||
void setNodesFilteringNative(const void *object, bool enabled)
|
||||
{
|
||||
if(object)
|
||||
native(object)->setNodesFiltering(enabled);
|
||||
else
|
||||
UERROR("object is null!");
|
||||
}
|
||||
void setGraphVisibleNative(const void *object, bool visible)
|
||||
{
|
||||
if(object)
|
||||
native(object)->setGraphVisible(visible);
|
||||
else
|
||||
UERROR("object is null!");
|
||||
}
|
||||
void setGridVisibleNative(const void *object, bool visible)
|
||||
{
|
||||
if(object)
|
||||
native(object)->setGridVisible(visible);
|
||||
else
|
||||
UERROR("object is null!");
|
||||
}
|
||||
void setFullResolutionNative(const void *object, bool enabled)
|
||||
{
|
||||
if(object)
|
||||
native(object)->setFullResolution(enabled);
|
||||
else
|
||||
UERROR("object is null!");
|
||||
}
|
||||
void setSmoothingNative(const void *object, bool enabled)
|
||||
{
|
||||
if(object)
|
||||
native(object)->setSmoothing(enabled);
|
||||
else
|
||||
UERROR("object is null!");
|
||||
}
|
||||
void setDepthBleedingErrorNative(const void *object, float value)
|
||||
{
|
||||
if(object)
|
||||
native(object)->setDepthBleedingError(value);
|
||||
else
|
||||
UERROR("object is null!");
|
||||
}
|
||||
void setAppendModeNative(const void *object, bool enabled)
|
||||
{
|
||||
if(object)
|
||||
native(object)->setAppendMode(enabled);
|
||||
else
|
||||
UERROR("object is null!");
|
||||
}
|
||||
void setUpstreamRelocalizationAccThrNative(const void * object, float value)
|
||||
{
|
||||
if(object)
|
||||
native(object)->setUpstreamRelocalizationAccThr(value);
|
||||
else
|
||||
UERROR("object is null!");
|
||||
}
|
||||
void setMaxCloudDepthNative(const void *object, float value)
|
||||
{
|
||||
if(object)
|
||||
native(object)->setMaxCloudDepth(value);
|
||||
else
|
||||
UERROR("object is null!");
|
||||
}
|
||||
void setMinCloudDepthNative(const void *object, float value)
|
||||
{
|
||||
if(object)
|
||||
native(object)->setMinCloudDepth(value);
|
||||
else
|
||||
UERROR("object is null!");
|
||||
}
|
||||
void setCloudDensityLevelNative(const void *object, int value)
|
||||
{
|
||||
if(object)
|
||||
native(object)->setCloudDensityLevel(value);
|
||||
else
|
||||
UERROR("object is null!");
|
||||
}
|
||||
void setMeshAngleToleranceNative(const void *object, float value)
|
||||
{
|
||||
if(object)
|
||||
native(object)->setMeshAngleTolerance(value);
|
||||
else
|
||||
UERROR("object is null!");
|
||||
}
|
||||
void setMeshDecimationFactorNative(const void *object, float value)
|
||||
{
|
||||
if(object)
|
||||
native(object)->setMeshDecimationFactor(value);
|
||||
else
|
||||
UERROR("object is null!");
|
||||
}
|
||||
void setMeshTriangleSizeNative(const void *object, int value)
|
||||
{
|
||||
if(object)
|
||||
native(object)->setMeshTriangleSize(value);
|
||||
else
|
||||
UERROR("object is null!");
|
||||
}
|
||||
void setClusterRatioNative(const void *object, float value)
|
||||
{
|
||||
if(object)
|
||||
native(object)->setClusterRatio(value);
|
||||
else
|
||||
UERROR("object is null!");
|
||||
}
|
||||
void setMaxGainRadiusNative(const void *object, float value)
|
||||
{
|
||||
if(object)
|
||||
native(object)->setMaxGainRadius(value);
|
||||
else
|
||||
UERROR("object is null!");
|
||||
}
|
||||
void setRenderingTextureDecimationNative(const void *object, int value)
|
||||
{
|
||||
if(object)
|
||||
native(object)->setRenderingTextureDecimation(value);
|
||||
else
|
||||
UERROR("object is null!");
|
||||
}
|
||||
void setBackgroundColorNative(const void *object, float gray)
|
||||
{
|
||||
if(object)
|
||||
native(object)->setBackgroundColor(gray);
|
||||
else
|
||||
UERROR("object is null!");
|
||||
}
|
||||
void setDepthConfidenceNative(const void *object, int value)
|
||||
{
|
||||
if(object)
|
||||
native(object)->setDepthConfidence(value);
|
||||
else
|
||||
UERROR("object is null!");
|
||||
}
|
||||
|
||||
void setExportPointCloudFormatNative(const void *object, const char * format)
|
||||
{
|
||||
if(object)
|
||||
native(object)->setExportPointCloudFormat(format);
|
||||
else
|
||||
UERROR("object is null!");
|
||||
}
|
||||
|
||||
int setMappingParameterNative(const void *object, const char * key, const char * value)
|
||||
{
|
||||
if(object)
|
||||
return native(object)->setMappingParameter(key, value);
|
||||
else
|
||||
UERROR("object is null!");
|
||||
return -1;
|
||||
}
|
||||
|
||||
void setGPSNative(const void *object, double stamp, double longitude, double latitude, double altitude, double accuracy, double bearing)
|
||||
{
|
||||
rtabmap::GPS gps(stamp, longitude, latitude, altitude, accuracy, bearing);
|
||||
if(object)
|
||||
return native(object)->setGPS(gps);
|
||||
else
|
||||
UERROR("object is null!");
|
||||
}
|
||||
|
||||
void addEnvSensorNative(const void *object, int type, float value)
|
||||
{
|
||||
if(object)
|
||||
return native(object)->addEnvSensor(type, value);
|
||||
else
|
||||
UERROR("object is null!");
|
||||
}
|
||||
|
||||
void removeMeasureNative(const void *object)
|
||||
{
|
||||
if(object)
|
||||
return native(object)->removeMeasure();
|
||||
else
|
||||
UERROR("object is null!");
|
||||
}
|
||||
void addMeasureNative(const void *object)
|
||||
{
|
||||
if(object)
|
||||
return native(object)->addMeasureButtonClicked();
|
||||
else
|
||||
UERROR("object is null!");
|
||||
}
|
||||
void teleportNative(const void *object)
|
||||
{
|
||||
if(object)
|
||||
return native(object)->teleportButtonClicked();
|
||||
else
|
||||
UERROR("object is null!");
|
||||
}
|
||||
void setMeasuringModeNative(const void *object, int mode)
|
||||
{
|
||||
if(object)
|
||||
return native(object)->setMeasuringMode(mode);
|
||||
else
|
||||
UERROR("object is null!");
|
||||
}
|
||||
void setMetricSystemNative(const void *object, bool enabled)
|
||||
{
|
||||
if(object)
|
||||
return native(object)->setMetricSystem(enabled);
|
||||
else
|
||||
UERROR("object is null!");
|
||||
}
|
||||
void setMeasuringTextSizeNative(const void *object, float size)
|
||||
{
|
||||
if(object)
|
||||
return native(object)->setMeasuringTextSize(size);
|
||||
else
|
||||
UERROR("object is null!");
|
||||
}
|
||||
void clearMeasuresNative(const void *object)
|
||||
{
|
||||
if(object)
|
||||
return native(object)->clearMeasures();
|
||||
else
|
||||
UERROR("object is null!");
|
||||
}
|
||||
@@ -0,0 +1,149 @@
|
||||
//
|
||||
// PCLWrapper.hpp
|
||||
// ThreeDScanner
|
||||
//
|
||||
// Created by Steven Roach on 2/9/18.
|
||||
// Copyright © 2018 Steven Roach. All rights reserved.
|
||||
//
|
||||
|
||||
#ifndef NativeWrapper_hpp
|
||||
#define NativeWrapper_hpp
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
const void *createNativeApplication();
|
||||
void setupCallbacksNative(const void *object, void * classPtr,
|
||||
void(*progressCallback)(void*, int, int),
|
||||
void(*initCallback)(void *, int, const char*),
|
||||
void(*statsUpdatedCallback)(void *,
|
||||
int, int, int, int,
|
||||
float,
|
||||
int, int, int, int, int ,int,
|
||||
float,
|
||||
int,
|
||||
float,
|
||||
int,
|
||||
float, float, float, float,
|
||||
int, int,
|
||||
float, float, float, float, float, float),
|
||||
void(*cameraInfoEventCallback)(void *, int, const char*, const char*));
|
||||
void destroyNativeApplication(const void *object);
|
||||
void setScreenRotationNative(const void *object, int displayRotation);
|
||||
int openDatabaseNative(const void *object, const char * databasePath, bool databaseInMemory, bool optimize, bool clearDatabase);
|
||||
void saveNative(const void *object, const char * databasePath);
|
||||
bool recoverNative(const void *object, const char * from, const char * to);
|
||||
void cancelProcessingNative(const void * object);
|
||||
int postProcessingNative(const void *object, int approach);
|
||||
bool exportMeshNative(
|
||||
const void *object,
|
||||
float cloudVoxelSize,
|
||||
bool regenerateCloud,
|
||||
bool meshing,
|
||||
int textureSize,
|
||||
int textureCount,
|
||||
int normalK,
|
||||
bool optimized,
|
||||
float optimizedVoxelSize,
|
||||
int optimizedDepth,
|
||||
int optimizedMaxPolygons,
|
||||
float optimizedColorRadius,
|
||||
bool optimizedCleanWhitePolygons,
|
||||
int optimizedMinClusterSize,
|
||||
float optimizedMaxTextureDistance,
|
||||
int optimizedMinTextureClusterSize,
|
||||
int textureVertexColorPolicy,
|
||||
bool blockRendering);
|
||||
bool postExportationNative(const void *object, bool visualize);
|
||||
bool writeExportedMeshNative(const void *object, const char * directory, const char * name);
|
||||
void initGlContentNative(const void *object);
|
||||
void setupGraphicNative(const void *object, int width, int height);
|
||||
void onTouchEventNative(const void *object, int touch_count, int event, float x0, float y0, float x1,
|
||||
float y1);
|
||||
void setPausedMappingNative(const void *object, bool paused);
|
||||
int renderNative(const void *object);
|
||||
bool startCameraNative(const void *object);
|
||||
void stopCameraNative(const void *object);
|
||||
void setCameraNative(const void *object, int type);
|
||||
void postOdometryEventNative(const void *object,
|
||||
float x, float y, float z, float qx, float qy, float qz, float qw,
|
||||
float fx, float fy, float cx, float cy,
|
||||
double stamp,
|
||||
const void * yPlane, const void * uPlane, const void * vPlane, int yPlaneLen, int rgbWidth, int rgbHeight, int rgbFormat,
|
||||
const void * depth, int depthLen, int depthWidth, int depthHeight, int depthFormat,
|
||||
const void * conf, int confLen, int confWidth, int confHeight, int confFormat,
|
||||
const void * points, int pointsLen, int pointsChannels,
|
||||
float vx, float vy, float vz, float vqx, float vqy, float vqz, float vqw,
|
||||
float p00, float p11, float p02, float p12, float p22, float p32, float p23,
|
||||
float t0, float t1, float t2, float t3, float t4, float t5, float t6, float t7);
|
||||
|
||||
void setOnlineBlendingNative(const void *object, bool enabled);
|
||||
void setMapCloudShownNative(const void *object, bool shown);
|
||||
void setOdomCloudShownNative(const void *object, bool shown);
|
||||
void setMeshRenderingNative(const void *object, bool enabled, bool withTexture);
|
||||
void setPointSizeNative(const void *object, float value);
|
||||
void setFOVNative(const void *object, float angle);
|
||||
void setOrthoCropFactorNative(const void *object, float value);
|
||||
void setGridRotationNative(const void *object, float value);
|
||||
void setLightingNative(const void *object, bool enabled);
|
||||
void setBackfaceCullingNative(const void *object, bool enabled);
|
||||
void setWireframeNative(const void *object, bool enabled);
|
||||
void setTextureColorSeamsHiddenNative(const void *object, bool hidden);
|
||||
void setLocalizationModeNative(const void *object, bool enabled);
|
||||
void setDataRecorderModeNative(const void *object, bool enabled);
|
||||
void setTrajectoryModeNative(const void *object, bool enabled);
|
||||
void setGraphOptimizationNative(const void *object, bool enabled);
|
||||
void setNodesFilteringNative(const void *object, bool enabled);
|
||||
void setGraphVisibleNative(const void *object, bool visible);
|
||||
void setGridVisibleNative(const void *object, bool visible);
|
||||
void setFullResolutionNative(const void *object, bool enabled);
|
||||
void setSmoothingNative(const void *object, bool enabled);
|
||||
void setDepthBleedingErrorNative(const void *object, float value);
|
||||
void setAppendModeNative(const void *object, bool enabled);
|
||||
void setUpstreamRelocalizationAccThrNative(const void *object, float value);
|
||||
void setMaxCloudDepthNative(const void *object, float value);
|
||||
void setMinCloudDepthNative(const void *object, float value);
|
||||
void setCloudDensityLevelNative(const void *object, int value);
|
||||
void setMeshAngleToleranceNative(const void *object, float value);
|
||||
void setMeshDecimationFactorNative(const void *object, float value);
|
||||
void setMeshTriangleSizeNative(const void *object, int value);
|
||||
void setClusterRatioNative(const void *object, float value);
|
||||
void setMaxGainRadiusNative(const void *object, float value);
|
||||
void setRenderingTextureDecimationNative(const void *object, int value);
|
||||
void setBackgroundColorNative(const void *object, float gray);
|
||||
void setDepthConfidenceNative(const void *object, int value);
|
||||
void setExportPointCloudFormatNative(const void *object, const char * format);
|
||||
int setMappingParameterNative(const void *object, const char * key, const char * value);
|
||||
|
||||
void removeMeasureNative(const void *object);
|
||||
void addMeasureNative(const void *object);
|
||||
void teleportNative(const void *object);
|
||||
void setMeasuringModeNative(const void *object, int mode);
|
||||
void setMetricSystemNative(const void *object, bool enabled);
|
||||
void setMeasuringTextSizeNative(const void *object, float size);
|
||||
void clearMeasuresNative(const void *object);
|
||||
|
||||
typedef struct ImageNative
|
||||
{
|
||||
const void * objectPtr;
|
||||
void * data;
|
||||
int width;
|
||||
int height;
|
||||
int channels;
|
||||
int totalBytes;
|
||||
} ImageNative;
|
||||
|
||||
ImageNative getPreviewImageNative(const char * databasePath);
|
||||
void releasePreviewImageNative(ImageNative image);
|
||||
|
||||
void setGPSNative(const void *object, double stamp, double longitude, double latitude, double altitude, double accuracy, double bearing);
|
||||
void addEnvSensorNative(const void *object, int type, float value);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* NativeWrapper_hpp */
|
||||
@@ -0,0 +1,16 @@
|
||||
//
|
||||
// PointCloud.swift
|
||||
// ThreeDScanner
|
||||
//
|
||||
// Created by Steven Roach on 4/3/18.
|
||||
// Copyright © 2018 Steven Roach. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import SceneKit
|
||||
|
||||
internal struct PointCloud {
|
||||
internal var points: [vector_float3] = []
|
||||
internal var framePointsSizes: [Int32] = []
|
||||
internal var frameViewpoints: [SCNVector3] = []
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
//
|
||||
// PointCloudData.swift
|
||||
// ThreeDScanner
|
||||
//
|
||||
// Created by Steven Roach on 4/3/18.
|
||||
// Copyright © 2018 Steven Roach. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import SceneKit
|
||||
|
||||
internal struct PointCloud {
|
||||
internal var points: [vector_float3] = []
|
||||
internal var pointCloudFrameSizes: [Int32] = []
|
||||
internal var pointCloudFrameViewpoints: [SCNVector3] = []
|
||||
}
|
||||
@@ -0,0 +1,600 @@
|
||||
//
|
||||
// RTABMap.swift
|
||||
// RTABMapApp
|
||||
//
|
||||
// Created by Mathieu Labbe on 2020-12-31.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import ARKit
|
||||
|
||||
class RTABMap {
|
||||
var native_rtabmap: UnsafeMutableRawPointer
|
||||
|
||||
struct Observation {
|
||||
weak var observer: RTABMapObserver?
|
||||
}
|
||||
private var observations = [ObjectIdentifier : Observation]()
|
||||
|
||||
func addObserver(_ observer: RTABMapObserver) {
|
||||
let id = ObjectIdentifier(observer)
|
||||
observations[id] = Observation(observer: observer)
|
||||
}
|
||||
|
||||
func removeObserver(_ observer: RTABMapObserver) {
|
||||
let id = ObjectIdentifier(observer)
|
||||
observations.removeValue(forKey: id)
|
||||
}
|
||||
|
||||
init() {
|
||||
native_rtabmap = UnsafeMutableRawPointer(mutating: createNativeApplication())
|
||||
}
|
||||
|
||||
func setupCallbacksWithCPP()
|
||||
{
|
||||
setupCallbacksNative(native_rtabmap,
|
||||
UnsafeMutableRawPointer(Unmanaged.passUnretained(self).toOpaque()),
|
||||
//progressCallback
|
||||
{(observer, count, max) -> Void in
|
||||
// Extract pointer to `self` from void pointer:
|
||||
let mySelf = Unmanaged<RTABMap>.fromOpaque(observer!).takeUnretainedValue()
|
||||
// Call instance method:
|
||||
//mySelf.TestMethod();
|
||||
for (id, observation) in mySelf.observations {
|
||||
// If the observer is no longer in memory, we
|
||||
// can clean up the observation for its ID
|
||||
guard let observer = observation.observer else {
|
||||
mySelf.observations.removeValue(forKey: id)
|
||||
continue
|
||||
}
|
||||
|
||||
observer.progressUpdated(mySelf, count: Int(count), max: Int(max))
|
||||
}
|
||||
},
|
||||
//initCallback
|
||||
{(observer, status, msg) -> Void in
|
||||
// Extract pointer to `self` from void pointer:
|
||||
let mySelf = Unmanaged<RTABMap>.fromOpaque(observer!).takeUnretainedValue()
|
||||
// Call instance method:
|
||||
//mySelf.TestMethod();
|
||||
for (id, observation) in mySelf.observations {
|
||||
// If the observer is no longer in memory, we
|
||||
// can clean up the observation for its ID
|
||||
guard let observer = observation.observer else {
|
||||
mySelf.observations.removeValue(forKey: id)
|
||||
continue
|
||||
}
|
||||
|
||||
let str = String(cString: msg!)
|
||||
observer.initEventReceived(mySelf, status: Int(status), msg: str)
|
||||
}
|
||||
},
|
||||
//statsUpdatedCallback
|
||||
{(observer, nodes, words, points, polygons, updateTime, loopClosureId, highestHypId, databaseMemoryUsed, inliers, matches, featuresExtracted, hypothesis, nodesDrawn, fps, rejected, rehearsalValue, optimizationMaxError, optimizationMaxErrorRatio, distanceTravelled, fastMovement, landmarkDetected, x, y, z, roll, pitch, yaw) -> Void in
|
||||
// Extract pointer to `self` from void pointer:
|
||||
let mySelf = Unmanaged<RTABMap>.fromOpaque(observer!).takeUnretainedValue()
|
||||
// Call instance method:
|
||||
//mySelf.TestMethod();
|
||||
for (id, observation) in mySelf.observations {
|
||||
// If the observer is no longer in memory, we
|
||||
// can clean up the observation for its ID
|
||||
guard let observer = observation.observer else {
|
||||
mySelf.observations.removeValue(forKey: id)
|
||||
continue
|
||||
}
|
||||
|
||||
observer.statsUpdated(mySelf, nodes: Int(nodes), words: Int(words), points: Int(points), polygons: Int(polygons), updateTime: updateTime, loopClosureId: Int(loopClosureId), highestHypId: Int(highestHypId), databaseMemoryUsed: Int(databaseMemoryUsed), inliers: Int(inliers), matches: Int(matches), featuresExtracted: Int(featuresExtracted), hypothesis: hypothesis, nodesDrawn: Int(nodesDrawn), fps: fps, rejected: Int(rejected), rehearsalValue: rehearsalValue, optimizationMaxError: optimizationMaxError, optimizationMaxErrorRatio: optimizationMaxErrorRatio, distanceTravelled: distanceTravelled, fastMovement: Int(fastMovement), landmarkDetected: Int(landmarkDetected), x: x, y: y, z: z, roll: roll, pitch: pitch, yaw: yaw)
|
||||
}
|
||||
},
|
||||
//cameraInfoEventCallback
|
||||
{(observer, type, key, value) -> Void in
|
||||
// Extract pointer to `self` from void pointer:
|
||||
let mySelf = Unmanaged<RTABMap>.fromOpaque(observer!).takeUnretainedValue()
|
||||
// Call instance method:
|
||||
//mySelf.TestMethod();
|
||||
for (id, observation) in mySelf.observations {
|
||||
// If the observer is no longer in memory, we
|
||||
// can clean up the observation for its ID
|
||||
guard let observer = observation.observer else {
|
||||
mySelf.observations.removeValue(forKey: id)
|
||||
continue
|
||||
}
|
||||
|
||||
let strKey = String(cString: key!)
|
||||
let strValue = String(cString: value!)
|
||||
observer.cameraInfoEventReceived(mySelf, type: Int(type), key: strKey, value: strValue)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
deinit {
|
||||
destroyNativeApplication(native_rtabmap)
|
||||
}
|
||||
|
||||
func initGlContent() {
|
||||
initGlContentNative(native_rtabmap)
|
||||
}
|
||||
|
||||
func setupGraphic(size: CGSize, orientation: UIInterfaceOrientation) {
|
||||
var rotation: Int32
|
||||
switch orientation.rawValue {
|
||||
case 4:
|
||||
rotation=2
|
||||
case 1:
|
||||
rotation=3
|
||||
case 2:
|
||||
rotation=1
|
||||
default:
|
||||
rotation=0
|
||||
}
|
||||
//NSLog("Orientation: ios %d android %d, view=%dx%d", orientation.rawValue, rotation, Int32(size.width), Int32(size.height))
|
||||
setScreenRotationNative(native_rtabmap, rotation)
|
||||
setupGraphicNative(native_rtabmap, Int32(size.width), Int32(size.height));
|
||||
}
|
||||
|
||||
func openDatabase(databasePath:String, databaseInMemory:Bool, optimize:Bool, clearDatabase: Bool) -> Int {
|
||||
databasePath.utf8CString.withUnsafeBufferPointer { buffer -> Int in
|
||||
return Int(openDatabaseNative(native_rtabmap, buffer.baseAddress, databaseInMemory, optimize, clearDatabase))
|
||||
}
|
||||
}
|
||||
|
||||
func save(databasePath:String) {
|
||||
databasePath.utf8CString.withUnsafeBufferPointer { buffer in
|
||||
saveNative(native_rtabmap, databasePath)
|
||||
}
|
||||
}
|
||||
|
||||
func recover(from: String, to: String) -> Bool {
|
||||
from.utf8CString.withUnsafeBufferPointer { bufferFrom -> Bool in
|
||||
to.utf8CString.withUnsafeBufferPointer { bufferTo -> Bool in
|
||||
return recoverNative(native_rtabmap, bufferFrom.baseAddress, bufferTo.baseAddress)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func removeMeasure() {
|
||||
removeMeasureNative(native_rtabmap)
|
||||
}
|
||||
func addMeasureButtonClicked() {
|
||||
addMeasureNative(native_rtabmap)
|
||||
}
|
||||
func teleportButtonClicked() {
|
||||
teleportNative(native_rtabmap)
|
||||
}
|
||||
func setMeasuringMode(_ mode: Int) {
|
||||
setMeasuringModeNative(native_rtabmap, Int32(mode))
|
||||
}
|
||||
func setMetricSystem(_ enabled: Bool) {
|
||||
setMetricSystemNative(native_rtabmap, enabled)
|
||||
}
|
||||
func setMeasuringTextSize(_ size: Float32) {
|
||||
setMeasuringTextSizeNative(native_rtabmap, size)
|
||||
}
|
||||
func clearMeasures() {
|
||||
clearMeasuresNative(native_rtabmap)
|
||||
}
|
||||
func cancelProcessing() {
|
||||
cancelProcessingNative(native_rtabmap);
|
||||
}
|
||||
|
||||
func postProcessing(approach: Int) -> Int {
|
||||
return Int(postProcessingNative(native_rtabmap, Int32(approach)))
|
||||
}
|
||||
|
||||
func exportMesh(
|
||||
cloudVoxelSize: Float,
|
||||
regenerateCloud: Bool,
|
||||
meshing: Bool,
|
||||
textureSize: Int,
|
||||
textureCount: Int,
|
||||
normalK: Int,
|
||||
optimized: Bool,
|
||||
optimizedVoxelSize: Float,
|
||||
optimizedDepth: Int,
|
||||
optimizedMaxPolygons: Int,
|
||||
optimizedColorRadius: Float,
|
||||
optimizedCleanWhitePolygons: Bool,
|
||||
optimizedMinClusterSize: Int,
|
||||
optimizedMaxTextureDistance: Float,
|
||||
optimizedMinTextureClusterSize: Int,
|
||||
textureVertexColorPolicy: Int,
|
||||
blockRendering: Bool) -> Bool
|
||||
{
|
||||
return exportMeshNative(native_rtabmap,
|
||||
cloudVoxelSize,
|
||||
regenerateCloud,
|
||||
meshing,
|
||||
Int32(textureSize),
|
||||
Int32(textureCount),
|
||||
Int32(normalK),
|
||||
optimized,
|
||||
optimizedVoxelSize,
|
||||
Int32(optimizedDepth),
|
||||
Int32(optimizedMaxPolygons),
|
||||
optimizedColorRadius,
|
||||
optimizedCleanWhitePolygons,
|
||||
Int32(optimizedMinClusterSize),
|
||||
optimizedMaxTextureDistance,
|
||||
Int32(optimizedMinTextureClusterSize),
|
||||
Int32(textureVertexColorPolicy),
|
||||
blockRendering)
|
||||
}
|
||||
|
||||
func postExportation(visualize: Bool) -> Bool
|
||||
{
|
||||
return postExportationNative(native_rtabmap, visualize)
|
||||
}
|
||||
|
||||
func writeExportedMesh(directory: String, name: String) -> Bool
|
||||
{
|
||||
directory.utf8CString.withUnsafeBufferPointer { bufferDir in
|
||||
name.utf8CString.withUnsafeBufferPointer { bufferName in
|
||||
return writeExportedMeshNative(native_rtabmap, bufferDir.baseAddress, bufferName.baseAddress)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func onTouchEvent(touch_count: Int, event: Int, x0: Float, y0: Float, x1: Float, y1: Float) {
|
||||
onTouchEventNative(native_rtabmap, Int32(touch_count), Int32(event), x0, y0, x1, y1)
|
||||
}
|
||||
|
||||
func setPausedMapping(paused: Bool) {
|
||||
setPausedMappingNative(native_rtabmap, paused)
|
||||
}
|
||||
|
||||
func render() -> Int {
|
||||
return Int(renderNative(native_rtabmap))
|
||||
}
|
||||
|
||||
func startCamera(imageOverlayInFirstPerson: Bool = true) -> Bool {
|
||||
return startCameraNative(native_rtabmap)
|
||||
}
|
||||
|
||||
func stopCamera() {
|
||||
stopCameraNative(native_rtabmap)
|
||||
}
|
||||
|
||||
func setCamera(type: Int) {
|
||||
setCameraNative(native_rtabmap, Int32(type))
|
||||
}
|
||||
|
||||
func postOdometryEvent(frame: ARFrame, orientation: UIInterfaceOrientation, viewport: CGSize) {
|
||||
let pose = frame.camera.transform // ViewMatrix
|
||||
let rotation = GLKMatrix3(
|
||||
m: (pose[0,0], pose[0,1], pose[0,2],
|
||||
pose[1,0], pose[1,1], pose[1,2],
|
||||
pose[2,0], pose[2,1], pose[2,2]))
|
||||
|
||||
let quat = GLKQuaternionMakeWithMatrix3(rotation)
|
||||
|
||||
let confMap = frame.sceneDepth?.confidenceMap
|
||||
let depthMap = frame.sceneDepth?.depthMap
|
||||
let points = frame.rawFeaturePoints?.points
|
||||
|
||||
if points != nil && (depthMap != nil || points!.count>0)
|
||||
{
|
||||
let v = frame.camera.viewMatrix(for: orientation)
|
||||
let p = frame.camera.projectionMatrix(for: orientation, viewportSize: viewport, zNear: 0.5, zFar: 50.0)
|
||||
|
||||
let rotation = GLKMatrix3(
|
||||
m: (v[0,0], v[0,1], v[0,2],
|
||||
v[1,0], v[1,1], v[1,2],
|
||||
v[2,0], v[2,1], v[2,2]))
|
||||
|
||||
let quatv = GLKQuaternionMakeWithMatrix3(rotation)
|
||||
|
||||
let texX1 = (1-(2*frame.camera.intrinsics[0,0]/Float(frame.camera.imageResolution.width)) / p[0,0])/2
|
||||
let texY1 = (1-(2*frame.camera.intrinsics[1,1]/Float(frame.camera.imageResolution.height)) / p[1,1])/2
|
||||
|
||||
let texX2 = (1-(2*frame.camera.intrinsics[0,0]/Float(frame.camera.imageResolution.width)) / p[1,1])/2
|
||||
let texY2 = (1-(2*frame.camera.intrinsics[1,1]/Float(frame.camera.imageResolution.height)) / p[0,0])/2
|
||||
|
||||
//11 10 01 00 // portrait
|
||||
//01 11 00 10 // right
|
||||
//10 00 11 01 // left
|
||||
//00 01 10 11 // down
|
||||
var texCoord: [Float]
|
||||
switch orientation {
|
||||
case .portrait:
|
||||
texCoord = [1-texX2, 1-texY2, 1-texX2,texY2, texX2, 1-texY2, texX2, texY2]
|
||||
case .landscapeRight:
|
||||
texCoord = [texX1, 1-texY1, 1-texX1, 1-texY1, texX1, texY1, 1-texX1, texY1]
|
||||
case .landscapeLeft:
|
||||
texCoord = [1-texX1, texY1, texX1, texY1, 1-texX1, 1-texY1, texX1, 1-texY1]
|
||||
default: // down
|
||||
texCoord = [texX2, texY2, texX2, 1-texY2, 1-texX2, texY2, 1-texX2, 1-texY2]
|
||||
}
|
||||
|
||||
frame.rawFeaturePoints?.points.withUnsafeBufferPointer { bufferPoints in
|
||||
|
||||
CVPixelBufferLockBaseAddress(frame.capturedImage, CVPixelBufferLockFlags.readOnly)
|
||||
var depthDataPtr: UnsafeMutableRawPointer?
|
||||
var depthSize: Int32 = 0
|
||||
var depthWidth: Int32 = 0
|
||||
var depthHeight: Int32 = 0
|
||||
var depthFormat: Int32 = 0
|
||||
if depthMap != nil {
|
||||
CVPixelBufferLockBaseAddress(depthMap!, CVPixelBufferLockFlags.readOnly)
|
||||
depthDataPtr = CVPixelBufferGetBaseAddress(depthMap!)!
|
||||
depthSize = Int32(CVPixelBufferGetDataSize(depthMap!))
|
||||
depthWidth = Int32(CVPixelBufferGetWidth(depthMap!))
|
||||
depthHeight = Int32(CVPixelBufferGetHeight(depthMap!))
|
||||
depthFormat = Int32(CVPixelBufferGetPixelFormatType(depthMap!))
|
||||
}
|
||||
|
||||
var confDataPtr: UnsafeMutableRawPointer?
|
||||
var confSize: Int32 = 0
|
||||
var confWidth: Int32 = 0
|
||||
var confHeight: Int32 = 0
|
||||
var confFormat: Int32 = 0
|
||||
if confMap != nil {
|
||||
CVPixelBufferLockBaseAddress(confMap!, CVPixelBufferLockFlags.readOnly)
|
||||
confDataPtr = CVPixelBufferGetBaseAddress(confMap!)!
|
||||
confSize = Int32(CVPixelBufferGetDataSize(confMap!))
|
||||
confWidth = Int32(CVPixelBufferGetWidth(confMap!))
|
||||
confHeight = Int32(CVPixelBufferGetHeight(confMap!))
|
||||
confFormat = Int32(CVPixelBufferGetPixelFormatType(confMap!))
|
||||
}
|
||||
|
||||
if(frame.lightEstimate != nil) {
|
||||
addEnvSensor(type: 4, value: Float(frame.lightEstimate!.ambientIntensity))
|
||||
}
|
||||
|
||||
var lost = false
|
||||
switch frame.camera.trackingState {
|
||||
case .normal:
|
||||
lost = false
|
||||
case .limited(.excessiveMotion):
|
||||
lost = false
|
||||
case .limited(.insufficientFeatures):
|
||||
lost = false
|
||||
default:
|
||||
lost = true
|
||||
}
|
||||
// Notify lost with pose=null
|
||||
|
||||
postOdometryEventNative(native_rtabmap,
|
||||
!lost ? pose[3,0]:0, !lost ? pose[3,1]:0, !lost ? pose[3,2]:0, !lost ? quat.x:0, !lost ? quat.y:0, !lost ? quat.z:0, !lost ? quat.w:0,
|
||||
frame.camera.intrinsics[0,0], // fx
|
||||
frame.camera.intrinsics[1,1], // fy
|
||||
frame.camera.intrinsics[2,0], // cx
|
||||
frame.camera.intrinsics[2,1], // cy
|
||||
frame.timestamp,
|
||||
CVPixelBufferGetBaseAddressOfPlane(frame.capturedImage, 0), // y plane pointer
|
||||
nil, // u plane pointer
|
||||
CVPixelBufferGetBaseAddressOfPlane(frame.capturedImage, 1), // v plane pointer
|
||||
Int32(CVPixelBufferGetBytesPerRowOfPlane(frame.capturedImage, 0)) * Int32(CVPixelBufferGetHeightOfPlane(frame.capturedImage, 0)), // yPlaneLen
|
||||
Int32(CVPixelBufferGetWidth(frame.capturedImage)), // rgb width
|
||||
Int32(CVPixelBufferGetHeight(frame.capturedImage)), // rgb height
|
||||
Int32(CVPixelBufferGetPixelFormatType(frame.capturedImage)), // rgb format
|
||||
depthDataPtr, // depth pointer
|
||||
depthSize, // depth size
|
||||
depthWidth, // depth width
|
||||
depthHeight, // depth height
|
||||
depthFormat, // depth format
|
||||
confDataPtr, // conf pointer
|
||||
confSize, // conf size
|
||||
confWidth, // conf width
|
||||
confHeight, // conf height
|
||||
confFormat, // conf format
|
||||
bufferPoints.baseAddress, Int32(frame.rawFeaturePoints!.points.count), 4,
|
||||
v[3,0], v[3,1], v[3,2], quatv.x, quatv.y, quatv.z, quatv.w,
|
||||
p[0,0], p[1,1], p[2,0], p[2,1], p[2,2], p[2,3], p[3,2],
|
||||
texCoord[0],texCoord[1],texCoord[2],texCoord[3],texCoord[4],texCoord[5],texCoord[6],texCoord[7])
|
||||
if depthMap != nil {
|
||||
CVPixelBufferUnlockBaseAddress(depthMap!, CVPixelBufferLockFlags.readOnly)
|
||||
}
|
||||
if confMap != nil {
|
||||
CVPixelBufferUnlockBaseAddress(confMap!, CVPixelBufferLockFlags.readOnly)
|
||||
}
|
||||
CVPixelBufferUnlockBaseAddress(frame.capturedImage, CVPixelBufferLockFlags.readOnly)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Parameters
|
||||
func setOnlineBlending(enabled: Bool) {
|
||||
setOnlineBlendingNative(native_rtabmap, enabled)
|
||||
}
|
||||
func setMapCloudShown(shown: Bool) {
|
||||
setMapCloudShownNative(native_rtabmap, shown)
|
||||
}
|
||||
func setOdomCloudShown(shown: Bool) {
|
||||
setOdomCloudShownNative(native_rtabmap, shown)
|
||||
}
|
||||
func setMeshRendering(enabled: Bool, withTexture: Bool) {
|
||||
setMeshRenderingNative(native_rtabmap, enabled, withTexture)
|
||||
}
|
||||
func setPointSize(value: Float) {
|
||||
setPointSizeNative(native_rtabmap, value)
|
||||
}
|
||||
func setFOV(angle: Float) {
|
||||
setFOVNative(native_rtabmap, angle)
|
||||
}
|
||||
func setOrthoCropFactor(value: Float) {
|
||||
setOrthoCropFactorNative(native_rtabmap, value)
|
||||
}
|
||||
func setGridRotation(value: Float) {
|
||||
setGridRotationNative(native_rtabmap, value)
|
||||
}
|
||||
func setLighting(enabled: Bool) {
|
||||
setLightingNative(native_rtabmap, enabled)
|
||||
}
|
||||
func setBackfaceCulling(enabled: Bool) {
|
||||
setBackfaceCullingNative(native_rtabmap, enabled)
|
||||
}
|
||||
func setWireframe(enabled: Bool) {
|
||||
setWireframeNative(native_rtabmap, enabled)
|
||||
}
|
||||
func setTextureColorSeamsHidden(hidden: Bool) {
|
||||
setTextureColorSeamsHiddenNative(native_rtabmap, hidden)
|
||||
}
|
||||
func setLocalizationMode(enabled: Bool) {
|
||||
setLocalizationModeNative(native_rtabmap, enabled)
|
||||
}
|
||||
func setDataRecorderMode(enabled: Bool) {
|
||||
setDataRecorderModeNative(native_rtabmap, enabled)
|
||||
}
|
||||
func setGraphOptimization(enabled: Bool) {
|
||||
setGraphOptimizationNative(native_rtabmap, enabled)
|
||||
}
|
||||
func setNodesFiltering(enabled: Bool) {
|
||||
setNodesFilteringNative(native_rtabmap, enabled)
|
||||
}
|
||||
func setGraphVisible(visible: Bool) {
|
||||
setGraphVisibleNative(native_rtabmap, visible)
|
||||
}
|
||||
func setGridVisible(visible: Bool) {
|
||||
setGridVisibleNative(native_rtabmap, visible)
|
||||
}
|
||||
func setFullResolution(enabled: Bool) {
|
||||
setFullResolutionNative(native_rtabmap, enabled)
|
||||
}
|
||||
func setSmoothing(enabled: Bool) {
|
||||
setSmoothingNative(native_rtabmap, enabled)
|
||||
}
|
||||
func setDepthBleedingError(value: Float) {
|
||||
setDepthBleedingErrorNative(native_rtabmap, value)
|
||||
}
|
||||
func setAppendMode(enabled: Bool) {
|
||||
setAppendModeNative(native_rtabmap, enabled)
|
||||
}
|
||||
func setUpstreamRelocalizationAccThr(value: Float) {
|
||||
setUpstreamRelocalizationAccThrNative(native_rtabmap, value)
|
||||
}
|
||||
func setMaxCloudDepth(value: Float) {
|
||||
setMaxCloudDepthNative(native_rtabmap, value)
|
||||
}
|
||||
func setMinCloudDepth(value: Float) {
|
||||
setMinCloudDepthNative(native_rtabmap, value)
|
||||
}
|
||||
func setCloudDensityLevel(value: Int) {
|
||||
setCloudDensityLevelNative(native_rtabmap, Int32(value))
|
||||
}
|
||||
func setMeshAngleTolerance(value: Float) {
|
||||
setMeshAngleToleranceNative(native_rtabmap, value)
|
||||
}
|
||||
func setMeshDecimationFactor(value: Float) {
|
||||
setMeshDecimationFactorNative(native_rtabmap, value)
|
||||
}
|
||||
func setMeshTriangleSize(value: Int) {
|
||||
setMeshTriangleSizeNative(native_rtabmap, Int32(value))
|
||||
}
|
||||
func setClusterRatio(value: Float) {
|
||||
setClusterRatioNative(native_rtabmap, value)
|
||||
}
|
||||
func setMaxGainRadius(value: Float) {
|
||||
setMaxGainRadiusNative(native_rtabmap, value)
|
||||
}
|
||||
func setRenderingTextureDecimation(value: Int) {
|
||||
setRenderingTextureDecimationNative(native_rtabmap, Int32(value))
|
||||
}
|
||||
func setBackgroundColor(gray: Float) {
|
||||
setBackgroundColorNative(native_rtabmap, gray)
|
||||
}
|
||||
func setDepthConfidence(value: Int) {
|
||||
setDepthConfidenceNative(native_rtabmap, Int32(value))
|
||||
}
|
||||
func setExportPointCloudFormat(format: String) {
|
||||
format.utf8CString.withUnsafeBufferPointer { bufferFormat in
|
||||
return setExportPointCloudFormatNative(native_rtabmap, bufferFormat.baseAddress)
|
||||
}
|
||||
}
|
||||
func setMappingParameter(key: String, value: String) {
|
||||
key.utf8CString.withUnsafeBufferPointer { bufferKey in
|
||||
value.utf8CString.withUnsafeBufferPointer { bufferValue in
|
||||
setMappingParameterNative(native_rtabmap, bufferKey.baseAddress, bufferValue.baseAddress)
|
||||
}
|
||||
}
|
||||
}
|
||||
func setGPS(location: CLLocation)
|
||||
{
|
||||
setGPSNative(native_rtabmap, location.timestamp.timeIntervalSince1970, location.coordinate.longitude, location.coordinate.latitude, location.altitude, location.horizontalAccuracy, location.course < 0.0 ? 0.0 : location.course)
|
||||
}
|
||||
func addEnvSensor(type: Int, value: Float)
|
||||
{
|
||||
addEnvSensorNative(native_rtabmap, Int32(type), value)
|
||||
}
|
||||
func setOrthoCropFactor(_ value: Float)
|
||||
{
|
||||
setOrthoCropFactorNative(native_rtabmap, value)
|
||||
}
|
||||
func setGridRotation(_ value: Float)
|
||||
{
|
||||
setGridRotationNative(native_rtabmap, value)
|
||||
}
|
||||
}
|
||||
|
||||
func getPreviewImage(databasePath: String) -> UIImage?
|
||||
{
|
||||
let imageOut = databasePath.utf8CString.withUnsafeBufferPointer { buffer -> UIImage? in
|
||||
var image = ImageNative()
|
||||
image = getPreviewImageNative(buffer.baseAddress)
|
||||
if let dataPtr = UnsafeRawPointer(image.data)
|
||||
{
|
||||
// copy data in swift
|
||||
let data = Data(bytes: dataPtr, count: Int(image.width*image.height*image.channels))
|
||||
// release memory
|
||||
releasePreviewImageNative(image)
|
||||
// Create bitmap image
|
||||
let bitmap = CIImage(bitmapData: data, bytesPerRow: Int(image.width*image.channels), size: CGSize(width: Int(image.width), height: Int(image.height)), format: CIFormat.BGRA8, colorSpace: nil)
|
||||
return UIImage(ciImage: bitmap)
|
||||
}
|
||||
return UIImage(named: "RTAB-Map1024")
|
||||
}
|
||||
return imageOut
|
||||
}
|
||||
|
||||
protocol RTABMapObserver: class {
|
||||
func progressUpdated(_ rtabmap: RTABMap, count: Int, max: Int)
|
||||
func initEventReceived(_ rtabmap: RTABMap, status: Int, msg: String)
|
||||
func statsUpdated(_ rtabmap: RTABMap,
|
||||
nodes: Int,
|
||||
words: Int,
|
||||
points: Int,
|
||||
polygons: Int,
|
||||
updateTime: Float,
|
||||
loopClosureId: Int,
|
||||
highestHypId: Int,
|
||||
databaseMemoryUsed: Int,
|
||||
inliers: Int,
|
||||
matches: Int,
|
||||
featuresExtracted: Int,
|
||||
hypothesis: Float,
|
||||
nodesDrawn: Int,
|
||||
fps: Float,
|
||||
rejected: Int,
|
||||
rehearsalValue: Float,
|
||||
optimizationMaxError: Float,
|
||||
optimizationMaxErrorRatio: Float,
|
||||
distanceTravelled: Float,
|
||||
fastMovement: Int,
|
||||
landmarkDetected: Int,
|
||||
x: Float,
|
||||
y: Float,
|
||||
z: Float,
|
||||
roll: Float,
|
||||
pitch: Float,
|
||||
yaw: Float)
|
||||
func cameraInfoEventReceived(_ rtabmap: RTABMap, type: Int, key: String, value: String)
|
||||
}
|
||||
|
||||
extension String {
|
||||
|
||||
func toPointer() -> UnsafePointer<UInt8>? {
|
||||
guard let data = self.data(using: String.Encoding.utf8) else { return nil }
|
||||
|
||||
let buffer = UnsafeMutablePointer<UInt8>.allocate(capacity: data.count)
|
||||
let stream = OutputStream(toBuffer: buffer, capacity: data.count)
|
||||
|
||||
stream.open()
|
||||
data.withUnsafeBytes({ (p: UnsafePointer<UInt8>) -> Void in
|
||||
stream.write(p, maxLength: data.count)
|
||||
})
|
||||
|
||||
stream.close()
|
||||
|
||||
return UnsafePointer<UInt8>(buffer)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
//
|
||||
// Use this file to import your target's public headers that you would like to expose to Swift.
|
||||
//
|
||||
|
||||
#include "NativeWrapper.hpp"
|
||||
#import <sqlite3.h>
|
||||
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>com.apple.developer.kernel.increased-memory-limit</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -0,0 +1,52 @@
|
||||
//
|
||||
// SceneDelegate.swift
|
||||
// GLKittutorial
|
||||
//
|
||||
// Created by Mathieu Labbe on 2020-12-28.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
|
||||
|
||||
var window: UIWindow?
|
||||
|
||||
|
||||
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
|
||||
// Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
|
||||
// If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
|
||||
// This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).
|
||||
guard let _ = (scene as? UIWindowScene) else { return }
|
||||
}
|
||||
|
||||
func sceneDidDisconnect(_ scene: UIScene) {
|
||||
// Called as the scene is being released by the system.
|
||||
// This occurs shortly after the scene enters the background, or when its session is discarded.
|
||||
// Release any resources associated with this scene that can be re-created the next time the scene connects.
|
||||
// The scene may re-connect later, as its session was not necessarily discarded (see `application:didDiscardSceneSessions` instead).
|
||||
}
|
||||
|
||||
func sceneDidBecomeActive(_ scene: UIScene) {
|
||||
// Called when the scene has moved from an inactive state to an active state.
|
||||
// Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive.
|
||||
}
|
||||
|
||||
func sceneWillResignActive(_ scene: UIScene) {
|
||||
// Called when the scene will move from an active state to an inactive state.
|
||||
// This may occur due to temporary interruptions (ex. an incoming phone call).
|
||||
}
|
||||
|
||||
func sceneWillEnterForeground(_ scene: UIScene) {
|
||||
// Called as the scene transitions from the background to the foreground.
|
||||
// Use this method to undo the changes made on entering the background.
|
||||
}
|
||||
|
||||
func sceneDidEnterBackground(_ scene: UIScene) {
|
||||
// Called as the scene transitions from the foreground to the background.
|
||||
// Use this method to save data, release shared resources, and store enough scene-specific state information
|
||||
// to restore the scene back to its current state.
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,138 @@
|
||||
/*
|
||||
* Copyright (c) 2017 Razeware LLC
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Notwithstanding the foregoing, you may not use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, create a derivative work, and/or sell copies of the
|
||||
* Software in any work that is designed, intended, or marketed for pedagogical or
|
||||
* instructional purposes related to programming, coding, application development,
|
||||
* or information technology. Permission for such use, copying, modification,
|
||||
* merger, publication, distribution, sublicensing, creation of derivative works,
|
||||
* or sale is expressly withheld.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import UIKit
|
||||
|
||||
protocol VerticalViewDataSource: class {
|
||||
// Ask the data source how many views it wants to present inside the horizontal scroller
|
||||
func numberOfViews(in verticalScrollerView: VerticalScrollerView) -> Int
|
||||
// Ask the data source to return the view that should appear at <index>
|
||||
func getScrollerViewItem(_ verticalScrollerView: VerticalScrollerView, viewAt index: Int) -> UIView
|
||||
}
|
||||
|
||||
protocol VerticalScrollerViewDelegate: class {
|
||||
// inform the delegate that the view at <index> has been selected
|
||||
func verticalScrollerView(_ verticalScrollerView: VerticalScrollerView, didSelectViewAt index: Int)
|
||||
}
|
||||
|
||||
class VerticalScrollerView: UIView {
|
||||
weak var dataSource: VerticalViewDataSource?
|
||||
weak var delegate: VerticalScrollerViewDelegate?
|
||||
|
||||
// 1
|
||||
private enum ViewConstants {
|
||||
static let Padding: CGFloat = 5
|
||||
static let Dimensions: CGFloat = 185
|
||||
static let Offset: CGFloat = 10
|
||||
}
|
||||
|
||||
// 2
|
||||
private let scroller = UIScrollView()
|
||||
|
||||
// 3
|
||||
private var contentViews = [UIView]()
|
||||
|
||||
override init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
initializeScrollView()
|
||||
}
|
||||
|
||||
required init?(coder aDecoder: NSCoder) {
|
||||
super.init(coder: aDecoder)
|
||||
initializeScrollView()
|
||||
}
|
||||
|
||||
func initializeScrollView() {
|
||||
|
||||
addSubview(scroller)
|
||||
|
||||
scroller.translatesAutoresizingMaskIntoConstraints = false
|
||||
|
||||
NSLayoutConstraint.activate([
|
||||
scroller.leadingAnchor.constraint(equalTo: self.leadingAnchor),
|
||||
scroller.trailingAnchor.constraint(equalTo: self.trailingAnchor),
|
||||
scroller.topAnchor.constraint(equalTo: self.topAnchor),
|
||||
scroller.bottomAnchor.constraint(equalTo: self.bottomAnchor)
|
||||
])
|
||||
|
||||
let tapRecognizer = UITapGestureRecognizer(target: self, action: #selector(scrollerTapped(gesture:)))
|
||||
scroller.addGestureRecognizer(tapRecognizer)
|
||||
}
|
||||
|
||||
func scrollToView(at index: Int, animated: Bool = true) {
|
||||
let centralView = contentViews[index]
|
||||
let targetCenter = centralView.center
|
||||
let targetOffsetY = targetCenter.y - (scroller.bounds.height / 2)
|
||||
scroller.setContentOffset(CGPoint(x: 0, y: targetOffsetY), animated: animated)
|
||||
}
|
||||
|
||||
@objc func scrollerTapped(gesture: UITapGestureRecognizer) {
|
||||
let location = gesture.location(in: scroller)
|
||||
guard
|
||||
let index = contentViews.index(where: { $0.frame.contains(location)})
|
||||
else { return }
|
||||
|
||||
delegate?.verticalScrollerView(self, didSelectViewAt: index)
|
||||
scrollToView(at: index)
|
||||
}
|
||||
|
||||
func view(at index :Int) -> UIView {
|
||||
return contentViews[index]
|
||||
}
|
||||
|
||||
func reload() {
|
||||
// 1 - Check if there is a data source, if not there is nothing to load.
|
||||
guard let dataSource = dataSource else {
|
||||
return
|
||||
}
|
||||
|
||||
//2 - Remove the old content views
|
||||
contentViews.forEach { $0.removeFromSuperview() }
|
||||
|
||||
// 3 - yValue is the starting point of each view inside the scroller
|
||||
var yValue = ViewConstants.Offset
|
||||
// 4 - Fetch and add the new views
|
||||
contentViews = (0..<dataSource.numberOfViews(in: self)).map {
|
||||
index in
|
||||
// 5 - add a view at the right position
|
||||
yValue += ViewConstants.Padding
|
||||
let view = dataSource.getScrollerViewItem(self, viewAt: index)
|
||||
view.frame = CGRect(x: ViewConstants.Padding, y: CGFloat(yValue), width: ViewConstants.Dimensions*2, height: ViewConstants.Dimensions)
|
||||
scroller.addSubview(view)
|
||||
yValue += ViewConstants.Dimensions + ViewConstants.Padding
|
||||
// 6 - Store the view so we can reference it later
|
||||
return view
|
||||
}
|
||||
|
||||
// 7
|
||||
scroller.contentSize = CGSize(width: frame.size.width, height: CGFloat(yValue + ViewConstants.Offset))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,293 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -euxo pipefail
|
||||
|
||||
# Tested on Apple Silicon Mac, with cmake 4.0.2, XCode 16.3.
|
||||
|
||||
mkdir -p Libraries
|
||||
cd Libraries
|
||||
pwd=$(pwd)
|
||||
prefix=$pwd
|
||||
sysroot=iphoneos
|
||||
#sysroot=iphonesimulator
|
||||
|
||||
# openmp
|
||||
# based on https://github.com/Homebrew/homebrew-core/blob/HEAD/Formula/libomp.rb
|
||||
#curl -L https://github.com/llvm/llvm-project/releases/download/llvmorg-11.1.0/openmp-11.1.0.src.tar.xz -o openmp-11.1.0.src.tar.xz
|
||||
#tar -xzf openmp-11.1.0.src.tar.xz
|
||||
#cd openmp-11.1.0.src
|
||||
#curl -L https://raw.githubusercontent.com/Homebrew/formula-patches/7e2ee1d7/libomp/arm.patch -o arm.patch
|
||||
#patch -p1 < arm.patch
|
||||
#mkdir build
|
||||
#cd build
|
||||
#cmake -G Xcode -DCMAKE_SYSTEM_NAME=iOS -DCMAKE_OSX_SYSROOT=$sysroot -DBUILD_SHARED_LIBS=OFF -DCMAKE_BUILD_TYPE=Release -DCMAKE_OSX_DEPLOYMENT_TARGET=12.0 -DCMAKE_INSTALL_PREFIX=$prefix -DLIBOMP_INSTALL_ALIASES=OFF -DLIBOMP_ENABLE_SHARED=OFF ..
|
||||
#cmake --build . --config Release -- CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED="NO" CODE_SIGN_ENTITLEMENTS="" CODE_SIGNING_ALLOWED="NO"
|
||||
#cp runtime/src/Release-iphoneos/libomp.a runtime/src/.
|
||||
#cmake --build . --config Release --target install -- CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED="NO" CODE_SIGN_ENTITLEMENTS="" CODE_SIGNING_ALLOWED="NO"
|
||||
|
||||
# Boost
|
||||
if [ ! -e $prefix/include/boost ]
|
||||
then
|
||||
if [ ! -e boost-1.88.0 ]
|
||||
then
|
||||
echo "wget boost..."
|
||||
curl -L https://github.com/boostorg/boost/releases/download/boost-1.88.0/boost-1.88.0-cmake.tar.gz -o boost-1.88.0-cmake.tar.gz
|
||||
tar -xzf boost-1.88.0-cmake.tar.gz
|
||||
fi
|
||||
cd boost-1.88.0
|
||||
mkdir -p build
|
||||
cd build
|
||||
cmake -G Xcode -DCMAKE_SYSTEM_NAME=iOS -DCMAKE_OSX_ARCHITECTURES=arm64 -DCMAKE_OSX_SYSROOT=$sysroot -DBUILD_SHARED_LIBS=OFF -DCMAKE_BUILD_TYPE=Release -DCMAKE_OSX_DEPLOYMENT_TARGET=12.0 -DCMAKE_INSTALL_PREFIX=$prefix -DBOOST_INCOMPATIBLE_LIBRARIES="process;context;coroutine;fiber;fiber_numa;log_setup;log;cobalt" -DBOOST_IOSTREAMS_ENABLE_ZLIB=OFF -DBOOST_IOSTREAMS_ENABLE_BZIP2=OFF ..
|
||||
cmake --build . --config Release
|
||||
cmake --build . --config Release --target install
|
||||
cd $pwd
|
||||
#rm -r boost-1.88.0-cmake.tar.gz boost-1.88.0
|
||||
fi
|
||||
|
||||
# eigen
|
||||
if [ ! -e $prefix/include/eigen3 ]
|
||||
then
|
||||
if [ ! -e eigen-3.4.0 ]
|
||||
then
|
||||
echo "wget eigen..."
|
||||
curl -L https://gitlab.com/libeigen/eigen/-/archive/3.4.0/eigen-3.4.0.tar.gz -o 3.4.0.tar.gz
|
||||
tar -xzf 3.4.0.tar.gz
|
||||
fi
|
||||
cd eigen-3.4.0
|
||||
mkdir -p build
|
||||
cd build
|
||||
cmake -G Xcode -DCMAKE_SYSTEM_NAME=iOS -DCMAKE_OSX_ARCHITECTURES=arm64 -DCMAKE_OSX_SYSROOT=$sysroot -DBUILD_SHARED_LIBS=OFF -DCMAKE_BUILD_TYPE=Release -DCMAKE_OSX_DEPLOYMENT_TARGET=12.0 -DCMAKE_INSTALL_PREFIX=$prefix ..
|
||||
cmake --build . --config Release
|
||||
cmake --build . --config Release --target install
|
||||
cd $pwd
|
||||
#rm -r 3.4.0.tar.gz eigen-3.4.0
|
||||
fi
|
||||
|
||||
# lz4 (required by flann)
|
||||
if [ ! -e $prefix/include/lz4.h ]
|
||||
then
|
||||
if [ ! -e lz4 ]
|
||||
then
|
||||
echo "wget lz4..."
|
||||
git clone https://github.com/lz4/lz4.git -b v1.10.0
|
||||
fi
|
||||
cd lz4
|
||||
if [ ! -e LZ4Config.cmake.in ]
|
||||
then
|
||||
curl -L https://gist.githubusercontent.com/matlabbe/abd0242305c29495bbba26065269daf2/raw/ad0b1865c02e61449f58358fdc4ddbed3cb5fb87/LZ4Config.cmake.in -o LZ4Config.cmake.in
|
||||
fi
|
||||
if [ ! -e CMakeLists.txt ]
|
||||
then
|
||||
curl -L https://gist.githubusercontent.com/matlabbe/abd0242305c29495bbba26065269daf2/raw/ad0b1865c02e61449f58358fdc4ddbed3cb5fb87/CMakeLists.txt -o CMakeLists.txt
|
||||
fi
|
||||
mkdir -p build
|
||||
cd build
|
||||
cmake -G Xcode -DCMAKE_SYSTEM_NAME=iOS -DCMAKE_OSX_ARCHITECTURES=arm64 -DCMAKE_OSX_SYSROOT=$sysroot -DBUILD_SHARED_LIBS=OFF -DCMAKE_BUILD_TYPE=Release -DCMAKE_OSX_DEPLOYMENT_TARGET=12.0 -DCMAKE_INSTALL_PREFIX=$prefix ..
|
||||
cmake --build . --config Release -- CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED="NO" CODE_SIGN_ENTITLEMENTS="" CODE_SIGNING_ALLOWED="NO"
|
||||
cmake --build . --config Release --target install -- CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED="NO" CODE_SIGN_ENTITLEMENTS="" CODE_SIGNING_ALLOWED="NO"
|
||||
cd $pwd
|
||||
#rm -r lz4
|
||||
fi
|
||||
|
||||
# FLANN
|
||||
if [ ! -e $prefix/include/flann ]
|
||||
then
|
||||
if [ ! -e flann ]
|
||||
then
|
||||
echo "wget flann..."
|
||||
git clone https://github.com/flann-lib/flann.git -b 1.9.2
|
||||
fi
|
||||
cd flann
|
||||
if [ ! -e flann_ios_lz4.patch ]
|
||||
then
|
||||
curl -L https://gist.githubusercontent.com/matlabbe/c858ba36fb85d5e44d8667dfb3543e12/raw/2586a356dec2b11440ec3c1bb113e709e1266d97/flann_ios_lz4.patch -o flann_ios_lz4.patch
|
||||
git apply flann_ios_lz4.patch
|
||||
fi
|
||||
mkdir -p build
|
||||
cd build
|
||||
cmake -G Xcode -DCMAKE_SYSTEM_NAME=iOS -DCMAKE_OSX_ARCHITECTURES=arm64 -DCMAKE_OSX_SYSROOT=$sysroot -DBUILD_SHARED_LIBS=OFF -DCMAKE_BUILD_TYPE=Release -DCMAKE_OSX_DEPLOYMENT_TARGET=12.0 -DCMAKE_INSTALL_PREFIX=$prefix -DBUILD_PYTHON_BINDINGS=OFF -DBUILD_MATLAB_BINDINGS=OFF -DBUILD_C_BINDINGS=OFF -DBUILD_EXAMPLES=OFF -DBUILD_TESTS=OFF -DBUILD_DOC=OFF -DUSE_OPENMP=OFF -DLZ4_DIR=$prefix/lib/lz4 ..
|
||||
cmake --build . --config Release -- CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED="NO" CODE_SIGN_ENTITLEMENTS="" CODE_SIGNING_ALLOWED="NO"
|
||||
cmake --build . --config Release --target install -- CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED="NO" CODE_SIGN_ENTITLEMENTS="" CODE_SIGNING_ALLOWED="NO"
|
||||
cd $pwd
|
||||
#rm -r flann
|
||||
fi
|
||||
|
||||
# GTSAM
|
||||
if [ ! -e $prefix/include/gtsam ]
|
||||
then
|
||||
if [ ! -e gtsam ]
|
||||
then
|
||||
git clone https://github.com/borglab/gtsam.git -b 4.2
|
||||
fi
|
||||
cd gtsam
|
||||
# patch
|
||||
if [ ! -e gtsam_4_2_ios.patch ]
|
||||
then
|
||||
curl -L https://gist.githubusercontent.com/matlabbe/76d658dddb841b3355ae3a6e32850cd8/raw/e7355348c2d536ec50f41effa775ed251ae4e045/gtsam_4_2_ios.patch -o gtsam_4_2_ios.patch
|
||||
git apply gtsam_4_2_ios.patch
|
||||
fi
|
||||
mkdir -p build
|
||||
cd build
|
||||
cmake -G Xcode -DCMAKE_SYSTEM_NAME=iOS -DCMAKE_OSX_ARCHITECTURES=arm64 -DCMAKE_OSX_SYSROOT=$sysroot -DBUILD_SHARED_LIBS=OFF -DCMAKE_BUILD_TYPE=Release -DCMAKE_OSX_DEPLOYMENT_TARGET=12.0 -DCMAKE_INSTALL_PREFIX=$prefix -DMETIS_SHARED=OFF -DGTSAM_BUILD_STATIC_LIBRARY=ON -DGTSAM_BUILD_TESTS=OFF -DGTSAM_BUILD_EXAMPLES_ALWAYS=OFF -DGTSAM_USE_SYSTEM_EIGEN=ON -DGTSAM_WRAP_SERIALIZATION=OFF -DGTSAM_BUILD_WRAP=OFF -DGTSAM_INSTALL_CPPUNITLITE=OFF -DCMAKE_FIND_ROOT_PATH=$prefix ..
|
||||
cmake --build . --config Release -- CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED="NO" CODE_SIGN_ENTITLEMENTS="" CODE_SIGNING_ALLOWED="NO"
|
||||
cmake --build . --config Release --target install -- CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED="NO" CODE_SIGN_ENTITLEMENTS="" CODE_SIGNING_ALLOWED="NO"
|
||||
cd $pwd
|
||||
#rm -rf gtsam
|
||||
fi
|
||||
|
||||
# suitesparse (dependency of g2o)
|
||||
if [ ! -e $prefix/include/suitesparse/SuiteSparse_config.h ]
|
||||
then
|
||||
if [ ! -e SuiteSparse ]
|
||||
then
|
||||
git clone https://github.com/DrTimothyAldenDavis/SuiteSparse.git -b v7.6.1
|
||||
fi
|
||||
cd SuiteSparse
|
||||
mkdir -p build
|
||||
cd build
|
||||
cmake -G Xcode -DCMAKE_SYSTEM_NAME=iOS -DCMAKE_OSX_ARCHITECTURES=arm64 -DCMAKE_OSX_SYSROOT=$sysroot -DBUILD_SHARED_LIBS=OFF -DCMAKE_BUILD_TYPE=Release -DCMAKE_OSX_DEPLOYMENT_TARGET=12.0 -DCMAKE_INSTALL_PREFIX=$prefix -DCMAKE_FIND_ROOT_PATH=$prefix -DSUITESPARSE_USE_OPENMP=OFF -DSUITESPARSE_ENABLE_PROJECTS="cholmod;cxsparse;spqr" ..
|
||||
cmake --build . --config Release -- CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED="NO" CODE_SIGN_ENTITLEMENTS="" CODE_SIGNING_ALLOWED="NO"
|
||||
cmake --build . --config Release --target install -- CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED="NO" CODE_SIGN_ENTITLEMENTS="" CODE_SIGNING_ALLOWED="NO"
|
||||
cd $pwd
|
||||
fi
|
||||
|
||||
# g2o
|
||||
if [ ! -e $prefix/include/g2o ]
|
||||
then
|
||||
if [ ! -e g2o ]
|
||||
then
|
||||
git clone https://github.com/RainerKuemmerle/g2o.git -b 20241228_git
|
||||
fi
|
||||
cd g2o
|
||||
# patch
|
||||
if [ ! -e g2o_20241228_ios.patch ]
|
||||
then
|
||||
ls
|
||||
curl -L https://gist.githubusercontent.com/matlabbe/b9ccfeae8f0744b275cab23510872680/raw/6fe2ffe5ba8fba59171adbd2f38f9c3999c61f75/g2o_20241228_ios.patch -o g2o_20241228_ios.patch
|
||||
git apply g2o_20241228_ios.patch
|
||||
fi
|
||||
mkdir -p build
|
||||
cd build
|
||||
cmake -G Xcode -DCMAKE_SYSTEM_NAME=iOS -DCMAKE_OSX_ARCHITECTURES=arm64 -DCMAKE_OSX_SYSROOT=$sysroot -DBUILD_SHARED_LIBS=OFF -DCMAKE_BUILD_TYPE=Release -DCMAKE_OSX_DEPLOYMENT_TARGET=12.0 -DCMAKE_INSTALL_PREFIX=$prefix -DBUILD_LGPL_SHARED_LIBS=OFF -DG2O_BUILD_APPS=OFF -DG2O_BUILD_EXAMPLES=OFF -DCMAKE_FIND_ROOT_PATH=$prefix ..
|
||||
cmake --build . --config Release -- CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED="NO" CODE_SIGN_ENTITLEMENTS="" CODE_SIGNING_ALLOWED="NO"
|
||||
cmake --build . --config Release --target install -- CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED="NO" CODE_SIGN_ENTITLEMENTS="" CODE_SIGNING_ALLOWED="NO"
|
||||
cd $pwd
|
||||
#rm -rf g2o
|
||||
fi
|
||||
|
||||
# VTK
|
||||
if [ ! -e $prefix/lib/vtk.framework ]
|
||||
then
|
||||
if [ ! -e VTK ]
|
||||
then
|
||||
git clone https://github.com/Kitware/VTK.git
|
||||
cd VTK
|
||||
git checkout tags/v9.5.0.rc1
|
||||
else
|
||||
cd VTK
|
||||
fi
|
||||
mkdir -p build
|
||||
cd build
|
||||
cmake -DBUILD_SHARED_LIBS=OFF -DCMAKE_BUILD_TYPE=Release -DCMAKE_FRAMEWORK_INSTALL_PREFIX=$prefix/lib -DIOS_DEVICE_ARCHITECTURES="arm64" -DIOS_SIMULATOR_ARCHITECTURES="" -DBUILD_EXAMPLES=OFF -DBUILD_TESTING=OFF -DVTK_IOS_BUILD=ON -DModule_vtkFiltersModeling=ON ..
|
||||
# For iphonesimulator: add -DIOS_DEVICE_ARCHITECTURES=""
|
||||
cmake --build . --config Release
|
||||
cd $pwd
|
||||
#rm -rf VTK
|
||||
fi
|
||||
|
||||
|
||||
|
||||
# PCL
|
||||
if [ ! -e $prefix/include/pcl-1.15 ]
|
||||
then
|
||||
if [ ! -e pcl ]
|
||||
then
|
||||
git clone https://github.com/PointCloudLibrary/pcl.git
|
||||
cd pcl
|
||||
git checkout tags/pcl-1.15.0
|
||||
else
|
||||
cd pcl
|
||||
fi
|
||||
# patch
|
||||
if [ ! -e pcl_1_15_0_ios.patch ]
|
||||
then
|
||||
curl -L https://gist.githubusercontent.com/matlabbe/f3ba9366eb91e1b855dadd2ddce5746d/raw/7231688d7fb9e86df72ca7c5f355d6b9727205d5/pcl_1_15_0_ios.patch -o pcl_1_15_0_ios.patch
|
||||
git apply pcl_1_15_0_ios.patch
|
||||
fi
|
||||
mkdir -p build
|
||||
cd build
|
||||
cmake -G Xcode -DCMAKE_SYSTEM_NAME=iOS -DCMAKE_OSX_ARCHITECTURES=arm64 -DCMAKE_OSX_SYSROOT=$sysroot -DBUILD_SHARED_LIBS=OFF -DCMAKE_BUILD_TYPE=Release -DCMAKE_OSX_DEPLOYMENT_TARGET=12.0 -DCMAKE_INSTALL_PREFIX=$prefix -DBUILD_apps=OFF -DBUILD_examples=OFF -DBUILD_tools=OFF -DBUILD_visualization=OFF -DBUILD_tracking=OFF -DBUILD_people=OFF -DBUILD_recognition=OFF -DBUILD_global_tests=OFF -DWITH_QT=OFF -DWITH_OPENGL=OFF -DWITH_OPENMP=OFF -DWITH_VTK=ON -DPCL_FLANN_REQUIRED_TYPE=STATIC -DPCL_SHARED_LIBS=OFF -DPCL_ENABLE_SSE=OFF -DCMAKE_FIND_ROOT_PATH=$prefix ..
|
||||
cmake --build . --config Release
|
||||
cmake --build . --config Release --target install
|
||||
cd $pwd
|
||||
#rm -rf pcl
|
||||
fi
|
||||
|
||||
# OpenCV
|
||||
if [ ! -e $prefix/include/opencv4 ]
|
||||
then
|
||||
if [ ! -e opencv_contrib ]
|
||||
then
|
||||
git clone https://github.com/opencv/opencv_contrib.git -b 4.11.0
|
||||
fi
|
||||
cd $pwd
|
||||
if [ ! -e opencv ]
|
||||
then
|
||||
git clone https://github.com/opencv/opencv.git -b 4.11.0
|
||||
fi
|
||||
cd opencv
|
||||
mkdir -p build
|
||||
cd build
|
||||
cmake -G Xcode -DCMAKE_SYSTEM_NAME=iOS -DCMAKE_OSX_ARCHITECTURES=arm64 -DCMAKE_OSX_SYSROOT=$sysroot -DBUILD_SHARED_LIBS=OFF -DCMAKE_BUILD_TYPE=Release -DCMAKE_OSX_DEPLOYMENT_TARGET=12.0 -DCMAKE_INSTALL_PREFIX=$prefix -DOPENCV_EXTRA_MODULES_PATH=$prefix/opencv_contrib/modules -DBUILD_TESTS=OFF -DBUILD_PERF_TESTS=OFF -DWITH_CUDA=OFF -DWITH_WEBP=OFF -DWITH_OPENEXR=OFF -DBUILD_opencv_apps=OFF -DBUILD_opencv_xobjdetect=OFF -DBUILD_opencv_stereo=OFF -DOPENCV_ENABLE_NONFREE=ON ..
|
||||
cmake --build . --config Release
|
||||
cmake --build . --config Release --target install
|
||||
cd $pwd
|
||||
#rm -rf opencv opencv_contrib
|
||||
fi
|
||||
|
||||
# LAZ (dependency for liblas)
|
||||
# LAS
|
||||
if [ ! -e $prefix/include/laszip ]
|
||||
then
|
||||
if [ ! -e LASzip ]
|
||||
then
|
||||
git clone https://github.com/LASzip/LASzip.git -b 2.0.1
|
||||
fi
|
||||
cd LASzip
|
||||
sed -i '' 's/cmake_minimum_required(VERSION 2.6.0)/cmake_minimum_required(VERSION 3.5)/g' CMakeLists.txt
|
||||
sed -i '' 's/add_subdirectory(tools)/#add_subdirectory(tools)/g' CMakeLists.txt
|
||||
mkdir -p build
|
||||
cd build
|
||||
cmake -G Xcode -DCMAKE_SYSTEM_NAME=iOS -DCMAKE_OSX_ARCHITECTURES=arm64 -DCMAKE_OSX_SYSROOT=$sysroot -DBUILD_SHARED_LIBS=OFF -DCMAKE_BUILD_TYPE=Release -DCMAKE_OSX_DEPLOYMENT_TARGET=12.0 -DCMAKE_INSTALL_PREFIX=$prefix -DCMAKE_FIND_ROOT_PATH=$prefix -DBUILD_STATIC=ON ..
|
||||
cmake --build . --config Release -- CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED="NO" CODE_SIGN_ENTITLEMENTS="" CODE_SIGNING_ALLOWED="NO"
|
||||
cmake --build . --config Release --target install -- CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED="NO" CODE_SIGN_ENTITLEMENTS="" CODE_SIGNING_ALLOWED="NO"
|
||||
cd $pwd
|
||||
fi
|
||||
|
||||
# LAS
|
||||
if [ ! -e $prefix/include/liblas ]
|
||||
then
|
||||
if [ ! -e libLAS ]
|
||||
then
|
||||
git clone https://github.com/libLAS/libLAS.git
|
||||
fi
|
||||
cd libLAS
|
||||
sed -i '' 's/cmake_minimum_required(VERSION 2.8.11)/cmake_minimum_required(VERSION 3.5)/g' CMakeLists.txt
|
||||
sed -i '' 's/SHARED/STATIC/g' src/CMakeLists.txt
|
||||
mkdir -p build
|
||||
cd build
|
||||
cmake -G Xcode -DCMAKE_SYSTEM_NAME=iOS -DCMAKE_OSX_ARCHITECTURES=arm64 -DCMAKE_OSX_SYSROOT=$sysroot -DBUILD_SHARED_LIBS=OFF -DCMAKE_BUILD_TYPE=Release -DCMAKE_OSX_DEPLOYMENT_TARGET=12.0 -DCMAKE_INSTALL_PREFIX=$prefix -DCMAKE_FIND_ROOT_PATH=$prefix -DWITH_UTILITIES=OFF -DWITH_TESTS=OFF -DWITH_GEOTIFF=OFF -DWITH_LASZIP=ON -DWITH_STATIC_LASZIP=ON ..
|
||||
cmake --build . --config Release -- CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED="NO" CODE_SIGN_ENTITLEMENTS="" CODE_SIGNING_ALLOWED="NO"
|
||||
cmake --build . --config Release --target install -- CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED="NO" CODE_SIGN_ENTITLEMENTS="" CODE_SIGNING_ALLOWED="NO"
|
||||
cd $pwd
|
||||
fi
|
||||
|
||||
mkdir -p rtabmap
|
||||
cd rtabmap
|
||||
cmake -DANDROID_PREBUILD=ON ../../../../..
|
||||
cmake --build . --config Release
|
||||
mkdir -p ios
|
||||
cd ios
|
||||
cmake -G Xcode -DCMAKE_SYSTEM_NAME=iOS -DCMAKE_OSX_ARCHITECTURES=arm64 -DCMAKE_OSX_SYSROOT=$sysroot -DBUILD_SHARED_LIBS=OFF -DCMAKE_BUILD_TYPE=Release -DCMAKE_OSX_DEPLOYMENT_TARGET=12.0 -DCMAKE_INSTALL_PREFIX=$prefix -DCMAKE_FIND_ROOT_PATH=$prefix -DWITH_QT=OFF -DBUILD_APP=OFF -DBUILD_TOOLS=OFF -DWITH_TORO=OFF -DWITH_VERTIGO=OFF -DWITH_MADGWICK=OFF -DWITH_ORB_OCTREE=ON -DBUILD_EXAMPLES=OFF -DWITH_LIBLAS=ON ../../../../../..
|
||||
cmake --build . --config Release
|
||||
cmake --build . --config Release --target install
|
||||
@@ -0,0 +1,40 @@
|
||||
/*This is a generated file...*/
|
||||
|
||||
#ifndef TEXT_ATLAS_PNG_H
|
||||
#define TEXT_ATLAS_PNG_H
|
||||
|
||||
namespace rtabmap
|
||||
{
|
||||
|
||||
static const char * TEXT_ATLAS_PNG =
|
||||
"89504E470D0A1A0A0000000D4948445200000200000002000806000000F478D4FA0000000473424954080808087C0864880000200049444154789CEC9D79FC6D53FDFF5F6FB9487413924844FC88287C2543869006A24832954491211129241245C60A9967C99C0C190A99E729F335DE6BBAD77571EF7587E7EF8FB58FCF3AEBAC33EFE133ACE7E3711E9FCF597BEDFD7EEF7DCED97BADF7B4A4442291482412894422914824128944229148241289442291482412894422914824124312AB5A81C4E006D848D20A926698D92155EB934824128944A204805371BC5BB52E896A00962AF8F84B1779FC4422116796AA15180C0073D75E5EDB9C615B223192C8BEFFA74BBA0758B840511702B702CB1728239148241AA19E75B3B6F15EDB9655EB5815555800B2C1D7A2C0A8B264B6D06534B048C1327C762E5256A700F303B7797AFDB220396B7A32C6016B17212791483432682C00C0CDC07DDEEBAAAA75AA1AE0CFDEF558DB6BBFD06B5FA200B96B0317002F48DA366B1E05BC04FC1D58276F9999DC9D8087244D92F48CA4B7813B806F1521AF851ECB0267012F4A7A43D2B3C0E46C96BA5599BA54013087A48B24AD92354D9534B620719325BD94FDBF80A4F381150B92D511D9E0B3F6FBBAA54A5D122317608EEC9E53FB2EEE52B54E8501BC1ECC849E2A51B6CF2A599B6F01D8B82C5D02BD1ECBE4CFC433C10213B3F64905C83C16984E6BA60187E72CF780EC3C9BC9DB2E4F792DF4D824F8EC43660247E42CD3E787791EBB477D4E0CCEB7D01B0FB03AF0A627F3212A74BD01F37ABABC5C951E89910DB06DF03B5CA96A9D0A0337BBF479A444D93EF3666DFE43E0B365E9E2E934073025933FD66B5FC1D3EBFE9C651E1B3EEDDA70504E7297C6CDB06BFC0F67E578DE6B1B0BCC19EC370F701CB0784E7A2C41EB877F8D99C0F7F39099C9F5D934AFE3F6A8CB977103AE1AE79724779FE03A1C5786DC16FAD4AEC13355EA9118B900177BBF8707ABD6A7508031C10DE0BE1265D798E4B5D51E0433A960368233C3D7B8D96BDFC16BFF7B8EF25606DE8D3CECEECABE880F47B64D2687086E607FEF988F913DE88145A87F206F16ECF797DAE7067C23073DFC99AF7FFEFFA0716090DBE02B38EE1A791DB7475D7CBFFF048A0DFE0B65DFEBC99E42494181C00A91B637323D1A6EBCA4C0E044C1E0E2A0DEF07E0FB95A5C6B0C9A180049619059156967E3236D6F9A59EEA6F60EF0AD0E4F78FF7FDAFBFFB11CE56D2D290CBA3BCCCC5632B34DCCECD3924E09B6CF2169C71C64FB0F99DBCCEC1D4932B3E724F90FDAC56AFF006B4AFA5EF6F61549D7E5A0C7EAC1FB33B2F3FFAAA47525BDE56D5B96C02291132FB5EF520CC0261AF0FB4BD22966F642892AF837B9D925ED5BB4405CA0E9B5C0E3C0C1DE80E79DECEFDB59BF7971568AFB249D56825EBF04"
|
||||
"9EF35EB7152D3331A8D852D2E8EC7F249D53A12EC5033C18CC846E2A51768D7BBCB6DA8CEFE9B2F408743AC9D36B6FAFFD4AAFFD3B39CABB3AB8FE9308A2F07126F77026FCDF1C649FE21DEFA460DB35DEB65F78ED77656D3381CDFBD5213B66786EEB07DB6F0BB62F9093DC1A33C26B5E26C1776B0AB068053A3CE9E9F036055B20802D82CFF41DE012E0E5ECFDFDC0D9D4CFC65E2FFA73028E08F47AAE487989C10570B9F7D9DF5B949C598B3A700F8433FEA915E8F07A876DB983F3FDCEE535F991D07301DB64FF2FE3B5CFEFB53F626677F5A1C21CC1FB37CD6C9ADF606613703ED179BCE68FF621B3866F61096FF80B79FFBF2149C07E1AB83E9798D90539E820357E07E7ABFD03CC23C98F3578D9CCF20E109B145EF3B2C0C5BEACE535DD6266632A50E532497B64FFCF29E9FB9272893569C28292C669E07BFC7E497ED0EF67B297CFFB25ADA97CAC4E89441DC068495FF49A0ACB881BCC0380325D00355FFAAD5EDBE5923E20E98192743842D2A24DB6FDAA49FBD1DEFF474AEA6700302178FF51E0F366169A1E0F50FD43F9ED3E64D6B849D2AED9FFEB02FB4BBA59D2373430E0992EE9065CDAE3CFB2B6F192F6CC417E8DC7E452D16A7C4FD239D9C3FF3C7903024997E628B776AC980BAA2C36937BB0D5B8BD223D6ED0C0004092365081030033FBA3A43FE2525BBF22690DB9D2D7B379DD90F494DCFDE13A49979959F87B4924F2E23B926A712633259D5DA12EE500DC1098BC2EAA5AA732019EA13FFA4A4D03F68B1CF351B2B4C8A2C1E5BBB6E2BCAC9F6F1ADB2B671D7E14917B2C8D01AA4F9093F97FB0009C169CE3D72AD2630E9C19BEC6DBB8BA0465C95F3B93E9737559F23D3D920B608442BD2BAE9F49DDD081461FF4B955EB5426B848F8A3B3979FFEF1A8D77E9DD77EBBD77E347DD62A0016045EA591A9B8E23FEBE675AE4DE42F4EA38FBDC695B8F883EF32502BA090A028E0EE263AD4789C48D4F85027FB3EF92CD47EAFC274792AD065FDF67BE5227711E0594FEE73DEFF0794A183A74B1A008C40B2FBDC5BDEE75EA4FB6BF0005C1A7CE14FAB5AA7AA007EED5D87E3BC763F586E9F02E47E9BFAD997CF4CDC2CBDD0AA7CC046C061B82A88BF65A034F33C0CCCC4A700AB16247FB516D7E04A2A7C301609F53517DEA858975B82EBBE6BFBBDFA96390AB829F8ACD7C40D80C9FEF69D6A1A91BB0CF515506BAF17836B30A549BFFDF2D629511DC04FBCCF7C3AB06491F206730C4015418083057FF535BF20D2A7BCFF732D02244966763EAEF2D9F1AA0F3694DCD2D19F97F4379C497457337BBC001D2E930B040BF9ADA44F64FF9F6466B746FAE4C11672296821CF4AFA8E994DAC3500CBAA3E66E07F66F662417A158D1FDFF066655A3842FF7A1983AEE3349006FA86A4DDCDEC71E054B954D7D9249D003C66668FE628774E49"
|
||||
"9DD43B98BD49BF219F1E888BBFF8719B6E3798D9F165E853315FF7FEBFBB887BECA004577BDDE798AA75AA0A0652DCC0F3C17BB38269B8C0B4A2E48F027E41BD0934E4556083A27408F459C39B893D4D568805B760CDC6C056C05A7DCA9813B8AAC5F9025C19EC13BAADBEDB8F0E55917DDE3E95DE747055207DFE5C82CCBF31E05EDACB6B9F8701B7C02406B26EF292BB529BEF5C3BFE92A73E55006CDFC1799E5AB59E4583BB9FF9D6C7FD8B9639980A014D09DE4FAE448B0AC86E02EFBD247D32DB3445D28CAC7D75B99425C915BE59DCDB67DE3CF531B36966F65BB9B4B79D24FD572E12DA673E4967514EA5B823E5666048DA47D22CC0D9929E977489A433E532045EA2F7D5F4FE2E17715E0349610D880D831B6E1808385423C33F1CBCAFDAFA16DE0BDE1FED952366B699A41F4ABAD4CC7EEFB54F90F40B398BDB3A667646D1BA24462C5B69E0BB3E5D2544FF0F26174078D3A9FA2654267736699FA3C9B68F05EDDB4ACAFDC694E5A49F2067FAFC8AA46335303891DC20604FD5A76DE50AAEF84F6D118C4BCDEC02E03A49B115091794742C30C3CC3A9E19013F95F4E5A0F950497F924B4BF35D2F3FC4D542385BF5AE1A243DD4A9CC41C6CCE0FD609A18488DFA158299FD55D25F23ED67ABB89BF1F31A486BF55957D286DEFBD7E5BE9321A5954C4F148E6FFEBFC3CC0A5F106F300D00C251FF481A00540AAE9EFFFC5ED34C33BBD9EF636657E21625BA45F533B2D50AD46B09493573EC04493FC599D96B0FFF99922E90F4A4A48DE40AB698A45F4AEAC634FACDE0FD7366B65FA6C3E692AE96F4916C9B49FA8D5C3C849F9EF64256BA78281206FDCD16ED551E61DA5F786F183664C5A41A5278818FA97E00F08E99E5BA0AE520E242392B632B2A0D4C2D1A6041495FF09AAE6CD63731CCC0951EADBDFEE7F980EEF1DA7D7FFCCDC13E6BF729FFD4C0DF369326A54E813B82BE63FA91DD46AFCB3C397B676D7EACC8455EDF85A85F5276AD2EE484B10E3704DBBF4C636E78C8E9B99D7805509F7A54E94086FA3C6880D8CC7758434A031C51007B799FF5546091AA754A54007085F745D8CA6BBFC76BCFB5380F7078E481169AC46B7DEF0CFA15B25C2AB025034159B77BED7EA0DEAF837D1EF0B6751C90870B2CF4690882037E804BCB89319D3E8310AB86FA4254552C7EE5EB121685FA5195FA5401690030A200FEED7DD6FF294BEEA0F1F5E12291F7C02DF1DA2E256438B384F7BF9FE253F3BDBF6D667997698DA5D4ED43B0DA5DF6905B2EE897FBEA75B85AD8BF9533B74F95F4D34E77F5FEB72E443E1BBCFF1441EE79E61FFE5393FDFF66663776216F30E2AFFA3717152C04E4B160F07EA8C656248608B86C8FC37195468F02E66FBF576EB217917329D6B8A22CD9832906E05C79BE58606533FB5E8BFEC30E5CC9D345B3B7AF99D99359"
|
||||
"FB721A581AB28819F73FE51E829FF0DABE28E9119C997DAC5C46402C47BE8805517EA7FA9CFF5BBC6D7EBDFCF72AF2E152033FEE6DEB666072B9EA17C2915C7DF8B525DD2DB748D367E402B3627CA80B5983954755BF1CF2E7248D295B89EC73F417987AD3CC4A5B1974A4825B7DF5BDDFBF998D3413F47992FC8A932BCAAD0B51065B6920EE66AA4642ED7F1F606E5C6EBB4FD5C5484A075779AC866FF6F6F3642F2E48F6B691CFA01D4F67B3F5BC75F911CE24FD5ECEBFB76D3B4FFE0CE04C606FEAD792184717CBB5E2AC4FF77679EE2127E67D1DCA04574BC1E7F7EDF72A448F6F057A8CC815F780DD70F136B557AC38569EF2FC65984BC9BA182C64BFFFA9C1F76E2639A757B790EF57BEBCA1FD1EC38CEC0398147C00E3AAD6AB6C80DDBDF33FCB6B3FD26BFF5D81F27F44FDBAE7AD788602170AC215E689D6DCA7BE646B8C4E5D06FE3197001EEEF0DCA7E16A0E84ECDBFF99574376BD277AE77273FBBD0AD1E3F8E09AC652E4123943FD006046D5FA940D6ED2E0534AD601B018F06E3FF7AE61016E35BADA85980CEC56B54E65039CE87D117EE9B5FFC36BDFAAD53172D06129E074E0B5E8A3CF55233C960A57C30316C0653F844179E37175037A3DEEDCB8E0ABB00E7B8D89C045C05AD9757A3ED8FE2EB0659EE75A26C005DEB94CC3A58796AD839F913181022B5E2606A03E10F69DAAF5291B604706B288DEA6A4E70FF02BFFBA57795FAD9CECA6BA29B078D5BA8C74705699B5191819DF4D494B03770A6EF4BC35F063E01B04EE823E8FBD32CEDDB02B2E03606DBA702B0C45B273AC655E009C50B2FC1D8201D59076AB0C2580D7BDEB5E4866CF6007188D5B0CAC14D37F26D35F01F59AB2E426121DC1407AD888F4C58E34806BBC1BD25BC052EDF7CA45EE28EA6B604CA4DA4C841103B07C30F02B24CE28514F36819984B3784F0676A95AA744A28E3400185964960F7F4192AB4A927B6830FB3FB00CB9090997F6E6B379D53A2512894100B0332E3E63C8FAB613DD01FCBACC8731B0116EBDFB1A29EDAF2470F134E3D3B54F24128984A4862579A703852CF804AC437DE6C913C9F45F1EC0260C647F8C0756AE5AA7442291485408CE27EF0F028A1A007C1657CF015C0C40E99907231D6051E02460C3F6BD138944223122000EC0A54516968E07FC17389712CBAF2612894422916803C19A1043EDF88944229148241289442291482412894422914824128944229148241289442291482412894422914824128944229148241289442291482412894422914824128944229148241289C41000987324D7E8CE96CB5CA822D9A3B2853AE6AD427E2201CC0B2C52A1FC05D2F73F3112C9BEFB731729C39A08DE48D28E925696345FD6EF6D490F4BBA4CD2116636A548C5223A7D47D2E6921E31B3FD0A94335AD25E92BE2C691949EFCF364D97"
|
||||
"F494A49B251D6B66F717247F39493F91F445499F94346BB6E92D498F4BBA5AD2F166F66211F29BE83487DCE7FE11AFF92D335B3D6739074AFA4697BB1D6C6617E6A9870FB09EA4AF495A55D247257D48D258335B2AA7E32F20F799F6C3DA663621277D4649DA59D266929695F4C16C53EDFB7FBDA4A3CDECB13CE435D16147495B4AFA9CA4B9B2E68992EE9074B2999D5F94EC44A22AB265B07795B49EA44F499A3DDB3451D2A3922E96744C61CF5E600EE06C6026AD791458A11025EAF55907380518EBC93EB54079EB032FB4397780B7805D0B90BF3FF07607F25F01B6C95B7E0BBDFE10D1616201722EEFE0DC4376CC5B8F4C97B5801B9BC87C3247390BF770CE21B958E8806581FB3A90F706F0A33C6406F2E705AE6F237B266EE5C05179CB4F24AA02D80678AD83DFDEFDC092452971613BE91E2FE2462C79EBB01C70046E6DF018850C007037FC495D9CFF34E0BB39CA3FB40BD90053812DF292DF42AF95817722F28B1800DCD1E53580020600C02EC094163207D3006026392CD58B7BF83ED585DCBCBFFFA3805BBB909FAC00896101F0755ADF6F42EE27EF0130B05D44D014E0DFC03F809723DB2FCD51FE86B807C08C36279FFB000077F3793C22EB45E032DCACE48DC8F6277292BF0AEE811EF25C76EDAF07C647B63F9387FC36BADDD2E47328620030A6E5271F27D70100B02730BD89AC49C013E4FBBD5F1078B58BD7B440A75B73D2E3C8C8F9BE0BFC07B892F8EF3FCF81D0E191E3BF055C035C477C10FA83BCE4271255417CE23309B809B89BF8337197BC95086FF493800DBCEDF347147D17C8CB17BA7FE42463143100D83D22E71ABC000C9C65E2B948BF757290FFA7C8714FC3F9DE6B7D16031E8AF4FB7ABFF25BE8F5B3169F43110380F026BF51DE32DAC85F3DA203C03F816F50B1D919583CA2DF0E391DFBD1E0B8D3806F78DB17061E895C9B3CBEFFF3D238C01D0FACE2F5591D3700F279B85FD9894495004BD0F8807F0ECFCC0FEC10F9DDE53609A9CD42C259CF49917E6B4714D93F271DC201C034DCE827A48801C0D5818CC9C032917EFB45F4D93307F9D705C77C93C8C306D83A22FF97FDCA6FA2D362C0EB117935721D0064F24272195C76A1C33D81FC77819F94A9432B681C283E1BFB9EF478EC7060717DA4CFCE91CF68F71C64EF1439EE61917E7B47FA6D103B660F3ACC83B3425C0E1C45C9994F55CBEF065C66D8C255EB9117D9B55FA022D99B46BED30745FA8593CFBBF2905F8B30FFA2A4F705DBFE157636B31B807172D1D0353E938722199325DD2EE95A49E79BD95300391EBF198B07EF1F33B34722FDEE89B4E591A6B1A706A2AD2569B2994D8BF47B28D23657A42D0F8E92F461EFFD2BAACF02C89BF0613FB5C848F3106053499F0D9A0F35B363CBD2A115B854B830E6E3EC26DF935E0807122F44FA3C1E697B7F"
|
||||
"A4AD5B568EB4FD25D276B2A4DFAAFE5EF545F59F452149E7495ADF7BBFA2A4357238EE5091DF1660690D64881C24E9F86A35CA8DFF27E91AE00A497F32B39B4A94FDB0A49D82B61B23FD2605EFC3E7754FD40600B1995633F3DA8BAA1F002C9A8722723F80E3CDECF59C8ED70D27ABFE41DECCB7F9A148DBABFD0A37B3FB3AECBA6CA4EDA97EE587005B4AF25D0B77481A2B69E3BC65797C2278FF4A81B26284A6F427CDEC0049C265BC2C26970AFBA0998D2D593749DA43921FECF796A43C07272F4BF2EB5D7C2CD2E79391B6A773903D5FF0FE0D336B886F31B3D78157242DE835F76D25CAAC286B05CDAB01F396713FAA5A7E3B808DE5D2C2D795345B41327EACDE2653A799D9CB39A83097DC00FBDBC01D92CE90744AD1E9EED924A7E5440758428DBFBD67735382780050B4F8062E28D0E77FB92912971752581A6007BA9C13E8328388ABA020D9F302F706F2C7E1EA16E429671E9C69B9C6146035E0924076DE2E80DF04C77F14670ABD1F98800BC27C26D3A3DB5A019DC80FDD1D47E25C3E6160E254E00660D5BC7568A1DB1CC0F3811E67E62CE3D4E0F8EF02EB7BDB47D3E822190BCC9983ECCB82E3BED9A26F98A9D060A9EC518771C171DFC8E3B843457E449FD1C03EC4E38E0076CE59DE8B4DE4B463A51C64AFDAE4D863816328D91519D1EF5F11DDB6CC53C0091101D1D1188DFEEAE77353242E2FA4920100B0128D7ED2C24C45B868F483804380D369AC4F301D376ACE5BEE89819C63B3F6A2070027473EEB66CC04CEC30B92EC53F69A11194FB4D1E12DE02B79C8EF40BF304875065E805C4E3296A2F121F40ECE277D36F074E433E8DBFF9FC93E2D727DA3036BE0C9A0DF7F73D261475CEC0DB85A1CBBE571DCA122DFD36305E0245AC7FFC0C81800D4988ACB84D9248F73ED42AF39804B23FA5C94B7A09322423A1D00145A912EA257E90300606E1A0BA44CC39B21152033967150E30D608F0264AE8B9BF9D578AAF63DA0F801C03F5A9C6F334ECF49F68E3DC80677D32ABC4C2DF07020F78682E4AC4BBDF5A7195389042AF521778F888C06FF32B0348DB53A72190064C71F8DB37655527AB84AF9C016C0B534A699863C0CFC8E9CCB4353ED00606EDC84EBDFC4D3B17D1EC15906CBF8DD87963170D97A7D5BDD6ACCDABE4B42D2E992960FDA8E36B36BAA5046D205924ECBF380383FE4911A080643D23E6616069F1445389B9F2EE906494F643AADA2C680D3AD8133CCECBA3E657FB849FB044957C8C53F2C295712D8FFCD7C4CD2CF25EDDDA7FCA6E08AED84B3E1138B906566D7016748DA4F4DCA8467DC21E9AF398AFEBBA443541F50F83DE03E333B49728313497F5263D0EB3B792961661325DD92D7F186827C5C60DFA572A5679BF1A2A42B259D596080DC21EA2D06A06F0B74768F3B42D211B8E2765BCBC5407D4E8DC1764B"
|
||||
"4B3A58D25EC081667654BFF2630047AA3E0E4B7201F21B99596EDFF99AB06401682E3FE61E293C4A94D61600702E8158F474AFF2421FFC85C1F6422D00998CCF03BFCC646D1AD91EAB97705E0E726355181F02160BFA7D3FD22F9762502D74FB6F20AF90CC089CB9F19AE65FB706C691EFF7EFCC26725EC795BE6E569EFCEF79E9301221EEFE026765BC10D8BC6A1DAB02580667ED78A0C9F7AF21553E27B90BE35C8C3E775294D58146BF2F743E0088A50BE5A95B48690300E0F711F9FFA384D50171A6C075810D7079D2E7526F9E073748E83B081057E4C837ADBE4A50E6991206001DE839378DA6C2BE1FC0C06191CF399A5F8EABCEE53333BC5679815B9B22BCF114B210166ECD8D907FE28A906C0E1C4DE33A1563F2F8FE65F217A4D1BF1F23BC1E27E4217FA4427C00F032B02B05AF44375400BE45E3EF1E8A1B00FC389033099709903B3573E6E416DB426609DEC7F61DF200BF92CBCFF77949D2B7CA5889CFCC4253E05F704587FEE0B57D5CD26E7239B9FD70B4EA4DABAF483A8CFA120CA1F97D0E06EAB15F6F6685DF88CD6C1270AFEA53D4F2188C4D8FB48D6BD2F72649FE2A882667A21F93831E21BBABDE143F41CE0C9E2B38337018557C91997DD37B7F0170A75C7A544DA74F643AFEBA5F1DCC6C2CAEAAE529923E1FE93259D23199BCD9BDF6586D8E447F7C44EE9E70102ECBE24233EBDBD2D60AE0443577C5B5E2E76656442AF49A92B692F415E5738FE986D0E5F71F33CBADEC7603349A7F6936E2006E0BFA759AC3DEAB6E21855B007051D76179C6D780CA0B73D0580EB5AF3804DC0A70FD52C848B889BEA746E4F7151403EC15396634CD8F7835BCEFF423BF899C15690CC82AC4F70FFC3C724EEB35E91B6647E4EE0EC3955DFE332E02FA629C1976191AABA6CDA4A099D1480197F6FB3BDA077F8EC5FDF60A097CA6C220404F876570D6C058C96B9FB771EE91D5F2921DE8717620AFB06264B559FE98C8B6A5152F8813964C7C294F85AA06D85ED2E1AAB7744C94B465510130B807883FD37B366201A83156F585533EDAA45FA7F45DC8A85FB21FF1BA41F3F9663626D23DF4834DCD212826F63D5F42526CA19DD8F52EA258CB1EAAB7C24D939B0117412CA2BB59ACC12B72D7A6C6824DFAF58C995D22E992B01D1718E5735BA133A31180994D90B48FA47DB27BDFF7247D418D41A01F95B49DA4ED708B40FDC4CCAE2A53D7A200169774965C45CA5615F6C668A0605D61AE6F33FBAEA4DC56DA6C0BB064649413ABC5BD148D3EB8C30BD62DA4300B00F06DDC3A003E932878511A1AEB0BFCA749BF51345A00FA5E0D8EF6A92FEDE8CB02006C15396634CD91C6C23C7DAF88888B2D083F83688A212E55CAE75D72AE230E2C4AA3BFFDCA3C6504F28E8A5CFFE8779EC69962A185C03CB97BD178EFF96119B2471AB8BCF8B369BD3C"
|
||||
"FA48A903301D57F86B9B3CCE73D04263AEF18B3406829D1BF49949C166F1C80752C80000F81A8D5FF877806F17212F901D9A9CA60161DDF76641897DE7C2E306804BB7795D19C87DD3DBD6D72C10B7CA5D68EE7E98C0B44FDCFC7E4E7F67FFDEB12F8F7CF6EB057D36A5F121745B1EF20339C746CEB3C8551F7789C8BB89A0D012715749A1A9B0B800D5336974C9E5B20CB22767C82CC65316C00238F770587D11F21F002C0D2CDFC3ABEF6260C40700E381BF02E1FA208583CBC8F915EE79BB3F39E6FDB7121A5BE9EE39DC43673FE2E508EF2C41AF902256035C93C6E548C1959EBDA683D7727DCA8FAD853E0D17797F20CE2F158B429D414EABA175A063D185806229684F017F047E817B084C899CFFEAED8FDE91FC7568CCB2780B57A5EE97B86A8CB1A582B7CE43BEA7C73CB878139FFBF3941191B900F1D9DE23B892C807E28A92C4D625CFA51AA0A7CB1AC005C055B88C9B7095528089C08A39CB0D57042D7341985A76C973B55799B23B01B712E90DDEE791EB00A04AA81F003C805B7532D712EB5DEA7371F05DBCAC0CA1A380BB223FB6664C01D62A41AF90220600477471DE31D6EC53FE68E0C11EE49E96D325E844C7A20700CBD3BEFC68C8C939EBD0EDF720DF929C4E87032372727DC836917B7097E70E907B043EB04D1B99E3812FE72C73148D6EB0999458918FFA14C89965C9ED165C49F4D3C8B3167DC5009FC5059C9652DABB1D344E34A690D3B2DFED042F815B7CA51D6F01DB15AE9046C60020D36161E08E0EE5CD20E7875F07FA955108680D1A6BCE37E39F14601A03FE42F3A233A1FCBC17621A45A38F7D5C11E7D944FE31C467DC31EEA180FA07B41E00DC44418B3051FD6240FE00604699B213830B5CC6854F792BA3E266A387110FCA7807E70BCEAD025807FA840CCB0180A7CBEEB855FF6235B9DFC19946BF9697BC2EF42AA5101003DFBF30D80FDC83F9095CDA5A6123625C30E89DC41F868F033F2B486ECC175F48A9D1163A7C39FB8EC5DC1D3319A8855EC8F5A77100F002CE255068453AAA5F0CC81FF8E65BEA3531A4C8BE8B3597DC5B14B0E85B8D56F5BE85F3AF2E2E57A77D9C5C4182094529931800B7D8C6E7E4D26FDE95F482DCF52F747DEAC1042E006739B92245E3253D64660F95287F71B9CF603EB954D087CDAC507FFC600167755853D2C2726B318C97748799F59D75D146EE629256944B777DDACCC616292F903D5AD2B292FE676645A476B692FDBA060AE18C31B3C55AF54F0C6F7041A89F96BBE7549EAA9D4824128902C0C5BFF86EA78BABD629313208CBFA26128944A25CBEA77A6BECB95529924824128944A2047029987E0A72A9E9878944229148242A00D80457D7806C20505A80752291482412890AC1957E3E09D8B06A5D12894422914824128944229148241289442291482412894422914824"
|
||||
"128944229148241289442291482412894422914824128944229148241289442291482412894422914824128944229148241289442291482412FA07BC59000020004944415489610FB030306FD57A24AA01981F58A86A3D128944F9007303A3F33EAEF5A8CC3C926A37A3A7CDEC9DFC546A9075A8247F95AC9992BE6966CFE42CE74E49A35A747957D2DB925E92F4B0A40BCDECF13C7508F4F9BCA41D24AD29E9E39266CF364D96F4A4A4DB241D6F66F7E724AFD5F94F963441D2B392AE96F40F339B9687DC0EE5B7E35766767945F25F31B3F5FB91DD449FA524ED22F7F92F2EE903D9A6E992C6497A50D20566765A4EF2C2F37FD4CCBED3669FE5259D1E345F6D663FEF41FE5F25AD14347FA1C87B4BB7001749FAA4D7F4A699AD99D3B1BBBAFEC019923E13344F96B46D2FF7A55E3EFF3C69F1FBFB9D999DD7E131B690B44F64D334336BB9CC7244FE2449DF30B3D75BECB3A2A49383E67F9AD9BE9DE8DB469F8524FD44D23A929694F4C16CD35B72F7FF1BE5EEFF4FF52BAB13651606F603FE0DBC4C3D338137803B812381D573943B0A184B2387E425C393F56E444E2BA6019703CBE6ACC728E044606A073A4C058ECA496E37E73F06D82D0FB93DCA0FD9A642F92FE671FE812EBF03267528FF1E60B91C6486E77F7707FBAC1AD1E7FC1EE5DF1839D6DCBD1CAB28804702FDC6E778EC8EAF3F705093EF42D703AF5EE41741447E8D8E07F6C0154D8EF16E8FF24F6CB3CF9A917DCEE954DF16C7DD0B78BDC9B9F8BC01FCBA5F79AD1499073886CE6F460033808BC9E7A6B47513190FE7717E81AC5E1F00E3805573D2614EE0EA1E74B8A0A2F3BF829CCC523DCAAF316C0600C0F93DE8F002B0449F72D300A00D0C820100B031F1C9C1D965C82F8A88FC1A93E8C0F509CC0BBCD5E418BD0E00A6D262424B010300E0B826E7D08AB37A95374B0B45D6903333FF44D25C59F35449774A3A4BD231928E93748E9C39E24DEF98DF907413B071AF8A656CD1A47D19609D3E8F9D170B483A36A7631D2B29664E7E4BD2E3929E92FB0C423603F6CB49876EF8AAA4AB80392A903DEC000E93B47964D3643993FF5D9262038E85249D54A06A8941006E907782A4D9824D77CBB90B87237349DABA837EDB68C04D9617B349FA7DCEC76C4A760FDF39B269A69CDB6FACA41991EDDF05FE90A7221B0213BC11C65BC051C0622DF69903D81E78C2DBEF6DE0DB3DEAB020F04E8B514FE87BEC0B1A4780F7E25C1FB5D7F2C096C0354DF459A34FF95FC7594F7CA600BFC69B6503A37126E26941DFF1F41124D6E6FC9706BE059C064C8E9C7BE807CB5B7EBBD79C15CA5FB05FD999FC55689CD9CD044E20980101DF065E8D7C0EDFEA437EB200B4810A2D0038D7E0AD916B340E172F52A8FCA289C8F7B9B183FDFFDD62FF5E2D0035766FB24F6E16006025E2CFBBBFE359D3"
|
||||
"81A5803371F786BA7304D6EB45764C11FFE1FF281006E7B4DA7F0EEACD98E380457AD063BF161F08B81B606E334FBAF3C1DD10D1A767FF5B76CCD8C02216D052EB7F7AA4FF2FFA90DFA909725DDC60C3673A7DBA41BAB9FE453008E49F1DF93CFFDAA2FFF691FE17F5213F0D00DA40B503801322D7670AF0F532E4174D44BECF5460D116FB2E4AEB98A97E07002F13995C91EF00E09C6E8E05FC39D2FFCA6EE5D6B900700FD4D3257D286B7A44D27A667657A70734B32966F66D49FFCC9A1690731774CBA6C1FB1BE522A06BCCA7CE4C43457075A4AD675F386E80B476D0FCA499FDAEC56EB140C82FF5AA43A798D975920E0A9ADF2769EFA2650F57805172EE149F49929A0E2ACDEC643997904FC703F5C4D001D8417113FFAFFBCD7E19C48CF3FE9F4DCEC4DF8C6D55EF1619D7AC638F7C4452AB7B715FE02CBC1B05CDE325EDD162B7BDD5E80E5C0F58BC1BD9610CC0019296C9FE7F43D21666F642B8136EE4FF4B5CD4FFFEC086611FB9D88137B2FFBF4A17D1F2C0CA923E1B349F25E7EBF289F94BCB2096AEF2521FC75B5FD2AC41DBBF5AED90A5FA3C27699AF7FA781F3A748C991DA5C61FD917CB903D4C59438D03C89B5BA520651C21E713AEBD86EBC360C492DD0B7FAFC694EDF3CCECD00A542A8B1B83F7E103B2D5B670DF3CD8823C4CEC71365063FCC2B566F672B31DCC6C92A47F04CDB32A1E43D694F70600C0FC9276F2B61D6E660FFA9D81E5801B24DD22E9377223945F4BBA127810F89AA7E05392CEF414FB51177A7D4FF55FF88992CE95149A38D6A0455C4211E0FCCDA17562B2A42BFA38ECE7226DF7B6DBC9CC3E6166B379AF4FF5A143B7DC16BC9F07D8A044F9C38955226D0FB4DBC9CCFE6C663B79AF580051628892DD6B4E56E3E0F01E49DB97AF51A93CA2FA49D567717527EA005650FD64F125498FE620FF31B9DA2735669574780EC78DF1F948DB1D1DEC774BA4AD65BD83107FD6B9B3064CFF6324D54515E20AD35C24A959D0D3B2922E055637B35BB3B633E48A99985C41834E09FD5AFF36B377329FC8AF3CBD6797FB21FCB28B6377CA07802DBDF71F94B4A8A44DE40A33F89C6C6663FA90154B7379B68FE395C11391B62515778FF4C242B86227AD78CACC8ACA839D1558BA4D9FC97D7EEE35E68BB43558DE4AA693EB3FA87CF4C390632485E9D42F4BDA723015482A8839E5267C3FC8DECF22E706D833E8B78DEA278BFFC8F6ED97B7E52C6C077B6D2B00FB9959DE75683E1A69EB6410F360A46D816E04FB0300DF8C72815FE90D57F9EF4C0D3CFC27CBCDC81F94AB52B64BD63E8BA4F7CC96667617F0ACDC83733160CE765F5C5CD6C0C241F3A5D9F19EC405A7F833A64D54CC00602949ED726BA7493ADDCC7ED2A7AC0F46DA720B302A888991B6D883AC571650FB188F3BE52C5045F019B959482BEE91B4620EB262"
|
||||
"9F7FECFA964927D73F511C8BA9D10D2AB90AA48F95AD4C057C40EE99F303AFEDAB6A1C007C25787FA672720D9BD921C066927CCBC39EC0393957A2EDF5FEFF6A87C76ACA2C9294050ED4CA4A22E76FF7394452ADD0C85449DF36B3ED335FB06FFA9E2E29BC3063B2BFB34BEAA44A60587E72A224BF14E43F83EDCB0061005D59DCAF46B7442F8479BD92FB1C063353226D79E7E18E14668FB4CD0C1B8097706998AD5E69BD80E1C13C8A976ADF16880D0C861BEF37B3FFA87E10BE14B056ED4D76DFF753201F31B39B24BD3F473DF6567DF0F93CCABF36402C9B2D767F0D894D12BA3AF75A0CC0DA7291DC9234C6F7FD030B48FAAEB7CFD941E4A9EF1278235223DE8F546C59D1298B43583768BE31B01A9CADFA0F447251A055B092A4BF037FECF338B1E20E3DADD3502261D0A2E4D64B48744FA79FFF1C1DBC06FBF726D11F7329BFC26383999A193F0C6CDDB2C9FF927459B06FDF98D935AA9F804AD226F45FE4CE27B6AE4A27EB92C4060E5DADD152BB89FB8B4A840B496CAE7AB342581FD9F75F4C5023FEC3BADDE8E47B1AA83A58E312FF4DE606B847D2FF79CD5F01E630B34E464D9DF2801A2B11CE2F17EDBEAB06CCDD266937E03A33EB35107052A46DB0FB573F14696B17B5DE0D0F4BFA719B3E6FB6D9DE0F13D5DE0FF7BF9C64C5CEA3EACFFF09D5FB3F632CA802D3A312EF3143031334495A0DD877986701D49E15A7CA99FD6BCF2A3FE3CCFF7F7AD6D7DF372FF6918BD49F3F7B3F8BA44315AFDAD70BB1FB7F2769E5317F7FEC584DA95DD48F796DCF057D7CF3FA8B66767BB07D7EEFFF98DFC29FDDB41BD584D1F548FA421680E813CE72E697B495A4A685537A60BA99850F804725FD077840D2C59E1E269741D1EB002066CAC9A5C25C81C4F24DF30C5C9B9A9900ABE22933CB658D870E88FD6E62A6FC5355EF66595FCE575C0493CCAC65102039AD819168C985929E56639D8D9F03979BD94315E85406734A92993D06DCA601F7F1C2C02672F75CFF37729BB70A62AE0300337B11B72AED915EF3D2AA8F4FE887D8C4E95392AE6BB3DFFF8BB475153B561B007CB8C501FC45469E8E1CC30FFC8A9D88BF7D6C3345B2148F3085C1D4798DEBCD95EF00A0296676293056F503A74FF771C8D84C32F6E1D6011CAFFA51E07833FB611F7A7443587466AAA46B4A923DDC882DE9DC5037C3CCEA02A080EB54DC0020513DD7CA99B9DF27E96B1AA8D122B919E2B16A2C20365CF01FE297A83E7E6C73354E022FF6FECFCD0550C3CCFE9805A8FB01E83D95B98F705FA42D961A1E122BFCD5367DD8A71603E05FCCD0BFEE3FE4621596FC07FC6B91EDFEFEADA257B7578BC5893A604D5A948B2C80309BA19F55F16E88B4B50C98CCAA477D4FD237BD572995E080ADD4F8E0B9DBCC622EA0447BAE91CBACF1599341560A7738027C17B823786DD7A4"
|
||||
"7BF879E4E9720C1923E99B66362D736DEEA1C67BF35A40AB6A7143197F00709ADC826835D697E417E5794BAE826D8DA21627FB99EAE39CDED7AC63975CADC6A0DFF5B30AA1AD8815E0BBBE1BC1B507AE7F526170971FA11C0BF2F203FBEA060059FA602D4AF3F936E92BFDD6B49E5DD2F7FB3C464764D68A707D839ED3B6CCEC4E35A69CAD1E717DF8ECA0465357DBE241FD92E5C6FF36B2E94F45CB1EAE6441AEE120701EB9625B8962995DCEF218BEEAC80A8E85F9DAB1094F5E8CCFAABD497A2F18EDB448BF5F01615D92E1C07B0FD7AC22A6FF60FBB0EAADD6D7075533F37A30D7616637AB7EA091D771C7480ADD9D9F508BF476E047AA8FDD93A4FBCC2C2CD0D692DA00C05F62367CA8F823AF8F044A2C162811BA0FB6D5C0A8F9BFCD9400BE21572BC0E76649BBB778FD4C8D23E24D9AC9C80BDCFAD067A83175AF5F5FDC99C1FB59259D41642126602349E1F2BFA87DDD829E01E6067691334B862587FF6B6685C91E211CABC6D4CF5D80E82000B742D8270AD76AF873871AAFFBC67E85D16C26F67B354E8E3A5E232527F656638CD63C1A19590117B4D8D6D302543DB2AFE24B72F7CBF16AFC1EEE0B34ACB19259A86255097B5B121C38C95B51E8B260DB2DDEB6376BA34DDCF2949753CFEFBCFD46038F65ED3380355BC8BF9046B6EB40EFDB23FB3595D3E658E16A506FE356FFAABD1E055EA17119C61A61C640B7F2470177478E3B05B809382FBB4EF737D1E1D23EE5B73AFFA769BE34F34BB875CAFBA283EBDFEA15D68EC8437EA9ABA1653A9CD1E41A3F977DF627E05681FC37F1659901C2225A9DCA1EB1AB01E27E532113704BB19E063C14D93E0D3719C84B874E57E3DC82F8EFBF5DC64CB7F23BFDFDE532236E77FEB8FBE3B8C8798F253095D3781FED6535C056ABC1EE10D1A3464FAB0166C78DAD080AF00C702970318D2B52D6E83DFE0AD8CD3BD023C1B67059DE17810B1878B8FBBC0CFC0CD811B8C76B6FFA7002E6012606C79940076BBC0307447438B5DD7E4D8ED56A39C876FCAD1799111D5622FE256FC763F478E3EFF3FC9F21A748F01EE5D7E83B1D2722BF8A01C0DCC07FFBB80E57D3DE6FD84CF6481E007C1BF740EF86E373D6A19B07D0DF23FABC4A1F315011F99D7263AF32DBC86F387FE0D488FC5322FD0A1D0064FD6F68723DFA19008C066EEDE6E2673C423FF16FC02ADEC166E0559A02E604FED744F04CE0309ACF0EC18DAE9B160002768FEC7371B3FEC1BE4BD0F8C37D19B7AC71B7D7A0971FC034E0447ABCE936D163459A5FEF18B7024BB53F725BB9DD9CFF34E06FB8658C73A14BF921C3620090E93127702ECD2D4D3126D1C455D085DC113B00C8E4FF94D6F7B11A3381DCB38DBAB9FEC0A2B8077EC865CDF6E9417EA7DCD8ABCC36F26303807522F21BB220286700B022F1EF4BCF0380ECB873E3AC7D9DFE"
|
||||
"FE6F00FA4F19071EF70E7A5CB06D395C74ACCF4BC08ED9F6AD70E6F1BA8B0E5C449B9929CEBC1DB25D177AC7DC005DAF9445673F8029B81FDE1DC071401E75E063BACC81B36E3C4CFC8B3015B80BD8959C061F6DCE7F0ACE3271277034105BBDAE48F9ED183603004F9FF5812B81379A9CF34C9C05E62FE41004D6CBF9338C0600990E9FC7DDB326457499861B6CE795FA15CAEEF601F49326DF8B9E56098CC8EF941B7B3AE1F6F29BB940FCC951B41017250C00B27DFE18B91E7D0D00BC636F0C5C4F7C903115F75DDCAE5F39EFA5FF01076B20B0EC6D496B99595D900BCEDCBBA4DC8A54D7050B06CD29B758C347E52A02DE686655AF6836E4C1CDEE9791CBF77F57D22B926E49297723039C35EB0B72E9B4A3E502765F91F4404E2B1126027083EA35E5822C67978BF6FFAF991511FC954834059749B78ADCEFFF7D72B574EE36B3A635757A15B410F566A57BC9C3B49048241289446270036C47BDC9F96146C6CA5389442291488C6C70BE6D9F29B8D4A30D5AECB33A704CAB3E8944229148240639C0FEC4D3625EC545F5FF1B177D780FF09AB7FDE8AA754F2412894422D107C07AB8C8DC6ED2913A4ADF4B2412894422512DE18A4A0D00EBC8D5E9FF82A44F4AFAA006CAE04E935B02F60149FF34B3130AD233914824128944D56419037D559E4B241289442291482412894422914824128944229148241289442291482412894422914824128944229148241289442291482412894422D140DB424089442291280E6031493F6FB2F911333BA64C7DCA0438506E09F990E966B64BC9EA2412894422511EC0AA2DCAAB5F53B57E45023CD6E4BCDFAD5AB791C02C552B904824128944A27C86CC0000180D8CAE5A8F2AC8CE7D81AAF548241289C4F061D6DA3FC09D9246B5E88BA42992264A7A4CD275667659518A018B48DA45D2BA9296903477D63E49D29392AE9774BC998DC9495EBBF39F29E96D49E3253D2CE93233BB2D0FD9115D5691B4BDA455E4CE7DCEAC7D9AA4E725DD23E9AF6676750EB27E20779DF3604733BBBD071DD69414FA392F35B3035AECB3A7A4AD83E603CDEC922E659F27E9FF05CDA799D9511DECBBBFA44D83E6FBCC6CBB2EE4FF50D28F83E643CCEC6F91BE0B48FAA7EA07EEDF36B3C7227DBF22E9B741F34966767CD0EFEB927E13F49B29E9FB66765F0BBD2F94FB6EFAFCDBCC766BB64F17C739CACC4E6BB3DF619236089AAF32B37DBA919F1DEB2AC5FDD0DDB0B799E569AE3FD4CC7E91E3F1A2642E868F784D8F99D9B78B965BC3CC96CAF43847D277CA92DB0AE0EF9216CFDE3E67661B55A94F2900EF76B1EC6F8D0780AF15A0CB7EC0F80EE44F00F6CB4966B7E73F13B809F87C1EF2331DE6064E07A675A8C3A5C0427DCADCAFCBF36EC5BA3DEAF0F5C8B14E6DB3CF11917DB6EF41F69191E3DCD4E1BE0F45F63DA8"
|
||||
"4BF91B468E717493BE5B47FAFEA449DF43237D3769D2F7EE48DF4B5BE8BC55A4FF5460D56ECE3D3BD64F23C7BAB7CD3E0B0213837DA6F5223F3BDE73111DBA65F35E6467F2633100E1E0AD1080D302B93380CF96213BD0E39C408F4A620080B570F7769FF5ABD0A50CFA75012C27E9EFC0AE79282349C049920E96344F07DD3F24E960E094BCE47781495A5DD2B540380BEC1A604E49D748DA469E65A60D1B49BA92E41EE88733E5AC5B3E2B01F3B6DA095846D23241F37449677429FF06499383B6A59BF48D3DE0FEAF49DF50B7A97256B318FB4A9A11B47D0D58AF49FFD8CCF42C33BBB549FF561C2BE989A06D059A0C56327E2AB72CB9CFE53DCACF8BF03B345408EF9DB348FA41158A0C1276546376DC0FAB50A40CF28801984DD2E13893635F00BF51FCCB3753D2384963B3FF43BE071CD2AFFC1E994BD209F4BF3CF2E19262D684D725DD27E92E492F47B67F465274C698688F99DD2BE981A0790E499BB5D9F59B6ABC51DC6E664F76297F8AA44782E6A59A74FF5CA4ADD96C2D3CC6E36636B1890ED748FA7BD03C8BA406170CCEF5120E505E91F4CB267AB4C4CCA6498AB95BA2938A6CA01CBA7EDE55A31BA34C9E941BBC0F39CCEC3F92EE0F9A37AE4297AA01E697F4D5C8A60DE9D3D23A58693500B84FD2C783D70A723FCC3141DFD9D5E70F10584DD25E914DE74B5ACECC1634B38FC9591DCE8FF4DB1358A31F1D02C2F35F42EE87F157B91B8ECF7C92F6E855507653DB326C967498A445CCECB366B6B2997D54D23E72334D9F6F01CD668DED38468D9F73ED15B3AC6CD5A2FF7F7AD4A16AFE11696B67F68BB93B2EEF517E78035E38B4EA00A3247D3AB2EF92A1B522FB3E2D16F47BB08D0EFB487A23685B0D78EF7B09CCADF8F7FC0F6636B6CDF19B62667F52E32068CD26BFE75D258516AF8BB2815CAFACA2E6DFE9F0FEF74AB0EF3449BB341B5C0D112E0CDE2F046C558926D5F22365B16672F16EEF64FFCF2969A74A342A0B1A7DE077B7E8BB143029E2B75AB90FF917468ED7D40F0C9C12E97F711FF2BB39FF0323B2EFEC43F6EA91E3DDD0A27FECDC730F1802FE1291D3CA34DBAB9CCA6200B2632D4563DC4578A3F7FBCF03BC13F49F0C2CD8A3FC9D22E7B259D0E7CB913E35BE13F4DD20D2A7ED0015F87564BF87BDEDBF8B6CEFE7C1EBCBFE7EE4D81745FA3D11F4998C73C7140E705944C7BEAD6F54180390C95F10783B907F6559F2331D2A8F01001EF5CF1F1763552374530D0B7A72016451C7A1C95092D6E9E578B8D94E687A7945CED7D78C3DD568122FCB5473881AFDB6FD4411C7E21D9E69D1FF1AB911AAFFEA378A79C4927D9FEF0A9AE7C745C8C7D84CD2FB83B69BFA9805FF4B8D3EE4D0B4BF668BFDBF10BC5F29D2A7E980D2E360B90C1F9F6570817A0BABD1173A53F17880AE31B353E4AC6E3E5FF11FEEB88C953063"
|
||||
"E002330BAD07B903EC2C29FC3E3CA0E615FC860CD9F7F65F41F33AB84CAC1101B0B1EAB381CE967496F77E098241F970A09F188087236D1F89B475C206727E579FABCC6C42B31DB26D5705CDB34B6A16B8941B99DFF2D5A079B63E0E197BD8AF8F2B111A937F9E99BD3F78E516883942B922D2D62CC325E61E681A35DF8E2C6EE085A03934F7AF18BCF7070C616C40B8EF2BAD52FA3C3DA649DA5F8D83913D140FCCBDD8CCFED9EEB85D7058F07E76B9817E8DD00CFBB64AF0FD67839050CE64493FCE623886036705EF6797B443158A54846F3D7CD1CCCECE52719FF5DABF57B24E85D3CF00205694279C1577CA2A91B64EF2C96351BFB163E50A30871AFD904D072BED30B387D438F35A48D22DC05E389F6EA258CE948B94F7F96293BEA16F7A921A6FA0DD12FAE8C320BEE5BDFF5F527DE4FCB2B818811A615D83873A55C2CC2E50E3C07A6149DB066D6FCAC50DE486999DA7C6DFFDB73213F5466A1C049DDD6DD0658F9CA0C6C1CF1FCCEC9612649742F6B01B1334F79DDD3414C8265AFEA0FED226FFAF0B2C598E56E5D0CF00202CC221B968D85E88A5B17562D68B5921CA4889FB8DDC08D9278C24EF96C3D538F35A306B7F36F3918D881F641598D9736A1C502E09F80FDE5A819DD0D275430E4160F704EF17C305DD099797BD40D0D7EFFF41496B79EF433379DBD97FC0BE6A3F983FBEA087EFA1C1FB0FCAB902430BD74439575CA1E016AB593D68BED5CCF62F5A76058445B4966118E7C07BFC5803F7F3997281DE35FEAA8114D9D9E40205870D5D0F00808581D3D5E8677C4BBD9B41C39C5E497AAD83FD5E8FB4E5552E78B62C38A7F65A13D81E57252A8C4D9829E9E47E84653ED003D418E12FB92C83EFC8D55C781117003762FC73251256B634B9743F9F5855B0583C4CB784B3C9D924AD96FDFFA560DBED6A1CACAC29BD574572EE605B57152BCDEC7E4927B6E8F2A4A4AE0A1E7521FB52496121A6EF4B5A3B683B231BB41506AEB0D0DE41F344B95CF1E1C8496ABCFF6C57811E65E31771BAC3CF2831B30755FFFBD92CB0B60D695A159C591A0847F8B3CB059BC5F63BA595CFBE0D614095D4993B615287C7EA856525FDB7C3BE7FCCA32CAF99FD06B8596E16D4CC95F131B901C8F78023CCACAAFA07C391B3E47CDDBECB651D39BF788DD02DF09AA40B72907DA35CDA912F7B4539737C985D739DDCE0170DD422A899C7C3EFCD3435067875C221723EF7D0D225B952C945FABE7F2BE94A0D9CDB8783ED1354F0EC3F73F3FD458DF79383B287C2B0C3CC1E01FEABFA80D30D81D1433CCDB1299975ED010D5870CF8B743B5EF52EDE1524F59CF53528A1B752C0356EE8C74F0D5C1F3966DBBC7660F1C87E1D95718D1CAB97F39F82AB499E3BC00EC02DB8D29CADB8948246A48C9034C0E0B857463EE3F9B36DCBD35826F4DC7E657AB2EF8C"
|
||||
"1D1B78DC6B7BD9EBFFB4D7FE62D67662708C989BAC135D0E8B5CDF1A8F50F02C08B8B685FCC38B949DC93F3622B7EF417E135995A60106BAFC28A2CBEE25C8AD3C0D7024D26F25C0E9723E928DCCEC9D769D5B109BC97FA883FDE68BB4F5A347374C93B4AE9915920664662799D96A7233BA13243533776E2437424DE443E8C69A5D035501375563F5BF3C66FF35C282404BE1D2EF16F7DA7C7FBE1F07F03160393556E9EB3A360537F80E1728F2595A39A5FFB5E010C5AB7EBEAAC66C815CC1AD6F12661CBCA6D6D764B870BA1ADDAFA52D0E942897560300E41E72B5D7BB727EFEB1723E9163257DCECC7630B3D803BC1B62BEFC4EA22D3F15691BD7A72E3526C8D54EAFBD4277C828B5AF16D73766769799ED64669F90F45D49B1C22BDB5252319411C039727E5E9FDAE71C56FF7BD1CC7A2E3E1521342B7E4A2ED8D6FF9DDEE1FD1F46CCAFA7C6DF4458DFA0130E932B71DD8ADD6992A69A076676A3E2E5754F36B3D8FD22177055158F51BD9B1349FB98D95345C91D2C6413B9B032E6FF51C1024189E2693500B8D7CC66F35EB39BD9DC66F631335BD5CC76CDD11716CE7CA478319390302D48EA2C7BA0139E31B3756B2FB9457AC200991FD166D1984E00D6C1557AABBDA2258DCDEC1C398B40E8E6984D52EEA6F91209D3EF24E97D6DF6896DEFDB2F9D0D66C3457356C315AB0ABF9361BA5CBF5CA7FA4C90B9D41884E817F4091F905F526316CCBFBB5100E7E209EB1FBCA646CBC88724FDAE9B63F7C0B391B6A2D3FE8E556319E5BF9B595F41BE438CB440D008218FC580F2E01A35A6C07DB983FDC23E28FF9BB224295B692C1C19CF2F298FE588CF925BE7BDF66AEA57CE8AB5C46E468BE6A04755BC14696B57542A96EE9997F5278CEA9F4FF1D4CFDCFCFFD27B05819E0F9A7DABC30433BBDEEB7FBFEA0B0885168AD7CCAC630B40E6D73F448D6E8EE3E42ADEBD1DB47F1388A5030F4980AD256D11343F2F69970AD4A98CB440D0C861500C00CCEC5135A6352D418BFAF6B8DAE661C193BBB29B62511C22E70EF1F93EFDA7E48555E03E06C4AC1B35C21BB434749723955C11A4D0ECBE32104DE9CC1E54AB05CD53D57F2D861A17A8B1D2E336C1FB27CDECBA9CE4F9845635BFC264ECBBEDBB84C26A941D1700CAD84F8D3104CF483A2C2B971C0666BE4F8D79FB4312605149BF57FD6F6B86A49F9A596C15CEE14E5A20680430280600197F8AB4ED4F641113E0876A4C03422E7DA830CCEC4E35E68A8F96F4AB3E0F7D63284A6E89E1864C08601EC56724ADD60E18D464568D7000F86149679215C3A9913DFC4F965B9DCDE75E330B1FDAFDE813A6CE85B3FF3C4BE0FA8405817CEE88B4B5AA98D97101A0CC9FBF5B64D3615ECADF416A1C187D1688ADE239D4F8B31AAD4AA79B59F8201C299CACC680EA70C5D2C470812E56C32B5087D88A80"
|
||||
"004FE2D2DD2E01FED7A44FAF4BB1D6647774FEC00AC0D4A0EF3BB1877517B21706C645CE690A2E1DEA445CDADB39C0CB917E932920208B92D2003359EB134F791C87FB5EFC813F094000002000494441540538171813E903B0797B295DE9F38D2672C0A502F6BCF2651BB9B195FC6A6C18E9BF4A8BFE1D476F031744F66F701F00BF8AF47B851E57426CA353ECFBD777AA6744CE1E4DAEDFE3B894C74E5E3DBB0219446980815E97063A4DA6A00264A434C06A61700C00E6A53117BA13EE24CBD5EE437637CB019F1BD1A12F7F302EF86F7C0FE70EC5D522286D0090C93BAAC7F32F24400B78A189BCC2DC4CC028E0AD88CC3769927B4F7CF0388D0E0354810D81E9C1FE3389AC8608CC811B90879CD6E7A9C7F42A6B00F074444EB71CD787FCC13A00D82CA257218B2F9106009530985C00CAD27BBE246766EFD4A73D5DD29E79997F3BE4103546AE7F933E66856676955CA04D377EDBE9928E2EAA1641D998D9EE7291E5B1AC8018D3251D6B66B93F14329A059416B6567AE67E8865B23C906D8B1133F53FD145BADCA16ACCAAB8C6CC1AAC6A993B205688674B9A64AF0C015A55441DB18CE40582460A836A0020496636D1CC3696ABCFFC6FB52F093CABA44B80EF16AE5C46B67ADFDF82E651927ED9E7716F32B3E524ED2CE93F6A8CBAAE31516E90B441F6D01C3698D9BE7275DF2F9034BE49B789922E96B45EC1CB20C7AC3A33249D51A04C291EECD72A9A3F1607D0518A2EF073D5AF3428B99A1F0734DBC7CC4E8CE8334AF181416268335217081A11C4A2C907153833E6FFC9D5C09F45D21B72CB90866BA0CF9074A499858B770C597001702BCB9DFB07E52A263E99A5248E0880D5E4F2B26BE7FF6C96A694480C0B708B0E85EB8E1C6A6645575B6C0BAEC0D8FDAAB7929C6B66B9060402E7C82D7856639A9985592DC30E60867A9B886F6B66454F440627C09CC0794D7C713FAC5ABF442291E89426310027E3E2823A298856B47ED7E202006BAF97E863ED97E0D86B64E719AEC13122620068BFD64B33C2B4E49107B01F0311F9D381A666CB442291188C341900D48895431E36008F3539EF340028610030A4835FCCEC10E01149474BFAAD99FDA56A9D1289442291E89033D59B0BE0E9BC1519B250F0D2A48944225114C90230722D005533A42D00355AA447251289C460E769355F6FA0D932E0C3855F4B9A27D23EA36C45128944229148241289442291482412894422914824128944229148241289442291482412894422914824128944229148241289442291482412894422914824128944229148241289442291482472C6AA56209118AC006B4BFA94A4D924BD28E93F66F67AB55A25861BD962667304CD53D21A2789C201460377042B31BD03AC5CB56E65016C1F598D6AFBAAF51A6C8C94EB041C0C8C8B9CEBF155EB5604C07E91735D"
|
||||
"B7641D96054E04FE06EC5CA6EC4CFE4AC029C0F9C07625CBDEA6CADF15307744FEA965C94F54C7AC663611D854D2759296CCDADF2FE91849AB56A659225101C0A592366AB2796699BA8C148005255D2BE9A359D3B780F9CCECD725C95F42D2351A58956E73602E333BAE0CF9894455CC224966F682A46F491AEB6DFB3CB077255A25121500ECA1E60F7F292D515A14EB68E0E15FE3CB25CAFFB21A97A4FD6A89F213894A98B5F68F993D086C29E91249A3B3E67D808BCCECC94AB44B24CAE53B91B63B255D2F69AAA4FBCA5567C4304612AA8F497AA964F9212F96283F91A88459FC376676A3A41F487A5AEE473151D26EA56B954854C3A783F78F485ACDCCF631B303CCECE22A941AEE98D92D920E95F4A69C95E52E49BF2A51FE15722ECFB7244D9774B3A483CA929F4854C5AC6183995D28E9C20A7449242A03985BD29C41F35D2912BB1CCC6C3F49FB01739AD93B15C8DF4DD26E55C94F24AAA06100305800464B5A5ED287254D92F488998D6DBD57217A8C92F47F92E695F4A299DD5DA2DC65252D24E95D494F98D93365C8CEE42F2F691149E325DD51C583105852D2627296AAE7CDECA102C585695892BBEE95002C266929B9C0C387CDAC329334B08CA4C5E566C8B717F980ACFAE15BB5FC4423DE6F6186A48762CF81EC7EF919B9FBE50449B7E575CF0216970B909F29E93E337B398FE376207769499F90738D157DFF1B1C003F01EE02DE0DD252A6030F007B15203396DEF603E030E0D5A07D2C701410CE16F3D26525E052607C207726F018F0ABECCB5E08C0FEC09840F6ABC0A14DAE53AEE94AC03CC011C0D311592FE252C516CA51DE89D9B50EAF37C0646FDBC379C96CA3CF36C0FDD9E75DE35DE0066055E02C4FA7F1C08939C88CA601669FF7FF82F6B771A9728BE471BE99FC3983731A0F1C9BD7F18780FCB66980C062C0A3113DFF9083FC4AD30081EF46CE6B34B025705FF05B98065C8B7B38D6743F1E7839D07F02F0273AB84F03BB06B29FCDDAB726FE5BBC1658A1A06BB1307012F07CE4331987FBFD2FD9FE48430C605EE0FAC849C7B809983747D9B107DB136D74B8999C0701C04EC0940ECEFF765CEA54AE0097B591FB78A42DB70100B022F1077FC80BC02A39C93CA703790085CFC0813F527FB3099910B93EE7E420373600B8B0CDF5788A9C066254FF00AA5A7ECB0140A6DF9D913ED792C36460109C7FECFEFB575AFF169E039600EE6DD107E0860EE4FF3CD867266E12D28A57816573BE0E5FA671C219E34D608B3C64CED2BE4B699C2B69ED0EFBAE2EE92F05EA22494BB4D9BE9AA423F212067C432E1069F60EBAFF9FA4BE6FFC81FCC3247DBD4DB74FE5293390BF88A4CBE44CFEED5848D205C0FC45E95336C08F25EDAED6D5393FA4CEAE4F1E7CB3CDF64F4AFA6D198A2474A6A49582B607246D318C6354B657EBDFC2"
|
||||
"C725DD21A9DD4C7C2DBA2F2C65927EDAA6CF7C920EEEF2B84DC115DE3B3F3B6E3BE696741AB041BF7207450C00B089A4F582E6FB241D25579B6065497B69203D5192360196283845F12549FF928B41585E6EE0E1B32D7044BF3AE046F1BF97E48FE6914B3F7B44D2FC92BE22E983DEF6B580ADCDECCC7E6467F21791F4E3C8A67B24DD26692E49EBCA3D788BE258491F0BDAC648BA51CEF7B7AAA465BC6D8B48FA8DA49DFA947B91A427E57E0BFB06DBFE2B57204B7211EA8580B324ED1FD9F4BCDCF76FAADC8DEEF345E9D0848724DD2A3751F882A4A583ED5F2B599F11077094A48D83E617246D3602CA523F25A936835F432E0EC0A756BBE151B9CC8D5172F7A98F07FDBE21A9972A9E4FC8DD7F246915B918039F3CAB65FE59F5F777C99DD7BFE5EE7FABCB3D836ACC2EE9386099213F08048E8B98395608FAFC32D267979CE4C74C507787334CE0CF917EBFC941FE0F22C73D3CE8B30AF056D02797B4349CDF3FE4C2A0CFFCD93509E9DB05808B7B98161CF71EFFFA037300D7047D5E0362C17BBDE8307FE4DC4ECAE3D81DC8DE3922FB1E0237177060A45F512E803322FD6E8AF45B3107F9559BA0AB961F7501E07CD3A119FC0D608D9CE5577DFEB1FBEF0D782E566014CE1F1F72359E1B04F73B1E1BF479AE8DFCD005007039C1BD05E77209E9BB5A2EB059E4B8D710B87788BBE5FA2A9B3D585C007F92F425EFB5AE99854557FE13D96F8102753AC1CC5E0DDA0E91148EB6BE9083AC7026354D817BC1CC6E977479D02FAF6090F0868202F356762D4EC8495EC8966AB446EDE75F7F339B22972BEE33AF5C15B9A14EEC1C7E13CEF0CCEC4095578EF8F448DB9591B670B695C887A5251DA67A33F8BB927634B39BAA51A954CEF23332B2596EEC1970B03F03CEEE19F7047D3ED483FCE3B37B8ECFBF22FDF288C5FA56A4EDA0C8CCFE1772752A7C42EB50570C0A1780993D2267EA96F4DE686F75B9D4A30FCAADC61696EA54D65E140D655FCDEC05E021499FF59A17CF4156184CF26893549353E5CC5235DEC841B6D4E8DB7F3C3200938A2B85FBB9E0FD6B92C69045FA7ABC2CF703F0BFB79F55FCC13494F87FC1FBE70769D1A1F191B6B94BD76264B0AB1A5D82BF30B3F32BD267303029D23639D2F656F0BE93B8AA4E88DD6F3F90C371C3388627CDECE6B093993D0EDCA57A5760E896E88A413100A801AC25E96792BE28E7771E8C8C0BDEF732BA0C09033F5E897532B36BE4162DC99BF01CCAAEB7105A72E69337206C436ED92015F2E1E0FDF39568D11B6949F16208A3FB276B201E25D11D457E47F3387618CCDC2AE3E839D50F00FABAFF0D161780807DE55604FBAA06EFC35F6A0C06CBC3071D1EA3B080B30EE54F28597E3F9FF7FB73D3A23AC27318EEC15D89EE9953CE559A187E84E9E4314B5B8D89C1FB59819E5DE183C202007C5D2E"
|
||||
"A2FB7D5EF33B7211DAFF9333BD7C5883A33E77F8B00CFD44BD3045F566AA5C02DBBAE0DD407E21458E5A10FAB5BA6138CC40A706EF47477B25463AAB02FB9BD960B80F26F223BCFFB79A1085AEF019FD54261C140300493BABFEE13F59D2D7CCECBD220EC04A1A1C038070B495C76C7D82EA6FFA9DE482E6C944D5FB723F52B2FC099216F5DE8F5563CA4F33F2188055CD04D55FF3DC8B3C25862457C8997BFDFBC1DEC095667657453A25F2E775D5DFFF5BCDE8C365B3FBB2D60E161740B80ADB9DFEC37FB090A5A584816979D4E70FFDDDCBE216A709E51F82AB80557BE5150D1CD6315816577F3BA4A8D9F603C1FB05256D606693622FB911F294ECFDD0CE81753C16BC5F0258B3124D128385CB246DAAC649CF07945C01C38D0783F79F06960B3B010BCBD5C4F1E96B7D80C13200084DDE31BFEE97CA50C463EB300F54D21E6A34CFDE9183ACAB83F773CA5945DE039713BE855CDA55ED95574A5818713A4AD2CF03F9734BDA2E277921B1D5278F6CF223585E2E56A4B43CE5120807BB26A961CD07604F0D9EDF6CA2582E33B3696676AC068AD1D458991CEA8F24060D5704EFDF2797F217B2AF1A331AAEEA47F0607101BCA07A33D7CAC0C9922E911BF16E2C69F3C87EEF8BB4E5C51725DD035C2967225F4ED226419FE992CECA41D65FE51EB87E25BC83B287DD4372F10F9BAADE4C2E49FFC841B6249D22694FD50FBC76CCAC00B7CBA5627E4505950236B32B80FF48F267BD1F97742B7099DC0CF97D72292F5F92FB4E7C1A78C5CCDA95EC1C0A9C2CF783F7A381BF24E92EE02AB9EFD9CA2A7F109C181CEC2A5795D2F70DEF095C91D507490C61CCECAFC0CF54EFF6DC02F8B85CE6C774B95A2D61B5DC97D4A73568B00C00FEA6C65CC8EF67AF56141D2CB5B41A4DFE3E179AD9FDFD0A31B377805FC8CD6A6B66F6517233FE66DC2FE98FFDCACEE43F83AB7AB76BB069FDEC55063BC995BDF41F821F90F49D16FB6C0C1C90B905862C663609F8AD1A3FCFCFA8CF3CDFC4D0C7CC1E048E907480D7FC7E49C703AB0E1337D84867374997AA7E86BF5AF68A3143D2CFFABDF70D1673E2EF25FDB34D9FD7D458E0A1DD823DBD325D8D66F19047D4F8C0EC19333B5DD281EACCACFF90A46FE6FCC3FFB91A4D8D2137AAA0624066F6A89C85A565D94E8F07246D3AD41FFE35CCEC28394B502B5E932B08931861645520EF0D9A57D4E0088C4EF489995D2DE98772D96FED9826694F333BB75FB9836200903DC8369674B81A73A067CA9580DC506E611A9F55FAC9816CC16B923692338D8795A6264B3A4FD29722A582FB224BEFD958CEDC177BB88F932B11BC8A993D95B3EC297235188E5363AEE93B924E92BB26AFE52937D0E116B955CF8E96730BC57852AE24F32A79585F061366B6835C21ACF0DC911B906E14D9AD9F14CAC4D0623735A68CEE06349B"
|
||||
"252686106676869C1BF432354E7625F7ECB956AE54FED1B9C8CCE320799205DEAD2DE913720F9EDBCD2C8C922E539FF9337D3E2C57A1EFA6BC1FFC4DE42E24E7F75D40EE26FF785935C0B380BFB5E562122648BABE8C738EE8B1A2DC7A071F92F4AA5C89CC5889E26107B0B65C99E9E992EE32B3878075D4580DEE1833DBAD74058711D9F73D4CE73DD5CCDAB920138942C832CEBE28770F9E456EF277B399955DA42D91489401F07960BF16DBCF8EAC06B643993A0E4780E523D7B597E5631389442291E80EDC92AC0FE1967FBD2C9BEDD7B62DF6FFDBBBF3205BAAF200E0DF4150A04424687025A8892B46346E880B89B108042441895B0296808A91A891481435115C826B702B154A408C5882286A447141232A22228A821B82282285B288B2C8F2E58FEE81BEE7F6CC7B33D3F7DE796F7EBFAAA9F77A99FE4EDFB9F776F7E9EF7C9D994766E64DD541EAAAAC1E19CCE264F398E90FF79C00F40DC302806165E6513D07A1AB33F3F29EF9735E3FEB76AFAB32F37D997965665EDBF3BADE94CDED2758AFAD946180B0DA5D184DC26B373177A19AE01F2EA5B84A5DBA12F30F23FE5429E55BD36C0C00AB58663E3333CF5EE08A3FB32901FDE259B7755D979947CCF3FA7E3D2733B208569C15370A0056BB6C9E03B07334A300368F6648D0C511F1D5883851E197E5CBCC03A2296D7D87689E86F9B368AEFCD5D907000000000000000000000000000000000000000080F55F666E94990766E61999F9C259B7679232F38B99F991CCDC61D66D018099C9CC4764E6B99D07147D61D66D9A94CCFC8BCCBCB9DDCF1B32F3DD99B9D1ACDB0500539599F7CDCC4BAA2714FE780A719FDA3E89F2ECCC7CD9A4E375E2EEDB1EF8BBDE37ADF8404464E69699F980EA67D359B70B5693CC3CA13A187E2533B79842DCE775621E3EE97855EC5D32F3BA4EFC9B32F32FA7D90658D532F3E09E67A33F71D6ED82D52233EFDE73207CF09462CFEC04A08D7F74F5DDF3E169B76135DA60D60D00202222768988DB75A67F5C4A3967568D99B2CF54D38F9E492B56192700002BC39F56D317CFA415B3F1836AFAEE3369C52AB3E19A56C82623F39111F14711F18B52CAB727DEAA26EE432262EB88B82222CE2CA55C378DB83DEDD822221E11112522BE524AB9664A71EF1711F78A88DB46C46511F1ED59BD06C054D4393757CFA415B3714935BD61666E594AF9CD4C5AB39A64E6B332F3F2CECF6599B96966BEB9FD7FD7C5997958666E3C81766C94998764E64555CCCB33F31D99B959667EBD6AEBB306885BEFFFE5D924C51D96995775DAB1FF10FBB9403BB6CCCCB7F7EC7F66E63599796A66EE3970CCEFB6FBFBBB9E9857765F8F21E3566DF8D79ED7FFF13DEBEDDDB3DED39719FBA3D5F67E9399F7E9596FA3CCBCA05AF7ABCB89DD6EF775D536C732BE33F31ED97C0EE7"
|
||||
"D6796BCF3A8756DBF9C95AC6DFB9DDE7EEEF7EAC67BD7FE879ED8F59DA5E8F6CB7FE3CFF3A33EFD5B3DEC6EDE7A2BBEEF7971BBFDDF6B13DFBB6A69F5F0E11BB6AC73BABCFDFC7878EB140EC59E700DCB9E7FBE7CED36EC76A33D703B07144D499A69F8B88C7F4FCCEDD22E26511F1C8CCDC79A8ABD26C7A1A3E19113BF52CDE22225E18110F8E886D23E2F69D65439C88F4EDFF9B23E2D9D5BC9B0688D52B33B78D888F47C4D8C1A7B54944EC18114FC8CC2795529E3B50E83BC6F8BECFD9BCF3FF49DE2EDAA4A70D7D6381FBFE4EB75D66ECD322628F6ADEEE11511F64778A886DAA79672C337644C49931BA4F5B64E6B6A594EF75E6ED111177EA4CFF75CF761E516D67AD7AEA4A292767E63763F473B77B66EE5A4AF95467DE7F54DBFF7D441CB63631D6E0F418BFDFBB6744BCB19AF7F71171CF6ADE2707881F11B159CCFF19988FDE38D6790B7DA9F71DFCBB768CE62039943745FFC1BFEB09317AF09FA4BD7BE64DE404A03DF9392EE63FF8779588D82F335F3389B6AC421F8C886BAB794FE859AF7E6F66447C6880F89F8DE660DA55F77EFC5535FDA09E5E8A0756D35F5F441B5E1EA3AF4189E6801F1111997950CFF6DF5B4A39771131E6F3C1685ECBAEBED1277FD3336F9699E2374C609BF549EF2462AC54D7C5F8FB60935934643559D355DD8511717444BC3B22CEEA59FE9CCCAC135716ADEDF2EBBBA23D3322DE19114746C45A75690EA8F4CCBB7142B1F689A667A3EBC888B85F343D2EFB47C455D5F27FCE616EC31C1E118746C4A77A96BDB75D76688C1FA4D60BA594CBA2E905E87A54CFAAF509F1B9A5946F0E10FF9A88F84E35FBA1D5747D85BC41443C656E2233B78E887B54EB7C7E116DF87644BCBF9AFDF0CCDCAFED867D49B5ECA288F8CFB5DDFE1A627F2BC6F7FFD1395E83A23E29BAB09472F2106D88E6BBE5AC057E6EEEF99DB1DB3003B84B357DE90462AC48A594AB63FC3BEEFEB368CBAA9399FBF4DC7FF972666E56AD777CCF7AAF1B20FE213DDB3DBE5A67D3CCFC7CCF7AFB0C10BF6FFF3333BF94992FCEA64AD6B3B349CC1B5C8E8F81BDA0679DB7F4B4AFBE325C4E1B665607606D63E7E87DCA397B0D10FF5F167A6D33F3AE99F9876AF960BD5F3D7FDBD33BCB9ED4D3B6CCCC4F77D6D9AB5A76D912DAB06536F93D5DE767E67B7A62EF37D4BEB7B15FDB13E3999DE58FEE59FEEE21DBB040DBDEBAD06B3F609CADB3C9B9E95A567ECB22E3CF3407A06DC317ABFD3F76066D383033CFCA262FE69799794A66EE36CFBA0FCFCCD7777E265EB06922B2FF00387660CDCC6D33F3C66ABD2F0E10FF0BD5366FC8CCFB2EB59D4B88DFB7DDA9752F66E607AAD8BFCDAA00483625429F59FD6C3D601B56F309C09699F9FB6ABB6FEA2C7F7EB5ECE6CCACAFD297137FD76AFB577696BDAD679F339B44B48DDA750EAF967D7689"
|
||||
"ED38A027CECDD574DD5BB26CD9BCB7EB72B01FE82C3FACA75D8F1DBA1D3DED7A5A4FBB2EC8CCBB0E18E37ED924825E50C5F9DE9A7F7B38B9324E00F6CCD1E3CBCD997952663E6F4AF14FEC799F65360599C64E3833F335D57A9BF56D77255B5462579B9854BF31D7E6BEF59AFC5935FD8352CA8F06D8EE727C6E8AB1EA84ADCD22E2CB99794C363D0F5B95527E544AF950F573D114DBB8DE6A871AFD5F35BB7B80D9B15A76CEC0C3613F1B11BFED4C6F9E99DBB7FF7F5C677EB74B788B88D8B5FD7F5D2D6E31F7FF6F514A794744D4B735BAB7C26E88265F6050ED67BD8EDBDDEF1DAB65E79552063F11E9CAA6B7EF1D313A54FABA88786E29A51EB2B61C8F8A8857C46882E985D19F83B45E2BA51C1FCDADA5EBE76645C49323E2DF261D3B330F8E26D1B4CF0611B17F667E66EEE42F9B5B63CFE8AC73697B1B639DB294CCEEFACDBF79EF5A8B73876AFAE7036C735DF2DE88A887346D11117B45C45111F1F3CCFC5666BE293315C8988C3AA37CBBBCB54B6FFB6A595DB56C594A293744C4D9D5EC1DDABFF59F77E6BD27464F14766EFFADEF952EE7E4F5E0983FD9F5B852CA5796B1ED857CA29ADE2633E75E83EDAA658377C17765D3B3724C44D4C3D00E2DA54CFAC2E0C68878659B1BB11ABD39C6DF0BD350F7325C1EE3C7A19D22E2BBD9DC023A33462F5C87181134754B3901F85D353DD430BCAEA914DB5929DA44B05DA249C4EB4B38DA28221E16110746C4F773C0FBCFDCE27F62F4BDBD7134C3E11E1E4D41AA394365FFD74EAFA6B78BE68A642E333C23E223317A75FFD86C6E9575BBA42F2DA52CB93E417B803B7F9EC5C7CF337F08C7C6F8D0BADDA34976EC0EF5CC68460E4CD2DB633C11F413A594D74F2056FD79DF30228EC9CC174C20D68AD69E789D1CCD30D09145138EBB438C0E313D2D22B629A56C1D4D727A3739F14ED19C7877BF136E8C88774DB28D93B2941380FA8A7F88F1B0D757D3D31AEAB76294522E2AA5EC16CD9BEBA3317F06F0E611F1D2F4C8CC419552AE8AF1DB004F8C883A01E83BA5943A6B7D08F533DFB78DD1E17FE7B6C3EEBAD9FDF78FCE688056DF689DB596990744C458FE4DEBDF97B3ED8594522E8EF1D1183BC678CD83B34B29756FC960B2C929A94724FD2422F69D44BC52CA07A31962D9CD39BA4D44FC57666E3589982BD82B63F476CFE511B15F34956827E941D5F41BE6BAF34B29474473ABED670BFCFEE1A59425E5DDCCDA524E00EA37E595BD6B2D4E3DFC63B5BDF16F514A39A594F2D452CA5DA2E9727A638C0F938A88D8CBED80C19D544D6F1FA3F7A22306EEFE9F534A39259AB2D773EE1BA3430FBFD4FE7B42DC3A1CB5C4F8C1EA6B4B6D437BCB63A183FC0E9939910361AB7EFD1F1AA3B91811FDC35507914DF9F1FF8ED1EFC56B22629F76B8E8449452CE2BA53C2322BA5520378BD59707F0D4"
|
||||
"6AFAADA594234B2957F4AE3D9C0BA3B9D5FA81687A02477268DA7C93EDDBE55755BFF7D252CA81136EDFC42CEA04209B31FF75419021C6E7D7DBD8367BCAB1AE8FB219627648F5F3C0885B4E060E2AA56C174D3D84AEDBC59A8B35AD2BEA1EA088E6D913D3765C8CDE63BF778C8EC1BF399A2F8849E95EBD6F12A327C29F8C8828A55C18A3F902DB54DB58CE95C821D1D49DE8AAEB3FBC7282D9CEC7C668FDFB0D63B442DF8DD17C090F2E9BBA0347C57845C0579752EA9EA149A97B6FE6EB89595FD525A0D7BA96C572B4DFB3CF29A5EC5D4AF9C7BE138E52CA25A594BDA3C90B797044DCBB9472AF52CA24EA414CCD4227004F69EFC9741D18E30F101A221BB7DEC68651657EB66DA9BB3BD7077F8826B3FA559D9FBEE71BFC6FCFBCBE72B94BD557E4A82E2E33297D5757235DBFD9143D9AE8DFBFEDF6FB5277568C56233BBB2AD13BB43A0F60CEAFAA2EC653E759EF974B2D4ED45EFDD6436ABF194D11A8AE3F8988572F25C69AB4B761E6DBB78888334A29932A08F6AE182FC0744229E52D138AD7E7D7D5F42C4E8267229B678DD495FF7E3A8BB62CA494724329E57BA594B15A2DEBA2859E06B873449C919927477315F098B835EB78CE35D1540A5CAEA3A239B9E8BE019E9B99F78CA64BF3F66DEC870C106B4529A5FC2633BF16A395CE5E94995744C411A594AB32F301D1BC3E5D374693893A94FACB2722E290CC7C5834278A474F3033F9ABD124FA74879C3D2733FF3822CE89E6AA6CA7181F2E3A09274533F4A8CF5095E7E6F3F968B2F06B75E6FD89D13F346A397F9F37C4E8E7EFE668AE7E3F9399FF14A3F7499F9F99EF2FA59CB78C78F3F968CCFFFA4F243BBC1D675E77B76744DC29334F59E0575F554AF9C624DAD45A4D8F6B5F4DFBBAB2E4FC95F0D664B08211395ECC646D4DAA10D0B2B7BB88F88FCFE6697FB59B32F3EA79F6FB8481DB709F1C2F7AD235DF18D9A1E29FBE88BF79D7B20B0155EDD83433AFE88973633627621395E34FDFCCEC2FCAF5D39EF59634463F9B4A9775C19F933ACBF7E8593E9127D565F3D4BFBED7E0DA1CB0004F15B3EFB55C1BBD15E296D10E4F031CE5698013B6D059D79AEA509F1611070DD8968362B4FBB54FDF55EA3AAFBDC7F88218BFDFBA41F48F88382D9AE7030CD986F3A3B9B29C9597C7F810D3DA7C5DE483698764F675439F35A12BDE5A7D157F4D34897FB52FF7CC5B740F4536B7D60E89D1DE976BA3C9C88E888852CA89315E5B60B7CCDC3506D63E5DB4EFDEEF690317E0E95AA827749AEAFA0BB799492B66E3763DF33C7171C2163A01F8CF68BAF7EB27A5FD369AC235BB0CF528E0885B3EF87F1B4DB25B3D2AE0FA6892AF2672EF712528A51C1D114F8AA6C849FD9ACFF9613445421E37A1ACE47DA349C4AA93F23226FC64B252CAA9D1FCFDBF11E3E37EAF8CE6E12B7596F0A47CAC"
|
||||
"67DEA4BBFFE7D455FCCE68EF8DD7EA62383F5FE2F0B88322A2EED938A694724E35EF1531FABED820225EBB84786BE3233DF3EA1102EBA33AF9EC8E3369C56CD4F946D7AC8B95F5D649B9401778DB35F3F43E4241D8000003D7494441546CEAA1FF5D660E51F96F4DEDD92C339FDCC67C46DE5A7E71A65DF5D3924D37F42E99B96F66EEDFBEFECB7EEAE222E2DFBD7DDD5F90CD3307A616BB8DFFC0CCDCBBFDFBEF96C33CF590754466EE5E7DC6AFCE75F5412B8BD0B3DFBF9A62EC59DF027851B5EF93A8B541658D5D5FED95E6549FBBDD9EF9CDA21CE48AD076434FB4DCE91AE25F1CCD90B859C53F37228678D63CEBA6FAA4FED4298C055F093E1DCDADD7B9E19F5B65E6B34A29931C7ABA52EC514D4FF3592CAB96CC4B6045C82601F0E068CA62770D9AF0BA52B5CF8438A29AFD96CCAC4BE3AE3732738B6CAA9A7647415D114D412626CC0900305399F9B8CCBC2C9A5C8FD7C668F2DB85A5948914FF59A10E89D1B2D05B45F354C2F5D5DED194FB9D737D44BCA494F28B19B56755710200CCDA6DA379C84A9D099ED1D4275835DA5E809DA349869E7B285AFD9C88493825229ED6FE1C358578738E8B5B939ECF8B883D4B29C74C31FEAAB65286BF00746544BCAD94B2EA1E7AD59E041CD026E33D3BFA877C0E1DF38288987A75BB52CAA5997958449CDF3E1889299A3B01F861441C592DFBE194DBB236D69576026BEF92686A80DC2D9AB1DF1746C4FB4B29AB61E8DFBCDAB2C7AF5CE38AEBB852CA6B66DD0600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
|
||||
"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000D629FF0F4A0CD12A5E549F170000000049454E44AE426082";
|
||||
|
||||
}
|
||||
|
||||
#endif //TEXT_ATLAS_PNG_H
|
||||
|
||||