diff --git a/.flutter b/.flutter index 9e1c85788..78666c8dc 160000 --- a/.flutter +++ b/.flutter @@ -1 +1 @@ -Subproject commit 9e1c857886f07d342cf106f2cd588bcd5e031bb2 +Subproject commit 78666c8dc57e9f7548ca9f8dd0740fbf0c658dc9 diff --git a/CHANGELOG.md b/CHANGELOG.md index 9b6c75139..71011bf79 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,19 @@ All notable changes to this project will be documented in this file. ## [Unreleased] +## [v1.10.1] - 2023-12-21 + +- Cataloguing: detect/filter `Ultra HDR` +- Viewer: show JPEG MPF dependent images (except thumbnails and HDR gain maps) +- Info: show metadata from JPEG MPF +- Info: open images embedded via JPEG MPF +- Arabic translation (thanks Mohamed Zeroug) +- Belarusian translation (thanks Макар Разин) + +### Changed + +- upgraded Flutter to stable v3.16.5 + ## [v1.10.0] - 2023-12-02 ### Added diff --git a/android/app/build.gradle b/android/app/build.gradle index 797d29e5a..1ff9698d7 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -214,7 +214,7 @@ dependencies { implementation "androidx.appcompat:appcompat:1.6.1" implementation 'androidx.core:core-ktx:1.12.0' - implementation 'androidx.exifinterface:exifinterface:1.3.6' + implementation 'androidx.exifinterface:exifinterface:1.3.7' implementation 'androidx.lifecycle:lifecycle-process:2.6.2' implementation 'androidx.media:media:1.7.0' implementation 'androidx.multidex:multidex:2.0.1' @@ -225,6 +225,7 @@ dependencies { implementation 'com.commonsware.cwac:document:0.5.0' implementation 'com.drewnoakes:metadata-extractor:2.19.0' implementation "com.github.bumptech.glide:glide:$glide_version" + implementation 'com.google.android.material:material:1.11.0' // SLF4J implementation for `mp4parser` implementation 'org.slf4j:slf4j-simple:2.0.9' @@ -242,7 +243,7 @@ dependencies { testImplementation 'org.junit.jupiter:junit-jupiter-engine:5.10.1' - kapt 'androidx.annotation:annotation:1.7.0' + kapt 'androidx.annotation:annotation:1.7.1' ksp "com.github.bumptech.glide:ksp:$glide_version" compileOnly rootProject.findProject(':streams_channel') diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 140a47077..c9fa9370a 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -7,6 +7,9 @@ + diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/DeviceHandler.kt b/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/DeviceHandler.kt index a6843a95a..ccc38f8b1 100644 --- a/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/DeviceHandler.kt +++ b/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/DeviceHandler.kt @@ -9,6 +9,7 @@ import android.os.Build import android.provider.MediaStore import android.provider.Settings import androidx.core.content.pm.ShortcutManagerCompat +import com.google.android.material.color.DynamicColors import deckers.thibault.aves.channel.calls.Coresult.Companion.safe import deckers.thibault.aves.model.FieldMap import io.flutter.plugin.common.MethodCall @@ -18,7 +19,8 @@ import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.launch -import java.util.* +import java.util.Locale +import java.util.TimeZone class DeviceHandler(private val context: Context) : MethodCallHandler { private val defaultScope = CoroutineScope(SupervisorJob() + Dispatchers.Default) @@ -52,7 +54,7 @@ class DeviceHandler(private val context: Context) : MethodCallHandler { "canSetLockScreenWallpaper" to (sdkInt >= Build.VERSION_CODES.N), "canUseCrypto" to (sdkInt >= Build.VERSION_CODES.LOLLIPOP), "hasGeocoder" to Geocoder.isPresent(), - "isDynamicColorAvailable" to (sdkInt >= Build.VERSION_CODES.S), + "isDynamicColorAvailable" to DynamicColors.isDynamicColorAvailable(), "showPinShortcutFeedback" to (sdkInt >= Build.VERSION_CODES.O), "supportEdgeToEdgeUIMode" to (sdkInt >= Build.VERSION_CODES.Q), ) diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/EmbeddedDataHandler.kt b/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/EmbeddedDataHandler.kt index e956a25aa..9d34011ea 100644 --- a/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/EmbeddedDataHandler.kt +++ b/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/EmbeddedDataHandler.kt @@ -11,21 +11,28 @@ import com.bumptech.glide.load.resource.bitmap.TransformationUtils import com.drew.metadata.xmp.XmpDirectory import deckers.thibault.aves.channel.calls.Coresult.Companion.safe import deckers.thibault.aves.channel.calls.Coresult.Companion.safeSuspend -import deckers.thibault.aves.metadata.* +import deckers.thibault.aves.metadata.GoogleDeviceContainer +import deckers.thibault.aves.metadata.Metadata +import deckers.thibault.aves.metadata.MultiPage +import deckers.thibault.aves.metadata.XMP import deckers.thibault.aves.metadata.XMP.doesPropPathExist import deckers.thibault.aves.metadata.XMP.getSafeStructField +import deckers.thibault.aves.metadata.XMPPropName import deckers.thibault.aves.metadata.metadataextractor.Helper import deckers.thibault.aves.model.FieldMap -import deckers.thibault.aves.model.provider.ContentImageProvider import deckers.thibault.aves.model.provider.ImageProvider -import deckers.thibault.aves.utils.* +import deckers.thibault.aves.model.provider.ImageProviderFactory.getProvider +import deckers.thibault.aves.utils.BitmapUtils import deckers.thibault.aves.utils.BitmapUtils.getBytes import deckers.thibault.aves.utils.FileUtils.transferFrom +import deckers.thibault.aves.utils.LogUtils +import deckers.thibault.aves.utils.MimeTypes import deckers.thibault.aves.utils.MimeTypes.canReadWithExifInterface import deckers.thibault.aves.utils.MimeTypes.canReadWithMetadataExtractor import deckers.thibault.aves.utils.MimeTypes.extensionFor import deckers.thibault.aves.utils.MimeTypes.isImage import deckers.thibault.aves.utils.MimeTypes.isVideo +import deckers.thibault.aves.utils.StorageUtils import io.flutter.plugin.common.MethodCall import io.flutter.plugin.common.MethodChannel import io.flutter.plugin.common.MethodChannel.MethodCallHandler @@ -42,6 +49,7 @@ class EmbeddedDataHandler(private val context: Context) : MethodCallHandler { when (call.method) { "getExifThumbnails" -> ioScope.launch { safeSuspend(call, result, ::getExifThumbnails) } "extractGoogleDeviceItem" -> ioScope.launch { safe(call, result, ::extractGoogleDeviceItem) } + "extractJpegMpfItem" -> ioScope.launch { safe(call, result, ::extractJpegMpfItem) } "extractMotionPhotoImage" -> ioScope.launch { safe(call, result, ::extractMotionPhotoImage) } "extractMotionPhotoVideo" -> ioScope.launch { safe(call, result, ::extractMotionPhotoVideo) } "extractVideoEmbeddedPicture" -> ioScope.launch { safe(call, result, ::extractVideoEmbeddedPicture) } @@ -141,6 +149,40 @@ class EmbeddedDataHandler(private val context: Context) : MethodCallHandler { result.error("extractGoogleDeviceItem-empty", "failed to extract item from Google Device XMP at uri=$uri dataUri=$dataUri", null) } + private fun extractJpegMpfItem(call: MethodCall, result: MethodChannel.Result) { + val mimeType = call.argument("mimeType") + val uri = call.argument("uri")?.let { Uri.parse(it) } + val sizeBytes = call.argument("sizeBytes")?.toLong() + val displayName = call.argument("displayName") + val id = call.argument("id") + if (mimeType == null || uri == null || sizeBytes == null || id == null) { + result.error("extractJpegMpfItem-args", "missing arguments", null) + return + } + + val pageIndex = id - 1 + val mpEntries = MultiPage.getJpegMpfEntries(context, uri) + if (mpEntries != null && pageIndex < mpEntries.size) { + val mpEntry = mpEntries[pageIndex] + mpEntry.mimeType?.let { embedMimeType -> + var dataOffset = mpEntry.dataOffset + if (dataOffset > 0) { + val baseOffset = MultiPage.getJpegMpfBaseOffset(context, uri) + if (baseOffset != null) { + dataOffset += baseOffset + } + } + StorageUtils.openInputStream(context, uri)?.let { input -> + input.skip(dataOffset) + copyEmbeddedBytes(result, embedMimeType, displayName, input, mpEntry.size) + } + return + } + } + + result.error("extractJpegMpfItem-empty", "failed to extract file index=$id from MPF at uri=$uri", null) + } + private fun extractMotionPhotoImage(call: MethodCall, result: MethodChannel.Result) { val mimeType = call.argument("mimeType") val uri = call.argument("uri")?.let { Uri.parse(it) } @@ -299,8 +341,14 @@ class EmbeddedDataHandler(private val context: Context) : MethodCallHandler { "mimeType" to mimeType, ) if (isImage(mimeType) || isVideo(mimeType)) { + val provider = getProvider(context, uri) + if (provider == null) { + result.error("copyEmbeddedBytes-provider", "failed to find provider for uri=$uri", null) + return + } + ioScope.launch { - ContentImageProvider().fetchSingle(context, uri, mimeType, object : ImageProvider.ImageOpCallback { + provider.fetchSingle(context, uri, mimeType, object : ImageProvider.ImageOpCallback { override fun onSuccess(fields: FieldMap) { resultFields.putAll(fields) result.success(resultFields) diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/MediaEditHandler.kt b/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/MediaEditHandler.kt index 533a078b4..9e40b4199 100644 --- a/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/MediaEditHandler.kt +++ b/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/MediaEditHandler.kt @@ -55,7 +55,7 @@ class MediaEditHandler(private val contextWrapper: ContextWrapper) : MethodCallH return } - val provider = getProvider(uri) + val provider = getProvider(contextWrapper, uri) if (provider == null) { result.error("captureFrame-provider", "failed to find provider for uri=$uri", null) return diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/MediaFetchObjectHandler.kt b/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/MediaFetchObjectHandler.kt index 665d17a17..d0d317c2a 100644 --- a/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/MediaFetchObjectHandler.kt +++ b/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/MediaFetchObjectHandler.kt @@ -34,7 +34,7 @@ class MediaFetchObjectHandler(private val context: Context) : MethodCallHandler return } - val provider = getProvider(uri) + val provider = getProvider(context, uri) if (provider == null) { result.error("getEntry-provider", "failed to find provider for uri=$uri", null) return diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/MetadataEditHandler.kt b/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/MetadataEditHandler.kt index f8915a8f6..9d1704b27 100644 --- a/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/MetadataEditHandler.kt +++ b/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/MetadataEditHandler.kt @@ -62,7 +62,7 @@ class MetadataEditHandler(private val contextWrapper: ContextWrapper) : MethodCa return } - val provider = getProvider(uri) + val provider = getProvider(contextWrapper, uri) if (provider == null) { result.error("editOrientation-provider", "failed to find provider for uri=$uri", null) return @@ -90,7 +90,7 @@ class MetadataEditHandler(private val contextWrapper: ContextWrapper) : MethodCa return } - val provider = getProvider(uri) + val provider = getProvider(contextWrapper, uri) if (provider == null) { result.error("editDate-provider", "failed to find provider for uri=$uri", null) return @@ -117,7 +117,7 @@ class MetadataEditHandler(private val contextWrapper: ContextWrapper) : MethodCa return } - val provider = getProvider(uri) + val provider = getProvider(contextWrapper, uri) if (provider == null) { result.error("editMetadata-provider", "failed to find provider for uri=$uri", null) return @@ -142,7 +142,7 @@ class MetadataEditHandler(private val contextWrapper: ContextWrapper) : MethodCa return } - val provider = getProvider(uri) + val provider = getProvider(contextWrapper, uri) if (provider == null) { result.error("removeTrailerVideo-provider", "failed to find provider for uri=$uri", null) return @@ -168,7 +168,7 @@ class MetadataEditHandler(private val contextWrapper: ContextWrapper) : MethodCa return } - val provider = getProvider(uri) + val provider = getProvider(contextWrapper, uri) if (provider == null) { result.error("removeTypes-provider", "failed to find provider for uri=$uri", null) return diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/MetadataFetchHandler.kt b/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/MetadataFetchHandler.kt index e04dc7241..b86b2d636 100644 --- a/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/MetadataFetchHandler.kt +++ b/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/MetadataFetchHandler.kt @@ -57,6 +57,7 @@ import deckers.thibault.aves.metadata.XMP.getSafeDateMillis import deckers.thibault.aves.metadata.XMP.getSafeInt import deckers.thibault.aves.metadata.XMP.getSafeLocalizedText import deckers.thibault.aves.metadata.XMP.getSafeString +import deckers.thibault.aves.metadata.XMP.hasHdrGainMap import deckers.thibault.aves.metadata.XMP.isMotionPhoto import deckers.thibault.aves.metadata.XMP.isPanorama import deckers.thibault.aves.metadata.metadataextractor.Helper @@ -76,6 +77,7 @@ import deckers.thibault.aves.metadata.metadataextractor.Helper.getSafeRational import deckers.thibault.aves.metadata.metadataextractor.Helper.getSafeString import deckers.thibault.aves.metadata.metadataextractor.Helper.isPngTextDir import deckers.thibault.aves.metadata.metadataextractor.PngActlDirectory +import deckers.thibault.aves.metadata.metadataextractor.mpf.MpEntryDirectory import deckers.thibault.aves.model.FieldMap import deckers.thibault.aves.utils.ContextUtils.queryContentPropValue import deckers.thibault.aves.utils.LogUtils @@ -225,7 +227,7 @@ class MetadataFetchHandler(private val context: Context) : MethodCallHandler { foundMp4Uuid = metadata.directories.any { it is Mp4UuidBoxDirectory && it.tagCount > 0 } val dirByName = metadata.directories.filter { - (it.tagCount > 0 || it.errorCount > 0) + (it.tagCount > 0 || it.errorCount > 0 || it is MpEntryDirectory) && it !is FileTypeDirectory && it !is AviDirectory }.groupBy { dir -> dir.name } @@ -344,6 +346,10 @@ class MetadataFetchHandler(private val context: Context) : MethodCallHandler { } } + dir is MpEntryDirectory -> { + dirMap.putAll(dir.describe()) + } + else -> dirMap.putAll(tags.map { Pair(it.tagName, it.description) }) } } @@ -551,6 +557,11 @@ class MetadataFetchHandler(private val context: Context) : MethodCallHandler { if (xmpMeta.isMotionPhoto()) { flags = flags or MASK_IS_MULTIPAGE or MASK_IS_MOTION_PHOTO } + + // identification of embedded gain map + if (xmpMeta.hasHdrGainMap()) { + flags = flags or MASK_HAS_HDR_GAIN_MAP + } } catch (e: XMPException) { Log.w(LOG_TAG, "failed to read XMP directory for uri=$uri", e) } @@ -623,6 +634,11 @@ class MetadataFetchHandler(private val context: Context) : MethodCallHandler { } } + // JPEG Multi-Picture Format + if (metadata.getDirectoriesOfType(MpEntryDirectory::class.java).count { !it.entry.isThumbnail } > 1) { + flags = flags or MASK_IS_MULTIPAGE + } + // XMP if (!isLargeMp4(mimeType, sizeBytes)) { metadata.getDirectoriesOfType(XmpDirectory::class.java).map { it.xmpMeta }.forEach { @@ -913,10 +929,11 @@ class MetadataFetchHandler(private val context: Context) : MethodCallHandler { } val pages: ArrayList? = if (isMotionPhoto) { - MultiPage.getMotionPhotoPages(context, uri, mimeType, sizeBytes = sizeBytes) + MultiPage.getMotionPhotoPages(context, uri, mimeType, sizeBytes) } else { when (mimeType) { MimeTypes.HEIC, MimeTypes.HEIF -> MultiPage.getHeicTracks(context, uri) + MimeTypes.JPEG -> MultiPage.getJpegMpfPages(context, uri) MimeTypes.TIFF -> MultiPage.getTiffPages(context, uri) else -> null } @@ -1297,6 +1314,7 @@ class MetadataFetchHandler(private val context: Context) : MethodCallHandler { private const val MASK_IS_360 = 1 shl 3 private const val MASK_IS_MULTIPAGE = 1 shl 4 private const val MASK_IS_MOTION_PHOTO = 1 shl 5 + private const val MASK_HAS_HDR_GAIN_MAP = 1 shl 6 private const val XMP_SUBJECTS_SEPARATOR = ";" // overlay metadata diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/fetchers/RegionFetcher.kt b/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/fetchers/RegionFetcher.kt index 65a3af050..b3efb8a3c 100644 --- a/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/fetchers/RegionFetcher.kt +++ b/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/fetchers/RegionFetcher.kt @@ -10,7 +10,7 @@ import com.bumptech.glide.Glide import com.bumptech.glide.load.DecodeFormat import com.bumptech.glide.load.engine.DiskCacheStrategy import com.bumptech.glide.request.RequestOptions -import deckers.thibault.aves.decoder.MultiTrackImage +import deckers.thibault.aves.decoder.MultiPageImage import deckers.thibault.aves.utils.BitmapRegionDecoderCompat import deckers.thibault.aves.utils.BitmapUtils.getBytes import deckers.thibault.aves.utils.MimeTypes @@ -40,10 +40,10 @@ class RegionFetcher internal constructor( imageHeight: Int, result: MethodChannel.Result, ) { - if (MimeTypes.isHeic(mimeType) && pageId != null) { + if (pageId != null && MultiPageImage.isSupported(mimeType)) { val id = Pair(uri, pageId) fetch( - uri = pageTempUris.getOrPut(id) { createJpegForPage(uri, pageId) }, + uri = pageTempUris.getOrPut(id) { createJpegForPage(uri, mimeType, pageId) }, mimeType = MimeTypes.JPEG, pageId = null, sampleSize = sampleSize, @@ -104,11 +104,11 @@ class RegionFetcher internal constructor( } } - private fun createJpegForPage(sourceUri: Uri, pageId: Int): Uri { + private fun createJpegForPage(sourceUri: Uri, mimeType: String, pageId: Int): Uri { val target = Glide.with(context) .asBitmap() .apply(multiTrackGlideOptions) - .load(MultiTrackImage(context, sourceUri, pageId)) + .load(MultiPageImage(context, sourceUri, mimeType, pageId)) .submit() try { val bitmap = target.get() diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/fetchers/ThumbnailFetcher.kt b/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/fetchers/ThumbnailFetcher.kt index 752633094..98e44e135 100644 --- a/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/fetchers/ThumbnailFetcher.kt +++ b/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/fetchers/ThumbnailFetcher.kt @@ -12,7 +12,7 @@ import com.bumptech.glide.load.DecodeFormat import com.bumptech.glide.load.engine.DiskCacheStrategy import com.bumptech.glide.request.RequestOptions import com.bumptech.glide.signature.ObjectKey -import deckers.thibault.aves.decoder.MultiTrackImage +import deckers.thibault.aves.decoder.MultiPageImage import deckers.thibault.aves.decoder.SvgImage import deckers.thibault.aves.decoder.TiffImage import deckers.thibault.aves.decoder.VideoThumbnail @@ -20,7 +20,6 @@ import deckers.thibault.aves.utils.BitmapUtils.applyExifOrientation import deckers.thibault.aves.utils.BitmapUtils.getBytes import deckers.thibault.aves.utils.MimeTypes import deckers.thibault.aves.utils.MimeTypes.SVG -import deckers.thibault.aves.utils.MimeTypes.isHeic import deckers.thibault.aves.utils.MimeTypes.isVideo import deckers.thibault.aves.utils.MimeTypes.needRotationAfterContentResolverThumbnail import deckers.thibault.aves.utils.MimeTypes.needRotationAfterGlide @@ -47,8 +46,8 @@ class ThumbnailFetcher internal constructor( private val height: Int = if (height?.takeIf { it > 0 } != null) height else defaultSize private val svgFetch = mimeType == SVG private val tiffFetch = mimeType == MimeTypes.TIFF - private val multiTrackFetch = isHeic(mimeType) && pageId != null - private val customFetch = svgFetch || tiffFetch || multiTrackFetch + private val multiPageFetch = pageId != null && MultiPageImage.isSupported(mimeType) + private val customFetch = svgFetch || tiffFetch || multiPageFetch suspend fun fetch() { var bitmap: Bitmap? = null @@ -135,7 +134,7 @@ class ThumbnailFetcher internal constructor( val model: Any = when { svgFetch -> SvgImage(context, uri) tiffFetch -> TiffImage(context, uri, pageId) - multiTrackFetch -> MultiTrackImage(context, uri, pageId) + multiPageFetch -> MultiPageImage(context, uri, mimeType, pageId) else -> StorageUtils.getGlideSafeUri(context, uri, mimeType) } Glide.with(context) diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/channel/streams/ImageByteStreamHandler.kt b/android/app/src/main/kotlin/deckers/thibault/aves/channel/streams/ImageByteStreamHandler.kt index 56e40cc9d..54fc04f9d 100644 --- a/android/app/src/main/kotlin/deckers/thibault/aves/channel/streams/ImageByteStreamHandler.kt +++ b/android/app/src/main/kotlin/deckers/thibault/aves/channel/streams/ImageByteStreamHandler.kt @@ -9,7 +9,7 @@ import com.bumptech.glide.Glide import com.bumptech.glide.load.DecodeFormat import com.bumptech.glide.load.engine.DiskCacheStrategy import com.bumptech.glide.request.RequestOptions -import deckers.thibault.aves.decoder.MultiTrackImage +import deckers.thibault.aves.decoder.MultiPageImage import deckers.thibault.aves.decoder.TiffImage import deckers.thibault.aves.decoder.VideoThumbnail import deckers.thibault.aves.utils.BitmapUtils.applyExifOrientation @@ -18,7 +18,6 @@ import deckers.thibault.aves.utils.LogUtils import deckers.thibault.aves.utils.MemoryUtils import deckers.thibault.aves.utils.MimeTypes import deckers.thibault.aves.utils.MimeTypes.canDecodeWithFlutter -import deckers.thibault.aves.utils.MimeTypes.isHeic import deckers.thibault.aves.utils.MimeTypes.isVideo import deckers.thibault.aves.utils.MimeTypes.needRotationAfterGlide import deckers.thibault.aves.utils.StorageUtils @@ -100,7 +99,7 @@ class ImageByteStreamHandler(private val context: Context, private val arguments if (isVideo(mimeType)) { streamVideoByGlide(uri, mimeType, sizeBytes) - } else if (!canDecodeWithFlutter(mimeType, rotationDegrees, isFlipped)) { + } else if (!canDecodeWithFlutter(mimeType, pageId, rotationDegrees, isFlipped)) { // decode exotic format on platform side, then encode it in portable format for Flutter streamImageByGlide(uri, pageId, mimeType, sizeBytes, rotationDegrees, isFlipped) } else { @@ -131,8 +130,8 @@ class ImageByteStreamHandler(private val context: Context, private val arguments rotationDegrees: Int, isFlipped: Boolean, ) { - val model: Any = if (isHeic(mimeType) && pageId != null) { - MultiTrackImage(context, uri, pageId) + val model: Any = if (pageId != null && MultiPageImage.isSupported(mimeType)) { + MultiPageImage(context, uri, mimeType, pageId) } else if (mimeType == MimeTypes.TIFF) { TiffImage(context, uri, pageId) } else { diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/channel/streams/ImageOpStreamHandler.kt b/android/app/src/main/kotlin/deckers/thibault/aves/channel/streams/ImageOpStreamHandler.kt index a2a31e122..c6f10000e 100644 --- a/android/app/src/main/kotlin/deckers/thibault/aves/channel/streams/ImageOpStreamHandler.kt +++ b/android/app/src/main/kotlin/deckers/thibault/aves/channel/streams/ImageOpStreamHandler.kt @@ -107,7 +107,7 @@ class ImageOpStreamHandler(private val activity: FragmentActivity, private val a result["skipped"] = true } else { result["success"] = false - getProvider(uri)?.let { provider -> + getProvider(activity, uri)?.let { provider -> try { provider.delete(activity, uri, path, mimeType) result["success"] = true @@ -142,7 +142,7 @@ class ImageOpStreamHandler(private val activity: FragmentActivity, private val a // assume same provider for all entries val firstEntry = entryMapList.first() - val provider = (firstEntry["uri"] as String?)?.let { Uri.parse(it) }?.let { getProvider(it) } + val provider = (firstEntry["uri"] as String?)?.let { Uri.parse(it) }?.let { getProvider(activity, it) } if (provider == null) { error("convert-provider", "failed to find provider for entry=$firstEntry", null) return @@ -231,7 +231,7 @@ class ImageOpStreamHandler(private val activity: FragmentActivity, private val a entriesToNewName[AvesEntry(rawEntry)] = newName } - val byProvider = entriesToNewName.entries.groupBy { kv -> getProvider(kv.key.uri) } + val byProvider = entriesToNewName.entries.groupBy { kv -> getProvider(activity, kv.key.uri) } for ((provider, entryList) in byProvider) { if (provider == null) { error("rename-provider", "failed to find provider for entry=${entryList.firstOrNull()}", null) diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/decoder/MultiTrackImageGlideModule.kt b/android/app/src/main/kotlin/deckers/thibault/aves/decoder/MultiPageImageGlideModule.kt similarity index 51% rename from android/app/src/main/kotlin/deckers/thibault/aves/decoder/MultiTrackImageGlideModule.kt rename to android/app/src/main/kotlin/deckers/thibault/aves/decoder/MultiPageImageGlideModule.kt index 63fe82405..c068834c1 100644 --- a/android/app/src/main/kotlin/deckers/thibault/aves/decoder/MultiTrackImageGlideModule.kt +++ b/android/app/src/main/kotlin/deckers/thibault/aves/decoder/MultiPageImageGlideModule.kt @@ -17,32 +17,40 @@ import com.bumptech.glide.load.model.ModelLoaderFactory import com.bumptech.glide.load.model.MultiModelLoaderFactory import com.bumptech.glide.module.LibraryGlideModule import com.bumptech.glide.signature.ObjectKey +import deckers.thibault.aves.metadata.MultiPage import deckers.thibault.aves.metadata.MultiTrackMedia +import deckers.thibault.aves.utils.MimeTypes @GlideModule -class MultiTrackImageGlideModule : LibraryGlideModule() { +class MultiPageImageGlideModule : LibraryGlideModule() { override fun registerComponents(context: Context, glide: Glide, registry: Registry) { - registry.append(MultiTrackImage::class.java, Bitmap::class.java, MultiTrackThumbnailLoader.Factory()) + registry.append(MultiPageImage::class.java, Bitmap::class.java, MultiPageThumbnailLoader.Factory()) } } -class MultiTrackImage(val context: Context, val uri: Uri, val trackIndex: Int?) +class MultiPageImage(val context: Context, val uri: Uri, val mimeType: String, val pageId: Int?) { + override fun toString(): String = "MultiPageImage#${hashCode()}{uri=$uri, mimeType=$mimeType, pageId=$pageId}" -internal class MultiTrackThumbnailLoader : ModelLoader { - override fun buildLoadData(model: MultiTrackImage, width: Int, height: Int, options: Options): ModelLoader.LoadData { - return ModelLoader.LoadData(ObjectKey(model.uri), MultiTrackImageFetcher(model, width, height)) + companion object { + fun isSupported(mimeType: String) = MimeTypes.isHeic(mimeType) || mimeType == MimeTypes.JPEG + } +} + +internal class MultiPageThumbnailLoader : ModelLoader { + override fun buildLoadData(model: MultiPageImage, width: Int, height: Int, options: Options): ModelLoader.LoadData { + return ModelLoader.LoadData(ObjectKey(model.uri), MultiPageImageFetcher(model, width, height)) } - override fun handles(model: MultiTrackImage): Boolean = true + override fun handles(model: MultiPageImage): Boolean = true - internal class Factory : ModelLoaderFactory { - override fun build(multiFactory: MultiModelLoaderFactory): ModelLoader = MultiTrackThumbnailLoader() + internal class Factory : ModelLoaderFactory { + override fun build(multiFactory: MultiModelLoaderFactory): ModelLoader = MultiPageThumbnailLoader() override fun teardown() {} } } -internal class MultiTrackImageFetcher(val model: MultiTrackImage, val width: Int, val height: Int) : DataFetcher { +internal class MultiPageImageFetcher(val model: MultiPageImage, val width: Int, val height: Int) : DataFetcher { override fun loadData(priority: Priority, callback: DataCallback) { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.P) { callback.onLoadFailed(Exception("unsupported Android version")) @@ -51,9 +59,17 @@ internal class MultiTrackImageFetcher(val model: MultiTrackImage, val width: Int val context = model.context val uri = model.uri - val trackIndex = model.trackIndex + val mimeType = model.mimeType + + var bitmap: Bitmap? = null + if (MimeTypes.isHeic(mimeType)) { + val trackIndex = model.pageId + bitmap = MultiTrackMedia.getImage(context, uri, trackIndex) + } else if (mimeType == MimeTypes.JPEG) { + val pageIndex = model.pageId ?: 0 + bitmap = MultiPage.getJpegMpfBitmap(context, uri, pageIndex) + } - val bitmap = MultiTrackMedia.getImage(context, uri, trackIndex) if (bitmap == null) { callback.onLoadFailed(Exception("null bitmap")) } else { diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/metadata/Metadata.kt b/android/app/src/main/kotlin/deckers/thibault/aves/metadata/Metadata.kt index b82f1cf12..4553b2c4f 100644 --- a/android/app/src/main/kotlin/deckers/thibault/aves/metadata/Metadata.kt +++ b/android/app/src/main/kotlin/deckers/thibault/aves/metadata/Metadata.kt @@ -10,7 +10,9 @@ import java.io.File import java.io.InputStream import java.text.ParseException import java.text.SimpleDateFormat -import java.util.* +import java.util.Date +import java.util.Locale +import java.util.TimeZone import java.util.regex.Pattern object Metadata { diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/metadata/MultiPage.kt b/android/app/src/main/kotlin/deckers/thibault/aves/metadata/MultiPage.kt index 53c5b472d..eab4b5954 100644 --- a/android/app/src/main/kotlin/deckers/thibault/aves/metadata/MultiPage.kt +++ b/android/app/src/main/kotlin/deckers/thibault/aves/metadata/MultiPage.kt @@ -1,6 +1,8 @@ package deckers.thibault.aves.metadata import android.content.Context +import android.graphics.Bitmap +import android.graphics.BitmapFactory import android.media.MediaExtractor import android.media.MediaFormat import android.net.Uri @@ -8,15 +10,19 @@ import android.os.Build import android.os.ParcelFileDescriptor import android.util.Log import com.adobe.internal.xmp.XMPMeta +import com.drew.imaging.jpeg.JpegSegmentType import com.drew.metadata.xmp.XmpDirectory import deckers.thibault.aves.metadata.XMP.countPropArrayItems import deckers.thibault.aves.metadata.XMP.doesPropExist import deckers.thibault.aves.metadata.XMP.getSafeLong import deckers.thibault.aves.metadata.XMP.getSafeStructField import deckers.thibault.aves.metadata.metadataextractor.Helper +import deckers.thibault.aves.metadata.metadataextractor.mpf.MpEntry +import deckers.thibault.aves.metadata.metadataextractor.mpf.MpEntryDirectory import deckers.thibault.aves.model.FieldMap import deckers.thibault.aves.utils.LogUtils import deckers.thibault.aves.utils.MimeTypes +import deckers.thibault.aves.utils.StorageUtils import deckers.thibault.aves.utils.indexOfBytes import org.beyka.tiffbitmapfactory.TiffBitmapFactory import java.io.DataInputStream @@ -47,13 +53,13 @@ object MultiPage { val tracks = ArrayList() val extractor = MediaExtractor() extractor.setDataSource(context, uri, null) - for (i in 0 until extractor.trackCount) { + for (pageIndex in 0 until extractor.trackCount) { try { - val format = extractor.getTrackFormat(i) + val format = extractor.getTrackFormat(pageIndex) format.getString(MediaFormat.KEY_MIME)?.let { mime -> val trackMime = if (mime == MediaFormat.MIMETYPE_IMAGE_ANDROID_HEIC) MimeTypes.HEIC else mime val track: FieldMap = hashMapOf( - KEY_PAGE to i, + KEY_PAGE to pageIndex, KEY_MIME_TYPE to trackMime, ) @@ -72,13 +78,115 @@ object MultiPage { tracks.add(track) } } catch (e: Exception) { - Log.w(LOG_TAG, "failed to get HEIC track information for uri=$uri, track num=$i", e) + Log.w(LOG_TAG, "failed to get HEIC track information for uri=$uri, pageIndex=$pageIndex", e) } } extractor.release() return tracks } + // starts after `[APP2 marker (1 byte)] [segment size (2 bytes)] [MPF marker (4 bytes)]` + fun getJpegMpfBaseOffset(context: Context, uri: Uri): Int? { + val app2Marker = JpegSegmentType.APP2.byteValue + val mpfMarker = "MPF".toByteArray() + 0x00 + + try { + Metadata.openSafeInputStream(context, uri, MimeTypes.JPEG, null)?.use { input -> + var offset = 0 + while (true) { + do { + val b = input.read().toByte() + offset++ + } while (b != app2Marker) + // skip 2 bytes for segment size + input.skip(2) + offset += 2 + val marker = ByteArray(4) + input.read(marker, 0, marker.size) + offset += 4 + if (marker.contentEquals(mpfMarker)) { + return offset + } + } + } + } catch (e: Exception) { + Log.w(LOG_TAG, "failed to get MPF base offset from uri=$uri", e) + } + return null + } + + fun getJpegMpfEntries(context: Context, uri: Uri): List? { + try { + Metadata.openSafeInputStream(context, uri, MimeTypes.JPEG, null)?.use { input -> + val metadata = Helper.safeRead(input) + return metadata.getDirectoriesOfType(MpEntryDirectory::class.java).map { it.entry } + } + } catch (e: Exception) { + Log.w(LOG_TAG, "failed to find MPF entries", e) + } catch (e: NoClassDefFoundError) { + Log.w(LOG_TAG, "failed to find MPF entries", e) + } catch (e: AssertionError) { + Log.w(LOG_TAG, "failed to find MPF entries", e) + } + return null + } + + fun getJpegMpfPages(context: Context, uri: Uri): ArrayList { + val pages = ArrayList() + val baseOffset = getJpegMpfBaseOffset(context, uri) + val mpEntries = getJpegMpfEntries(context, uri) + if (mpEntries != null && baseOffset != null) { + for ((pageIndex, mpEntry) in mpEntries.withIndex()) { + mpEntry.mimeType?.let { embedMimeType -> + val page = hashMapOf( + KEY_PAGE to pageIndex, + KEY_MIME_TYPE to embedMimeType, + KEY_IS_DEFAULT to (pageIndex == 0), + // TODO TLAD [MPF] page[KEY_ROTATION_DEGREES] = same as primary + KEY_ROTATION_DEGREES to 0, + ) + + var dataOffset = mpEntry.dataOffset + if (dataOffset > 0) { + dataOffset += baseOffset + } + StorageUtils.openInputStream(context, uri)?.let { input -> + input.skip(dataOffset) + val options = BitmapFactory.Options().apply { + inJustDecodeBounds = true + } + BitmapFactory.decodeStream(input, null, options) + options.outWidth.takeIf { it >= 0 }?.let { page[KEY_WIDTH] = it } + options.outHeight.takeIf { it >= 0 }?.let { page[KEY_HEIGHT] = it } + + pages.add(page) + } + } + } + } + + return pages + } + + fun getJpegMpfBitmap(context: Context, uri: Uri, pageIndex: Int): Bitmap? { + val mpEntries = getJpegMpfEntries(context, uri) + if (mpEntries != null && pageIndex < mpEntries.size) { + val mpEntry = mpEntries[pageIndex] + var dataOffset = mpEntry.dataOffset + if (dataOffset > 0) { + val baseOffset = getJpegMpfBaseOffset(context, uri) + if (baseOffset != null) { + dataOffset += baseOffset + } + } + StorageUtils.openInputStream(context, uri)?.let { input -> + input.skip(dataOffset) + return BitmapFactory.decodeStream(input) + } + } + return null + } + fun getMotionPhotoPages(context: Context, uri: Uri, mimeType: String, sizeBytes: Long): ArrayList { fun MediaFormat.getSafeInt(key: String, save: (value: Int) -> Unit) { if (this.containsKey(key)) save(this.getInteger(key)) @@ -88,7 +196,7 @@ object MultiPage { if (this.containsKey(key)) save(this.getLong(key)) } - val tracks = ArrayList() + val pages = ArrayList() val extractor = MediaExtractor() var pfd: ParcelFileDescriptor? = null try { @@ -98,10 +206,10 @@ object MultiPage { pfd?.fileDescriptor?.let { fd -> extractor.setDataSource(fd, videoStartOffset, videoSizeBytes) // set the original image as the first and default track - var trackCount = 0 - tracks.add( + var pageIndex = 0 + pages.add( hashMapOf( - KEY_PAGE to trackCount++, + KEY_PAGE to pageIndex++, KEY_MIME_TYPE to mimeType, KEY_IS_DEFAULT to true, ) @@ -114,18 +222,18 @@ object MultiPage { val format = extractor.getTrackFormat(trackIndex) format.getString(MediaFormat.KEY_MIME)?.let { mime -> if (MimeTypes.isVideo(mime)) { - val track: FieldMap = hashMapOf( - KEY_PAGE to trackCount++, + val page: FieldMap = hashMapOf( + KEY_PAGE to pageIndex++, KEY_MIME_TYPE to MimeTypes.MP4, KEY_IS_DEFAULT to false, ) - format.getSafeInt(MediaFormat.KEY_WIDTH) { track[KEY_WIDTH] = it } - format.getSafeInt(MediaFormat.KEY_HEIGHT) { track[KEY_HEIGHT] = it } + format.getSafeInt(MediaFormat.KEY_WIDTH) { page[KEY_WIDTH] = it } + format.getSafeInt(MediaFormat.KEY_HEIGHT) { page[KEY_HEIGHT] = it } if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - format.getSafeInt(MediaFormat.KEY_ROTATION) { track[KEY_ROTATION_DEGREES] = it } + format.getSafeInt(MediaFormat.KEY_ROTATION) { page[KEY_ROTATION_DEGREES] = it } } - format.getSafeLong(MediaFormat.KEY_DURATION) { track[KEY_DURATION] = it / 1000 } - tracks.add(track) + format.getSafeLong(MediaFormat.KEY_DURATION) { page[KEY_DURATION] = it / 1000 } + pages.add(page) } } } catch (e: Exception) { @@ -140,7 +248,7 @@ object MultiPage { extractor.release() pfd?.close() } - return tracks + return pages } fun getMotionPhotoOffset(context: Context, uri: Uri, mimeType: String, sizeBytes: Long): Long? { @@ -204,9 +312,9 @@ object MultiPage { } fun getTiffPages(context: Context, uri: Uri): ArrayList { - fun toMap(page: Int, options: TiffBitmapFactory.Options): FieldMap { + fun toMap(pageIndex: Int, options: TiffBitmapFactory.Options): FieldMap { return hashMapOf( - KEY_PAGE to page, + KEY_PAGE to pageIndex, KEY_MIME_TYPE to MimeTypes.TIFF, KEY_WIDTH to options.outWidth, KEY_HEIGHT to options.outHeight, @@ -217,8 +325,8 @@ object MultiPage { getTiffPageInfo(context, uri, 0)?.let { first -> pages.add(toMap(0, first)) val pageCount = first.outDirectoryCount - for (i in 1 until pageCount) { - getTiffPageInfo(context, uri, i)?.let { pages.add(toMap(i, it)) } + for (pageIndex in 1 until pageCount) { + getTiffPageInfo(context, uri, pageIndex)?.let { pages.add(toMap(pageIndex, it)) } } } return pages diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/metadata/XMP.kt b/android/app/src/main/kotlin/deckers/thibault/aves/metadata/XMP.kt index e593dd16c..2744a70aa 100644 --- a/android/app/src/main/kotlin/deckers/thibault/aves/metadata/XMP.kt +++ b/android/app/src/main/kotlin/deckers/thibault/aves/metadata/XMP.kt @@ -49,6 +49,7 @@ object XMP { private const val GDEVICE_ITEM_NS_URI = "http://ns.google.com/photos/dd/1.0/item/" private const val GIMAGE_NS_URI = "http://ns.google.com/photos/1.0/image/" private const val GPANO_NS_URI = "http://ns.google.com/photos/1.0/panorama/" + private const val HDRGM_NS_URI = "http://ns.adobe.com/hdr-gain-map/1.0/" private const val PMTM_NS_URI = "http://www.hdrsoft.com/photomatix_settings01" val DC_SUBJECT_PROP_NAME = XMPPropName(DC_NS_URI, "subject") @@ -83,13 +84,20 @@ object XMP { val GDEVICE_CONTAINER_ITEM_LENGTH_PROP_NAME = XMPPropName(GDEVICE_ITEM_NS_URI, "Length") val GDEVICE_CONTAINER_ITEM_MIME_PROP_NAME = XMPPropName(GDEVICE_ITEM_NS_URI, "Mime") - // motion photo + // container val GCAMERA_VIDEO_OFFSET_PROP_NAME = XMPPropName(GCAMERA_NS_URI, "MicroVideoOffset") val GCONTAINER_DIRECTORY_PROP_NAME = XMPPropName(GCONTAINER_NS_URI, "Directory") val GCONTAINER_ITEM_PROP_NAME = XMPPropName(GCONTAINER_NS_URI, "Item") val GCONTAINER_ITEM_LENGTH_PROP_NAME = XMPPropName(GCONTAINER_ITEM_NS_URI, "Length") val GCONTAINER_ITEM_MIME_PROP_NAME = XMPPropName(GCONTAINER_ITEM_NS_URI, "Mime") + private val GCONTAINER_ITEM_SEMANTIC_PROP_NAME = XMPPropName(GCONTAINER_ITEM_NS_URI, "Semantic") + + private const val ITEM_SEMANTIC_GAIN_MAP = "GainMap" + + // HDR gain map + + private val HDRGM_VERSION_PROP_NAME = XMPPropName(HDRGM_NS_URI, "Version") // panorama // cf https://developers.google.com/streetview/spherical-metadata @@ -180,6 +188,35 @@ object XMP { // extensions + fun XMPMeta.hasHdrGainMap(): Boolean { + try { + // standard HDR gain map + if (doesPropExist(HDRGM_VERSION_PROP_NAME)) { + return true + } + + // `Ultra HDR` + if (doesPropExist(GCONTAINER_DIRECTORY_PROP_NAME)) { + val count = countPropArrayItems(GCONTAINER_DIRECTORY_PROP_NAME) + for (i in 1 until count + 1) { + val semantic = getSafeStructField(listOf(GCONTAINER_DIRECTORY_PROP_NAME, i, GCONTAINER_ITEM_PROP_NAME, GCONTAINER_ITEM_SEMANTIC_PROP_NAME))?.value + if (semantic == ITEM_SEMANTIC_GAIN_MAP) { + return true + } + } + } + + return false + } catch (e: XMPException) { + if (e.errorCode != XMPError.BADSCHEMA) { + // `BADSCHEMA` code is reported when we check a property + // from a non standard namespace, and that namespace is not declared in the XMP + Log.w(LOG_TAG, "failed to check HDR props from XMP", e) + } + } + return false + } + fun XMPMeta.isMotionPhoto(): Boolean { try { // GCamera motion photo diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/metadata/metadataextractor/Helper.kt b/android/app/src/main/kotlin/deckers/thibault/aves/metadata/metadataextractor/Helper.kt index 6bbd418ff..3ee6f18fc 100644 --- a/android/app/src/main/kotlin/deckers/thibault/aves/metadata/metadataextractor/Helper.kt +++ b/android/app/src/main/kotlin/deckers/thibault/aves/metadata/metadataextractor/Helper.kt @@ -27,6 +27,7 @@ import com.drew.metadata.xmp.XmpReader import deckers.thibault.aves.metadata.ExifGeoTiffTags import deckers.thibault.aves.metadata.GeoTiffKeys import deckers.thibault.aves.metadata.Metadata +import deckers.thibault.aves.metadata.metadataextractor.mpf.MpfReader import deckers.thibault.aves.utils.LogUtils import java.io.BufferedInputStream import java.io.IOException @@ -97,6 +98,7 @@ object Helper { val readers = ArrayList().apply { addAll(JpegMetadataReader.ALL_READERS.filter { it !is XmpReader }) add(SafeXmpReader()) + add(MpfReader()) } val metadata = com.drew.metadata.Metadata() diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/metadata/metadataextractor/mpf/MpEntry.kt b/android/app/src/main/kotlin/deckers/thibault/aves/metadata/metadataextractor/mpf/MpEntry.kt new file mode 100644 index 000000000..dc777dbd2 --- /dev/null +++ b/android/app/src/main/kotlin/deckers/thibault/aves/metadata/metadataextractor/mpf/MpEntry.kt @@ -0,0 +1,37 @@ +package deckers.thibault.aves.metadata.metadataextractor.mpf + +import deckers.thibault.aves.utils.MimeTypes + +class MpEntry(val flags: Int, val format: Int, val type: Int, val size: Long, val dataOffset: Long, val dep1: Short, val dep2: Short) { + val mimeType: String? + get() = getMimeType(format) + + val isThumbnail: Boolean + get() = when (type) { + TYPE_THUMBNAIL_VGA, TYPE_THUMBNAIL_FULL_HD -> true + else -> false + } + + override fun toString(): String = "MpEntry#${hashCode()}{flags=$flags, format=$format, type=$type, size=$size, dataOffset=$dataOffset, dep1=$dep1, dep2=$dep2}" + + companion object { + const val FLAG_REPRESENTATIVE = 1 shl 2 + const val FLAG_DEPENDENT_CHILD = 1 shl 3 + const val FLAG_DEPENDENT_PARENT = 1 shl 4 + + const val TYPE_PRIMARY = 0x030000 + const val TYPE_THUMBNAIL_VGA = 0x010001 + const val TYPE_THUMBNAIL_FULL_HD = 0x010002 + const val TYPE_PANORAMA = 0x020001 + const val TYPE_DISPARITY = 0x020002 + const val TYPE_MULTI_ANGLE = 0x020003 + const val TYPE_UNDEFINED = 0x000000 + + fun getMimeType(format: Int): String? { + return when (format) { + 0 -> MimeTypes.JPEG + else -> null + } + } + } +} diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/metadata/metadataextractor/mpf/MpEntryDirectory.kt b/android/app/src/main/kotlin/deckers/thibault/aves/metadata/metadataextractor/mpf/MpEntryDirectory.kt new file mode 100644 index 000000000..7dba5520f --- /dev/null +++ b/android/app/src/main/kotlin/deckers/thibault/aves/metadata/metadataextractor/mpf/MpEntryDirectory.kt @@ -0,0 +1,64 @@ +package deckers.thibault.aves.metadata.metadataextractor.mpf + +import com.drew.metadata.Directory +import com.drew.metadata.TagDescriptor + +class MpEntryDirectory(val id: Int, val entry: MpEntry) : Directory() { + private val descriptor = MpEntryDescriptor(this) + + init { + setDescriptor(descriptor) + } + + fun describe(): Map { + return HashMap().apply { + put("Flags", descriptor.getFlagsDescription(entry.flags)) + put("Format", descriptor.getFormatDescription(entry.format)) + put("Type", descriptor.getTypeDescription(entry.type)) + put("Size", "${entry.size} bytes") + put("Offset", "${entry.dataOffset} bytes") + put("Dependent Image 1 Entry Number", "${entry.dep1}") + put("Dependent Image 2 Entry Number", "${entry.dep2}") + } + } + + override fun getName(): String { + return "MPF Image #$id" + } + + override fun getTagNameMap(): HashMap { + return _tagNameMap + } + + companion object { + private val _tagNameMap = HashMap() + } +} + +class MpEntryDescriptor(directory: MpEntryDirectory?) : TagDescriptor(directory) { + fun getFlagsDescription(flags: Int): String { + val flagStrings = ArrayList().apply { + if (flags and MpEntry.FLAG_REPRESENTATIVE != 0) add("representative image") + if (flags and MpEntry.FLAG_DEPENDENT_CHILD != 0) add("dependent child image") + if (flags and MpEntry.FLAG_DEPENDENT_PARENT != 0) add("dependent parent image") + } + return if (flagStrings.isEmpty()) "none" else flagStrings.joinToString(", ") + } + + fun getFormatDescription(format: Int): String { + return MpEntry.getMimeType(format) ?: "Unknown ($format)" + } + + fun getTypeDescription(type: Int): String { + return when (type) { + MpEntry.TYPE_PRIMARY -> "Baseline MP Primary Image" + MpEntry.TYPE_THUMBNAIL_VGA -> "Large Thumbnail (VGA equivalent)" + MpEntry.TYPE_THUMBNAIL_FULL_HD -> "Large Thumbnail (full HD equivalent)" + MpEntry.TYPE_PANORAMA -> "Multi-frame Panorama" + MpEntry.TYPE_DISPARITY -> "Multi-frame Disparity" + MpEntry.TYPE_MULTI_ANGLE -> "Multi-angle" + MpEntry.TYPE_UNDEFINED -> "Undefined" + else -> "Unknown ($type)" + } + } +} diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/metadata/metadataextractor/mpf/MpfDirectory.kt b/android/app/src/main/kotlin/deckers/thibault/aves/metadata/metadataextractor/mpf/MpfDirectory.kt new file mode 100644 index 000000000..53904b56f --- /dev/null +++ b/android/app/src/main/kotlin/deckers/thibault/aves/metadata/metadataextractor/mpf/MpfDirectory.kt @@ -0,0 +1,38 @@ +package deckers.thibault.aves.metadata.metadataextractor.mpf + +import com.drew.metadata.Directory +import com.drew.metadata.TagDescriptor + +class MpfDirectory : Directory() { + init { + setDescriptor(MpfDescriptor(this)) + } + + override fun getName(): String { + return "MPF" + } + + override fun getTagNameMap(): HashMap { + return _tagNameMap + } + + fun getNumberOfImages() = getInt(TAG_NUMBER_OF_IMAGES) + + companion object { + const val TAG_MPF_VERSION = 0xb000 + const val TAG_NUMBER_OF_IMAGES = 0xb001 + const val TAG_MP_ENTRY = 0xb002 + private const val TAG_IMAGE_UID_LIST = 0xb003 + private const val TAG_TOTAL_FRAMES = 0xb004 + + private val _tagNameMap = HashMap().apply { + put(TAG_MPF_VERSION, "MPF Version") + put(TAG_NUMBER_OF_IMAGES, "Number Of Images") + put(TAG_MP_ENTRY, "MP Entry") + put(TAG_IMAGE_UID_LIST, "Image UID List") + put(TAG_TOTAL_FRAMES, "Total Frames") + } + } +} + +class MpfDescriptor(directory: MpfDirectory?) : TagDescriptor(directory) \ No newline at end of file diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/metadata/metadataextractor/mpf/MpfReader.kt b/android/app/src/main/kotlin/deckers/thibault/aves/metadata/metadataextractor/mpf/MpfReader.kt new file mode 100644 index 000000000..423ff56d4 --- /dev/null +++ b/android/app/src/main/kotlin/deckers/thibault/aves/metadata/metadataextractor/mpf/MpfReader.kt @@ -0,0 +1,95 @@ +package deckers.thibault.aves.metadata.metadataextractor.mpf + +import android.util.Log +import com.drew.imaging.jpeg.JpegSegmentMetadataReader +import com.drew.imaging.jpeg.JpegSegmentType +import com.drew.lang.ByteArrayReader +import com.drew.lang.RandomAccessReader +import com.drew.metadata.Metadata +import com.drew.metadata.MetadataReader +import deckers.thibault.aves.utils.LogUtils + +class MpfReader : JpegSegmentMetadataReader, MetadataReader { + override fun getSegmentTypes(): Iterable { + return listOf(JpegSegmentType.APP2) + } + + override fun readJpegSegments(segments: Iterable, metadata: Metadata, segmentType: JpegSegmentType) { + for (segmentBytes in segments) { + // Skip segments not starting with the required header + if (segmentBytes.size >= PREAMBLE.length && PREAMBLE == String(segmentBytes, 0, PREAMBLE.length)) { + extract(ByteArrayReader(segmentBytes), metadata) + } + } + } + + override fun extract(reader: RandomAccessReader, metadata: Metadata) { + val directory = MpfDirectory() + metadata.addDirectory(directory) + + val baseOffset = 4 + + // MP Format Identifier (4Byte) + // MP header + // - MP Endian (4Byte) + val byteOrderIdentifier = reader.getInt16(baseOffset) + if (byteOrderIdentifier.toInt() == 0x4d4d) { // "MM" + reader.isMotorolaByteOrder = true + } else if (byteOrderIdentifier.toInt() == 0x4949) { // "II" + reader.isMotorolaByteOrder = false + } + // - Offset to First IFD (4Byte) + val firstIfdOffset = reader.getInt32(baseOffset + 4) + + // [in primary image only] MP Index IFD: + // - Count (2Byte) + var offset = baseOffset + firstIfdOffset + val tagCount = reader.getInt16(offset) + offset += 2 + // - MP Index Fields (Overall Structure Info.) + var imageCount = 0 + for (tag in 0.. directory.setString(tagId, reader.getString(offset + 8, 4, Charsets.US_ASCII)) + MpfDirectory.TAG_NUMBER_OF_IMAGES -> { + imageCount = reader.getInt32(offset + 8) + directory.setInt(tagId, imageCount) + } + + MpfDirectory.TAG_MP_ENTRY -> { + var mpEntryOffset = baseOffset + reader.getInt32(offset + 8) + for (index in 0.. Log.d(LOG_TAG, "unknown tag=$tagId") + } + offset += 12 + } + + // - Offset of Next IFD (4Byte) + // Value (MP Index IFD) + + // [in primary & other images] MP Attributes IFD: + // - Count (2Byte) + // - MP Attribute Fields (Details of Specific Image Usage) + // - Offset of Next IFD + // Value (MP Attribute IFD) + } + + companion object { + private val LOG_TAG = LogUtils.createTag() + private const val PREAMBLE = "MPF" + } +} diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/model/provider/AvesEmbeddedMediaProvider.kt b/android/app/src/main/kotlin/deckers/thibault/aves/model/provider/AvesEmbeddedMediaProvider.kt new file mode 100644 index 000000000..49f0a8895 --- /dev/null +++ b/android/app/src/main/kotlin/deckers/thibault/aves/model/provider/AvesEmbeddedMediaProvider.kt @@ -0,0 +1,18 @@ +package deckers.thibault.aves.model.provider + +import android.content.ContentResolver +import android.content.Context +import android.net.Uri +import java.util.Locale + +class AvesEmbeddedMediaProvider : UnknownContentProvider() { + override val reliableProviderMimeType: Boolean + get() = true + + companion object { + fun provides(context: Context, uri: Uri): Boolean { + if (uri.scheme?.lowercase(Locale.ROOT) != ContentResolver.SCHEME_CONTENT) return false + return uri.authority == "${context.applicationContext.packageName}.file_provider" + } + } +} \ No newline at end of file diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/model/provider/ImageProvider.kt b/android/app/src/main/kotlin/deckers/thibault/aves/model/provider/ImageProvider.kt index 8abdc5648..766c3b936 100644 --- a/android/app/src/main/kotlin/deckers/thibault/aves/model/provider/ImageProvider.kt +++ b/android/app/src/main/kotlin/deckers/thibault/aves/model/provider/ImageProvider.kt @@ -19,25 +19,36 @@ import com.bumptech.glide.load.engine.DiskCacheStrategy import com.bumptech.glide.request.FutureTarget import com.bumptech.glide.request.RequestOptions import com.commonsware.cwac.document.DocumentFileCompat -import deckers.thibault.aves.decoder.MultiTrackImage +import deckers.thibault.aves.decoder.MultiPageImage import deckers.thibault.aves.decoder.SvgImage import deckers.thibault.aves.decoder.TiffImage -import deckers.thibault.aves.metadata.* +import deckers.thibault.aves.metadata.ExifInterfaceHelper import deckers.thibault.aves.metadata.ExifInterfaceHelper.getSafeDateMillis import deckers.thibault.aves.metadata.Metadata.TYPE_EXIF import deckers.thibault.aves.metadata.Metadata.TYPE_IPTC import deckers.thibault.aves.metadata.Metadata.TYPE_MP4 import deckers.thibault.aves.metadata.Metadata.TYPE_XMP +import deckers.thibault.aves.metadata.Mp4ParserHelper import deckers.thibault.aves.metadata.Mp4ParserHelper.updateLocation import deckers.thibault.aves.metadata.Mp4ParserHelper.updateRotation import deckers.thibault.aves.metadata.Mp4ParserHelper.updateXmp +import deckers.thibault.aves.metadata.MultiPage +import deckers.thibault.aves.metadata.PixyMetaHelper import deckers.thibault.aves.metadata.PixyMetaHelper.extendedXmpDocString import deckers.thibault.aves.metadata.PixyMetaHelper.xmpDocString +import deckers.thibault.aves.metadata.XMP import deckers.thibault.aves.metadata.metadataextractor.Helper -import deckers.thibault.aves.model.* -import deckers.thibault.aves.utils.* +import deckers.thibault.aves.model.AvesEntry +import deckers.thibault.aves.model.ExifOrientationOp +import deckers.thibault.aves.model.FieldMap +import deckers.thibault.aves.model.NameConflictStrategy +import deckers.thibault.aves.model.SourceEntry +import deckers.thibault.aves.utils.BitmapUtils +import deckers.thibault.aves.utils.BmpWriter import deckers.thibault.aves.utils.FileUtils.transferFrom import deckers.thibault.aves.utils.FileUtils.transferTo +import deckers.thibault.aves.utils.LogUtils +import deckers.thibault.aves.utils.MimeTypes import deckers.thibault.aves.utils.MimeTypes.canEditExif import deckers.thibault.aves.utils.MimeTypes.canEditIptc import deckers.thibault.aves.utils.MimeTypes.canEditXmp @@ -46,13 +57,19 @@ import deckers.thibault.aves.utils.MimeTypes.canReadWithPixyMeta import deckers.thibault.aves.utils.MimeTypes.canRemoveMetadata import deckers.thibault.aves.utils.MimeTypes.extensionFor import deckers.thibault.aves.utils.MimeTypes.isVideo +import deckers.thibault.aves.utils.StorageUtils import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext import pixy.meta.meta.Metadata import pixy.meta.meta.MetadataType -import java.io.* +import java.io.ByteArrayInputStream +import java.io.File +import java.io.FileOutputStream +import java.io.IOException +import java.io.OutputStream import java.nio.channels.Channels -import java.util.* +import java.util.Date +import java.util.TimeZone import kotlin.math.absoluteValue abstract class ImageProvider { @@ -291,8 +308,8 @@ abstract class ImageProvider { targetHeightPx = sourceEntry.height * targetHeightPx / 100 } - val model: Any = if (MimeTypes.isHeic(sourceMimeType) && pageId != null) { - MultiTrackImage(activity, sourceUri, pageId) + val model: Any = if (pageId != null && MultiPageImage.isSupported(sourceMimeType)) { + MultiPageImage(activity, sourceUri, sourceMimeType, pageId) } else if (sourceMimeType == MimeTypes.TIFF) { TiffImage(activity, sourceUri, pageId) } else if (sourceMimeType == MimeTypes.SVG) { diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/model/provider/ImageProviderFactory.kt b/android/app/src/main/kotlin/deckers/thibault/aves/model/provider/ImageProviderFactory.kt index 63d0afbde..180720652 100644 --- a/android/app/src/main/kotlin/deckers/thibault/aves/model/provider/ImageProviderFactory.kt +++ b/android/app/src/main/kotlin/deckers/thibault/aves/model/provider/ImageProviderFactory.kt @@ -1,20 +1,24 @@ package deckers.thibault.aves.model.provider import android.content.ContentResolver +import android.content.Context import android.net.Uri import deckers.thibault.aves.utils.StorageUtils -import java.util.* +import java.util.Locale object ImageProviderFactory { - fun getProvider(uri: Uri): ImageProvider? { + fun getProvider(context: Context, uri: Uri): ImageProvider? { return when (uri.scheme?.lowercase(Locale.ROOT)) { ContentResolver.SCHEME_CONTENT -> { if (StorageUtils.isMediaStoreContentUri(uri)) { MediaStoreImageProvider() + } else if (AvesEmbeddedMediaProvider.provides(context, uri)) { + AvesEmbeddedMediaProvider() } else { - ContentImageProvider() + UnknownContentProvider() } } + ContentResolver.SCHEME_FILE -> FileImageProvider() else -> null } diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/model/provider/ContentImageProvider.kt b/android/app/src/main/kotlin/deckers/thibault/aves/model/provider/UnknownContentProvider.kt similarity index 62% rename from android/app/src/main/kotlin/deckers/thibault/aves/model/provider/ContentImageProvider.kt rename to android/app/src/main/kotlin/deckers/thibault/aves/model/provider/UnknownContentProvider.kt index ef2e87410..8fc4e6db0 100644 --- a/android/app/src/main/kotlin/deckers/thibault/aves/model/provider/ContentImageProvider.kt +++ b/android/app/src/main/kotlin/deckers/thibault/aves/model/provider/UnknownContentProvider.kt @@ -13,31 +13,35 @@ import deckers.thibault.aves.utils.LogUtils import deckers.thibault.aves.utils.MimeTypes import deckers.thibault.aves.utils.StorageUtils -internal class ContentImageProvider : ImageProvider() { +open class UnknownContentProvider : ImageProvider() { + open val reliableProviderMimeType: Boolean + get() = false + override fun fetchSingle(context: Context, uri: Uri, sourceMimeType: String?, callback: ImageOpCallback) { - // source MIME type may be incorrect, so we get a second opinion if possible - var extractorMimeType: String? = null - try { - val safeUri = Uri.fromFile(Metadata.createPreviewFile(context, uri)) - StorageUtils.openInputStream(context, safeUri)?.use { input -> - // `metadata-extractor` is the most reliable, except for `tiff` (false positives, false negatives) - // cf https://github.com/drewnoakes/metadata-extractor/issues/296 - Helper.readMimeType(input)?.takeIf { it != MimeTypes.TIFF }?.let { - extractorMimeType = it - if (extractorMimeType != sourceMimeType) { - Log.d(LOG_TAG, "source MIME type is $sourceMimeType but extracted MIME type is $extractorMimeType for uri=$uri") + var mimeType = sourceMimeType + if (sourceMimeType == null || !reliableProviderMimeType) { + // source MIME type may be incorrect, so we get a second opinion if possible + try { + val safeUri = Uri.fromFile(Metadata.createPreviewFile(context, uri)) + StorageUtils.openInputStream(context, safeUri)?.use { input -> + // `metadata-extractor` is the most reliable, except for `tiff` (false positives, false negatives) + // cf https://github.com/drewnoakes/metadata-extractor/issues/296 + Helper.readMimeType(input)?.takeIf { it != MimeTypes.TIFF }?.let { + if (it != sourceMimeType) { + Log.d(LOG_TAG, "source MIME type is $sourceMimeType but extracted MIME type is $it for uri=$uri") + mimeType = it + } } } + } catch (e: Exception) { + Log.w(LOG_TAG, "failed to get MIME type by metadata-extractor for uri=$uri", e) + } catch (e: NoClassDefFoundError) { + Log.w(LOG_TAG, "failed to get MIME type by metadata-extractor for uri=$uri", e) + } catch (e: AssertionError) { + Log.w(LOG_TAG, "failed to get MIME type by metadata-extractor for uri=$uri", e) } - } catch (e: Exception) { - Log.w(LOG_TAG, "failed to get MIME type by metadata-extractor for uri=$uri", e) - } catch (e: NoClassDefFoundError) { - Log.w(LOG_TAG, "failed to get MIME type by metadata-extractor for uri=$uri", e) - } catch (e: AssertionError) { - Log.w(LOG_TAG, "failed to get MIME type by metadata-extractor for uri=$uri", e) } - val mimeType = extractorMimeType ?: sourceMimeType val fields: FieldMap = hashMapOf( "origin" to SourceEntry.ORIGIN_UNKNOWN_CONTENT, "uri" to uri.toString(), @@ -75,6 +79,6 @@ internal class ContentImageProvider : ImageProvider() { } companion object { - private val LOG_TAG = LogUtils.createTag() + private val LOG_TAG = LogUtils.createTag() } } \ No newline at end of file diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/utils/MimeTypes.kt b/android/app/src/main/kotlin/deckers/thibault/aves/utils/MimeTypes.kt index 31d0e9986..d68d851b1 100644 --- a/android/app/src/main/kotlin/deckers/thibault/aves/utils/MimeTypes.kt +++ b/android/app/src/main/kotlin/deckers/thibault/aves/utils/MimeTypes.kt @@ -82,9 +82,10 @@ object MimeTypes { else -> false } - // as of Flutter v1.22.0, with additional custom handling for SVG - fun canDecodeWithFlutter(mimeType: String, rotationDegrees: Int?, isFlipped: Boolean?) = when (mimeType) { - JPEG, GIF, WEBP, BMP, WBMP, ICO, SVG -> true + // as of Flutter v3.16.4, with additional custom handling for SVG + fun canDecodeWithFlutter(mimeType: String, pageId: Int?, rotationDegrees: Int?, isFlipped: Boolean?) = when (mimeType) { + GIF, WEBP, BMP, WBMP, ICO, SVG -> true + JPEG -> (pageId ?: 0) == 0 PNG -> (rotationDegrees ?: 0) == 0 && !(isFlipped ?: false) else -> false } diff --git a/android/app/src/main/res/values-ar/strings.xml b/android/app/src/main/res/values-ar/strings.xml index 0d6515695..dd308de11 100644 --- a/android/app/src/main/res/values-ar/strings.xml +++ b/android/app/src/main/res/values-ar/strings.xml @@ -8,5 +8,5 @@ يتم فحص الوسائط إيقاف الوضع الآمن - أيفيس + Aves \ No newline at end of file diff --git a/android/app/src/main/res/values-tr/strings.xml b/android/app/src/main/res/values-tr/strings.xml index e516cc30b..85fa22f09 100644 --- a/android/app/src/main/res/values-tr/strings.xml +++ b/android/app/src/main/res/values-tr/strings.xml @@ -8,4 +8,5 @@ Medya tarama Medya taranıyor Durdur + Güvenli mod \ No newline at end of file diff --git a/fastlane/metadata/android/ar/full_description.txt b/fastlane/metadata/android/ar/full_description.txt index 167ed3b35..74df1a08d 100644 --- a/fastlane/metadata/android/ar/full_description.txt +++ b/fastlane/metadata/android/ar/full_description.txt @@ -1,5 +1,5 @@ أيفيس يمكنه التعامل مع جميع أنواع الصور ومقاطع الفيديو ، بما في ذلك ملفات JPEG و MP4 النموذجية ، ولكن أيضًا أشياء أكثر غرابة مثل ملفات TIFF و SVG و AVI القديمة متعددة الصفحات والمزيد! يقوم بمسح مجموعة الوسائط الخاصة بك لتحديد الصور المتحركة, الإستعراضات (المعروف أيضًا باسم الصور البانورامية), 360 درجة مقاطع الفيديو, إلى جانب GeoTIFF الملفات. -Navigation and search is an important part of Aves. The goal is for users to easily flow from albums to photos to tags to maps, etc. +الملاحة والبحث جزء مهم من Avesالهدف هو أن يكون بإمكان المستخدمين التنقل بسهولة من الألبومات إلى الصور إلى الوسوم إلى الخرائط، وما إلى ذلك.. -Aves integrates with Android (from KitKat to Android 13, including Android TV) with features such as widgets, app shortcuts, screen saver and global search handling. It also works as a media viewer and picker. \ No newline at end of file +Avesتتكامل مع نظام Android (من KitKat إلى Android 14، بما في ذلك Android TV) مع ميزات مثلs الودجتس, اختصارات التطبيق, حافظة الشاشة والبحث العالمي التعامل معه. كما أنه يعمل كـ عارض واختار لوسائط (ملفات الوسائط). diff --git a/fastlane/metadata/android/ar/images/featureGraphic.png b/fastlane/metadata/android/ar/images/featureGraphic.png new file mode 100644 index 000000000..7204bd0d6 Binary files /dev/null and b/fastlane/metadata/android/ar/images/featureGraphic.png differ diff --git a/fastlane/metadata/android/ar/images/phoneScreenshots/1.png b/fastlane/metadata/android/ar/images/phoneScreenshots/1.png new file mode 100644 index 000000000..c53c38202 Binary files /dev/null and b/fastlane/metadata/android/ar/images/phoneScreenshots/1.png differ diff --git a/fastlane/metadata/android/ar/images/phoneScreenshots/2.png b/fastlane/metadata/android/ar/images/phoneScreenshots/2.png new file mode 100644 index 000000000..b18c82d1e Binary files /dev/null and b/fastlane/metadata/android/ar/images/phoneScreenshots/2.png differ diff --git a/fastlane/metadata/android/ar/images/phoneScreenshots/3.png b/fastlane/metadata/android/ar/images/phoneScreenshots/3.png new file mode 100644 index 000000000..50a8c7a8d Binary files /dev/null and b/fastlane/metadata/android/ar/images/phoneScreenshots/3.png differ diff --git a/fastlane/metadata/android/ar/images/phoneScreenshots/4.png b/fastlane/metadata/android/ar/images/phoneScreenshots/4.png new file mode 100644 index 000000000..9cb4a4ed2 Binary files /dev/null and b/fastlane/metadata/android/ar/images/phoneScreenshots/4.png differ diff --git a/fastlane/metadata/android/ar/images/phoneScreenshots/5.png b/fastlane/metadata/android/ar/images/phoneScreenshots/5.png new file mode 100644 index 000000000..bf90202cd Binary files /dev/null and b/fastlane/metadata/android/ar/images/phoneScreenshots/5.png differ diff --git a/fastlane/metadata/android/ar/images/phoneScreenshots/6.png b/fastlane/metadata/android/ar/images/phoneScreenshots/6.png new file mode 100644 index 000000000..e46abd530 Binary files /dev/null and b/fastlane/metadata/android/ar/images/phoneScreenshots/6.png differ diff --git a/fastlane/metadata/android/ar/images/phoneScreenshots/7.png b/fastlane/metadata/android/ar/images/phoneScreenshots/7.png new file mode 100644 index 000000000..07d4603b9 Binary files /dev/null and b/fastlane/metadata/android/ar/images/phoneScreenshots/7.png differ diff --git a/fastlane/metadata/android/ar/short_description.txt b/fastlane/metadata/android/ar/short_description.txt index 3cbcb03a4..24ef32619 100644 --- a/fastlane/metadata/android/ar/short_description.txt +++ b/fastlane/metadata/android/ar/short_description.txt @@ -1 +1 @@ -المعرض ومستكشف البيانات الوصفية \ No newline at end of file +مستعرض الصور والبيانات \ No newline at end of file diff --git a/fastlane/metadata/android/be/full_description.txt b/fastlane/metadata/android/be/full_description.txt index 9f6558c1a..9be4265ce 100644 --- a/fastlane/metadata/android/be/full_description.txt +++ b/fastlane/metadata/android/be/full_description.txt @@ -2,4 +2,4 @@ Навігацыя і пошук з'яўляюцца важнай часткай Aves. Мэта складаецца ў тым, каб карыстальнікі лёгка пераходзілі ад альбомаў да фатаграфій да тэгаў да карт і г.д. -Aves інтэгруецца з Android (ад KitKat да Android 13, уключаючы Android TV) з такімі функцыямі, як віджэты, ярлыкі праграм, застаўка і апрацоўка глабальнага пошуку. Ён таксама працуе як сродак прагляду і выбару мультымедыя. \ No newline at end of file +Aves інтэгруецца з Android (ад KitKat да Android 14, уключаючы Android TV) з такімі функцыямі, як віджэты, ярлыкі праграм, застаўка і апрацоўка глабальнага пошуку. Ён таксама працуе як сродак прагляду і выбару мультымедыя. diff --git a/fastlane/metadata/android/be/images/featureGraphic.png b/fastlane/metadata/android/be/images/featureGraphic.png new file mode 100644 index 000000000..c1455009b Binary files /dev/null and b/fastlane/metadata/android/be/images/featureGraphic.png differ diff --git a/fastlane/metadata/android/be/images/phoneScreenshots/1.png b/fastlane/metadata/android/be/images/phoneScreenshots/1.png new file mode 100644 index 000000000..6b176ae33 Binary files /dev/null and b/fastlane/metadata/android/be/images/phoneScreenshots/1.png differ diff --git a/fastlane/metadata/android/be/images/phoneScreenshots/2.png b/fastlane/metadata/android/be/images/phoneScreenshots/2.png new file mode 100644 index 000000000..d22c0a2c9 Binary files /dev/null and b/fastlane/metadata/android/be/images/phoneScreenshots/2.png differ diff --git a/fastlane/metadata/android/be/images/phoneScreenshots/3.png b/fastlane/metadata/android/be/images/phoneScreenshots/3.png new file mode 100644 index 000000000..7ebc7d837 Binary files /dev/null and b/fastlane/metadata/android/be/images/phoneScreenshots/3.png differ diff --git a/fastlane/metadata/android/be/images/phoneScreenshots/4.png b/fastlane/metadata/android/be/images/phoneScreenshots/4.png new file mode 100644 index 000000000..cfa4a9727 Binary files /dev/null and b/fastlane/metadata/android/be/images/phoneScreenshots/4.png differ diff --git a/fastlane/metadata/android/be/images/phoneScreenshots/5.png b/fastlane/metadata/android/be/images/phoneScreenshots/5.png new file mode 100644 index 000000000..fc8b1c9bb Binary files /dev/null and b/fastlane/metadata/android/be/images/phoneScreenshots/5.png differ diff --git a/fastlane/metadata/android/be/images/phoneScreenshots/6.png b/fastlane/metadata/android/be/images/phoneScreenshots/6.png new file mode 100644 index 000000000..0567e896e Binary files /dev/null and b/fastlane/metadata/android/be/images/phoneScreenshots/6.png differ diff --git a/fastlane/metadata/android/be/images/phoneScreenshots/7.png b/fastlane/metadata/android/be/images/phoneScreenshots/7.png new file mode 100644 index 000000000..e440673f5 Binary files /dev/null and b/fastlane/metadata/android/be/images/phoneScreenshots/7.png differ diff --git a/fastlane/metadata/android/bn/full_description.txt b/fastlane/metadata/android/bn/full_description.txt index 47d36a004..bae3cb8be 100644 --- a/fastlane/metadata/android/bn/full_description.txt +++ b/fastlane/metadata/android/bn/full_description.txt @@ -2,4 +2,4 @@ নেভিগেশন এবং সার্চ আভেস এর একটি গুরুত্বপূর্ণ অংশ। লক্ষ্য হল ইউসার যাতে সহজেই অ্যালবাম, ফটো, ট্যাগ, ম্যাপ ইত্যাদিতে স্থানান্তর করতে পারে। -উইজেট, অ্যাপ শর্টকাট, স্ক্রিন সেভারের এবং গ্লোবাল সার্চ এর মতো বৈশিষ্ট্য সহ, আভেস অ্যান্ড্রয়েড এর সাথে সংহত হতে পারে (কিট ক্যাট থেকে অ্যান্ড্রয়েড ১৩, অ্যান্ড্রয়েড টিভি সহ)। এটি একটি মিডিয়া উপস্থাপক এবং বাছাইকারী হিসেবেও কাজ করে। \ No newline at end of file +উইজেট, অ্যাপ শর্টকাট, স্ক্রিন সেভারের এবং গ্লোবাল সার্চ এর মতো বৈশিষ্ট্য সহ, আভেস অ্যান্ড্রয়েড এর সাথে সংহত হতে পারে (কিট ক্যাট থেকে অ্যান্ড্রয়েড ১৩, অ্যান্ড্রয়েড টিভি সহ)। এটি একটি মিডিয়া উপস্থাপক এবং বাছাইকারী হিসেবেও কাজ করে। diff --git a/fastlane/metadata/android/ckb/full_description.txt b/fastlane/metadata/android/ckb/full_description.txt index 6c92748f8..6b96ec3ea 100644 --- a/fastlane/metadata/android/ckb/full_description.txt +++ b/fastlane/metadata/android/ckb/full_description.txt @@ -2,4 +2,4 @@ Navigation and search is an important part of Aves. The goal is for users to easily flow from albums to photos to tags to maps, etc. -Aves integrates with Android (from KitKat to Android 13, including Android TV) with features such as widgets, app shortcuts, screen saver and global search handling. It also works as a media viewer and picker. \ No newline at end of file +Aves integrates with Android (from KitKat to Android 14, including Android TV) with features such as widgets, app shortcuts, screen saver and global search handling. It also works as a media viewer and picker. diff --git a/fastlane/metadata/android/cs/full_description.txt b/fastlane/metadata/android/cs/full_description.txt index 2ca7137cc..63000d41a 100644 --- a/fastlane/metadata/android/cs/full_description.txt +++ b/fastlane/metadata/android/cs/full_description.txt @@ -2,4 +2,4 @@ Navigace a vyhledávání jsou důležitou součástí aplikace Aves. Cílem je, aby uživatelé jednoduše přecházeli z alb k fotografiím, albům, mapám, atd. -Aves podporuje Android (od verze KitKat po Android 13, včetně Android TV) s funkcemi jako jsou widgety, zkratky aplikací, spořič displeje a globální vyhledávání. Rovněž jej lze použít pro prohlížení a výběr médií. \ No newline at end of file +Aves podporuje Android (od verze KitKat po Android 14, včetně Android TV) s funkcemi jako jsou widgety, zkratky aplikací, spořič displeje a globální vyhledávání. Rovněž jej lze použít pro prohlížení a výběr médií. diff --git a/fastlane/metadata/android/de/full_description.txt b/fastlane/metadata/android/de/full_description.txt index 7cfc6826c..3b78e40f8 100644 --- a/fastlane/metadata/android/de/full_description.txt +++ b/fastlane/metadata/android/de/full_description.txt @@ -2,4 +2,4 @@ Navigation und Suche ist ein wichtiger Bestandteil von Aves. Das Ziel besteht darin, dass Benutzer problemlos von Alben zu Fotos zu Tags zu Karten usw. wechseln können. -Aves lässt sich mit Android (von API 19 bis 33, d. h. von KitKat bis Android 13) mit Funktionen wie App-Verknüpfungen und globaler Suche integrieren. Es funktioniert auch als Medienbetrachter und -auswahl. \ No newline at end of file +Aves lässt sich mit Android (von API 19 bis 34, d. h. von KitKat bis Android 14) mit Funktionen wie App-Verknüpfungen und globaler Suche integrieren. Es funktioniert auch als Medienbetrachter und -auswahl. diff --git a/fastlane/metadata/android/el/full_description.txt b/fastlane/metadata/android/el/full_description.txt index c183af4c3..c7ee2b244 100644 --- a/fastlane/metadata/android/el/full_description.txt +++ b/fastlane/metadata/android/el/full_description.txt @@ -2,4 +2,4 @@ Η πλοήγηση και η αναζήτηση αποτελούν σημαντικό μέρος της εφαρμογής Aves. Ο στόχος της εφαρμογής είναι να παρέχει στους χρήστες εύκολη και γρήγορη πρόσβαση στα άλμπουμ, σε φωτογραφίες, ετικέτες, χάρτες κ.λπ. -Η εφαρμογή Aves εγκαθίσταται στο λογισμικό Android (συμβατότητα από API 19 έως 33, δηλαδή από KitKat έως Android 13) με δυνατότητες όπως γραφικά στοιχεία, συντομεύσεις, προφύλαξη οθόνης και global search. Μπορεί επίσης να χρησιμοποιηθεί ως εφαρμογή προβολής και επιλογής πολυμέσων. \ No newline at end of file +Η εφαρμογή Aves εγκαθίσταται στο λογισμικό Android (συμβατότητα από API 19 έως 34, δηλαδή από KitKat έως Android 14) με δυνατότητες όπως γραφικά στοιχεία, συντομεύσεις, προφύλαξη οθόνης και global search. Μπορεί επίσης να χρησιμοποιηθεί ως εφαρμογή προβολής και επιλογής πολυμέσων. diff --git a/fastlane/metadata/android/en-US/changelogs/110.txt b/fastlane/metadata/android/en-US/changelogs/110.txt new file mode 100644 index 000000000..69b5f63e7 --- /dev/null +++ b/fastlane/metadata/android/en-US/changelogs/110.txt @@ -0,0 +1,4 @@ +In v1.10.1: +- JPEG MPF support +- enjoy the app in Arabic & Belarusian +Full changelog available on GitHub \ No newline at end of file diff --git a/fastlane/metadata/android/en-US/changelogs/11001.txt b/fastlane/metadata/android/en-US/changelogs/11001.txt new file mode 100644 index 000000000..69b5f63e7 --- /dev/null +++ b/fastlane/metadata/android/en-US/changelogs/11001.txt @@ -0,0 +1,4 @@ +In v1.10.1: +- JPEG MPF support +- enjoy the app in Arabic & Belarusian +Full changelog available on GitHub \ No newline at end of file diff --git a/fastlane/metadata/android/en-US/full_description.txt b/fastlane/metadata/android/en-US/full_description.txt index 6c92748f8..6b96ec3ea 100644 --- a/fastlane/metadata/android/en-US/full_description.txt +++ b/fastlane/metadata/android/en-US/full_description.txt @@ -2,4 +2,4 @@ Navigation and search is an important part of Aves. The goal is for users to easily flow from albums to photos to tags to maps, etc. -Aves integrates with Android (from KitKat to Android 13, including Android TV) with features such as widgets, app shortcuts, screen saver and global search handling. It also works as a media viewer and picker. \ No newline at end of file +Aves integrates with Android (from KitKat to Android 14, including Android TV) with features such as widgets, app shortcuts, screen saver and global search handling. It also works as a media viewer and picker. diff --git a/fastlane/metadata/android/es-MX/full_description.txt b/fastlane/metadata/android/es-MX/full_description.txt index 01ef58d76..9d58d9cfb 100644 --- a/fastlane/metadata/android/es-MX/full_description.txt +++ b/fastlane/metadata/android/es-MX/full_description.txt @@ -2,4 +2,4 @@ La navegación y búsqueda son las partes más importantes de Aves. Su propósito es que los usuarios puedan fácilmente ir de álbumes a fotos, etiquetas, mapas, etc. -Aves se integra con Android (desde KitKat hasta Android 13, incluido Android TV) con funciones como complementos, accesos directos a aplicaciones, protector de pantalla y búsqueda global. También funciona como un visor y selector de medios. \ No newline at end of file +Aves se integra con Android (desde KitKat hasta Android 14, incluido Android TV) con funciones como complementos, accesos directos a aplicaciones, protector de pantalla y búsqueda global. También funciona como un visor y selector de medios. diff --git a/fastlane/metadata/android/eu/full_description.txt b/fastlane/metadata/android/eu/full_description.txt index c64149f18..63af644c6 100644 --- a/fastlane/metadata/android/eu/full_description.txt +++ b/fastlane/metadata/android/eu/full_description.txt @@ -2,4 +2,4 @@ Nabigazioa eta bilaketa Aves aplikazioaren zati garrantzitsu bat da. Helburua, erabiltzaileek albumetatik argazkietara, etiketetara, mapetara, etab. modu errazean mugi ahal izatea da. -Aves Androidera (KitKatetik Android 13ra, Android TV barne) egiten da ezaugarri ugarirekin: widgetak, aplikazioko lasterbideak, pantaila-babeslea eta bilaketa globala. Baita ere, media-bisore edo -hautagailu bezala erabil daiteke. \ No newline at end of file +Aves Androidera (KitKatetik Android 14ra, Android TV barne) egiten da ezaugarri ugarirekin: widgetak, aplikazioko lasterbideak, pantaila-babeslea eta bilaketa globala. Baita ere, media-bisore edo -hautagailu bezala erabil daiteke. diff --git a/fastlane/metadata/android/fa/full_description.txt b/fastlane/metadata/android/fa/full_description.txt index 6c92748f8..6b96ec3ea 100644 --- a/fastlane/metadata/android/fa/full_description.txt +++ b/fastlane/metadata/android/fa/full_description.txt @@ -2,4 +2,4 @@ Navigation and search is an important part of Aves. The goal is for users to easily flow from albums to photos to tags to maps, etc. -Aves integrates with Android (from KitKat to Android 13, including Android TV) with features such as widgets, app shortcuts, screen saver and global search handling. It also works as a media viewer and picker. \ No newline at end of file +Aves integrates with Android (from KitKat to Android 14, including Android TV) with features such as widgets, app shortcuts, screen saver and global search handling. It also works as a media viewer and picker. diff --git a/fastlane/metadata/android/fi/full_description.txt b/fastlane/metadata/android/fi/full_description.txt index 6c92748f8..6b96ec3ea 100644 --- a/fastlane/metadata/android/fi/full_description.txt +++ b/fastlane/metadata/android/fi/full_description.txt @@ -2,4 +2,4 @@ Navigation and search is an important part of Aves. The goal is for users to easily flow from albums to photos to tags to maps, etc. -Aves integrates with Android (from KitKat to Android 13, including Android TV) with features such as widgets, app shortcuts, screen saver and global search handling. It also works as a media viewer and picker. \ No newline at end of file +Aves integrates with Android (from KitKat to Android 14, including Android TV) with features such as widgets, app shortcuts, screen saver and global search handling. It also works as a media viewer and picker. diff --git a/fastlane/metadata/android/fr/full_description.txt b/fastlane/metadata/android/fr/full_description.txt index 0c83cfb83..9358d7cf1 100644 --- a/fastlane/metadata/android/fr/full_description.txt +++ b/fastlane/metadata/android/fr/full_description.txt @@ -2,4 +2,4 @@ La navigation et la recherche sont une partie importante d’Aves. Le but est que les utilisateurs puissent passer facilement des albums aux photos, des photos aux tags, des tags aux cartes, etc. -Aves s’intègre avec Android (de KitKat à Android 13, y compris Android TV) avec des fonctionnalités telles que les widgets, les raccourcis d’application, économiseur d’écran et la recherche globale. Il est également possible de l’utiliser comme visionneuse et sélecteur de médias. \ No newline at end of file +Aves s’intègre avec Android (de KitKat à Android 14, y compris Android TV) avec des fonctionnalités telles que les widgets, les raccourcis d’application, économiseur d’écran et la recherche globale. Il est également possible de l’utiliser comme visionneuse et sélecteur de médias. diff --git a/fastlane/metadata/android/gl/full_description.txt b/fastlane/metadata/android/gl/full_description.txt index 548d3fe17..6e3b9f2cf 100644 --- a/fastlane/metadata/android/gl/full_description.txt +++ b/fastlane/metadata/android/gl/full_description.txt @@ -2,4 +2,4 @@ A navegación e busca é unha parte importante de Aves. O obxectivo é que os usuarios poidan fluír facilmente de álbums a fotos, a etiquetas a mapas, etc. -Aves intégrase con Android (desde KitKat ata Android 13, incluíndo Android TV) con funcións como complementos, atallos de aplicacións, salvapantallas e busca global. Tamén funciona como visor e selector de medios. \ No newline at end of file +Aves intégrase con Android (desde KitKat ata Android 14, incluíndo Android TV) con funcións como complementos, atallos de aplicacións, salvapantallas e busca global. Tamén funciona como visor e selector de medios. diff --git a/fastlane/metadata/android/he/full_description.txt b/fastlane/metadata/android/he/full_description.txt index 6c92748f8..6b96ec3ea 100644 --- a/fastlane/metadata/android/he/full_description.txt +++ b/fastlane/metadata/android/he/full_description.txt @@ -2,4 +2,4 @@ Navigation and search is an important part of Aves. The goal is for users to easily flow from albums to photos to tags to maps, etc. -Aves integrates with Android (from KitKat to Android 13, including Android TV) with features such as widgets, app shortcuts, screen saver and global search handling. It also works as a media viewer and picker. \ No newline at end of file +Aves integrates with Android (from KitKat to Android 14, including Android TV) with features such as widgets, app shortcuts, screen saver and global search handling. It also works as a media viewer and picker. diff --git a/fastlane/metadata/android/hi/full_description.txt b/fastlane/metadata/android/hi/full_description.txt index 6c92748f8..6b96ec3ea 100644 --- a/fastlane/metadata/android/hi/full_description.txt +++ b/fastlane/metadata/android/hi/full_description.txt @@ -2,4 +2,4 @@ Navigation and search is an important part of Aves. The goal is for users to easily flow from albums to photos to tags to maps, etc. -Aves integrates with Android (from KitKat to Android 13, including Android TV) with features such as widgets, app shortcuts, screen saver and global search handling. It also works as a media viewer and picker. \ No newline at end of file +Aves integrates with Android (from KitKat to Android 14, including Android TV) with features such as widgets, app shortcuts, screen saver and global search handling. It also works as a media viewer and picker. diff --git a/fastlane/metadata/android/hu/full_description.txt b/fastlane/metadata/android/hu/full_description.txt index 65ec60bf4..614f6266e 100644 --- a/fastlane/metadata/android/hu/full_description.txt +++ b/fastlane/metadata/android/hu/full_description.txt @@ -2,4 +2,4 @@ Az Aves mindenféle képet és videót képes kezelni, beleértve a tipik A navigáció és a keresés fontos része az Aves-nek. A cél, hogy a felhasználók egyszerűen tudjanak váltani az albumokról a fotókra, címkézni vagy helyadatokkal ellátni az elemeket, stb. -Az Aves beépül az Android-ba (a KitKat-tól az Android 13-ig, beleértve az Android TV-t) olyan funkciókkal, mint a widgetek, alkalmazás parancsikonok, képernyővédő és globális keresés kezelése. Média fájlok megnyitására és kezelésére is használható. \ No newline at end of file +Az Aves beépül az Android-ba (a KitKat-tól az Android 14-ig, beleértve az Android TV-t) olyan funkciókkal, mint a widgetek, alkalmazás parancsikonok, képernyővédő és globális keresés kezelése. Média fájlok megnyitására és kezelésére is használható. diff --git a/fastlane/metadata/android/id/full_description.txt b/fastlane/metadata/android/id/full_description.txt index 3c18c062f..c0d9d1c9a 100644 --- a/fastlane/metadata/android/id/full_description.txt +++ b/fastlane/metadata/android/id/full_description.txt @@ -2,4 +2,4 @@ Navigasi dan pencarian merupakan bagian penting dari Aves. Tujuannya adalah agar pengguna dengan mudah mengalir dari album ke foto ke tag ke peta, dll. -Aves mengintegrasi dengan Android (dari Kitkat ke Android 13) dengan fitur-fitur seperti pintasan aplikasi, jalan pintas aplikasi, screen saver dan pencarian global penanganan. Ini juga berfungsi sebagai penampil dan pemilih media. \ No newline at end of file +Aves mengintegrasi dengan Android (dari Kitkat ke Android 14) dengan fitur-fitur seperti pintasan aplikasi, jalan pintas aplikasi, screen saver dan pencarian global penanganan. Ini juga berfungsi sebagai penampil dan pemilih media. diff --git a/fastlane/metadata/android/is/full_description.txt b/fastlane/metadata/android/is/full_description.txt index 6c92748f8..6b96ec3ea 100644 --- a/fastlane/metadata/android/is/full_description.txt +++ b/fastlane/metadata/android/is/full_description.txt @@ -2,4 +2,4 @@ Navigation and search is an important part of Aves. The goal is for users to easily flow from albums to photos to tags to maps, etc. -Aves integrates with Android (from KitKat to Android 13, including Android TV) with features such as widgets, app shortcuts, screen saver and global search handling. It also works as a media viewer and picker. \ No newline at end of file +Aves integrates with Android (from KitKat to Android 14, including Android TV) with features such as widgets, app shortcuts, screen saver and global search handling. It also works as a media viewer and picker. diff --git a/fastlane/metadata/android/it/full_description.txt b/fastlane/metadata/android/it/full_description.txt index 463c23554..0b1afa53f 100644 --- a/fastlane/metadata/android/it/full_description.txt +++ b/fastlane/metadata/android/it/full_description.txt @@ -2,4 +2,4 @@ Navigazione e ricerca sono una parte importante di Aves. L'obiettivo è che gli utenti passino facilmente dagli album alle foto, ai tag, alle mappe, ecc. -Aves si integra con Android (da KitKat ad Android 13, anche Android TV) con funzionalità come widget, scorciatoie app, salvaschermo e gestione della ricerca globale. Funziona anche come visualizzazione e raccolta di media. \ No newline at end of file +Aves si integra con Android (da KitKat ad Android 14, anche Android TV) con funzionalità come widget, scorciatoie app, salvaschermo e gestione della ricerca globale. Funziona anche come visualizzazione e raccolta di media. diff --git a/fastlane/metadata/android/ja/full_description.txt b/fastlane/metadata/android/ja/full_description.txt index 996e794a5..bd93f6622 100644 --- a/fastlane/metadata/android/ja/full_description.txt +++ b/fastlane/metadata/android/ja/full_description.txt @@ -2,4 +2,4 @@ ナビゲーションと検索は、Avesの重要な部分です。アルバムから写真、タグ、地図などへ簡単に移動できます。 -Avesは、アプリショートカットグローバル検索などの機能を、Android(API 19から33まで、つまりAndroid 4.4から13 Lまで)と統合しています。また、メディアビューワーメディアピッカーとしても機能します。 \ No newline at end of file +Avesは、アプリショートカットグローバル検索などの機能を、Android(API 19から34まで、つまりAndroid 4.4から14 Lまで)と統合しています。また、メディアビューワーメディアピッカーとしても機能します。 diff --git a/fastlane/metadata/android/kn/full_description.txt b/fastlane/metadata/android/kn/full_description.txt index 6c92748f8..6b96ec3ea 100644 --- a/fastlane/metadata/android/kn/full_description.txt +++ b/fastlane/metadata/android/kn/full_description.txt @@ -2,4 +2,4 @@ Navigation and search is an important part of Aves. The goal is for users to easily flow from albums to photos to tags to maps, etc. -Aves integrates with Android (from KitKat to Android 13, including Android TV) with features such as widgets, app shortcuts, screen saver and global search handling. It also works as a media viewer and picker. \ No newline at end of file +Aves integrates with Android (from KitKat to Android 14, including Android TV) with features such as widgets, app shortcuts, screen saver and global search handling. It also works as a media viewer and picker. diff --git a/fastlane/metadata/android/ko/full_description.txt b/fastlane/metadata/android/ko/full_description.txt index 6c92748f8..6b96ec3ea 100644 --- a/fastlane/metadata/android/ko/full_description.txt +++ b/fastlane/metadata/android/ko/full_description.txt @@ -2,4 +2,4 @@ Navigation and search is an important part of Aves. The goal is for users to easily flow from albums to photos to tags to maps, etc. -Aves integrates with Android (from KitKat to Android 13, including Android TV) with features such as widgets, app shortcuts, screen saver and global search handling. It also works as a media viewer and picker. \ No newline at end of file +Aves integrates with Android (from KitKat to Android 14, including Android TV) with features such as widgets, app shortcuts, screen saver and global search handling. It also works as a media viewer and picker. diff --git a/fastlane/metadata/android/lt/full_description.txt b/fastlane/metadata/android/lt/full_description.txt index db97f4f98..246bda3c0 100644 --- a/fastlane/metadata/android/lt/full_description.txt +++ b/fastlane/metadata/android/lt/full_description.txt @@ -2,4 +2,4 @@ Naršymas ir paieška yra svarbi „Aves” dalis. Tikslas yra, kad vartotojai galėtų lengvai pereiti nuo albumų prie nuotraukų, žymų, žemėlapių ir kt. -„Aves” integruojasi su „Android” (nuo 19 iki 33 API, t. y. nuo „KitKat” iki 13 versijos „Android”) su tokiomis funkcijomis kaip valdiklių, programėlių nuorodų , ekrano užsklandų ir globalios paieškos palaikymu. Ji taip pat veikia kaip medijos peržiūros priemonė ir rinkiklis. \ No newline at end of file +„Aves” integruojasi su „Android” (nuo 19 iki 34 API, t. y. nuo „KitKat” iki 14 versijos „Android”) su tokiomis funkcijomis kaip valdiklių, programėlių nuorodų , ekrano užsklandų ir globalios paieškos palaikymu. Ji taip pat veikia kaip medijos peržiūros priemonė ir rinkiklis. diff --git a/fastlane/metadata/android/ml/full_description.txt b/fastlane/metadata/android/ml/full_description.txt index 6c92748f8..6b96ec3ea 100644 --- a/fastlane/metadata/android/ml/full_description.txt +++ b/fastlane/metadata/android/ml/full_description.txt @@ -2,4 +2,4 @@ Navigation and search is an important part of Aves. The goal is for users to easily flow from albums to photos to tags to maps, etc. -Aves integrates with Android (from KitKat to Android 13, including Android TV) with features such as widgets, app shortcuts, screen saver and global search handling. It also works as a media viewer and picker. \ No newline at end of file +Aves integrates with Android (from KitKat to Android 14, including Android TV) with features such as widgets, app shortcuts, screen saver and global search handling. It also works as a media viewer and picker. diff --git a/fastlane/metadata/android/my/full_description.txt b/fastlane/metadata/android/my/full_description.txt index ff89ddf0b..44d1a23cf 100644 --- a/fastlane/metadata/android/my/full_description.txt +++ b/fastlane/metadata/android/my/full_description.txt @@ -2,4 +2,4 @@ အလွယ်တကူ ရှာဖွေကြည့်ရှုနိုင်တာက Aves ရဲ့ အဓိကကျတဲ့အစိတ်အပိုင်းတစ်ခုဖြစ်ပါတယ်။ အသုံးပြုသူတွေကို အယ်လ်ဘမ်တွေကနေ ပုံတွေ၊ ပုံတွေကနေ tag တွေ၊ tag တွေကနေ မြေပုံတွေ၊ အစရှိသဖြင့် အလွယ်လေးကူးပြောင်းနိုင်စေဖို့က Aves ရဲ့ ပန်းတိုင်ဖြစ်ပါတယ်။ -Aves ဟာ Android (KitKat ကနေ Android 13 အထိ၊ Android တီဗီအပါအဝင်) ဖြင့်ပေါင်းစပ်ပြီး ဝစ်ဂျက်တွေအက်ပ်ဖြတ်လမ်းတိုတွေscreen saver တွေနဲ့ နေရာအနှံ့ရှာဖွေမှုတွေကိုပါ ကိုင်တွယ်နိုင်ပါတယ်။ ဒါ့အပြင် မီဒီယာကြည့်ဖို့၊ မီဒီယာရွေးချယ်ဖို့အတွက်လည်း သုံးလို့ရပါသေးတယ်။ \ No newline at end of file +Aves ဟာ Android (KitKat ကနေ Android 14 အထိ၊ Android တီဗီအပါအဝင်) ဖြင့်ပေါင်းစပ်ပြီး ဝစ်ဂျက်တွေအက်ပ်ဖြတ်လမ်းတိုတွေscreen saver တွေနဲ့ နေရာအနှံ့ရှာဖွေမှုတွေကိုပါ ကိုင်တွယ်နိုင်ပါတယ်။ ဒါ့အပြင် မီဒီယာကြည့်ဖို့၊ မီဒီယာရွေးချယ်ဖို့အတွက်လည်း သုံးလို့ရပါသေးတယ်။ diff --git a/fastlane/metadata/android/nb-NO/full_description.txt b/fastlane/metadata/android/nb-NO/full_description.txt index b2259273d..9f4e596b0 100644 --- a/fastlane/metadata/android/nb-NO/full_description.txt +++ b/fastlane/metadata/android/nb-NO/full_description.txt @@ -2,4 +2,4 @@ Navigasjon og søk er en viktig del av Aves. Målet er at brukere enkelt skal kunne ta seg fra album, til bilder, til etiketter, til kart, osv. -Aves integrerer seg med Android (fra API 19 til 33, altså fra KitKat til Android 13) med funksjoner som f.eks. miniprogrammer, programsnarveier, skjermsparer og søk i hele programmet. Det fungerer også som mediaviser og utvelger. \ No newline at end of file +Aves integrerer seg med Android (fra API 19 til 34, altså fra KitKat til Android 14) med funksjoner som f.eks. miniprogrammer, programsnarveier, skjermsparer og søk i hele programmet. Det fungerer også som mediaviser og utvelger. diff --git a/fastlane/metadata/android/nl/full_description.txt b/fastlane/metadata/android/nl/full_description.txt index 8d13866ce..11f348f36 100644 --- a/fastlane/metadata/android/nl/full_description.txt +++ b/fastlane/metadata/android/nl/full_description.txt @@ -2,4 +2,4 @@ Navigatie en zoeken is een belangrijk onderdeel van Aves. Het doel is dat gebruikers gemakkelijk van albums naar foto's naar tags naar kaarten enz. kunnen gaan. -Aves integrates with Android (from KitKat to Android 13, including Android TV) with features such as widgets, app shortcuts, screen saver and global search handling. It also works as a media viewer and picker. \ No newline at end of file +Aves integrates with Android (from KitKat to Android 14, including Android TV) with features such as widgets, app shortcuts, screen saver and global search handling. It also works as a media viewer and picker. diff --git a/fastlane/metadata/android/nn/full_description.txt b/fastlane/metadata/android/nn/full_description.txt index ed514a8df..0ecaa08de 100644 --- a/fastlane/metadata/android/nn/full_description.txt +++ b/fastlane/metadata/android/nn/full_description.txt @@ -2,4 +2,4 @@ Navigering og søk har mykje å sei i Aves. Målet er at ein skal lett kunne gå ifrå album, til bilete, til merkelappar, til kart, osv. -Aves integrates with Android (from KitKat to Android 13, including Android TV) with features such as widgets, app shortcuts, screen saver and global search handling. It also works as a media viewer and picker. \ No newline at end of file +Aves integrates with Android (from KitKat to Android 14, including Android TV) with features such as widgets, app shortcuts, screen saver and global search handling. It also works as a media viewer and picker. diff --git a/fastlane/metadata/android/or/full_description.txt b/fastlane/metadata/android/or/full_description.txt index 6c92748f8..6b96ec3ea 100644 --- a/fastlane/metadata/android/or/full_description.txt +++ b/fastlane/metadata/android/or/full_description.txt @@ -2,4 +2,4 @@ Navigation and search is an important part of Aves. The goal is for users to easily flow from albums to photos to tags to maps, etc. -Aves integrates with Android (from KitKat to Android 13, including Android TV) with features such as widgets, app shortcuts, screen saver and global search handling. It also works as a media viewer and picker. \ No newline at end of file +Aves integrates with Android (from KitKat to Android 14, including Android TV) with features such as widgets, app shortcuts, screen saver and global search handling. It also works as a media viewer and picker. diff --git a/fastlane/metadata/android/pl/full_description.txt b/fastlane/metadata/android/pl/full_description.txt index c10a1a6c6..e0f0b7f36 100644 --- a/fastlane/metadata/android/pl/full_description.txt +++ b/fastlane/metadata/android/pl/full_description.txt @@ -2,4 +2,4 @@ Nawigacja i wyszukiwanie jest ważną częścią Aves. Celem jest aby użytkownicy mogli łatwo przechodzić od albumów do zdjęć, tagów, map itd. -Aves integruje się z Androidem (od API 19 do 33, czyli od KitKata do Androida 13) z funkcjami takimi jak widżety, skróty do aplikacji, wygaszacz ekranu i obsługa globalnego wyszukiwania. Działa również jako przeglądarka i selektor mediów. \ No newline at end of file +Aves integruje się z Androidem (od API 19 do 34, czyli od KitKata do Androida 14) z funkcjami takimi jak widżety, skróty do aplikacji, wygaszacz ekranu i obsługa globalnego wyszukiwania. Działa również jako przeglądarka i selektor mediów. diff --git a/fastlane/metadata/android/pt-BR/full_description.txt b/fastlane/metadata/android/pt-BR/full_description.txt index 9cae013fe..a0550b001 100644 --- a/fastlane/metadata/android/pt-BR/full_description.txt +++ b/fastlane/metadata/android/pt-BR/full_description.txt @@ -2,4 +2,4 @@ Navegação e pesquisa é uma parte importante do Aves. O objetivo é que os usuários fluam facilmente de álbuns para fotos, etiquetas, mapas, etc. -Aves integra com Android (de KitKat até Android 13, incluindo TVs Android) com recursos como widgets, atalhos de apps, protetor de tela e pesquisa global. Também funciona como um visualizador e selecionador de mídia. \ No newline at end of file +Aves integra com Android (de KitKat até Android 14, incluindo TVs Android) com recursos como widgets, atalhos de apps, protetor de tela e pesquisa global. Também funciona como um visualizador e selecionador de mídia. diff --git a/fastlane/metadata/android/ro/full_description.txt b/fastlane/metadata/android/ro/full_description.txt index 3914872df..e76ce6d7c 100644 --- a/fastlane/metadata/android/ro/full_description.txt +++ b/fastlane/metadata/android/ro/full_description.txt @@ -2,4 +2,4 @@ Navigația și căutarea sunt o parte importantă a Aves. Scopul este ca utilizatorii să treacă cu ușurință de la albume la fotografii la etichete la hărți etc. -Aves se integrează cu Android (începând de la API 19 la 33, adică de la KitKat la Android 13) cu funcții precum widget-uri, comenzi rapide pentru aplicații, protector de ecran și gestionarea căutării globale. De asemenea, funcționează ca vizionator și selector de conținut media. \ No newline at end of file +Aves se integrează cu Android (începând de la API 19 la 34, adică de la KitKat la Android 14) cu funcții precum widget-uri, comenzi rapide pentru aplicații, protector de ecran și gestionarea căutării globale. De asemenea, funcționează ca vizionator și selector de conținut media. diff --git a/fastlane/metadata/android/ru/full_description.txt b/fastlane/metadata/android/ru/full_description.txt index 158e533fd..d09a7d4de 100644 --- a/fastlane/metadata/android/ru/full_description.txt +++ b/fastlane/metadata/android/ru/full_description.txt @@ -2,4 +2,4 @@ Навигация и поиск важные части Aves. Пользователи могут легко переходить от альбомов к фотографиям, тэгам, картам и т.д. -Aves интегрируется с Android (от KitKat до Android 13, включая Android TV) предлагая такие возможности как виджеты, пользовательские ярлыки, скринсейвер и поддержку глобального поиска. Он так же работает как диалоговое окно для просмотра и выбора медиа. \ No newline at end of file +Aves интегрируется с Android (от KitKat до Android 14, включая Android TV) предлагая такие возможности как виджеты, пользовательские ярлыки, скринсейвер и поддержку глобального поиска. Он так же работает как диалоговое окно для просмотра и выбора медиа. diff --git a/fastlane/metadata/android/sk/full_description.txt b/fastlane/metadata/android/sk/full_description.txt index 74557d170..1e9788de0 100644 --- a/fastlane/metadata/android/sk/full_description.txt +++ b/fastlane/metadata/android/sk/full_description.txt @@ -2,4 +2,4 @@ Navigácia a vyhľadávanie je dôležitou súčasťou aplikácie Aves. Jej cieľom je poskytnúť užívateľom jednoduchý prechod z albumov, do fotiek, tagov, máp, atď. -Aves je schopný pracovať s Android (od KitKat do Android 13, včetne Android TV) a ponúka rozšírenia ako miniaplikácie (widgety), skratky aplikácie, šetrič obrazovky a globálne vyhľadávanie. Rovnako poskytuje prehľadávnie médií. \ No newline at end of file +Aves je schopný pracovať s Android (od KitKat do Android 14, včetne Android TV) a ponúka rozšírenia ako miniaplikácie (widgety), skratky aplikácie, šetrič obrazovky a globálne vyhľadávanie. Rovnako poskytuje prehľadávnie médií. diff --git a/fastlane/metadata/android/sl/full_description.txt b/fastlane/metadata/android/sl/full_description.txt index 6c92748f8..6b96ec3ea 100644 --- a/fastlane/metadata/android/sl/full_description.txt +++ b/fastlane/metadata/android/sl/full_description.txt @@ -2,4 +2,4 @@ Navigation and search is an important part of Aves. The goal is for users to easily flow from albums to photos to tags to maps, etc. -Aves integrates with Android (from KitKat to Android 13, including Android TV) with features such as widgets, app shortcuts, screen saver and global search handling. It also works as a media viewer and picker. \ No newline at end of file +Aves integrates with Android (from KitKat to Android 14, including Android TV) with features such as widgets, app shortcuts, screen saver and global search handling. It also works as a media viewer and picker. diff --git a/fastlane/metadata/android/th/full_description.txt b/fastlane/metadata/android/th/full_description.txt index 6c92748f8..6b96ec3ea 100644 --- a/fastlane/metadata/android/th/full_description.txt +++ b/fastlane/metadata/android/th/full_description.txt @@ -2,4 +2,4 @@ Navigation and search is an important part of Aves. The goal is for users to easily flow from albums to photos to tags to maps, etc. -Aves integrates with Android (from KitKat to Android 13, including Android TV) with features such as widgets, app shortcuts, screen saver and global search handling. It also works as a media viewer and picker. \ No newline at end of file +Aves integrates with Android (from KitKat to Android 14, including Android TV) with features such as widgets, app shortcuts, screen saver and global search handling. It also works as a media viewer and picker. diff --git a/fastlane/metadata/android/tr/full_description.txt b/fastlane/metadata/android/tr/full_description.txt index c966a3094..96fd599be 100644 --- a/fastlane/metadata/android/tr/full_description.txt +++ b/fastlane/metadata/android/tr/full_description.txt @@ -2,4 +2,4 @@ Gezinme ve arama Aves'in önemli bir parçasıdır. Amaç, kullanıcıların albümlerden fotoğraflara, etiketlerden haritalara vb. kolayca geçmesini sağlamaktır. -Aves, uygulama kısayolları ve global arama işleme gibi özelliklerle Android (API 19'dan 33'ye, yani KitKat'tan Android 13'ye kadar) ile entegre olur. Ayrıca bir medya görüntüleyici ve alıcı olarak da çalışır. \ No newline at end of file +Aves, uygulama kısayolları ve global arama işleme gibi özelliklerle Android (API 19'dan 34'ye, yani KitKat'tan Android 14'ye kadar) ile entegre olur. Ayrıca bir medya görüntüleyici ve alıcı olarak da çalışır. diff --git a/fastlane/metadata/android/uk/full_description.txt b/fastlane/metadata/android/uk/full_description.txt index 760891c90..cc81f9cd5 100644 --- a/fastlane/metadata/android/uk/full_description.txt +++ b/fastlane/metadata/android/uk/full_description.txt @@ -2,4 +2,4 @@ Навігація та пошук є важливою частиною Aves. Мета полягає в тому, щоб користувачі легко переходили від альбомів до фотографій, від тегів до карт тощо. -Aves інтегрується з Android (від KitKat до Android 13, включаючи Android TV) пропонуючи такі можливості як віджети, ярлики додатка, заставка екрану та работа з глобальним пошуком. Він також працює як переглядач і засоб вибору медіа. \ No newline at end of file +Aves інтегрується з Android (від KitKat до Android 14, включаючи Android TV) пропонуючи такі можливості як віджети, ярлики додатка, заставка екрану та работа з глобальним пошуком. Він також працює як переглядач і засоб вибору медіа. diff --git a/fastlane/metadata/android/vi/full_description.txt b/fastlane/metadata/android/vi/full_description.txt index f952f3b18..fa415ff0c 100644 --- a/fastlane/metadata/android/vi/full_description.txt +++ b/fastlane/metadata/android/vi/full_description.txt @@ -2,4 +2,4 @@ Điều hướng và tìm kiếm là một phần quan trọng của Aves. Mục tiêu là để người dùng dễ dàng chuyển từ album sang ảnh sang thẻ sang bản đồ, v.v. -Aves tương thích với Android (từ KitKat đến Android 13, bao gồm cả Android TV) với các tính năng như widget, phím tắt ứng dụng, trình bảo vệ màn hình và xử lý tìm kiếm toàn hệ thống. Nó cũng hoạt động như một trình xem và lựa chọn phương tiện. \ No newline at end of file +Aves tương thích với Android (từ KitKat đến Android 14, bao gồm cả Android TV) với các tính năng như widget, phím tắt ứng dụng, trình bảo vệ màn hình và xử lý tìm kiếm toàn hệ thống. Nó cũng hoạt động như một trình xem và lựa chọn phương tiện. diff --git a/fastlane/metadata/android/vi/images/feature_graphics.png b/fastlane/metadata/android/vi/images/featureGraphic.png similarity index 100% rename from fastlane/metadata/android/vi/images/feature_graphics.png rename to fastlane/metadata/android/vi/images/featureGraphic.png diff --git a/fastlane/metadata/android/zh-CN/full_description.txt b/fastlane/metadata/android/zh-CN/full_description.txt index b8352fc7e..429d20c02 100644 --- a/fastlane/metadata/android/zh-CN/full_description.txt +++ b/fastlane/metadata/android/zh-CN/full_description.txt @@ -2,4 +2,4 @@ 导航与搜索Aves 的核心功能之一,旨在帮助用户在相册、照片、标签、地图等之间轻松切换。 -Aves 与 Android(API 19-33,即从 KitKat 到 Android 13)集成,具有快捷方式全局搜索等功能。它还可用作媒体查看器和选择器。 \ No newline at end of file +Aves 与 Android(API 19-34,即从 KitKat 到 Android 14)集成,具有快捷方式全局搜索等功能。它还可用作媒体查看器和选择器。 diff --git a/fastlane/metadata/android/zh-Hant/full_description.txt b/fastlane/metadata/android/zh-Hant/full_description.txt index 102982150..96c231562 100644 --- a/fastlane/metadata/android/zh-Hant/full_description.txt +++ b/fastlane/metadata/android/zh-Hant/full_description.txt @@ -2,4 +2,4 @@ 瀏覽和搜尋Aves重要的一部份. 目的是為了讓使用者能夠輕易的從相簿, 相片, 標籤, 地圖, 等等之間順暢切換. -Aves 與 Android (從 KitKat 到 Android 13, 包括 Android TV) 整合, 具有特色像是 小工具, app 捷徑, 螢幕保護程式全域搜尋 等功能. 還可以當成 媒體檢視和選擇器. \ No newline at end of file +Aves 與 Android (從 KitKat 到 Android 14, 包括 Android TV) 整合, 具有特色像是 小工具, app 捷徑, 螢幕保護程式全域搜尋 等功能. 還可以當成 媒體檢視和選擇器. diff --git a/lib/l10n/app_ar.arb b/lib/l10n/app_ar.arb index 73b65e109..12836dbde 100644 --- a/lib/l10n/app_ar.arb +++ b/lib/l10n/app_ar.arb @@ -27,7 +27,7 @@ "@doNotAskAgain": {}, "welcomeTermsToggle": "أوافق على الشروط", "@welcomeTermsToggle": {}, - "doubleBackExitMessage": "اضغط على \"رجوع\" مرة أخرى للخروج.", + "doubleBackExitMessage": "اضغط على «رجوع» مرة أخرى للخروج.", "@doubleBackExitMessage": {}, "hideButtonLabel": "إخفاء", "@hideButtonLabel": {}, @@ -39,7 +39,7 @@ "@changeTooltip": {}, "actionRemove": "إزالة", "@actionRemove": {}, - "appName": "أيفيس", + "appName": "Aves", "@appName": {}, "welcomeOptional": "اختياري", "@welcomeOptional": {}, @@ -53,7 +53,7 @@ "@previousTooltip": {}, "welcomeMessage": "مرحبا بكم في أيفيس", "@welcomeMessage": {}, - "applyButtonLabel": "تطبيق", + "applyButtonLabel": "تقديم", "@applyButtonLabel": {}, "nextButtonLabel": "التالي", "@nextButtonLabel": {}, @@ -70,5 +70,1453 @@ "tagEditorPageAddTagTooltip": "إضافة علامة", "@tagEditorPageAddTagTooltip": {}, "albumScreenRecordings": "تسجيل الشاشة", - "@albumScreenRecordings": {} + "@albumScreenRecordings": {}, + "chipActionSetCover": "تعيين كغلاف", + "@chipActionSetCover": {}, + "saveCopyButtonLabel": "حفظ نسخة", + "@saveCopyButtonLabel": {}, + "chipActionFilterOut": "تصفية أو استبعاد", + "@chipActionFilterOut": {}, + "chipActionHide": "يخفي", + "@chipActionHide": {}, + "sourceStateCataloguing": "تصنيف", + "@sourceStateCataloguing": {}, + "chipActionDelete": "يمسح", + "@chipActionDelete": {}, + "sourceStateLoading": "تحميل", + "@sourceStateLoading": {}, + "sourceStateLocatingCountries": "تحديد مواقع الدول", + "@sourceStateLocatingCountries": {}, + "chipActionFilterIn": "تصفية أو اختيار", + "@chipActionFilterIn": {}, + "chipActionPin": "تثبيت في الأعلى", + "@chipActionPin": {}, + "chipActionRename": "إعادة تسمية", + "@chipActionRename": {}, + "chipActionGoToPlacePage": "عرض في الأماكن", + "@chipActionGoToPlacePage": {}, + "chipActionGoToAlbumPage": "عرض في الألبومات", + "@chipActionGoToAlbumPage": {}, + "chipActionLock": "قَفل", + "@chipActionLock": {}, + "pickTooltip": "اختيار", + "@pickTooltip": {}, + "chipActionGoToCountryPage": "عرض في الدول", + "@chipActionGoToCountryPage": {}, + "applyTooltip": "يتقدم", + "@applyTooltip": {}, + "chipActionUnpin": "إلغاء تثبيت من الأعلى", + "@chipActionUnpin": {}, + "chipActionGoToTagPage": "عرض في الوسوم", + "@chipActionGoToTagPage": {}, + "sourceStateLocatingPlaces": "تحديد المواقع", + "@sourceStateLocatingPlaces": {}, + "aboutCreditsWorldAtlas2": "بموجب ترخيص ISC.", + "@aboutCreditsWorldAtlas2": {}, + "binEntriesConfirmationDialogMessage": "{count, plural, =1{هل تريد نقل هذا العنصر إلى سلة المحذوفات؟} other{حرك هذه {count}العناصر إلى سلة المحذوفات؟}}", + "@binEntriesConfirmationDialogMessage": { + "placeholders": { + "count": {} + } + }, + "settingsNavigationDrawerAddAlbum": "إضافة ألبوم", + "@settingsNavigationDrawerAddAlbum": {}, + "settingsPrivacySectionTitle": "خصوصية", + "@settingsPrivacySectionTitle": {}, + "settingsEnableBinSubtitle": "الاحتفاظ بالعناصر المحذوفة لمدة 30 يومًا", + "@settingsEnableBinSubtitle": {}, + "viewerInfoPageTitle": "معلومات", + "@viewerInfoPageTitle": {}, + "mapAttributionStamen": "بيانات الخريطة © [OpenStreetMap](https://www.openstreetmap.org/copyright) المساهمين • البلاط بواسطة [Stamen Design](https://stamen.com), [CC BY 3.0](https://creativecommons.org/licenses/by/3.0)", + "@mapAttributionStamen": {}, + "widgetOpenPageViewer": "افتح العارض", + "@widgetOpenPageViewer": {}, + "setCoverDialogLatest": "أحدث عنصر", + "@setCoverDialogLatest": {}, + "settingsThumbnailShowRating": "عرض التقييم", + "@settingsThumbnailShowRating": {}, + "editEntryRatingDialogTitle": "تقييم", + "@editEntryRatingDialogTitle": {}, + "entryInfoActionExportMetadata": "تصدير البيانات الوصفية", + "@entryInfoActionExportMetadata": {}, + "aboutDataUsageMisc": "منوعات", + "@aboutDataUsageMisc": {}, + "editorActionTransform": "تحول", + "@editorActionTransform": {}, + "collectionExportFailureFeedback": "{count, plural, =1{فشل تصدير صفحة واحدة} other{فشل التصدير {count} pages}}", + "@collectionExportFailureFeedback": { + "placeholders": { + "count": {} + } + }, + "vaultDialogLockModeWhenScreenOff": "القفل عند إيقاف تشغيل الشاشة", + "@vaultDialogLockModeWhenScreenOff": {}, + "videoResumeDialogMessage": "هل ترغب في استئناف التشغيل في {time}؟", + "@videoResumeDialogMessage": { + "placeholders": { + "time": { + "type": "String", + "example": "13:37" + } + } + }, + "albumVideoCaptures": "الفيديوهات الملتقطة", + "@albumVideoCaptures": {}, + "wallpaperUseScrollEffect": "استخدم تأثير التمرير على الشاشة الرئيسية", + "@wallpaperUseScrollEffect": {}, + "coordinateDms": "{coordinate} {direction}", + "@coordinateDms": { + "placeholders": { + "coordinate": { + "type": "String", + "example": "38° 41′ 47.72″" + }, + "direction": { + "type": "String", + "example": "S" + } + } + }, + "editEntryDateDialogSetCustom": "تحديد تاريخ مخصص", + "@editEntryDateDialogSetCustom": {}, + "mapStyleGoogleTerrain": "خرائط جوجل (التضاريس)", + "@mapStyleGoogleTerrain": {}, + "statsTopTagsSectionTitle": "أهم العلامات", + "@statsTopTagsSectionTitle": {}, + "settingsSubtitleThemeTextAlignmentDialogTitle": "مُحاذاة النص", + "@settingsSubtitleThemeTextAlignmentDialogTitle": {}, + "settingsSearchEmpty": "لا يوجد إعداد مطابق", + "@settingsSearchEmpty": {}, + "removeEntryMetadataDialogMore": "أكثر", + "@removeEntryMetadataDialogMore": {}, + "viewerActionLock": "قفل المعاينة", + "@viewerActionLock": {}, + "pinDialogConfirm": "تأكيد الرمز السري", + "@pinDialogConfirm": {}, + "settingsViewerSlideshowPageTitle": "عرض الشرائح", + "@settingsViewerSlideshowPageTitle": {}, + "tooManyItemsErrorDialogMessage": "حاول مرة أخرى باستخدام عدد أقل من العناصر.", + "@tooManyItemsErrorDialogMessage": {}, + "collectionActionEdit": "تحرير", + "@collectionActionEdit": {}, + "viewerInfoSearchSuggestionResolution": "دقة", + "@viewerInfoSearchSuggestionResolution": {}, + "viewerTransitionSlide": "الإنزلاق", + "@viewerTransitionSlide": {}, + "sortOrderLargestFirst": "الأكبر أولاً", + "@sortOrderLargestFirst": {}, + "viewerTransitionParallax": "تأثير الشبكية", + "@viewerTransitionParallax": {}, + "settingsViewerSectionTitle": "عارض", + "@settingsViewerSectionTitle": {}, + "mapStyleStamenWatercolor": "ستايمن بالألوان المائية", + "@mapStyleStamenWatercolor": {}, + "editEntryDateDialogSourceFileModifiedDate": "تاريخ تعديل الملف", + "@editEntryDateDialogSourceFileModifiedDate": {}, + "editorTransformRotate": "تدوير", + "@editorTransformRotate": {}, + "collectionEmptyFavourites": "لا يوجد مفضلة", + "@collectionEmptyFavourites": {}, + "albumTierNew": "جديد", + "@albumTierNew": {}, + "removeEntryMetadataDialogTitle": "ازالة البيانات الوصفية", + "@removeEntryMetadataDialogTitle": {}, + "settingsLanguageTile": "اللغة", + "@settingsLanguageTile": {}, + "drawerCollectionVideos": "الفيديوهات", + "@drawerCollectionVideos": {}, + "videoResumptionModeNever": "أبداً", + "@videoResumptionModeNever": {}, + "countryEmpty": "لا توجد دول", + "@countryEmpty": {}, + "collectionSelectSectionTooltip": "اختر القسم", + "@collectionSelectSectionTooltip": {}, + "settingsAllowInstalledAppAccessSubtitle": "يستخدم لتحسين عرض الألبوم", + "@settingsAllowInstalledAppAccessSubtitle": {}, + "aboutLicensesBanner": "يستخدم هذا التطبيق الحزم والمكتبات مفتوحة المصدر التالية.", + "@aboutLicensesBanner": {}, + "moveUndatedConfirmationDialogSetDate": "حفظ التواريخ", + "@moveUndatedConfirmationDialogSetDate": {}, + "coordinateDmsNorth": "شمال", + "@coordinateDmsNorth": {}, + "dateYesterday": "أمس", + "@dateYesterday": {}, + "viewerInfoLabelDate": "تاريخ", + "@viewerInfoLabelDate": {}, + "nameConflictStrategyReplace": "إستبدال", + "@nameConflictStrategyReplace": {}, + "aboutDataUsageDatabase": "قاعدة البيانات", + "@aboutDataUsageDatabase": {}, + "collectionMoveFailureFeedback": "{count, plural, =1{فشل في نقل عنصر واحد} other{فشل في النقل {count} items}}", + "@collectionMoveFailureFeedback": { + "placeholders": { + "count": {} + } + }, + "videoLoopModeAlways": "دائماً", + "@videoLoopModeAlways": {}, + "settingsRemoveAnimationsDialogTitle": "ازالة الرسوم المتحركة", + "@settingsRemoveAnimationsDialogTitle": {}, + "tileLayoutMosaic": "فسيفساء", + "@tileLayoutMosaic": {}, + "settingsSubtitleThemeTextColor": "لون الخط", + "@settingsSubtitleThemeTextColor": {}, + "collectionDeselectSectionTooltip": "قم بإلغاء تحديد القسم", + "@collectionDeselectSectionTooltip": {}, + "settingsKeepScreenOnTile": "إبقاء شاشة قيد التشغيل", + "@settingsKeepScreenOnTile": {}, + "tileLayoutGrid": "شبكة", + "@tileLayoutGrid": {}, + "settingsDisplayUseTvInterface": "واجهة أندرويد TV", + "@settingsDisplayUseTvInterface": {}, + "settingsTimeToTakeActionTile": "حان الوقت لاتخاذ الإجراءات اللازمة", + "@settingsTimeToTakeActionTile": {}, + "aboutCreditsWorldAtlas1": "يستخدم هذا التطبيق ملف TopoJSON من", + "@aboutCreditsWorldAtlas1": {}, + "nameConflictDialogMultipleSourceMessage": "بعض الملفات لها نفس الاسم.", + "@nameConflictDialogMultipleSourceMessage": {}, + "settingsVideoSectionTitle": "فيديو", + "@settingsVideoSectionTitle": {}, + "appExportCovers": "أغلفة", + "@appExportCovers": {}, + "viewerOpenPanoramaButtonLabel": "فتح البانوراما", + "@viewerOpenPanoramaButtonLabel": {}, + "createAlbumButtonLabel": "إنشاء", + "@createAlbumButtonLabel": {}, + "newAlbumDialogStorageLabel": "تخزين:", + "@newAlbumDialogStorageLabel": {}, + "settingsSubtitleThemeBackgroundColor": "لون الخلفية", + "@settingsSubtitleThemeBackgroundColor": {}, + "menuActionSlideshow": "عرض الشرائح", + "@menuActionSlideshow": {}, + "vaultLockTypePassword": "كلمة سر", + "@vaultLockTypePassword": {}, + "settingsThumbnailOverlayTile": "التراكب", + "@settingsThumbnailOverlayTile": {}, + "settingsNavigationDrawerTabPages": "الصفحات", + "@settingsNavigationDrawerTabPages": {}, + "settingsConfirmationDialogTitle": "نوافذ التأكيد الحوار", + "@settingsConfirmationDialogTitle": {}, + "videoStreamSelectionDialogText": "ترجمات", + "@videoStreamSelectionDialogText": {}, + "settingsVideoAutoPlay": "تشغيل تلقائي", + "@settingsVideoAutoPlay": {}, + "settingsVideoEnableHardwareAcceleration": "تسريع الأجهزة", + "@settingsVideoEnableHardwareAcceleration": {}, + "editEntryDateDialogShift": "يحول", + "@editEntryDateDialogShift": {}, + "viewerInfoLabelCoordinates": "الإحداثيات", + "@viewerInfoLabelCoordinates": {}, + "nameConflictDialogSingleSourceMessage": "بعض الملفات الموجودة في مجلد الوجهة لها نفس الاسم.", + "@nameConflictDialogSingleSourceMessage": {}, + "exportEntryDialogFormat": "شكل:", + "@exportEntryDialogFormat": {}, + "widgetOpenPageHome": "إفتح الرئيسية", + "@widgetOpenPageHome": {}, + "mapStyleHuaweiNormal": "خرائط بيتال (هواوي)", + "@mapStyleHuaweiNormal": {}, + "keepScreenOnAlways": "دائما", + "@keepScreenOnAlways": {}, + "appExportSettings": "إعدادات", + "@appExportSettings": {}, + "exportEntryDialogQuality": "جودة", + "@exportEntryDialogQuality": {}, + "searchPlacesSectionTitle": "الأماكن", + "@searchPlacesSectionTitle": {}, + "settingsCollectionSelectionQuickActionEditorBanner": "المس مع الاستمرار لتحريك الأزرار وتحديد الإجراءات التي يتم عرضها عند تحديد العناصر.", + "@settingsCollectionSelectionQuickActionEditorBanner": {}, + "settingsSlideshowShuffle": "تشغيل عشوائي", + "@settingsSlideshowShuffle": {}, + "settingsThumbnailSectionTitle": "الصور المصغرة", + "@settingsThumbnailSectionTitle": {}, + "videoStreamSelectionDialogAudio": "صوت", + "@videoStreamSelectionDialogAudio": {}, + "videoSpeedDialogLabel": "سرعة التشغيل", + "@videoSpeedDialogLabel": {}, + "openMapPageTooltip": "عرض على صفحة الخريطة", + "@openMapPageTooltip": {}, + "videoActionSkip10": "تقدم إلى الأمام لمدة 10 ثوانٍ", + "@videoActionSkip10": {}, + "editEntryLocationDialogSetCustom": "تعيين الموقع المخصص", + "@editEntryLocationDialogSetCustom": {}, + "viewerInfoUnknown": "مَجهول", + "@viewerInfoUnknown": {}, + "displayRefreshRatePreferHighest": "أعلى معدل", + "@displayRefreshRatePreferHighest": {}, + "settingsVideoShowVideos": "عرض الفيديوهات", + "@settingsVideoShowVideos": {}, + "deleteEntriesConfirmationDialogMessage": "{count, plural, =1{هل تريد حذف هذا العنصر؟} other{احذف هذه {count} أغراض؟}}", + "@deleteEntriesConfirmationDialogMessage": { + "placeholders": { + "count": {} + } + }, + "settingsViewerShowInformation": "مزيد من المعلومات", + "@settingsViewerShowInformation": {}, + "placeEmpty": "لا توجد أماكن", + "@placeEmpty": {}, + "settingsCollectionQuickActionsTile": "إجراءات سريعة", + "@settingsCollectionQuickActionsTile": {}, + "editEntryDateDialogExtractFromTitle": "استخراج من العنوان", + "@editEntryDateDialogExtractFromTitle": {}, + "settingsViewerOverlayTile": "تراكب", + "@settingsViewerOverlayTile": {}, + "albumTierRegular": "آخرون", + "@albumTierRegular": {}, + "settingsThumbnailShowFavouriteIcon": "إظهار الأيقونة المفضلة", + "@settingsThumbnailShowFavouriteIcon": {}, + "aboutLinkLicense": "رخصة", + "@aboutLinkLicense": {}, + "albumScreenshots": "لقطات الشاشة", + "@albumScreenshots": {}, + "editEntryDateDialogTitle": "التاريخ والوقت", + "@editEntryDateDialogTitle": {}, + "settingsSubtitleThemeTextPositionDialogTitle": "موضع النَص", + "@settingsSubtitleThemeTextPositionDialogTitle": {}, + "viewerInfoLabelOwner": "المالك", + "@viewerInfoLabelOwner": {}, + "editEntryLocationDialogLongitude": "خط الطول", + "@editEntryLocationDialogLongitude": {}, + "setCoverDialogCustom": "مخصص", + "@setCoverDialogCustom": {}, + "searchCountriesSectionTitle": "البلدان", + "@searchCountriesSectionTitle": {}, + "settingsSlideshowIntervalTile": "فاصلة", + "@settingsSlideshowIntervalTile": {}, + "settingsAskEverytime": "اسأل كل مرة", + "@settingsAskEverytime": {}, + "editEntryDateDialogCopyField": "نسخة من تاريخ آخر", + "@editEntryDateDialogCopyField": {}, + "searchTagsSectionTitle": "العلامات", + "@searchTagsSectionTitle": {}, + "displayRefreshRatePreferLowest": "أدنى معدل", + "@displayRefreshRatePreferLowest": {}, + "filterNoAddressLabel": "لا يوجد عنوان", + "@filterNoAddressLabel": {}, + "settingsModificationWarningDialogMessage": "سيتم تعديل الإعدادات الأخرى.", + "@settingsModificationWarningDialogMessage": {}, + "videoStartOverButtonLabel": "ابدأ من جديد", + "@videoStartOverButtonLabel": {}, + "accessibilityAnimationsKeep": "الحفاظ على تأثيرات الشاشة", + "@accessibilityAnimationsKeep": {}, + "settingsCollectionQuickActionEditorPageTitle": "اجراءات سريعة", + "@settingsCollectionQuickActionEditorPageTitle": {}, + "policyPageTitle": "سياسة الخصوصية", + "@policyPageTitle": {}, + "tileLayoutList": "قائمة", + "@tileLayoutList": {}, + "settingsStorageAccessRevokeTooltip": "إبطال", + "@settingsStorageAccessRevokeTooltip": {}, + "settingsSubtitleThemeTile": "ترجمات", + "@settingsSubtitleThemeTile": {}, + "widgetDisplayedItemMostRecent": "الأحدث", + "@widgetDisplayedItemMostRecent": {}, + "videoActionUnmute": "إلغاء كتم الصوت", + "@videoActionUnmute": {}, + "appPickDialogNone": "لاشيء", + "@appPickDialogNone": {}, + "filterMimeImageLabel": "صورة", + "@filterMimeImageLabel": {}, + "settingsVideoGestureVerticalDragBrightnessVolume": "اسحب لأعلى أو لأسفل لضبط مستوى السطوع/الصوت", + "@settingsVideoGestureVerticalDragBrightnessVolume": {}, + "settingsAccessibilitySectionTitle": "إمكانية الوصول", + "@settingsAccessibilitySectionTitle": {}, + "settingsActionExport": "يصدّر", + "@settingsActionExport": {}, + "aboutBugCopyInfoInstruction": "نسخ معلومات النظام", + "@aboutBugCopyInfoInstruction": {}, + "filterNoTagLabel": "بدون علامات", + "@filterNoTagLabel": {}, + "missingSystemFilePickerDialogMessage": "منتقي ملفات النظام مفقود أو معطل. يرجى تمكينه والمحاولة مرة أخرى.", + "@missingSystemFilePickerDialogMessage": {}, + "viewerInfoViewXmlLinkText": "عرض ملف XML", + "@viewerInfoViewXmlLinkText": {}, + "sortOrderOldestFirst": "الأقدم أولا", + "@sortOrderOldestFirst": {}, + "collectionRenameFailureFeedback": "{count, plural, =1{فشلت إعادة تسمية عنصر واحد} other{فشلت إعادة التسمية {count} items}}", + "@collectionRenameFailureFeedback": { + "placeholders": { + "count": {} + } + }, + "videoResumptionModeAlways": "دائماً", + "@videoResumptionModeAlways": {}, + "tagEditorDiscardDialogMessage": "هل تريد تجاهل التغييرات؟", + "@tagEditorDiscardDialogMessage": {}, + "collectionEditSuccessFeedback": "{count, plural, =1{تم تحريرعنصر واحد} other{تحرير {count} عناصر}}", + "@collectionEditSuccessFeedback": { + "placeholders": { + "count": {} + } + }, + "wallpaperTargetLock": "شاشة القفل", + "@wallpaperTargetLock": {}, + "coverDialogTabApp": "التطبيق", + "@coverDialogTabApp": {}, + "settingsThumbnailShowMotionPhotoIcon": "إظهار أيقونة الصورة المتحركة", + "@settingsThumbnailShowMotionPhotoIcon": {}, + "accessibilityAnimationsRemove": "منع تأثيرات الشاشة", + "@accessibilityAnimationsRemove": {}, + "removeEntryMetadataMotionPhotoXmpWarningDialogMessage": "مطلوب XMP لتشغيل الفيديو داخل الصورة المتحركة.\n\nهل أنت متأكد أنك تريد إزالته؟", + "@removeEntryMetadataMotionPhotoXmpWarningDialogMessage": {}, + "nameConflictStrategyRename": "إعادة تسمية", + "@nameConflictStrategyRename": {}, + "settingsThumbnailShowRawIcon": "إظهار أيقونة الخام", + "@settingsThumbnailShowRawIcon": {}, + "vaultLockTypePattern": "نمط", + "@vaultLockTypePattern": {}, + "tagPageTitle": "العلامات", + "@tagPageTitle": {}, + "collectionEmptyVideos": "لا توجد فيديوهات", + "@collectionEmptyVideos": {}, + "entryActionRemoveFavourite": "إزالة من المفضلة", + "@entryActionRemoveFavourite": {}, + "aboutCreditsSectionTitle": "الاعتمادات", + "@aboutCreditsSectionTitle": {}, + "drawerAlbumPage": "الألبومات", + "@drawerAlbumPage": {}, + "statsTopCountriesSectionTitle": "أهم الدول", + "@statsTopCountriesSectionTitle": {}, + "settingsActionImport": "يستورد", + "@settingsActionImport": {}, + "viewerInfoLabelSize": "مقاس", + "@viewerInfoLabelSize": {}, + "locationPickerUseThisLocationButton": "استخدم هذا الموقع", + "@locationPickerUseThisLocationButton": {}, + "settingsSlideshowFillScreen": "ملء الشاشة", + "@settingsSlideshowFillScreen": {}, + "settingsHiddenFiltersBanner": "لن تظهر الصور ومقاطع الفيديو المطابقة للمرشحات المخفية في مجموعتك.", + "@settingsHiddenFiltersBanner": {}, + "albumTierVaults": "خزائن", + "@albumTierVaults": {}, + "viewerSetWallpaperButtonLabel": "تعيين خلفية", + "@viewerSetWallpaperButtonLabel": {}, + "settingsVideoResumptionModeTile": "استئناف التشغيل", + "@settingsVideoResumptionModeTile": {}, + "collectionGroupNone": "لا تجمع", + "@collectionGroupNone": {}, + "searchRatingSectionTitle": "التقييمات", + "@searchRatingSectionTitle": {}, + "vaultBinUsageDialogMessage": "تستخدم بعض الخزائن سلة المحذوفات.", + "@vaultBinUsageDialogMessage": {}, + "collectionCopyFailureFeedback": "{count, plural, =1{فشل نسخ عنصر واحد} other{فشل النسخ {count} items}}", + "@collectionCopyFailureFeedback": { + "placeholders": { + "count": {} + } + }, + "settingsDisabled": "غير مفعل", + "@settingsDisabled": {}, + "settingsVideoGestureDoubleTapTogglePlay": "انقر نقرًا مزدوجًا للتشغيل/الإيقاف", + "@settingsVideoGestureDoubleTapTogglePlay": {}, + "coordinateFormatDecimal": "الدرجات العشرية", + "@coordinateFormatDecimal": {}, + "overlayHistogramLuminance": "الانارة", + "@overlayHistogramLuminance": {}, + "coordinateDmsEast": "شرق", + "@coordinateDmsEast": {}, + "filterAspectRatioLandscapeLabel": "طبيعي", + "@filterAspectRatioLandscapeLabel": {}, + "albumTierApps": "تطبيقات", + "@albumTierApps": {}, + "filterAspectRatioPortraitLabel": "لوحة", + "@filterAspectRatioPortraitLabel": {}, + "settingsWidgetDisplayedItem": "العنصر المعروض", + "@settingsWidgetDisplayedItem": {}, + "aboutBugSaveLogInstruction": "حفظ سجلات التطبيق في ملف", + "@aboutBugSaveLogInstruction": {}, + "settingsActionImportDialogTitle": "يستورد", + "@settingsActionImportDialogTitle": {}, + "filterTypeGeotiffLabel": "GeoTIFF", + "@filterTypeGeotiffLabel": {}, + "entryActionRotateScreen": "تدوير الشاشة", + "@entryActionRotateScreen": {}, + "albumGroupTier": "حسب الطبقة", + "@albumGroupTier": {}, + "aboutBugReportInstruction": "تقرير على GitHub مع السجلات ومعلومات النظام", + "@aboutBugReportInstruction": {}, + "addPathTooltip": "أضف المسار", + "@addPathTooltip": {}, + "videoActionCaptureFrame": "التقاط الإطار", + "@videoActionCaptureFrame": {}, + "patternDialogEnter": "أدخل النمط", + "@patternDialogEnter": {}, + "settingsEnableBin": "استخدم سلة المحذوفات", + "@settingsEnableBin": {}, + "entryActionViewMotionPhotoVideo": "فتح الفيديو", + "@entryActionViewMotionPhotoVideo": {}, + "videoControlsNone": "لا شيء", + "@videoControlsNone": {}, + "otherDirectoryDescription": "دليل «{name}»", + "@otherDirectoryDescription": { + "placeholders": { + "name": { + "type": "String", + "example": "Pictures", + "description": "the name of a specific directory" + } + } + }, + "viewerTransitionZoomIn": "تكبير", + "@viewerTransitionZoomIn": {}, + "drawerCollectionAll": "كل جمع", + "@drawerCollectionAll": {}, + "collectionMoveSuccessFeedback": "{count, plural, =1{تم نقل عنصر واحد} other{نقل {count} عناصر}}", + "@collectionMoveSuccessFeedback": { + "placeholders": { + "count": {} + } + }, + "settingsSubtitleThemeTextAlignmentLeft": "يسار", + "@settingsSubtitleThemeTextAlignmentLeft": {}, + "settingsVideoGestureSideDoubleTapSeek": "انقر نقرًا مزدوجًا على حواف الشاشة للتقدم للأمام/للخلف", + "@settingsVideoGestureSideDoubleTapSeek": {}, + "mapStyleHuaweiTerrain": "خرائط بيتال (التضاريس)", + "@mapStyleHuaweiTerrain": {}, + "sortByItemCount": "حسب عدد العناصر", + "@sortByItemCount": {}, + "sectionUnknown": "مجهول", + "@sectionUnknown": {}, + "dateToday": "اليوم", + "@dateToday": {}, + "filterNoTitleLabel": "بدون عنوان", + "@filterNoTitleLabel": {}, + "videoStreamSelectionDialogNoSelection": "لا توجد مسارات أخرى.", + "@videoStreamSelectionDialogNoSelection": {}, + "searchRecentSectionTitle": "مؤخرًا", + "@searchRecentSectionTitle": {}, + "albumPickPageTitlePick": "اختر الألبوم", + "@albumPickPageTitlePick": {}, + "videoPlaybackMuted": "تشغيل بدون صوت", + "@videoPlaybackMuted": {}, + "settingsSubtitleThemeTextAlignmentRight": "يمين", + "@settingsSubtitleThemeTextAlignmentRight": {}, + "menuActionMap": "خريطة", + "@menuActionMap": {}, + "entryInfoActionRemoveMetadata": "إزالة البيانات الوصفية", + "@entryInfoActionRemoveMetadata": {}, + "collectionActionMove": "الانتقال إلى الألبوم", + "@collectionActionMove": {}, + "searchAlbumsSectionTitle": "الألبومات", + "@searchAlbumsSectionTitle": {}, + "settingsLanguagePageTitle": "اللغة", + "@settingsLanguagePageTitle": {}, + "rootDirectoryDescription": "دليل الجذر", + "@rootDirectoryDescription": {}, + "viewDialogGroupSectionTitle": "مجموعة", + "@viewDialogGroupSectionTitle": {}, + "maxBrightnessAlways": "دائماً", + "@maxBrightnessAlways": {}, + "settingsAllowMediaManagement": "السماح بإدارة الوسائط", + "@settingsAllowMediaManagement": {}, + "aboutDataUsageSectionTitle": "استخدام البيانات", + "@aboutDataUsageSectionTitle": {}, + "durationDialogSeconds": "ثواني", + "@durationDialogSeconds": {}, + "themeBrightnessLight": "مضيء", + "@themeBrightnessLight": {}, + "unitSystemImperial": "النظام الإنشي", + "@unitSystemImperial": {}, + "filterMimeVideoLabel": "فيديو", + "@filterMimeVideoLabel": {}, + "albumEmpty": "لا توجد ألبومات", + "@albumEmpty": {}, + "editEntryLocationDialogChooseOnMap": "اختر على الخريطة", + "@editEntryLocationDialogChooseOnMap": {}, + "settingsCollectionBrowsingQuickActionEditorBanner": "المس مع الاستمرار لتحريك الأزرار وتحديد الإجراءات التي يتم عرضها عند تصفح العناصر.", + "@settingsCollectionBrowsingQuickActionEditorBanner": {}, + "settingsConfirmationBeforeDeleteItems": "اسأل قبل حذف العناصر إلى الأبد", + "@settingsConfirmationBeforeDeleteItems": {}, + "sortByName": "حسب الإسم", + "@sortByName": {}, + "settingsHomeDialogTitle": "الرئيسية", + "@settingsHomeDialogTitle": {}, + "searchDateSectionTitle": "تاريخ", + "@searchDateSectionTitle": {}, + "viewerErrorUnknown": "آسف!", + "@viewerErrorUnknown": {}, + "storageAccessDialogMessage": "يرجى تحديد {directory} لـ «{volume}» في الشاشة التالية لمنح هذا التطبيق حق الوصول إليه.", + "@storageAccessDialogMessage": { + "placeholders": { + "directory": { + "type": "String", + "description": "the name of a directory, using the output of `rootDirectoryDescription` or `otherDirectoryDescription`" + }, + "volume": { + "type": "String", + "example": "SD card", + "description": "the name of a storage volume" + } + } + }, + "themeBrightnessDark": "مظلم", + "@themeBrightnessDark": {}, + "entryActionConvertMotionPhotoToStillImage": "تحويل إلى صورة ثابتة", + "@entryActionConvertMotionPhotoToStillImage": {}, + "entryActionCast": "البث", + "@entryActionCast": {}, + "entryInfoActionEditTitleDescription": "تحرير العنوان والوصف", + "@entryInfoActionEditTitleDescription": {}, + "collectionSearchTitlesHintText": "عناوين البحث", + "@collectionSearchTitlesHintText": {}, + "entryInfoActionEditLocation": "تحديد الوجهة", + "@entryInfoActionEditLocation": {}, + "viewerInfoSearchSuggestionDate": "التَاريخ والوقت", + "@viewerInfoSearchSuggestionDate": {}, + "videoPlaybackWithSound": "تشغيل بالصوت", + "@videoPlaybackWithSound": {}, + "viewerInfoLabelTitle": "عنوان", + "@viewerInfoLabelTitle": {}, + "searchCollectionFieldHint": "البحث في المجموعة", + "@searchCollectionFieldHint": {}, + "viewerActionUnlock": "إلغاء قفل المعاينة", + "@viewerActionUnlock": {}, + "settingsDoubleBackExit": "اضغط على «رجوع» مرتين للخروج", + "@settingsDoubleBackExit": {}, + "entryActionShare": "مشاركة", + "@entryActionShare": {}, + "drawerCollectionSphericalVideos": "فيديوهات 360 درجة", + "@drawerCollectionSphericalVideos": {}, + "moveUndatedConfirmationDialogMessage": "هل تريد حفظ تواريخ العناصر قبل المتابعة؟", + "@moveUndatedConfirmationDialogMessage": {}, + "collectionEditFailureFeedback": "{count, plural, =1{فشل تحرير عنصر واحد} other{فشل التحرير {count} items}}", + "@collectionEditFailureFeedback": { + "placeholders": { + "count": {} + } + }, + "videoActionPause": "إيقاف مؤقت", + "@videoActionPause": {}, + "noMatchingAppDialogMessage": "لا توجد تطبيقات يمكنها التعامل مع هذا.", + "@noMatchingAppDialogMessage": {}, + "settingsThumbnailOverlayPageTitle": "التراكب", + "@settingsThumbnailOverlayPageTitle": {}, + "settingsViewerShowInformationSubtitle": "إظهار العنوان والتاريخ والموقع وما إلى ذلك.", + "@settingsViewerShowInformationSubtitle": {}, + "searchMetadataSectionTitle": "البيانات الوصفية", + "@searchMetadataSectionTitle": {}, + "widgetOpenPageCollection": "فتح المجموعة", + "@widgetOpenPageCollection": {}, + "settingsWidgetOpenPage": "عند النقر على الويدجت", + "@settingsWidgetOpenPage": {}, + "settingsShowBottomNavigationBar": "إظهار شريط التنقل السفلي", + "@settingsShowBottomNavigationBar": {}, + "renameProcessorName": "اسم", + "@renameProcessorName": {}, + "viewerInfoSearchFieldLabel": "البحث في البيانات الوصفية", + "@viewerInfoSearchFieldLabel": {}, + "viewerInfoLabelDescription": "وصف", + "@viewerInfoLabelDescription": {}, + "nameConflictStrategySkip": "تخطي", + "@nameConflictStrategySkip": {}, + "addShortcutButtonLabel": "إضافة", + "@addShortcutButtonLabel": {}, + "exportEntryDialogHeight": "ارتفاع", + "@exportEntryDialogHeight": {}, + "collectionActionEmptyBin": "سلة فارغة", + "@collectionActionEmptyBin": {}, + "settingsSlideshowRepeat": "تكرار", + "@settingsSlideshowRepeat": {}, + "settingsViewerQuickActionEditorPageTitle": "اجراءات سريعة", + "@settingsViewerQuickActionEditorPageTitle": {}, + "sortOrderAtoZ": "من الألف إلى الياء", + "@sortOrderAtoZ": {}, + "settingsVideoPageTitle": "اعدادات الفيديو", + "@settingsVideoPageTitle": {}, + "setCoverDialogAuto": "آلي", + "@setCoverDialogAuto": {}, + "tagEditorPageNewTagFieldLabel": "علامة جديدة", + "@tagEditorPageNewTagFieldLabel": {}, + "exportEntryDialogWidth": "عرض", + "@exportEntryDialogWidth": {}, + "newAlbumDialogTitle": "البوم جديد", + "@newAlbumDialogTitle": {}, + "collectionRenameSuccessFeedback": "{count, plural, =1{تمت إعادة تسمية عنصر واحد} other{أعادة تسمية {count} عناصر}}", + "@collectionRenameSuccessFeedback": { + "placeholders": { + "count": {} + } + }, + "videoStreamSelectionDialogTrack": "مسار", + "@videoStreamSelectionDialogTrack": {}, + "settingsViewerUseCutout": "استخدام منطقة القص", + "@settingsViewerUseCutout": {}, + "tagEditorPageTitle": "تحريرالعلامات", + "@tagEditorPageTitle": {}, + "settingsWidgetShowOutline": "الخطوط العريضة", + "@settingsWidgetShowOutline": {}, + "settingsHomeTile": "الرئيسية", + "@settingsHomeTile": {}, + "entryActionOpenMap": "عرض في تطبيق الخرائط", + "@entryActionOpenMap": {}, + "hideFilterConfirmationDialogMessage": "سيتم إخفاء الصور ومقاطع الفيديو المطابقة من مجموعتك. ويمكنك إظهارها مرة أخرى من إعدادات «الخصوصية».\n\nهل أنت متأكد أنك تريد إخفاءهم؟", + "@hideFilterConfirmationDialogMessage": {}, + "settingsViewerGestureSideTapNext": "اضغط على حواف الشاشة لإظهار العنصر السابق/التالي", + "@settingsViewerGestureSideTapNext": {}, + "collectionGroupDay": "حسب اليوم", + "@collectionGroupDay": {}, + "collectionGroupAlbum": "حسب الألبوم", + "@collectionGroupAlbum": {}, + "newFilterBanner": "الجديد", + "@newFilterBanner": {}, + "drawerCollectionFavourites": "المفضلة", + "@drawerCollectionFavourites": {}, + "filterTypeRawLabel": "خام", + "@filterTypeRawLabel": {}, + "videoControlsPlaySeek": "تشغيل وتقدم للأمام/ للخلف", + "@videoControlsPlaySeek": {}, + "settingsSubtitleThemeTextAlignmentCenter": "وسط", + "@settingsSubtitleThemeTextAlignmentCenter": {}, + "keepScreenOnVideoPlayback": "أثناء تشغيل الفيديو", + "@keepScreenOnVideoPlayback": {}, + "vaultLockTypePin": "رمز سري", + "@vaultLockTypePin": {}, + "settingsSubtitleThemeTextAlignmentTile": "محاذاة النص", + "@settingsSubtitleThemeTextAlignmentTile": {}, + "editorTransformCrop": "قص", + "@editorTransformCrop": {}, + "aboutLicensesFlutterPackagesSectionTitle": "حزم إضافية", + "@aboutLicensesFlutterPackagesSectionTitle": {}, + "settingsCollectionQuickActionTabSelecting": "إختيار", + "@settingsCollectionQuickActionTabSelecting": {}, + "focalLength": "{length} mm", + "@focalLength": { + "placeholders": { + "length": { + "type": "String", + "example": "5.4" + } + } + }, + "filterTaggedLabel": "الموسومة", + "@filterTaggedLabel": {}, + "statePageTitle": "الولايات", + "@statePageTitle": {}, + "drawerTagPage": "العلامات", + "@drawerTagPage": {}, + "newAlbumDialogNameLabelAlreadyExistsHelper": "الدليل موجود بالفعل", + "@newAlbumDialogNameLabelAlreadyExistsHelper": {}, + "patternDialogConfirm": "تأكيد النمط", + "@patternDialogConfirm": {}, + "restrictedAccessDialogMessage": "لا يُسمح لهذا التطبيق بتعديل الملفات في {directory} لـ «{volume}»\n\nالرجاء استخدام مدير الملفات أو تطبيق المعرض المثبت مسبقًا لنقل العناصر إلى دليل آخر.", + "@restrictedAccessDialogMessage": { + "placeholders": { + "directory": { + "type": "String", + "description": "the name of a directory, using the output of `rootDirectoryDescription` or `otherDirectoryDescription`" + }, + "volume": { + "type": "String", + "example": "SD card", + "description": "the name of a storage volume" + } + } + }, + "durationDialogMinutes": "دقائق", + "@durationDialogMinutes": {}, + "settingsAllowErrorReporting": "السماح بالإبلاغ عن الأخطاء المجهولة", + "@settingsAllowErrorReporting": {}, + "settingsVideoLoopModeTile": "وضع التكرار", + "@settingsVideoLoopModeTile": {}, + "unsupportedTypeDialogMessage": "{count, plural, =1{هذه العملية غير مدعومة للعناصر من النوع التالي: {types}.} other{هذه العملية غير معتمدة لعناصر الأنواع التالية: {types}.}}", + "@unsupportedTypeDialogMessage": { + "placeholders": { + "count": {}, + "types": { + "type": "String", + "example": "GIF, TIFF, MP4", + "description": "a list of unsupported types" + } + } + }, + "settingsScreenSaverPageTitle": "شاشة التوقف", + "@settingsScreenSaverPageTitle": {}, + "settingsNavigationDrawerEditorPageTitle": "قائمة التنقل", + "@settingsNavigationDrawerEditorPageTitle": {}, + "settingsConfirmationBeforeMoveUndatedItems": "اسأل قبل نقل العناصر غير المؤرخة", + "@settingsConfirmationBeforeMoveUndatedItems": {}, + "albumPageTitle": "الألبومات", + "@albumPageTitle": {}, + "editEntryLocationDialogTitle": "موقع", + "@editEntryLocationDialogTitle": {}, + "statsWithGps": "{count, plural, =1{1 عنصر مع الموقع} other{{count} العناصر مع الموقع}}", + "@statsWithGps": { + "placeholders": { + "count": {} + } + }, + "settingsVideoResumptionModeDialogTitle": "إستئناف التشغيل", + "@settingsVideoResumptionModeDialogTitle": {}, + "albumTierPinned": "مثبت", + "@albumTierPinned": {}, + "mapStyleDialogTitle": "نمط الخريطة", + "@mapStyleDialogTitle": {}, + "entryActionRotateCCW": "تدوير باتجاه عقارب الساعة", + "@entryActionRotateCCW": {}, + "settingsVideoBackgroundMode": "وضع الخلفية", + "@settingsVideoBackgroundMode": {}, + "chipActionCreateVault": "إنشاء خزنة", + "@chipActionCreateVault": {}, + "albumPickPageTitleCopy": "نسخ إلى ألبوم", + "@albumPickPageTitleCopy": {}, + "collectionActionCopy": "نسخ إلى الألبوم", + "@collectionActionCopy": {}, + "entryActionPrint": "طباعة", + "@entryActionPrint": {}, + "settingsAllowInstalledAppAccess": "السماح بالوصول إلى مخزون التطبيق", + "@settingsAllowInstalledAppAccess": {}, + "entryActionShowGeoTiffOnMap": "عرض كتراكب على الخريطة", + "@entryActionShowGeoTiffOnMap": {}, + "viewDialogReverseSortOrder": "عكس ترتيب الفرز", + "@viewDialogReverseSortOrder": {}, + "menuActionConfigureView": "رؤية", + "@menuActionConfigureView": {}, + "aboutLicensesDartPackagesSectionTitle": "حزم البرمجة", + "@aboutLicensesDartPackagesSectionTitle": {}, + "drawerCollectionMotionPhotos": "صور متحركة", + "@drawerCollectionMotionPhotos": {}, + "settingsDefault": "افتراضي", + "@settingsDefault": {}, + "settingsHiddenItemsTabFilters": "المرشحات المخفية", + "@settingsHiddenItemsTabFilters": {}, + "settingsSlideshowAnimatedZoomEffect": "تأثير التكبير المتحرك", + "@settingsSlideshowAnimatedZoomEffect": {}, + "viewerActionSettings": "الإعدادات", + "@viewerActionSettings": {}, + "placePageTitle": "أماكن", + "@placePageTitle": {}, + "filterOnThisDayLabel": "في هذا اليوم", + "@filterOnThisDayLabel": {}, + "columnCount": "{count, plural, =1{1 عمود} other{{count} أعمدة}}{count}", + "@columnCount": { + "placeholders": { + "count": {} + } + }, + "viewerTransitionNone": "لا شيء", + "@viewerTransitionNone": {}, + "settingsDisplayRefreshRateModeTile": "عرض معدل التحديث", + "@settingsDisplayRefreshRateModeTile": {}, + "addShortcutDialogLabel": "تسمية الاختصار", + "@addShortcutDialogLabel": {}, + "settingsViewerOverlayPageTitle": "تراكب", + "@settingsViewerOverlayPageTitle": {}, + "tagEmpty": "لا توجد العلامات", + "@tagEmpty": {}, + "pinDialogEnter": "أدخل الرمز السري", + "@pinDialogEnter": {}, + "videoControlsPlayOutside": "فتح في مشغل آخر", + "@videoControlsPlayOutside": {}, + "settingsCoordinateFormatDialogTitle": "تنسيق الاحداثيات", + "@settingsCoordinateFormatDialogTitle": {}, + "authenticateToUnlockVault": "المصادقة لفتح الخزنة", + "@authenticateToUnlockVault": {}, + "collectionActionShowTitleSearch": "إظهار مرشح العنوان", + "@collectionActionShowTitleSearch": {}, + "lengthUnitPercent": "%", + "@lengthUnitPercent": {}, + "settingsNavigationDrawerTabTypes": "أنواع", + "@settingsNavigationDrawerTabTypes": {}, + "menuActionSelectAll": "تحديد الكل", + "@menuActionSelectAll": {}, + "settingsHiddenItemsTile": "العناصر المخفية", + "@settingsHiddenItemsTile": {}, + "maxBrightnessNever": "أبداً", + "@maxBrightnessNever": {}, + "aboutDataUsageCache": "التخزين المؤقت", + "@aboutDataUsageCache": {}, + "settingsConfirmationTile": "نوافذ التأكيد", + "@settingsConfirmationTile": {}, + "coordinateDmsSouth": "جنوب", + "@coordinateDmsSouth": {}, + "settingsThumbnailShowVideoDuration": "عرض مدة الفيديو", + "@settingsThumbnailShowVideoDuration": {}, + "passwordDialogConfirm": "تأكيد كلمة السر", + "@passwordDialogConfirm": {}, + "videoActionReplay10": "تقدم الخلفي لمدة 10 ثوانٍ", + "@videoActionReplay10": {}, + "settingsCollectionBurstPatternsNone": "لا شيء", + "@settingsCollectionBurstPatternsNone": {}, + "albumMimeTypeMixed": "مختلط", + "@albumMimeTypeMixed": {}, + "settingsViewerQuickActionEditorAvailableButtonsSectionTitle": "الأزرار المتاحة", + "@settingsViewerQuickActionEditorAvailableButtonsSectionTitle": {}, + "itemCount": "{count, plural, =1{1 عنصر} other{{count} عناصر}}", + "@itemCount": { + "placeholders": { + "count": {} + } + }, + "widgetTapUpdateWidget": "تحديث الويدجت", + "@widgetTapUpdateWidget": {}, + "settingsViewerShowDescription": "إظهار الوصف", + "@settingsViewerShowDescription": {}, + "viewerTransitionFade": "تلاشي", + "@viewerTransitionFade": {}, + "chipActionConfigureVault": "تكوين الخزنة", + "@chipActionConfigureVault": {}, + "cropAspectRatioFree": "حر", + "@cropAspectRatioFree": {}, + "aboutLinkPolicy": "سياسة الخصوصية", + "@aboutLinkPolicy": {}, + "filterTypeSphericalVideoLabel": "فيديو 360 درجة", + "@filterTypeSphericalVideoLabel": {}, + "slideshowActionShowInCollection": "عرض في المجموعة", + "@slideshowActionShowInCollection": {}, + "notEnoughSpaceDialogMessage": "تحتاج هذه العملية إلى {neededSize} من المساحة الحرة على «{volume}» لإكمالها، ولكن لم يتبق سوى {freeSize}.", + "@notEnoughSpaceDialogMessage": { + "placeholders": { + "neededSize": { + "type": "String", + "example": "314 MB" + }, + "freeSize": { + "type": "String", + "example": "123 MB" + }, + "volume": { + "type": "String", + "example": "SD card", + "description": "the name of a storage volume" + } + } + }, + "filterNoRatingLabel": "غير مصنف", + "@filterNoRatingLabel": {}, + "settingsUnitSystemTile": "الوحدات", + "@settingsUnitSystemTile": {}, + "entryActionOpen": "فتح باستخدام", + "@entryActionOpen": {}, + "settingsCoordinateFormatTile": "تنسيق الإحداثيات", + "@settingsCoordinateFormatTile": {}, + "newVaultWarningDialogMessage": "العناصر الموجودة في الخزائن متاحة فقط لهذا التطبيق وليس للتطبيقات الأخرى.\n\nإذا قمت بإلغاء تثبيت هذا التطبيق، أو قمت بمسح بيانات هذا التطبيق، فسوف تفقد كل هذه العناصر.", + "@newVaultWarningDialogMessage": {}, + "settingsViewerQuickActionEditorBanner": "المس مع الاستمرار لتحريك الأزرار وتحديد الإجراءات التي سيتم عرضها في العارض.", + "@settingsViewerQuickActionEditorBanner": {}, + "themeBrightnessBlack": "أسود", + "@themeBrightnessBlack": {}, + "filterNoLocationLabel": "غير محدد", + "@filterNoLocationLabel": {}, + "mapZoomInTooltip": "تكبير", + "@mapZoomInTooltip": {}, + "viewerInfoOpenLinkText": "فتح", + "@viewerInfoOpenLinkText": {}, + "storageVolumeDescriptionFallbackNonPrimary": "بطاقة الذاكرة", + "@storageVolumeDescriptionFallbackNonPrimary": {}, + "renameEntrySetPagePatternFieldLabel": "نمط التسمية", + "@renameEntrySetPagePatternFieldLabel": {}, + "renameAlbumDialogLabel": "إسم جديد", + "@renameAlbumDialogLabel": {}, + "videoActionPlay": "تشغيل", + "@videoActionPlay": {}, + "settingsDisablingBinWarningDialogMessage": "سيتم حذف العناصر الموجودة في سلة المحذوفات إلى الأبد.", + "@settingsDisablingBinWarningDialogMessage": {}, + "entryActionSetAs": "تعيين كـ", + "@entryActionSetAs": {}, + "sortOrderLowestFirst": "الأدنى أولاً", + "@sortOrderLowestFirst": {}, + "albumGroupNone": "لا تجمع", + "@albumGroupNone": {}, + "statsTopStatesSectionTitle": "أهم الولايات", + "@statsTopStatesSectionTitle": {}, + "settingsViewerQuickActionEditorDisplayedButtonsSectionTitle": "الأزرار المعروضة", + "@settingsViewerQuickActionEditorDisplayedButtonsSectionTitle": {}, + "settingsVideoPlaybackPageTitle": "التشغيل", + "@settingsVideoPlaybackPageTitle": {}, + "filterLocatedLabel": "متواجد", + "@filterLocatedLabel": {}, + "videoPlaybackSkip": "تخطي", + "@videoPlaybackSkip": {}, + "mapStyleTooltip": "حدد نمط الخريطة", + "@mapStyleTooltip": {}, + "countryPageTitle": "دول", + "@countryPageTitle": {}, + "albumGroupType": "حسب النوع", + "@albumGroupType": {}, + "entryActionInfo": "معلومات", + "@entryActionInfo": {}, + "viewerErrorDoesNotExist": "الملف لم يعد موجودا.", + "@viewerErrorDoesNotExist": {}, + "albumCamera": "الكاميرا", + "@albumCamera": {}, + "videoControlsPlay": "تشغيل", + "@videoControlsPlay": {}, + "settingsNavigationSectionTitle": "التنقل", + "@settingsNavigationSectionTitle": {}, + "settingsDisplayRefreshRateModeDialogTitle": "معدل التحديث", + "@settingsDisplayRefreshRateModeDialogTitle": {}, + "viewerInfoLabelUri": "URI", + "@viewerInfoLabelUri": {}, + "entryActionViewSource": "عرض المصدر", + "@entryActionViewSource": {}, + "entryActionShareVideoOnly": "مشاركة الفيديوهات فقط", + "@entryActionShareVideoOnly": {}, + "filterTypePanoramaLabel": "بانوراما", + "@filterTypePanoramaLabel": {}, + "coordinateFormatDms": "نظام إدارة الوجهة", + "@coordinateFormatDms": {}, + "passwordDialogEnter": "أدخل كلمة السر", + "@passwordDialogEnter": {}, + "mapZoomOutTooltip": "تصغير", + "@mapZoomOutTooltip": {}, + "entryInfoActionEditTags": "تعديل العلامات", + "@entryInfoActionEditTags": {}, + "collectionActionHideTitleSearch": "إخفاء مرشح العنوان", + "@collectionActionHideTitleSearch": {}, + "mapAttributionOsmHot": "بيانات الخريطة © [OpenStreetMap](https://www.openstreetmap.org/copyright) المساهمين • البلاط بواسطة [HOT](https://www.hotosm.org/) • استضافة بواسطة [OSM France](https://openstreetmap.fr/)", + "@mapAttributionOsmHot": {}, + "settingsNavigationDrawerTile": "قائمة تنقل", + "@settingsNavigationDrawerTile": {}, + "drawerCollectionAnimated": "متحرك", + "@drawerCollectionAnimated": {}, + "renameAlbumDialogLabelAlreadyExistsHelper": "الدليل موجود بالفعل", + "@renameAlbumDialogLabelAlreadyExistsHelper": {}, + "settingsHiddenItemsPageTitle": "العناصر المَخفية", + "@settingsHiddenItemsPageTitle": {}, + "keepScreenOnViewerOnly": "صفحة المشاهدة فقط", + "@keepScreenOnViewerOnly": {}, + "durationDialogHours": "ساعات", + "@durationDialogHours": {}, + "settingsHiddenPathsBanner": "لن تظهر الصور ومقاطع الفيديو الموجودة في هذه المجلدات، أو أي من مجلداتها الفرعية في مجموعتك.", + "@settingsHiddenPathsBanner": {}, + "settingsKeepScreenOnDialogTitle": "ابقاء الشَاشة قيد التشغيل", + "@settingsKeepScreenOnDialogTitle": {}, + "wallpaperTargetHome": "الشاشة الرئيسية", + "@wallpaperTargetHome": {}, + "settingsViewerShowOverlayOnOpening": "عرض عند الفتح", + "@settingsViewerShowOverlayOnOpening": {}, + "settingsAccessibilityShowPinchGestureAlternatives": "عرض بدائل إيماءات اللمس المتعدد", + "@settingsAccessibilityShowPinchGestureAlternatives": {}, + "videoActionSelectStreams": "اختيار المسارات", + "@videoActionSelectStreams": {}, + "settingsViewerShowShootingDetails": "عرض تفاصيل التصوير", + "@settingsViewerShowShootingDetails": {}, + "settingsConfirmationAfterMoveToBinItems": "إظهار الرسالة بعد نقل العناصر إلى سلة المحذوفات", + "@settingsConfirmationAfterMoveToBinItems": {}, + "widgetDisplayedItemRandom": "عشوائي", + "@widgetDisplayedItemRandom": {}, + "settingsLanguageSectionTitle": "اللغة والتنسيقات", + "@settingsLanguageSectionTitle": {}, + "drawerPlacePage": "الأماكن", + "@drawerPlacePage": {}, + "menuActionSelect": "تحديد", + "@menuActionSelect": {}, + "drawerCollectionPanoramas": "لقطات بانورامية", + "@drawerCollectionPanoramas": {}, + "renameEntrySetPagePreviewSectionTitle": "معاينة", + "@renameEntrySetPagePreviewSectionTitle": {}, + "filterBinLabel": "سلة المَحذوفات", + "@filterBinLabel": {}, + "settingsDisplaySectionTitle": "عَرض", + "@settingsDisplaySectionTitle": {}, + "settingsConfirmationVaultDataLoss": "إظهار تحذير فقدان بيانات المخزن", + "@settingsConfirmationVaultDataLoss": {}, + "settingsSlideshowTransitionTile": "انتقال", + "@settingsSlideshowTransitionTile": {}, + "settingsPageTitle": "إعدادات", + "@settingsPageTitle": {}, + "subtitlePositionTop": "أعلى", + "@subtitlePositionTop": {}, + "menuActionSelectNone": "لا تحدد شيء", + "@menuActionSelectNone": {}, + "entryActionConvert": "تحويل", + "@entryActionConvert": {}, + "aboutDataUsageClearCache": "مسح ذاكرة التخزين المؤقت", + "@aboutDataUsageClearCache": {}, + "settingsSearchFieldLabel": "إعدادات البحث", + "@settingsSearchFieldLabel": {}, + "appExportFavourites": "المفضلة", + "@appExportFavourites": {}, + "collectionEmptyImages": "لا توجد صور", + "@collectionEmptyImages": {}, + "settingsViewerMaximumBrightness": "أقصى سطوع", + "@settingsViewerMaximumBrightness": {}, + "albumPickPageTitleExport": "تصدير إلى الألبوم", + "@albumPickPageTitleExport": {}, + "settingsThumbnailShowTagIcon": "إظهار رمز العلامة", + "@settingsThumbnailShowTagIcon": {}, + "settingsStorageAccessEmpty": "عدم منح الوصول", + "@settingsStorageAccessEmpty": {}, + "settingsRemoveAnimationsTile": "إزالة الرسوم المتحركة", + "@settingsRemoveAnimationsTile": {}, + "settingsStorageAccessBanner": "تتطلب بعض الدلائل منح وصول صريح لتعديل الملفات الموجودة فيها. يمكنك هنا مراجعة الدلائل التي منحتها حق الوصول إليها مسبقًا.", + "@settingsStorageAccessBanner": {}, + "authenticateToConfigureVault": "قم بالمصادقة لتكوين المخزن", + "@authenticateToConfigureVault": {}, + "settingsActionExportDialogTitle": "يصدّر", + "@settingsActionExportDialogTitle": {}, + "genericDangerWarningDialogMessage": "هل أنت متأكد؟", + "@genericDangerWarningDialogMessage": {}, + "lengthUnitPixel": "بكسل", + "@lengthUnitPixel": {}, + "vaultDialogLockTypeLabel": "نوع القفل", + "@vaultDialogLockTypeLabel": {}, + "aboutDataUsageExternal": "خارجي", + "@aboutDataUsageExternal": {}, + "collectionSelectPageTitle": "اختيار العناصر", + "@collectionSelectPageTitle": {}, + "entryInfoActionEditDate": "تعديل التاريخ والوقت", + "@entryInfoActionEditDate": {}, + "editEntryLocationDialogLatitude": "خط العرض", + "@editEntryLocationDialogLatitude": {}, + "slideshowActionResume": "استئناف", + "@slideshowActionResume": {}, + "cropAspectRatioSquare": "مربع", + "@cropAspectRatioSquare": {}, + "collectionActionRescan": "إعادة المسح", + "@collectionActionRescan": {}, + "collectionCopySuccessFeedback": "{count, plural, =1{تم نسخ عنصر واحد} other{نسخ {count} أغراض}}", + "@collectionCopySuccessFeedback": { + "placeholders": { + "count": {} + } + }, + "settingsNavigationDrawerBanner": "إلمس مع الاستمرار لنقل عناصر القائمة وإعادة ترتيبها.", + "@settingsNavigationDrawerBanner": {}, + "settingsWidgetPageTitle": "إطار الصورة", + "@settingsWidgetPageTitle": {}, + "viewDialogSortSectionTitle": "نوع", + "@viewDialogSortSectionTitle": {}, + "collectionPageTitle": "مجموعة بيانات", + "@collectionPageTitle": {}, + "unitSystemMetric": "النظام المتري", + "@unitSystemMetric": {}, + "overlayHistogramNone": "لا شيء", + "@overlayHistogramNone": {}, + "chipActionShowCountryStates": "عرض الولايات", + "@chipActionShowCountryStates": {}, + "filterRecentlyAddedLabel": "أضيف مؤخرا", + "@filterRecentlyAddedLabel": {}, + "editEntryDialogTargetFieldsHeader": "الحقول المراد تعديلها", + "@editEntryDialogTargetFieldsHeader": {}, + "storageVolumeDescriptionFallbackPrimary": "التخزين الداخلي", + "@storageVolumeDescriptionFallbackPrimary": {}, + "collectionActionAddShortcut": "إضافة اختصار", + "@collectionActionAddShortcut": {}, + "settingsViewerShowMinimap": "إظهار الخريطة المصغرة", + "@settingsViewerShowMinimap": {}, + "settingsCollectionBurstPatternsTile": "أنماط الانفجار", + "@settingsCollectionBurstPatternsTile": {}, + "viewerInfoLabelPath": "الطريق", + "@viewerInfoLabelPath": {}, + "albumGroupVolume": "حسب حجم التخزين", + "@albumGroupVolume": {}, + "collectionGroupMonth": "حسب الشهر", + "@collectionGroupMonth": {}, + "viewerInfoLabelResolution": "دقة", + "@viewerInfoLabelResolution": {}, + "renameProcessorCounter": "عداد", + "@renameProcessorCounter": {}, + "settingsImageBackground": "خلفية الصورة", + "@settingsImageBackground": {}, + "newAlbumDialogNameLabel": "اسم الألبوم", + "@newAlbumDialogNameLabel": {}, + "cropAspectRatioOriginal": "الأصل", + "@cropAspectRatioOriginal": {}, + "sortByDate": "حسب التاريخ", + "@sortByDate": {}, + "statsTopAlbumsSectionTitle": "أهم الألبومات", + "@statsTopAlbumsSectionTitle": {}, + "configureVaultDialogTitle": "تكوين قبو", + "@configureVaultDialogTitle": {}, + "entryActionRename": "إعادة تسمية", + "@entryActionRename": {}, + "viewerInfoLabelDuration": "المدة", + "@viewerInfoLabelDuration": {}, + "sortOrderZtoA": "من الياء إلى الألف", + "@sortOrderZtoA": {}, + "keepScreenOnNever": "أبداً", + "@keepScreenOnNever": {}, + "statsPageTitle": "احصائيات", + "@statsPageTitle": {}, + "viewerInfoSearchSuggestionDimensions": "أبعاد", + "@viewerInfoSearchSuggestionDimensions": {}, + "mapStyleOsmHot": "خرائط OSM", + "@mapStyleOsmHot": {}, + "drawerAboutButton": "حول", + "@drawerAboutButton": {}, + "aboutTranslatorsSectionTitle": "المترجمين", + "@aboutTranslatorsSectionTitle": {}, + "statsTopPlacesSectionTitle": "أهم المواقع", + "@statsTopPlacesSectionTitle": {}, + "videoStreamSelectionDialogOff": "ايقاف", + "@videoStreamSelectionDialogOff": {}, + "settingsVideoLoopModeDialogTitle": "وضع التَكرار", + "@settingsVideoLoopModeDialogTitle": {}, + "drawerCollectionImages": "الصور", + "@drawerCollectionImages": {}, + "sortOrderSmallestFirst": "الأصغر أولاً", + "@sortOrderSmallestFirst": {}, + "timeSeconds": "{seconds, plural, =1{1 ثانية} other{{seconds} ثواني}}", + "@timeSeconds": { + "placeholders": { + "seconds": {} + } + }, + "sortBySize": "حسب الحجم", + "@sortBySize": {}, + "viewerInfoSearchSuggestionDescription": "وصف", + "@viewerInfoSearchSuggestionDescription": {}, + "settingsViewerShowOverlayThumbnails": "عرض الصور المصغرة", + "@settingsViewerShowOverlayThumbnails": {}, + "collectionPickPageTitle": "اختيار", + "@collectionPickPageTitle": {}, + "settingsVideoControlsPageTitle": "ضوابط", + "@settingsVideoControlsPageTitle": {}, + "aboutBugReportButton": "تقرير", + "@aboutBugReportButton": {}, + "collectionEmptyGrantAccessButtonLabel": "منح الوصول", + "@collectionEmptyGrantAccessButtonLabel": {}, + "filterTypeMotionPhotoLabel": "الصور المتحركة", + "@filterTypeMotionPhotoLabel": {}, + "mapStyleGoogleNormal": "خرائط جوجل", + "@mapStyleGoogleNormal": {}, + "videoStreamSelectionDialogVideo": "فيديو", + "@videoStreamSelectionDialogVideo": {}, + "viewDialogLayoutSectionTitle": "تخطيط", + "@viewDialogLayoutSectionTitle": {}, + "searchStatesSectionTitle": "الولايات", + "@searchStatesSectionTitle": {}, + "filterTypeAnimatedLabel": "متحرك", + "@filterTypeAnimatedLabel": {}, + "videoLoopModeNever": "أبداً", + "@videoLoopModeNever": {}, + "settingsUnitSystemDialogTitle": "الوحدات", + "@settingsUnitSystemDialogTitle": {}, + "videoActionSetSpeed": "سرعة التشغيل", + "@videoActionSetSpeed": {}, + "dateThisMonth": "هذا الشهر", + "@dateThisMonth": {}, + "renameEntrySetPageTitle": "إعادة تسمية", + "@renameEntrySetPageTitle": {}, + "settingsConfirmationBeforeMoveToBinItems": "اسأل قبل نقل العناصر إلى سلة المحذوفات", + "@settingsConfirmationBeforeMoveToBinItems": {}, + "settingsSlideshowVideoPlaybackTile": "تشغيل الفيديو", + "@settingsSlideshowVideoPlaybackTile": {}, + "settingsHiddenFiltersEmpty": "لا يوجد مرشحات مخفية", + "@settingsHiddenFiltersEmpty": {}, + "aboutPageTitle": "حول", + "@aboutPageTitle": {}, + "sortByRating": "حسب التصنيف", + "@sortByRating": {}, + "stateEmpty": "لا توجد ولايات", + "@stateEmpty": {}, + "viewerInfoSearchEmpty": "لا توجد مفاتيح مطابقة", + "@viewerInfoSearchEmpty": {}, + "filterFavouriteLabel": "مفضل", + "@filterFavouriteLabel": {}, + "drawerCountryPage": "البلدان", + "@drawerCountryPage": {}, + "aboutBugSectionTitle": "تقرير الأخطاء", + "@aboutBugSectionTitle": {}, + "filterRatingRejectedLabel": "مرفوض", + "@filterRatingRejectedLabel": {}, + "settingsThumbnailShowLocationIcon": "إظهار رمز الموقع", + "@settingsThumbnailShowLocationIcon": {}, + "editEntryDialogCopyFromItem": "نسخ من عنصر آخر", + "@editEntryDialogCopyFromItem": {}, + "settingsStorageAccessPageTitle": "الوصُول إلى التخزين", + "@settingsStorageAccessPageTitle": {}, + "genericFailureFeedback": "فشل", + "@genericFailureFeedback": {}, + "aboutDataUsageData": "بيانات", + "@aboutDataUsageData": {}, + "settingsThemeEnableDynamicColor": "اللون الديناميكي", + "@settingsThemeEnableDynamicColor": {}, + "viewerInfoOpenEmbeddedFailureFeedback": "فشل في استخراج البيانات المضمنة", + "@viewerInfoOpenEmbeddedFailureFeedback": {}, + "aboutDataUsageInternal": "داخلي", + "@aboutDataUsageInternal": {}, + "albumDownload": "التحميل", + "@albumDownload": {}, + "coverDialogTabColor": "اللون", + "@coverDialogTabColor": {}, + "coordinateDmsWest": "غرب", + "@coordinateDmsWest": {}, + "genericSuccessFeedback": "إنتهى!", + "@genericSuccessFeedback": {}, + "videoActionMute": "كتم الصوت", + "@videoActionMute": {}, + "renameEntryDialogLabel": "اسم جديد", + "@renameEntryDialogLabel": {}, + "renameEntrySetPageInsertTooltip": "أدخل الحقل", + "@renameEntrySetPageInsertTooltip": {}, + "aboutLicensesShowAllButtonLabel": "عرض كافة التراخيص", + "@aboutLicensesShowAllButtonLabel": {}, + "settingsSubtitleThemeBackgroundOpacity": "عتامة الخلفية", + "@settingsSubtitleThemeBackgroundOpacity": {}, + "settingsStorageAccessTile": "الوصول إلى التخزين", + "@settingsStorageAccessTile": {}, + "entryActionDelete": "مسح", + "@entryActionDelete": {}, + "settingsThemeBrightnessTile": "السمَة", + "@settingsThemeBrightnessTile": {}, + "settingsViewerQuickActionEmpty": "لا يوجد أزرار", + "@settingsViewerQuickActionEmpty": {}, + "viewerInfoBackToViewerTooltip": "العودة إلى العارض", + "@viewerInfoBackToViewerTooltip": {}, + "settingsSystemDefault": "الإعداد الافتراضي للنظام", + "@settingsSystemDefault": {}, + "settingsViewerSlideshowTile": "عرض الشرائح", + "@settingsViewerSlideshowTile": {}, + "settingsCollectionTile": "مجمُوعة", + "@settingsCollectionTile": {}, + "entryActionRotateCW": "تدوير في اتجاه عقارب الساعة", + "@entryActionRotateCW": {}, + "settingsSubtitleThemeTextOpacity": "عتامة النص", + "@settingsSubtitleThemeTextOpacity": {}, + "sortOrderNewestFirst": "الأحدث أولاً", + "@sortOrderNewestFirst": {}, + "settingsViewerShowRatingTags": "عرض التصنيف والعلامات", + "@settingsViewerShowRatingTags": {}, + "drawerSettingsButton": "إعدادات", + "@drawerSettingsButton": {}, + "entryActionFlip": "عكس أفقيًا", + "@entryActionFlip": {}, + "drawerCollectionRaws": "الصور الخام", + "@drawerCollectionRaws": {}, + "settingsViewerEnableOverlayBlurEffect": "تأثير الضبابية", + "@settingsViewerEnableOverlayBlurEffect": {}, + "settingsMotionPhotoAutoPlay": "التشغيل التلقائي للصور المتحركة", + "@settingsMotionPhotoAutoPlay": {}, + "overlayHistogramRGB": "RGB", + "@overlayHistogramRGB": {}, + "settingsVideoControlsTile": "ضوابط", + "@settingsVideoControlsTile": {}, + "settingsSlideshowVideoPlaybackDialogTitle": "تَشغيل الفيديو", + "@settingsSlideshowVideoPlaybackDialogTitle": {}, + "settingsSubtitleThemeShowOutline": "إظهار الخطوط العريضة والظل", + "@settingsSubtitleThemeShowOutline": {}, + "settingsNavigationDrawerTabAlbums": "الألبومات", + "@settingsNavigationDrawerTabAlbums": {}, + "subtitlePositionBottom": "أسفل", + "@subtitlePositionBottom": {}, + "castDialogTitle": "أجهزة البث", + "@castDialogTitle": {}, + "timeDays": "{days, plural, =1{1 يوم} other{{days} أيام}}", + "@timeDays": { + "placeholders": { + "days": {} + } + }, + "videoResumeButtonLabel": "إستئناف", + "@videoResumeButtonLabel": {}, + "entryActionExport": "تصدير", + "@entryActionExport": {}, + "mapEmptyRegion": "لا توجد صور في هذه المنطقة", + "@mapEmptyRegion": {}, + "settingsVideoEnablePip": "صورة في صورة", + "@settingsVideoEnablePip": {}, + "settingsThemeBrightnessDialogTitle": "السمة", + "@settingsThemeBrightnessDialogTitle": {}, + "aboutLicensesFlutterPluginsSectionTitle": "مكونات إضافية", + "@aboutLicensesFlutterPluginsSectionTitle": {}, + "sortOrderHighestFirst": "الاعلى اولا", + "@sortOrderHighestFirst": {}, + "aboutLicensesAndroidLibrariesSectionTitle": "مكتبات أندرويد", + "@aboutLicensesAndroidLibrariesSectionTitle": {}, + "settingsViewerQuickActionsTile": "إجراءات سريعة", + "@settingsViewerQuickActionsTile": {}, + "entryActionAddFavourite": "إضافة إلى المفضلة", + "@entryActionAddFavourite": {}, + "entryActionEdit": "تحرير", + "@entryActionEdit": {}, + "newVaultDialogTitle": "قبو جديد", + "@newVaultDialogTitle": {}, + "entryInfoActionEditRating": "تحرير التقييم", + "@entryInfoActionEditRating": {}, + "timeMinutes": "{minutes, plural, =1{1 دقيقة} other{{minutes} دقائق}}", + "@timeMinutes": { + "placeholders": { + "minutes": {} + } + }, + "albumTierSpecial": "شائع", + "@albumTierSpecial": {}, + "settingsSubtitleThemePageTitle": "ترجمات", + "@settingsSubtitleThemePageTitle": {}, + "settingsSubtitleThemeTextPositionTile": "موضع النص", + "@settingsSubtitleThemeTextPositionTile": {}, + "entryActionRestore": "استعادة", + "@entryActionRestore": {}, + "entryActionCopyToClipboard": "نسخ إلى الحافظة", + "@entryActionCopyToClipboard": {}, + "viewerInfoLabelAddress": "العنوان", + "@viewerInfoLabelAddress": {}, + "settingsVideoBackgroundModeDialogTitle": "وضع الخلـفية", + "@settingsVideoBackgroundModeDialogTitle": {}, + "binPageTitle": "سلة المحذوفات", + "@binPageTitle": {}, + "tagPlaceholderState": "ولاية", + "@tagPlaceholderState": {}, + "sortByAlbumFileName": "حسب الألبوم واسم الملف", + "@sortByAlbumFileName": {}, + "deleteMultiAlbumConfirmationDialogMessage": "{count, plural, =1{هل تريد حذف هذه الألبومات والعنصر الموجود فيها؟} other{احذف هذه الألبومات و {count} العناصر فيها؟}}", + "@deleteMultiAlbumConfirmationDialogMessage": { + "placeholders": { + "count": {} + } + }, + "settingsSubtitleThemeTextSize": "حجم الخط", + "@settingsSubtitleThemeTextSize": {}, + "aboutLicensesSectionTitle": "تراخيص مفتوحة المصدر", + "@aboutLicensesSectionTitle": {}, + "menuActionStats": "احصائيات", + "@menuActionStats": {}, + "settingsCollectionQuickActionTabBrowsing": "التصفح", + "@settingsCollectionQuickActionTabBrowsing": {}, + "chipActionCreateAlbum": "إنشاء ألبوم", + "@chipActionCreateAlbum": {}, + "videoLoopModeShortOnly": "فيديوهات قصيرة فقط", + "@videoLoopModeShortOnly": {}, + "deleteSingleAlbumConfirmationDialogMessage": "{count, plural, =1{هل تريد حذف هذا الألبوم والعنصر الموجود فيه؟} other{احذف هذا الألبوم و {count} العناصر فيه؟}}", + "@deleteSingleAlbumConfirmationDialogMessage": { + "placeholders": { + "count": {} + } + }, + "settingsThemeColorHighlights": "تحديد الألوان", + "@settingsThemeColorHighlights": {}, + "appPickDialogTitle": "اختر التطبيق", + "@appPickDialogTitle": {}, + "settingsHiddenItemsTabPaths": "المسارات المخفية", + "@settingsHiddenItemsTabPaths": {}, + "viewerInfoSearchSuggestionRights": "حقوق", + "@viewerInfoSearchSuggestionRights": {}, + "mapPointNorthUpTooltip": "نقطة الشمال لأعلى", + "@mapPointNorthUpTooltip": {}, + "entryInfoActionRemoveLocation": "إزالة الموقع", + "@entryInfoActionRemoveLocation": {}, + "collectionDeleteFailureFeedback": "{count, plural, =1{فشل حذف عنصر واحد} other{فشل الحذف {count} items}}", + "@collectionDeleteFailureFeedback": { + "placeholders": { + "count": {} + } + }, + "entryActionShareImageOnly": "مشاركة الصورة فقط", + "@entryActionShareImageOnly": {}, + "settingsVideoButtonsTile": "أزرار", + "@settingsVideoButtonsTile": {}, + "settingsSubtitleThemeSample": "هذه عينة.", + "@settingsSubtitleThemeSample": {}, + "albumPickPageTitleMove": "انتقل إلى الألبوم", + "@albumPickPageTitleMove": {}, + "settingsSaveSearchHistory": "حفظ سجل البحث", + "@settingsSaveSearchHistory": {}, + "settingsViewerShowHistogram": "إظهار الرسم البياني", + "@settingsViewerShowHistogram": {}, + "aboutBugCopyInfoButton": "نسخ", + "@aboutBugCopyInfoButton": {}, + "mapStyleGoogleHybrid": "خرائط جوجل (الهجينة)", + "@mapStyleGoogleHybrid": {}, + "wallpaperTargetHomeLock": "الشاشة الرئيسية وشاشة القفل", + "@wallpaperTargetHomeLock": {}, + "coverDialogTabCover": "غلاف", + "@coverDialogTabCover": {}, + "settingsVideoPlaybackTile": "التشغيل", + "@settingsVideoPlaybackTile": {}, + "filterNoDateLabel": "غير مؤرخ", + "@filterNoDateLabel": {}, + "exportEntryDialogWriteMetadata": "كتابة البيانات الوصفية", + "@exportEntryDialogWriteMetadata": {} } diff --git a/lib/l10n/app_be.arb b/lib/l10n/app_be.arb index 04857893c..2d919b3fd 100644 --- a/lib/l10n/app_be.arb +++ b/lib/l10n/app_be.arb @@ -166,30 +166,6 @@ "@slideshowActionResume": {}, "viewerActionUnlock": "Разблакіроўка прагляду", "@viewerActionUnlock": {}, - "columnCount": "{count, plural, =1{1 column} other{{count} columns}}", - "@columnCount": { - "placeholders": { - "count": {} - } - }, - "timeSeconds": "{seconds, plural, =1{1 second} other{{seconds} seconds}}", - "@timeSeconds": { - "placeholders": { - "seconds": {} - } - }, - "timeMinutes": "{minutes, plural, =1{1 minute} other{{minutes} minutes}}", - "@timeMinutes": { - "placeholders": { - "minutes": {} - } - }, - "timeDays": "{days, plural, =1{1 day} other{{days} days}}", - "@timeDays": { - "placeholders": { - "days": {} - } - }, "entryActionExport": "Экспарт", "@entryActionExport": {}, "entryActionInfo": "Інфармацыя", @@ -236,7 +212,7 @@ "@cropAspectRatioOriginal": {}, "cropAspectRatioSquare": "Квадратнае", "@cropAspectRatioSquare": {}, - "coordinateDmsNorth": "Поўнач", + "coordinateDmsNorth": "Пн", "@coordinateDmsNorth": {}, "filterAspectRatioPortraitLabel": "Партрэтныя", "@filterAspectRatioPortraitLabel": {}, @@ -295,7 +271,7 @@ "@filterNoDateLabel": {}, "filterNoAddressLabel": "Без адрасу", "@filterNoAddressLabel": {}, - "filterLocatedLabel": "Месцазнаходжанне", + "filterLocatedLabel": "Размешчаны", "@filterLocatedLabel": {}, "filterNoLocationLabel": "Без месцазнаходжання", "@filterNoLocationLabel": {}, @@ -325,11 +301,11 @@ "@albumTierVaults": {}, "albumTierSpecial": "Стандартныя", "@albumTierSpecial": {}, - "coordinateDmsSouth": "Поўдзень", + "coordinateDmsSouth": "Пд", "@coordinateDmsSouth": {}, - "coordinateDmsEast": "Усход", + "coordinateDmsEast": "У", "@coordinateDmsEast": {}, - "coordinateDmsWest": "Захад", + "coordinateDmsWest": "З", "@coordinateDmsWest": {}, "displayRefreshRatePreferHighest": "Найвышэйшая частата", "@displayRefreshRatePreferHighest": {}, @@ -415,7 +391,7 @@ "@storageVolumeDescriptionFallbackNonPrimary": {}, "rootDirectoryDescription": "каранёвы каталог", "@rootDirectoryDescription": {}, - "otherDirectoryDescription": "Каталог “{name}”", + "otherDirectoryDescription": "Каталог «{name}»", "@otherDirectoryDescription": { "placeholders": { "name": { @@ -439,7 +415,7 @@ } } }, - "notEnoughSpaceDialogMessage": "Для завяршэння гэтай аперацыі патрабуецца {neededSize} вольнага месца на “{volume}”, але засталося толькі {freeSize}.", + "notEnoughSpaceDialogMessage": "Для завяршэння гэтай аперацыі патрабуецца {neededSize} вольнага месца на «{volume}», але засталося толькі {freeSize}.", "@notEnoughSpaceDialogMessage": { "placeholders": { "neededSize": { @@ -830,5 +806,717 @@ "settingsThemeColorHighlights": "Каляровыя акцэнты", "@settingsThemeColorHighlights": {}, "exportEntryDialogWriteMetadata": "Запісаць метададзеныя", - "@exportEntryDialogWriteMetadata": {} + "@exportEntryDialogWriteMetadata": {}, + "aboutCreditsWorldAtlas2": "пад ліцэнзіяй ISC.", + "@aboutCreditsWorldAtlas2": {}, + "settingsPrivacySectionTitle": "Канфідэнцыяльнасць", + "@settingsPrivacySectionTitle": {}, + "albumScreenRecordings": "Запісы экрана", + "@albumScreenRecordings": {}, + "editEntryRatingDialogTitle": "Рэйтынг", + "@editEntryRatingDialogTitle": {}, + "aboutDataUsageMisc": "Розныя", + "@aboutDataUsageMisc": {}, + "albumVideoCaptures": "Відэазапісы", + "@albumVideoCaptures": {}, + "editEntryDateDialogSetCustom": "Усталяваць карыстацкую дату", + "@editEntryDateDialogSetCustom": {}, + "settingsSearchEmpty": "Няма адпаведнай налады", + "@settingsSearchEmpty": {}, + "removeEntryMetadataDialogMore": "Больш", + "@removeEntryMetadataDialogMore": {}, + "tooManyItemsErrorDialogMessage": "Паўтарыце спробу з меншай колькасцю элементаў.", + "@tooManyItemsErrorDialogMessage": {}, + "collectionActionEdit": "Рэдагаваць", + "@collectionActionEdit": {}, + "sortOrderLargestFirst": "Спачатку вялікія", + "@sortOrderLargestFirst": {}, + "editEntryDateDialogSourceFileModifiedDate": "Дата змены файла", + "@editEntryDateDialogSourceFileModifiedDate": {}, + "collectionEmptyFavourites": "Няма абраных", + "@collectionEmptyFavourites": {}, + "removeEntryMetadataDialogTitle": "Выдаленне метададзеных", + "@removeEntryMetadataDialogTitle": {}, + "drawerCollectionVideos": "Відэа", + "@drawerCollectionVideos": {}, + "countryEmpty": "Няма краін", + "@countryEmpty": {}, + "collectionSelectSectionTooltip": "Выбраць раздзел", + "@collectionSelectSectionTooltip": {}, + "aboutLicensesBanner": "Гэта праграма выкарыстоўвае наступныя пакеты і бібліятэкі з адкрытым зыходным кодам.", + "@aboutLicensesBanner": {}, + "dateYesterday": "Учора", + "@dateYesterday": {}, + "aboutDataUsageDatabase": "База дадзеных", + "@aboutDataUsageDatabase": {}, + "tileLayoutMosaic": "Мазаіка", + "@tileLayoutMosaic": {}, + "collectionDeselectSectionTooltip": "Адмяніць выбар раздзела", + "@collectionDeselectSectionTooltip": {}, + "settingsKeepScreenOnTile": "Трымаць экран уключаным", + "@settingsKeepScreenOnTile": {}, + "tileLayoutGrid": "Сетка", + "@tileLayoutGrid": {}, + "aboutCreditsWorldAtlas1": "Гэта праграма выкарыстоўвае файл TopoJSON з", + "@aboutCreditsWorldAtlas1": {}, + "appExportCovers": "Вокладкі", + "@appExportCovers": {}, + "createAlbumButtonLabel": "СТВАРЫЦЬ", + "@createAlbumButtonLabel": {}, + "menuActionSlideshow": "Слайд-шоў", + "@menuActionSlideshow": {}, + "settingsConfirmationDialogTitle": "Дыялогі пацверджання", + "@settingsConfirmationDialogTitle": {}, + "videoStreamSelectionDialogText": "Субтытры", + "@videoStreamSelectionDialogText": {}, + "editEntryDateDialogShift": "Зрух", + "@editEntryDateDialogShift": {}, + "appExportSettings": "Налады", + "@appExportSettings": {}, + "searchPlacesSectionTitle": "Месцы", + "@searchPlacesSectionTitle": {}, + "videoStreamSelectionDialogAudio": "Аўдыё", + "@videoStreamSelectionDialogAudio": {}, + "videoSpeedDialogLabel": "Хуткасць прайгравання", + "@videoSpeedDialogLabel": {}, + "editEntryLocationDialogSetCustom": "Устанавіць карыстацкае месцазнаходжанне", + "@editEntryLocationDialogSetCustom": {}, + "placeEmpty": "Няма месцаў", + "@placeEmpty": {}, + "editEntryDateDialogExtractFromTitle": "Выняць з загалоўка", + "@editEntryDateDialogExtractFromTitle": {}, + "aboutLinkLicense": "Ліцэнзія", + "@aboutLinkLicense": {}, + "albumScreenshots": "Скрыншоты", + "@albumScreenshots": {}, + "editEntryLocationDialogLongitude": "Даўгата", + "@editEntryLocationDialogLongitude": {}, + "searchCountriesSectionTitle": "Краіны", + "@searchCountriesSectionTitle": {}, + "settingsAskEverytime": "Пытацца кожны раз", + "@settingsAskEverytime": {}, + "editEntryDateDialogCopyField": "Капіяваць з іншай даты", + "@editEntryDateDialogCopyField": {}, + "searchTagsSectionTitle": "Тэгі", + "@searchTagsSectionTitle": {}, + "settingsModificationWarningDialogMessage": "Іншыя налады будуць зменены.", + "@settingsModificationWarningDialogMessage": {}, + "policyPageTitle": "Палітыка канфідэнцыяльнасці", + "@policyPageTitle": {}, + "tileLayoutList": "Спіс", + "@tileLayoutList": {}, + "appPickDialogNone": "Нічога", + "@appPickDialogNone": {}, + "settingsActionExport": "Экспарт", + "@settingsActionExport": {}, + "sortOrderOldestFirst": "Спачатку самы стары", + "@sortOrderOldestFirst": {}, + "coverDialogTabApp": "Праграма", + "@coverDialogTabApp": {}, + "removeEntryMetadataMotionPhotoXmpWarningDialogMessage": "XMP патрабуецца для прайгравання відэа ўнутры фота з рухам.\n\nВы ўпэўнены, што хочаце выдаліць яго?", + "@removeEntryMetadataMotionPhotoXmpWarningDialogMessage": {}, + "tagPageTitle": "Тэгі", + "@tagPageTitle": {}, + "collectionEmptyVideos": "Няма відэа", + "@collectionEmptyVideos": {}, + "aboutCreditsSectionTitle": "Падзякі", + "@aboutCreditsSectionTitle": {}, + "drawerAlbumPage": "Альбомы", + "@drawerAlbumPage": {}, + "settingsActionImport": "Імпарт", + "@settingsActionImport": {}, + "locationPickerUseThisLocationButton": "Выкарыстоўваць гэтае месца", + "@locationPickerUseThisLocationButton": {}, + "collectionGroupNone": "Не групаваць", + "@collectionGroupNone": {}, + "searchRatingSectionTitle": "Рэйтынгі", + "@searchRatingSectionTitle": {}, + "settingsDisabled": "Адключана", + "@settingsDisabled": {}, + "settingsActionImportDialogTitle": "Імпарт", + "@settingsActionImportDialogTitle": {}, + "albumGroupTier": "Па ўзроўні", + "@albumGroupTier": {}, + "drawerCollectionAll": "Уся калекцыя", + "@drawerCollectionAll": {}, + "sortByItemCount": "Па колькасці элементаў", + "@sortByItemCount": {}, + "sectionUnknown": "Невядома", + "@sectionUnknown": {}, + "dateToday": "Сёння", + "@dateToday": {}, + "videoStreamSelectionDialogNoSelection": "Іншых трэкаў няма.", + "@videoStreamSelectionDialogNoSelection": {}, + "searchRecentSectionTitle": "Апошнія", + "@searchRecentSectionTitle": {}, + "albumPickPageTitlePick": "Выбраць Альбом", + "@albumPickPageTitlePick": {}, + "menuActionMap": "Карта", + "@menuActionMap": {}, + "collectionActionMove": "Перамясціць у альбом", + "@collectionActionMove": {}, + "searchAlbumsSectionTitle": "Альбомы", + "@searchAlbumsSectionTitle": {}, + "viewDialogGroupSectionTitle": "Групоўка", + "@viewDialogGroupSectionTitle": {}, + "aboutDataUsageSectionTitle": "Выкарыстанне дадзеных", + "@aboutDataUsageSectionTitle": {}, + "durationDialogSeconds": "Секунды", + "@durationDialogSeconds": {}, + "albumEmpty": "Няма альбомаў", + "@albumEmpty": {}, + "editEntryLocationDialogChooseOnMap": "Выбраць на карце", + "@editEntryLocationDialogChooseOnMap": {}, + "sortByName": "Па назве", + "@sortByName": {}, + "settingsHomeDialogTitle": "Галоўная", + "@settingsHomeDialogTitle": {}, + "searchDateSectionTitle": "Дата", + "@searchDateSectionTitle": {}, + "collectionSearchTitlesHintText": "Пошук загалоўкаў", + "@collectionSearchTitlesHintText": {}, + "searchCollectionFieldHint": "Пошук калекцый", + "@searchCollectionFieldHint": {}, + "settingsDoubleBackExit": "Двойчы націсніце «назад», каб выйсці", + "@settingsDoubleBackExit": {}, + "drawerCollectionSphericalVideos": "360° Відэа", + "@drawerCollectionSphericalVideos": {}, + "searchMetadataSectionTitle": "Метададзеныя", + "@searchMetadataSectionTitle": {}, + "settingsShowBottomNavigationBar": "Паказаць ніжнюю панэль навігацыі", + "@settingsShowBottomNavigationBar": {}, + "collectionActionEmptyBin": "Ачысціць кошык", + "@collectionActionEmptyBin": {}, + "sortOrderAtoZ": "Ад А да Я", + "@sortOrderAtoZ": {}, + "videoStreamSelectionDialogTrack": "Трэк", + "@videoStreamSelectionDialogTrack": {}, + "settingsHomeTile": "Галоўная", + "@settingsHomeTile": {}, + "collectionGroupDay": "Па днях", + "@collectionGroupDay": {}, + "collectionGroupAlbum": "Па альбоме", + "@collectionGroupAlbum": {}, + "newFilterBanner": "новы", + "@newFilterBanner": {}, + "drawerCollectionFavourites": "Абраныя", + "@drawerCollectionFavourites": {}, + "aboutLicensesFlutterPackagesSectionTitle": "Пакеты Flutter", + "@aboutLicensesFlutterPackagesSectionTitle": {}, + "statePageTitle": "Штаты", + "@statePageTitle": {}, + "drawerTagPage": "Тэгі", + "@drawerTagPage": {}, + "durationDialogMinutes": "Хвіліны", + "@durationDialogMinutes": {}, + "albumPageTitle": "Альбомы", + "@albumPageTitle": {}, + "editEntryLocationDialogTitle": "Месцазнаходжанне", + "@editEntryLocationDialogTitle": {}, + "albumPickPageTitleCopy": "Капіюваць у альбом", + "@albumPickPageTitleCopy": {}, + "collectionActionCopy": "Скапіюваць у альбом", + "@collectionActionCopy": {}, + "viewDialogReverseSortOrder": "Адваротны парадак сартавання", + "@viewDialogReverseSortOrder": {}, + "menuActionConfigureView": "Выгляд", + "@menuActionConfigureView": {}, + "aboutLicensesDartPackagesSectionTitle": "Пакеты Dart", + "@aboutLicensesDartPackagesSectionTitle": {}, + "drawerCollectionMotionPhotos": "Фота з рухам", + "@drawerCollectionMotionPhotos": {}, + "settingsDefault": "Па змаўчанні", + "@settingsDefault": {}, + "placePageTitle": "Месцы", + "@placePageTitle": {}, + "tagEmpty": "Няма тэгаў", + "@tagEmpty": {}, + "collectionActionShowTitleSearch": "Паказаць фільтр загалоўка", + "@collectionActionShowTitleSearch": {}, + "menuActionSelectAll": "Выбраць усё", + "@menuActionSelectAll": {}, + "settingsConfirmationTile": "Дыялогі пацверджання", + "@settingsConfirmationTile": {}, + "albumMimeTypeMixed": "Змешаны", + "@albumMimeTypeMixed": {}, + "aboutLinkPolicy": "Палітыка канфідэнцыяльнасці", + "@aboutLinkPolicy": {}, + "sortOrderLowestFirst": "Спачатку з нізкім", + "@sortOrderLowestFirst": {}, + "albumGroupNone": "Не групаваць", + "@albumGroupNone": {}, + "countryPageTitle": "Краіны", + "@countryPageTitle": {}, + "albumGroupType": "Па тыпу", + "@albumGroupType": {}, + "albumCamera": "Камера", + "@albumCamera": {}, + "settingsNavigationSectionTitle": "Навігацыя", + "@settingsNavigationSectionTitle": {}, + "collectionActionHideTitleSearch": "Схаваць фільтр загалоўка", + "@collectionActionHideTitleSearch": {}, + "drawerCollectionAnimated": "Анімацыі", + "@drawerCollectionAnimated": {}, + "durationDialogHours": "Гадзіны", + "@durationDialogHours": {}, + "settingsKeepScreenOnDialogTitle": "Трымаць экран уключаным", + "@settingsKeepScreenOnDialogTitle": {}, + "drawerPlacePage": "Месцы", + "@drawerPlacePage": {}, + "menuActionSelect": "Выбраць", + "@menuActionSelect": {}, + "drawerCollectionPanoramas": "Панарамы", + "@drawerCollectionPanoramas": {}, + "settingsPageTitle": "Налады", + "@settingsPageTitle": {}, + "menuActionSelectNone": "Зняць вылучэнне", + "@menuActionSelectNone": {}, + "settingsSearchFieldLabel": "Пошук налад", + "@settingsSearchFieldLabel": {}, + "appExportFavourites": "Абранае", + "@appExportFavourites": {}, + "collectionEmptyImages": "Няма выяў", + "@collectionEmptyImages": {}, + "albumPickPageTitleExport": "Экспартаваць у альбом", + "@albumPickPageTitleExport": {}, + "settingsActionExportDialogTitle": "Экспарт", + "@settingsActionExportDialogTitle": {}, + "genericDangerWarningDialogMessage": "Вы ўпэўнены?", + "@genericDangerWarningDialogMessage": {}, + "aboutDataUsageExternal": "Знешні", + "@aboutDataUsageExternal": {}, + "collectionSelectPageTitle": "Выбраць элементы", + "@collectionSelectPageTitle": {}, + "editEntryLocationDialogLatitude": "Шырата", + "@editEntryLocationDialogLatitude": {}, + "collectionActionRescan": "Паўторнае сканаванне", + "@collectionActionRescan": {}, + "viewDialogSortSectionTitle": "Сартаваць", + "@viewDialogSortSectionTitle": {}, + "collectionPageTitle": "Калекцыя", + "@collectionPageTitle": {}, + "collectionActionAddShortcut": "Дадаць ярлык", + "@collectionActionAddShortcut": {}, + "albumGroupVolume": "Па аб'ёме захоўвання", + "@albumGroupVolume": {}, + "collectionGroupMonth": "Па месяцу", + "@collectionGroupMonth": {}, + "sortByDate": "Па даце", + "@sortByDate": {}, + "sortOrderZtoA": "Ад Я да А", + "@sortOrderZtoA": {}, + "drawerAboutButton": "Пра нас", + "@drawerAboutButton": {}, + "aboutTranslatorsSectionTitle": "Перакладчыкі", + "@aboutTranslatorsSectionTitle": {}, + "videoStreamSelectionDialogOff": "Адкл.", + "@videoStreamSelectionDialogOff": {}, + "drawerCollectionImages": "Выявы", + "@drawerCollectionImages": {}, + "sortOrderSmallestFirst": "Спачатку маленькі", + "@sortOrderSmallestFirst": {}, + "sortBySize": "Па памеры", + "@sortBySize": {}, + "collectionPickPageTitle": "Выбраць", + "@collectionPickPageTitle": {}, + "collectionEmptyGrantAccessButtonLabel": "Даць доступ", + "@collectionEmptyGrantAccessButtonLabel": {}, + "videoStreamSelectionDialogVideo": "Відэа", + "@videoStreamSelectionDialogVideo": {}, + "viewDialogLayoutSectionTitle": "Макет", + "@viewDialogLayoutSectionTitle": {}, + "searchStatesSectionTitle": "Штаты", + "@searchStatesSectionTitle": {}, + "dateThisMonth": "У гэтым месяцы", + "@dateThisMonth": {}, + "aboutPageTitle": "Пра нас", + "@aboutPageTitle": {}, + "sortByRating": "Па рэйтынгу", + "@sortByRating": {}, + "stateEmpty": "Няма штатаў", + "@stateEmpty": {}, + "drawerCountryPage": "Краіны", + "@drawerCountryPage": {}, + "genericFailureFeedback": "Не атрымалася", + "@genericFailureFeedback": {}, + "aboutDataUsageData": "Дадзеныя", + "@aboutDataUsageData": {}, + "aboutDataUsageInternal": "Унутраны", + "@aboutDataUsageInternal": {}, + "albumDownload": "Загрузкі", + "@albumDownload": {}, + "coverDialogTabColor": "Колер", + "@coverDialogTabColor": {}, + "genericSuccessFeedback": "Гатова!", + "@genericSuccessFeedback": {}, + "aboutLicensesShowAllButtonLabel": "Паказаць усе ліцэнзіі", + "@aboutLicensesShowAllButtonLabel": {}, + "sortOrderNewestFirst": "Спачатку самае новае", + "@sortOrderNewestFirst": {}, + "drawerSettingsButton": "Налады", + "@drawerSettingsButton": {}, + "drawerCollectionRaws": "Raw фатаграфіі", + "@drawerCollectionRaws": {}, + "castDialogTitle": "Прылады трансляцыі", + "@castDialogTitle": {}, + "aboutLicensesFlutterPluginsSectionTitle": "Плагіны Flutter", + "@aboutLicensesFlutterPluginsSectionTitle": {}, + "sortOrderHighestFirst": "Спачатку з высокім", + "@sortOrderHighestFirst": {}, + "aboutLicensesAndroidLibrariesSectionTitle": "Бібліятэкі Android", + "@aboutLicensesAndroidLibrariesSectionTitle": {}, + "binPageTitle": "Кошык", + "@binPageTitle": {}, + "sortByAlbumFileName": "Па назве альбома і файла", + "@sortByAlbumFileName": {}, + "aboutLicensesSectionTitle": "Ліцэнзіі з адкрытым зыходным кодам", + "@aboutLicensesSectionTitle": {}, + "menuActionStats": "Статыстыка", + "@menuActionStats": {}, + "appPickDialogTitle": "Выбраць праграму", + "@appPickDialogTitle": {}, + "albumPickPageTitleMove": "Перамясціць у альбом", + "@albumPickPageTitleMove": {}, + "coverDialogTabCover": "Вокладка", + "@coverDialogTabCover": {}, + "settingsConfirmationBeforeDeleteItems": "Спытаць, перш чым выдаляць элементы назаўжды", + "@settingsConfirmationBeforeDeleteItems": {}, + "settingsConfirmationBeforeMoveUndatedItems": "Спытаць, перш чым перамяшчаць прадметы без даты", + "@settingsConfirmationBeforeMoveUndatedItems": {}, + "settingsConfirmationAfterMoveToBinItems": "Паказваць паведамленне пасля перамяшчэння элементаў у кошык", + "@settingsConfirmationAfterMoveToBinItems": {}, + "settingsConfirmationBeforeMoveToBinItems": "Спытаць, перш чым перамяшчаць элементы ў кошык", + "@settingsConfirmationBeforeMoveToBinItems": {}, + "settingsNavigationDrawerAddAlbum": "Дадаць альбом", + "@settingsNavigationDrawerAddAlbum": {}, + "settingsEnableBinSubtitle": "Захоўвае выдаленыя элементы на працягу 30 дзён", + "@settingsEnableBinSubtitle": {}, + "settingsThumbnailShowRating": "Паказаць рэйтынг", + "@settingsThumbnailShowRating": {}, + "collectionExportFailureFeedback": "{count, plural, =1{Не атрымалася экспартаваць 1 старонку} few{Не атрымалася экспартаваць {count} старонкі} other{Не атрымалася экспартаваць {count} старонак}}", + "@collectionExportFailureFeedback": { + "placeholders": { + "count": {} + } + }, + "settingsSubtitleThemeTextAlignmentDialogTitle": "Выраўноўванне тэксту", + "@settingsSubtitleThemeTextAlignmentDialogTitle": {}, + "settingsViewerSlideshowPageTitle": "Слайд-шоў", + "@settingsViewerSlideshowPageTitle": {}, + "settingsViewerSectionTitle": "Прагляднік", + "@settingsViewerSectionTitle": {}, + "settingsAllowInstalledAppAccessSubtitle": "Выкарыстоўваецца для паляпшэння адлюстравання альбомаў", + "@settingsAllowInstalledAppAccessSubtitle": {}, + "collectionMoveFailureFeedback": "{count, plural, =1{Немагчыма перанесці 1 элемент} few{Немагчыма перанесці {count} элементы} other{Немагчыма перанесці {count} элементаў}}", + "@collectionMoveFailureFeedback": { + "placeholders": { + "count": {} + } + }, + "settingsSubtitleThemeTextColor": "Колер тэксту", + "@settingsSubtitleThemeTextColor": {}, + "settingsVideoSectionTitle": "Відэа", + "@settingsVideoSectionTitle": {}, + "settingsSubtitleThemeBackgroundColor": "Колер фону", + "@settingsSubtitleThemeBackgroundColor": {}, + "settingsThumbnailOverlayTile": "Навязванне", + "@settingsThumbnailOverlayTile": {}, + "settingsNavigationDrawerTabPages": "Старонкі", + "@settingsNavigationDrawerTabPages": {}, + "settingsVideoAutoPlay": "Аўтапрайграванне", + "@settingsVideoAutoPlay": {}, + "settingsVideoEnableHardwareAcceleration": "Апаратнае паскарэнне", + "@settingsVideoEnableHardwareAcceleration": {}, + "settingsCollectionSelectionQuickActionEditorBanner": "Націсніце і ўтрымлівайце, каб перамясціць кнопкі і выбраць дзеянні, якія будуць адлюстроўвацца пры выбары элементаў.", + "@settingsCollectionSelectionQuickActionEditorBanner": {}, + "settingsSlideshowShuffle": "Ператасаваць", + "@settingsSlideshowShuffle": {}, + "settingsThumbnailSectionTitle": "Мініяцюры", + "@settingsThumbnailSectionTitle": {}, + "settingsVideoShowVideos": "Паказаць відэа", + "@settingsVideoShowVideos": {}, + "settingsViewerShowInformation": "Паказаць інфармацыю", + "@settingsViewerShowInformation": {}, + "settingsCollectionQuickActionsTile": "Хуткія дзеянні", + "@settingsCollectionQuickActionsTile": {}, + "settingsViewerOverlayTile": "Навязванне", + "@settingsViewerOverlayTile": {}, + "settingsThumbnailShowFavouriteIcon": "Паказаць значок абранага", + "@settingsThumbnailShowFavouriteIcon": {}, + "settingsSubtitleThemeTextPositionDialogTitle": "Палажэнне тэксту", + "@settingsSubtitleThemeTextPositionDialogTitle": {}, + "settingsSlideshowIntervalTile": "Інтэрвал", + "@settingsSlideshowIntervalTile": {}, + "settingsCollectionQuickActionEditorPageTitle": "Хуткія дзеянні", + "@settingsCollectionQuickActionEditorPageTitle": {}, + "settingsStorageAccessRevokeTooltip": "Адклікаць", + "@settingsStorageAccessRevokeTooltip": {}, + "settingsSubtitleThemeTile": "Субтытры", + "@settingsSubtitleThemeTile": {}, + "settingsVideoGestureVerticalDragBrightnessVolume": "Правядзіце пальцам уверх ці ўніз, каб наладзіць яркасць/гучнасць", + "@settingsVideoGestureVerticalDragBrightnessVolume": {}, + "settingsAccessibilitySectionTitle": "Спецыяльныя магчымасці", + "@settingsAccessibilitySectionTitle": {}, + "collectionRenameFailureFeedback": "{count, plural, =1{Не атрымалася перайменаваць 1 элемент} few{Не атрымалася перайменаваць {count} элементы} other{Не атрымалася перайменаваць {count} элементаў}}", + "@collectionRenameFailureFeedback": { + "placeholders": { + "count": {} + } + }, + "collectionEditSuccessFeedback": "{count, plural, =1{1 элемент адрэдагаваны} few{{count} элементы адрэдагаваны} other{{count} элементаў адрэдагаваны}}", + "@collectionEditSuccessFeedback": { + "placeholders": { + "count": {} + } + }, + "settingsThumbnailShowMotionPhotoIcon": "Паказаць значок фота з рухам", + "@settingsThumbnailShowMotionPhotoIcon": {}, + "settingsThumbnailShowRawIcon": "Паказаць значок raw", + "@settingsThumbnailShowRawIcon": {}, + "settingsSlideshowFillScreen": "Запоўніць экран", + "@settingsSlideshowFillScreen": {}, + "settingsHiddenFiltersBanner": "Фота і відэа, якія адпавядаюць схаваным фільтрам, не будуць адлюстроўвацца ў вашай калекцыі.", + "@settingsHiddenFiltersBanner": {}, + "settingsVideoResumptionModeTile": "Працягнуць прайграванне", + "@settingsVideoResumptionModeTile": {}, + "collectionCopyFailureFeedback": "{count, plural, =1{Не атрымалася скапіюваць 1 элемент} few{Не атрымалася скапіюваць {count} элементы} other{Не атрымалася скапіюваць {count} элементаў}}", + "@collectionCopyFailureFeedback": { + "placeholders": { + "count": {} + } + }, + "settingsVideoGestureDoubleTapTogglePlay": "Двойчы націсніце, каб прайграць/прыпыніць", + "@settingsVideoGestureDoubleTapTogglePlay": {}, + "addPathTooltip": "Дадаць шлях", + "@addPathTooltip": {}, + "settingsEnableBin": "Выкарыстоўваць кошык", + "@settingsEnableBin": {}, + "collectionMoveSuccessFeedback": "{count, plural, =1{Перамяшчаны 1 элемент} few{Перамяшчаны {count} элементы} other{Перамяшчаны {count} элементаў}}", + "@collectionMoveSuccessFeedback": { + "placeholders": { + "count": {} + } + }, + "settingsSubtitleThemeTextAlignmentLeft": "Злева", + "@settingsSubtitleThemeTextAlignmentLeft": {}, + "settingsVideoGestureSideDoubleTapSeek": "Двойчы націсніце на край экрана, каб перайсці назад/наперад", + "@settingsVideoGestureSideDoubleTapSeek": {}, + "settingsSubtitleThemeTextAlignmentRight": "Справа", + "@settingsSubtitleThemeTextAlignmentRight": {}, + "settingsAllowMediaManagement": "Дазволіць кіраванне мультымедыя", + "@settingsAllowMediaManagement": {}, + "settingsCollectionBrowsingQuickActionEditorBanner": "Націсніце і ўтрымлівайце, каб перамясціць кнопкі і выбраць дзеянні, якія будуць адлюстроўвацца пры праглядзе элементаў.", + "@settingsCollectionBrowsingQuickActionEditorBanner": {}, + "collectionEditFailureFeedback": "{count, plural, =1{Немагчыма адрэдагаваць 1 элемент} few{Немагчыма адрэдагаваць {count} элементы} other{Немагчыма адрэдагаваць {count} элементаў}}", + "@collectionEditFailureFeedback": { + "placeholders": { + "count": {} + } + }, + "settingsThumbnailOverlayPageTitle": "Навязванне", + "@settingsThumbnailOverlayPageTitle": {}, + "settingsViewerShowInformationSubtitle": "Паказаць назву, дату, месцазнаходжанне і г.д.", + "@settingsViewerShowInformationSubtitle": {}, + "settingsSlideshowRepeat": "Паўтарэнне", + "@settingsSlideshowRepeat": {}, + "settingsViewerQuickActionEditorPageTitle": "Хуткія дзеянні", + "@settingsViewerQuickActionEditorPageTitle": {}, + "settingsVideoPageTitle": "Налады відэа", + "@settingsVideoPageTitle": {}, + "collectionRenameSuccessFeedback": "{count, plural, =1{Перайменаваны 1 элемент} few{Перайменаваны {count} элементы} other{Перайменаваны {count} элементаў}}", + "@collectionRenameSuccessFeedback": { + "placeholders": { + "count": {} + } + }, + "settingsViewerUseCutout": "Выкарыстоўваць вобласць выраза", + "@settingsViewerUseCutout": {}, + "settingsViewerGestureSideTapNext": "Дакраніцеся да краёў экрана, каб паказаць папярэдні/наступны элемент", + "@settingsViewerGestureSideTapNext": {}, + "settingsSubtitleThemeTextAlignmentCenter": "Па цэнтры", + "@settingsSubtitleThemeTextAlignmentCenter": {}, + "settingsSubtitleThemeTextAlignmentTile": "Выраўноўванне тэксту", + "@settingsSubtitleThemeTextAlignmentTile": {}, + "settingsCollectionQuickActionTabSelecting": "Выбар", + "@settingsCollectionQuickActionTabSelecting": {}, + "settingsAllowErrorReporting": "Дазволіць ананімнае паведамленне пра памылкі", + "@settingsAllowErrorReporting": {}, + "settingsVideoLoopModeTile": "Цыклічны рэжым", + "@settingsVideoLoopModeTile": {}, + "settingsNavigationDrawerEditorPageTitle": "Меню навігацыі", + "@settingsNavigationDrawerEditorPageTitle": {}, + "statsWithGps": "{count, plural, =1{1 элемент з месцазнаходжаннем} few{{count} элементы з месцазнаходжаннем} other{{count} элементаў з месцазнаходжаннем}}", + "@statsWithGps": { + "placeholders": { + "count": {} + } + }, + "settingsVideoResumptionModeDialogTitle": "Працягнуць прайграванне", + "@settingsVideoResumptionModeDialogTitle": {}, + "settingsVideoBackgroundMode": "Фонавы рэжым", + "@settingsVideoBackgroundMode": {}, + "settingsAllowInstalledAppAccess": "Дазволіць доступ да інвентара праграм", + "@settingsAllowInstalledAppAccess": {}, + "settingsHiddenItemsTabFilters": "Схаваныя фільтры", + "@settingsHiddenItemsTabFilters": {}, + "settingsSlideshowAnimatedZoomEffect": "Аніміраваны эфект маштабавання", + "@settingsSlideshowAnimatedZoomEffect": {}, + "settingsViewerOverlayPageTitle": "Навязванне", + "@settingsViewerOverlayPageTitle": {}, + "settingsNavigationDrawerTabTypes": "Тыпы", + "@settingsNavigationDrawerTabTypes": {}, + "settingsHiddenItemsTile": "Схаваныя элементы", + "@settingsHiddenItemsTile": {}, + "settingsThumbnailShowVideoDuration": "Паказаць працягласць відэа", + "@settingsThumbnailShowVideoDuration": {}, + "settingsCollectionBurstPatternsNone": "Без ўспышкі", + "@settingsCollectionBurstPatternsNone": {}, + "settingsViewerQuickActionEditorAvailableButtonsSectionTitle": "Даступныя кнопкі", + "@settingsViewerQuickActionEditorAvailableButtonsSectionTitle": {}, + "settingsViewerShowDescription": "Паказаць апісанне", + "@settingsViewerShowDescription": {}, + "settingsViewerQuickActionEditorBanner": "Націсніце і ўтрымлівайце, каб перамяшчаць кнопкі і выбіраць дзеянні для адлюстравання ў праглядніку.", + "@settingsViewerQuickActionEditorBanner": {}, + "settingsDisablingBinWarningDialogMessage": "Элементы ў кошыку будуць выдалены назаўжды.", + "@settingsDisablingBinWarningDialogMessage": {}, + "settingsViewerQuickActionEditorDisplayedButtonsSectionTitle": "Адлюстраваныя кнопкі", + "@settingsViewerQuickActionEditorDisplayedButtonsSectionTitle": {}, + "settingsVideoPlaybackPageTitle": "Прайграванне", + "@settingsVideoPlaybackPageTitle": {}, + "settingsNavigationDrawerTile": "Меню навігацыі", + "@settingsNavigationDrawerTile": {}, + "settingsHiddenItemsPageTitle": "Схаваныя элементы", + "@settingsHiddenItemsPageTitle": {}, + "settingsHiddenPathsBanner": "Фатаграфіі і відэа ў гэтых папках або ў любой з іх укладзеных папак не будуць адлюстроўвацца ў вашай калекцыі.", + "@settingsHiddenPathsBanner": {}, + "settingsViewerShowOverlayOnOpening": "Паказаць на адкрыцці", + "@settingsViewerShowOverlayOnOpening": {}, + "settingsViewerShowShootingDetails": "Паказаць дэталі здымкі", + "@settingsViewerShowShootingDetails": {}, + "settingsConfirmationVaultDataLoss": "Паказаць папярэджанне аб страце даных сховішча", + "@settingsConfirmationVaultDataLoss": {}, + "settingsSlideshowTransitionTile": "Пераход", + "@settingsSlideshowTransitionTile": {}, + "settingsViewerMaximumBrightness": "Максімальная яркасць", + "@settingsViewerMaximumBrightness": {}, + "settingsThumbnailShowTagIcon": "Паказаць значок тэга", + "@settingsThumbnailShowTagIcon": {}, + "settingsStorageAccessEmpty": "Доступ не прадстаўлены", + "@settingsStorageAccessEmpty": {}, + "settingsRemoveAnimationsTile": "Выдаліць анімацыі", + "@settingsRemoveAnimationsTile": {}, + "settingsStorageAccessBanner": "Некаторыя каталогі патрабуюць відавочнага дазволу на змяненне файлаў у іх. Тут вы можаце прагледзець каталогі, да якіх вы раней далі доступ.", + "@settingsStorageAccessBanner": {}, + "collectionCopySuccessFeedback": "{count, plural, =1{1 элемент скапіяваны} few{{count} элементы скапіявана} other{{count} элементаў скапіявана}}", + "@collectionCopySuccessFeedback": { + "placeholders": { + "count": {} + } + }, + "settingsNavigationDrawerBanner": "Націсніце і ўтрымлівайце для перамяшчэння і змены парадку пунктаў меню.", + "@settingsNavigationDrawerBanner": {}, + "settingsViewerShowMinimap": "Паказаць мінікарту", + "@settingsViewerShowMinimap": {}, + "settingsCollectionBurstPatternsTile": "Шаблоны ўспышкі", + "@settingsCollectionBurstPatternsTile": {}, + "settingsImageBackground": "Фон выявы", + "@settingsImageBackground": {}, + "settingsVideoLoopModeDialogTitle": "Цыклічны рэжым", + "@settingsVideoLoopModeDialogTitle": {}, + "settingsViewerShowOverlayThumbnails": "Паказаць мініяцюры", + "@settingsViewerShowOverlayThumbnails": {}, + "settingsVideoControlsPageTitle": "Элементы кіравання", + "@settingsVideoControlsPageTitle": {}, + "settingsSlideshowVideoPlaybackTile": "Прайграванне відэа", + "@settingsSlideshowVideoPlaybackTile": {}, + "settingsHiddenFiltersEmpty": "Няма схаваных фільтраў", + "@settingsHiddenFiltersEmpty": {}, + "settingsThumbnailShowLocationIcon": "Паказаць значок месцазнаходжання", + "@settingsThumbnailShowLocationIcon": {}, + "settingsStorageAccessPageTitle": "Доступ да сховішча", + "@settingsStorageAccessPageTitle": {}, + "settingsSubtitleThemeBackgroundOpacity": "Непразрыстасць фону", + "@settingsSubtitleThemeBackgroundOpacity": {}, + "settingsStorageAccessTile": "Доступ да сховішча", + "@settingsStorageAccessTile": {}, + "settingsViewerQuickActionEmpty": "Няма кнопак", + "@settingsViewerQuickActionEmpty": {}, + "settingsViewerSlideshowTile": "Слайд-шоў", + "@settingsViewerSlideshowTile": {}, + "settingsSubtitleThemeTextOpacity": "Непразрыстасць тэксту", + "@settingsSubtitleThemeTextOpacity": {}, + "settingsViewerShowRatingTags": "Паказаць рэйтынг і тэгі", + "@settingsViewerShowRatingTags": {}, + "settingsViewerEnableOverlayBlurEffect": "Эфект размыцця", + "@settingsViewerEnableOverlayBlurEffect": {}, + "settingsMotionPhotoAutoPlay": "Аўтаматычнае прайграванне фатаграфій з рухам", + "@settingsMotionPhotoAutoPlay": {}, + "settingsVideoControlsTile": "Элементы кіравання", + "@settingsVideoControlsTile": {}, + "settingsSlideshowVideoPlaybackDialogTitle": "Прайграванне відэа", + "@settingsSlideshowVideoPlaybackDialogTitle": {}, + "settingsSubtitleThemeShowOutline": "Паказаць контур і цень", + "@settingsSubtitleThemeShowOutline": {}, + "settingsNavigationDrawerTabAlbums": "Альбомы", + "@settingsNavigationDrawerTabAlbums": {}, + "settingsViewerQuickActionsTile": "Хуткія дзеянні", + "@settingsViewerQuickActionsTile": {}, + "settingsSubtitleThemePageTitle": "Субтытры", + "@settingsSubtitleThemePageTitle": {}, + "settingsSubtitleThemeTextPositionTile": "Палажэнне тэксту", + "@settingsSubtitleThemeTextPositionTile": {}, + "settingsVideoBackgroundModeDialogTitle": "Фонавы рэжым", + "@settingsVideoBackgroundModeDialogTitle": {}, + "deleteMultiAlbumConfirmationDialogMessage": "{count, plural, =1{Выдаліць гэтыя альбомы і элемент у іх?} few{Выдаліць гэтыя альбомы і {count} элементы у іх?} other{Выдаліць гэтыя альбомы і {count} элементаў у іх?}}", + "@deleteMultiAlbumConfirmationDialogMessage": { + "placeholders": { + "count": {} + } + }, + "settingsSubtitleThemeTextSize": "Памер тэксту", + "@settingsSubtitleThemeTextSize": {}, + "settingsCollectionQuickActionTabBrowsing": "Прагляд", + "@settingsCollectionQuickActionTabBrowsing": {}, + "settingsHiddenItemsTabPaths": "Схаваныя шляхі", + "@settingsHiddenItemsTabPaths": {}, + "collectionDeleteFailureFeedback": "{count, plural, =1{Не атрымалася выдаліць 1 элемент} few{Не атрымалася выдаліць {count} элементы} other{Не атрымалася выдаліць {count} элементаў}}", + "@collectionDeleteFailureFeedback": { + "placeholders": { + "count": {} + } + }, + "settingsVideoButtonsTile": "Кнопкі", + "@settingsVideoButtonsTile": {}, + "settingsSubtitleThemeSample": "Гэта ўзор.", + "@settingsSubtitleThemeSample": {}, + "settingsSaveSearchHistory": "Захаваць гісторыю пошуку", + "@settingsSaveSearchHistory": {}, + "settingsViewerShowHistogram": "Паказаць гістаграму", + "@settingsViewerShowHistogram": {}, + "settingsVideoPlaybackTile": "Прайграванне", + "@settingsVideoPlaybackTile": {}, + "columnCount": "{count, plural, =1{1 слупок} few{{count} слупкі} other{{count} слупкоў}}", + "@columnCount": { + "placeholders": { + "count": {} + } + }, + "timeSeconds": "{seconds, plural, =1{1 секунда} few{{seconds} секунды} other{{seconds} секунд}}", + "@timeSeconds": { + "placeholders": { + "seconds": {} + } + }, + "timeDays": "{days, plural, =1{1 дзень} few{{days} дні} other{{days} дзён}}", + "@timeDays": { + "placeholders": { + "days": {} + } + }, + "timeMinutes": "{minutes, plural, =1{1 хвіліна} few{{minutes} хвіліны} other{{minutes} хвілін}}", + "@timeMinutes": { + "placeholders": { + "minutes": {} + } + } } diff --git a/lib/l10n/app_de.arb b/lib/l10n/app_de.arb index b8b4be190..4a72170e9 100644 --- a/lib/l10n/app_de.arb +++ b/lib/l10n/app_de.arb @@ -1350,5 +1350,9 @@ "overlayHistogramLuminance": "Leuchtdichte", "@overlayHistogramLuminance": {}, "overlayHistogramRGB": "RGB", - "@overlayHistogramRGB": {} + "@overlayHistogramRGB": {}, + "aboutDataUsageClearCache": "Cache leeren", + "@aboutDataUsageClearCache": {}, + "settingsViewerShowHistogram": "Histogramm anzeigen", + "@settingsViewerShowHistogram": {} } diff --git a/lib/l10n/app_it.arb b/lib/l10n/app_it.arb index a9104a63b..d71aa99b5 100644 --- a/lib/l10n/app_it.arb +++ b/lib/l10n/app_it.arb @@ -1354,5 +1354,11 @@ "settingsViewerShowHistogram": "Mostra istogramma", "@settingsViewerShowHistogram": {}, "overlayHistogramRGB": "RGB", - "@overlayHistogramRGB": {} + "@overlayHistogramRGB": {}, + "entryActionCast": "Cast", + "@entryActionCast": {}, + "aboutDataUsageClearCache": "Pulisci Cache", + "@aboutDataUsageClearCache": {}, + "castDialogTitle": "Dispositivi per Cast", + "@castDialogTitle": {} } diff --git a/lib/l10n/app_pt.arb b/lib/l10n/app_pt.arb index 81fd67d77..0e09ed45b 100644 --- a/lib/l10n/app_pt.arb +++ b/lib/l10n/app_pt.arb @@ -1354,5 +1354,7 @@ "overlayHistogramRGB": "RGB", "@overlayHistogramRGB": {}, "settingsViewerShowHistogram": "Mostrar histograma", - "@settingsViewerShowHistogram": {} + "@settingsViewerShowHistogram": {}, + "aboutDataUsageClearCache": "Limpar o cache", + "@aboutDataUsageClearCache": {} } diff --git a/lib/l10n/app_zh.arb b/lib/l10n/app_zh.arb index 141cf4d61..36ba2b40a 100644 --- a/lib/l10n/app_zh.arb +++ b/lib/l10n/app_zh.arb @@ -613,7 +613,7 @@ "@drawerCollectionImages": {}, "drawerCollectionVideos": "视频", "@drawerCollectionVideos": {}, - "drawerCollectionAnimated": "动画", + "drawerCollectionAnimated": "动图", "@drawerCollectionAnimated": {}, "drawerCollectionMotionPhotos": "动态照片", "@drawerCollectionMotionPhotos": {}, @@ -1228,5 +1228,137 @@ "overlayHistogramRGB": "RGB", "@overlayHistogramRGB": {}, "saveCopyButtonLabel": "保存副本", - "@saveCopyButtonLabel": {} + "@saveCopyButtonLabel": {}, + "aboutDataUsageMisc": "其他", + "@aboutDataUsageMisc": {}, + "vaultDialogLockModeWhenScreenOff": "屏幕关闭时锁定", + "@vaultDialogLockModeWhenScreenOff": {}, + "tooManyItemsErrorDialogMessage": "用较少的项目重试。", + "@tooManyItemsErrorDialogMessage": {}, + "videoResumptionModeNever": "从不", + "@videoResumptionModeNever": {}, + "aboutDataUsageDatabase": "数据库", + "@aboutDataUsageDatabase": {}, + "exportEntryDialogQuality": "画质", + "@exportEntryDialogQuality": {}, + "placeEmpty": "没有地点", + "@placeEmpty": {}, + "settingsAskEverytime": "每次询问", + "@settingsAskEverytime": {}, + "settingsModificationWarningDialogMessage": "其他设置将被修改。", + "@settingsModificationWarningDialogMessage": {}, + "settingsVideoGestureVerticalDragBrightnessVolume": "上下滑动屏幕调整亮度或音量", + "@settingsVideoGestureVerticalDragBrightnessVolume": {}, + "videoResumptionModeAlways": "始终", + "@videoResumptionModeAlways": {}, + "vaultLockTypePattern": "图案", + "@vaultLockTypePattern": {}, + "albumTierVaults": "保险库", + "@albumTierVaults": {}, + "settingsVideoResumptionModeTile": "恢复回放", + "@settingsVideoResumptionModeTile": {}, + "vaultBinUsageDialogMessage": "有些保险库正在使用资源回收站。", + "@vaultBinUsageDialogMessage": {}, + "overlayHistogramLuminance": "亮度", + "@overlayHistogramLuminance": {}, + "patternDialogEnter": "输入图形", + "@patternDialogEnter": {}, + "maxBrightnessAlways": "始终", + "@maxBrightnessAlways": {}, + "aboutDataUsageSectionTitle": "数据使用量", + "@aboutDataUsageSectionTitle": {}, + "entryActionCast": "投屏", + "@entryActionCast": {}, + "vaultLockTypePin": "PIN", + "@vaultLockTypePin": {}, + "editorTransformCrop": "裁剪", + "@editorTransformCrop": {}, + "filterTaggedLabel": "已标记", + "@filterTaggedLabel": {}, + "statePageTitle": "地区", + "@statePageTitle": {}, + "settingsVideoResumptionModeDialogTitle": "恢复回放", + "@settingsVideoResumptionModeDialogTitle": {}, + "settingsVideoBackgroundMode": "后台模式", + "@settingsVideoBackgroundMode": {}, + "chipActionGoToPlacePage": "在地点中显示", + "@chipActionGoToPlacePage": {}, + "placePageTitle": "地点", + "@placePageTitle": {}, + "authenticateToUnlockVault": "验证以解锁保险库", + "@authenticateToUnlockVault": {}, + "lengthUnitPercent": "百分比", + "@lengthUnitPercent": {}, + "maxBrightnessNever": "从不", + "@maxBrightnessNever": {}, + "aboutDataUsageCache": "缓存", + "@aboutDataUsageCache": {}, + "settingsCollectionBurstPatternsNone": "无", + "@settingsCollectionBurstPatternsNone": {}, + "widgetTapUpdateWidget": "更新小工具", + "@widgetTapUpdateWidget": {}, + "settingsViewerShowDescription": "显示描述", + "@settingsViewerShowDescription": {}, + "cropAspectRatioFree": "自由", + "@cropAspectRatioFree": {}, + "newVaultWarningDialogMessage": "保险库中的项目仅供此应用使用,其他应用不可用。\n\n如果您卸载此应用或清除此应用数据,您将丢失所有这些项目。", + "@newVaultWarningDialogMessage": {}, + "settingsDisablingBinWarningDialogMessage": "回收站中的项目将被永久删除。", + "@settingsDisablingBinWarningDialogMessage": {}, + "statsTopStatesSectionTitle": "最多项的地区", + "@statsTopStatesSectionTitle": {}, + "settingsVideoPlaybackPageTitle": "回放", + "@settingsVideoPlaybackPageTitle": {}, + "filterLocatedLabel": "位于", + "@filterLocatedLabel": {}, + "settingsAccessibilityShowPinchGestureAlternatives": "显示触屏手势可选方案", + "@settingsAccessibilityShowPinchGestureAlternatives": {}, + "drawerPlacePage": "地点", + "@drawerPlacePage": {}, + "settingsConfirmationVaultDataLoss": "显示保险库数据丢失警报", + "@settingsConfirmationVaultDataLoss": {}, + "aboutDataUsageClearCache": "清理缓存", + "@aboutDataUsageClearCache": {}, + "authenticateToConfigureVault": "验证以设置保险库", + "@authenticateToConfigureVault": {}, + "lengthUnitPixel": "像素", + "@lengthUnitPixel": {}, + "vaultDialogLockTypeLabel": "锁定类型", + "@vaultDialogLockTypeLabel": {}, + "aboutDataUsageExternal": "外部存储", + "@aboutDataUsageExternal": {}, + "cropAspectRatioSquare": "方形", + "@cropAspectRatioSquare": {}, + "overlayHistogramNone": "无", + "@overlayHistogramNone": {}, + "settingsCollectionBurstPatternsTile": "连拍模式", + "@settingsCollectionBurstPatternsTile": {}, + "cropAspectRatioOriginal": "原始", + "@cropAspectRatioOriginal": {}, + "configureVaultDialogTitle": "设置保险库", + "@configureVaultDialogTitle": {}, + "searchStatesSectionTitle": "地区", + "@searchStatesSectionTitle": {}, + "stateEmpty": "没有地区", + "@stateEmpty": {}, + "aboutDataUsageData": "数据", + "@aboutDataUsageData": {}, + "aboutDataUsageInternal": "内部存储", + "@aboutDataUsageInternal": {}, + "castDialogTitle": "投屏设备", + "@castDialogTitle": {}, + "settingsVideoEnablePip": "画中画", + "@settingsVideoEnablePip": {}, + "newVaultDialogTitle": "新保险库", + "@newVaultDialogTitle": {}, + "settingsVideoBackgroundModeDialogTitle": "后台模式", + "@settingsVideoBackgroundModeDialogTitle": {}, + "tagPlaceholderState": "地区", + "@tagPlaceholderState": {}, + "settingsViewerShowHistogram": "显示直方图", + "@settingsViewerShowHistogram": {}, + "settingsVideoPlaybackTile": "回放", + "@settingsVideoPlaybackTile": {}, + "exportEntryDialogWriteMetadata": "写入元数据", + "@exportEntryDialogWriteMetadata": {} } diff --git a/lib/model/app/contributors.dart b/lib/model/app/contributors.dart index 031b6c9a3..9e3c7b812 100644 --- a/lib/model/app/contributors.dart +++ b/lib/model/app/contributors.dart @@ -66,10 +66,12 @@ class Contributors { Contributor('Fqwe1', 'Fqwe1@users.noreply.hosted.weblate.org'), Contributor('Reza Almanda', 'rezaalmanda27@gmail.com'), Contributor('Sveinn í Felli', 'sv1@fellsnet.is'), - // Contributor('SAMIRAH AIL', 'samiratalzahrani@gmail.com'), // Arabic - // Contributor('Salih Ail', 'rrrfff444@gmail.com'), // Arabic - // Contributor('nasreddineloukriz', 'nasreddineloukriz@gmail.com'), // Arabic - // Contributor('Mohamed Zeroug', 'mzeroug19@gmail.com'), // Arabic + Contributor('Henning Bunk', 'henningtbunk@gmail.com'), + Contributor('SAMIRAH AIL', 'samiratalzahrani@gmail.com'), + Contributor('Salih Ail', 'rrrfff444@gmail.com'), + Contributor('nasreddineloukriz', 'nasreddineloukriz@gmail.com'), + Contributor('Mohamed Zeroug', 'mzeroug19@gmail.com'), + Contributor('ssantos', 'ssantos@web.de'), // Contributor('Alvi Khan', 'aveenalvi@gmail.com'), // Bengali // Contributor('Htet Oo Hlaing', 'htetoh2006@outlook.com'), // Burmese // Contributor('Khant', 'khant@users.noreply.hosted.weblate.org'), // Burmese diff --git a/lib/model/entry/extensions/multipage.dart b/lib/model/entry/extensions/multipage.dart index 2352b27f0..e613583a6 100644 --- a/lib/model/entry/extensions/multipage.dart +++ b/lib/model/entry/extensions/multipage.dart @@ -3,19 +3,17 @@ import 'dart:async'; import 'package:aves/model/entry/entry.dart'; import 'package:aves/model/multipage.dart'; import 'package:aves/ref/bursts.dart'; -import 'package:aves/ref/mime_types.dart'; import 'package:aves/services/common/services.dart'; import 'package:collection/collection.dart'; extension ExtraAvesEntryMultipage on AvesEntry { - bool get isMultiPage => (catalogMetadata?.isMultiPage ?? false) || isBurst; + bool get isMultiPage => isBurst || ((catalogMetadata?.isMultiPage ?? false) && (isMotionPhoto || !isHdr)); bool get isBurst => burstEntries?.isNotEmpty == true; - // for backward compatibility - bool get _isMotionPhotoLegacy => isMultiPage && !isBurst && mimeType == MimeTypes.jpeg; + bool get isMotionPhoto => catalogMetadata?.isMotionPhoto ?? false; - bool get isMotionPhoto => (catalogMetadata?.isMotionPhoto ?? false) || _isMotionPhotoLegacy; + bool get isHdr => catalogMetadata?.hasHdrGainMap ?? false; String? getBurstKey(List patterns) { final key = BurstPatterns.getKeyForName(filenameWithoutExtension, patterns); diff --git a/lib/model/filters/coordinate.dart b/lib/model/filters/coordinate.dart index 4a17edb2e..57b7b4ebe 100644 --- a/lib/model/filters/coordinate.dart +++ b/lib/model/filters/coordinate.dart @@ -4,12 +4,10 @@ import 'package:aves/model/filters/filters.dart'; import 'package:aves/model/settings/enums/coordinate_format.dart'; import 'package:aves/model/settings/settings.dart'; import 'package:aves/theme/icons.dart'; -import 'package:aves/widgets/common/extensions/build_context.dart'; import 'package:aves_map/aves_map.dart'; import 'package:aves_model/aves_model.dart'; import 'package:flutter/widgets.dart'; import 'package:latlong2/latlong.dart'; -import 'package:provider/provider.dart'; class CoordinateFilter extends CollectionFilter { static const type = 'coordinate'; @@ -45,24 +43,30 @@ class CoordinateFilter extends CollectionFilter { @override EntryFilter get positiveTest => _test; - String _formatBounds(AppLocalizations l10n, CoordinateFormat format) { - String s(LatLng latLng) => format.format( - l10n, - latLng, - minuteSecondPadding: minuteSecondPadding, - dmsSecondDecimals: 0, - ); - return '${s(ne)}\n${s(sw)}'; - } + String _formatBounds(String Function(LatLng latLng) s) => '${s(ne)}\n${s(sw)}'; @override bool get exclusiveProp => false; @override - String get universalLabel => _formatBounds(lookupAppLocalizations(AppLocalizations.supportedLocales.first), CoordinateFormat.decimal); + String get universalLabel { + return _formatBounds((latLng) => CoordinateFormat.decimal.formatWithoutDirectionality( + lookupAppLocalizations(AppLocalizations.supportedLocales.first), + latLng, + minuteSecondPadding: minuteSecondPadding, + dmsSecondDecimals: 0, + )); + } @override - String getLabel(BuildContext context) => _formatBounds(context.l10n, context.read().coordinateFormat); + String getLabel(BuildContext context) { + return _formatBounds((latLng) => settings.coordinateFormat.format( + context, + latLng, + minuteSecondPadding: minuteSecondPadding, + dmsSecondDecimals: 0, + )); + } @override Widget iconBuilder(BuildContext context, double size, {bool showGenericIcon = true}) => Icon(AIcons.geoBounds, size: size); diff --git a/lib/model/filters/type.dart b/lib/model/filters/type.dart index a095887dc..9b4e331e1 100644 --- a/lib/model/filters/type.dart +++ b/lib/model/filters/type.dart @@ -13,7 +13,8 @@ class TypeFilter extends CollectionFilter { static const _animated = 'animated'; // subset of `image/gif` and `image/webp` static const _geotiff = 'geotiff'; // subset of `image/tiff` - static const _motionPhoto = 'motion_photo'; // subset of `image/jpeg` + static const _hdr = 'hdr'; // subset of `image/jpeg` + static const _motionPhoto = 'motion_photo'; // subset of images (jpeg, heic) static const _panorama = 'panorama'; // subset of images static const _raw = 'raw'; // specific image formats static const _sphericalVideo = 'spherical_video'; // subset of videos @@ -24,6 +25,7 @@ class TypeFilter extends CollectionFilter { static final animated = TypeFilter._private(_animated); static final geotiff = TypeFilter._private(_geotiff); + static final hdr = TypeFilter._private(_hdr); static final motionPhoto = TypeFilter._private(_motionPhoto); static final panorama = TypeFilter._private(_panorama); static final raw = TypeFilter._private(_raw); @@ -40,6 +42,9 @@ class TypeFilter extends CollectionFilter { case _geotiff: _test = (entry) => entry.isGeotiff; _icon = AIcons.geo; + case _hdr: + _test = (entry) => entry.isHdr; + _icon = AIcons.hdr; case _motionPhoto: _test = (entry) => entry.isMotionPhoto; _icon = AIcons.motionPhoto; @@ -83,11 +88,12 @@ class TypeFilter extends CollectionFilter { final l10n = context.l10n; return switch (itemType) { _animated => l10n.filterTypeAnimatedLabel, + _geotiff => l10n.filterTypeGeotiffLabel, + _hdr => 'HDR', _motionPhoto => l10n.filterTypeMotionPhotoLabel, _panorama => l10n.filterTypePanoramaLabel, _raw => l10n.filterTypeRawLabel, _sphericalVideo => l10n.filterTypeSphericalVideoLabel, - _geotiff => l10n.filterTypeGeotiffLabel, _ => itemType, }; } diff --git a/lib/model/metadata/catalog.dart b/lib/model/metadata/catalog.dart index 0d389eae2..157c348aa 100644 --- a/lib/model/metadata/catalog.dart +++ b/lib/model/metadata/catalog.dart @@ -4,7 +4,7 @@ import 'package:flutter/foundation.dart'; class CatalogMetadata { final int id; final int? dateMillis; - final bool isAnimated, isGeotiff, is360, isMultiPage, isMotionPhoto; + final bool isAnimated, isGeotiff, is360, isMultiPage, isMotionPhoto, hasHdrGainMap; bool isFlipped; int? rotationDegrees; final String? mimeType, xmpSubjects, xmpTitle; @@ -12,13 +12,16 @@ class CatalogMetadata { Address? address; int rating; + // less lenient than Flutter's `precisionErrorTolerance` (1e-10) static const double _precisionErrorTolerance = 1e-9; + static const _isAnimatedMask = 1 << 0; static const _isFlippedMask = 1 << 1; static const _isGeotiffMask = 1 << 2; static const _is360Mask = 1 << 3; static const _isMultiPageMask = 1 << 4; static const _isMotionPhotoMask = 1 << 5; + static const _hasHdrGainMapMask = 1 << 6; CatalogMetadata({ required this.id, @@ -30,6 +33,7 @@ class CatalogMetadata { this.is360 = false, this.isMultiPage = false, this.isMotionPhoto = false, + this.hasHdrGainMap = false, this.rotationDegrees, this.xmpSubjects, this.xmpTitle, @@ -71,6 +75,7 @@ class CatalogMetadata { is360: is360, isMultiPage: isMultiPage ?? this.isMultiPage, isMotionPhoto: isMotionPhoto, + hasHdrGainMap: hasHdrGainMap, rotationDegrees: rotationDegrees ?? this.rotationDegrees, xmpSubjects: xmpSubjects, xmpTitle: xmpTitle, @@ -92,6 +97,7 @@ class CatalogMetadata { is360: flags & _is360Mask != 0, isMultiPage: flags & _isMultiPageMask != 0, isMotionPhoto: flags & _isMotionPhotoMask != 0, + hasHdrGainMap: flags & _hasHdrGainMapMask != 0, // `rotationDegrees` should default to `sourceRotationDegrees`, not 0 rotationDegrees: map['rotationDegrees'], xmpSubjects: map['xmpSubjects'] ?? '', @@ -106,7 +112,7 @@ class CatalogMetadata { 'id': id, 'mimeType': mimeType, 'dateMillis': dateMillis, - 'flags': (isAnimated ? _isAnimatedMask : 0) | (isFlipped ? _isFlippedMask : 0) | (isGeotiff ? _isGeotiffMask : 0) | (is360 ? _is360Mask : 0) | (isMultiPage ? _isMultiPageMask : 0) | (isMotionPhoto ? _isMotionPhotoMask : 0), + 'flags': (isAnimated ? _isAnimatedMask : 0) | (isFlipped ? _isFlippedMask : 0) | (isGeotiff ? _isGeotiffMask : 0) | (is360 ? _is360Mask : 0) | (isMultiPage ? _isMultiPageMask : 0) | (isMotionPhoto ? _isMotionPhotoMask : 0) | (hasHdrGainMap ? _hasHdrGainMapMask : 0), 'rotationDegrees': rotationDegrees, 'xmpSubjects': xmpSubjects, 'xmpTitle': xmpTitle, diff --git a/lib/model/multipage.dart b/lib/model/multipage.dart index 278a62e6a..286dda44d 100644 --- a/lib/model/multipage.dart +++ b/lib/model/multipage.dart @@ -9,6 +9,7 @@ class MultiPageInfo { final AvesEntry mainEntry; final List _pages; final Map _pageEntries = {}; + final Set _transientEntries = {}; int get pageCount => _pages.length; @@ -16,6 +17,13 @@ class MultiPageInfo { required this.mainEntry, required List pages, }) : _pages = pages { + if (kFlutterMemoryAllocationsEnabled) { + MemoryAllocations.instance.dispatchObjectCreated( + library: 'aves', + className: '$MultiPageInfo', + object: this, + ); + } if (_pages.isNotEmpty) { _pages.sort(); // make sure there is a page marked as default @@ -34,6 +42,13 @@ class MultiPageInfo { } } + void dispose() { + if (kFlutterMemoryAllocationsEnabled) { + MemoryAllocations.instance.dispatchObjectDisposed(object: this); + } + _transientEntries.forEach((entry) => entry.dispose()); + } + factory MultiPageInfo.fromPageMaps(AvesEntry mainEntry, List pageMaps) { return MultiPageInfo( mainEntry: mainEntry, @@ -91,7 +106,7 @@ class MultiPageInfo { // dynamically extracted video is not in the trash like the original motion photo final trashed = (mainEntry.isMotionPhoto && pageInfo.isVideo) ? false : mainEntry.trashed; - return AvesEntry( + final pageEntry = AvesEntry( id: mainEntry.id, uri: pageInfo.uri ?? mainEntry.uri, path: mainEntry.path, @@ -117,6 +132,8 @@ class MultiPageInfo { ) ..addressDetails = mainEntry.addressDetails?.copyWith() ..trashDetails = trashed ? mainEntry.trashDetails : null; + _transientEntries.add(pageEntry); + return pageEntry; } @override diff --git a/lib/model/settings/enums/coordinate_format.dart b/lib/model/settings/enums/coordinate_format.dart index ed81bad64..ca5835744 100644 --- a/lib/model/settings/enums/coordinate_format.dart +++ b/lib/model/settings/enums/coordinate_format.dart @@ -1,12 +1,19 @@ import 'package:aves/l10n/l10n.dart'; +import 'package:aves/widgets/common/extensions/build_context.dart'; import 'package:aves_model/aves_model.dart'; +import 'package:flutter/widgets.dart'; import 'package:intl/intl.dart'; import 'package:latlong2/latlong.dart'; extension ExtraCoordinateFormat on CoordinateFormat { static const _separator = ', '; - String format(AppLocalizations l10n, LatLng latLng, {bool minuteSecondPadding = false, int dmsSecondDecimals = 2}) { + String format(BuildContext context, LatLng latLng, {bool minuteSecondPadding = false, int dmsSecondDecimals = 2}) { + final text = formatWithoutDirectionality(context.l10n, latLng, minuteSecondPadding: minuteSecondPadding, dmsSecondDecimals: dmsSecondDecimals); + return context.applyDirectionality(text); + } + + String formatWithoutDirectionality(AppLocalizations l10n, LatLng latLng, {bool minuteSecondPadding = false, int dmsSecondDecimals = 2}) { switch (this) { case CoordinateFormat.dms: return toDMS(l10n, latLng, minuteSecondPadding: minuteSecondPadding, secondDecimals: dmsSecondDecimals).join(_separator); diff --git a/lib/services/app_service.dart b/lib/services/app_service.dart index 2f4a8c418..9941df2f3 100644 --- a/lib/services/app_service.dart +++ b/lib/services/app_service.dart @@ -38,7 +38,7 @@ class PlatformAppService implements AppService { 'com.sony.playmemories.mobile': {'Imaging Edge Mobile'}, 'nekox.messenger': {'NekoX'}, 'org.telegram.messenger': {'Telegram Images', 'Telegram Video'}, - 'com.whatsapp': {'Whatsapp', 'WhatsApp Animated Gifs', 'WhatsApp Images', 'WhatsApp Video'} + 'com.whatsapp': {'Whatsapp', 'WhatsApp Animated Gifs', 'WhatsApp Documents', 'WhatsApp Images', 'WhatsApp Video'} }; @override diff --git a/lib/services/media/embedded_data_service.dart b/lib/services/media/embedded_data_service.dart index 137144dca..bb3a00aa5 100644 --- a/lib/services/media/embedded_data_service.dart +++ b/lib/services/media/embedded_data_service.dart @@ -12,6 +12,8 @@ abstract class EmbeddedDataService { Future extractMotionPhotoVideo(AvesEntry entry); + Future extractJpegMpfItem(AvesEntry entry, int index); + Future extractVideoEmbeddedPicture(AvesEntry entry); Future extractXmpDataProp(AvesEntry entry, List? props, String? propMimeType); @@ -84,6 +86,23 @@ class PlatformEmbeddedDataService implements EmbeddedDataService { return {}; } + @override + Future extractJpegMpfItem(AvesEntry entry, int id) async { + try { + final result = await _platform.invokeMethod('extractJpegMpfItem', { + 'mimeType': entry.mimeType, + 'uri': entry.uri, + 'sizeBytes': entry.sizeBytes, + 'displayName': ['${entry.bestTitle}', 'MPF #$id'].join(AText.separator), + 'id': id, + }); + if (result != null) return result as Map; + } on PlatformException catch (e, stack) { + await reportService.recordError(e, stack); + } + return {}; + } + @override Future extractVideoEmbeddedPicture(AvesEntry entry) async { try { diff --git a/lib/theme/icons.dart b/lib/theme/icons.dart index ca9191812..abf9008b0 100644 --- a/lib/theme/icons.dart +++ b/lib/theme/icons.dart @@ -32,7 +32,12 @@ class AIcons { static const folder = Icons.folder_outlined; static const grid = Icons.grid_on_outlined; static const home = Icons.home_outlined; - static const important = Icons.label_important_outline; + + // as of Flutter v3.16.3, + // `label_important_outlined` matches text direction but is filled + // `label_important_outline` is outlined but does not match text direction + static const important = IconData(labelImportantOutlineCodePoint, fontFamily: materialIconsFontFamily, matchTextDirection: true); + static const language = Icons.translate_outlined; static const location = Icons.place_outlined; static const locationUnlocated = Icons.location_off_outlined; @@ -169,6 +174,7 @@ class AIcons { // thumbnail overlay static const animated = Icons.slideshow; static const geo = Icons.language_outlined; + static const hdr = Icons.hdr_on_outlined; static const motionPhoto = Icons.motion_photos_on_outlined; static const multiPage = Icons.burst_mode_outlined; static const panorama = Icons.vrpano_outlined; @@ -179,4 +185,9 @@ class AIcons { static final github = MdiIcons.github; static final legal = MdiIcons.scaleBalance; + + // Material Icons references to make constant instances of `IconData` + // as non-constant instances of `IconData` prevent icon font tree shaking + static const labelImportantOutlineCodePoint = 0xe362; + static const materialIconsFontFamily = 'MaterialIcons'; } diff --git a/lib/theme/styles.dart b/lib/theme/styles.dart index bd8b584f2..6cacf0b53 100644 --- a/lib/theme/styles.dart +++ b/lib/theme/styles.dart @@ -3,10 +3,6 @@ import 'dart:ui'; import 'package:flutter/painting.dart'; class AStyles { - // as of Flutter v2.8.0, overflowing `Text` miscalculates height and some text (e.g. 'Å') is clipped - // so we give it a `strutStyle` with a slightly larger height - static const overflowStrut = StrutStyle(height: 1.3); - static const knownTitleText = TextStyle( fontSize: 20, fontWeight: FontWeight.w300, diff --git a/lib/theme/themes.dart b/lib/theme/themes.dart index c4b860602..f3d7fc06e 100644 --- a/lib/theme/themes.dart +++ b/lib/theme/themes.dart @@ -1,6 +1,7 @@ import 'dart:ui'; import 'package:aves/widgets/aves_app.dart'; +import 'package:aves_utils/aves_utils.dart'; import 'package:flutter/material.dart'; class Themes { @@ -10,17 +11,6 @@ class Themes { fontFeatures: [FontFeature.enable('smcp')], ); - // adapted from M3 defaults - static MaterialStateProperty _popupMenuTextStyle(ColorScheme colors, TextTheme textTheme) { - return MaterialStateProperty.resolveWith((states) { - final TextStyle style = textTheme.labelLarge!; - if (states.contains(MaterialState.disabled)) { - return style.apply(color: colors.onSurface.withOpacity(0.38)); - } - return style.apply(color: colors.onSurface); - }); - } - static TextStyle searchFieldStyle(BuildContext context) => Theme.of(context).textTheme.bodyLarge!; static Color overlayBackgroundColor({ @@ -69,6 +59,7 @@ class Themes { typography: _typography, // COMPONENT THEMES checkboxTheme: _checkboxTheme(colors), + floatingActionButtonTheme: _floatingActionButtonTheme(colors), radioTheme: _radioTheme(colors), sliderTheme: _sliderTheme(colors), tooltipTheme: _tooltipTheme, @@ -83,6 +74,27 @@ class Themes { contentPadding: EdgeInsets.symmetric(horizontal: 16), ); + static PopupMenuThemeData _popupMenuTheme(ColorScheme colors, TextTheme textTheme) { + return PopupMenuThemeData( + labelTextStyle: MaterialStateProperty.resolveWith((states) { + // adapted from M3 defaults + final TextStyle style = textTheme.labelLarge!; + if (states.contains(MaterialState.disabled)) { + return style.apply(color: colors.onSurface.withOpacity(0.38)); + } + return style.apply(color: colors.onSurface); + }), + iconColor: colors.onSurface, + ); + } + + static FloatingActionButtonThemeData _floatingActionButtonTheme(ColorScheme colors) { + return FloatingActionButtonThemeData( + foregroundColor: colors.onPrimary, + backgroundColor: colors.primary, + ); + } + // adapted from M3 defaults static RadioThemeData _radioTheme(ColorScheme colors) => RadioThemeData( fillColor: MaterialStateProperty.resolveWith((states) { @@ -125,19 +137,19 @@ class Themes { static final _lightThemeTypo = _typography.black; static final _lightTitleColor = _lightThemeTypo.titleMedium!.color!; - static final _lightBodyColor = _lightThemeTypo.bodyMedium!.color!; static final _lightLabelColor = _lightThemeTypo.labelMedium!.color!; static const _lightActionIconColor = Color(0xAA000000); static const _lightOnSurface = Colors.black; static ThemeData lightTheme(Color accentColor, bool deviceInitialized) { + final onAccent = ColorUtils.textColorOn(accentColor); final colors = ColorScheme.fromSeed( seedColor: accentColor, brightness: Brightness.light, primary: accentColor, - onPrimary: _lightBodyColor, + onPrimary: onAccent, secondary: accentColor, - onSecondary: _lightBodyColor, + onSecondary: onAccent, onSurface: _lightOnSurface, ); final textTheme = _lightThemeTypo; @@ -158,24 +170,8 @@ class Themes { listTileTheme: _listTileTheme.copyWith( iconColor: _lightActionIconColor, ), - popupMenuTheme: PopupMenuThemeData( - labelTextStyle: _popupMenuTextStyle(colors, textTheme), - ), + popupMenuTheme: _popupMenuTheme(colors, textTheme), snackBarTheme: _snackBarTheme(colors), - switchTheme: SwitchThemeData( - thumbColor: MaterialStateProperty.resolveWith((states) { - final active = states.contains(MaterialState.selected); - return active ? Colors.white : Colors.grey.shade600; - }), - trackColor: MaterialStateProperty.resolveWith((states) { - final active = states.contains(MaterialState.selected); - return colors.primary.withOpacity(active ? 1 : .1); - }), - trackOutlineColor: MaterialStateProperty.resolveWith((states) { - final active = states.contains(MaterialState.selected); - return active ? colors.primary : colors.onPrimary.withOpacity(.5); - }), - ), textButtonTheme: TextButtonThemeData( style: TextButton.styleFrom( foregroundColor: _lightLabelColor, @@ -192,6 +188,20 @@ class Themes { static final _darkLabelColor = _darkThemeTypo.labelMedium!.color!; static const _darkOnSurface = Colors.white; + static ColorScheme _darkColorScheme(Color accentColor) { + final onAccent = ColorUtils.textColorOn(accentColor); + final colors = ColorScheme.fromSeed( + seedColor: accentColor, + brightness: Brightness.dark, + primary: accentColor, + onPrimary: onAccent, + secondary: accentColor, + onSecondary: onAccent, + onSurface: _darkOnSurface, + ); + return colors; + } + static ThemeData _baseDarkTheme(ColorScheme colors, bool deviceInitialized) { final textTheme = _darkThemeTypo; return _baseTheme(colors, deviceInitialized).copyWith( @@ -209,9 +219,7 @@ class Themes { titleTextStyle: _titleTextStyle.copyWith(color: _darkTitleColor), ), listTileTheme: _listTileTheme, - popupMenuTheme: PopupMenuThemeData( - labelTextStyle: _popupMenuTextStyle(colors, textTheme), - ), + popupMenuTheme: _popupMenuTheme(colors, textTheme), snackBarTheme: _snackBarTheme(colors).copyWith( backgroundColor: _schemeSecondLayer(colors), contentTextStyle: TextStyle( @@ -227,30 +235,14 @@ class Themes { } static ThemeData darkTheme(Color accentColor, bool deviceInitialized) { - final colors = ColorScheme.fromSeed( - seedColor: accentColor, - brightness: Brightness.dark, - primary: accentColor, - onPrimary: _darkBodyColor, - secondary: accentColor, - onSecondary: _darkBodyColor, - onSurface: _darkOnSurface, - ); + final colors = _darkColorScheme(accentColor); return _baseDarkTheme(colors, deviceInitialized); } // black static ThemeData blackTheme(Color accentColor, bool deviceInitialized) { - final colors = ColorScheme.fromSeed( - seedColor: accentColor, - brightness: Brightness.dark, - primary: accentColor, - onPrimary: _darkBodyColor, - secondary: accentColor, - onSecondary: _darkBodyColor, - onSurface: _darkOnSurface, - ).copyWith( + final colors = _darkColorScheme(accentColor).copyWith( background: Colors.black, ); final baseTheme = _baseDarkTheme(colors, deviceInitialized); diff --git a/lib/widgets/about/app_ref.dart b/lib/widgets/about/app_ref.dart index b5db10133..6fd99957f 100644 --- a/lib/widgets/about/app_ref.dart +++ b/lib/widgets/about/app_ref.dart @@ -48,7 +48,12 @@ class AppReference extends StatelessWidget { ), const SizedBox(width: 8), Text( - '${context.l10n.appName} ${device.packageVersion}', + context.l10n.appName, + style: _appTitleStyle, + ), + const SizedBox(width: 8), + Text( + device.packageVersion, style: _appTitleStyle, ), ], diff --git a/lib/widgets/about/bug_report.dart b/lib/widgets/about/bug_report.dart index 3c8276b15..671b3e0b6 100644 --- a/lib/widgets/about/bug_report.dart +++ b/lib/widgets/about/bug_report.dart @@ -1,5 +1,6 @@ import 'dart:convert'; import 'dart:io'; +import 'dart:ui' as ui; import 'package:aves/app_flavor.dart'; import 'package:aves/flutter_version.dart'; @@ -98,6 +99,7 @@ class _BugReportState extends State with FeedbackMixin { // as of Flutter v3.0.0, `SelectableText` does not allow passing the `scrollController` child: SelectableText( info, + textDirection: ui.TextDirection.ltr, style: Theme.of(context).textTheme.bodySmall, ), ), diff --git a/lib/widgets/about/licenses.dart b/lib/widgets/about/licenses.dart index f5a603673..4bdad8da7 100644 --- a/lib/widgets/about/licenses.dart +++ b/lib/widgets/about/licenses.dart @@ -132,7 +132,6 @@ class _LicenseRow extends StatelessWidget { child: LinkChip( text: package.name, urlString: package.sourceUrl, - textStyle: const TextStyle(fontWeight: FontWeight.bold), ), ); } diff --git a/lib/widgets/about/translators.dart b/lib/widgets/about/translators.dart index dba2a6404..e3056be10 100644 --- a/lib/widgets/about/translators.dart +++ b/lib/widgets/about/translators.dart @@ -30,7 +30,7 @@ class AboutTranslators extends StatelessWidget { static Widget buildBody(BuildContext context) { return _RandomTextSpanHighlighter( spans: Contributors.translators.map((v) => v.name).toList(), - color: Theme.of(context).colorScheme.onPrimary, + color: Theme.of(context).colorScheme.onBackground, ); } } @@ -112,7 +112,6 @@ class _RandomTextSpanHighlighterState extends State<_RandomTextSpanHighlighter> ]) ], ), - strutStyle: const StrutStyle(height: 1.5, forceStrutHeight: true), ); } } diff --git a/lib/widgets/about/tv_license_page.dart b/lib/widgets/about/tv_license_page.dart index 76eb7a847..e487f9760 100644 --- a/lib/widgets/about/tv_license_page.dart +++ b/lib/widgets/about/tv_license_page.dart @@ -219,9 +219,7 @@ class _PackageLicensePageState extends State<_PackageLicensePage> { return true; }()); for (final LicenseEntry license in widget.licenseEntries) { - if (!mounted) { - return; - } + if (!mounted) return; assert(() { Timeline.timeSync('_initLicenses()', () {}, flow: Flow.step(debugFlowId)); return true; @@ -231,9 +229,7 @@ class _PackageLicensePageState extends State<_PackageLicensePage> { Priority.animation, debugLabel: 'License', ); - if (!mounted) { - return; - } + if (!mounted) return; setState(() { _licenses.add(const Padding( padding: EdgeInsets.all(18.0), diff --git a/lib/widgets/aves_app.dart b/lib/widgets/aves_app.dart index 90b3e8876..1d58e1b4e 100644 --- a/lib/widgets/aves_app.dart +++ b/lib/widgets/aves_app.dart @@ -45,7 +45,6 @@ import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_localization_nn/flutter_localization_nn.dart'; -import 'package:material_color_utilities/material_color_utilities.dart'; import 'package:overlay_support/overlay_support.dart'; import 'package:provider/provider.dart'; import 'package:screen_brightness/screen_brightness.dart'; @@ -58,8 +57,6 @@ class AvesApp extends StatefulWidget { // temporary exclude locales not ready yet for prime time // `ckb`: add `flutter_ckb_localization` and necessary app localization delegates when ready static final _unsupportedLocales = { - 'ar', // Arabic - 'be', // Belarusian 'bn', // Bengali 'ckb', // Kurdish (Central) 'fa', // Persian @@ -153,7 +150,6 @@ class _AvesAppState extends State with WidgetsBindingObserver { final List _subscriptions = []; late final Future _appSetup; late final Future _shouldUseBoldFontLoader; - late final Future _dynamicColorPaletteLoader; final TvRailController _tvRailController = TvRailController(); final CollectionSource _mediaStoreSource = MediaStoreSource(); final Debouncer _mediaStoreChangeDebouncer = Debouncer(delay: ADurations.mediaContentChangeDebounceDelay); @@ -185,7 +181,6 @@ class _AvesAppState extends State with WidgetsBindingObserver { EquatableConfig.stringify = true; _appSetup = _setup(); _shouldUseBoldFontLoader = AccessibilityService.shouldUseBoldFont(); - _dynamicColorPaletteLoader = DynamicColorPlugin.getCorePalette(); _subscriptions.add(_mediaStoreChangeChannel.receiveBroadcastStream().listen((event) => _onMediaStoreChanged(event as String?))); _subscriptions.add(_newIntentChannel.receiveBroadcastStream().listen((event) => _onNewIntent(event as Map?))); _subscriptions.add(_analysisCompletionChannel.receiveBroadcastStream().listen((event) => _onAnalysisCompletion())); @@ -248,18 +243,13 @@ class _AvesAppState extends State with WidgetsBindingObserver { AStyles.updateStylesForLocale(settings.appliedLocale); - return FutureBuilder( - future: _dynamicColorPaletteLoader, - builder: (context, snapshot) { + return DynamicColorBuilder( + builder: (lightScheme, darkScheme) { const defaultAccent = AvesColorsData.defaultAccent; Color lightAccent = defaultAccent, darkAccent = defaultAccent; if (enableDynamicColor) { - // `DynamicColorBuilder` from package `dynamic_color` provides light/dark - // palettes with a primary color from tones too dark/light (40/80), - // so we derive the color with adjusted tones (60/70) - final tonalPalette = snapshot.data?.primary; - lightAccent = Color(tonalPalette?.get(60) ?? defaultAccent.value); - darkAccent = Color(tonalPalette?.get(70) ?? defaultAccent.value); + lightAccent = lightScheme?.primary ?? lightAccent; + darkAccent = darkScheme?.primary ?? darkAccent; } final lightTheme = Themes.lightTheme(lightAccent, initialized); final darkTheme = themeBrightness == AvesThemeBrightness.black ? Themes.blackTheme(darkAccent, initialized) : Themes.darkTheme(darkAccent, initialized); @@ -270,34 +260,38 @@ class _AvesAppState extends State with WidgetsBindingObserver { // KEYCODE_ENTER, KEYCODE_BUTTON_A, KEYCODE_NUMPAD_ENTER LogicalKeySet(LogicalKeyboardKey.select): const ActivateIntent(), }, - child: MediaQuery( - data: MediaQuery.of(context).copyWith( - // disable accessible navigation, as it impacts snack bar action timer - // for all users of apps registered as accessibility services, - // even though they are not for accessibility purposes (like TalkBack is) - accessibleNavigation: false, - ), - child: MaterialApp( - navigatorKey: _navigatorKey, - home: home, - navigatorObservers: _navigatorObservers, - builder: (context, child) => _decorateAppChild( - context: context, - initialized: initialized, - child: child, - ), - onGenerateTitle: (context) => context.l10n.appName, - theme: lightTheme, - darkTheme: darkTheme, - themeMode: themeBrightness.appThemeMode, - locale: settingsLocale, - localizationsDelegates: const [ - ...AppLocalizations.localizationsDelegates, - ...LocalizationsNn.delegates, - ], - supportedLocales: AvesApp.supportedLocales, - scrollBehavior: AvesScrollBehavior(), - ), + child: Builder( + builder: (context) { + return MediaQuery( + data: MediaQuery.of(context).copyWith( + // disable accessible navigation, as it impacts snack bar action timer + // for all users of apps registered as accessibility services, + // even though they are not for accessibility purposes (like TalkBack is) + accessibleNavigation: false, + ), + child: MaterialApp( + navigatorKey: _navigatorKey, + home: home, + navigatorObservers: _navigatorObservers, + builder: (context, child) => _decorateAppChild( + context: context, + initialized: initialized, + child: child, + ), + onGenerateTitle: (context) => context.l10n.appName, + theme: lightTheme, + darkTheme: darkTheme, + themeMode: themeBrightness.appThemeMode, + locale: settingsLocale, + localizationsDelegates: const [ + ...AppLocalizations.localizationsDelegates, + ...LocalizationsNn.delegates, + ], + supportedLocales: AvesApp.supportedLocales, + scrollBehavior: AvesScrollBehavior(), + ), + ); + }, ), ); }, diff --git a/lib/widgets/collection/entry_set_action_delegate.dart b/lib/widgets/collection/entry_set_action_delegate.dart index 6a0b9c49a..262424abf 100644 --- a/lib/widgets/collection/entry_set_action_delegate.dart +++ b/lib/widgets/collection/entry_set_action_delegate.dart @@ -84,7 +84,7 @@ class EntrySetActionDelegate with FeedbackMixin, PermissionAwareMixin, SizeAware case EntrySetAction.stats: return isMain; case EntrySetAction.rescan: - return !useTvLayout && isMain && !isTrash; + return !useTvLayout && isMain && !isTrash && isSelecting; // selecting case EntrySetAction.share: case EntrySetAction.toggleFavourite: diff --git a/lib/widgets/collection/filter_bar.dart b/lib/widgets/collection/filter_bar.dart index 848c8b37a..013a39601 100644 --- a/lib/widgets/collection/filter_bar.dart +++ b/lib/widgets/collection/filter_bar.dart @@ -11,11 +11,13 @@ class FilterBar extends StatefulWidget { static const double preferredHeight = AvesFilterChip.minChipHeight + verticalPadding; final List filters; + final bool interactive; final FilterCallback? onTap, onRemove; FilterBar({ super.key, required Set filters, + this.interactive = true, this.onTap, this.onRemove, }) : filters = List.from(filters)..sort(); @@ -111,6 +113,7 @@ class _FilterBarState extends State { return _Chip( filter: filter, single: filters.length == 1, + interactive: widget.interactive, onTap: onTap, onRemove: onRemove, ); @@ -119,12 +122,13 @@ class _FilterBarState extends State { class _Chip extends StatelessWidget { final CollectionFilter filter; - final bool single; + final bool single, interactive; final FilterCallback? onTap, onRemove; const _Chip({ required this.filter, required this.single, + required this.interactive, required this.onTap, required this.onRemove, }); @@ -148,6 +152,7 @@ class _Chip extends StatelessWidget { heroType: HeroType.always, onTap: onTap, onRemove: onRemove, + onLongPress: interactive ? AvesFilterChip.showDefaultLongPressMenu : null, ), ), ); diff --git a/lib/widgets/collection/grid/list_details.dart b/lib/widgets/collection/grid/list_details.dart index 1175dc0bd..8b3c9790e 100644 --- a/lib/widgets/collection/grid/list_details.dart +++ b/lib/widgets/collection/grid/list_details.dart @@ -4,7 +4,6 @@ import 'package:aves/model/settings/enums/coordinate_format.dart'; import 'package:aves/model/settings/settings.dart'; import 'package:aves/theme/format.dart'; import 'package:aves/theme/icons.dart'; -import 'package:aves/theme/styles.dart'; import 'package:aves/theme/text.dart'; import 'package:aves/utils/collection_utils.dart'; import 'package:aves/utils/file_utils.dart'; @@ -60,7 +59,6 @@ class EntryListDetails extends StatelessWidget { children: spans, ), style: style, - strutStyle: AStyles.overflowStrut, softWrap: false, overflow: TextOverflow.fade, ); @@ -85,25 +83,26 @@ class EntryListDetails extends StatelessWidget { final size = entry.burstEntries?.map((v) => v.sizeBytes).sum ?? entry.sizeBytes; final sizeText = size != null ? formatFileSize(locale, size) : AText.valueNotAvailable; - return _buildRow( - [ - _buildIconSpan(AIcons.date), - TextSpan(text: dateText), - _buildIconSpan(AIcons.size, padding: const EdgeInsetsDirectional.only(start: 8)), - TextSpan(text: sizeText), + return Wrap( + spacing: 8, + children: [ + _buildRow( + [_buildIconSpan(AIcons.date), TextSpan(text: dateText)], + style, + ), + _buildRow( + [_buildIconSpan(AIcons.size), TextSpan(text: sizeText)], + style, + ), ], - style, ); } Widget _buildLocationRow(BuildContext context, TextStyle style) { - final location = entry.hasAddress ? entry.shortAddress : settings.coordinateFormat.format(context.l10n, entry.latLng!); + final location = entry.hasAddress ? entry.shortAddress : settings.coordinateFormat.format(context, entry.latLng!); return _buildRow( - [ - _buildIconSpan(AIcons.location), - TextSpan(text: location), - ], + [_buildIconSpan(AIcons.location), TextSpan(text: location)], style, ); } diff --git a/lib/widgets/collection/grid/list_details_theme.dart b/lib/widgets/collection/grid/list_details_theme.dart index 38fe2b901..41da131a3 100644 --- a/lib/widgets/collection/grid/list_details_theme.dart +++ b/lib/widgets/collection/grid/list_details_theme.dart @@ -1,6 +1,7 @@ import 'package:aves/theme/format.dart'; -import 'package:aves/theme/styles.dart'; import 'package:aves/widgets/common/extensions/build_context.dart'; +import 'package:aves/widgets/common/tile_extent_controller.dart'; +import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter/rendering.dart'; import 'package:provider/provider.dart'; @@ -29,11 +30,18 @@ class EntryListDetailsTheme extends StatelessWidget { final textScaler = mq.textScaler; final textTheme = Theme.of(context).textTheme; - final titleStyle = textTheme.bodyMedium!; - final captionStyle = textTheme.bodySmall!; + var titleStyle = textTheme.bodyMedium!; + var captionStyle = textTheme.bodySmall!; + // specify `height` for accurate paragraph height measurement + final defaultTextHeight = DefaultTextStyle.of(context).style.height; + titleStyle = titleStyle.copyWith(height: titleStyle.height ?? defaultTextHeight); + captionStyle = captionStyle.copyWith(height: captionStyle.height ?? defaultTextHeight); final titleLineHeightParagraph = RenderParagraph( - TextSpan(text: 'Fake Title', style: titleStyle), + TextSpan( + text: 'Fake Title', + style: titleStyle, + ), textDirection: TextDirection.ltr, textScaler: textScaler, )..layout(const BoxConstraints(), parentUsesSize: true); @@ -41,10 +49,12 @@ class EntryListDetailsTheme extends StatelessWidget { titleLineHeightParagraph.dispose(); final captionLineHeightParagraph = RenderParagraph( - TextSpan(text: formatDateTime(DateTime.now(), locale, use24hour), style: captionStyle), + TextSpan( + text: formatDateTime(DateTime.now(), locale, use24hour), + style: captionStyle, + ), textDirection: TextDirection.ltr, textScaler: textScaler, - strutStyle: AStyles.overflowStrut, )..layout(const BoxConstraints(), parentUsesSize: true); final captionLineHeight = captionLineHeightParagraph.getMaxIntrinsicHeight(double.infinity); @@ -52,6 +62,9 @@ class EntryListDetailsTheme extends StatelessWidget { var showDate = false; var showLocation = false; + final gridExtentMin = context.read().effectiveExtentMin; + final isMinExtent = (extent - gridExtentMin).abs() < precisionErrorTolerance; + var availableHeight = extent - contentMargin.vertical - contentPadding.vertical; if (availableHeight >= titleLineHeight + titleDetailPadding + captionLineHeight) { showDate = true; @@ -66,6 +79,7 @@ class EntryListDetailsTheme extends StatelessWidget { return EntryListDetailsThemeData( extent: extent, titleMaxLines: titleMaxLines, + isMinExtent: isMinExtent, showDate: showDate, showLocation: showLocation, titleStyle: titleStyle, @@ -84,13 +98,14 @@ class EntryListDetailsTheme extends StatelessWidget { class EntryListDetailsThemeData { final double extent; final int titleMaxLines; - final bool showDate, showLocation; + final bool isMinExtent, showDate, showLocation; final TextStyle titleStyle, captionStyle; final IconThemeData iconTheme; const EntryListDetailsThemeData({ required this.extent, required this.titleMaxLines, + required this.isMinExtent, required this.showDate, required this.showLocation, required this.titleStyle, diff --git a/lib/widgets/common/action_controls/quick_choosers/rate_chooser.dart b/lib/widgets/common/action_controls/quick_choosers/rate_chooser.dart index 4551e2575..f1f10ac74 100644 --- a/lib/widgets/common/action_controls/quick_choosers/rate_chooser.dart +++ b/lib/widgets/common/action_controls/quick_choosers/rate_chooser.dart @@ -3,6 +3,7 @@ import 'dart:async'; import 'package:aves/theme/colors.dart'; import 'package:aves/theme/icons.dart'; import 'package:aves/widgets/common/action_controls/quick_choosers/common/quick_chooser.dart'; +import 'package:aves/widgets/common/extensions/build_context.dart'; import 'package:flutter/material.dart'; class RateQuickChooser extends StatefulWidget { @@ -92,8 +93,7 @@ class _RateQuickChooserState extends State { final contentWidth = chooserSize.width - padding; final local = chooserBox.globalToLocal(globalPosition); - final dx = local.dx - padding / 2; - - valueNotifier.value = (5 * dx / contentWidth).ceil().clamp(0, 5); + final t = (local.dx - padding / 2) / contentWidth; + valueNotifier.value = (5 * (context.isRtl ? 1 - t : t)).ceil().clamp(0, 5); } } diff --git a/lib/widgets/common/action_mixins/entry_storage.dart b/lib/widgets/common/action_mixins/entry_storage.dart index be9f0e111..76eb30d8a 100644 --- a/lib/widgets/common/action_mixins/entry_storage.dart +++ b/lib/widgets/common/action_mixins/entry_storage.dart @@ -9,6 +9,7 @@ import 'package:aves/model/filters/album.dart'; import 'package:aves/model/filters/trash.dart'; import 'package:aves/model/highlight.dart'; import 'package:aves/model/metadata/date_modifier.dart'; +import 'package:aves/model/multipage.dart'; import 'package:aves/model/settings/settings.dart'; import 'package:aves/model/source/collection_lens.dart'; import 'package:aves/model/source/collection_source.dart'; @@ -49,11 +50,13 @@ mixin EntryStorageMixin on FeedbackMixin, PermissionAwareMixin, SizeAwareMixin { if (!await checkFreeSpaceForMove(context, targetEntries, destinationAlbum, MoveType.export)) return; + final transientMultiPageInfo = {}; final selection = {}; await Future.forEach(targetEntries, (targetEntry) async { if (targetEntry.isMultiPage) { final multiPageInfo = await targetEntry.getMultiPageInfo(); if (multiPageInfo != null) { + transientMultiPageInfo.add(multiPageInfo); if (targetEntry.isMotionPhoto) { await multiPageInfo.extractMotionPhotoVideo(); } @@ -130,6 +133,7 @@ mixin EntryStorageMixin on FeedbackMixin, PermissionAwareMixin, SizeAwareMixin { } }, ); + transientMultiPageInfo.forEach((v) => v.dispose()); } Future doQuickMove( diff --git a/lib/widgets/common/action_mixins/feedback.dart b/lib/widgets/common/action_mixins/feedback.dart index 871cca7e6..bee8bfc5c 100644 --- a/lib/widgets/common/action_mixins/feedback.dart +++ b/lib/widgets/common/action_mixins/feedback.dart @@ -213,6 +213,7 @@ class _ReportOverlayState extends State> with SingleTickerPr final processedCount = processed.length.toDouble(); final total = widget.itemCount; final percent = total == null || total == 0 ? 0.0 : min(1.0, processedCount / total); + final percentFormat = NumberFormat.percentPattern(); return FadeTransition( opacity: _animation, child: Stack( @@ -245,7 +246,7 @@ class _ReportOverlayState extends State> with SingleTickerPr animation: animate, center: total != null ? Text( - NumberFormat.percentPattern().format(percent), + percentFormat.format(percent), style: const TextStyle(fontSize: fontSize), ) : null, @@ -340,6 +341,7 @@ class _FeedbackMessageState extends State<_FeedbackMessage> with SingleTickerPro theme.textTheme.bodyMedium!.copyWith( color: colorScheme.onInverseSurface, ); + final contentTextFontSize = contentTextStyle.fontSize ?? theme.textTheme.bodyMedium!.fontSize!; final timerChangeShadowColor = colorScheme.primary; return Row( @@ -347,7 +349,7 @@ class _FeedbackMessageState extends State<_FeedbackMessage> with SingleTickerPro if (widget.type == FeedbackType.warn) ...[ CustomPaint( painter: const _WarnIndicator(AColors.warning), - size: Size(4, textScaler.scale(contentTextStyle.fontSize!)), + size: Size(4, textScaler.scale(contentTextFontSize)), ), const SizedBox(width: 8), ], diff --git a/lib/widgets/common/basic/text/animated_diff.dart b/lib/widgets/common/basic/text/animated_diff.dart index 213a2a58e..a76726e25 100644 --- a/lib/widgets/common/basic/text/animated_diff.dart +++ b/lib/widgets/common/basic/text/animated_diff.dart @@ -29,6 +29,14 @@ class _AnimatedDiffTextState extends State with SingleTickerPr late final Animation _animation; final List<_TextDiff> _diffs = []; + TextStyle get _textStyle { + final style = widget.textStyle ?? const TextStyle(); + // specify `height` for accurate paragraph height measurement + return style.copyWith(height: style.height ?? DefaultTextStyle.of(context).style.height); + } + + StrutStyle? get _strutStyle => widget.strutStyle; + @override void initState() { super.initState(); @@ -101,24 +109,25 @@ class _AnimatedDiffTextState extends State with SingleTickerPr child: Text( text, key: Key(text), + style: _textStyle, ), ), ), ); }).toList(), ), - strutStyle: widget.strutStyle, + strutStyle: _strutStyle, ); }, ); } - Size textSize(String text) { + Size _textSize(String text) { final paragraph = RenderParagraph( - TextSpan(text: text, style: widget.textStyle), + TextSpan(text: text, style: _textStyle), textDirection: Directionality.of(context), textScaler: MediaQuery.textScalerOf(context), - strutStyle: widget.strutStyle, + strutStyle: _strutStyle, )..layout(const BoxConstraints(), parentUsesSize: true); final width = paragraph.getMaxIntrinsicWidth(double.infinity); final height = paragraph.getMaxIntrinsicHeight(double.infinity); @@ -140,7 +149,7 @@ class _AnimatedDiffTextState extends State with SingleTickerPr ..clear() ..addAll(d.map((diff) { final text = diff.text; - final size = textSize(text); + final size = _textSize(text); return switch (diff.operation) { Operation.delete => (text, null, size, Size.zero), Operation.insert => (null, text, Size.zero, size), diff --git a/lib/widgets/common/extensions/build_context.dart b/lib/widgets/common/extensions/build_context.dart index 6a4a86af0..7a5585e74 100644 --- a/lib/widgets/common/extensions/build_context.dart +++ b/lib/widgets/common/extensions/build_context.dart @@ -1,4 +1,5 @@ import 'package:aves/l10n/l10n.dart'; +import 'package:flutter/foundation.dart'; import 'package:flutter/widgets.dart'; extension ExtraContext on BuildContext { @@ -6,5 +7,17 @@ extension ExtraContext on BuildContext { AppLocalizations get l10n => AppLocalizations.of(this)!; + bool get isArabic => l10n.localeName.startsWith('ar'); + bool get isRtl => Directionality.of(this) == TextDirection.rtl; + + String applyDirectionality(String text) => '$_directionalityMark$text'; + + String get _directionalityMark { + if (isRtl) { + return isArabic ? Unicode.ALM : Unicode.RLM; + } else { + return Unicode.LRM; + } + } } diff --git a/lib/widgets/common/grid/header.dart b/lib/widgets/common/grid/header.dart index 18ba54ec6..b1efa5884 100644 --- a/lib/widgets/common/grid/header.dart +++ b/lib/widgets/common/grid/header.dart @@ -34,6 +34,8 @@ class SectionHeader extends StatelessWidget { Widget build(BuildContext context) { final onTap = selectable ? () => _toggleSectionSelection(context) : null; + final theme = Theme.of(context); + Widget child = Container( padding: padding, constraints: BoxConstraints(minHeight: leadingSize.height), @@ -55,23 +57,30 @@ class SectionHeader extends StatelessWidget { children: [ WidgetSpan( alignment: widgetSpanAlignment, - child: _SectionSelectableLeading( - selectable: selectable, - sectionKey: sectionKey, - browsingBuilder: leading != null - ? (context) => Container( - padding: const EdgeInsetsDirectional.only(end: 8, bottom: 4), - width: leadingSize.width, - height: leadingSize.height, - child: leading, - ) - : null, - onPressed: onTap, + child: Theme( + data: theme.copyWith( + iconTheme: theme.iconTheme.copyWith( + color: theme.colorScheme.onSurface, + ), + ), + child: _SectionSelectableLeading( + selectable: selectable, + sectionKey: sectionKey, + browsingBuilder: leading != null + ? (context) => Container( + padding: const EdgeInsetsDirectional.only(end: 8), + width: leadingSize.width, + height: leadingSize.height, + child: leading, + ) + : null, + onPressed: onTap, + ), ), ), TextSpan( text: title, - style: AStyles.unknownTitleText, + style: _headerTextStyle(context), ), if (trailing != null) WidgetSpan( @@ -143,7 +152,7 @@ class SectionHeader extends StatelessWidget { if (hasTrailing) TextSpan(text: '\u200A' * 17), TextSpan( text: title, - style: AStyles.unknownTitleText, + style: _headerTextStyle(context), ), ], ), @@ -154,6 +163,12 @@ class SectionHeader extends StatelessWidget { paragraph.dispose(); return height; } + + static TextStyle _headerTextStyle(BuildContext context) { + // specify `height` for accurate paragraph height measurement + final defaultTextHeight = DefaultTextStyle.of(context).style.height; + return AStyles.unknownTitleText.copyWith(height: defaultTextHeight); + } } class _SectionSelectableLeading extends StatelessWidget { diff --git a/lib/widgets/common/grid/scaling.dart b/lib/widgets/common/grid/scaling.dart index c05b3f63e..87d2cb98c 100644 --- a/lib/widgets/common/grid/scaling.dart +++ b/lib/widgets/common/grid/scaling.dart @@ -4,6 +4,7 @@ import 'package:aves/widgets/common/grid/sections/fixed/scale_overlay.dart'; import 'package:aves/widgets/common/grid/sections/mosaic/scale_overlay.dart'; import 'package:aves/widgets/common/grid/sections/section_layout_builder.dart'; import 'package:aves/widgets/common/grid/theme.dart'; +import 'package:aves/widgets/common/providers/tile_extent_controller_provider.dart'; import 'package:aves/widgets/common/tile_extent_controller.dart'; import 'package:aves_model/aves_model.dart'; import 'package:collection/collection.dart'; @@ -151,17 +152,20 @@ class _GridScaleGestureDetectorState extends State FixedExtentScaleOverlay( - tileLayout: tileLayout, - tileCenter: tileCenter, - contentRect: contentRect, - scaledSizeNotifier: _scaledSizeNotifier!, - gridBuilder: widget.gridBuilder, - builder: (scaledTileSize) => SizedBox.fromSize( - size: scaledTileSize, - child: GridTheme( - extent: tileLayout == TileLayout.grid ? scaledTileSize.width : scaledTileSize.height, - child: widget.scaledItemBuilder(_metadata!.item, scaledTileSize), + builder: (context) => TileExtentControllerProvider( + controller: tileExtentController, + child: FixedExtentScaleOverlay( + tileLayout: tileLayout, + tileCenter: tileCenter, + contentRect: contentRect, + scaledSizeNotifier: _scaledSizeNotifier!, + gridBuilder: widget.gridBuilder, + builder: (scaledTileSize) => SizedBox.fromSize( + size: scaledTileSize, + child: GridTheme( + extent: tileLayout == TileLayout.grid ? scaledTileSize.width : scaledTileSize.height, + child: widget.scaledItemBuilder(_metadata!.item, scaledTileSize), + ), ), ), ), diff --git a/lib/widgets/common/grid/sections/mosaic/row.dart b/lib/widgets/common/grid/sections/mosaic/row.dart index 2cf0aa829..119840515 100644 --- a/lib/widgets/common/grid/sections/mosaic/row.dart +++ b/lib/widgets/common/grid/sections/mosaic/row.dart @@ -113,17 +113,22 @@ class RenderMosaicGridRow extends RenderBox with ContainerRenderObjectMixin extends State, bool>((selection) => selection.isSelecting) ? (details) { + if (_isScrolling) return; + final item = _getItemAt(details.localPosition); if (item == null) return; diff --git a/lib/widgets/common/grid/theme.dart b/lib/widgets/common/grid/theme.dart index 134308a0b..dc63e793c 100644 --- a/lib/widgets/common/grid/theme.dart +++ b/lib/widgets/common/grid/theme.dart @@ -97,10 +97,9 @@ class GridThemeData { if (entry.isRaw && showRaw) const RawIcon(), if (entry.is360) const PanoramaIcon(), ], - if (entry.isMultiPage) ...[ - if (entry.isMotionPhoto && showMotionPhoto) const MotionPhotoIcon(), - if (!entry.isMotionPhoto) MultiPageIcon(entry: entry), - ], + if (entry.isHdr) const HdrIcon(), + if (entry.isMotionPhoto && showMotionPhoto) const MotionPhotoIcon(), + if (entry.isMultiPage && !entry.isMotionPhoto) MultiPageIcon(entry: entry), if (entry.isGeotiff) const GeoTiffIcon(), if (entry.trashed && showTrash) TrashIcon(trashDaysLeft: entry.trashDaysLeft), ]; diff --git a/lib/widgets/common/identity/aves_caption.dart b/lib/widgets/common/identity/aves_caption.dart index 68bf75e60..095caff9e 100644 --- a/lib/widgets/common/identity/aves_caption.dart +++ b/lib/widgets/common/identity/aves_caption.dart @@ -15,7 +15,7 @@ class AvesCaption extends StatelessWidget { Widget build(BuildContext context) { final theme = Theme.of(context); final subtitleStyle = theme.textTheme.bodySmall!; - final subtitleChangeShadowColor = theme.colorScheme.onPrimary; + final subtitleChangeShadowColor = theme.colorScheme.onBackground; return ChangeHighlightText( // provide key to refresh on theme brightness change key: ValueKey(subtitleChangeShadowColor), diff --git a/lib/widgets/common/identity/aves_expansion_tile.dart b/lib/widgets/common/identity/aves_expansion_tile.dart index b8ef518fb..92c8aa18b 100644 --- a/lib/widgets/common/identity/aves_expansion_tile.dart +++ b/lib/widgets/common/identity/aves_expansion_tile.dart @@ -57,7 +57,7 @@ class AvesExpansionTile extends StatelessWidget { initiallyExpanded: initiallyExpanded, finalPadding: const EdgeInsets.symmetric(vertical: 6.0), baseColor: theme.colorScheme.background, - expandedTextColor: colorScheme.onBackground, + expandedTextColor: colorScheme.onSurface, duration: animationDuration, shadowColor: theme.shadowColor, child: Column( diff --git a/lib/widgets/common/identity/aves_fab.dart b/lib/widgets/common/identity/aves_fab.dart index df50d8bbd..2c943ca18 100644 --- a/lib/widgets/common/identity/aves_fab.dart +++ b/lib/widgets/common/identity/aves_fab.dart @@ -20,9 +20,6 @@ class AvesFab extends StatelessWidget { child: FloatingActionButton( tooltip: tooltip, onPressed: onPressed, - shape: const RoundedRectangleBorder( - borderRadius: BorderRadius.all(Radius.circular(16)), - ), child: const Icon(AIcons.apply), ), ); diff --git a/lib/widgets/common/identity/aves_icons.dart b/lib/widgets/common/identity/aves_icons.dart index f108ca0fe..504ba9fa9 100644 --- a/lib/widgets/common/identity/aves_icons.dart +++ b/lib/widgets/common/identity/aves_icons.dart @@ -65,6 +65,17 @@ class GeoTiffIcon extends StatelessWidget { } } +class HdrIcon extends StatelessWidget { + const HdrIcon({super.key}); + + @override + Widget build(BuildContext context) { + return const OverlayIcon( + icon: AIcons.hdr, + ); + } +} + class PanoramaIcon extends StatelessWidget { const PanoramaIcon({super.key}); diff --git a/lib/widgets/common/identity/buttons/captioned_button.dart b/lib/widgets/common/identity/buttons/captioned_button.dart index 7417cd866..a3cda2caf 100644 --- a/lib/widgets/common/identity/buttons/captioned_button.dart +++ b/lib/widgets/common/identity/buttons/captioned_button.dart @@ -39,7 +39,7 @@ class CaptionedButton extends StatefulWidget { var height = width; if (showCaption) { final paragraph = RenderParagraph( - TextSpan(text: text, style: CaptionedButtonText.textStyle(context)), + TextSpan(text: text, style: CaptionedButtonText._textStyle(context)), textDirection: TextDirection.ltr, textScaler: MediaQuery.textScalerOf(context), maxLines: CaptionedButtonText.maxLines, @@ -112,11 +112,11 @@ class _CaptionedButtonState extends State { child: ValueListenableBuilder( valueListenable: _focusedNotifier, builder: (context, focused, child) { - final style = CaptionedButtonText.textStyle(context); + final style = CaptionedButtonText._textStyle(context); return AnimatedDefaultTextStyle( style: focused ? style.copyWith( - color: Theme.of(context).colorScheme.onPrimary, + color: Theme.of(context).colorScheme.primary, ) : style, duration: const Duration(milliseconds: 200), @@ -176,5 +176,9 @@ class CaptionedButtonText extends StatelessWidget { ); } - static TextStyle textStyle(BuildContext context) => Theme.of(context).textTheme.bodySmall!; + static TextStyle _textStyle(BuildContext context) { + // specify `height` for accurate paragraph height measurement + final defaultTextHeight = DefaultTextStyle.of(context).style.height; + return Theme.of(context).textTheme.bodySmall!.copyWith(height: defaultTextHeight); + } } diff --git a/lib/widgets/common/identity/buttons/outlined_button.dart b/lib/widgets/common/identity/buttons/outlined_button.dart index 97b715280..9d4299cb1 100644 --- a/lib/widgets/common/identity/buttons/outlined_button.dart +++ b/lib/widgets/common/identity/buttons/outlined_button.dart @@ -22,7 +22,7 @@ class AvesOutlinedButton extends StatelessWidget { ); }), foregroundColor: MaterialStateProperty.resolveWith((states) { - return states.contains(MaterialState.disabled) ? theme.disabledColor : theme.colorScheme.onPrimary; + return states.contains(MaterialState.disabled) ? theme.disabledColor : theme.colorScheme.onBackground; }), ); return icon != null diff --git a/lib/widgets/common/map/leaflet/scale_layer.dart b/lib/widgets/common/map/leaflet/scale_layer.dart index ff3922042..639e718d4 100644 --- a/lib/widgets/common/map/leaflet/scale_layer.dart +++ b/lib/widgets/common/map/leaflet/scale_layer.dart @@ -123,7 +123,9 @@ class ScaleBar extends StatelessWidget { @override Widget build(BuildContext context) { return Container( - alignment: AlignmentDirectional.bottomStart, + // keep `left` (and not `start`) because zoom buttons are kept right + // because `Google` logo on Google layers are always in the bottom left + alignment: Alignment.bottomLeft, padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 16), child: Column( mainAxisSize: MainAxisSize.min, diff --git a/lib/widgets/common/thumbnail/error.dart b/lib/widgets/common/thumbnail/error.dart index 01320bf54..f6064f4e8 100644 --- a/lib/widgets/common/thumbnail/error.dart +++ b/lib/widgets/common/thumbnail/error.dart @@ -32,7 +32,8 @@ class _ErrorThumbnailState extends State { @override void initState() { super.initState(); - _exists = entry.path != null ? File(entry.path!).exists() : SynchronousFuture(true); + final path = entry.trashDetails?.path ?? entry.path; + _exists = path != null ? File(path).exists() : SynchronousFuture(true); } @override diff --git a/lib/widgets/debug/colors.dart b/lib/widgets/debug/colors.dart index f0a6f3471..2b37bd3eb 100644 --- a/lib/widgets/debug/colors.dart +++ b/lib/widgets/debug/colors.dart @@ -1,4 +1,5 @@ import 'package:aves/widgets/common/identity/aves_expansion_tile.dart'; +import 'package:flex_color_picker/flex_color_picker.dart'; import 'package:flutter/material.dart'; class DebugColorSection extends StatefulWidget { @@ -58,6 +59,11 @@ class _DebugColorSectionState extends State with AutomaticKee children: [ Text(text), const Spacer(), + Text( + color.hex, + style: const TextStyle(fontFamily: 'monospace'), + ), + const SizedBox(width: 4), Container( width: 20, height: 20, diff --git a/lib/widgets/debug/general.dart b/lib/widgets/debug/general.dart index a85913b0b..87ed6aee4 100644 --- a/lib/widgets/debug/general.dart +++ b/lib/widgets/debug/general.dart @@ -66,6 +66,9 @@ class _DebugGeneralSectionState extends State with Automati ElevatedButton( onPressed: () => LeakTracking.collectLeaks().then((leaks) { leaks.byType.forEach((type, reports) { + // ignore `notGCed` and `gcedLate` for now + if (type != LeakType.notDisposed) return; + debugPrint('* leak type=$type'); groupBy(reports, (report) => report.type).forEach((reportType, typedReports) { debugPrint(' * report type=$reportType'); diff --git a/lib/widgets/dialogs/convert_entry_dialog.dart b/lib/widgets/dialogs/convert_entry_dialog.dart index 10fd78821..ef9ffc8f8 100644 --- a/lib/widgets/dialogs/convert_entry_dialog.dart +++ b/lib/widgets/dialogs/convert_entry_dialog.dart @@ -99,12 +99,12 @@ class _ConvertEntryDialogState extends State { const contentHorizontalPadding = EdgeInsets.symmetric(horizontal: AvesDialog.defaultHorizontalContentPadding); final colorScheme = Theme.of(context).colorScheme; final trailingStyle = TextStyle(color: colorScheme.onSurfaceVariant); - final trailingChangeShadowColor = colorScheme.onPrimary; + final trailingChangeShadowColor = colorScheme.onBackground; // used by the drop down to match input decoration final textFieldDecorationBorder = Border( bottom: BorderSide( - color: colorScheme.onSurface.withOpacity(0.38), //Color(0xFFBDBDBD), + color: colorScheme.onSurface.withOpacity(0.38), width: 1.0, ), ); diff --git a/lib/widgets/dialogs/pick_dialogs/album_pick_page.dart b/lib/widgets/dialogs/pick_dialogs/album_pick_page.dart index 259c40606..769f14f80 100644 --- a/lib/widgets/dialogs/pick_dialogs/album_pick_page.dart +++ b/lib/widgets/dialogs/pick_dialogs/album_pick_page.dart @@ -167,7 +167,7 @@ class _AlbumPickPageState extends State<_AlbumPickPage> { case ChipSetAction.createVault: _createVault(); default: - actionDelegate.onActionSelected(context, {}, action); + actionDelegate.onActionSelected(context, action); } } @@ -282,10 +282,10 @@ class _AlbumChipSetPickActionDelegate extends AlbumChipSetActionDelegate { _AlbumChipSetPickActionDelegate(super.items); @override - void onActionSelected(BuildContext context, Set filters, ChipSetAction action) { + void onActionSelected(BuildContext context, ChipSetAction action) { if (action == ChipSetAction.toggleTitleSearch) { settings.showAlbumPickQuery = !settings.showAlbumPickQuery; } - super.onActionSelected(context, filters, action); + super.onActionSelected(context, action); } } diff --git a/lib/widgets/dialogs/pick_dialogs/location_pick_page.dart b/lib/widgets/dialogs/pick_dialogs/location_pick_page.dart index 82f928955..4c8d13d1e 100644 --- a/lib/widgets/dialogs/pick_dialogs/location_pick_page.dart +++ b/lib/widgets/dialogs/pick_dialogs/location_pick_page.dart @@ -8,7 +8,6 @@ import 'package:aves/services/common/services.dart'; import 'package:aves/services/geocoding_service.dart'; import 'package:aves/theme/durations.dart'; import 'package:aves/theme/icons.dart'; -import 'package:aves/theme/styles.dart'; import 'package:aves/theme/text.dart'; import 'package:aves/utils/debouncer.dart'; import 'package:aves/widgets/common/basic/scaffold.dart'; @@ -280,7 +279,6 @@ class _AddressRowState extends State<_AddressRow> { builder: (context, addressLine, child) { return Text( addressLine ?? AText.valueNotAvailable, - strutStyle: AStyles.overflowStrut, softWrap: false, overflow: TextOverflow.fade, maxLines: 1, @@ -330,8 +328,7 @@ class _CoordinateRow extends StatelessWidget { const SizedBox(width: _LocationInfo.iconPadding), Expanded( child: Text( - location != null ? settings.coordinateFormat.format(context.l10n, location!) : AText.valueNotAvailable, - strutStyle: AStyles.overflowStrut, + location != null ? settings.coordinateFormat.format(context, location!) : AText.valueNotAvailable, softWrap: false, overflow: TextOverflow.fade, maxLines: 1, diff --git a/lib/widgets/dialogs/selection_dialogs/multi_selection.dart b/lib/widgets/dialogs/selection_dialogs/multi_selection.dart index f31b7e364..a9079b346 100644 --- a/lib/widgets/dialogs/selection_dialogs/multi_selection.dart +++ b/lib/widgets/dialogs/selection_dialogs/multi_selection.dart @@ -64,7 +64,7 @@ class _AvesMultiSelectionDialogState extends State with } @override - void onActionSelected(BuildContext context, Set filters, ChipSetAction action) { + void onActionSelected(BuildContext context, ChipSetAction action) { reportService.log('$action'); switch (action) { // general @@ -151,19 +151,19 @@ class AlbumChipSetActionDelegate extends ChipSetActionDelegate with _createAlbum(context, locked: true); // single/multiple filters case ChipSetAction.delete: - _delete(context, filters); + _delete(context); case ChipSetAction.lockVault: - lockFilters(filters); + lockFilters(getSelectedFilters(context)); browse(context); // single filter case ChipSetAction.rename: - _rename(context, filters.first); + _rename(context); case ChipSetAction.configureVault: - _configureVault(context, filters.first); + _configureVault(context); default: break; } - super.onActionSelected(context, filters, action); + super.onActionSelected(context, action); } @override @@ -259,7 +259,8 @@ class AlbumChipSetActionDelegate extends ChipSetActionDelegate with showFeedback(context, FeedbackType.info, l10n.genericSuccessFeedback, showAction); } - Future _delete(BuildContext context, Set filters) async { + Future _delete(BuildContext context) async { + final filters = getSelectedFilters(context); final byBinUsage = groupBy(filters, (filter) { final details = vaults.getVault(filter.album); return details?.useBin ?? settings.enableBin; @@ -373,7 +374,11 @@ class AlbumChipSetActionDelegate extends ChipSetActionDelegate with ); } - Future _rename(BuildContext context, AlbumFilter filter) async { + Future _rename(BuildContext context) async { + final filters = getSelectedFilters(context); + if (filters.isEmpty) return; + + final filter = filters.first; if (!await unlockFilter(context, filter)) return; final album = filter.album; @@ -454,7 +459,11 @@ class AlbumChipSetActionDelegate extends ChipSetActionDelegate with ); } - Future _configureVault(BuildContext context, AlbumFilter filter) async { + Future _configureVault(BuildContext context) async { + final filters = getSelectedFilters(context); + if (filters.isEmpty) return; + + final filter = filters.first; if (!await unlockFilter(context, filter)) return; final oldDetails = vaults.getVault(filter.album); diff --git a/lib/widgets/filter_grids/common/action_delegates/chip_set.dart b/lib/widgets/filter_grids/common/action_delegates/chip_set.dart index d51281ac8..4bfb43966 100644 --- a/lib/widgets/filter_grids/common/action_delegates/chip_set.dart +++ b/lib/widgets/filter_grids/common/action_delegates/chip_set.dart @@ -158,7 +158,7 @@ abstract class ChipSetActionDelegate with FeedbackMi } } - void onActionSelected(BuildContext context, Set filters, ChipSetAction action) { + void onActionSelected(BuildContext context, ChipSetAction action) { reportService.log('$action'); switch (action) { // general @@ -180,19 +180,19 @@ abstract class ChipSetActionDelegate with FeedbackMi break; // browsing or selecting case ChipSetAction.map: - _goToMap(context, filters); + _goToMap(context); case ChipSetAction.slideshow: - _goToSlideshow(context, filters); + _goToSlideshow(context); case ChipSetAction.stats: - _goToStats(context, filters); + _goToStats(context); // selecting (single/multiple filters) case ChipSetAction.hide: - _hide(context, filters); + _hide(context); case ChipSetAction.pin: - settings.pinnedFilters = settings.pinnedFilters..addAll(filters); + settings.pinnedFilters = settings.pinnedFilters..addAll(getSelectedFilters(context)); browse(context); case ChipSetAction.unpin: - settings.pinnedFilters = settings.pinnedFilters..removeAll(filters); + settings.pinnedFilters = settings.pinnedFilters..removeAll(getSelectedFilters(context)); browse(context); case ChipSetAction.delete: case ChipSetAction.lockVault: @@ -200,7 +200,7 @@ abstract class ChipSetActionDelegate with FeedbackMi break; // selecting (single filter) case ChipSetAction.setCover: - _setCover(context, filters.first); + _setCover(context); case ChipSetAction.rename: case ChipSetAction.configureVault: break; @@ -209,9 +209,15 @@ abstract class ChipSetActionDelegate with FeedbackMi void browse(BuildContext context) => context.read>?>()?.browse(); - Iterable _selectedEntries(BuildContext context, Set filters) { + Set getSelectedFilters(BuildContext context) { + final selection = context.read>>(); + return selection.isSelecting ? selection.selectedItems.map((v) => v.filter).toSet() : {}; + } + + Iterable _selectedEntries(BuildContext context) { final source = context.read(); final visibleEntries = source.visibleEntries; + final filters = getSelectedFilters(context); return filters.isEmpty ? visibleEntries : visibleEntries.where((entry) => filters.any((f) => f.test(entry))); } @@ -245,10 +251,10 @@ abstract class ChipSetActionDelegate with FeedbackMi } } - Future _goToMap(BuildContext context, Set filters) async { + Future _goToMap(BuildContext context) async { final mapCollection = CollectionLens( source: context.read(), - fixedSelection: _selectedEntries(context, filters).where((entry) => entry.hasGps).toList(), + fixedSelection: _selectedEntries(context).where((entry) => entry.hasGps).toList(), ); await Navigator.maybeOf(context)?.push( MaterialPageRoute( @@ -258,7 +264,8 @@ abstract class ChipSetActionDelegate with FeedbackMi ); } - void _goToSlideshow(BuildContext context, Set filters) { + void _goToSlideshow(BuildContext context) { + final entries = _selectedEntries(context).toList(); Navigator.maybeOf(context)?.push( MaterialPageRoute( settings: const RouteSettings(name: SlideshowPage.routeName), @@ -266,7 +273,7 @@ abstract class ChipSetActionDelegate with FeedbackMi return SlideshowPage( collection: CollectionLens( source: context.read(), - fixedSelection: _selectedEntries(context, filters).toList(), + fixedSelection: entries, ), ); }, @@ -274,13 +281,14 @@ abstract class ChipSetActionDelegate with FeedbackMi ); } - void _goToStats(BuildContext context, Set filters) { + void _goToStats(BuildContext context) { + final entries = _selectedEntries(context).toSet(); Navigator.maybeOf(context)?.push( MaterialPageRoute( settings: const RouteSettings(name: StatsPage.routeName), builder: (context) { return StatsPage( - entries: _selectedEntries(context, filters).toSet(), + entries: entries, source: context.read(), ); }, @@ -300,7 +308,7 @@ abstract class ChipSetActionDelegate with FeedbackMi ); } - Future _hide(BuildContext context, Set filters) async { + Future _hide(BuildContext context) async { final confirmed = await showDialog( context: context, builder: (context) => AvesDialog( @@ -317,12 +325,17 @@ abstract class ChipSetActionDelegate with FeedbackMi ); if (confirmed == null || !confirmed) return; + final filters = getSelectedFilters(context); settings.changeFilterVisibility(filters, false); browse(context); } - void _setCover(BuildContext context, T filter) async { + void _setCover(BuildContext context) async { + final filters = getSelectedFilters(context); + if (filters.isEmpty) return; + + final filter = filters.first; if (!await unlockFilter(context, filter)) return; final existingCover = covers.of(filter); diff --git a/lib/widgets/filter_grids/common/action_delegates/country_set.dart b/lib/widgets/filter_grids/common/action_delegates/country_set.dart index 669bb67d0..6e72aecd3 100644 --- a/lib/widgets/filter_grids/common/action_delegates/country_set.dart +++ b/lib/widgets/filter_grids/common/action_delegates/country_set.dart @@ -80,20 +80,21 @@ class CountryChipSetActionDelegate extends ChipSetActionDelegate } @override - void onActionSelected(BuildContext context, Set filters, ChipSetAction action) { + void onActionSelected(BuildContext context, ChipSetAction action) { reportService.log('$action'); switch (action) { // single/multiple filters case ChipSetAction.showCountryStates: - _showStates(context, filters); + _showStates(context); browse(context); default: break; } - super.onActionSelected(context, filters, action); + super.onActionSelected(context, action); } - void _showStates(BuildContext context, Set filters) { + void _showStates(BuildContext context) { + final filters = getSelectedFilters(context); final countryCodes = filters.map((v) => v.code).where(GeoStates.stateCountryCodes.contains).whereNotNull().toSet(); Navigator.maybeOf(context)?.push( MaterialPageRoute( diff --git a/lib/widgets/filter_grids/common/action_delegates/tag_set.dart b/lib/widgets/filter_grids/common/action_delegates/tag_set.dart index 6c9e2324d..004c2f44c 100644 --- a/lib/widgets/filter_grids/common/action_delegates/tag_set.dart +++ b/lib/widgets/filter_grids/common/action_delegates/tag_set.dart @@ -64,19 +64,21 @@ class TagChipSetActionDelegate extends ChipSetActionDelegate { } @override - void onActionSelected(BuildContext context, Set filters, ChipSetAction action) { + void onActionSelected(BuildContext context, ChipSetAction action) { reportService.log('$action'); switch (action) { // single/multiple filters case ChipSetAction.delete: - _delete(context, filters); + _delete(context); default: break; } - super.onActionSelected(context, filters, action); + super.onActionSelected(context, action); } - Future _delete(BuildContext context, Set filters) async { + Future _delete(BuildContext context) async { + final filters = getSelectedFilters(context); + final source = context.read(); final todoEntries = source.visibleEntries.where((entry) => filters.any((f) => f.test(entry))).toSet(); final todoTags = filters.map((v) => v.tag).toSet(); diff --git a/lib/widgets/filter_grids/common/app_bar.dart b/lib/widgets/filter_grids/common/app_bar.dart index c0a610de0..f39bba04e 100644 --- a/lib/widgets/filter_grids/common/app_bar.dart +++ b/lib/widgets/filter_grids/common/app_bar.dart @@ -437,9 +437,7 @@ class _FilterGridAppBarState actionDelegate) { - final selection = context.read>>(); - final selectedFilters = selection.selectedItems.map((v) => v.filter).toSet(); - actionDelegate.onActionSelected(context, selectedFilters, action); + actionDelegate.onActionSelected(context, action); } void _goToSearch() { diff --git a/lib/widgets/filter_grids/common/list_details.dart b/lib/widgets/filter_grids/common/list_details.dart index ea43c32ea..955ff70fb 100644 --- a/lib/widgets/filter_grids/common/list_details.dart +++ b/lib/widgets/filter_grids/common/list_details.dart @@ -4,7 +4,6 @@ import 'package:aves/model/filters/filters.dart'; import 'package:aves/model/source/collection_source.dart'; import 'package:aves/theme/format.dart'; import 'package:aves/theme/icons.dart'; -import 'package:aves/theme/styles.dart'; import 'package:aves/theme/text.dart'; import 'package:aves/utils/android_file_utils.dart'; import 'package:aves/utils/file_utils.dart'; @@ -107,7 +106,6 @@ class FilterListDetails extends StatelessWidget { child: Text( dateText, style: detailsTheme.captionStyle, - strutStyle: AStyles.overflowStrut, softWrap: false, overflow: TextOverflow.fade, ), @@ -158,7 +156,6 @@ class FilterListDetails extends StatelessWidget { Text( '${l10n.itemCount(source.count(filter))} • ${formatFileSize(locale, source.size(filter))}', style: detailsTheme.captionStyle, - strutStyle: AStyles.overflowStrut, softWrap: false, overflow: TextOverflow.fade, ), diff --git a/lib/widgets/filter_grids/common/list_details_theme.dart b/lib/widgets/filter_grids/common/list_details_theme.dart index 049f91c73..d5af3e26d 100644 --- a/lib/widgets/filter_grids/common/list_details_theme.dart +++ b/lib/widgets/filter_grids/common/list_details_theme.dart @@ -1,9 +1,10 @@ import 'dart:math'; import 'package:aves/theme/format.dart'; -import 'package:aves/theme/styles.dart'; import 'package:aves/widgets/common/extensions/build_context.dart'; import 'package:aves/widgets/common/identity/aves_filter_chip.dart'; +import 'package:aves/widgets/common/tile_extent_controller.dart'; +import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter/rendering.dart'; import 'package:provider/provider.dart'; @@ -33,9 +34,15 @@ class FilterListDetailsTheme extends StatelessWidget { final textScaler = mq.textScaler; final textTheme = Theme.of(context).textTheme; - final titleStyleBase = textTheme.bodyMedium!; - final titleStyle = titleStyleBase.copyWith(fontSize: textScaler.scale(titleStyleBase.fontSize!)); - final captionStyle = textTheme.bodySmall!; + var titleStyle = textTheme.bodyMedium!; + var captionStyle = textTheme.bodySmall!; + // specify `height` for accurate paragraph height measurement + final defaultTextHeight = DefaultTextStyle.of(context).style.height; + titleStyle = titleStyle.copyWith( + fontSize: textScaler.scale(titleStyle.fontSize!), + height: titleStyle.height ?? defaultTextHeight, + ); + captionStyle = captionStyle.copyWith(height: captionStyle.height ?? defaultTextHeight); final titleIconSize = textScaler.scale(AvesFilterChip.iconSize); final titleLineHeightParagraph = RenderParagraph( @@ -50,7 +57,6 @@ class FilterListDetailsTheme extends StatelessWidget { TextSpan(text: formatDateTime(DateTime.now(), locale, use24hour), style: captionStyle), textDirection: TextDirection.ltr, textScaler: textScaler, - strutStyle: AStyles.overflowStrut, )..layout(const BoxConstraints(), parentUsesSize: true); final captionLineHeight = captionLineHeightParagraph.getMaxIntrinsicHeight(double.infinity); captionLineHeightParagraph.dispose(); @@ -59,6 +65,9 @@ class FilterListDetailsTheme extends StatelessWidget { var showCount = false; var showDate = false; + final gridExtentMin = context.read().effectiveExtentMin; + final isMinExtent = (extent - gridExtentMin).abs() < precisionErrorTolerance; + var availableHeight = extent - contentMargin.vertical - contentPadding.vertical; final firstTitleLineHeight = max(titleLineHeight, titleIconSize); if (availableHeight >= firstTitleLineHeight + titleDetailPadding + captionLineHeight) { @@ -74,6 +83,7 @@ class FilterListDetailsTheme extends StatelessWidget { return FilterListDetailsThemeData( extent: extent, titleMaxLines: titleMaxLines, + isMinExtent: isMinExtent, showCount: showCount, showDate: showDate, titleStyle: titleStyle, @@ -93,7 +103,7 @@ class FilterListDetailsTheme extends StatelessWidget { class FilterListDetailsThemeData { final double extent; final int titleMaxLines; - final bool showCount, showDate; + final bool isMinExtent, showCount, showDate; final TextStyle titleStyle, captionStyle; final double titleIconSize; final IconThemeData captionIconTheme; @@ -101,6 +111,7 @@ class FilterListDetailsThemeData { const FilterListDetailsThemeData({ required this.extent, required this.titleMaxLines, + required this.isMinExtent, required this.showCount, required this.showDate, required this.titleStyle, diff --git a/lib/widgets/home_widget.dart b/lib/widgets/home_widget.dart index 62f106af3..76e1288ba 100644 --- a/lib/widgets/home_widget.dart +++ b/lib/widgets/home_widget.dart @@ -15,8 +15,8 @@ class HomeWidgetPainter { final double devicePixelRatio; static const backgroundGradient = LinearGradient( - begin: Alignment.bottomLeft, - end: Alignment.topRight, + begin: AlignmentDirectional.bottomStart, + end: AlignmentDirectional.topEnd, colors: AColors.boraBoraGradient, ); diff --git a/lib/widgets/map/address_row.dart b/lib/widgets/map/address_row.dart index 983d7ca06..252b6c5d2 100644 --- a/lib/widgets/map/address_row.dart +++ b/lib/widgets/map/address_row.dart @@ -5,9 +5,7 @@ import 'package:aves/model/settings/settings.dart'; import 'package:aves/services/common/services.dart'; import 'package:aves/services/geocoding_service.dart'; import 'package:aves/theme/icons.dart'; -import 'package:aves/theme/styles.dart'; import 'package:aves/theme/text.dart'; -import 'package:aves/widgets/common/extensions/build_context.dart'; import 'package:flutter/material.dart'; import 'info_row.dart'; @@ -65,7 +63,7 @@ class _MapAddressRowState extends State { ? AText.valueNotAvailable : entry.hasAddress ? entry.shortAddress - : settings.coordinateFormat.format(context.l10n, entry.latLng!)); + : settings.coordinateFormat.format(context, entry.latLng!)); return Text.rich( TextSpan( children: [ @@ -79,7 +77,6 @@ class _MapAddressRowState extends State { TextSpan(text: location), ], ), - strutStyle: AStyles.overflowStrut, softWrap: false, overflow: TextOverflow.fade, maxLines: 1, diff --git a/lib/widgets/map/date_row.dart b/lib/widgets/map/date_row.dart index 33e5893ca..e663afcb0 100644 --- a/lib/widgets/map/date_row.dart +++ b/lib/widgets/map/date_row.dart @@ -1,7 +1,6 @@ import 'package:aves/model/entry/entry.dart'; import 'package:aves/theme/format.dart'; import 'package:aves/theme/icons.dart'; -import 'package:aves/theme/styles.dart'; import 'package:aves/theme/text.dart'; import 'package:aves/widgets/common/extensions/build_context.dart'; import 'package:aves/widgets/map/info_row.dart'; @@ -35,7 +34,6 @@ class MapDateRow extends StatelessWidget { TextSpan(text: dateText), ], ), - strutStyle: AStyles.overflowStrut, softWrap: false, overflow: TextOverflow.fade, maxLines: 1, diff --git a/lib/widgets/navigation/drawer/app_drawer.dart b/lib/widgets/navigation/drawer/app_drawer.dart index e3c94d672..3139a5049 100644 --- a/lib/widgets/navigation/drawer/app_drawer.dart +++ b/lib/widgets/navigation/drawer/app_drawer.dart @@ -14,6 +14,7 @@ import 'package:aves/theme/icons.dart'; import 'package:aves/utils/android_file_utils.dart'; import 'package:aves/utils/file_utils.dart'; import 'package:aves/widgets/about/about_page.dart'; +import 'package:aves/widgets/common/basic/text/outlined.dart'; import 'package:aves/widgets/common/extensions/build_context.dart'; import 'package:aves/widgets/common/extensions/media_query.dart'; import 'package:aves/widgets/common/identity/aves_logo.dart'; @@ -120,17 +121,21 @@ class _AppDrawerState extends State { )); } + final colorScheme = Theme.of(context).colorScheme; + final onPrimary = colorScheme.onPrimary; + final drawerButtonStyle = ButtonStyle( padding: MaterialStateProperty.all(const EdgeInsetsDirectional.only(start: 12, end: 16)), ); return Container( - padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 16), - color: Theme.of(context).colorScheme.primary, + padding: const EdgeInsets.symmetric(horizontal: 16), + color: colorScheme.primary, child: SafeArea( bottom: false, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ + const SizedBox(height: 6), Align( alignment: AlignmentDirectional.centerStart, child: Wrap( @@ -138,15 +143,19 @@ class _AppDrawerState extends State { crossAxisAlignment: WrapCrossAlignment.center, children: [ const AvesLogo(size: 48), - Text( - context.l10n.appName, - style: const TextStyle( - color: Colors.white, - fontSize: 38, - fontWeight: FontWeight.w300, - letterSpacing: 1.0, - fontFeatures: [FontFeature.enable('smcp')], - ), + OutlinedText( + textSpans: [ + TextSpan( + text: context.l10n.appName, + style: const TextStyle( + color: Colors.white, + fontSize: 38, + fontWeight: FontWeight.w300, + letterSpacing: 1.0, + fontFeatures: [FontFeature.enable('smcp')], + ), + ), + ], ), ], ), @@ -155,9 +164,9 @@ class _AppDrawerState extends State { OutlinedButtonTheme( data: OutlinedButtonThemeData( style: ButtonStyle( - foregroundColor: MaterialStateProperty.all(Colors.white), - overlayColor: MaterialStateProperty.all(Colors.white24), - side: MaterialStateProperty.all(BorderSide(width: 1, color: Colors.white.withOpacity(0.12))), + foregroundColor: MaterialStateProperty.all(onPrimary), + overlayColor: MaterialStateProperty.all(onPrimary.withOpacity(.12)), + side: MaterialStateProperty.all(BorderSide(width: 1, color: onPrimary.withOpacity(.24))), ), ), child: Wrap( @@ -181,7 +190,8 @@ class _AppDrawerState extends State { ), ], ), - ) + ), + const SizedBox(height: 8), ], ), ), diff --git a/lib/widgets/search/search_delegate.dart b/lib/widgets/search/search_delegate.dart index 6e37f4eb9..955a55904 100644 --- a/lib/widgets/search/search_delegate.dart +++ b/lib/widgets/search/search_delegate.dart @@ -58,6 +58,7 @@ class CollectionSearchDelegate extends AvesSearchDelegate with FeedbackMixin, Va TypeFilter.panorama, TypeFilter.sphericalVideo, TypeFilter.geotiff, + TypeFilter.hdr, TypeFilter.raw, MimeFilter(MimeTypes.svg), ]; diff --git a/lib/widgets/settings/common/collection_tile.dart b/lib/widgets/settings/common/collection_tile.dart index ff5bfefe4..3299c90e8 100644 --- a/lib/widgets/settings/common/collection_tile.dart +++ b/lib/widgets/settings/common/collection_tile.dart @@ -61,7 +61,11 @@ class SettingsCollectionTile extends StatelessWidget { ], ), ), - if (filters.isNotEmpty) FilterBar(filters: filters), + if (filters.isNotEmpty) + FilterBar( + filters: filters, + interactive: false, + ), ], ), ), diff --git a/lib/widgets/settings/common/quick_actions/editor_page.dart b/lib/widgets/settings/common/quick_actions/editor_page.dart index 49f0c63af..6d6aa5e74 100644 --- a/lib/widgets/settings/common/quick_actions/editor_page.dart +++ b/lib/widgets/settings/common/quick_actions/editor_page.dart @@ -275,7 +275,7 @@ class _QuickActionEditorBodyState extends State settings.coordinateFormat = v, tileTitle: title(context), dialogTitle: context.l10n.settingsCoordinateFormatDialogTitle, - optionSubtitleBuilder: (value) => value.format(context.l10n, PointsOfInterest.pointNemo), + optionSubtitleBuilder: (value) => value.format(context, PointsOfInterest.pointNemo), ); } diff --git a/lib/widgets/settings/language/locales.dart b/lib/widgets/settings/language/locales.dart index fa32ecf73..88d8c72c4 100644 --- a/lib/widgets/settings/language/locales.dart +++ b/lib/widgets/settings/language/locales.dart @@ -3,6 +3,8 @@ class SupportedLocales { static const languagesByLanguageCode = { + 'ar': 'العربية', + 'be': 'Беларуская мова', 'cs': 'Čeština', 'de': 'Deutsch', 'el': 'Ελληνικά', diff --git a/lib/widgets/settings/thumbnails/thumbnails.dart b/lib/widgets/settings/thumbnails/thumbnails.dart index 3edac6e01..b74f55dce 100644 --- a/lib/widgets/settings/thumbnails/thumbnails.dart +++ b/lib/widgets/settings/thumbnails/thumbnails.dart @@ -8,6 +8,7 @@ import 'package:aves/widgets/settings/common/tiles.dart'; import 'package:aves/widgets/settings/settings_definition.dart'; import 'package:aves/widgets/settings/thumbnails/collection_actions_editor_page.dart'; import 'package:aves/widgets/settings/thumbnails/overlay.dart'; +import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; @@ -68,6 +69,6 @@ class SettingsTileBurstPatterns extends SettingsTile { onSelection: (v) => settings.collectionBurstPatterns = v, tileTitle: title(context), noneSubtitle: context.l10n.settingsCollectionBurstPatternsNone, - optionSubtitleBuilder: BurstPatterns.getExample, + optionSubtitleBuilder: (value) => '${Unicode.FSI}${BurstPatterns.getExample(value)}${Unicode.PDI}', ); } diff --git a/lib/widgets/settings/video/subtitle_sample.dart b/lib/widgets/settings/video/subtitle_sample.dart index 40879e56a..a7ffad64a 100644 --- a/lib/widgets/settings/video/subtitle_sample.dart +++ b/lib/widgets/settings/video/subtitle_sample.dart @@ -33,8 +33,8 @@ class SubtitleSample extends StatelessWidget { return Container( decoration: BoxDecoration( gradient: const LinearGradient( - begin: Alignment.bottomLeft, - end: Alignment.topRight, + begin: AlignmentDirectional.bottomStart, + end: AlignmentDirectional.topEnd, colors: AColors.boraBoraGradient, ), border: AvesBorder.border(context), diff --git a/lib/widgets/stats/date/histogram.dart b/lib/widgets/stats/date/histogram.dart index 55cebcaa9..0debd691b 100644 --- a/lib/widgets/stats/date/histogram.dart +++ b/lib/widgets/stats/date/histogram.dart @@ -195,10 +195,10 @@ class _HistogramState extends State with AutomaticKeepAliveClientMixi final colorScheme = Theme.of(context).colorScheme; final accentColor = colorScheme.primary; - final axisColor = charts.ColorUtil.fromDartColor(drawPoints ? colorScheme.onPrimary.withOpacity(.9) : Colors.transparent); - final measureLineColor = charts.ColorUtil.fromDartColor(drawPoints ? colorScheme.onPrimary.withOpacity(.1) : Colors.transparent); + final axisColor = charts.ColorUtil.fromDartColor(drawPoints ? colorScheme.onBackground : Colors.transparent); + final measureLineColor = charts.ColorUtil.fromDartColor(drawPoints ? colorScheme.onBackground.withOpacity(.1) : Colors.transparent); final histogramLineColor = charts.ColorUtil.fromDartColor(drawLine ? accentColor : Colors.white); - final histogramPointStrikeColor = axisColor; + final histogramPointStrikeColor = charts.ColorUtil.fromDartColor(drawPoints ? colorScheme.onSurface : Colors.transparent); final histogramPointFillColor = charts.ColorUtil.fromDartColor(colorScheme.background); final series = [ diff --git a/lib/widgets/viewer/debug/debug_page.dart b/lib/widgets/viewer/debug/debug_page.dart index 833bda5c2..7dc76d47d 100644 --- a/lib/widgets/viewer/debug/debug_page.dart +++ b/lib/widgets/viewer/debug/debug_page.dart @@ -131,9 +131,10 @@ class ViewerDebugPage extends StatelessWidget { 'isSvg': '${entry.isSvg}', 'isVideo': '${entry.isVideo}', 'isCatalogued': '${entry.isCatalogued}', + 'is360': '${entry.is360}', 'isAnimated': '${entry.isAnimated}', 'isGeotiff': '${entry.isGeotiff}', - 'is360': '${entry.is360}', + 'isHdr': '${entry.isHdr}', 'isMultiPage': '${entry.isMultiPage}', 'isMotionPhoto': '${entry.isMotionPhoto}', 'canEdit': '${entry.canEdit}', diff --git a/lib/widgets/viewer/info/basic_section.dart b/lib/widgets/viewer/info/basic_section.dart index ae9726151..ff76fd69c 100644 --- a/lib/widgets/viewer/info/basic_section.dart +++ b/lib/widgets/viewer/info/basic_section.dart @@ -122,6 +122,7 @@ class _BasicSectionState extends State { MimeFilter(entry.mimeType), if (entry.isAnimated) TypeFilter.animated, if (entry.isGeotiff) TypeFilter.geotiff, + if (entry.isHdr) TypeFilter.hdr, if (entry.isMotionPhoto) TypeFilter.motionPhoto, if (entry.isRaw) TypeFilter.raw, if (entry.isImage && entry.is360) TypeFilter.panorama, @@ -329,8 +330,8 @@ class _BasicInfoState extends State<_BasicInfo> { l10n.viewerInfoLabelTitle: title, l10n.viewerInfoLabelDate: dateText, if (entry.isVideo) ..._buildVideoRows(context), - if (showResolution) l10n.viewerInfoLabelResolution: rasterResolutionText, - l10n.viewerInfoLabelSize: sizeText, + if (showResolution) l10n.viewerInfoLabelResolution: context.applyDirectionality(rasterResolutionText), + l10n.viewerInfoLabelSize: context.applyDirectionality(sizeText), if (!entry.trashed) l10n.viewerInfoLabelUri: entry.uri, if (path != null) l10n.viewerInfoLabelPath: path, if (ownerPackage != null) l10n.viewerInfoLabelOwner: ownerPackage, @@ -359,7 +360,7 @@ class _BasicInfoState extends State<_BasicInfo> { WidgetSpan( alignment: PlaceholderAlignment.middle, child: Padding( - padding: const EdgeInsetsDirectional.only(end: 4), + padding: const EdgeInsetsDirectional.only(start: 2, end: 4), child: ConstrainedBox( // use constraints instead of sizing `Image`, // so that it can collapse when handling an empty image diff --git a/lib/widgets/viewer/info/common.dart b/lib/widgets/viewer/info/common.dart index cf10ebcf9..8c9d706df 100644 --- a/lib/widgets/viewer/info/common.dart +++ b/lib/widgets/viewer/info/common.dart @@ -116,20 +116,32 @@ class _InfoRowGroupState extends State { (kv) { final key = kv.key; final value = kv.value; - final spanBuilder = spanBuilders[key] ?? _buildTextValueSpans; + final customSpanBuilder = spanBuilders[key]; + final spanBuilder = customSpanBuilder ?? _buildTextValueSpans; final thisSpaceSize = max(0.0, (baseValueX - keySizes[key]!)) + InfoRowGroup.keyValuePadding; - final textScaleFactor = textScaler.scale(thisSpaceSize) / thisSpaceSize; - return [ - TextSpan(text: _buildTextValue(key), style: _keyStyle), - WidgetSpan( + InlineSpan paddingSpan; + if (customSpanBuilder != null) { + // add padding using hair spaces instead of a straightforward `SizedBox` in a `WidgetSpan`, + // because ordering of multiple `WidgetSpan`s (e.g. with owner app icon) in Bidi context is tricky + final baseSpaceWidth = _getSpanWidth(TextSpan(text: '\u200A' * 100, style: _keyStyle), textScaler); + final spaceCount = (100 * thisSpaceSize / baseSpaceWidth).round(); + paddingSpan = TextSpan(text: '\u200A' * spaceCount); + } else { + final textScaleFactor = textScaler.scale(thisSpaceSize) / thisSpaceSize; + paddingSpan = WidgetSpan( child: SizedBox( width: thisSpaceSize / textScaleFactor, // as of Flutter v3.0.0, the underline decoration from the following `TextSpan` // is applied to the `WidgetSpan` too, so we add a dummy `Text` as a workaround child: const Text(''), ), - ), + ); + } + + return [ + TextSpan(text: _buildTextValue(key), style: _keyStyle), + paddingSpan, ...spanBuilder(context, key, value), if (key != lastKey) const TextSpan(text: '\n'), ]; diff --git a/lib/widgets/viewer/info/embedded/embedded_data_opener.dart b/lib/widgets/viewer/info/embedded/embedded_data_opener.dart index c7dc91b81..331743110 100644 --- a/lib/widgets/viewer/info/embedded/embedded_data_opener.dart +++ b/lib/widgets/viewer/info/embedded/embedded_data_opener.dart @@ -44,6 +44,8 @@ class EmbeddedDataOpener extends StatelessWidget with FeedbackMixin { fields = await embeddedDataService.extractGoogleDeviceItem(entry, notification.dataUri!); case EmbeddedDataSource.motionPhotoVideo: fields = await embeddedDataService.extractMotionPhotoVideo(entry); + case EmbeddedDataSource.mpf: + fields = await embeddedDataService.extractJpegMpfItem(entry, notification.mpfId!); case EmbeddedDataSource.videoCover: fields = await embeddedDataService.extractVideoEmbeddedPicture(entry); case EmbeddedDataSource.xmp: diff --git a/lib/widgets/viewer/info/embedded/notifications.dart b/lib/widgets/viewer/info/embedded/notifications.dart index a857b9aa3..b8401f27a 100644 --- a/lib/widgets/viewer/info/embedded/notifications.dart +++ b/lib/widgets/viewer/info/embedded/notifications.dart @@ -1,19 +1,21 @@ import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; -enum EmbeddedDataSource { googleDevice, motionPhotoVideo, videoCover, xmp } +enum EmbeddedDataSource { googleDevice, motionPhotoVideo, mpf, videoCover, xmp } @immutable class OpenEmbeddedDataNotification extends Notification { final EmbeddedDataSource source; final List? props; final String? mimeType, dataUri; + final int? mpfId; const OpenEmbeddedDataNotification._private({ required this.source, this.props, this.mimeType, this.dataUri, + this.mpfId, }); factory OpenEmbeddedDataNotification.googleDevice({ @@ -28,6 +30,11 @@ class OpenEmbeddedDataNotification extends Notification { source: EmbeddedDataSource.motionPhotoVideo, ); + factory OpenEmbeddedDataNotification.mpf(int id) => OpenEmbeddedDataNotification._private( + source: EmbeddedDataSource.mpf, + mpfId: id, + ); + factory OpenEmbeddedDataNotification.videoCover() => const OpenEmbeddedDataNotification._private( source: EmbeddedDataSource.videoCover, ); @@ -43,5 +50,5 @@ class OpenEmbeddedDataNotification extends Notification { ); @override - String toString() => '$runtimeType#${shortHash(this)}{source=$source, props=$props, mimeType=$mimeType, dataUri=$dataUri}'; + String toString() => '$runtimeType#${shortHash(this)}{source=$source, props=$props, mimeType=$mimeType, dataUri=$dataUri, index=$mpfId}'; } diff --git a/lib/widgets/viewer/info/location_section.dart b/lib/widgets/viewer/info/location_section.dart index df001809f..84606cb3b 100644 --- a/lib/widgets/viewer/info/location_section.dart +++ b/lib/widgets/viewer/info/location_section.dart @@ -201,7 +201,7 @@ class _AddressInfoGroupState extends State<_AddressInfoGroup> { final l10n = context.l10n; return InfoRowGroup( info: { - l10n.viewerInfoLabelCoordinates: settings.coordinateFormat.format(l10n, entry.latLng!), + l10n.viewerInfoLabelCoordinates: settings.coordinateFormat.format(context, entry.latLng!), if (address.isNotEmpty) l10n.viewerInfoLabelAddress: address, }, ); diff --git a/lib/widgets/viewer/info/metadata/metadata_dir.dart b/lib/widgets/viewer/info/metadata/metadata_dir.dart index c2737e8fe..af717700d 100644 --- a/lib/widgets/viewer/info/metadata/metadata_dir.dart +++ b/lib/widgets/viewer/info/metadata/metadata_dir.dart @@ -13,9 +13,10 @@ class MetadataDirectory { // special directory names static const exifThumbnailDirectory = 'Exif Thumbnail'; // from metadata-extractor static const xmpDirectory = 'XMP'; // from metadata-extractor - static const mediaDirectory = 'Media'; // custom static const coverDirectory = 'Cover'; // custom static const geoTiffDirectory = 'GeoTIFF'; // custom + static const mediaDirectory = 'Media'; // custom + static const mpfImageDirectoryPrefix = 'MPF Image #'; // custom const MetadataDirectory( this.name, diff --git a/lib/widgets/viewer/info/metadata/metadata_dir_tile.dart b/lib/widgets/viewer/info/metadata/metadata_dir_tile.dart index 0fa09df08..28b0d5243 100644 --- a/lib/widgets/viewer/info/metadata/metadata_dir_tile.dart +++ b/lib/widgets/viewer/info/metadata/metadata_dir_tile.dart @@ -6,6 +6,7 @@ import 'package:aves/services/metadata/svg_metadata_service.dart'; import 'package:aves/theme/colors.dart'; import 'package:aves/widgets/common/extensions/build_context.dart'; import 'package:aves/widgets/common/identity/aves_expansion_tile.dart'; +import 'package:aves/widgets/common/identity/buttons/outlined_button.dart'; import 'package:aves/widgets/viewer/info/common.dart'; import 'package:aves/widgets/viewer/info/embedded/notifications.dart'; import 'package:aves/widgets/viewer/info/metadata/geotiff.dart'; @@ -109,6 +110,19 @@ class MetadataDirTileBody extends StatelessWidget { children = [ if (showThumbnails && dirName == MetadataDirectory.exifThumbnailDirectory) MetadataThumbnails(entry: entry), + if (dirName.startsWith(MetadataDirectory.mpfImageDirectoryPrefix)) + Padding( + padding: const EdgeInsets.symmetric(horizontal: 8), + child: AvesOutlinedButton( + label: context.l10n.viewerInfoOpenLinkText, + onPressed: () { + final id = int.tryParse(dirName.substring(MetadataDirectory.mpfImageDirectoryPrefix.length)); + if (id != null) { + OpenEmbeddedDataNotification.mpf(id).dispatch(context); + } + }, + ), + ), Padding( padding: const EdgeInsets.only(left: 8, right: 8, bottom: 8), child: InfoRowGroup( diff --git a/lib/widgets/viewer/info/metadata/metadata_section.dart b/lib/widgets/viewer/info/metadata/metadata_section.dart index c72588edc..bd0d34c34 100644 --- a/lib/widgets/viewer/info/metadata/metadata_section.dart +++ b/lib/widgets/viewer/info/metadata/metadata_section.dart @@ -98,6 +98,7 @@ class _MetadataSectionSliverState extends State { ), children: settings.useTvLayout ? [ + const SizedBox(height: 16), AvesOutlinedButton( label: MaterialLocalizations.of(context).moreButtonTooltip, onPressed: () { diff --git a/lib/widgets/viewer/info/metadata/xmp_card.dart b/lib/widgets/viewer/info/metadata/xmp_card.dart index 49ec41cf1..7df746d69 100644 --- a/lib/widgets/viewer/info/metadata/xmp_card.dart +++ b/lib/widgets/viewer/info/metadata/xmp_card.dart @@ -74,7 +74,7 @@ class _XmpCardState extends State { return Container( decoration: BoxDecoration( border: Border.all( - color: Theme.of(context).colorScheme.onPrimary.withOpacity(.2), + color: Theme.of(context).dividerColor, ), borderRadius: const BorderRadius.all(Radius.circular(4)), ), diff --git a/lib/widgets/viewer/multipage/controller.dart b/lib/widgets/viewer/multipage/controller.dart index 429fb582d..1dfa7abcf 100644 --- a/lib/widgets/viewer/multipage/controller.dart +++ b/lib/widgets/viewer/multipage/controller.dart @@ -50,6 +50,7 @@ class MultiPageController { if (kFlutterMemoryAllocationsEnabled) { MemoryAllocations.instance.dispatchObjectDisposed(object: this); } + _info?.dispose(); _disposed = true; pageNotifier.dispose(); } diff --git a/lib/widgets/viewer/overlay/details/date.dart b/lib/widgets/viewer/overlay/details/date.dart index e6e77fb55..480ce4c2e 100644 --- a/lib/widgets/viewer/overlay/details/date.dart +++ b/lib/widgets/viewer/overlay/details/date.dart @@ -2,7 +2,6 @@ import 'package:aves/model/entry/entry.dart'; import 'package:aves/model/entry/extensions/props.dart'; import 'package:aves/theme/format.dart'; import 'package:aves/theme/icons.dart'; -import 'package:aves/theme/styles.dart'; import 'package:aves/theme/text.dart'; import 'package:aves/widgets/common/extensions/build_context.dart'; import 'package:aves/widgets/viewer/multipage/controller.dart'; @@ -37,8 +36,8 @@ class OverlayDateRow extends StatelessWidget { children: [ DecoratedIcon(AIcons.date, size: ViewerDetailOverlayContent.iconSize, shadows: ViewerDetailOverlayContent.shadows(context)), const SizedBox(width: ViewerDetailOverlayContent.iconPadding), - Expanded(flex: 3, child: Text(dateText, strutStyle: AStyles.overflowStrut)), - Expanded(flex: 2, child: Text(resolutionText, strutStyle: AStyles.overflowStrut)), + Expanded(flex: 3, child: Text(dateText)), + Expanded(flex: 2, child: Text(resolutionText)), ], ); } diff --git a/lib/widgets/viewer/overlay/details/description.dart b/lib/widgets/viewer/overlay/details/description.dart index 171ecde5e..18e6da347 100644 --- a/lib/widgets/viewer/overlay/details/description.dart +++ b/lib/widgets/viewer/overlay/details/description.dart @@ -1,5 +1,4 @@ import 'package:aves/theme/icons.dart'; -import 'package:aves/theme/styles.dart'; import 'package:aves/widgets/viewer/overlay/details/details.dart'; import 'package:decorated_icon/decorated_icon.dart'; import 'package:flutter/material.dart'; @@ -31,7 +30,6 @@ class OverlayDescriptionRow extends StatelessWidget { TextSpan(text: description), ], ), - strutStyle: AStyles.overflowStrut, ); } } diff --git a/lib/widgets/viewer/overlay/details/location.dart b/lib/widgets/viewer/overlay/details/location.dart index b646168e6..4df7b891c 100644 --- a/lib/widgets/viewer/overlay/details/location.dart +++ b/lib/widgets/viewer/overlay/details/location.dart @@ -3,9 +3,7 @@ import 'package:aves/model/entry/extensions/location.dart'; import 'package:aves/model/settings/enums/coordinate_format.dart'; import 'package:aves/model/settings/settings.dart'; import 'package:aves/theme/icons.dart'; -import 'package:aves/theme/styles.dart'; import 'package:aves/theme/text.dart'; -import 'package:aves/widgets/common/extensions/build_context.dart'; import 'package:aves/widgets/viewer/overlay/details/details.dart'; import 'package:decorated_icon/decorated_icon.dart'; import 'package:flutter/material.dart'; @@ -27,14 +25,14 @@ class OverlayLocationRow extends AnimatedWidget { if (location == null || location.isEmpty) { final latLng = entry.latLng; if (latLng != null) { - location = settings.coordinateFormat.format(context.l10n, latLng); + location = settings.coordinateFormat.format(context, latLng); } } return Row( children: [ DecoratedIcon(AIcons.location, size: ViewerDetailOverlayContent.iconSize, shadows: ViewerDetailOverlayContent.shadows(context)), const SizedBox(width: ViewerDetailOverlayContent.iconPadding), - Expanded(child: Text(location ?? AText.valueNotAvailable, strutStyle: AStyles.overflowStrut)), + Expanded(child: Text(location ?? AText.valueNotAvailable)), ], ); } diff --git a/lib/widgets/viewer/overlay/details/position_title.dart b/lib/widgets/viewer/overlay/details/position_title.dart index 167594b8b..346f66dd3 100644 --- a/lib/widgets/viewer/overlay/details/position_title.dart +++ b/lib/widgets/viewer/overlay/details/position_title.dart @@ -1,6 +1,5 @@ import 'package:aves/model/entry/entry.dart'; import 'package:aves/model/multipage.dart'; -import 'package:aves/theme/styles.dart'; import 'package:aves/theme/text.dart'; import 'package:aves/widgets/viewer/multipage/controller.dart'; import 'package:flutter/foundation.dart'; @@ -25,12 +24,12 @@ class OverlayPositionTitleRow extends StatelessWidget { @override Widget build(BuildContext context) { Text toText({String? pagePosition}) => Text( - [ - if (collectionPosition != null) collectionPosition, - if (pagePosition != null) pagePosition, - if (title != null) '${Unicode.FSI}$title${Unicode.PDI}', - ].join(AText.separator), - strutStyle: AStyles.overflowStrut); + [ + if (collectionPosition != null) collectionPosition, + if (pagePosition != null) pagePosition, + if (title != null) '${Unicode.FSI}$title${Unicode.PDI}', + ].join(AText.separator), + ); if (multiPageController == null) return toText(); diff --git a/lib/widgets/viewer/overlay/details/rating_tags.dart b/lib/widgets/viewer/overlay/details/rating_tags.dart index f2b92c0d0..e777b9841 100644 --- a/lib/widgets/viewer/overlay/details/rating_tags.dart +++ b/lib/widgets/viewer/overlay/details/rating_tags.dart @@ -1,6 +1,5 @@ import 'package:aves/model/entry/entry.dart'; import 'package:aves/theme/icons.dart'; -import 'package:aves/theme/styles.dart'; import 'package:aves/theme/text.dart'; import 'package:aves/widgets/common/extensions/build_context.dart'; import 'package:aves/widgets/viewer/overlay/details/details.dart'; @@ -57,7 +56,6 @@ class OverlayRatingTagsRow extends AnimatedWidget { ] ], ), - strutStyle: AStyles.overflowStrut, ); } } diff --git a/lib/widgets/viewer/overlay/details/shooting.dart b/lib/widgets/viewer/overlay/details/shooting.dart index 567e652be..94ea6f260 100644 --- a/lib/widgets/viewer/overlay/details/shooting.dart +++ b/lib/widgets/viewer/overlay/details/shooting.dart @@ -1,6 +1,5 @@ import 'package:aves/model/metadata/overlay.dart'; import 'package:aves/theme/icons.dart'; -import 'package:aves/theme/styles.dart'; import 'package:aves/theme/text.dart'; import 'package:aves/widgets/common/extensions/build_context.dart'; import 'package:aves/widgets/viewer/overlay/details/details.dart'; @@ -33,10 +32,10 @@ class OverlayShootingRow extends StatelessWidget { children: [ DecoratedIcon(AIcons.shooting, size: ViewerDetailOverlayContent.iconSize, shadows: ViewerDetailOverlayContent.shadows(context)), const SizedBox(width: ViewerDetailOverlayContent.iconPadding), - Expanded(child: Text(apertureText, strutStyle: AStyles.overflowStrut)), - Expanded(child: Text(details.exposureTime ?? AText.valueNotAvailable, strutStyle: AStyles.overflowStrut)), - Expanded(child: Text(focalLengthText, strutStyle: AStyles.overflowStrut)), - Expanded(child: Text(isoText, strutStyle: AStyles.overflowStrut)), + Expanded(child: Text(apertureText)), + Expanded(child: Text(details.exposureTime ?? AText.valueNotAvailable)), + Expanded(child: Text(focalLengthText)), + Expanded(child: Text(isoText)), ], ); } diff --git a/lib/widgets/viewer/overlay/minimap.dart b/lib/widgets/viewer/overlay/minimap.dart index a29be6f86..5c63c5b20 100644 --- a/lib/widgets/viewer/overlay/minimap.dart +++ b/lib/widgets/viewer/overlay/minimap.dart @@ -1,6 +1,8 @@ import 'dart:math'; +import 'dart:ui'; import 'package:aves/model/view_state.dart'; +import 'package:aves/widgets/common/extensions/build_context.dart'; import 'package:aves/widgets/editor/transform/controller.dart'; import 'package:aves/widgets/editor/transform/transformation.dart'; import 'package:aves/widgets/viewer/overlay/top.dart'; @@ -36,6 +38,7 @@ class Minimap extends StatelessWidget { contentSize: contentSize, viewCenterOffset: viewState.position, viewScale: viewState.scale!, + alignmentX: context.isRtl ? 1 : 0, transformation: transformation, minimapBorderColor: ViewerTopOverlay.componentBorderColor, ), @@ -52,7 +55,7 @@ class Minimap extends StatelessWidget { class _MinimapPainter extends CustomPainter { final Size contentSize, viewportSize; final Offset viewCenterOffset; - final double viewScale; + final double viewScale, alignmentX; final Transformation? transformation; final Color minimapBorderColor; @@ -63,6 +66,7 @@ class _MinimapPainter extends CustomPainter { required this.contentSize, required this.viewCenterOffset, required this.viewScale, + required this.alignmentX, this.transformation, this.minimapBorderColor = Colors.white, }) { @@ -103,6 +107,8 @@ class _MinimapPainter extends CustomPainter { height: min(scaledContentSize.height, scaledViewportSize.height), ); + canvas.translate(lerpDouble(0, size.width - contentRect.width, alignmentX)!, 0); + Matrix4? transformMatrix; if (transformation != null) { final viewportCenter = viewportRect.center; diff --git a/lib/widgets/viewer/overlay/video/progress_bar.dart b/lib/widgets/viewer/overlay/video/progress_bar.dart index 2c547f16a..2da712a1e 100644 --- a/lib/widgets/viewer/overlay/video/progress_bar.dart +++ b/lib/widgets/viewer/overlay/video/progress_bar.dart @@ -43,6 +43,9 @@ class _VideoProgressBarState extends State { final textStyle = TextStyle( shadows: brightness == Brightness.dark ? AStyles.embossShadows : null, ); + const strutStyle = StrutStyle( + forceStrutHeight: true, + ); return SizeTransition( sizeFactor: widget.scale, child: BlurredRRect.all( @@ -90,12 +93,14 @@ class _VideoProgressBarState extends State { return Text( formatFriendlyDuration(Duration(milliseconds: position)), style: textStyle, + strutStyle: strutStyle, ); }), const Spacer(), Text( formatFriendlyDuration(Duration(milliseconds: controller?.duration ?? 0)), style: textStyle, + strutStyle: strutStyle, ), ], ), @@ -125,6 +130,7 @@ class _VideoProgressBarState extends State { // fake text below to match the height of the text above and center the whole thing '', style: textStyle, + strutStyle: strutStyle, ), ], ), diff --git a/lib/widgets/viewer/visual/controller_mixin.dart b/lib/widgets/viewer/visual/controller_mixin.dart index b00c44761..90fa9af8b 100644 --- a/lib/widgets/viewer/visual/controller_mixin.dart +++ b/lib/widgets/viewer/visual/controller_mixin.dart @@ -26,7 +26,7 @@ mixin EntryViewControllerMixin on State { ValueNotifier get entryNotifier; Future initEntryControllers(AvesEntry? entry) async { - if (entry == null) return; + if (!mounted || entry == null) return; if (entry.isVideo) { await _initVideoController(entry); diff --git a/lib/widgets/viewer/visual/entry_page_view.dart b/lib/widgets/viewer/visual/entry_page_view.dart index 3b598c336..b026993d4 100644 --- a/lib/widgets/viewer/visual/entry_page_view.dart +++ b/lib/widgets/viewer/visual/entry_page_view.dart @@ -51,7 +51,7 @@ class EntryPageView extends StatefulWidget { State createState() => _EntryPageViewState(); } -class _EntryPageViewState extends State with SingleTickerProviderStateMixin { +class _EntryPageViewState extends State with TickerProviderStateMixin { late ValueNotifier _viewStateNotifier; late AvesMagnifierController _magnifierController; final List _subscriptions = []; diff --git a/lib/widgets/viewer/visual/error.dart b/lib/widgets/viewer/visual/error.dart index 50d8167ee..51a4c7b10 100644 --- a/lib/widgets/viewer/visual/error.dart +++ b/lib/widgets/viewer/visual/error.dart @@ -29,7 +29,8 @@ class _ErrorViewState extends State { @override void initState() { super.initState(); - _exists = entry.path != null ? File(entry.path!).exists() : SynchronousFuture(true); + final path = entry.trashDetails?.path ?? entry.path; + _exists = path != null ? File(path).exists() : SynchronousFuture(true); } @override diff --git a/lib/widgets/viewer/visual/video/cover.dart b/lib/widgets/viewer/visual/video/cover.dart index 3a09a897f..0a56c8ff3 100644 --- a/lib/widgets/viewer/visual/video/cover.dart +++ b/lib/widgets/viewer/visual/video/cover.dart @@ -79,6 +79,7 @@ class _VideoCoverState extends State { @override void dispose() { _unregisterWidget(widget); + _dismissedCoverMagnifierController?.dispose(); _videoCoverInfoNotifier.dispose(); super.dispose(); } diff --git a/plugins/aves_map/pubspec.lock b/plugins/aves_map/pubspec.lock index 261a1a3d8..148349718 100644 --- a/plugins/aves_map/pubspec.lock +++ b/plugins/aves_map/pubspec.lock @@ -81,10 +81,10 @@ packages: dependency: "direct main" description: name: flutter_map - sha256: "2b925948b675ef74ca524179fb133dbe0a21741889ccf56ad08fc8dcc38ba94b" + sha256: cda8d72135b697f519287258b5294a57ce2f2a5ebf234f0e406aad4dc14c9399 url: "https://pub.dev" source: hosted - version: "6.0.1" + version: "6.1.0" http: dependency: transitive description: @@ -105,10 +105,10 @@ packages: dependency: transitive description: name: intl - sha256: "3bc132a9dbce73a7e4a21a17d06e1878839ffbf975568bc875c60537824b0c4d" + sha256: d6f56758b7d3014a48af9701c085700aac781a92a87a62b1333b46d8879661cf url: "https://pub.dev" source: hosted - version: "0.18.1" + version: "0.19.0" latlong2: dependency: "direct main" description: @@ -177,10 +177,10 @@ packages: dependency: transitive description: name: path - sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917" + sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af" url: "https://pub.dev" source: hosted - version: "1.8.3" + version: "1.9.0" polylabel: dependency: transitive description: diff --git a/plugins/aves_report/pubspec.lock b/plugins/aves_report/pubspec.lock index 0d7dc5310..e85ee7c44 100644 --- a/plugins/aves_report/pubspec.lock +++ b/plugins/aves_report/pubspec.lock @@ -58,10 +58,10 @@ packages: dependency: transitive description: name: path - sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917" + sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af" url: "https://pub.dev" source: hosted - version: "1.8.3" + version: "1.9.0" sky_engine: dependency: transitive description: flutter diff --git a/plugins/aves_report_console/pubspec.lock b/plugins/aves_report_console/pubspec.lock index 4c0f5e17b..73e565c7f 100644 --- a/plugins/aves_report_console/pubspec.lock +++ b/plugins/aves_report_console/pubspec.lock @@ -65,10 +65,10 @@ packages: dependency: transitive description: name: path - sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917" + sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af" url: "https://pub.dev" source: hosted - version: "1.8.3" + version: "1.9.0" sky_engine: dependency: transitive description: flutter diff --git a/plugins/aves_report_crashlytics/pubspec.lock b/plugins/aves_report_crashlytics/pubspec.lock index 7054c1619..3eb8822a3 100644 --- a/plugins/aves_report_crashlytics/pubspec.lock +++ b/plugins/aves_report_crashlytics/pubspec.lock @@ -5,10 +5,10 @@ packages: dependency: transitive description: name: _flutterfire_internals - sha256: eb0ac20f704799b986049fbb3c1c16421eca319a1b872378d669513e12452ba5 + sha256: f5628cd9c92ed11083f425fd1f8f1bc60ecdda458c81d73b143aeda036c35fe7 url: "https://pub.dev" source: hosted - version: "1.3.14" + version: "1.3.16" async: dependency: transitive description: @@ -68,10 +68,10 @@ packages: dependency: "direct main" description: name: firebase_core - sha256: d301561d614487688d797717bef013a264c517d1d09e4c5c1325c3a64c835efb + sha256: "96607c0e829a581c2a483c658f04e8b159964c3bae2730f73297070bc85d40bb" url: "https://pub.dev" source: hosted - version: "2.24.0" + version: "2.24.2" firebase_core_platform_interface: dependency: transitive description: @@ -84,26 +84,26 @@ packages: dependency: transitive description: name: firebase_core_web - sha256: "10159d9ee42c79f4548971d92f3f0fcd5791f6738cda3583a4e3b2c8b244c018" + sha256: d585bdf3c656c3f7821ba1bd44da5f13365d22fcecaf5eb75c4295246aaa83c0 url: "https://pub.dev" source: hosted - version: "2.9.0" + version: "2.10.0" firebase_crashlytics: dependency: "direct main" description: name: firebase_crashlytics - sha256: "60ef0016c0c2a7d16bf02468e3b27cd0ad4606f6d35535998dde3150cc0bc771" + sha256: "5ccdf05de039f9544d0ba41c5ae2052ca2425985d32229911b09f69981164518" url: "https://pub.dev" source: hosted - version: "3.4.6" + version: "3.4.8" firebase_crashlytics_platform_interface: dependency: transitive description: name: firebase_crashlytics_platform_interface - sha256: d185100facc6f7c43c5718103111488d008c52df8c19cbc5e5f9d2115d734909 + sha256: "359197344def001589c84f8d1d57c05f6e2e773f559205610ce58c25e2045a57" url: "https://pub.dev" source: hosted - version: "3.6.14" + version: "3.6.16" flutter: dependency: "direct main" description: flutter diff --git a/plugins/aves_services/pubspec.lock b/plugins/aves_services/pubspec.lock index 2509df018..75523d088 100644 --- a/plugins/aves_services/pubspec.lock +++ b/plugins/aves_services/pubspec.lock @@ -88,10 +88,10 @@ packages: dependency: transitive description: name: flutter_map - sha256: "2b925948b675ef74ca524179fb133dbe0a21741889ccf56ad08fc8dcc38ba94b" + sha256: cda8d72135b697f519287258b5294a57ce2f2a5ebf234f0e406aad4dc14c9399 url: "https://pub.dev" source: hosted - version: "6.0.1" + version: "6.1.0" http: dependency: transitive description: @@ -112,10 +112,10 @@ packages: dependency: transitive description: name: intl - sha256: "3bc132a9dbce73a7e4a21a17d06e1878839ffbf975568bc875c60537824b0c4d" + sha256: d6f56758b7d3014a48af9701c085700aac781a92a87a62b1333b46d8879661cf url: "https://pub.dev" source: hosted - version: "0.18.1" + version: "0.19.0" latlong2: dependency: "direct main" description: @@ -184,10 +184,10 @@ packages: dependency: transitive description: name: path - sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917" + sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af" url: "https://pub.dev" source: hosted - version: "1.8.3" + version: "1.9.0" polylabel: dependency: transitive description: diff --git a/plugins/aves_services_google/pubspec.lock b/plugins/aves_services_google/pubspec.lock index ff01098ca..7f3fa86b8 100644 --- a/plugins/aves_services_google/pubspec.lock +++ b/plugins/aves_services_google/pubspec.lock @@ -142,10 +142,10 @@ packages: dependency: transitive description: name: flutter_map - sha256: "2b925948b675ef74ca524179fb133dbe0a21741889ccf56ad08fc8dcc38ba94b" + sha256: cda8d72135b697f519287258b5294a57ce2f2a5ebf234f0e406aad4dc14c9399 url: "https://pub.dev" source: hosted - version: "6.0.1" + version: "6.1.0" flutter_plugin_android_lifecycle: dependency: transitive description: @@ -211,10 +211,10 @@ packages: dependency: transitive description: name: google_maps_flutter_ios - sha256: "2aa28eb9b9d5dfdce6932a7b7f096430bf83a1a09b4e21e81939351f407c787f" + sha256: "6ad65362aeeeda44b7c2c807e36bf578ef4b1c163882e085bdb040bf2934b246" url: "https://pub.dev" source: hosted - version: "2.3.2" + version: "2.3.3" google_maps_flutter_platform_interface: dependency: "direct main" description: @@ -259,10 +259,10 @@ packages: dependency: transitive description: name: intl - sha256: "3bc132a9dbce73a7e4a21a17d06e1878839ffbf975568bc875c60537824b0c4d" + sha256: d6f56758b7d3014a48af9701c085700aac781a92a87a62b1333b46d8879661cf url: "https://pub.dev" source: hosted - version: "0.18.1" + version: "0.19.0" js: dependency: transitive description: @@ -347,10 +347,10 @@ packages: dependency: transitive description: name: path - sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917" + sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af" url: "https://pub.dev" source: hosted - version: "1.8.3" + version: "1.9.0" plugin_platform_interface: dependency: transitive description: @@ -464,10 +464,10 @@ packages: dependency: transitive description: name: win32 - sha256: "7c99c0e1e2fa190b48d25c81ca5e42036d5cac81430ef249027d97b0935c553f" + sha256: b0f37db61ba2f2e9b7a78a1caece0052564d1bc70668156cf3a29d676fe4e574 url: "https://pub.dev" source: hosted - version: "5.1.0" + version: "5.1.1" win32_registry: dependency: transitive description: diff --git a/plugins/aves_services_huawei/pubspec.lock b/plugins/aves_services_huawei/pubspec.lock index c02c76e5e..33415cddb 100644 --- a/plugins/aves_services_huawei/pubspec.lock +++ b/plugins/aves_services_huawei/pubspec.lock @@ -109,10 +109,10 @@ packages: dependency: transitive description: name: flutter_map - sha256: "2b925948b675ef74ca524179fb133dbe0a21741889ccf56ad08fc8dcc38ba94b" + sha256: cda8d72135b697f519287258b5294a57ce2f2a5ebf234f0e406aad4dc14c9399 url: "https://pub.dev" source: hosted - version: "6.0.1" + version: "6.1.0" http: dependency: transitive description: @@ -151,10 +151,10 @@ packages: dependency: transitive description: name: intl - sha256: "3bc132a9dbce73a7e4a21a17d06e1878839ffbf975568bc875c60537824b0c4d" + sha256: d6f56758b7d3014a48af9701c085700aac781a92a87a62b1333b46d8879661cf url: "https://pub.dev" source: hosted - version: "0.18.1" + version: "0.19.0" latlong2: dependency: "direct main" description: @@ -223,10 +223,10 @@ packages: dependency: transitive description: name: path - sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917" + sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af" url: "https://pub.dev" source: hosted - version: "1.8.3" + version: "1.9.0" plugin_platform_interface: dependency: transitive description: diff --git a/plugins/aves_services_none/pubspec.lock b/plugins/aves_services_none/pubspec.lock index 3b9e8af2e..62af4f3b5 100644 --- a/plugins/aves_services_none/pubspec.lock +++ b/plugins/aves_services_none/pubspec.lock @@ -95,10 +95,10 @@ packages: dependency: transitive description: name: flutter_map - sha256: "2b925948b675ef74ca524179fb133dbe0a21741889ccf56ad08fc8dcc38ba94b" + sha256: cda8d72135b697f519287258b5294a57ce2f2a5ebf234f0e406aad4dc14c9399 url: "https://pub.dev" source: hosted - version: "6.0.1" + version: "6.1.0" http: dependency: transitive description: @@ -119,10 +119,10 @@ packages: dependency: transitive description: name: intl - sha256: "3bc132a9dbce73a7e4a21a17d06e1878839ffbf975568bc875c60537824b0c4d" + sha256: d6f56758b7d3014a48af9701c085700aac781a92a87a62b1333b46d8879661cf url: "https://pub.dev" source: hosted - version: "0.18.1" + version: "0.19.0" latlong2: dependency: "direct main" description: @@ -191,10 +191,10 @@ packages: dependency: transitive description: name: path - sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917" + sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af" url: "https://pub.dev" source: hosted - version: "1.8.3" + version: "1.9.0" polylabel: dependency: transitive description: diff --git a/plugins/aves_utils/lib/src/colors.dart b/plugins/aves_utils/lib/src/colors.dart index d5e9768b4..6189f4131 100644 --- a/plugins/aves_utils/lib/src/colors.dart +++ b/plugins/aves_utils/lib/src/colors.dart @@ -5,4 +5,9 @@ class ColorUtils { // when used in gradients or lerping to it static const transparentWhite = Color(0x00FFFFFF); static const transparentBlack = Color(0x00000000); + + static Color textColorOn(Color background) { + final yiq = (background.red * 299 + background.green * 587 + background.blue * 114) / 1000; + return Color(yiq >= 128 ? 0xFF000000 : 0xFFFFFFFF); + } } diff --git a/plugins/aves_video_mpv/pubspec.lock b/plugins/aves_video_mpv/pubspec.lock index 7ae539f49..36a69373b 100644 --- a/plugins/aves_video_mpv/pubspec.lock +++ b/plugins/aves_video_mpv/pubspec.lock @@ -228,10 +228,10 @@ packages: dependency: transitive description: name: path - sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917" + sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af" url: "https://pub.dev" source: hosted - version: "1.8.3" + version: "1.9.0" petitparser: dependency: transitive description: @@ -345,10 +345,10 @@ packages: dependency: transitive description: name: synchronized - sha256: "5fcbd27688af6082f5abd611af56ee575342c30e87541d0245f7ff99faa02c60" + sha256: "539ef412b170d65ecdafd780f924e5be3f60032a1128df156adad6c5b373d558" url: "https://pub.dev" source: hosted - version: "3.1.0" + version: "3.1.0+1" term_glyph: dependency: transitive description: @@ -385,10 +385,10 @@ packages: dependency: transitive description: name: uuid - sha256: df5a4d8f22ee4ccd77f8839ac7cb274ebc11ef9adcce8b92be14b797fe889921 + sha256: "22c94e5ad1e75f9934b766b53c742572ee2677c56bc871d850a57dad0f82127f" url: "https://pub.dev" source: hosted - version: "4.2.1" + version: "4.2.2" vector_math: dependency: transitive description: @@ -433,18 +433,18 @@ packages: dependency: transitive description: name: win32 - sha256: "7c99c0e1e2fa190b48d25c81ca5e42036d5cac81430ef249027d97b0935c553f" + sha256: b0f37db61ba2f2e9b7a78a1caece0052564d1bc70668156cf3a29d676fe4e574 url: "https://pub.dev" source: hosted - version: "5.1.0" + version: "5.1.1" xml: dependency: transitive description: name: xml - sha256: af5e77e9b83f2f4adc5d3f0a4ece1c7f45a2467b695c2540381bac793e34e556 + sha256: b015a8ad1c488f66851d762d3090a21c600e479dc75e68328c52774040cf9226 url: "https://pub.dev" source: hosted - version: "6.4.2" + version: "6.5.0" sdks: dart: ">=3.2.0 <4.0.0" flutter: ">=3.7.0" diff --git a/pubspec.lock b/pubspec.lock index a6a7b3561..ee5e578c2 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -13,10 +13,10 @@ packages: dependency: transitive description: name: _flutterfire_internals - sha256: eb0ac20f704799b986049fbb3c1c16421eca319a1b872378d669513e12452ba5 + sha256: f5628cd9c92ed11083f425fd1f8f1bc60ecdda458c81d73b143aeda036c35fe7 url: "https://pub.dev" source: hosted - version: "1.3.14" + version: "1.3.16" analyzer: dependency: transitive description: @@ -144,10 +144,10 @@ packages: dependency: transitive description: name: barcode - sha256: "789f898eef0bd88312470bdb2cc996f895ad7dd5f89e9adde84b204546a90b45" + sha256: "2a8b2ee065f419c2aeda141436cc556d91ae772d220fd80679f4d431d6c2ab43" url: "https://pub.dev" source: hosted - version: "2.2.4" + version: "2.2.5" bidi: dependency: transitive description: @@ -314,10 +314,10 @@ packages: dependency: "direct main" description: name: dynamic_color - sha256: "8b8bd1d798bd393e11eddeaa8ae95b12ff028bf7d5998fc5d003488cd5f4ce2f" + sha256: a866f1f8947bfdaf674d7928e769eac7230388a2e7a2542824fad4bb5b87be3b url: "https://pub.dev" source: hosted - version: "1.6.8" + version: "1.6.9" equatable: dependency: "direct main" description: @@ -388,10 +388,10 @@ packages: dependency: transitive description: name: firebase_core - sha256: d301561d614487688d797717bef013a264c517d1d09e4c5c1325c3a64c835efb + sha256: "96607c0e829a581c2a483c658f04e8b159964c3bae2730f73297070bc85d40bb" url: "https://pub.dev" source: hosted - version: "2.24.0" + version: "2.24.2" firebase_core_platform_interface: dependency: transitive description: @@ -404,26 +404,26 @@ packages: dependency: transitive description: name: firebase_core_web - sha256: "10159d9ee42c79f4548971d92f3f0fcd5791f6738cda3583a4e3b2c8b244c018" + sha256: d585bdf3c656c3f7821ba1bd44da5f13365d22fcecaf5eb75c4295246aaa83c0 url: "https://pub.dev" source: hosted - version: "2.9.0" + version: "2.10.0" firebase_crashlytics: dependency: transitive description: name: firebase_crashlytics - sha256: "60ef0016c0c2a7d16bf02468e3b27cd0ad4606f6d35535998dde3150cc0bc771" + sha256: "5ccdf05de039f9544d0ba41c5ae2052ca2425985d32229911b09f69981164518" url: "https://pub.dev" source: hosted - version: "3.4.6" + version: "3.4.8" firebase_crashlytics_platform_interface: dependency: transitive description: name: firebase_crashlytics_platform_interface - sha256: d185100facc6f7c43c5718103111488d008c52df8c19cbc5e5f9d2115d734909 + sha256: "359197344def001589c84f8d1d57c05f6e2e773f559205610ce58c25e2045a57" url: "https://pub.dev" source: hosted - version: "3.6.14" + version: "3.6.16" flex_color_picker: dependency: "direct main" description: @@ -516,10 +516,10 @@ packages: dependency: "direct main" description: name: flutter_map - sha256: "2b925948b675ef74ca524179fb133dbe0a21741889ccf56ad08fc8dcc38ba94b" + sha256: cda8d72135b697f519287258b5294a57ce2f2a5ebf234f0e406aad4dc14c9399 url: "https://pub.dev" source: hosted - version: "6.0.1" + version: "6.1.0" flutter_markdown: dependency: "direct main" description: @@ -635,10 +635,10 @@ packages: dependency: transitive description: name: google_maps_flutter_ios - sha256: "2aa28eb9b9d5dfdce6932a7b7f096430bf83a1a09b4e21e81939351f407c787f" + sha256: "6ad65362aeeeda44b7c2c807e36bf578ef4b1c163882e085bdb040bf2934b246" url: "https://pub.dev" source: hosted - version: "2.3.2" + version: "2.3.3" google_maps_flutter_platform_interface: dependency: transitive description: @@ -747,10 +747,10 @@ packages: dependency: "direct main" description: name: leak_tracker - sha256: "04be76c4a4bb50f14904e64749237e541e7c7bcf7ec0b196907322ab5d2fc739" + sha256: e45c31f458d01fd9ef4a214feb2e153b72d5b1907435f4332b1637a2f348c021 url: "https://pub.dev" source: hosted - version: "9.0.16" + version: "9.0.18" lints: dependency: transitive description: @@ -779,10 +779,10 @@ packages: dependency: transitive description: name: local_auth_android - sha256: df4ccb3193525b8a60c78a5ca7bf188a47705bcf77bcc837a6b2cf6da64ae0e2 + sha256: "54e9c35ce52c06333355ab0d0f41e4c06dbca354b23426765ba41dfb1de27598" url: "https://pub.dev" source: hosted - version: "1.0.35" + version: "1.0.36" local_auth_ios: dependency: transitive description: @@ -1061,10 +1061,10 @@ packages: dependency: "direct main" description: name: pdf - sha256: aa8835fcb9cfaf57ab2f1970e8548ceed3d0cb53eda7da906648f8153eaf37c9 + sha256: "93cbb2c06de9bab91844550f19896b2373e7a5ce25173995e7e5ec5e1741429d" url: "https://pub.dev" source: hosted - version: "3.10.6" + version: "3.10.7" percent_indicator: dependency: "direct main" description: @@ -1101,10 +1101,10 @@ packages: dependency: transitive description: name: permission_handler_html - sha256: d96ff56a757b7f04fa825c469d296c5aebc55f743e87bd639fef91a466a24da8 + sha256: "11b762a8c123dced6461933a88ea1edbbe036078c3f9f41b08886e678e7864df" url: "https://pub.dev" source: hosted - version: "0.1.0+1" + version: "0.1.0+2" permission_handler_platform_interface: dependency: transitive description: @@ -1491,10 +1491,10 @@ packages: dependency: transitive description: name: synchronized - sha256: "5fcbd27688af6082f5abd611af56ee575342c30e87541d0245f7ff99faa02c60" + sha256: "539ef412b170d65ecdafd780f924e5be3f60032a1128df156adad6c5b373d558" url: "https://pub.dev" source: hosted - version: "3.1.0" + version: "3.1.0+1" term_glyph: dependency: transitive description: @@ -1571,10 +1571,10 @@ packages: dependency: "direct main" description: name: url_launcher - sha256: b1c9e98774adf8820c96fbc7ae3601231d324a7d5ebd8babe27b6dfac91357ba + sha256: e9aa5ea75c84cf46b3db4eea212523591211c3cf2e13099ee4ec147f54201c86 url: "https://pub.dev" source: hosted - version: "6.2.1" + version: "6.2.2" url_launcher_android: dependency: transitive description: @@ -1595,10 +1595,10 @@ packages: dependency: transitive description: name: url_launcher_linux - sha256: "9f2d390e096fdbe1e6e6256f97851e51afc2d9c423d3432f1d6a02a8a9a8b9fd" + sha256: ab360eb661f8879369acac07b6bb3ff09d9471155357da8443fd5d3cf7363811 url: "https://pub.dev" source: hosted - version: "3.1.0" + version: "3.1.1" url_launcher_macos: dependency: transitive description: @@ -1619,26 +1619,26 @@ packages: dependency: transitive description: name: url_launcher_web - sha256: "138bd45b3a456dcfafc46d1a146787424f8d2edfbf2809c9324361e58f851cf7" + sha256: "7286aec002c8feecc338cc33269e96b73955ab227456e9fb2a91f7fab8a358e9" url: "https://pub.dev" source: hosted - version: "2.2.1" + version: "2.2.2" url_launcher_windows: dependency: transitive description: name: url_launcher_windows - sha256: "7754a1ad30ee896b265f8d14078b0513a4dba28d358eabb9d5f339886f4a1adc" + sha256: ecf9725510600aa2bb6d7ddabe16357691b6d2805f66216a97d1b881e21beff7 url: "https://pub.dev" source: hosted - version: "3.1.0" + version: "3.1.1" uuid: dependency: transitive description: name: uuid - sha256: df5a4d8f22ee4ccd77f8839ac7cb274ebc11ef9adcce8b92be14b797fe889921 + sha256: "22c94e5ad1e75f9934b766b53c742572ee2677c56bc871d850a57dad0f82127f" url: "https://pub.dev" source: hosted - version: "4.2.1" + version: "4.2.2" vector_math: dependency: "direct main" description: @@ -1723,10 +1723,10 @@ packages: dependency: transitive description: name: win32 - sha256: "7c99c0e1e2fa190b48d25c81ca5e42036d5cac81430ef249027d97b0935c553f" + sha256: b0f37db61ba2f2e9b7a78a1caece0052564d1bc70668156cf3a29d676fe4e574 url: "https://pub.dev" source: hosted - version: "5.1.0" + version: "5.1.1" win32_registry: dependency: transitive description: @@ -1755,10 +1755,10 @@ packages: dependency: "direct main" description: name: xml - sha256: af5e77e9b83f2f4adc5d3f0a4ece1c7f45a2467b695c2540381bac793e34e556 + sha256: b015a8ad1c488f66851d762d3090a21c600e479dc75e68328c52774040cf9226 url: "https://pub.dev" source: hosted - version: "6.4.2" + version: "6.5.0" yaml: dependency: transitive description: @@ -1769,4 +1769,4 @@ packages: version: "3.1.2" sdks: dart: ">=3.2.0 <4.0.0" - flutter: ">=3.16.1" + flutter: ">=3.16.5" diff --git a/pubspec.yaml b/pubspec.yaml index b2303691b..9685864a0 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -7,13 +7,13 @@ repository: https://github.com/deckerst/aves # - play changelog: /whatsnew/whatsnew-en-US # - izzy changelog: /fastlane/metadata/android/en-US/changelogs/XXX01.txt # - libre changelog: /fastlane/metadata/android/en-US/changelogs/XXX.txt -version: 1.10.0+109 +version: 1.10.1+110 publish_to: none environment: # this project bundles Flutter SDK via `flutter_wrapper` # cf https://github.com/passsy/flutter_wrapper - flutter: 3.16.1 + flutter: 3.16.5 sdk: '>=3.2.0 <4.0.0' # use `scripts/apply_flavor_{flavor}.sh` to set the right dependencies for the flavor diff --git a/scripts/screenshot_post_process.sh b/scripts/screenshot_post_process.sh index 861b7cb9e..38c732fd0 100755 --- a/scripts/screenshot_post_process.sh +++ b/scripts/screenshot_post_process.sh @@ -69,6 +69,9 @@ for source in framed/*/*; do convert "$source" -gravity center -background transparent -extent $PLAY_SIZE "$target" fi done +mv play/nb play/no-NO +mv play/zh play/zh-CN +mv play/zh_Hant play/zh-TW # readme: scale down for source in framed/en/*; do diff --git a/shaders.sksl.json b/shaders.sksl.json index fbaf64825..ba0a7ce99 100644 --- a/shaders.sksl.json +++ b/shaders.sksl.json @@ -1 +1 @@ -{"platform":"android","name":"SM G970N","engineRevision":"cf7a9d0800f2a5da166dbe0eb9fb2476018269b1","data":{"HUJAAAAAAAQAADAAAIOAAAH677777777777QGHAQAD7P7777777777YBAAAAAAQAAAAAAQQGABZAA6IAAAAACAAAAAADUAAAAAAAEAAAAAIDEAAAAAAA":"DAAAAExTS1PlAAAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gZmxvYXQyIGxvY2FsQ29vcmQ7Cm91dCBmbG9hdDIgdmxvY2FsQ29vcmRfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJdmxvY2FsQ29vcmRfUzAgPSBsb2NhbENvb3JkOwoJc2tfUG9zaXRpb24gPSBwb3NpdGlvbi54eTAxOwp9CgAAAAEAAAAzAwAAdW5pZm9ybSBmbG9hdDQgdWlubmVyUmVjdF9TMTsKdW5pZm9ybSBoYWxmMiB1cmFkaXVzUGx1c0hhbGZfUzE7CnNhbXBsZXIyRCB1VGV4dHVyZVNhbXBsZXJfMF9TMDsKaW4gZmxvYXQyIHZsb2NhbENvb3JkX1MwOwpoYWxmNCBDaXJjdWxhclJSZWN0X1MxKGhhbGY0IF9pbnB1dCkgCnsKCWZsb2F0MiBkeHkwID0gdWlubmVyUmVjdF9TMS5MVCAtIHNrX0ZyYWdDb29yZC54eTsKCWZsb2F0MiBkeHkxID0gc2tfRnJhZ0Nvb3JkLnh5IC0gdWlubmVyUmVjdF9TMS5SQjsKCWZsb2F0MiBkeHkgPSBtYXgobWF4KGR4eTAsIGR4eTEpLCAwLjApOwoJaGFsZiBhbHBoYSA9IGhhbGYoc2F0dXJhdGUodXJhZGl1c1BsdXNIYWxmX1MxLnggLSBsZW5ndGgoZHh5KSkpOwoJcmV0dXJuIF9pbnB1dCAqIGFscGhhOwp9CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwID0gaGFsZjQoMSk7CglmbG9hdDIgdGV4Q29vcmQ7Cgl0ZXhDb29yZCA9IHZsb2NhbENvb3JkX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSAoYmxlbmRfbW9kdWxhdGUoc2FtcGxlKHVUZXh0dXJlU2FtcGxlcl8wX1MwLCB0ZXhDb29yZCksIGhhbGY0KDEpKSk7Cgljb25zdCBoYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KDEpOwoJaGFsZjQgb3V0cHV0X1MxOwoJb3V0cHV0X1MxID0gQ2lyY3VsYXJSUmVjdF9TMShvdXRwdXRDb3ZlcmFnZV9TMCk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRfUzE7Cgl9Cn0KAAEAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAACAAAACAAAAHBvc2l0aW9uCgAAAGxvY2FsQ29vcmQAAAAAAAA=","HUQACAAAAAMAADAAAIOAAAH677776IZOCAAP577777777777777777YBAAAAAAAAAAAKAAYAAAACAAAAAAACCAYAAA":"DAAAAExTS1PPAAAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gaGFsZjQgY29sb3I7Cm91dCBoYWxmNCB2Y29sb3JfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJdmNvbG9yX1MwID0gY29sb3I7Cglza19Qb3NpdGlvbiA9IHBvc2l0aW9uLnh5MDE7Cn0KAAAAAAAMAQAAaW4gaGFsZjQgdmNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmNvbG9yX1MwOwoJY29uc3QgaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNCgxKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dENvdmVyYWdlX1MwOwoJfQp9CgAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAACAAAACAAAAHBvc2l0aW9uBQAAAGNvbG9yAAAAAAAAAA==","HUIAAAAAAAQAADAAAIOAAAH677777777777QGHAQAD7P7777777777YBAAAAAAAAAAALUAQBAAAQAAAAGQCBAMQACAAAAAAAACQAGAAAAAQAAAAAAAQQGAAAAA":"DAAAAExTS1M2AQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMTsKaW4gZmxvYXQyIHBvc2l0aW9uOwppbiBmbG9hdDIgbG9jYWxDb29yZDsKb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCglza19Qb3NpdGlvbiA9IHBvc2l0aW9uLnh5MDE7Cgl7CgkJdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzAgPSBmbG9hdDN4Mih1bWF0cml4X1MxKSAqIGxvY2FsQ29vcmQueHkxOwoJfQp9CgAAAAAAAGgDAAB1bmlmb3JtIGZsb2F0NCB1Y2xhbXBfUzFfYzA7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMTsKc2FtcGxlcjJEIHVUZXh0dXJlU2FtcGxlcl8wX1MxOwppbiBmbG9hdDIgdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzA7CmhhbGY0IFRleHR1cmVFZmZlY3RfUzFfYzAoaGFsZjQgX2lucHV0KSAKewoJZmxvYXQyIGluQ29vcmQgPSB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKCWZsb2F0MiBzdWJzZXRDb29yZDsKCXN1YnNldENvb3JkLnggPSBpbkNvb3JkLng7CglzdWJzZXRDb29yZC55ID0gaW5Db29yZC55OwoJZmxvYXQyIGNsYW1wZWRDb29yZDsKCWNsYW1wZWRDb29yZC54ID0gY2xhbXAoc3Vic2V0Q29vcmQueCwgdWNsYW1wX1MxX2MwLngsIHVjbGFtcF9TMV9jMC56KTsKCWNsYW1wZWRDb29yZC55ID0gc3Vic2V0Q29vcmQueTsKCWhhbGY0IHRleHR1cmVDb2xvciA9IHNhbXBsZSh1VGV4dHVyZVNhbXBsZXJfMF9TMSwgY2xhbXBlZENvb3JkKTsKCXJldHVybiB0ZXh0dXJlQ29sb3I7Cn0KaGFsZjQgTWF0cml4RWZmZWN0X1MxKGhhbGY0IF9pbnB1dCkgCnsKCXJldHVybiBUZXh0dXJlRWZmZWN0X1MxX2MwKF9pbnB1dCk7Cn0Kdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJaGFsZjQgb3V0cHV0Q29sb3JfUzAgPSBoYWxmNCgxKTsKCWNvbnN0IGhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoMSk7CgloYWxmNCBvdXRwdXRfUzE7CglvdXRwdXRfUzEgPSBNYXRyaXhFZmZlY3RfUzEob3V0cHV0Q29sb3JfUzApOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dF9TMSAqIG91dHB1dENvdmVyYWdlX1MwOwoJfQp9CgAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAACAAAACAAAAHBvc2l0aW9uCgAAAGxvY2FsQ29vcmQAAAAAAAA=","HVIAAAAAABIAAGAAAQ4AAAH477776R24EAAAIOBQAD6P7777777777YDAAAAAAAAAAAFIBVWKMG7QAAAAAAAEAQCAAAAAVREEAQAAAAAQCDAAQQGAABAEAAAAAAHIAAAAAAAIAAAAAQGIAAAAAAA":"DAAAAExTS1N6AQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMV9jMDsKaW4gZmxvYXQyIHBvc2l0aW9uOwppbiBoYWxmNCBjb2xvcjsKaW4gZmxvYXQyIGxvY2FsQ29vcmQ7CmZsYXQgb3V0IGhhbGY0IHZjb2xvcl9TMDsKb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfM19TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgl2Y29sb3JfUzAgPSBjb2xvcjsKCXNrX1Bvc2l0aW9uID0gcG9zaXRpb24ueHkwMTsKCXsKCQl2VHJhbnNmb3JtZWRDb29yZHNfM19TMCA9IGZsb2F0M3gyKHVtYXRyaXhfUzFfYzApICogbG9jYWxDb29yZC54eTE7Cgl9Cn0KAAAAAAAAHwQAAHVuaWZvcm0gZmxvYXQ0IHVjbGFtcF9TMV9jMF9jMDsKdW5pZm9ybSBmbG9hdDN4MyB1bWF0cml4X1MxX2MwOwpzYW1wbGVyMkQgdVRleHR1cmVTYW1wbGVyXzBfUzE7CmZsYXQgaW4gaGFsZjQgdmNvbG9yX1MwOwppbiBmbG9hdDIgdlRyYW5zZm9ybWVkQ29vcmRzXzNfUzA7CmhhbGY0IFRleHR1cmVFZmZlY3RfUzFfYzBfYzAoaGFsZjQgX2lucHV0KSAKewoJZmxvYXQyIGluQ29vcmQgPSB2VHJhbnNmb3JtZWRDb29yZHNfM19TMDsKCWZsb2F0MiBzdWJzZXRDb29yZDsKCXN1YnNldENvb3JkLnggPSBpbkNvb3JkLng7CglzdWJzZXRDb29yZC55ID0gaW5Db29yZC55OwoJZmxvYXQyIGNsYW1wZWRDb29yZDsKCWNsYW1wZWRDb29yZCA9IGNsYW1wKHN1YnNldENvb3JkLCB1Y2xhbXBfUzFfYzBfYzAueHksIHVjbGFtcF9TMV9jMF9jMC56dyk7CgloYWxmNCB0ZXh0dXJlQ29sb3IgPSBzYW1wbGUodVRleHR1cmVTYW1wbGVyXzBfUzEsIGNsYW1wZWRDb29yZCk7CglyZXR1cm4gdGV4dHVyZUNvbG9yOwp9CmhhbGY0IE1hdHJpeEVmZmVjdF9TMV9jMChoYWxmNCBfaW5wdXQpIAp7CglyZXR1cm4gVGV4dHVyZUVmZmVjdF9TMV9jMF9jMChfaW5wdXQpOwp9CmhhbGY0IERpc2FibGVDb3ZlcmFnZUFzQWxwaGFfUzEoaGFsZjQgX2lucHV0KSAKewoJX2lucHV0ID0gTWF0cml4RWZmZWN0X1MxX2MwKF9pbnB1dCk7CgloYWxmNCBfdG1wXzBfaW5Db2xvciA9IF9pbnB1dDsKCXJldHVybiBoYWxmNChfaW5wdXQpOwp9CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2Y29sb3JfUzA7Cgljb25zdCBoYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KDEpOwoJaGFsZjQgb3V0cHV0X1MxOwoJb3V0cHV0X1MxID0gRGlzYWJsZUNvdmVyYWdlQXNBbHBoYV9TMShvdXRwdXRDb2xvcl9TMCk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0X1MxICogb3V0cHV0Q292ZXJhZ2VfUzA7Cgl9Cn0KAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAADAAAACAAAAHBvc2l0aW9uBQAAAGNvbG9yAAAACgAAAGxvY2FsQ29vcmQAAAAAAAA=","CMRQCIAABBYAAAEIXBAAACDQMAABRAFAAAAAAAAAAAAAAAEABYAAAAEAAAAAAAEEBQAAAAA":"DAAAAExTS1MyAgAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQ0IHVsb2NhbE1hdHJpeF9TMDsKaW4gZmxvYXQyIGluUG9zaXRpb247CmluIGhhbGY0IGluQ29sb3I7CmluIGZsb2F0MiBpbkVsbGlwc2VPZmZzZXQ7CmluIGZsb2F0NCBpbkVsbGlwc2VSYWRpaTsKb3V0IGZsb2F0MiB2RWxsaXBzZU9mZnNldHNfUzA7Cm91dCBmbG9hdDQgdkVsbGlwc2VSYWRpaV9TMDsKb3V0IGhhbGY0IHZpbkNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBFbGxpcHNlR2VvbWV0cnlQcm9jZXNzb3IKCXZFbGxpcHNlT2Zmc2V0c19TMCA9IGluRWxsaXBzZU9mZnNldDsKCXZFbGxpcHNlUmFkaWlfUzAgPSBpbkVsbGlwc2VSYWRpaTsKCXZpbkNvbG9yX1MwID0gaW5Db2xvcjsKCWZsb2F0MiBfdG1wXzBfaW5Qb3NpdGlvbiA9IGluUG9zaXRpb247CglmbG9hdDIgX3RtcF8xX2luUG9zaXRpb24gPSB1bG9jYWxNYXRyaXhfUzAueHogKiBpblBvc2l0aW9uICsgdWxvY2FsTWF0cml4X1MwLnl3OwoJc2tfUG9zaXRpb24gPSBfdG1wXzBfaW5Qb3NpdGlvbi54eTAxOwp9CgAAAAAAAHIDAABpbiBmbG9hdDIgdkVsbGlwc2VPZmZzZXRzX1MwOwppbiBmbG9hdDQgdkVsbGlwc2VSYWRpaV9TMDsKaW4gaGFsZjQgdmluQ29sb3JfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBFbGxpcHNlR2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2aW5Db2xvcl9TMDsKCWZsb2F0MiBvZmZzZXQgPSB2RWxsaXBzZU9mZnNldHNfUzAueHk7CglvZmZzZXQgKj0gdkVsbGlwc2VSYWRpaV9TMC54eTsKCWZsb2F0IHRlc3QgPSBkb3Qob2Zmc2V0LCBvZmZzZXQpIC0gMS4wOwoJZmxvYXQyIGdyYWQgPSAyLjAqb2Zmc2V0KnZFbGxpcHNlUmFkaWlfUzAueHk7CglmbG9hdCBncmFkX2RvdCA9IGRvdChncmFkLCBncmFkKTsKCWdyYWRfZG90ID0gbWF4KGdyYWRfZG90LCAxLjE3NTVlLTM4KTsKCWZsb2F0IGludmxlbiA9IGludmVyc2VzcXJ0KGdyYWRfZG90KTsKCWZsb2F0IGVkZ2VBbHBoYSA9IHNhdHVyYXRlKDAuNS10ZXN0Kmludmxlbik7CglvZmZzZXQgPSB2RWxsaXBzZU9mZnNldHNfUzAueHkqdkVsbGlwc2VSYWRpaV9TMC56dzsKCXRlc3QgPSBkb3Qob2Zmc2V0LCBvZmZzZXQpIC0gMS4wOwoJZ3JhZCA9IDIuMCpvZmZzZXQqdkVsbGlwc2VSYWRpaV9TMC56dzsKCWdyYWRfZG90ID0gZG90KGdyYWQsIGdyYWQpOwoJaW52bGVuID0gaW52ZXJzZXNxcnQoZ3JhZF9kb3QpOwoJZWRnZUFscGhhICo9IHNhdHVyYXRlKDAuNSt0ZXN0Kmludmxlbik7CgloYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KGhhbGYoZWRnZUFscGhhKSk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRDb3ZlcmFnZV9TMDsKCX0KfQoAAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAEAAAACgAAAGluUG9zaXRpb24AAAcAAABpbkNvbG9yAA8AAABpbkVsbGlwc2VPZmZzZXQADgAAAGluRWxsaXBzZVJhZGlpAAAAAAAA","HVJAAAAAABIAAGAAAQ4AAAH477776R24EAAAIOBQAD6P7777777777YDAAAAABAAAAAABBAMABAAOAAAABAAAAAAABBAMAAA":"DAAAAExTS1MjAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gaGFsZjQgY29sb3I7CmluIGZsb2F0MiBsb2NhbENvb3JkOwpmbGF0IG91dCBoYWxmNCB2Y29sb3JfUzA7Cm91dCBmbG9hdDIgdmxvY2FsQ29vcmRfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJdmNvbG9yX1MwID0gY29sb3I7Cgl2bG9jYWxDb29yZF9TMCA9IGxvY2FsQ29vcmQ7Cglza19Qb3NpdGlvbiA9IHBvc2l0aW9uLnh5MDE7Cn0KAAAAAADVAQAAc2FtcGxlcjJEIHVUZXh0dXJlU2FtcGxlcl8wX1MwOwpmbGF0IGluIGhhbGY0IHZjb2xvcl9TMDsKaW4gZmxvYXQyIHZsb2NhbENvb3JkX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmNvbG9yX1MwOwoJZmxvYXQyIHRleENvb3JkOwoJdGV4Q29vcmQgPSB2bG9jYWxDb29yZF9TMDsKCW91dHB1dENvbG9yX1MwID0gKGJsZW5kX21vZHVsYXRlKHNhbXBsZSh1VGV4dHVyZVNhbXBsZXJfMF9TMCwgdGV4Q29vcmQpLCBvdXRwdXRDb2xvcl9TMCkpOwoJY29uc3QgaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNCgxKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dENvdmVyYWdlX1MwOwoJfQp9CgAAAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAADAAAACAAAAHBvc2l0aW9uBQAAAGNvbG9yAAAACgAAAGxvY2FsQ29vcmQAAAAAAAA=","AYQQ5AADQAAAOAEARAFQJAABBADIB7777777777777777777777767YAAAAAAAAAAAAOQAAAAAAAQAAAABAMQAAAAA":"DAAAAExTS1PMAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQ0IHVsb2NhbE1hdHJpeF9TMDsKaW4gZmxvYXQyIGluUG9zaXRpb247CmluIGhhbGY0IGluQ29sb3I7CmluIGZsb2F0NCBpbkNpcmNsZUVkZ2U7Cm91dCBmbG9hdDQgdmluQ2lyY2xlRWRnZV9TMDsKb3V0IGhhbGY0IHZpbkNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBDaXJjbGVHZW9tZXRyeVByb2Nlc3NvcgoJdmluQ2lyY2xlRWRnZV9TMCA9IGluQ2lyY2xlRWRnZTsKCXZpbkNvbG9yX1MwID0gaW5Db2xvcjsKCWZsb2F0MiBfdG1wXzBfaW5Qb3NpdGlvbiA9IGluUG9zaXRpb247CglmbG9hdDIgX3RtcF8xX2luUG9zaXRpb24gPSB1bG9jYWxNYXRyaXhfUzAueHogKiBpblBvc2l0aW9uICsgdWxvY2FsTWF0cml4X1MwLnl3OwoJc2tfUG9zaXRpb24gPSBfdG1wXzBfaW5Qb3NpdGlvbi54eTAxOwp9CgAAAAB7AgAAaW4gZmxvYXQ0IHZpbkNpcmNsZUVkZ2VfUzA7CmluIGhhbGY0IHZpbkNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgQ2lyY2xlR2VvbWV0cnlQcm9jZXNzb3IKCWZsb2F0NCBjaXJjbGVFZGdlOwoJY2lyY2xlRWRnZSA9IHZpbkNpcmNsZUVkZ2VfUzA7CgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmluQ29sb3JfUzA7CglmbG9hdCBkID0gbGVuZ3RoKGNpcmNsZUVkZ2UueHkpOwoJaGFsZiBkaXN0YW5jZVRvT3V0ZXJFZGdlID0gaGFsZihjaXJjbGVFZGdlLnogKiAoMS4wIC0gZCkpOwoJaGFsZiBlZGdlQWxwaGEgPSBzYXR1cmF0ZShkaXN0YW5jZVRvT3V0ZXJFZGdlKTsKCWhhbGYgZGlzdGFuY2VUb0lubmVyRWRnZSA9IGhhbGYoY2lyY2xlRWRnZS56ICogKGQgLSBjaXJjbGVFZGdlLncpKTsKCWhhbGYgaW5uZXJBbHBoYSA9IHNhdHVyYXRlKGRpc3RhbmNlVG9Jbm5lckVkZ2UpOwoJZWRnZUFscGhhICo9IGlubmVyQWxwaGE7CgloYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KGVkZ2VBbHBoYSk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRDb3ZlcmFnZV9TMDsKCX0KfQoAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAKAAAAaW5Qb3NpdGlvbgAABwAAAGluQ29sb3IADAAAAGluQ2lyY2xlRWRnZQAAAAA=","HVIACAAAABQAAGAAAQ4AAAAAGQQAARC4GAAAIOCAAD6P7777777777YDAAAAAAAAAAAHQBNGZODK5YIAAAAAAQAAAAAIADCNS4GV3QYBAAAAAAAAAAAIAALIAAAAB2BQ7SD2OAAAAAMAAAAAEAHQAACAAAAAAQCGHIGP7YJJAAAAABQAAAAAAAAAAA4JAPAAACAAAAAAAAAB2AAAAAAACAAAAAEBSAAA":"DAAAAExTS1PZAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMTsKaW4gZmxvYXQyIHBvc2l0aW9uOwppbiBmbG9hdCBjb3ZlcmFnZTsKaW4gaGFsZjQgY29sb3I7CmluIGZsb2F0MiBsb2NhbENvb3JkOwpmbGF0IG91dCBoYWxmNCB2Y29sb3JfUzA7Cm91dCBmbG9hdCB2Y292ZXJhZ2VfUzA7Cm91dCBmbG9hdDIgdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJZmxvYXQyIHBvc2l0aW9uID0gcG9zaXRpb24ueHk7Cgl2Y29sb3JfUzAgPSBjb2xvcjsKCXZjb3ZlcmFnZV9TMCA9IGNvdmVyYWdlOwoJc2tfUG9zaXRpb24gPSBwb3NpdGlvbi54eTAxOwoJewoJCXZUcmFuc2Zvcm1lZENvb3Jkc18yX1MwID0gZmxvYXQzeDIodW1hdHJpeF9TMSkgKiBsb2NhbENvb3JkLnh5MTsKCX0KfQoAAAABAAAA2CAAAGZsb2F0NCBmbHV0dGVyX0ZyYWdDb29yZF9TMV9jMDsKZmxvYXQ0IGZyYWdDb2xvcl9TMV9jMDsKZmxvYXQgdV9hbHBoYV9TMV9jMDsKZmxvYXQgdV9zcGFya2xlX2FscGhhX1MxX2MwOwpmbG9hdCB1X2JsdXJfUzFfYzA7CmZsb2F0IHVfcmFkaXVzX3NjYWxlX1MxX2MwOwpjb25zdCBpbnQga0ZpbGxCV19TMl9jMCA9IDA7CmNvbnN0IGludCBrSW52ZXJzZUZpbGxCV19TMl9jMCA9IDI7CmNvbnN0IGludCBrSW52ZXJzZUZpbGxBQV9TMl9jMCA9IDM7CnVuaWZvcm0gZmxvYXQ0IHVfY29sb3JfUzFfYzA7CnVuaWZvcm0gZmxvYXQ0IHVfY29tcG9zaXRlXzFfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfY2VudGVyX1MxX2MwOwp1bmlmb3JtIGZsb2F0IHVfbWF4X3JhZGl1c19TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9yZXNvbHV0aW9uX3NjYWxlX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X25vaXNlX3NjYWxlX1MxX2MwOwp1bmlmb3JtIGZsb2F0IHVfbm9pc2VfcGhhc2VfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfY2lyY2xlMV9TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9jaXJjbGUyX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X2NpcmNsZTNfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfcm90YXRpb24xX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X3JvdGF0aW9uMl9TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9yb3RhdGlvbjNfUzFfYzA7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMTsKdW5pZm9ybSBmbG9hdDQgdXJlY3RVbmlmb3JtX1MyX2MwOwp1bmlmb3JtIGZsb2F0NCB1aW5uZXJSZWN0X1MyX2MxOwp1bmlmb3JtIGhhbGYyIHVyYWRpdXNQbHVzSGFsZl9TMl9jMTsKZmxhdCBpbiBoYWxmNCB2Y29sb3JfUzA7CmluIGZsb2F0IHZjb3ZlcmFnZV9TMDsKaW4gZmxvYXQyIHZUcmFuc2Zvcm1lZENvb3Jkc18yX1MwOwpmbG9hdDIgRkxUX2ZsdXR0ZXJfbG9jYWxfRmx1dHRlckZyYWdDb29yZF9TMV9jMCgpOwpmbG9hdDJ4MiBGTFRfZmx1dHRlcl9sb2NhbF9yb3RhdGUyZF9TMV9jMChmbG9hdDIgcmFkKTsKZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9jaXJjbGVfUzFfYzAoZmxvYXQyIHV2LCBmbG9hdDIgeHksIGZsb2F0IHJhZGl1cywgZmxvYXQgYmx1cik7CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX2NpcmNsZV9ncmlkX1MxX2MwKGZsb2F0MiByZXNvbHV0aW9uLCBpbm91dCBmbG9hdDIgcCwgZmxvYXQyIHh5LCBmbG9hdDIgcm90YXRpb24sIGZsb2F0IGNlbGxfZGlhbWV0ZXIpOwpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF90dXJidWxlbmNlX1MxX2MwKGZsb2F0MiB1dik7CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfcmluZ19TMV9jMChmbG9hdDIgdXYsIGZsb2F0MiB4eSwgZmxvYXQgcmFkaXVzLCBmbG9hdCB0aGlja25lc3MsIGZsb2F0IGJsdXIpOwpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF90cmlhbmdsZV9ub2lzZV9TMV9jMChpbm91dCBmbG9hdDIgbik7CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3RocmVzaG9sZF9TMV9jMChmbG9hdCB2LCBmbG9hdCBsLCBmbG9hdCBoKTsKZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfc3BhcmtsZV9TMV9jMChmbG9hdDIgdXYsIGZsb2F0IHQpOwp2b2lkIEZMVF9tYWluX1MxX2MwKCk7CmZsb2F0MiBGTFRfZmx1dHRlcl9sb2NhbF9GbHV0dGVyRnJhZ0Nvb3JkX1MxX2MwKCkgCnsKCXJldHVybiBmbHV0dGVyX0ZyYWdDb29yZF9TMV9jMC54eTsKfQpmbG9hdDJ4MiBGTFRfZmx1dHRlcl9sb2NhbF9yb3RhdGUyZF9TMV9jMChmbG9hdDIgcmFkKSAKewoJcmV0dXJuIGZsb2F0MngyKHJhZC54LCAtcmFkLnksIHJhZC55LCByYWQueCk7Cn0KZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9jaXJjbGVfUzFfYzAoZmxvYXQyIHV2LCBmbG9hdDIgeHksIGZsb2F0IHJhZGl1cywgZmxvYXQgYmx1cikgCnsKCWZsb2F0IGJsdXJfaGFsZiA9IGJsdXIgKiAwLjU7CglmbG9hdCBkID0gZGlzdGFuY2UodXYsIHh5KTsKCXJldHVybiAxLjAgLSBzbW9vdGhzdGVwKDEuMCAtIGJsdXJfaGFsZiwgMS4wICsgYmx1cl9oYWxmLCBkIC8gcmFkaXVzKTsKfQpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9jaXJjbGVfZ3JpZF9TMV9jMChmbG9hdDIgcmVzb2x1dGlvbiwgaW5vdXQgZmxvYXQyIHAsIGZsb2F0MiB4eSwgZmxvYXQyIHJvdGF0aW9uLCBmbG9hdCBjZWxsX2RpYW1ldGVyKSAKewoJZmxvYXQyIHBhcmFtID0gcm90YXRpb247CglwID0gRkxUX2ZsdXR0ZXJfbG9jYWxfcm90YXRlMmRfUzFfYzAocGFyYW0pICogKHh5IC0gcCkgKyB4eTsKCXAgPSBtb2QocCwgZmxvYXQyKGNlbGxfZGlhbWV0ZXIpKSAvIHJlc29sdXRpb247CglmbG9hdCBjZWxsX3V2ID0gKGNlbGxfZGlhbWV0ZXIgLyByZXNvbHV0aW9uLnkpICogMC41OwoJZmxvYXQgciA9IDAuNjUgKiBjZWxsX3V2OwoJZmxvYXQyIHBhcmFtXzEgPSBwOwoJZmxvYXQyIHBhcmFtXzIgPSBmbG9hdDIoY2VsbF91dik7CglmbG9hdCBwYXJhbV8zID0gcjsKCWZsb2F0IHBhcmFtXzQgPSByICogNTAuMDsKCXJldHVybiBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X2NpcmNsZV9TMV9jMChwYXJhbV8xLCBwYXJhbV8yLCBwYXJhbV8zLCBwYXJhbV80KTsKfQpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF90dXJidWxlbmNlX1MxX2MwKGZsb2F0MiB1dikgCnsKCWZsb2F0MiB1dl9zY2FsZSA9IHV2ICogZmxvYXQyKDAuOCk7CglmbG9hdDIgcGFyYW0gPSBmbG9hdDIoMC44KTsKCWZsb2F0MiBwYXJhbV8xID0gdXZfc2NhbGU7CglmbG9hdDIgcGFyYW1fMiA9IHVfY2lyY2xlMV9TMV9jMDsKCWZsb2F0MiBwYXJhbV8zID0gdV9yb3RhdGlvbjFfUzFfYzA7CglmbG9hdCBwYXJhbV80ID0gMC4xNzsKCWZsb2F0IF8zMTkgPSBGTFRfZmx1dHRlcl9sb2NhbF9jaXJjbGVfZ3JpZF9TMV9jMChwYXJhbSwgcGFyYW1fMSwgcGFyYW1fMiwgcGFyYW1fMywgcGFyYW1fNCk7CglmbG9hdCBnMSA9IF8zMTk7CglmbG9hdDIgcGFyYW1fNSA9IGZsb2F0MigwLjgpOwoJZmxvYXQyIHBhcmFtXzYgPSB1dl9zY2FsZTsKCWZsb2F0MiBwYXJhbV83ID0gdV9jaXJjbGUyX1MxX2MwOwoJZmxvYXQyIHBhcmFtXzggPSB1X3JvdGF0aW9uMl9TMV9jMDsKCWZsb2F0IHBhcmFtXzkgPSAwLjI7CglmbG9hdCBfMzMxID0gRkxUX2ZsdXR0ZXJfbG9jYWxfY2lyY2xlX2dyaWRfUzFfYzAocGFyYW1fNSwgcGFyYW1fNiwgcGFyYW1fNywgcGFyYW1fOCwgcGFyYW1fOSk7CglmbG9hdCBnMiA9IF8zMzE7CglmbG9hdDIgcGFyYW1fMTAgPSBmbG9hdDIoMC44KTsKCWZsb2F0MiBwYXJhbV8xMSA9IHV2X3NjYWxlOwoJZmxvYXQyIHBhcmFtXzEyID0gdV9jaXJjbGUzX1MxX2MwOwoJZmxvYXQyIHBhcmFtXzEzID0gdV9yb3RhdGlvbjNfUzFfYzA7CglmbG9hdCBwYXJhbV8xNCA9IDAuMjc1OwoJZmxvYXQgXzM0NCA9IEZMVF9mbHV0dGVyX2xvY2FsX2NpcmNsZV9ncmlkX1MxX2MwKHBhcmFtXzEwLCBwYXJhbV8xMSwgcGFyYW1fMTIsIHBhcmFtXzEzLCBwYXJhbV8xNCk7CglmbG9hdCBnMyA9IF8zNDQ7CglmbG9hdCB2ID0gKChnMSAqIGcxICsgZzIpIC0gZzMpICogMC41OwoJcmV0dXJuIGNsYW1wKDAuNDUgKyAwLjggKiB2LCAwLjAsIDEuMCk7Cn0KZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9yaW5nX1MxX2MwKGZsb2F0MiB1diwgZmxvYXQyIHh5LCBmbG9hdCByYWRpdXMsIGZsb2F0IHRoaWNrbmVzcywgZmxvYXQgYmx1cikgCnsKCWZsb2F0MiBwYXJhbSA9IHV2OwoJZmxvYXQyIHBhcmFtXzEgPSB4eTsKCWZsb2F0IHBhcmFtXzIgPSByYWRpdXMgKyB0aGlja25lc3M7CglmbG9hdCBwYXJhbV8zID0gYmx1cjsKCWZsb2F0IGNpcmNsZV9vdXRlciA9IEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfY2lyY2xlX1MxX2MwKHBhcmFtLCBwYXJhbV8xLCBwYXJhbV8yLCBwYXJhbV8zKTsKCWZsb2F0MiBwYXJhbV80ID0gdXY7CglmbG9hdDIgcGFyYW1fNSA9IHh5OwoJZmxvYXQgcGFyYW1fNiA9IG1heChyYWRpdXMgLSB0aGlja25lc3MsIDAuMCk7CglmbG9hdCBwYXJhbV83ID0gYmx1cjsKCWZsb2F0IGNpcmNsZV9pbm5lciA9IEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfY2lyY2xlX1MxX2MwKHBhcmFtXzQsIHBhcmFtXzUsIHBhcmFtXzYsIHBhcmFtXzcpOwoJcmV0dXJuIGNsYW1wKGNpcmNsZV9vdXRlciAtIGNpcmNsZV9pbm5lciwgMC4wLCAxLjApOwp9CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3RyaWFuZ2xlX25vaXNlX1MxX2MwKGlub3V0IGZsb2F0MiBuKSAKewoJbiA9IGZyYWN0KG4gKiBmbG9hdDIoNS4zOTg3LCA1LjQ0MjEpKTsKCW4gKz0gZmxvYXQyKGRvdChuLnl4LCBuICsgZmxvYXQyKDIxLjUzNTEsIDE0LjMxMzcpKSk7CglmbG9hdCB4eSA9IG4ueCAqIG4ueTsKCXJldHVybiAoZnJhY3QoeHkgKiA5NS40MzA3KSArIGZyYWN0KHh5ICogNzUuMDQ5NjEpKSAtIDEuMDsKfQpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF90aHJlc2hvbGRfUzFfYzAoZmxvYXQgdiwgZmxvYXQgbCwgZmxvYXQgaCkgCnsKCXJldHVybiBzdGVwKGwsIHYpICogKDEuMCAtIHN0ZXAoaCwgdikpOwp9CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3NwYXJrbGVfUzFfYzAoZmxvYXQyIHV2LCBmbG9hdCB0KSAKewoJZmxvYXQyIHBhcmFtID0gdXY7CglmbG9hdCBfMjQyID0gRkxUX2ZsdXR0ZXJfbG9jYWxfdHJpYW5nbGVfbm9pc2VfUzFfYzAocGFyYW0pOwoJZmxvYXQgbiA9IF8yNDI7CglmbG9hdCBwYXJhbV8xID0gbjsKCWZsb2F0IHBhcmFtXzIgPSAwLjA7CglmbG9hdCBwYXJhbV8zID0gMC4wNTsKCWZsb2F0IHMgPSBGTFRfZmx1dHRlcl9sb2NhbF90aHJlc2hvbGRfUzFfYzAocGFyYW1fMSwgcGFyYW1fMiwgcGFyYW1fMyk7CglmbG9hdCBwYXJhbV80ID0gbiArIHNpbigzLjE0MTU5Mjc0ICogKHQgKyAwLjM1KSk7CglmbG9hdCBwYXJhbV81ID0gMC4xOwoJZmxvYXQgcGFyYW1fNiA9IDAuMTU7CglzICs9IEZMVF9mbHV0dGVyX2xvY2FsX3RocmVzaG9sZF9TMV9jMChwYXJhbV80LCBwYXJhbV81LCBwYXJhbV82KTsKCWZsb2F0IHBhcmFtXzcgPSBuICsgc2luKDMuMTQxNTkyNzQgKiAodCArIDAuNykpOwoJZmxvYXQgcGFyYW1fOCA9IDAuMjsKCWZsb2F0IHBhcmFtXzkgPSAwLjI1OwoJcyArPSBGTFRfZmx1dHRlcl9sb2NhbF90aHJlc2hvbGRfUzFfYzAocGFyYW1fNywgcGFyYW1fOCwgcGFyYW1fOSk7CglmbG9hdCBwYXJhbV8xMCA9IG4gKyBzaW4oMy4xNDE1OTI3NCAqICh0ICsgMS4wNSkpOwoJZmxvYXQgcGFyYW1fMTEgPSAwLjM7CglmbG9hdCBwYXJhbV8xMiA9IDAuMzU7CglzICs9IEZMVF9mbHV0dGVyX2xvY2FsX3RocmVzaG9sZF9TMV9jMChwYXJhbV8xMCwgcGFyYW1fMTEsIHBhcmFtXzEyKTsKCXJldHVybiBjbGFtcChzLCAwLjAsIDEuMCkgKiAwLjU1Owp9CnZvaWQgRkxUX21haW5fUzFfYzAoKSAKewoJdV9hbHBoYV9TMV9jMCA9IHVfY29tcG9zaXRlXzFfUzFfYzAueDsKCXVfc3BhcmtsZV9hbHBoYV9TMV9jMCA9IHVfY29tcG9zaXRlXzFfUzFfYzAueTsKCXVfYmx1cl9TMV9jMCA9IHVfY29tcG9zaXRlXzFfUzFfYzAuejsKCXVfcmFkaXVzX3NjYWxlX1MxX2MwID0gdV9jb21wb3NpdGVfMV9TMV9jMC53OwoJZmxvYXQyIHAgPSBGTFRfZmx1dHRlcl9sb2NhbF9GbHV0dGVyRnJhZ0Nvb3JkX1MxX2MwKCk7CglmbG9hdDIgdXZfMSA9IHAgKiB1X3Jlc29sdXRpb25fc2NhbGVfUzFfYzA7CglmbG9hdDIgZGVuc2l0eV91diA9IHV2XzEgLSBtb2QocCwgdV9ub2lzZV9zY2FsZV9TMV9jMCk7CglmbG9hdCByYWRpdXMgPSB1X21heF9yYWRpdXNfUzFfYzAgKiB1X3JhZGl1c19zY2FsZV9TMV9jMDsKCWZsb2F0MiBwYXJhbV8xMyA9IHV2XzE7CglmbG9hdCB0dXJidWxlbmNlID0gRkxUX2ZsdXR0ZXJfbG9jYWxfdHVyYnVsZW5jZV9TMV9jMChwYXJhbV8xMyk7CglmbG9hdDIgcGFyYW1fMTQgPSBwOwoJZmxvYXQyIHBhcmFtXzE1ID0gdV9jZW50ZXJfUzFfYzA7CglmbG9hdCBwYXJhbV8xNiA9IHJhZGl1czsKCWZsb2F0IHBhcmFtXzE3ID0gMC4wNSAqIHVfbWF4X3JhZGl1c19TMV9jMDsKCWZsb2F0IHBhcmFtXzE4ID0gdV9ibHVyX1MxX2MwOwoJZmxvYXQgcmluZyA9IEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfcmluZ19TMV9jMChwYXJhbV8xNCwgcGFyYW1fMTUsIHBhcmFtXzE2LCBwYXJhbV8xNywgcGFyYW1fMTgpOwoJZmxvYXQyIHBhcmFtXzE5ID0gZGVuc2l0eV91djsKCWZsb2F0IHBhcmFtXzIwID0gdV9ub2lzZV9waGFzZV9TMV9jMDsKCWZsb2F0IHNwYXJrbGUgPSAoKEZMVF9mbHV0dGVyX2xvY2FsX3NwYXJrbGVfUzFfYzAocGFyYW1fMTksIHBhcmFtXzIwKSAqIHJpbmcpICogdHVyYnVsZW5jZSkgKiB1X3NwYXJrbGVfYWxwaGFfUzFfYzA7CglmbG9hdDIgcGFyYW1fMjEgPSBwOwoJZmxvYXQyIHBhcmFtXzIyID0gdV9jZW50ZXJfUzFfYzA7CglmbG9hdCBwYXJhbV8yMyA9IHJhZGl1czsKCWZsb2F0IHBhcmFtXzI0ID0gdV9ibHVyX1MxX2MwOwoJZmxvYXQgd2F2ZV9hbHBoYSA9IChGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X2NpcmNsZV9TMV9jMChwYXJhbV8yMSwgcGFyYW1fMjIsIHBhcmFtXzIzLCBwYXJhbV8yNCkgKiB1X2FscGhhX1MxX2MwKSAqIHVfY29sb3JfUzFfYzAudzsKCWZsb2F0NCB3YXZlX2NvbG9yID0gZmxvYXQ0KHVfY29sb3JfUzFfYzAueHl6ICogd2F2ZV9hbHBoYSwgd2F2ZV9hbHBoYSk7CglmcmFnQ29sb3JfUzFfYzAgPSBtaXgod2F2ZV9jb2xvciwgZmxvYXQ0KDEuMCksIGZsb2F0NChzcGFya2xlKSk7Cn0KaGFsZjQgcnVudGltZV9zaGFkZXJfUzFfYzAoaGFsZjQgX2lucHV0KSAKewoJaGFsZjQgX3RtcF8wX2luQ29sb3IgPSBfaW5wdXQ7CglmbG9hdDIgX3RtcF8xX2Nvb3JkcyA9IHZUcmFuc2Zvcm1lZENvb3Jkc18yX1MwOwoJZmx1dHRlcl9GcmFnQ29vcmRfUzFfYzAgPSBmbG9hdDQoX3RtcF8xX2Nvb3JkcywgMC4wLCAwLjApOwoJRkxUX21haW5fUzFfYzAoKTsKCXJldHVybiBoYWxmNChoYWxmNChmcmFnQ29sb3JfUzFfYzApKTsKfQpoYWxmNCBNYXRyaXhFZmZlY3RfUzEoaGFsZjQgX2lucHV0KSAKewoJcmV0dXJuIHJ1bnRpbWVfc2hhZGVyX1MxX2MwKF9pbnB1dCk7Cn0KaGFsZjQgUmVjdF9TMl9jMChoYWxmNCBfaW5wdXQpIAp7CgloYWxmNCBfdG1wXzJfaW5Db2xvciA9IF9pbnB1dDsKCWhhbGYgY292ZXJhZ2U7CglpZiAoaW50KDEpID09IGtGaWxsQldfUzJfYzAgfHwgaW50KDEpID09IGtJbnZlcnNlRmlsbEJXX1MyX2MwKSAKCXsKCQljb3ZlcmFnZSA9IGhhbGYoYWxsKGdyZWF0ZXJUaGFuKGZsb2F0NChza19GcmFnQ29vcmQueHksIHVyZWN0VW5pZm9ybV9TMl9jMC56dyksIGZsb2F0NCh1cmVjdFVuaWZvcm1fUzJfYzAueHksIHNrX0ZyYWdDb29yZC54eSkpKSk7Cgl9CgllbHNlIAoJewoJCWhhbGY0IGRpc3RzNCA9IHNhdHVyYXRlKGhhbGY0KDEuMCwgMS4wLCAtMS4wLCAtMS4wKSAqIGhhbGY0KHNrX0ZyYWdDb29yZC54eXh5IC0gdXJlY3RVbmlmb3JtX1MyX2MwKSk7CgkJaGFsZjIgZGlzdHMyID0gKGRpc3RzNC54eSArIGRpc3RzNC56dykgLSAxLjA7CgkJY292ZXJhZ2UgPSBkaXN0czIueCAqIGRpc3RzMi55OwoJfQoJaWYgKGludCgxKSA9PSBrSW52ZXJzZUZpbGxCV19TMl9jMCB8fCBpbnQoMSkgPT0ga0ludmVyc2VGaWxsQUFfUzJfYzApIAoJewoJCWNvdmVyYWdlID0gMS4wIC0gY292ZXJhZ2U7Cgl9CglyZXR1cm4gaGFsZjQoaGFsZjQoY292ZXJhZ2UpKTsKfQpoYWxmNCBDaXJjdWxhclJSZWN0X1MyX2MxKGhhbGY0IF9pbnB1dCkgCnsKCWZsb2F0MiBkeHkwID0gdWlubmVyUmVjdF9TMl9jMS5MVCAtIHNrX0ZyYWdDb29yZC54eTsKCWZsb2F0MiBkeHkxID0gc2tfRnJhZ0Nvb3JkLnh5IC0gdWlubmVyUmVjdF9TMl9jMS5SQjsKCWZsb2F0MiBkeHkgPSBtYXgobWF4KGR4eTAsIGR4eTEpLCAwLjApOwoJaGFsZiBhbHBoYSA9IGhhbGYoc2F0dXJhdGUodXJhZGl1c1BsdXNIYWxmX1MyX2MxLnggLSBsZW5ndGgoZHh5KSkpOwoJcmV0dXJuIF9pbnB1dCAqIGFscGhhOwp9CmhhbGY0IEJsZW5kX1MyKGhhbGY0IF9zcmMsIGhhbGY0IF9kc3QpIAp7CglyZXR1cm4gYmxlbmRfbW9kdWxhdGUoUmVjdF9TMl9jMChfc3JjKSwgQ2lyY3VsYXJSUmVjdF9TMl9jMShfc3JjKSk7Cn0Kdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJaGFsZjQgb3V0cHV0Q29sb3JfUzA7CglvdXRwdXRDb2xvcl9TMCA9IHZjb2xvcl9TMDsKCWZsb2F0IGNvdmVyYWdlID0gdmNvdmVyYWdlX1MwOwoJaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNChoYWxmKGNvdmVyYWdlKSk7CgloYWxmNCBvdXRwdXRfUzE7CglvdXRwdXRfUzEgPSBNYXRyaXhFZmZlY3RfUzEob3V0cHV0Q29sb3JfUzApOwoJaGFsZjQgb3V0cHV0X1MyOwoJb3V0cHV0X1MyID0gQmxlbmRfUzIob3V0cHV0Q292ZXJhZ2VfUzAsIGhhbGY0KDEpKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRfUzEgKiBvdXRwdXRfUzI7Cgl9Cn0KAQAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAIAAAAcG9zaXRpb24IAAAAY292ZXJhZ2UFAAAAY29sb3IAAAAKAAAAbG9jYWxDb29yZAAAAAAAAA==","FAAQMYAAMAAAEADAAABAEYAAAICIAB5AABQAAAQAMAAAEATAAABAIIGAAEDCBYQCA4AAAAAAEAB5AAAAACQNNQSEIYAQAADQAAAABAAAAAAABAEMVC2TBEKRAAAAAHAAAAAAAAAAACQAGAAAAAQAAAAAAAQQGAAA":"DAAAAExTS1PUCwAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0NCByYWRpaV9zZWxlY3RvcjsKaW4gZmxvYXQ0IGNvcm5lcl9hbmRfcmFkaXVzX291dHNldHM7CmluIGZsb2F0NCBhYV9ibG9hdF9hbmRfY292ZXJhZ2U7CmluIGZsb2F0NCByYWRpaV94OwppbiBmbG9hdDQgcmFkaWlfeTsKaW4gZmxvYXQ0IHNrZXc7CmluIGZsb2F0MiB0cmFuc2xhdGVfYW5kX2xvY2Fscm90YXRlOwppbiBoYWxmNCBjb2xvcjsKZmxhdCBvdXQgaGFsZjQgdmNvbG9yX1MwOwpvdXQgZmxvYXQyIHZhcmNjb29yZF9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgRmlsbFJSZWN0T3A6OlByb2Nlc3NvcgoJdmNvbG9yX1MwID0gY29sb3I7CglmbG9hdCBhYV9ibG9hdF9tdWx0aXBsaWVyID0gMTsKCWZsb2F0MiBjb3JuZXIgPSBjb3JuZXJfYW5kX3JhZGl1c19vdXRzZXRzLnh5OwoJZmxvYXQyIHJhZGl1c19vdXRzZXQgPSBjb3JuZXJfYW5kX3JhZGl1c19vdXRzZXRzLnp3OwoJZmxvYXQyIGFhX2Jsb2F0X2RpcmVjdGlvbiA9IGFhX2Jsb2F0X2FuZF9jb3ZlcmFnZS54eTsKCWZsb2F0IGlzX2xpbmVhcl9jb3ZlcmFnZSA9IGFhX2Jsb2F0X2FuZF9jb3ZlcmFnZS53OwoJZmxvYXQyIHBpeGVsbGVuZ3RoID0gaW52ZXJzZXNxcnQoZmxvYXQyKGRvdChza2V3Lnh6LCBza2V3Lnh6KSwgZG90KHNrZXcueXcsIHNrZXcueXcpKSk7CglmbG9hdDQgbm9ybWFsaXplZF9heGlzX2RpcnMgPSBza2V3ICogcGl4ZWxsZW5ndGgueHl4eTsKCWZsb2F0MiBheGlzd2lkdGhzID0gKGFicyhub3JtYWxpemVkX2F4aXNfZGlycy54eSkgKyBhYnMobm9ybWFsaXplZF9heGlzX2RpcnMuencpKTsKCWZsb2F0MiBhYV9ibG9hdHJhZGl1cyA9IGF4aXN3aWR0aHMgKiBwaXhlbGxlbmd0aCAqIC41OwoJZmxvYXQ0IHJhZGlpX2FuZF9uZWlnaGJvcnMgPSByYWRpaV9zZWxlY3RvciogZmxvYXQ0eDQocmFkaWlfeCwgcmFkaWlfeSwgcmFkaWlfeC55eHd6LCByYWRpaV95Lnd6eXgpOwoJZmxvYXQyIHJhZGlpID0gcmFkaWlfYW5kX25laWdoYm9ycy54eTsKCWZsb2F0MiBuZWlnaGJvcl9yYWRpaSA9IHJhZGlpX2FuZF9uZWlnaGJvcnMuenc7CglmbG9hdCBjb3ZlcmFnZV9tdWx0aXBsaWVyID0gMTsKCWlmIChhbnkoZ3JlYXRlclRoYW4oYWFfYmxvYXRyYWRpdXMsIGZsb2F0MigxKSkpKSAKCXsKCQljb3JuZXIgPSBtYXgoYWJzKGNvcm5lciksIGFhX2Jsb2F0cmFkaXVzKSAqIHNpZ24oY29ybmVyKTsKCQljb3ZlcmFnZV9tdWx0aXBsaWVyID0gMSAvIChtYXgoYWFfYmxvYXRyYWRpdXMueCwgMSkgKiBtYXgoYWFfYmxvYXRyYWRpdXMueSwgMSkpOwoJCXJhZGlpID0gZmxvYXQyKDApOwoJfQoJZmxvYXQgY292ZXJhZ2UgPSBhYV9ibG9hdF9hbmRfY292ZXJhZ2UuejsKCWlmIChhbnkobGVzc1RoYW4ocmFkaWksIGFhX2Jsb2F0cmFkaXVzICogMS41KSkpIAoJewoJCXJhZGlpID0gZmxvYXQyKDApOwoJCWFhX2Jsb2F0X2RpcmVjdGlvbiA9IHNpZ24oY29ybmVyKTsKCQlpZiAoY292ZXJhZ2UgPiAuNSkgCgkJewoJCQlhYV9ibG9hdF9kaXJlY3Rpb24gPSAtYWFfYmxvYXRfZGlyZWN0aW9uOwoJCX0KCQlpc19saW5lYXJfY292ZXJhZ2UgPSAxOwoJfQoJZWxzZSAKCXsKCQlyYWRpaSA9IGNsYW1wKHJhZGlpLCBwaXhlbGxlbmd0aCAqIDEuNSwgMiAtIHBpeGVsbGVuZ3RoICogMS41KTsKCQluZWlnaGJvcl9yYWRpaSA9IGNsYW1wKG5laWdoYm9yX3JhZGlpLCBwaXhlbGxlbmd0aCAqIDEuNSwgMiAtIHBpeGVsbGVuZ3RoICogMS41KTsKCQlmbG9hdDIgc3BhY2luZyA9IDIgLSByYWRpaSAtIG5laWdoYm9yX3JhZGlpOwoJCWZsb2F0MiBleHRyYV9wYWQgPSBtYXgocGl4ZWxsZW5ndGggKiAuMDYyNSAtIHNwYWNpbmcsIGZsb2F0MigwKSk7CgkJcmFkaWkgLT0gZXh0cmFfcGFkICogLjU7Cgl9CglmbG9hdDIgYWFfb3V0c2V0ID0gYWFfYmxvYXRfZGlyZWN0aW9uICogYWFfYmxvYXRyYWRpdXMgKiBhYV9ibG9hdF9tdWx0aXBsaWVyOwoJZmxvYXQyIHZlcnRleHBvcyA9IGNvcm5lciArIHJhZGl1c19vdXRzZXQgKiByYWRpaSArIGFhX291dHNldDsKCWlmIChjb3ZlcmFnZSA+IC41KSAKCXsKCQlpZiAoYWFfYmxvYXRfZGlyZWN0aW9uLnggIT0gMCAmJiB2ZXJ0ZXhwb3MueCAqIGNvcm5lci54IDwgMCkgCgkJewoJCQlmbG9hdCBiYWNrc2V0ID0gYWJzKHZlcnRleHBvcy54KTsKCQkJdmVydGV4cG9zLnggPSAwOwoJCQl2ZXJ0ZXhwb3MueSArPSBiYWNrc2V0ICogc2lnbihjb3JuZXIueSkgKiBwaXhlbGxlbmd0aC55L3BpeGVsbGVuZ3RoLng7CgkJCWNvdmVyYWdlID0gKGNvdmVyYWdlIC0gLjUpICogYWJzKGNvcm5lci54KSAvIChhYnMoY29ybmVyLngpICsgYmFja3NldCkgKyAuNTsKCQl9CgkJaWYgKGFhX2Jsb2F0X2RpcmVjdGlvbi55ICE9IDAgJiYgdmVydGV4cG9zLnkgKiBjb3JuZXIueSA8IDApIAoJCXsKCQkJZmxvYXQgYmFja3NldCA9IGFicyh2ZXJ0ZXhwb3MueSk7CgkJCXZlcnRleHBvcy55ID0gMDsKCQkJdmVydGV4cG9zLnggKz0gYmFja3NldCAqIHNpZ24oY29ybmVyLngpICogcGl4ZWxsZW5ndGgueC9waXhlbGxlbmd0aC55OwoJCQljb3ZlcmFnZSA9IChjb3ZlcmFnZSAtIC41KSAqIGFicyhjb3JuZXIueSkgLyAoYWJzKGNvcm5lci55KSArIGJhY2tzZXQpICsgLjU7CgkJfQoJfQoJZmxvYXQyeDIgc2tld21hdHJpeCA9IGZsb2F0MngyKHNrZXcueHksIHNrZXcuencpOwoJZmxvYXQyIGRldmNvb3JkID0gdmVydGV4cG9zICogc2tld21hdHJpeCArIHRyYW5zbGF0ZV9hbmRfbG9jYWxyb3RhdGUueHk7CglpZiAoMCAhPSBpc19saW5lYXJfY292ZXJhZ2UpIAoJewoJCXZhcmNjb29yZF9TMC54eSA9IGZsb2F0MigwLCBjb3ZlcmFnZSAqIGNvdmVyYWdlX211bHRpcGxpZXIpOwoJfQoJZWxzZSAKCXsKCQlmbG9hdDIgYXJjY29vcmQgPSAxIC0gYWJzKHJhZGl1c19vdXRzZXQpICsgYWFfb3V0c2V0L3JhZGlpICogY29ybmVyOwoJCXZhcmNjb29yZF9TMC54eSA9IGZsb2F0MihhcmNjb29yZC54KzEsIGFyY2Nvb3JkLnkpOwoJfQoJc2tfUG9zaXRpb24gPSBkZXZjb29yZC54eTAxOwp9CgEAAABJBQAAY29uc3QgaW50IGtGaWxsQUFfUzFfYzAgPSAxOwpjb25zdCBpbnQga0ludmVyc2VGaWxsQldfUzFfYzAgPSAyOwpjb25zdCBpbnQga0ludmVyc2VGaWxsQUFfUzFfYzAgPSAzOwp1bmlmb3JtIGZsb2F0NCB1Y2lyY2xlX1MxX2MwOwpmbGF0IGluIGhhbGY0IHZjb2xvcl9TMDsKaW4gZmxvYXQyIHZhcmNjb29yZF9TMDsKaGFsZjQgQ2lyY2xlX1MxX2MwKGhhbGY0IF9pbnB1dCkgCnsKCWhhbGY0IF90bXBfMF9pbkNvbG9yID0gX2lucHV0OwoJaGFsZiBkOwoJaWYgKGludCgzKSA9PSBrSW52ZXJzZUZpbGxCV19TMV9jMCB8fCBpbnQoMykgPT0ga0ludmVyc2VGaWxsQUFfUzFfYzApIAoJewoJCWQgPSBoYWxmKChsZW5ndGgoKHVjaXJjbGVfUzFfYzAueHkgLSBza19GcmFnQ29vcmQueHkpICogdWNpcmNsZV9TMV9jMC53KSAtIDEuMCkgKiB1Y2lyY2xlX1MxX2MwLnopOwoJfQoJZWxzZSAKCXsKCQlkID0gaGFsZigoMS4wIC0gbGVuZ3RoKCh1Y2lyY2xlX1MxX2MwLnh5IC0gc2tfRnJhZ0Nvb3JkLnh5KSAqIHVjaXJjbGVfUzFfYzAudykpICogdWNpcmNsZV9TMV9jMC56KTsKCX0KCXJldHVybiBoYWxmNChoYWxmNChpbnQoMykgPT0ga0ZpbGxBQV9TMV9jMCB8fCBpbnQoMykgPT0ga0ludmVyc2VGaWxsQUFfUzFfYzAgPyBzYXR1cmF0ZShkKSA6IGhhbGYoZCA+IDAuNSkpKTsKfQpoYWxmNCBCbGVuZF9TMShoYWxmNCBfc3JjLCBoYWxmNCBfZHN0KSAKewoJcmV0dXJuIGJsZW5kX21vZHVsYXRlKF9zcmMsIENpcmNsZV9TMV9jMChfc3JjKSk7Cn0Kdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIEZpbGxSUmVjdE9wOjpQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2Y29sb3JfUzA7CglmbG9hdCB4X3BsdXNfMT12YXJjY29vcmRfUzAueCwgeT12YXJjY29vcmRfUzAueTsKCWhhbGYgY292ZXJhZ2U7CglpZiAoMCA9PSB4X3BsdXNfMSkgCgl7CgkJY292ZXJhZ2UgPSBoYWxmKHkpOwoJfQoJZWxzZSAKCXsKCQlmbG9hdCBmbiA9IHhfcGx1c18xICogKHhfcGx1c18xIC0gMik7CgkJZm4gPSBmbWEoeSx5LCBmbik7CgkJZmxvYXQgZm53aWR0aCA9IGZ3aWR0aChmbik7CgkJY292ZXJhZ2UgPSAuNSAtIGhhbGYoZm4vZm53aWR0aCk7CgkJY292ZXJhZ2UgPSBjbGFtcChjb3ZlcmFnZSwgMCwgMSk7Cgl9CgloYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KGNvdmVyYWdlKTsKCWhhbGY0IG91dHB1dF9TMTsKCW91dHB1dF9TMSA9IEJsZW5kX1MxKG91dHB1dENvdmVyYWdlX1MwLCBoYWxmNCgxKSk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRfUzE7Cgl9Cn0KAAAAAQAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAOAAAAcmFkaWlfc2VsZWN0b3IAABkAAABjb3JuZXJfYW5kX3JhZGl1c19vdXRzZXRzAAAAFQAAAGFhX2Jsb2F0X2FuZF9jb3ZlcmFnZQAAAAcAAAByYWRpaV94AAcAAAByYWRpaV95AAQAAABza2V3GQAAAHRyYW5zbGF0ZV9hbmRfbG9jYWxyb3RhdGUAAAAFAAAAY29sb3IAAAAAAAAA","HVIACAAAABQAAGAAAQ4AAAAAGQQAARC4GAAAIOCAAD6P7777777777YDAAAAAAAAAAAHQBNGZODK5YIAAAAAAQAAAAAIADCNS4GV3QYBAAAAAAAAAAAIAA4IAEAAACAAAAAABUABAAAAAEAAAAAIBEABAA":"DAAAAExTS1PZAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMTsKaW4gZmxvYXQyIHBvc2l0aW9uOwppbiBmbG9hdCBjb3ZlcmFnZTsKaW4gaGFsZjQgY29sb3I7CmluIGZsb2F0MiBsb2NhbENvb3JkOwpmbGF0IG91dCBoYWxmNCB2Y29sb3JfUzA7Cm91dCBmbG9hdCB2Y292ZXJhZ2VfUzA7Cm91dCBmbG9hdDIgdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJZmxvYXQyIHBvc2l0aW9uID0gcG9zaXRpb24ueHk7Cgl2Y29sb3JfUzAgPSBjb2xvcjsKCXZjb3ZlcmFnZV9TMCA9IGNvdmVyYWdlOwoJc2tfUG9zaXRpb24gPSBwb3NpdGlvbi54eTAxOwoJewoJCXZUcmFuc2Zvcm1lZENvb3Jkc18yX1MwID0gZmxvYXQzeDIodW1hdHJpeF9TMSkgKiBsb2NhbENvb3JkLnh5MTsKCX0KfQoAAAABAAAAth0AAGZsb2F0NCBmbHV0dGVyX0ZyYWdDb29yZF9TMV9jMDsKZmxvYXQ0IGZyYWdDb2xvcl9TMV9jMDsKZmxvYXQgdV9hbHBoYV9TMV9jMDsKZmxvYXQgdV9zcGFya2xlX2FscGhhX1MxX2MwOwpmbG9hdCB1X2JsdXJfUzFfYzA7CmZsb2F0IHVfcmFkaXVzX3NjYWxlX1MxX2MwOwp1bmlmb3JtIGZsb2F0NCB1X2NvbG9yX1MxX2MwOwp1bmlmb3JtIGZsb2F0NCB1X2NvbXBvc2l0ZV8xX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X2NlbnRlcl9TMV9jMDsKdW5pZm9ybSBmbG9hdCB1X21heF9yYWRpdXNfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfcmVzb2x1dGlvbl9zY2FsZV9TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9ub2lzZV9zY2FsZV9TMV9jMDsKdW5pZm9ybSBmbG9hdCB1X25vaXNlX3BoYXNlX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X2NpcmNsZTFfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfY2lyY2xlMl9TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9jaXJjbGUzX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X3JvdGF0aW9uMV9TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9yb3RhdGlvbjJfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfcm90YXRpb24zX1MxX2MwOwp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzE7CnVuaWZvcm0gZmxvYXQ0IHVpbm5lclJlY3RfUzI7CnVuaWZvcm0gaGFsZjIgdXJhZGl1c1BsdXNIYWxmX1MyOwpmbGF0IGluIGhhbGY0IHZjb2xvcl9TMDsKaW4gZmxvYXQgdmNvdmVyYWdlX1MwOwppbiBmbG9hdDIgdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzA7CmZsb2F0MiBGTFRfZmx1dHRlcl9sb2NhbF9GbHV0dGVyRnJhZ0Nvb3JkX1MxX2MwKCk7CmZsb2F0MngyIEZMVF9mbHV0dGVyX2xvY2FsX3JvdGF0ZTJkX1MxX2MwKGZsb2F0MiByYWQpOwpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X2NpcmNsZV9TMV9jMChmbG9hdDIgdXYsIGZsb2F0MiB4eSwgZmxvYXQgcmFkaXVzLCBmbG9hdCBibHVyKTsKZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfY2lyY2xlX2dyaWRfUzFfYzAoZmxvYXQyIHJlc29sdXRpb24sIGlub3V0IGZsb2F0MiBwLCBmbG9hdDIgeHksIGZsb2F0MiByb3RhdGlvbiwgZmxvYXQgY2VsbF9kaWFtZXRlcik7CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3R1cmJ1bGVuY2VfUzFfYzAoZmxvYXQyIHV2KTsKZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9yaW5nX1MxX2MwKGZsb2F0MiB1diwgZmxvYXQyIHh5LCBmbG9hdCByYWRpdXMsIGZsb2F0IHRoaWNrbmVzcywgZmxvYXQgYmx1cik7CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3RyaWFuZ2xlX25vaXNlX1MxX2MwKGlub3V0IGZsb2F0MiBuKTsKZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfdGhyZXNob2xkX1MxX2MwKGZsb2F0IHYsIGZsb2F0IGwsIGZsb2F0IGgpOwpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9zcGFya2xlX1MxX2MwKGZsb2F0MiB1diwgZmxvYXQgdCk7CnZvaWQgRkxUX21haW5fUzFfYzAoKTsKZmxvYXQyIEZMVF9mbHV0dGVyX2xvY2FsX0ZsdXR0ZXJGcmFnQ29vcmRfUzFfYzAoKSAKewoJcmV0dXJuIGZsdXR0ZXJfRnJhZ0Nvb3JkX1MxX2MwLnh5Owp9CmZsb2F0MngyIEZMVF9mbHV0dGVyX2xvY2FsX3JvdGF0ZTJkX1MxX2MwKGZsb2F0MiByYWQpIAp7CglyZXR1cm4gZmxvYXQyeDIocmFkLngsIC1yYWQueSwgcmFkLnksIHJhZC54KTsKfQpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X2NpcmNsZV9TMV9jMChmbG9hdDIgdXYsIGZsb2F0MiB4eSwgZmxvYXQgcmFkaXVzLCBmbG9hdCBibHVyKSAKewoJZmxvYXQgYmx1cl9oYWxmID0gYmx1ciAqIDAuNTsKCWZsb2F0IGQgPSBkaXN0YW5jZSh1diwgeHkpOwoJcmV0dXJuIDEuMCAtIHNtb290aHN0ZXAoMS4wIC0gYmx1cl9oYWxmLCAxLjAgKyBibHVyX2hhbGYsIGQgLyByYWRpdXMpOwp9CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX2NpcmNsZV9ncmlkX1MxX2MwKGZsb2F0MiByZXNvbHV0aW9uLCBpbm91dCBmbG9hdDIgcCwgZmxvYXQyIHh5LCBmbG9hdDIgcm90YXRpb24sIGZsb2F0IGNlbGxfZGlhbWV0ZXIpIAp7CglmbG9hdDIgcGFyYW0gPSByb3RhdGlvbjsKCXAgPSBGTFRfZmx1dHRlcl9sb2NhbF9yb3RhdGUyZF9TMV9jMChwYXJhbSkgKiAoeHkgLSBwKSArIHh5OwoJcCA9IG1vZChwLCBmbG9hdDIoY2VsbF9kaWFtZXRlcikpIC8gcmVzb2x1dGlvbjsKCWZsb2F0IGNlbGxfdXYgPSAoY2VsbF9kaWFtZXRlciAvIHJlc29sdXRpb24ueSkgKiAwLjU7CglmbG9hdCByID0gMC42NSAqIGNlbGxfdXY7CglmbG9hdDIgcGFyYW1fMSA9IHA7CglmbG9hdDIgcGFyYW1fMiA9IGZsb2F0MihjZWxsX3V2KTsKCWZsb2F0IHBhcmFtXzMgPSByOwoJZmxvYXQgcGFyYW1fNCA9IHIgKiA1MC4wOwoJcmV0dXJuIEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfY2lyY2xlX1MxX2MwKHBhcmFtXzEsIHBhcmFtXzIsIHBhcmFtXzMsIHBhcmFtXzQpOwp9CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3R1cmJ1bGVuY2VfUzFfYzAoZmxvYXQyIHV2KSAKewoJZmxvYXQyIHV2X3NjYWxlID0gdXYgKiBmbG9hdDIoMC44KTsKCWZsb2F0MiBwYXJhbSA9IGZsb2F0MigwLjgpOwoJZmxvYXQyIHBhcmFtXzEgPSB1dl9zY2FsZTsKCWZsb2F0MiBwYXJhbV8yID0gdV9jaXJjbGUxX1MxX2MwOwoJZmxvYXQyIHBhcmFtXzMgPSB1X3JvdGF0aW9uMV9TMV9jMDsKCWZsb2F0IHBhcmFtXzQgPSAwLjE3OwoJZmxvYXQgXzMxOSA9IEZMVF9mbHV0dGVyX2xvY2FsX2NpcmNsZV9ncmlkX1MxX2MwKHBhcmFtLCBwYXJhbV8xLCBwYXJhbV8yLCBwYXJhbV8zLCBwYXJhbV80KTsKCWZsb2F0IGcxID0gXzMxOTsKCWZsb2F0MiBwYXJhbV81ID0gZmxvYXQyKDAuOCk7CglmbG9hdDIgcGFyYW1fNiA9IHV2X3NjYWxlOwoJZmxvYXQyIHBhcmFtXzcgPSB1X2NpcmNsZTJfUzFfYzA7CglmbG9hdDIgcGFyYW1fOCA9IHVfcm90YXRpb24yX1MxX2MwOwoJZmxvYXQgcGFyYW1fOSA9IDAuMjsKCWZsb2F0IF8zMzEgPSBGTFRfZmx1dHRlcl9sb2NhbF9jaXJjbGVfZ3JpZF9TMV9jMChwYXJhbV81LCBwYXJhbV82LCBwYXJhbV83LCBwYXJhbV84LCBwYXJhbV85KTsKCWZsb2F0IGcyID0gXzMzMTsKCWZsb2F0MiBwYXJhbV8xMCA9IGZsb2F0MigwLjgpOwoJZmxvYXQyIHBhcmFtXzExID0gdXZfc2NhbGU7CglmbG9hdDIgcGFyYW1fMTIgPSB1X2NpcmNsZTNfUzFfYzA7CglmbG9hdDIgcGFyYW1fMTMgPSB1X3JvdGF0aW9uM19TMV9jMDsKCWZsb2F0IHBhcmFtXzE0ID0gMC4yNzU7CglmbG9hdCBfMzQ0ID0gRkxUX2ZsdXR0ZXJfbG9jYWxfY2lyY2xlX2dyaWRfUzFfYzAocGFyYW1fMTAsIHBhcmFtXzExLCBwYXJhbV8xMiwgcGFyYW1fMTMsIHBhcmFtXzE0KTsKCWZsb2F0IGczID0gXzM0NDsKCWZsb2F0IHYgPSAoKGcxICogZzEgKyBnMikgLSBnMykgKiAwLjU7CglyZXR1cm4gY2xhbXAoMC40NSArIDAuOCAqIHYsIDAuMCwgMS4wKTsKfQpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X3JpbmdfUzFfYzAoZmxvYXQyIHV2LCBmbG9hdDIgeHksIGZsb2F0IHJhZGl1cywgZmxvYXQgdGhpY2tuZXNzLCBmbG9hdCBibHVyKSAKewoJZmxvYXQyIHBhcmFtID0gdXY7CglmbG9hdDIgcGFyYW1fMSA9IHh5OwoJZmxvYXQgcGFyYW1fMiA9IHJhZGl1cyArIHRoaWNrbmVzczsKCWZsb2F0IHBhcmFtXzMgPSBibHVyOwoJZmxvYXQgY2lyY2xlX291dGVyID0gRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9jaXJjbGVfUzFfYzAocGFyYW0sIHBhcmFtXzEsIHBhcmFtXzIsIHBhcmFtXzMpOwoJZmxvYXQyIHBhcmFtXzQgPSB1djsKCWZsb2F0MiBwYXJhbV81ID0geHk7CglmbG9hdCBwYXJhbV82ID0gbWF4KHJhZGl1cyAtIHRoaWNrbmVzcywgMC4wKTsKCWZsb2F0IHBhcmFtXzcgPSBibHVyOwoJZmxvYXQgY2lyY2xlX2lubmVyID0gRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9jaXJjbGVfUzFfYzAocGFyYW1fNCwgcGFyYW1fNSwgcGFyYW1fNiwgcGFyYW1fNyk7CglyZXR1cm4gY2xhbXAoY2lyY2xlX291dGVyIC0gY2lyY2xlX2lubmVyLCAwLjAsIDEuMCk7Cn0KZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfdHJpYW5nbGVfbm9pc2VfUzFfYzAoaW5vdXQgZmxvYXQyIG4pIAp7CgluID0gZnJhY3QobiAqIGZsb2F0Mig1LjM5ODcsIDUuNDQyMSkpOwoJbiArPSBmbG9hdDIoZG90KG4ueXgsIG4gKyBmbG9hdDIoMjEuNTM1MSwgMTQuMzEzNykpKTsKCWZsb2F0IHh5ID0gbi54ICogbi55OwoJcmV0dXJuIChmcmFjdCh4eSAqIDk1LjQzMDcpICsgZnJhY3QoeHkgKiA3NS4wNDk2MSkpIC0gMS4wOwp9CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3RocmVzaG9sZF9TMV9jMChmbG9hdCB2LCBmbG9hdCBsLCBmbG9hdCBoKSAKewoJcmV0dXJuIHN0ZXAobCwgdikgKiAoMS4wIC0gc3RlcChoLCB2KSk7Cn0KZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfc3BhcmtsZV9TMV9jMChmbG9hdDIgdXYsIGZsb2F0IHQpIAp7CglmbG9hdDIgcGFyYW0gPSB1djsKCWZsb2F0IF8yNDIgPSBGTFRfZmx1dHRlcl9sb2NhbF90cmlhbmdsZV9ub2lzZV9TMV9jMChwYXJhbSk7CglmbG9hdCBuID0gXzI0MjsKCWZsb2F0IHBhcmFtXzEgPSBuOwoJZmxvYXQgcGFyYW1fMiA9IDAuMDsKCWZsb2F0IHBhcmFtXzMgPSAwLjA1OwoJZmxvYXQgcyA9IEZMVF9mbHV0dGVyX2xvY2FsX3RocmVzaG9sZF9TMV9jMChwYXJhbV8xLCBwYXJhbV8yLCBwYXJhbV8zKTsKCWZsb2F0IHBhcmFtXzQgPSBuICsgc2luKDMuMTQxNTkyNzQgKiAodCArIDAuMzUpKTsKCWZsb2F0IHBhcmFtXzUgPSAwLjE7CglmbG9hdCBwYXJhbV82ID0gMC4xNTsKCXMgKz0gRkxUX2ZsdXR0ZXJfbG9jYWxfdGhyZXNob2xkX1MxX2MwKHBhcmFtXzQsIHBhcmFtXzUsIHBhcmFtXzYpOwoJZmxvYXQgcGFyYW1fNyA9IG4gKyBzaW4oMy4xNDE1OTI3NCAqICh0ICsgMC43KSk7CglmbG9hdCBwYXJhbV84ID0gMC4yOwoJZmxvYXQgcGFyYW1fOSA9IDAuMjU7CglzICs9IEZMVF9mbHV0dGVyX2xvY2FsX3RocmVzaG9sZF9TMV9jMChwYXJhbV83LCBwYXJhbV84LCBwYXJhbV85KTsKCWZsb2F0IHBhcmFtXzEwID0gbiArIHNpbigzLjE0MTU5Mjc0ICogKHQgKyAxLjA1KSk7CglmbG9hdCBwYXJhbV8xMSA9IDAuMzsKCWZsb2F0IHBhcmFtXzEyID0gMC4zNTsKCXMgKz0gRkxUX2ZsdXR0ZXJfbG9jYWxfdGhyZXNob2xkX1MxX2MwKHBhcmFtXzEwLCBwYXJhbV8xMSwgcGFyYW1fMTIpOwoJcmV0dXJuIGNsYW1wKHMsIDAuMCwgMS4wKSAqIDAuNTU7Cn0Kdm9pZCBGTFRfbWFpbl9TMV9jMCgpIAp7Cgl1X2FscGhhX1MxX2MwID0gdV9jb21wb3NpdGVfMV9TMV9jMC54OwoJdV9zcGFya2xlX2FscGhhX1MxX2MwID0gdV9jb21wb3NpdGVfMV9TMV9jMC55OwoJdV9ibHVyX1MxX2MwID0gdV9jb21wb3NpdGVfMV9TMV9jMC56OwoJdV9yYWRpdXNfc2NhbGVfUzFfYzAgPSB1X2NvbXBvc2l0ZV8xX1MxX2MwLnc7CglmbG9hdDIgcCA9IEZMVF9mbHV0dGVyX2xvY2FsX0ZsdXR0ZXJGcmFnQ29vcmRfUzFfYzAoKTsKCWZsb2F0MiB1dl8xID0gcCAqIHVfcmVzb2x1dGlvbl9zY2FsZV9TMV9jMDsKCWZsb2F0MiBkZW5zaXR5X3V2ID0gdXZfMSAtIG1vZChwLCB1X25vaXNlX3NjYWxlX1MxX2MwKTsKCWZsb2F0IHJhZGl1cyA9IHVfbWF4X3JhZGl1c19TMV9jMCAqIHVfcmFkaXVzX3NjYWxlX1MxX2MwOwoJZmxvYXQyIHBhcmFtXzEzID0gdXZfMTsKCWZsb2F0IHR1cmJ1bGVuY2UgPSBGTFRfZmx1dHRlcl9sb2NhbF90dXJidWxlbmNlX1MxX2MwKHBhcmFtXzEzKTsKCWZsb2F0MiBwYXJhbV8xNCA9IHA7CglmbG9hdDIgcGFyYW1fMTUgPSB1X2NlbnRlcl9TMV9jMDsKCWZsb2F0IHBhcmFtXzE2ID0gcmFkaXVzOwoJZmxvYXQgcGFyYW1fMTcgPSAwLjA1ICogdV9tYXhfcmFkaXVzX1MxX2MwOwoJZmxvYXQgcGFyYW1fMTggPSB1X2JsdXJfUzFfYzA7CglmbG9hdCByaW5nID0gRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9yaW5nX1MxX2MwKHBhcmFtXzE0LCBwYXJhbV8xNSwgcGFyYW1fMTYsIHBhcmFtXzE3LCBwYXJhbV8xOCk7CglmbG9hdDIgcGFyYW1fMTkgPSBkZW5zaXR5X3V2OwoJZmxvYXQgcGFyYW1fMjAgPSB1X25vaXNlX3BoYXNlX1MxX2MwOwoJZmxvYXQgc3BhcmtsZSA9ICgoRkxUX2ZsdXR0ZXJfbG9jYWxfc3BhcmtsZV9TMV9jMChwYXJhbV8xOSwgcGFyYW1fMjApICogcmluZykgKiB0dXJidWxlbmNlKSAqIHVfc3BhcmtsZV9hbHBoYV9TMV9jMDsKCWZsb2F0MiBwYXJhbV8yMSA9IHA7CglmbG9hdDIgcGFyYW1fMjIgPSB1X2NlbnRlcl9TMV9jMDsKCWZsb2F0IHBhcmFtXzIzID0gcmFkaXVzOwoJZmxvYXQgcGFyYW1fMjQgPSB1X2JsdXJfUzFfYzA7CglmbG9hdCB3YXZlX2FscGhhID0gKEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfY2lyY2xlX1MxX2MwKHBhcmFtXzIxLCBwYXJhbV8yMiwgcGFyYW1fMjMsIHBhcmFtXzI0KSAqIHVfYWxwaGFfUzFfYzApICogdV9jb2xvcl9TMV9jMC53OwoJZmxvYXQ0IHdhdmVfY29sb3IgPSBmbG9hdDQodV9jb2xvcl9TMV9jMC54eXogKiB3YXZlX2FscGhhLCB3YXZlX2FscGhhKTsKCWZyYWdDb2xvcl9TMV9jMCA9IG1peCh3YXZlX2NvbG9yLCBmbG9hdDQoMS4wKSwgZmxvYXQ0KHNwYXJrbGUpKTsKfQpoYWxmNCBydW50aW1lX3NoYWRlcl9TMV9jMChoYWxmNCBfaW5wdXQpIAp7CgloYWxmNCBfdG1wXzBfaW5Db2xvciA9IF9pbnB1dDsKCWZsb2F0MiBfdG1wXzFfY29vcmRzID0gdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzA7CglmbHV0dGVyX0ZyYWdDb29yZF9TMV9jMCA9IGZsb2F0NChfdG1wXzFfY29vcmRzLCAwLjAsIDAuMCk7CglGTFRfbWFpbl9TMV9jMCgpOwoJcmV0dXJuIGhhbGY0KGhhbGY0KGZyYWdDb2xvcl9TMV9jMCkpOwp9CmhhbGY0IE1hdHJpeEVmZmVjdF9TMShoYWxmNCBfaW5wdXQpIAp7CglyZXR1cm4gcnVudGltZV9zaGFkZXJfUzFfYzAoX2lucHV0KTsKfQpoYWxmNCBDaXJjdWxhclJSZWN0X1MyKGhhbGY0IF9pbnB1dCkgCnsKCWZsb2F0IGR5MCA9IHVpbm5lclJlY3RfUzIuVCAtIHNrX0ZyYWdDb29yZC55OwoJZmxvYXQyIGR4eTEgPSBza19GcmFnQ29vcmQueHkgLSB1aW5uZXJSZWN0X1MyLlJCOwoJZmxvYXQyIGR4eSA9IG1heChmbG9hdDIoZHh5MS54LCBtYXgoZHkwLCBkeHkxLnkpKSwgMC4wKTsKCWhhbGYgbGVmdEFscGhhID0gaGFsZihzYXR1cmF0ZShza19GcmFnQ29vcmQueCAtIHVpbm5lclJlY3RfUzIuTCkpOwoJaGFsZiBhbHBoYSA9IGxlZnRBbHBoYSAqIGhhbGYoc2F0dXJhdGUodXJhZGl1c1BsdXNIYWxmX1MyLnggLSBsZW5ndGgoZHh5KSkpOwoJcmV0dXJuIF9pbnB1dCAqIGFscGhhOwp9CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2Y29sb3JfUzA7CglmbG9hdCBjb3ZlcmFnZSA9IHZjb3ZlcmFnZV9TMDsKCWhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoaGFsZihjb3ZlcmFnZSkpOwoJaGFsZjQgb3V0cHV0X1MxOwoJb3V0cHV0X1MxID0gTWF0cml4RWZmZWN0X1MxKG91dHB1dENvbG9yX1MwKTsKCWhhbGY0IG91dHB1dF9TMjsKCW91dHB1dF9TMiA9IENpcmN1bGFyUlJlY3RfUzIob3V0cHV0Q292ZXJhZ2VfUzApOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dF9TMSAqIG91dHB1dF9TMjsKCX0KfQoAAAEAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAEAAAACAAAAHBvc2l0aW9uCAAAAGNvdmVyYWdlBQAAAGNvbG9yAAAACgAAAGxvY2FsQ29vcmQAAAAAAAA=","DASAAAAAAAAAAAEAAFQAAIGAAEAOB77776PUEAIBAAAAAABAAAAAAABAMQAAAOQAAAAAAAQAAAABAMQAAAAA":"DAAAAExTS1PVAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQyIHVBdGxhc1NpemVJbnZfUzA7CmluIGZsb2F0MiBpblBvc2l0aW9uOwppbiB1c2hvcnQyIGluVGV4dHVyZUNvb3JkczsKb3V0IGZsb2F0MiB2VGV4dHVyZUNvb3Jkc19TMDsKZmxhdCBvdXQgZmxvYXQgdlRleEluZGV4X1MwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBCaXRtYXBUZXh0CglpbnQgdGV4SWR4ID0gMDsKCWZsb2F0MiB1bm9ybVRleENvb3JkcyA9IGZsb2F0MihpblRleHR1cmVDb29yZHMueCwgaW5UZXh0dXJlQ29vcmRzLnkpOwoJdlRleHR1cmVDb29yZHNfUzAgPSB1bm9ybVRleENvb3JkcyAqIHVBdGxhc1NpemVJbnZfUzA7Cgl2VGV4SW5kZXhfUzAgPSBmbG9hdCh0ZXhJZHgpOwoJZmxvYXQyIF90bXBfMV9pblBvc2l0aW9uID0gaW5Qb3NpdGlvbjsKCXNrX1Bvc2l0aW9uID0gaW5Qb3NpdGlvbi54eTAxOwp9CgAAAAAAAADYAQAAdW5pZm9ybSBoYWxmNCB1Q29sb3JfUzA7CnNhbXBsZXIyRCB1VGV4dHVyZVNhbXBsZXJfMF9TMDsKaW4gZmxvYXQyIHZUZXh0dXJlQ29vcmRzX1MwOwpmbGF0IGluIGZsb2F0IHZUZXhJbmRleF9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIEJpdG1hcFRleHQKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB1Q29sb3JfUzA7CgloYWxmNCB0ZXhDb2xvcjsKCXsKCQl0ZXhDb2xvciA9IHNhbXBsZSh1VGV4dHVyZVNhbXBsZXJfMF9TMCwgdlRleHR1cmVDb29yZHNfUzApOwoJfQoJb3V0cHV0Q29sb3JfUzAgPSBvdXRwdXRDb2xvcl9TMCAqIHRleENvbG9yOwoJY29uc3QgaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNCgxKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dENvdmVyYWdlX1MwOwoJfQp9CgAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAACAAAACgAAAGluUG9zaXRpb24AAA8AAABpblRleHR1cmVDb29yZHMAAAAAAA==","AYAA5AADQAAAOAEARAFQJAABBADIB7777777777777777777777767YAAAAAAAAAAAAOQAAAAAAAQAAAABAMQAAAAA":"DAAAAExTS1OCAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0MiBpblBvc2l0aW9uOwppbiBoYWxmNCBpbkNvbG9yOwppbiBmbG9hdDQgaW5DaXJjbGVFZGdlOwpvdXQgZmxvYXQ0IHZpbkNpcmNsZUVkZ2VfUzA7Cm91dCBoYWxmNCB2aW5Db2xvcl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgQ2lyY2xlR2VvbWV0cnlQcm9jZXNzb3IKCXZpbkNpcmNsZUVkZ2VfUzAgPSBpbkNpcmNsZUVkZ2U7Cgl2aW5Db2xvcl9TMCA9IGluQ29sb3I7CglmbG9hdDIgX3RtcF8wX2luUG9zaXRpb24gPSBpblBvc2l0aW9uOwoJZmxvYXQyIF90bXBfMl9pblBvc2l0aW9uID0gaW5Qb3NpdGlvbjsKCXNrX1Bvc2l0aW9uID0gX3RtcF8wX2luUG9zaXRpb24ueHkwMTsKfQoAAAAAAADqAQAAaW4gZmxvYXQ0IHZpbkNpcmNsZUVkZ2VfUzA7CmluIGhhbGY0IHZpbkNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgQ2lyY2xlR2VvbWV0cnlQcm9jZXNzb3IKCWZsb2F0NCBjaXJjbGVFZGdlOwoJY2lyY2xlRWRnZSA9IHZpbkNpcmNsZUVkZ2VfUzA7CgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmluQ29sb3JfUzA7CglmbG9hdCBkID0gbGVuZ3RoKGNpcmNsZUVkZ2UueHkpOwoJaGFsZiBkaXN0YW5jZVRvT3V0ZXJFZGdlID0gaGFsZihjaXJjbGVFZGdlLnogKiAoMS4wIC0gZCkpOwoJaGFsZiBlZGdlQWxwaGEgPSBzYXR1cmF0ZShkaXN0YW5jZVRvT3V0ZXJFZGdlKTsKCWhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoZWRnZUFscGhhKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dENvdmVyYWdlX1MwOwoJfQp9CgAAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAKAAAAaW5Qb3NpdGlvbgAABwAAAGluQ29sb3IADAAAAGluQ2lyY2xlRWRnZQAAAAA=","HUQACAAAAAMAADAAAIOAAAH677776IZOCAAP577777777777777777YBAAAAAAAAAAAHEADZAAAAAAIAAAAAAOQAAAAAAAQAAAABAMQAAAAAA":"DAAAAExTS1PPAAAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gaGFsZjQgY29sb3I7Cm91dCBoYWxmNCB2Y29sb3JfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJdmNvbG9yX1MwID0gY29sb3I7Cglza19Qb3NpdGlvbiA9IHBvc2l0aW9uLnh5MDE7Cn0KAAEAAACbAgAAdW5pZm9ybSBmbG9hdDQgdWlubmVyUmVjdF9TMTsKdW5pZm9ybSBoYWxmMiB1cmFkaXVzUGx1c0hhbGZfUzE7CmluIGhhbGY0IHZjb2xvcl9TMDsKaGFsZjQgQ2lyY3VsYXJSUmVjdF9TMShoYWxmNCBfaW5wdXQpIAp7CglmbG9hdDIgZHh5MCA9IHVpbm5lclJlY3RfUzEuTFQgLSBza19GcmFnQ29vcmQueHk7CglmbG9hdDIgZHh5MSA9IHNrX0ZyYWdDb29yZC54eSAtIHVpbm5lclJlY3RfUzEuUkI7CglmbG9hdDIgZHh5ID0gbWF4KG1heChkeHkwLCBkeHkxKSwgMC4wKTsKCWhhbGYgYWxwaGEgPSBoYWxmKHNhdHVyYXRlKHVyYWRpdXNQbHVzSGFsZl9TMS54IC0gbGVuZ3RoKGR4eSkpKTsKCXJldHVybiBfaW5wdXQgKiBhbHBoYTsKfQp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmNvbG9yX1MwOwoJY29uc3QgaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNCgxKTsKCWhhbGY0IG91dHB1dF9TMTsKCW91dHB1dF9TMSA9IENpcmN1bGFyUlJlY3RfUzEob3V0cHV0Q292ZXJhZ2VfUzApOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dENvbG9yX1MwICogb3V0cHV0X1MxOwoJfQp9CgABAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAgAAABwb3NpdGlvbgUAAABjb2xvcgAAAAAAAAA=","DAQAAAAAAAAAAAAAAJQAAIGAAEACBYQCAGAEFAIBAAAAAABAAAAAAAAAAAAAAOQAAAAAAAQAAAABAMQAAAAA":"DAAAAExTS1MWAgAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQyIHVBdGxhc1NpemVJbnZfUzA7CmluIGZsb2F0MiBpblBvc2l0aW9uOwppbiBoYWxmNCBpbkNvbG9yOwppbiB1c2hvcnQyIGluVGV4dHVyZUNvb3JkczsKb3V0IGZsb2F0MiB2VGV4dHVyZUNvb3Jkc19TMDsKZmxhdCBvdXQgZmxvYXQgdlRleEluZGV4X1MwOwpvdXQgaGFsZjQgdmluQ29sb3JfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIEJpdG1hcFRleHQKCWludCB0ZXhJZHggPSAwOwoJZmxvYXQyIHVub3JtVGV4Q29vcmRzID0gZmxvYXQyKGluVGV4dHVyZUNvb3Jkcy54LCBpblRleHR1cmVDb29yZHMueSk7Cgl2VGV4dHVyZUNvb3Jkc19TMCA9IHVub3JtVGV4Q29vcmRzICogdUF0bGFzU2l6ZUludl9TMDsKCXZUZXhJbmRleF9TMCA9IGZsb2F0KHRleElkeCk7Cgl2aW5Db2xvcl9TMCA9IGluQ29sb3I7CglmbG9hdDIgX3RtcF8xX2luUG9zaXRpb24gPSBpblBvc2l0aW9uOwoJc2tfUG9zaXRpb24gPSBpblBvc2l0aW9uLnh5MDE7Cn0KAAAAAAAAqQEAAHNhbXBsZXIyRCB1VGV4dHVyZVNhbXBsZXJfMF9TMDsKaW4gZmxvYXQyIHZUZXh0dXJlQ29vcmRzX1MwOwpmbGF0IGluIGZsb2F0IHZUZXhJbmRleF9TMDsKaW4gaGFsZjQgdmluQ29sb3JfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBCaXRtYXBUZXh0CgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmluQ29sb3JfUzA7CgloYWxmNCB0ZXhDb2xvcjsKCXsKCQl0ZXhDb2xvciA9IHNhbXBsZSh1VGV4dHVyZVNhbXBsZXJfMF9TMCwgdlRleHR1cmVDb29yZHNfUzApLnJycnI7Cgl9CgloYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IHRleENvbG9yOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dENvbG9yX1MwICogb3V0cHV0Q292ZXJhZ2VfUzA7Cgl9Cn0KAAAAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAKAAAAaW5Qb3NpdGlvbgAABwAAAGluQ29sb3IADwAAAGluVGV4dHVyZUNvb3JkcwAAAAAA","FAAQMYAAMAAAEADAAABAEYAAAICIAB5AABQAAAQAMAAAEATAAABAIIGAAEDCBYQCA4AAAAAAAA5AAAAAAABAAAAACAZAAAAA":"DAAAAExTS1PUCwAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0NCByYWRpaV9zZWxlY3RvcjsKaW4gZmxvYXQ0IGNvcm5lcl9hbmRfcmFkaXVzX291dHNldHM7CmluIGZsb2F0NCBhYV9ibG9hdF9hbmRfY292ZXJhZ2U7CmluIGZsb2F0NCByYWRpaV94OwppbiBmbG9hdDQgcmFkaWlfeTsKaW4gZmxvYXQ0IHNrZXc7CmluIGZsb2F0MiB0cmFuc2xhdGVfYW5kX2xvY2Fscm90YXRlOwppbiBoYWxmNCBjb2xvcjsKZmxhdCBvdXQgaGFsZjQgdmNvbG9yX1MwOwpvdXQgZmxvYXQyIHZhcmNjb29yZF9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgRmlsbFJSZWN0T3A6OlByb2Nlc3NvcgoJdmNvbG9yX1MwID0gY29sb3I7CglmbG9hdCBhYV9ibG9hdF9tdWx0aXBsaWVyID0gMTsKCWZsb2F0MiBjb3JuZXIgPSBjb3JuZXJfYW5kX3JhZGl1c19vdXRzZXRzLnh5OwoJZmxvYXQyIHJhZGl1c19vdXRzZXQgPSBjb3JuZXJfYW5kX3JhZGl1c19vdXRzZXRzLnp3OwoJZmxvYXQyIGFhX2Jsb2F0X2RpcmVjdGlvbiA9IGFhX2Jsb2F0X2FuZF9jb3ZlcmFnZS54eTsKCWZsb2F0IGlzX2xpbmVhcl9jb3ZlcmFnZSA9IGFhX2Jsb2F0X2FuZF9jb3ZlcmFnZS53OwoJZmxvYXQyIHBpeGVsbGVuZ3RoID0gaW52ZXJzZXNxcnQoZmxvYXQyKGRvdChza2V3Lnh6LCBza2V3Lnh6KSwgZG90KHNrZXcueXcsIHNrZXcueXcpKSk7CglmbG9hdDQgbm9ybWFsaXplZF9heGlzX2RpcnMgPSBza2V3ICogcGl4ZWxsZW5ndGgueHl4eTsKCWZsb2F0MiBheGlzd2lkdGhzID0gKGFicyhub3JtYWxpemVkX2F4aXNfZGlycy54eSkgKyBhYnMobm9ybWFsaXplZF9heGlzX2RpcnMuencpKTsKCWZsb2F0MiBhYV9ibG9hdHJhZGl1cyA9IGF4aXN3aWR0aHMgKiBwaXhlbGxlbmd0aCAqIC41OwoJZmxvYXQ0IHJhZGlpX2FuZF9uZWlnaGJvcnMgPSByYWRpaV9zZWxlY3RvciogZmxvYXQ0eDQocmFkaWlfeCwgcmFkaWlfeSwgcmFkaWlfeC55eHd6LCByYWRpaV95Lnd6eXgpOwoJZmxvYXQyIHJhZGlpID0gcmFkaWlfYW5kX25laWdoYm9ycy54eTsKCWZsb2F0MiBuZWlnaGJvcl9yYWRpaSA9IHJhZGlpX2FuZF9uZWlnaGJvcnMuenc7CglmbG9hdCBjb3ZlcmFnZV9tdWx0aXBsaWVyID0gMTsKCWlmIChhbnkoZ3JlYXRlclRoYW4oYWFfYmxvYXRyYWRpdXMsIGZsb2F0MigxKSkpKSAKCXsKCQljb3JuZXIgPSBtYXgoYWJzKGNvcm5lciksIGFhX2Jsb2F0cmFkaXVzKSAqIHNpZ24oY29ybmVyKTsKCQljb3ZlcmFnZV9tdWx0aXBsaWVyID0gMSAvIChtYXgoYWFfYmxvYXRyYWRpdXMueCwgMSkgKiBtYXgoYWFfYmxvYXRyYWRpdXMueSwgMSkpOwoJCXJhZGlpID0gZmxvYXQyKDApOwoJfQoJZmxvYXQgY292ZXJhZ2UgPSBhYV9ibG9hdF9hbmRfY292ZXJhZ2UuejsKCWlmIChhbnkobGVzc1RoYW4ocmFkaWksIGFhX2Jsb2F0cmFkaXVzICogMS41KSkpIAoJewoJCXJhZGlpID0gZmxvYXQyKDApOwoJCWFhX2Jsb2F0X2RpcmVjdGlvbiA9IHNpZ24oY29ybmVyKTsKCQlpZiAoY292ZXJhZ2UgPiAuNSkgCgkJewoJCQlhYV9ibG9hdF9kaXJlY3Rpb24gPSAtYWFfYmxvYXRfZGlyZWN0aW9uOwoJCX0KCQlpc19saW5lYXJfY292ZXJhZ2UgPSAxOwoJfQoJZWxzZSAKCXsKCQlyYWRpaSA9IGNsYW1wKHJhZGlpLCBwaXhlbGxlbmd0aCAqIDEuNSwgMiAtIHBpeGVsbGVuZ3RoICogMS41KTsKCQluZWlnaGJvcl9yYWRpaSA9IGNsYW1wKG5laWdoYm9yX3JhZGlpLCBwaXhlbGxlbmd0aCAqIDEuNSwgMiAtIHBpeGVsbGVuZ3RoICogMS41KTsKCQlmbG9hdDIgc3BhY2luZyA9IDIgLSByYWRpaSAtIG5laWdoYm9yX3JhZGlpOwoJCWZsb2F0MiBleHRyYV9wYWQgPSBtYXgocGl4ZWxsZW5ndGggKiAuMDYyNSAtIHNwYWNpbmcsIGZsb2F0MigwKSk7CgkJcmFkaWkgLT0gZXh0cmFfcGFkICogLjU7Cgl9CglmbG9hdDIgYWFfb3V0c2V0ID0gYWFfYmxvYXRfZGlyZWN0aW9uICogYWFfYmxvYXRyYWRpdXMgKiBhYV9ibG9hdF9tdWx0aXBsaWVyOwoJZmxvYXQyIHZlcnRleHBvcyA9IGNvcm5lciArIHJhZGl1c19vdXRzZXQgKiByYWRpaSArIGFhX291dHNldDsKCWlmIChjb3ZlcmFnZSA+IC41KSAKCXsKCQlpZiAoYWFfYmxvYXRfZGlyZWN0aW9uLnggIT0gMCAmJiB2ZXJ0ZXhwb3MueCAqIGNvcm5lci54IDwgMCkgCgkJewoJCQlmbG9hdCBiYWNrc2V0ID0gYWJzKHZlcnRleHBvcy54KTsKCQkJdmVydGV4cG9zLnggPSAwOwoJCQl2ZXJ0ZXhwb3MueSArPSBiYWNrc2V0ICogc2lnbihjb3JuZXIueSkgKiBwaXhlbGxlbmd0aC55L3BpeGVsbGVuZ3RoLng7CgkJCWNvdmVyYWdlID0gKGNvdmVyYWdlIC0gLjUpICogYWJzKGNvcm5lci54KSAvIChhYnMoY29ybmVyLngpICsgYmFja3NldCkgKyAuNTsKCQl9CgkJaWYgKGFhX2Jsb2F0X2RpcmVjdGlvbi55ICE9IDAgJiYgdmVydGV4cG9zLnkgKiBjb3JuZXIueSA8IDApIAoJCXsKCQkJZmxvYXQgYmFja3NldCA9IGFicyh2ZXJ0ZXhwb3MueSk7CgkJCXZlcnRleHBvcy55ID0gMDsKCQkJdmVydGV4cG9zLnggKz0gYmFja3NldCAqIHNpZ24oY29ybmVyLngpICogcGl4ZWxsZW5ndGgueC9waXhlbGxlbmd0aC55OwoJCQljb3ZlcmFnZSA9IChjb3ZlcmFnZSAtIC41KSAqIGFicyhjb3JuZXIueSkgLyAoYWJzKGNvcm5lci55KSArIGJhY2tzZXQpICsgLjU7CgkJfQoJfQoJZmxvYXQyeDIgc2tld21hdHJpeCA9IGZsb2F0MngyKHNrZXcueHksIHNrZXcuencpOwoJZmxvYXQyIGRldmNvb3JkID0gdmVydGV4cG9zICogc2tld21hdHJpeCArIHRyYW5zbGF0ZV9hbmRfbG9jYWxyb3RhdGUueHk7CglpZiAoMCAhPSBpc19saW5lYXJfY292ZXJhZ2UpIAoJewoJCXZhcmNjb29yZF9TMC54eSA9IGZsb2F0MigwLCBjb3ZlcmFnZSAqIGNvdmVyYWdlX211bHRpcGxpZXIpOwoJfQoJZWxzZSAKCXsKCQlmbG9hdDIgYXJjY29vcmQgPSAxIC0gYWJzKHJhZGl1c19vdXRzZXQpICsgYWFfb3V0c2V0L3JhZGlpICogY29ybmVyOwoJCXZhcmNjb29yZF9TMC54eSA9IGZsb2F0MihhcmNjb29yZC54KzEsIGFyY2Nvb3JkLnkpOwoJfQoJc2tfUG9zaXRpb24gPSBkZXZjb29yZC54eTAxOwp9CgAAAABFAgAAZmxhdCBpbiBoYWxmNCB2Y29sb3JfUzA7CmluIGZsb2F0MiB2YXJjY29vcmRfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBGaWxsUlJlY3RPcDo6UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmNvbG9yX1MwOwoJZmxvYXQgeF9wbHVzXzE9dmFyY2Nvb3JkX1MwLngsIHk9dmFyY2Nvb3JkX1MwLnk7CgloYWxmIGNvdmVyYWdlOwoJaWYgKDAgPT0geF9wbHVzXzEpIAoJewoJCWNvdmVyYWdlID0gaGFsZih5KTsKCX0KCWVsc2UgCgl7CgkJZmxvYXQgZm4gPSB4X3BsdXNfMSAqICh4X3BsdXNfMSAtIDIpOwoJCWZuID0gZm1hKHkseSwgZm4pOwoJCWZsb2F0IGZud2lkdGggPSBmd2lkdGgoZm4pOwoJCWNvdmVyYWdlID0gLjUgLSBoYWxmKGZuL2Zud2lkdGgpOwoJCWNvdmVyYWdlID0gY2xhbXAoY292ZXJhZ2UsIDAsIDEpOwoJfQoJaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNChjb3ZlcmFnZSk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRDb3ZlcmFnZV9TMDsKCX0KfQoAAAAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAACAAAAA4AAAByYWRpaV9zZWxlY3RvcgAAGQAAAGNvcm5lcl9hbmRfcmFkaXVzX291dHNldHMAAAAVAAAAYWFfYmxvYXRfYW5kX2NvdmVyYWdlAAAABwAAAHJhZGlpX3gABwAAAHJhZGlpX3kABAAAAHNrZXcZAAAAdHJhbnNsYXRlX2FuZF9sb2NhbHJvdGF0ZQAAAAUAAABjb2xvcgAAAAAAAAA=","HVIAAAAAABIAAGAAAQ4AAAH477776R24EAAAIOBQAD6P7777777777YDAAAAAAAAAAAFIBVWKMG7QAAAAAAGVXOVKVEAAAAADAAAAAFQ454NUDACAAAIAQZUOAMQAAAAIAAAAAEARTKLVK5LSAAAAABQAAAAAYGP6G2BSBAAAAAIO2HAGIAAAAAAAEAAAAAZ3RZTY3IGAEAAAAAAAAAGARI4UKA4WAAAAAAAEAAAABSMQII2XAGAAAAAAAAAAACAA4AAAACAAAAAAACCAYAA":"DAAAAExTS1OAAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMV9jMF9jMTsKaW4gZmxvYXQyIHBvc2l0aW9uOwppbiBoYWxmNCBjb2xvcjsKaW4gZmxvYXQyIGxvY2FsQ29vcmQ7CmZsYXQgb3V0IGhhbGY0IHZjb2xvcl9TMDsKb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfNV9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgl2Y29sb3JfUzAgPSBjb2xvcjsKCXNrX1Bvc2l0aW9uID0gcG9zaXRpb24ueHkwMTsKCXsKCQl2VHJhbnNmb3JtZWRDb29yZHNfNV9TMCA9IGZsb2F0M3gyKHVtYXRyaXhfUzFfYzBfYzEpICogbG9jYWxDb29yZC54eTE7Cgl9Cn0KAAAAAIIGAAB1bmlmb3JtIGhhbGY0IHVzdGFydF9TMV9jMF9jMDsKdW5pZm9ybSBoYWxmNCB1ZW5kX1MxX2MwX2MwOwp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzFfYzBfYzE7CnVuaWZvcm0gaGFsZjQgdWxlZnRCb3JkZXJDb2xvcl9TMV9jMDsKdW5pZm9ybSBoYWxmNCB1cmlnaHRCb3JkZXJDb2xvcl9TMV9jMDsKZmxhdCBpbiBoYWxmNCB2Y29sb3JfUzA7CmluIGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfNV9TMDsKaGFsZjQgU2luZ2xlSW50ZXJ2YWxDb2xvcml6ZXJfUzFfYzBfYzAoaGFsZjQgX2lucHV0LCBmbG9hdDIgX2Nvb3JkcykgCnsKCWhhbGY0IF90bXBfMF9pbkNvbG9yID0gX2lucHV0OwoJZmxvYXQyIF90bXBfMV9jb29yZHMgPSBfY29vcmRzOwoJcmV0dXJuIGhhbGY0KG1peCh1c3RhcnRfUzFfYzBfYzAsIHVlbmRfUzFfYzBfYzAsIGhhbGYoX3RtcF8xX2Nvb3Jkcy54KSkpOwp9CmhhbGY0IExpbmVhckxheW91dF9TMV9jMF9jMV9jMChoYWxmNCBfaW5wdXQpIAp7CgloYWxmNCBfdG1wXzJfaW5Db2xvciA9IF9pbnB1dDsKCWZsb2F0MiBfdG1wXzNfY29vcmRzID0gdlRyYW5zZm9ybWVkQ29vcmRzXzVfUzA7CglyZXR1cm4gaGFsZjQoaGFsZjQoaGFsZihfdG1wXzNfY29vcmRzLngpICsgMWUtMDUsIDEuMCwgMC4wLCAwLjApKTsKfQpoYWxmNCBNYXRyaXhFZmZlY3RfUzFfYzBfYzEoaGFsZjQgX2lucHV0KSAKewoJcmV0dXJuIExpbmVhckxheW91dF9TMV9jMF9jMV9jMChfaW5wdXQpOwp9CmhhbGY0IENsYW1wZWRHcmFkaWVudF9TMV9jMChoYWxmNCBfaW5wdXQpIAp7CgloYWxmNCBfdG1wXzRfaW5Db2xvciA9IF9pbnB1dDsKCWhhbGY0IHQgPSBNYXRyaXhFZmZlY3RfUzFfYzBfYzEoX3RtcF80X2luQ29sb3IpOwoJaGFsZjQgb3V0Q29sb3I7CglpZiAoIWJvb2woaW50KDEpKSAmJiB0LnkgPCAwLjApIAoJewoJCW91dENvbG9yID0gaGFsZjQoMC4wKTsKCX0KCWVsc2UgaWYgKHQueCA8IDAuMCkgCgl7CgkJb3V0Q29sb3IgPSB1bGVmdEJvcmRlckNvbG9yX1MxX2MwOwoJfQoJZWxzZSBpZiAodC54ID4gMS4wKSAKCXsKCQlvdXRDb2xvciA9IHVyaWdodEJvcmRlckNvbG9yX1MxX2MwOwoJfQoJZWxzZSAKCXsKCQlvdXRDb2xvciA9IFNpbmdsZUludGVydmFsQ29sb3JpemVyX1MxX2MwX2MwKF90bXBfNF9pbkNvbG9yLCBmbG9hdDIoaGFsZjIodC54LCAwLjApKSk7Cgl9CglyZXR1cm4gaGFsZjQob3V0Q29sb3IpOwp9CmhhbGY0IERpc2FibGVDb3ZlcmFnZUFzQWxwaGFfUzEoaGFsZjQgX2lucHV0KSAKewoJX2lucHV0ID0gQ2xhbXBlZEdyYWRpZW50X1MxX2MwKF9pbnB1dCk7CgloYWxmNCBfdG1wXzVfaW5Db2xvciA9IF9pbnB1dDsKCXJldHVybiBoYWxmNChfaW5wdXQpOwp9CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2Y29sb3JfUzA7Cgljb25zdCBoYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KDEpOwoJaGFsZjQgb3V0cHV0X1MxOwoJb3V0cHV0X1MxID0gRGlzYWJsZUNvdmVyYWdlQXNBbHBoYV9TMShvdXRwdXRDb2xvcl9TMCk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0X1MxICogb3V0cHV0Q292ZXJhZ2VfUzA7Cgl9Cn0KAAAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAgAAABwb3NpdGlvbgUAAABjb2xvcgAAAAoAAABsb2NhbENvb3JkAAAAAAAA","HVIAAAAAABIAAGAAAQ4AAAH477776R24EAAAIOBQAD6P7777777777YDAAAAAAAAAAAHIBNGZODK5YIAAAAAAQAAAAAIADCNS4GV3QYBAAAAAAAAAAAAAHIAAAAAAAIAAAAAQGIAAAAAA":"DAAAAExTS1N0AQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMTsKaW4gZmxvYXQyIHBvc2l0aW9uOwppbiBoYWxmNCBjb2xvcjsKaW4gZmxvYXQyIGxvY2FsQ29vcmQ7CmZsYXQgb3V0IGhhbGY0IHZjb2xvcl9TMDsKb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgl2Y29sb3JfUzAgPSBjb2xvcjsKCXNrX1Bvc2l0aW9uID0gcG9zaXRpb24ueHkwMTsKCXsKCQl2VHJhbnNmb3JtZWRDb29yZHNfMl9TMCA9IGZsb2F0M3gyKHVtYXRyaXhfUzEpICogbG9jYWxDb29yZC54eTE7Cgl9Cn0KAAAAAIwbAABmbG9hdDQgZmx1dHRlcl9GcmFnQ29vcmRfUzFfYzA7CmZsb2F0NCBmcmFnQ29sb3JfUzFfYzA7CmZsb2F0IHVfYWxwaGFfUzFfYzA7CmZsb2F0IHVfc3BhcmtsZV9hbHBoYV9TMV9jMDsKZmxvYXQgdV9ibHVyX1MxX2MwOwpmbG9hdCB1X3JhZGl1c19zY2FsZV9TMV9jMDsKdW5pZm9ybSBmbG9hdDQgdV9jb2xvcl9TMV9jMDsKdW5pZm9ybSBmbG9hdDQgdV9jb21wb3NpdGVfMV9TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9jZW50ZXJfUzFfYzA7CnVuaWZvcm0gZmxvYXQgdV9tYXhfcmFkaXVzX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X3Jlc29sdXRpb25fc2NhbGVfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfbm9pc2Vfc2NhbGVfUzFfYzA7CnVuaWZvcm0gZmxvYXQgdV9ub2lzZV9waGFzZV9TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9jaXJjbGUxX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X2NpcmNsZTJfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfY2lyY2xlM19TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9yb3RhdGlvbjFfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfcm90YXRpb24yX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X3JvdGF0aW9uM19TMV9jMDsKdW5pZm9ybSBmbG9hdDN4MyB1bWF0cml4X1MxOwpmbGF0IGluIGhhbGY0IHZjb2xvcl9TMDsKaW4gZmxvYXQyIHZUcmFuc2Zvcm1lZENvb3Jkc18yX1MwOwpmbG9hdDIgRkxUX2ZsdXR0ZXJfbG9jYWxfRmx1dHRlckZyYWdDb29yZF9TMV9jMCgpOwpmbG9hdDJ4MiBGTFRfZmx1dHRlcl9sb2NhbF9yb3RhdGUyZF9TMV9jMChmbG9hdDIgcmFkKTsKZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9jaXJjbGVfUzFfYzAoZmxvYXQyIHV2LCBmbG9hdDIgeHksIGZsb2F0IHJhZGl1cywgZmxvYXQgYmx1cik7CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX2NpcmNsZV9ncmlkX1MxX2MwKGZsb2F0MiByZXNvbHV0aW9uLCBpbm91dCBmbG9hdDIgcCwgZmxvYXQyIHh5LCBmbG9hdDIgcm90YXRpb24sIGZsb2F0IGNlbGxfZGlhbWV0ZXIpOwpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF90dXJidWxlbmNlX1MxX2MwKGZsb2F0MiB1dik7CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfcmluZ19TMV9jMChmbG9hdDIgdXYsIGZsb2F0MiB4eSwgZmxvYXQgcmFkaXVzLCBmbG9hdCB0aGlja25lc3MsIGZsb2F0IGJsdXIpOwpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF90cmlhbmdsZV9ub2lzZV9TMV9jMChpbm91dCBmbG9hdDIgbik7CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3RocmVzaG9sZF9TMV9jMChmbG9hdCB2LCBmbG9hdCBsLCBmbG9hdCBoKTsKZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfc3BhcmtsZV9TMV9jMChmbG9hdDIgdXYsIGZsb2F0IHQpOwp2b2lkIEZMVF9tYWluX1MxX2MwKCk7CmZsb2F0MiBGTFRfZmx1dHRlcl9sb2NhbF9GbHV0dGVyRnJhZ0Nvb3JkX1MxX2MwKCkgCnsKCXJldHVybiBmbHV0dGVyX0ZyYWdDb29yZF9TMV9jMC54eTsKfQpmbG9hdDJ4MiBGTFRfZmx1dHRlcl9sb2NhbF9yb3RhdGUyZF9TMV9jMChmbG9hdDIgcmFkKSAKewoJcmV0dXJuIGZsb2F0MngyKHJhZC54LCAtcmFkLnksIHJhZC55LCByYWQueCk7Cn0KZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9jaXJjbGVfUzFfYzAoZmxvYXQyIHV2LCBmbG9hdDIgeHksIGZsb2F0IHJhZGl1cywgZmxvYXQgYmx1cikgCnsKCWZsb2F0IGJsdXJfaGFsZiA9IGJsdXIgKiAwLjU7CglmbG9hdCBkID0gZGlzdGFuY2UodXYsIHh5KTsKCXJldHVybiAxLjAgLSBzbW9vdGhzdGVwKDEuMCAtIGJsdXJfaGFsZiwgMS4wICsgYmx1cl9oYWxmLCBkIC8gcmFkaXVzKTsKfQpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9jaXJjbGVfZ3JpZF9TMV9jMChmbG9hdDIgcmVzb2x1dGlvbiwgaW5vdXQgZmxvYXQyIHAsIGZsb2F0MiB4eSwgZmxvYXQyIHJvdGF0aW9uLCBmbG9hdCBjZWxsX2RpYW1ldGVyKSAKewoJZmxvYXQyIHBhcmFtID0gcm90YXRpb247CglwID0gRkxUX2ZsdXR0ZXJfbG9jYWxfcm90YXRlMmRfUzFfYzAocGFyYW0pICogKHh5IC0gcCkgKyB4eTsKCXAgPSBtb2QocCwgZmxvYXQyKGNlbGxfZGlhbWV0ZXIpKSAvIHJlc29sdXRpb247CglmbG9hdCBjZWxsX3V2ID0gKGNlbGxfZGlhbWV0ZXIgLyByZXNvbHV0aW9uLnkpICogMC41OwoJZmxvYXQgciA9IDAuNjUgKiBjZWxsX3V2OwoJZmxvYXQyIHBhcmFtXzEgPSBwOwoJZmxvYXQyIHBhcmFtXzIgPSBmbG9hdDIoY2VsbF91dik7CglmbG9hdCBwYXJhbV8zID0gcjsKCWZsb2F0IHBhcmFtXzQgPSByICogNTAuMDsKCXJldHVybiBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X2NpcmNsZV9TMV9jMChwYXJhbV8xLCBwYXJhbV8yLCBwYXJhbV8zLCBwYXJhbV80KTsKfQpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF90dXJidWxlbmNlX1MxX2MwKGZsb2F0MiB1dikgCnsKCWZsb2F0MiB1dl9zY2FsZSA9IHV2ICogZmxvYXQyKDAuOCk7CglmbG9hdDIgcGFyYW0gPSBmbG9hdDIoMC44KTsKCWZsb2F0MiBwYXJhbV8xID0gdXZfc2NhbGU7CglmbG9hdDIgcGFyYW1fMiA9IHVfY2lyY2xlMV9TMV9jMDsKCWZsb2F0MiBwYXJhbV8zID0gdV9yb3RhdGlvbjFfUzFfYzA7CglmbG9hdCBwYXJhbV80ID0gMC4xNzsKCWZsb2F0IF8zMTkgPSBGTFRfZmx1dHRlcl9sb2NhbF9jaXJjbGVfZ3JpZF9TMV9jMChwYXJhbSwgcGFyYW1fMSwgcGFyYW1fMiwgcGFyYW1fMywgcGFyYW1fNCk7CglmbG9hdCBnMSA9IF8zMTk7CglmbG9hdDIgcGFyYW1fNSA9IGZsb2F0MigwLjgpOwoJZmxvYXQyIHBhcmFtXzYgPSB1dl9zY2FsZTsKCWZsb2F0MiBwYXJhbV83ID0gdV9jaXJjbGUyX1MxX2MwOwoJZmxvYXQyIHBhcmFtXzggPSB1X3JvdGF0aW9uMl9TMV9jMDsKCWZsb2F0IHBhcmFtXzkgPSAwLjI7CglmbG9hdCBfMzMxID0gRkxUX2ZsdXR0ZXJfbG9jYWxfY2lyY2xlX2dyaWRfUzFfYzAocGFyYW1fNSwgcGFyYW1fNiwgcGFyYW1fNywgcGFyYW1fOCwgcGFyYW1fOSk7CglmbG9hdCBnMiA9IF8zMzE7CglmbG9hdDIgcGFyYW1fMTAgPSBmbG9hdDIoMC44KTsKCWZsb2F0MiBwYXJhbV8xMSA9IHV2X3NjYWxlOwoJZmxvYXQyIHBhcmFtXzEyID0gdV9jaXJjbGUzX1MxX2MwOwoJZmxvYXQyIHBhcmFtXzEzID0gdV9yb3RhdGlvbjNfUzFfYzA7CglmbG9hdCBwYXJhbV8xNCA9IDAuMjc1OwoJZmxvYXQgXzM0NCA9IEZMVF9mbHV0dGVyX2xvY2FsX2NpcmNsZV9ncmlkX1MxX2MwKHBhcmFtXzEwLCBwYXJhbV8xMSwgcGFyYW1fMTIsIHBhcmFtXzEzLCBwYXJhbV8xNCk7CglmbG9hdCBnMyA9IF8zNDQ7CglmbG9hdCB2ID0gKChnMSAqIGcxICsgZzIpIC0gZzMpICogMC41OwoJcmV0dXJuIGNsYW1wKDAuNDUgKyAwLjggKiB2LCAwLjAsIDEuMCk7Cn0KZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9yaW5nX1MxX2MwKGZsb2F0MiB1diwgZmxvYXQyIHh5LCBmbG9hdCByYWRpdXMsIGZsb2F0IHRoaWNrbmVzcywgZmxvYXQgYmx1cikgCnsKCWZsb2F0MiBwYXJhbSA9IHV2OwoJZmxvYXQyIHBhcmFtXzEgPSB4eTsKCWZsb2F0IHBhcmFtXzIgPSByYWRpdXMgKyB0aGlja25lc3M7CglmbG9hdCBwYXJhbV8zID0gYmx1cjsKCWZsb2F0IGNpcmNsZV9vdXRlciA9IEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfY2lyY2xlX1MxX2MwKHBhcmFtLCBwYXJhbV8xLCBwYXJhbV8yLCBwYXJhbV8zKTsKCWZsb2F0MiBwYXJhbV80ID0gdXY7CglmbG9hdDIgcGFyYW1fNSA9IHh5OwoJZmxvYXQgcGFyYW1fNiA9IG1heChyYWRpdXMgLSB0aGlja25lc3MsIDAuMCk7CglmbG9hdCBwYXJhbV83ID0gYmx1cjsKCWZsb2F0IGNpcmNsZV9pbm5lciA9IEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfY2lyY2xlX1MxX2MwKHBhcmFtXzQsIHBhcmFtXzUsIHBhcmFtXzYsIHBhcmFtXzcpOwoJcmV0dXJuIGNsYW1wKGNpcmNsZV9vdXRlciAtIGNpcmNsZV9pbm5lciwgMC4wLCAxLjApOwp9CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3RyaWFuZ2xlX25vaXNlX1MxX2MwKGlub3V0IGZsb2F0MiBuKSAKewoJbiA9IGZyYWN0KG4gKiBmbG9hdDIoNS4zOTg3LCA1LjQ0MjEpKTsKCW4gKz0gZmxvYXQyKGRvdChuLnl4LCBuICsgZmxvYXQyKDIxLjUzNTEsIDE0LjMxMzcpKSk7CglmbG9hdCB4eSA9IG4ueCAqIG4ueTsKCXJldHVybiAoZnJhY3QoeHkgKiA5NS40MzA3KSArIGZyYWN0KHh5ICogNzUuMDQ5NjEpKSAtIDEuMDsKfQpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF90aHJlc2hvbGRfUzFfYzAoZmxvYXQgdiwgZmxvYXQgbCwgZmxvYXQgaCkgCnsKCXJldHVybiBzdGVwKGwsIHYpICogKDEuMCAtIHN0ZXAoaCwgdikpOwp9CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3NwYXJrbGVfUzFfYzAoZmxvYXQyIHV2LCBmbG9hdCB0KSAKewoJZmxvYXQyIHBhcmFtID0gdXY7CglmbG9hdCBfMjQyID0gRkxUX2ZsdXR0ZXJfbG9jYWxfdHJpYW5nbGVfbm9pc2VfUzFfYzAocGFyYW0pOwoJZmxvYXQgbiA9IF8yNDI7CglmbG9hdCBwYXJhbV8xID0gbjsKCWZsb2F0IHBhcmFtXzIgPSAwLjA7CglmbG9hdCBwYXJhbV8zID0gMC4wNTsKCWZsb2F0IHMgPSBGTFRfZmx1dHRlcl9sb2NhbF90aHJlc2hvbGRfUzFfYzAocGFyYW1fMSwgcGFyYW1fMiwgcGFyYW1fMyk7CglmbG9hdCBwYXJhbV80ID0gbiArIHNpbigzLjE0MTU5Mjc0ICogKHQgKyAwLjM1KSk7CglmbG9hdCBwYXJhbV81ID0gMC4xOwoJZmxvYXQgcGFyYW1fNiA9IDAuMTU7CglzICs9IEZMVF9mbHV0dGVyX2xvY2FsX3RocmVzaG9sZF9TMV9jMChwYXJhbV80LCBwYXJhbV81LCBwYXJhbV82KTsKCWZsb2F0IHBhcmFtXzcgPSBuICsgc2luKDMuMTQxNTkyNzQgKiAodCArIDAuNykpOwoJZmxvYXQgcGFyYW1fOCA9IDAuMjsKCWZsb2F0IHBhcmFtXzkgPSAwLjI1OwoJcyArPSBGTFRfZmx1dHRlcl9sb2NhbF90aHJlc2hvbGRfUzFfYzAocGFyYW1fNywgcGFyYW1fOCwgcGFyYW1fOSk7CglmbG9hdCBwYXJhbV8xMCA9IG4gKyBzaW4oMy4xNDE1OTI3NCAqICh0ICsgMS4wNSkpOwoJZmxvYXQgcGFyYW1fMTEgPSAwLjM7CglmbG9hdCBwYXJhbV8xMiA9IDAuMzU7CglzICs9IEZMVF9mbHV0dGVyX2xvY2FsX3RocmVzaG9sZF9TMV9jMChwYXJhbV8xMCwgcGFyYW1fMTEsIHBhcmFtXzEyKTsKCXJldHVybiBjbGFtcChzLCAwLjAsIDEuMCkgKiAwLjU1Owp9CnZvaWQgRkxUX21haW5fUzFfYzAoKSAKewoJdV9hbHBoYV9TMV9jMCA9IHVfY29tcG9zaXRlXzFfUzFfYzAueDsKCXVfc3BhcmtsZV9hbHBoYV9TMV9jMCA9IHVfY29tcG9zaXRlXzFfUzFfYzAueTsKCXVfYmx1cl9TMV9jMCA9IHVfY29tcG9zaXRlXzFfUzFfYzAuejsKCXVfcmFkaXVzX3NjYWxlX1MxX2MwID0gdV9jb21wb3NpdGVfMV9TMV9jMC53OwoJZmxvYXQyIHAgPSBGTFRfZmx1dHRlcl9sb2NhbF9GbHV0dGVyRnJhZ0Nvb3JkX1MxX2MwKCk7CglmbG9hdDIgdXZfMSA9IHAgKiB1X3Jlc29sdXRpb25fc2NhbGVfUzFfYzA7CglmbG9hdDIgZGVuc2l0eV91diA9IHV2XzEgLSBtb2QocCwgdV9ub2lzZV9zY2FsZV9TMV9jMCk7CglmbG9hdCByYWRpdXMgPSB1X21heF9yYWRpdXNfUzFfYzAgKiB1X3JhZGl1c19zY2FsZV9TMV9jMDsKCWZsb2F0MiBwYXJhbV8xMyA9IHV2XzE7CglmbG9hdCB0dXJidWxlbmNlID0gRkxUX2ZsdXR0ZXJfbG9jYWxfdHVyYnVsZW5jZV9TMV9jMChwYXJhbV8xMyk7CglmbG9hdDIgcGFyYW1fMTQgPSBwOwoJZmxvYXQyIHBhcmFtXzE1ID0gdV9jZW50ZXJfUzFfYzA7CglmbG9hdCBwYXJhbV8xNiA9IHJhZGl1czsKCWZsb2F0IHBhcmFtXzE3ID0gMC4wNSAqIHVfbWF4X3JhZGl1c19TMV9jMDsKCWZsb2F0IHBhcmFtXzE4ID0gdV9ibHVyX1MxX2MwOwoJZmxvYXQgcmluZyA9IEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfcmluZ19TMV9jMChwYXJhbV8xNCwgcGFyYW1fMTUsIHBhcmFtXzE2LCBwYXJhbV8xNywgcGFyYW1fMTgpOwoJZmxvYXQyIHBhcmFtXzE5ID0gZGVuc2l0eV91djsKCWZsb2F0IHBhcmFtXzIwID0gdV9ub2lzZV9waGFzZV9TMV9jMDsKCWZsb2F0IHNwYXJrbGUgPSAoKEZMVF9mbHV0dGVyX2xvY2FsX3NwYXJrbGVfUzFfYzAocGFyYW1fMTksIHBhcmFtXzIwKSAqIHJpbmcpICogdHVyYnVsZW5jZSkgKiB1X3NwYXJrbGVfYWxwaGFfUzFfYzA7CglmbG9hdDIgcGFyYW1fMjEgPSBwOwoJZmxvYXQyIHBhcmFtXzIyID0gdV9jZW50ZXJfUzFfYzA7CglmbG9hdCBwYXJhbV8yMyA9IHJhZGl1czsKCWZsb2F0IHBhcmFtXzI0ID0gdV9ibHVyX1MxX2MwOwoJZmxvYXQgd2F2ZV9hbHBoYSA9IChGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X2NpcmNsZV9TMV9jMChwYXJhbV8yMSwgcGFyYW1fMjIsIHBhcmFtXzIzLCBwYXJhbV8yNCkgKiB1X2FscGhhX1MxX2MwKSAqIHVfY29sb3JfUzFfYzAudzsKCWZsb2F0NCB3YXZlX2NvbG9yID0gZmxvYXQ0KHVfY29sb3JfUzFfYzAueHl6ICogd2F2ZV9hbHBoYSwgd2F2ZV9hbHBoYSk7CglmcmFnQ29sb3JfUzFfYzAgPSBtaXgod2F2ZV9jb2xvciwgZmxvYXQ0KDEuMCksIGZsb2F0NChzcGFya2xlKSk7Cn0KaGFsZjQgcnVudGltZV9zaGFkZXJfUzFfYzAoaGFsZjQgX2lucHV0KSAKewoJaGFsZjQgX3RtcF8wX2luQ29sb3IgPSBfaW5wdXQ7CglmbG9hdDIgX3RtcF8xX2Nvb3JkcyA9IHZUcmFuc2Zvcm1lZENvb3Jkc18yX1MwOwoJZmx1dHRlcl9GcmFnQ29vcmRfUzFfYzAgPSBmbG9hdDQoX3RtcF8xX2Nvb3JkcywgMC4wLCAwLjApOwoJRkxUX21haW5fUzFfYzAoKTsKCXJldHVybiBoYWxmNChoYWxmNChmcmFnQ29sb3JfUzFfYzApKTsKfQpoYWxmNCBNYXRyaXhFZmZlY3RfUzEoaGFsZjQgX2lucHV0KSAKewoJcmV0dXJuIHJ1bnRpbWVfc2hhZGVyX1MxX2MwKF9pbnB1dCk7Cn0Kdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJaGFsZjQgb3V0cHV0Q29sb3JfUzA7CglvdXRwdXRDb2xvcl9TMCA9IHZjb2xvcl9TMDsKCWNvbnN0IGhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoMSk7CgloYWxmNCBvdXRwdXRfUzE7CglvdXRwdXRfUzEgPSBNYXRyaXhFZmZlY3RfUzEob3V0cHV0Q29sb3JfUzApOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dF9TMSAqIG91dHB1dENvdmVyYWdlX1MwOwoJfQp9CgAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAADAAAACAAAAHBvc2l0aW9uBQAAAGNvbG9yAAAACgAAAGxvY2FsQ29vcmQAAAAAAAA=","HWQACAAAABAAADAAAIOAAAAADIIAAIRODAAP577774DSAIAA737777YBAAAAAAAAAAAKAAYAAAACAAAAAAACCAYAAA":"DAAAAExTS1ONAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gZmxvYXQgY292ZXJhZ2U7CmluIGhhbGY0IGNvbG9yOwppbiBmbG9hdDQgZ2VvbVN1YnNldDsKZmxhdCBvdXQgaGFsZjQgdmNvbG9yX1MwOwpvdXQgZmxvYXQgdmNvdmVyYWdlX1MwOwpmbGF0IG91dCBmbG9hdDQgdmdlb21TdWJzZXRfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJZmxvYXQyIHBvc2l0aW9uID0gcG9zaXRpb24ueHk7Cgl2Y29sb3JfUzAgPSBjb2xvcjsKCXZjb3ZlcmFnZV9TMCA9IGNvdmVyYWdlOwoJdmdlb21TdWJzZXRfUzAgPSBnZW9tU3Vic2V0OwoJc2tfUG9zaXRpb24gPSBwb3NpdGlvbi54eTAxOwp9CgAAAAEAAAB5AgAAZmxhdCBpbiBoYWxmNCB2Y29sb3JfUzA7CmluIGZsb2F0IHZjb3ZlcmFnZV9TMDsKZmxhdCBpbiBmbG9hdDQgdmdlb21TdWJzZXRfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2Y29sb3JfUzA7CglmbG9hdCBjb3ZlcmFnZSA9IHZjb3ZlcmFnZV9TMDsKCWZsb2F0NCBnZW9TdWJzZXQ7CglnZW9TdWJzZXQgPSB2Z2VvbVN1YnNldF9TMDsKCWhhbGY0IGRpc3RzNCA9IGNsYW1wKGhhbGY0KDEsIDEsIC0xLCAtMSkgKiBoYWxmNChza19GcmFnQ29vcmQueHl4eSAtIGdlb1N1YnNldCksIDAsIDEpOwoJaGFsZjIgZGlzdHMyID0gZGlzdHM0Lnh5ICsgZGlzdHM0Lnp3IC0gMTsKCWhhbGYgc3Vic2V0Q292ZXJhZ2UgPSBkaXN0czIueCAqIGRpc3RzMi55OwoJY292ZXJhZ2UgPSBtaW4oY292ZXJhZ2UsIHN1YnNldENvdmVyYWdlKTsKCWhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoaGFsZihjb3ZlcmFnZSkpOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dENvbG9yX1MwICogb3V0cHV0Q292ZXJhZ2VfUzA7Cgl9Cn0KAAAAAQAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAIAAAAcG9zaXRpb24IAAAAY292ZXJhZ2UFAAAAY29sb3IAAAAKAAAAZ2VvbVN1YnNldAAAAAAAAA==","HVIAAAAAABIAAGAAAQ4AAAH477776R24EAAAIOBQAD6P7777777777YDAAAAAAAAAAAFQBVWKMG7QAAAAAAAAAACAAAAAVQEAAQAAAAAQCDAEQQGAAAAAAAAAAAA4IAPAAACAAAAAAAEABYAAAAEAAAAAAAEEBQA":"DAAAAExTS1N6AQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMV9jMDsKaW4gZmxvYXQyIHBvc2l0aW9uOwppbiBoYWxmNCBjb2xvcjsKaW4gZmxvYXQyIGxvY2FsQ29vcmQ7CmZsYXQgb3V0IGhhbGY0IHZjb2xvcl9TMDsKb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfM19TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgl2Y29sb3JfUzAgPSBjb2xvcjsKCXNrX1Bvc2l0aW9uID0gcG9zaXRpb24ueHkwMTsKCXsKCQl2VHJhbnNmb3JtZWRDb29yZHNfM19TMCA9IGZsb2F0M3gyKHVtYXRyaXhfUzFfYzApICogbG9jYWxDb29yZC54eTE7Cgl9Cn0KAAABAAAApAQAAHVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMV9jMDsKdW5pZm9ybSBmbG9hdDQgdWlubmVyUmVjdF9TMjsKdW5pZm9ybSBoYWxmMiB1cmFkaXVzUGx1c0hhbGZfUzI7CnNhbXBsZXJFeHRlcm5hbE9FUyB1VGV4dHVyZVNhbXBsZXJfMF9TMTsKZmxhdCBpbiBoYWxmNCB2Y29sb3JfUzA7CmluIGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfM19TMDsKaGFsZjQgVGV4dHVyZUVmZmVjdF9TMV9jMF9jMChoYWxmNCBfaW5wdXQpIAp7CglyZXR1cm4gc2FtcGxlKHVUZXh0dXJlU2FtcGxlcl8wX1MxLCB2VHJhbnNmb3JtZWRDb29yZHNfM19TMCk7Cn0KaGFsZjQgTWF0cml4RWZmZWN0X1MxX2MwKGhhbGY0IF9pbnB1dCkgCnsKCXJldHVybiBUZXh0dXJlRWZmZWN0X1MxX2MwX2MwKF9pbnB1dCk7Cn0KaGFsZjQgRGlzYWJsZUNvdmVyYWdlQXNBbHBoYV9TMShoYWxmNCBfaW5wdXQpIAp7CglfaW5wdXQgPSBNYXRyaXhFZmZlY3RfUzFfYzAoX2lucHV0KTsKCWhhbGY0IF90bXBfMF9pbkNvbG9yID0gX2lucHV0OwoJcmV0dXJuIGhhbGY0KF9pbnB1dCk7Cn0KaGFsZjQgQ2lyY3VsYXJSUmVjdF9TMihoYWxmNCBfaW5wdXQpIAp7CglmbG9hdDIgZHh5MCA9IHVpbm5lclJlY3RfUzIuTFQgLSBza19GcmFnQ29vcmQueHk7CglmbG9hdDIgZHh5MSA9IHNrX0ZyYWdDb29yZC54eSAtIHVpbm5lclJlY3RfUzIuUkI7CglmbG9hdDIgZHh5ID0gbWF4KG1heChkeHkwLCBkeHkxKSwgMC4wKTsKCWhhbGYgYWxwaGEgPSBoYWxmKHNhdHVyYXRlKHVyYWRpdXNQbHVzSGFsZl9TMi54IC0gbGVuZ3RoKGR4eSkpKTsKCXJldHVybiBfaW5wdXQgKiBhbHBoYTsKfQp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmNvbG9yX1MwOwoJY29uc3QgaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNCgxKTsKCWhhbGY0IG91dHB1dF9TMTsKCW91dHB1dF9TMSA9IERpc2FibGVDb3ZlcmFnZUFzQWxwaGFfUzEob3V0cHV0Q29sb3JfUzApOwoJaGFsZjQgb3V0cHV0X1MyOwoJb3V0cHV0X1MyID0gQ2lyY3VsYXJSUmVjdF9TMihvdXRwdXRDb3ZlcmFnZV9TMCk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0X1MxICogb3V0cHV0X1MyOwoJfQp9CgEAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAADAAAACAAAAHBvc2l0aW9uBQAAAGNvbG9yAAAACgAAAGxvY2FsQ29vcmQAAAAAAAA=","HUQACAAAAAMAADAAAIOAAAH677776IZOCAAP577777777777777777YBAAAAAAAAAAADEAAGAAAAAAAAAIAAAAAPAIABAAAAACYGEAAAAEAAAABUARCAIAAAAAAAAAAAACQAGAAAAAQAAAAAAAQQGAAAAA":"DAAAAExTS1NjAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMV9jMF9jMDsKaW4gZmxvYXQyIHBvc2l0aW9uOwppbiBoYWxmNCBjb2xvcjsKb3V0IGhhbGY0IHZjb2xvcl9TMDsKb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfNF9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgl2Y29sb3JfUzAgPSBjb2xvcjsKCXNrX1Bvc2l0aW9uID0gcG9zaXRpb24ueHkwMTsKCXsKCQl2VHJhbnNmb3JtZWRDb29yZHNfNF9TMCA9IGZsb2F0M3gyKHVtYXRyaXhfUzFfYzBfYzApICogcG9zaXRpb24ueHkxOwoJfQp9CgAAAAAANAMAAHVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMV9jMF9jMDsKc2FtcGxlcjJEIHVUZXh0dXJlU2FtcGxlcl8wX1MxOwppbiBoYWxmNCB2Y29sb3JfUzA7CmluIGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfNF9TMDsKaGFsZjQgVGV4dHVyZUVmZmVjdF9TMV9jMF9jMF9jMChoYWxmNCBfaW5wdXQpIAp7CglyZXR1cm4gc2FtcGxlKHVUZXh0dXJlU2FtcGxlcl8wX1MxLCB2VHJhbnNmb3JtZWRDb29yZHNfNF9TMCkuMDAwcjsKfQpoYWxmNCBNYXRyaXhFZmZlY3RfUzFfYzBfYzAoaGFsZjQgX2lucHV0KSAKewoJcmV0dXJuIFRleHR1cmVFZmZlY3RfUzFfYzBfYzBfYzAoX2lucHV0KTsKfQpoYWxmNCBEZXZpY2VTcGFjZV9TMV9jMChoYWxmNCBfaW5wdXQpIAp7CglyZXR1cm4gTWF0cml4RWZmZWN0X1MxX2MwX2MwKF9pbnB1dCk7Cn0KaGFsZjQgQmxlbmRfUzEoaGFsZjQgX3NyYywgaGFsZjQgX2RzdCkgCnsKCXJldHVybiBibGVuZF9kc3RfaW4oRGV2aWNlU3BhY2VfUzFfYzAoX3NyYyksIF9zcmMpOwp9CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2Y29sb3JfUzA7Cgljb25zdCBoYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KDEpOwoJaGFsZjQgb3V0cHV0X1MxOwoJb3V0cHV0X1MxID0gQmxlbmRfUzEob3V0cHV0Q292ZXJhZ2VfUzAsIGhhbGY0KDEpKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dF9TMTsKCX0KfQoAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAgAAABwb3NpdGlvbgUAAABjb2xvcgAAAAAAAAA=","B2AAQAAABQAAIAABBYAAB7777777777774ABICAAAAAAAAAAAAAABUABAAAAAEAAAAAIBEABAAAAA":"DAAAAExTS1MOAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0MiBpblBvc2l0aW9uOwppbiBoYWxmIGluQ292ZXJhZ2U7Cm91dCBoYWxmIHZpbkNvdmVyYWdlX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBEZWZhdWx0R2VvbWV0cnlQcm9jZXNzb3IKCWZsb2F0MiBfdG1wXzFfaW5Qb3NpdGlvbiA9IGluUG9zaXRpb247Cgl2aW5Db3ZlcmFnZV9TMCA9IGluQ292ZXJhZ2U7Cglza19Qb3NpdGlvbiA9IF90bXBfMV9pblBvc2l0aW9uLnh5MDE7Cn0KAAAAAAAATQEAAHVuaWZvcm0gaGFsZjQgdUNvbG9yX1MwOwppbiBoYWxmIHZpbkNvdmVyYWdlX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgRGVmYXVsdEdlb21ldHJ5UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdUNvbG9yX1MwOwoJaGFsZiBhbHBoYSA9IDEuMDsKCWFscGhhID0gdmluQ292ZXJhZ2VfUzA7CgloYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KGFscGhhKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dENvdmVyYWdlX1MwOwoJfQp9CgAAAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAACAAAACgAAAGluUG9zaXRpb24AAAoAAABpbkNvdmVyYWdlAAAAAAAA","HUJAAAAAAAQAADAAAIOAAAH677777777777QGHAQAD7P7777777777YBAAAAAAQAAAAAAQQGAAZAADIAAAAGULKMMQKAAAAAAMAAAAAIAAAAAAGIRBNAWEYZAUAABQAAAAAAAAAAAAADUAAAAAAAEAAAAAIDEAAA":"DAAAAExTS1PlAAAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gZmxvYXQyIGxvY2FsQ29vcmQ7Cm91dCBmbG9hdDIgdmxvY2FsQ29vcmRfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJdmxvY2FsQ29vcmRfUzAgPSBsb2NhbENvb3JkOwoJc2tfUG9zaXRpb24gPSBwb3NpdGlvbi54eTAxOwp9CgAAAAEAAACoBAAAY29uc3QgaW50IGtGaWxsQUFfUzFfYzAgPSAxOwpjb25zdCBpbnQga0ludmVyc2VGaWxsQldfUzFfYzAgPSAyOwpjb25zdCBpbnQga0ludmVyc2VGaWxsQUFfUzFfYzAgPSAzOwp1bmlmb3JtIGZsb2F0NCB1Y2lyY2xlX1MxX2MwOwpzYW1wbGVyMkQgdVRleHR1cmVTYW1wbGVyXzBfUzA7CmluIGZsb2F0MiB2bG9jYWxDb29yZF9TMDsKaGFsZjQgQ2lyY2xlX1MxX2MwKGhhbGY0IF9pbnB1dCkgCnsKCWhhbGY0IF90bXBfMF9pbkNvbG9yID0gX2lucHV0OwoJaGFsZiBkOwoJaWYgKGludCgxKSA9PSBrSW52ZXJzZUZpbGxCV19TMV9jMCB8fCBpbnQoMSkgPT0ga0ludmVyc2VGaWxsQUFfUzFfYzApIAoJewoJCWQgPSBoYWxmKChsZW5ndGgoKHVjaXJjbGVfUzFfYzAueHkgLSBza19GcmFnQ29vcmQueHkpICogdWNpcmNsZV9TMV9jMC53KSAtIDEuMCkgKiB1Y2lyY2xlX1MxX2MwLnopOwoJfQoJZWxzZSAKCXsKCQlkID0gaGFsZigoMS4wIC0gbGVuZ3RoKCh1Y2lyY2xlX1MxX2MwLnh5IC0gc2tfRnJhZ0Nvb3JkLnh5KSAqIHVjaXJjbGVfUzFfYzAudykpICogdWNpcmNsZV9TMV9jMC56KTsKCX0KCXJldHVybiBoYWxmNChoYWxmNChpbnQoMSkgPT0ga0ZpbGxBQV9TMV9jMCB8fCBpbnQoMSkgPT0ga0ludmVyc2VGaWxsQUFfUzFfYzAgPyBzYXR1cmF0ZShkKSA6IGhhbGYoZCA+IDAuNSkpKTsKfQpoYWxmNCBCbGVuZF9TMShoYWxmNCBfc3JjLCBoYWxmNCBfZHN0KSAKewoJcmV0dXJuIGJsZW5kX21vZHVsYXRlKF9zcmMsIENpcmNsZV9TMV9jMChfc3JjKSk7Cn0Kdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJaGFsZjQgb3V0cHV0Q29sb3JfUzAgPSBoYWxmNCgxKTsKCWZsb2F0MiB0ZXhDb29yZDsKCXRleENvb3JkID0gdmxvY2FsQ29vcmRfUzA7CglvdXRwdXRDb2xvcl9TMCA9IChibGVuZF9tb2R1bGF0ZShzYW1wbGUodVRleHR1cmVTYW1wbGVyXzBfUzAsIHRleENvb3JkKSwgaGFsZjQoMSkpKTsKCWNvbnN0IGhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoMSk7CgloYWxmNCBvdXRwdXRfUzE7CglvdXRwdXRfUzEgPSBCbGVuZF9TMShvdXRwdXRDb3ZlcmFnZV9TMCwgaGFsZjQoMSkpOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dENvbG9yX1MwICogb3V0cHV0X1MxOwoJfQp9CgEAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAACAAAACAAAAHBvc2l0aW9uCgAAAGxvY2FsQ29vcmQAAAAAAAA=","HVIACAAAABQAAGAAAQ4AAAAAGQQAARC4GAAAIOCAAD6P7777777777YDAAAAAAAAAAAFIBUAFS7EOCAAAAAGZJY26AAQAAAA2S5KXK4QAAAAAMAAAAAAAAQAABQM74NUDECAAAAAQ5UOAMQAAAAAAAAAAEAAAAAZ3FHDLYADAAAABKDVK5LSCAIAABQAAAAAAACAAAGAT3RWSMYIAAAAADWRYBSQAAAAAAAQAAAAGJJOXLVOIIBAAAGAAAAAAAAIAAAIAPOH2NTBAAAAAAOKFAOLAAAAAAAEAAAAAMQQAIAAAYGP6G2BSBAAACAAAAAAAAM5S4Z4NUDACAAAAAAAAADAIUOKFAOLAAAAAAACAAAAAZGIEENLQDAAAAAAAAAAABQAKAIAAIAAAADIBCEAQAAAAAAAAAAAIADQAAAAUAAAAAAAIIDA":"DAAAAExTS1PrAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMV9jMF9jMF9jMTsKaW4gZmxvYXQyIHBvc2l0aW9uOwppbiBmbG9hdCBjb3ZlcmFnZTsKaW4gaGFsZjQgY29sb3I7CmluIGZsb2F0MiBsb2NhbENvb3JkOwpmbGF0IG91dCBoYWxmNCB2Y29sb3JfUzA7Cm91dCBmbG9hdCB2Y292ZXJhZ2VfUzA7Cm91dCBmbG9hdDIgdlRyYW5zZm9ybWVkQ29vcmRzXzdfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJZmxvYXQyIHBvc2l0aW9uID0gcG9zaXRpb24ueHk7Cgl2Y29sb3JfUzAgPSBjb2xvcjsKCXZjb3ZlcmFnZV9TMCA9IGNvdmVyYWdlOwoJc2tfUG9zaXRpb24gPSBwb3NpdGlvbi54eTAxOwoJewoJCXZUcmFuc2Zvcm1lZENvb3Jkc183X1MwID0gZmxvYXQzeDIodW1hdHJpeF9TMV9jMF9jMF9jMSkgKiBsb2NhbENvb3JkLnh5MTsKCX0KfQoAAQAAAG4KAAB1bmlmb3JtIGhhbGY0IHVzdGFydF9TMV9jMF9jMF9jMF9jMDsKdW5pZm9ybSBoYWxmNCB1ZW5kX1MxX2MwX2MwX2MwX2MwOwp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzFfYzBfYzBfYzE7CnVuaWZvcm0gaGFsZjQgdWxlZnRCb3JkZXJDb2xvcl9TMV9jMF9jMDsKdW5pZm9ybSBoYWxmNCB1cmlnaHRCb3JkZXJDb2xvcl9TMV9jMF9jMDsKdW5pZm9ybSBmbG9hdDN4MyB1bWF0cml4X1MxX2MxOwp1bmlmb3JtIGhhbGYgdXJhbmdlX1MxOwpzYW1wbGVyMkQgdVRleHR1cmVTYW1wbGVyXzBfUzE7CmZsYXQgaW4gaGFsZjQgdmNvbG9yX1MwOwppbiBmbG9hdCB2Y292ZXJhZ2VfUzA7CmluIGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfN19TMDsKaGFsZjQgU2luZ2xlSW50ZXJ2YWxDb2xvcml6ZXJfUzFfYzBfYzBfYzBfYzAoaGFsZjQgX2lucHV0LCBmbG9hdDIgX2Nvb3JkcykgCnsKCWhhbGY0IF90bXBfMF9pbkNvbG9yID0gX2lucHV0OwoJZmxvYXQyIF90bXBfMV9jb29yZHMgPSBfY29vcmRzOwoJcmV0dXJuIGhhbGY0KG1peCh1c3RhcnRfUzFfYzBfYzBfYzBfYzAsIHVlbmRfUzFfYzBfYzBfYzBfYzAsIGhhbGYoX3RtcF8xX2Nvb3Jkcy54KSkpOwp9CmhhbGY0IGNvbG9yX3hmb3JtX1MxX2MwX2MwX2MwKGZsb2F0NCBjb2xvcikgCnsKCWNvbG9yLnJnYiAqPSBjb2xvci5hOwoJcmV0dXJuIGhhbGY0KGNvbG9yKTsKfQpoYWxmNCBDb2xvclNwYWNlWGZvcm1fUzFfYzBfYzBfYzAoaGFsZjQgX2lucHV0LCBmbG9hdDIgX2Nvb3JkcykgCnsKCXJldHVybiBjb2xvcl94Zm9ybV9TMV9jMF9jMF9jMChTaW5nbGVJbnRlcnZhbENvbG9yaXplcl9TMV9jMF9jMF9jMF9jMChfaW5wdXQsIF9jb29yZHMpKTsKfQpoYWxmNCBMaW5lYXJMYXlvdXRfUzFfYzBfYzBfYzFfYzAoaGFsZjQgX2lucHV0KSAKewoJaGFsZjQgX3RtcF8yX2luQ29sb3IgPSBfaW5wdXQ7CglmbG9hdDIgX3RtcF8zX2Nvb3JkcyA9IHZUcmFuc2Zvcm1lZENvb3Jkc183X1MwOwoJcmV0dXJuIGhhbGY0KGhhbGY0KGhhbGYoX3RtcF8zX2Nvb3Jkcy54KSArIDFlLTA1LCAxLjAsIDAuMCwgMC4wKSk7Cn0KaGFsZjQgTWF0cml4RWZmZWN0X1MxX2MwX2MwX2MxKGhhbGY0IF9pbnB1dCkgCnsKCXJldHVybiBMaW5lYXJMYXlvdXRfUzFfYzBfYzBfYzFfYzAoX2lucHV0KTsKfQpoYWxmNCBDbGFtcGVkR3JhZGllbnRfUzFfYzBfYzAoaGFsZjQgX2lucHV0KSAKewoJaGFsZjQgX3RtcF80X2luQ29sb3IgPSBfaW5wdXQ7CgloYWxmNCB0ID0gTWF0cml4RWZmZWN0X1MxX2MwX2MwX2MxKF90bXBfNF9pbkNvbG9yKTsKCWhhbGY0IG91dENvbG9yOwoJaWYgKCFib29sKGludCgxKSkgJiYgdC55IDwgMC4wKSAKCXsKCQlvdXRDb2xvciA9IGhhbGY0KDAuMCk7Cgl9CgllbHNlIGlmICh0LnggPCAwLjApIAoJewoJCW91dENvbG9yID0gdWxlZnRCb3JkZXJDb2xvcl9TMV9jMF9jMDsKCX0KCWVsc2UgaWYgKHQueCA+IDEuMCkgCgl7CgkJb3V0Q29sb3IgPSB1cmlnaHRCb3JkZXJDb2xvcl9TMV9jMF9jMDsKCX0KCWVsc2UgCgl7CgkJb3V0Q29sb3IgPSBDb2xvclNwYWNlWGZvcm1fUzFfYzBfYzBfYzAoX3RtcF80X2luQ29sb3IsIGZsb2F0MihoYWxmMih0LngsIDAuMCkpKTsKCX0KCXJldHVybiBoYWxmNChvdXRDb2xvcik7Cn0KaGFsZjQgRGlzYWJsZUNvdmVyYWdlQXNBbHBoYV9TMV9jMChoYWxmNCBfaW5wdXQpIAp7CglfaW5wdXQgPSBDbGFtcGVkR3JhZGllbnRfUzFfYzBfYzAoX2lucHV0KTsKCWhhbGY0IF90bXBfNV9pbkNvbG9yID0gX2lucHV0OwoJcmV0dXJuIGhhbGY0KF9pbnB1dCk7Cn0KaGFsZjQgVGV4dHVyZUVmZmVjdF9TMV9jMV9jMChoYWxmNCBfaW5wdXQsIGZsb2F0MiBfY29vcmRzKSAKewoJcmV0dXJuIHNhbXBsZSh1VGV4dHVyZVNhbXBsZXJfMF9TMSwgX2Nvb3JkcykuMDAwcjsKfQpoYWxmNCBNYXRyaXhFZmZlY3RfUzFfYzEoaGFsZjQgX2lucHV0LCBmbG9hdDIgX2Nvb3JkcykgCnsKCXJldHVybiBUZXh0dXJlRWZmZWN0X1MxX2MxX2MwKF9pbnB1dCwgZmxvYXQzeDIodW1hdHJpeF9TMV9jMSkgKiBfY29vcmRzLnh5MSk7Cn0KaGFsZjQgRGl0aGVyX1MxKGhhbGY0IF9pbnB1dCkgCnsKCWhhbGY0IF90bXBfNl9pbkNvbG9yID0gX2lucHV0OwoJaGFsZjQgY29sb3IgPSBEaXNhYmxlQ292ZXJhZ2VBc0FscGhhX1MxX2MwKF90bXBfNl9pbkNvbG9yKTsKCWhhbGYgdmFsdWUgPSBNYXRyaXhFZmZlY3RfUzFfYzEoX3RtcF82X2luQ29sb3IsIHNrX0ZyYWdDb29yZC54eSkudyAtIDAuNTsKCXJldHVybiBoYWxmNChoYWxmNChjbGFtcChjb2xvci54eXogKyB2YWx1ZSAqIHVyYW5nZV9TMSwgMC4wLCBjb2xvci53KSwgY29sb3IudykpOwp9CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2Y29sb3JfUzA7CglmbG9hdCBjb3ZlcmFnZSA9IHZjb3ZlcmFnZV9TMDsKCWhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoaGFsZihjb3ZlcmFnZSkpOwoJaGFsZjQgb3V0cHV0X1MxOwoJb3V0cHV0X1MxID0gRGl0aGVyX1MxKG91dHB1dENvbG9yX1MwKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSAoaGFsZjQoMS4wKSAtIG91dHB1dF9TMSkgKiBvdXRwdXRDb3ZlcmFnZV9TMDsKCX0KfQoAAAEAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAEAAAACAAAAHBvc2l0aW9uCAAAAGNvdmVyYWdlBQAAAGNvbG9yAAAACgAAAGxvY2FsQ29vcmQAAAAAAAA=","HVIAAAAAABIAAGAAAQ4AAAH477776R24EAAAIOBQAD6P7777777777YDAAAAAAAAAAAGIBIAAABAAAAANAEAAAAAAAAAAAAAABAAOAAAABAAAAAAABBAMAAAAA":"DAAAAExTS1N0AQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMTsKaW4gZmxvYXQyIHBvc2l0aW9uOwppbiBoYWxmNCBjb2xvcjsKaW4gZmxvYXQyIGxvY2FsQ29vcmQ7CmZsYXQgb3V0IGhhbGY0IHZjb2xvcl9TMDsKb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgl2Y29sb3JfUzAgPSBjb2xvcjsKCXNrX1Bvc2l0aW9uID0gcG9zaXRpb24ueHkwMTsKCXsKCQl2VHJhbnNmb3JtZWRDb29yZHNfMl9TMCA9IGZsb2F0M3gyKHVtYXRyaXhfUzEpICogbG9jYWxDb29yZC54eTE7Cgl9Cn0KAAAAAGsCAAB1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzE7CnNhbXBsZXIyRCB1VGV4dHVyZVNhbXBsZXJfMF9TMTsKZmxhdCBpbiBoYWxmNCB2Y29sb3JfUzA7CmluIGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKaGFsZjQgVGV4dHVyZUVmZmVjdF9TMV9jMChoYWxmNCBfaW5wdXQpIAp7CglyZXR1cm4gc2FtcGxlKHVUZXh0dXJlU2FtcGxlcl8wX1MxLCB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMCkucnJycjsKfQpoYWxmNCBNYXRyaXhFZmZlY3RfUzEoaGFsZjQgX2lucHV0KSAKewoJcmV0dXJuIFRleHR1cmVFZmZlY3RfUzFfYzAoX2lucHV0KTsKfQp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmNvbG9yX1MwOwoJY29uc3QgaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNCgxKTsKCWhhbGY0IG91dHB1dF9TMTsKCW91dHB1dF9TMSA9IE1hdHJpeEVmZmVjdF9TMShvdXRwdXRDb3ZlcmFnZV9TMCk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRfUzE7Cgl9Cn0KAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAADAAAACAAAAHBvc2l0aW9uBQAAAGNvbG9yAAAACgAAAGxvY2FsQ29vcmQAAAAAAAA=","HUIAAAAAAAQAADAAAIOAAAH677777777777QGHAQAD7P7777777777YBAAAAAAAAAAALUASJ3EZYN2AAAAAAAIAEAAAABSCQKL3IYIJ2AAAAAAAIAEAAAABLBCABAAAAABAEGABBAMAAACAAAAAAAOQAAAAAAAQAAAABAMQAAAAAA":"DAAAAExTS1M2AQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMTsKaW4gZmxvYXQyIHBvc2l0aW9uOwppbiBmbG9hdDIgbG9jYWxDb29yZDsKb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCglza19Qb3NpdGlvbiA9IHBvc2l0aW9uLnh5MDE7Cgl7CgkJdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzAgPSBmbG9hdDN4Mih1bWF0cml4X1MxKSAqIGxvY2FsQ29vcmQueHkxOwoJfQp9CgAAAAAAAGgHAABjb25zdCBpbnQga01heExvb3BMaW1pdF9TMV9jMCA9IDg7CnVuaWZvcm0gaGFsZjQgdWJvcmRlcl9TMV9jMF9jMF9jMDsKdW5pZm9ybSBmbG9hdDQgdXN1YnNldF9TMV9jMF9jMF9jMDsKdW5pZm9ybSBmbG9hdDQgdWNsYW1wX1MxX2MwX2MwX2MwOwp1bmlmb3JtIGZsb2F0MiB1aWRpbXNfUzFfYzBfYzBfYzA7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMV9jMF9jMDsKdW5pZm9ybSBoYWxmNCB1b2Zmc2V0c0FuZEtlcm5lbF9TMV9jMFsxNF07CnVuaWZvcm0gaGFsZjIgdWRpcl9TMV9jMDsKdW5pZm9ybSBmbG9hdDN4MyB1bWF0cml4X1MxOwpzYW1wbGVyMkQgdVRleHR1cmVTYW1wbGVyXzBfUzE7CmluIGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKaGFsZjQgVGV4dHVyZUVmZmVjdF9TMV9jMF9jMF9jMChoYWxmNCBfaW5wdXQsIGZsb2F0MiBfY29vcmRzKSAKewoJZmxvYXQyIGluQ29vcmQgPSBfY29vcmRzOwoJZmxvYXQyIHN1YnNldENvb3JkOwoJc3Vic2V0Q29vcmQueCA9IGluQ29vcmQueDsKCXN1YnNldENvb3JkLnkgPSBpbkNvb3JkLnk7CglmbG9hdDIgY2xhbXBlZENvb3JkOwoJY2xhbXBlZENvb3JkLnggPSBzdWJzZXRDb29yZC54OwoJY2xhbXBlZENvb3JkLnkgPSBjbGFtcChzdWJzZXRDb29yZC55LCB1Y2xhbXBfUzFfYzBfYzBfYzAueSwgdWNsYW1wX1MxX2MwX2MwX2MwLncpOwoJaGFsZjQgdGV4dHVyZUNvbG9yID0gc2FtcGxlKHVUZXh0dXJlU2FtcGxlcl8wX1MxLCAoY2xhbXBlZENvb3JkKSAqIHVpZGltc19TMV9jMF9jMF9jMCk7CgloYWxmIGVyclkgPSBoYWxmKHN1YnNldENvb3JkLnkgLSBjbGFtcGVkQ29vcmQueSk7Cgl0ZXh0dXJlQ29sb3IgPSBtaXgodGV4dHVyZUNvbG9yLCB1Ym9yZGVyX1MxX2MwX2MwX2MwLCBtaW4oYWJzKGVyclkpLCAxKSk7CglyZXR1cm4gdGV4dHVyZUNvbG9yOwp9CmhhbGY0IE1hdHJpeEVmZmVjdF9TMV9jMF9jMChoYWxmNCBfaW5wdXQsIGZsb2F0MiBfY29vcmRzKSAKewoJcmV0dXJuIFRleHR1cmVFZmZlY3RfUzFfYzBfYzBfYzAoX2lucHV0LCBmbG9hdDN4Mih1bWF0cml4X1MxX2MwX2MwKSAqIF9jb29yZHMueHkxKTsKfQpoYWxmNCBHYXVzc2lhbkJsdXIxRF9TMV9jMChoYWxmNCBfaW5wdXQpIAp7CgloYWxmNCBfdG1wXzBfaW5Db2xvciA9IF9pbnB1dDsKCWZsb2F0MiBfdG1wXzFfY29vcmRzID0gdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzA7CgloYWxmNCBzdW0gPSBoYWxmNCgwLjApOwoJZm9yIChpbnQgaSA9IDA7aSA8IGtNYXhMb29wTGltaXRfUzFfYzA7ICsraSkgCgl7CgkJaGFsZjQgcyA9IHVvZmZzZXRzQW5kS2VybmVsX1MxX2MwW2ldOwoJCXN1bSArPSBzLnkgKiBNYXRyaXhFZmZlY3RfUzFfYzBfYzAoX3RtcF8wX2luQ29sb3IsIF90bXBfMV9jb29yZHMgKyBmbG9hdDIocy54ICogdWRpcl9TMV9jMCkpOwoJCXN1bSArPSBzLncgKiBNYXRyaXhFZmZlY3RfUzFfYzBfYzAoX3RtcF8wX2luQ29sb3IsIF90bXBfMV9jb29yZHMgKyBmbG9hdDIocy56ICogdWRpcl9TMV9jMCkpOwoJfQoJcmV0dXJuIGhhbGY0KHN1bSk7Cn0KaGFsZjQgTWF0cml4RWZmZWN0X1MxKGhhbGY0IF9pbnB1dCkgCnsKCXJldHVybiBHYXVzc2lhbkJsdXIxRF9TMV9jMChfaW5wdXQpOwp9CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwID0gaGFsZjQoMSk7Cgljb25zdCBoYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KDEpOwoJaGFsZjQgb3V0cHV0X1MxOwoJb3V0cHV0X1MxID0gTWF0cml4RWZmZWN0X1MxKG91dHB1dENvbG9yX1MwKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRfUzEgKiBvdXRwdXRDb3ZlcmFnZV9TMDsKCX0KfQoAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAgAAABwb3NpdGlvbgoAAABsb2NhbENvb3JkAAAAAAAA","DAQAAAAAAAAAAAAAAJQAAIGAAEACBYQCAGAEFAIBAAAAAABAAAAAAAAAAAACAB4QA4AAAEAAAAAABIADAAAAAIAAAAAAAIID":"DAAAAExTS1MWAgAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQyIHVBdGxhc1NpemVJbnZfUzA7CmluIGZsb2F0MiBpblBvc2l0aW9uOwppbiBoYWxmNCBpbkNvbG9yOwppbiB1c2hvcnQyIGluVGV4dHVyZUNvb3JkczsKb3V0IGZsb2F0MiB2VGV4dHVyZUNvb3Jkc19TMDsKZmxhdCBvdXQgZmxvYXQgdlRleEluZGV4X1MwOwpvdXQgaGFsZjQgdmluQ29sb3JfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIEJpdG1hcFRleHQKCWludCB0ZXhJZHggPSAwOwoJZmxvYXQyIHVub3JtVGV4Q29vcmRzID0gZmxvYXQyKGluVGV4dHVyZUNvb3Jkcy54LCBpblRleHR1cmVDb29yZHMueSk7Cgl2VGV4dHVyZUNvb3Jkc19TMCA9IHVub3JtVGV4Q29vcmRzICogdUF0bGFzU2l6ZUludl9TMDsKCXZUZXhJbmRleF9TMCA9IGZsb2F0KHRleElkeCk7Cgl2aW5Db2xvcl9TMCA9IGluQ29sb3I7CglmbG9hdDIgX3RtcF8xX2luUG9zaXRpb24gPSBpblBvc2l0aW9uOwoJc2tfUG9zaXRpb24gPSBpblBvc2l0aW9uLnh5MDE7Cn0KAAABAAAAOAMAAHVuaWZvcm0gZmxvYXQ0IHVpbm5lclJlY3RfUzE7CnVuaWZvcm0gaGFsZjIgdXJhZGl1c1BsdXNIYWxmX1MxOwpzYW1wbGVyMkQgdVRleHR1cmVTYW1wbGVyXzBfUzA7CmluIGZsb2F0MiB2VGV4dHVyZUNvb3Jkc19TMDsKZmxhdCBpbiBmbG9hdCB2VGV4SW5kZXhfUzA7CmluIGhhbGY0IHZpbkNvbG9yX1MwOwpoYWxmNCBDaXJjdWxhclJSZWN0X1MxKGhhbGY0IF9pbnB1dCkgCnsKCWZsb2F0MiBkeHkwID0gdWlubmVyUmVjdF9TMS5MVCAtIHNrX0ZyYWdDb29yZC54eTsKCWZsb2F0MiBkeHkxID0gc2tfRnJhZ0Nvb3JkLnh5IC0gdWlubmVyUmVjdF9TMS5SQjsKCWZsb2F0MiBkeHkgPSBtYXgobWF4KGR4eTAsIGR4eTEpLCAwLjApOwoJaGFsZiBhbHBoYSA9IGhhbGYoc2F0dXJhdGUodXJhZGl1c1BsdXNIYWxmX1MxLnggLSBsZW5ndGgoZHh5KSkpOwoJcmV0dXJuIF9pbnB1dCAqIGFscGhhOwp9CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBCaXRtYXBUZXh0CgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmluQ29sb3JfUzA7CgloYWxmNCB0ZXhDb2xvcjsKCXsKCQl0ZXhDb2xvciA9IHNhbXBsZSh1VGV4dHVyZVNhbXBsZXJfMF9TMCwgdlRleHR1cmVDb29yZHNfUzApLnJycnI7Cgl9CgloYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IHRleENvbG9yOwoJaGFsZjQgb3V0cHV0X1MxOwoJb3V0cHV0X1MxID0gQ2lyY3VsYXJSUmVjdF9TMShvdXRwdXRDb3ZlcmFnZV9TMCk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRfUzE7Cgl9Cn0KAQAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAKAAAAaW5Qb3NpdGlvbgAABwAAAGluQ29sb3IADwAAAGluVGV4dHVyZUNvb3JkcwAAAAAA","HUJAAAAAAAQAADAAAIOAAAH677777777777QGHAQAD7P7777777777YBAAAAAAQAAAAAAQQGACQAGAAAAAQAAAAAAAQQGAAA":"DAAAAExTS1PlAAAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gZmxvYXQyIGxvY2FsQ29vcmQ7Cm91dCBmbG9hdDIgdmxvY2FsQ29vcmRfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJdmxvY2FsQ29vcmRfUzAgPSBsb2NhbENvb3JkOwoJc2tfUG9zaXRpb24gPSBwb3NpdGlvbi54eTAxOwp9CgAAAAAAAACkAQAAc2FtcGxlcjJEIHVUZXh0dXJlU2FtcGxlcl8wX1MwOwppbiBmbG9hdDIgdmxvY2FsQ29vcmRfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwID0gaGFsZjQoMSk7CglmbG9hdDIgdGV4Q29vcmQ7Cgl0ZXhDb29yZCA9IHZsb2NhbENvb3JkX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSAoYmxlbmRfbW9kdWxhdGUoc2FtcGxlKHVUZXh0dXJlU2FtcGxlcl8wX1MwLCB0ZXhDb29yZCksIGhhbGY0KDEpKSk7Cgljb25zdCBoYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KDEpOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dENvbG9yX1MwICogb3V0cHV0Q292ZXJhZ2VfUzA7Cgl9Cn0KAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAIAAAAcG9zaXRpb24KAAAAbG9jYWxDb29yZAAAAAAAAA==","DAQAAAAAAAAAAAAAAJQAAIGAAEACBYQCAGAEFAIBAAAAAABAAAAAAAAAAAACAA6QAAAABUDB7AHU6AIAAAYAAAAAQAAAAAEARR2BR7WDKMAAAAAMAAAAAAAAAAAABIADAAAAAIAAAAAAAIIDAAAA":"DAAAAExTS1MWAgAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQyIHVBdGxhc1NpemVJbnZfUzA7CmluIGZsb2F0MiBpblBvc2l0aW9uOwppbiBoYWxmNCBpbkNvbG9yOwppbiB1c2hvcnQyIGluVGV4dHVyZUNvb3JkczsKb3V0IGZsb2F0MiB2VGV4dHVyZUNvb3Jkc19TMDsKZmxhdCBvdXQgZmxvYXQgdlRleEluZGV4X1MwOwpvdXQgaGFsZjQgdmluQ29sb3JfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIEJpdG1hcFRleHQKCWludCB0ZXhJZHggPSAwOwoJZmxvYXQyIHVub3JtVGV4Q29vcmRzID0gZmxvYXQyKGluVGV4dHVyZUNvb3Jkcy54LCBpblRleHR1cmVDb29yZHMueSk7Cgl2VGV4dHVyZUNvb3Jkc19TMCA9IHVub3JtVGV4Q29vcmRzICogdUF0bGFzU2l6ZUludl9TMDsKCXZUZXhJbmRleF9TMCA9IGZsb2F0KHRleElkeCk7Cgl2aW5Db2xvcl9TMCA9IGluQ29sb3I7CglmbG9hdDIgX3RtcF8xX2luUG9zaXRpb24gPSBpblBvc2l0aW9uOwoJc2tfUG9zaXRpb24gPSBpblBvc2l0aW9uLnh5MDE7Cn0KAAABAAAAPQUAAGNvbnN0IGludCBrRmlsbEJXX1MxX2MwID0gMDsKY29uc3QgaW50IGtJbnZlcnNlRmlsbEJXX1MxX2MwID0gMjsKY29uc3QgaW50IGtJbnZlcnNlRmlsbEFBX1MxX2MwID0gMzsKdW5pZm9ybSBmbG9hdDQgdXJlY3RVbmlmb3JtX1MxX2MwOwpzYW1wbGVyMkQgdVRleHR1cmVTYW1wbGVyXzBfUzA7CmluIGZsb2F0MiB2VGV4dHVyZUNvb3Jkc19TMDsKZmxhdCBpbiBmbG9hdCB2VGV4SW5kZXhfUzA7CmluIGhhbGY0IHZpbkNvbG9yX1MwOwpoYWxmNCBSZWN0X1MxX2MwKGhhbGY0IF9pbnB1dCkgCnsKCWhhbGY0IF90bXBfMF9pbkNvbG9yID0gX2lucHV0OwoJaGFsZiBjb3ZlcmFnZTsKCWlmIChpbnQoMSkgPT0ga0ZpbGxCV19TMV9jMCB8fCBpbnQoMSkgPT0ga0ludmVyc2VGaWxsQldfUzFfYzApIAoJewoJCWNvdmVyYWdlID0gaGFsZihhbGwoZ3JlYXRlclRoYW4oZmxvYXQ0KHNrX0ZyYWdDb29yZC54eSwgdXJlY3RVbmlmb3JtX1MxX2MwLnp3KSwgZmxvYXQ0KHVyZWN0VW5pZm9ybV9TMV9jMC54eSwgc2tfRnJhZ0Nvb3JkLnh5KSkpKTsKCX0KCWVsc2UgCgl7CgkJaGFsZjQgZGlzdHM0ID0gc2F0dXJhdGUoaGFsZjQoMS4wLCAxLjAsIC0xLjAsIC0xLjApICogaGFsZjQoc2tfRnJhZ0Nvb3JkLnh5eHkgLSB1cmVjdFVuaWZvcm1fUzFfYzApKTsKCQloYWxmMiBkaXN0czIgPSAoZGlzdHM0Lnh5ICsgZGlzdHM0Lnp3KSAtIDEuMDsKCQljb3ZlcmFnZSA9IGRpc3RzMi54ICogZGlzdHMyLnk7Cgl9CglpZiAoaW50KDEpID09IGtJbnZlcnNlRmlsbEJXX1MxX2MwIHx8IGludCgxKSA9PSBrSW52ZXJzZUZpbGxBQV9TMV9jMCkgCgl7CgkJY292ZXJhZ2UgPSAxLjAgLSBjb3ZlcmFnZTsKCX0KCXJldHVybiBoYWxmNChoYWxmNChjb3ZlcmFnZSkpOwp9CmhhbGY0IEJsZW5kX1MxKGhhbGY0IF9zcmMsIGhhbGY0IF9kc3QpIAp7CglyZXR1cm4gYmxlbmRfbW9kdWxhdGUoUmVjdF9TMV9jMChfc3JjKSwgX3NyYyk7Cn0Kdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIEJpdG1hcFRleHQKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2aW5Db2xvcl9TMDsKCWhhbGY0IHRleENvbG9yOwoJewoJCXRleENvbG9yID0gc2FtcGxlKHVUZXh0dXJlU2FtcGxlcl8wX1MwLCB2VGV4dHVyZUNvb3Jkc19TMCkucnJycjsKCX0KCWhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gdGV4Q29sb3I7CgloYWxmNCBvdXRwdXRfUzE7CglvdXRwdXRfUzEgPSBCbGVuZF9TMShvdXRwdXRDb3ZlcmFnZV9TMCwgaGFsZjQoMSkpOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dENvbG9yX1MwICogb3V0cHV0X1MxOwoJfQp9CgAAAAEAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAADAAAACgAAAGluUG9zaXRpb24AAAcAAABpbkNvbG9yAA8AAABpblRleHR1cmVDb29yZHMAAAAAAA==","HVIACAAAABQAAGAAAQ4AAAAAGQQAARC4GAAAIOCAAD6P7777777777YDAAAAAAAAAAAHIBNGZODK5YIAAAAAAQAAAAAIADCNS4GV3QYBAAAAAAAAAAAAAHIAAAAAAAIAAAAAQGIAAAAAA":"DAAAAExTS1PZAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMTsKaW4gZmxvYXQyIHBvc2l0aW9uOwppbiBmbG9hdCBjb3ZlcmFnZTsKaW4gaGFsZjQgY29sb3I7CmluIGZsb2F0MiBsb2NhbENvb3JkOwpmbGF0IG91dCBoYWxmNCB2Y29sb3JfUzA7Cm91dCBmbG9hdCB2Y292ZXJhZ2VfUzA7Cm91dCBmbG9hdDIgdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJZmxvYXQyIHBvc2l0aW9uID0gcG9zaXRpb24ueHk7Cgl2Y29sb3JfUzAgPSBjb2xvcjsKCXZjb3ZlcmFnZV9TMCA9IGNvdmVyYWdlOwoJc2tfUG9zaXRpb24gPSBwb3NpdGlvbi54eTAxOwoJewoJCXZUcmFuc2Zvcm1lZENvb3Jkc18yX1MwID0gZmxvYXQzeDIodW1hdHJpeF9TMSkgKiBsb2NhbENvb3JkLnh5MTsKCX0KfQoAAAAAAAAAyhsAAGZsb2F0NCBmbHV0dGVyX0ZyYWdDb29yZF9TMV9jMDsKZmxvYXQ0IGZyYWdDb2xvcl9TMV9jMDsKZmxvYXQgdV9hbHBoYV9TMV9jMDsKZmxvYXQgdV9zcGFya2xlX2FscGhhX1MxX2MwOwpmbG9hdCB1X2JsdXJfUzFfYzA7CmZsb2F0IHVfcmFkaXVzX3NjYWxlX1MxX2MwOwp1bmlmb3JtIGZsb2F0NCB1X2NvbG9yX1MxX2MwOwp1bmlmb3JtIGZsb2F0NCB1X2NvbXBvc2l0ZV8xX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X2NlbnRlcl9TMV9jMDsKdW5pZm9ybSBmbG9hdCB1X21heF9yYWRpdXNfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfcmVzb2x1dGlvbl9zY2FsZV9TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9ub2lzZV9zY2FsZV9TMV9jMDsKdW5pZm9ybSBmbG9hdCB1X25vaXNlX3BoYXNlX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X2NpcmNsZTFfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfY2lyY2xlMl9TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9jaXJjbGUzX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X3JvdGF0aW9uMV9TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9yb3RhdGlvbjJfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfcm90YXRpb24zX1MxX2MwOwp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzE7CmZsYXQgaW4gaGFsZjQgdmNvbG9yX1MwOwppbiBmbG9hdCB2Y292ZXJhZ2VfUzA7CmluIGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKZmxvYXQyIEZMVF9mbHV0dGVyX2xvY2FsX0ZsdXR0ZXJGcmFnQ29vcmRfUzFfYzAoKTsKZmxvYXQyeDIgRkxUX2ZsdXR0ZXJfbG9jYWxfcm90YXRlMmRfUzFfYzAoZmxvYXQyIHJhZCk7CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfY2lyY2xlX1MxX2MwKGZsb2F0MiB1diwgZmxvYXQyIHh5LCBmbG9hdCByYWRpdXMsIGZsb2F0IGJsdXIpOwpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9jaXJjbGVfZ3JpZF9TMV9jMChmbG9hdDIgcmVzb2x1dGlvbiwgaW5vdXQgZmxvYXQyIHAsIGZsb2F0MiB4eSwgZmxvYXQyIHJvdGF0aW9uLCBmbG9hdCBjZWxsX2RpYW1ldGVyKTsKZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfdHVyYnVsZW5jZV9TMV9jMChmbG9hdDIgdXYpOwpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X3JpbmdfUzFfYzAoZmxvYXQyIHV2LCBmbG9hdDIgeHksIGZsb2F0IHJhZGl1cywgZmxvYXQgdGhpY2tuZXNzLCBmbG9hdCBibHVyKTsKZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfdHJpYW5nbGVfbm9pc2VfUzFfYzAoaW5vdXQgZmxvYXQyIG4pOwpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF90aHJlc2hvbGRfUzFfYzAoZmxvYXQgdiwgZmxvYXQgbCwgZmxvYXQgaCk7CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3NwYXJrbGVfUzFfYzAoZmxvYXQyIHV2LCBmbG9hdCB0KTsKdm9pZCBGTFRfbWFpbl9TMV9jMCgpOwpmbG9hdDIgRkxUX2ZsdXR0ZXJfbG9jYWxfRmx1dHRlckZyYWdDb29yZF9TMV9jMCgpIAp7CglyZXR1cm4gZmx1dHRlcl9GcmFnQ29vcmRfUzFfYzAueHk7Cn0KZmxvYXQyeDIgRkxUX2ZsdXR0ZXJfbG9jYWxfcm90YXRlMmRfUzFfYzAoZmxvYXQyIHJhZCkgCnsKCXJldHVybiBmbG9hdDJ4MihyYWQueCwgLXJhZC55LCByYWQueSwgcmFkLngpOwp9CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfY2lyY2xlX1MxX2MwKGZsb2F0MiB1diwgZmxvYXQyIHh5LCBmbG9hdCByYWRpdXMsIGZsb2F0IGJsdXIpIAp7CglmbG9hdCBibHVyX2hhbGYgPSBibHVyICogMC41OwoJZmxvYXQgZCA9IGRpc3RhbmNlKHV2LCB4eSk7CglyZXR1cm4gMS4wIC0gc21vb3Roc3RlcCgxLjAgLSBibHVyX2hhbGYsIDEuMCArIGJsdXJfaGFsZiwgZCAvIHJhZGl1cyk7Cn0KZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfY2lyY2xlX2dyaWRfUzFfYzAoZmxvYXQyIHJlc29sdXRpb24sIGlub3V0IGZsb2F0MiBwLCBmbG9hdDIgeHksIGZsb2F0MiByb3RhdGlvbiwgZmxvYXQgY2VsbF9kaWFtZXRlcikgCnsKCWZsb2F0MiBwYXJhbSA9IHJvdGF0aW9uOwoJcCA9IEZMVF9mbHV0dGVyX2xvY2FsX3JvdGF0ZTJkX1MxX2MwKHBhcmFtKSAqICh4eSAtIHApICsgeHk7CglwID0gbW9kKHAsIGZsb2F0MihjZWxsX2RpYW1ldGVyKSkgLyByZXNvbHV0aW9uOwoJZmxvYXQgY2VsbF91diA9IChjZWxsX2RpYW1ldGVyIC8gcmVzb2x1dGlvbi55KSAqIDAuNTsKCWZsb2F0IHIgPSAwLjY1ICogY2VsbF91djsKCWZsb2F0MiBwYXJhbV8xID0gcDsKCWZsb2F0MiBwYXJhbV8yID0gZmxvYXQyKGNlbGxfdXYpOwoJZmxvYXQgcGFyYW1fMyA9IHI7CglmbG9hdCBwYXJhbV80ID0gciAqIDUwLjA7CglyZXR1cm4gRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9jaXJjbGVfUzFfYzAocGFyYW1fMSwgcGFyYW1fMiwgcGFyYW1fMywgcGFyYW1fNCk7Cn0KZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfdHVyYnVsZW5jZV9TMV9jMChmbG9hdDIgdXYpIAp7CglmbG9hdDIgdXZfc2NhbGUgPSB1diAqIGZsb2F0MigwLjgpOwoJZmxvYXQyIHBhcmFtID0gZmxvYXQyKDAuOCk7CglmbG9hdDIgcGFyYW1fMSA9IHV2X3NjYWxlOwoJZmxvYXQyIHBhcmFtXzIgPSB1X2NpcmNsZTFfUzFfYzA7CglmbG9hdDIgcGFyYW1fMyA9IHVfcm90YXRpb24xX1MxX2MwOwoJZmxvYXQgcGFyYW1fNCA9IDAuMTc7CglmbG9hdCBfMzE5ID0gRkxUX2ZsdXR0ZXJfbG9jYWxfY2lyY2xlX2dyaWRfUzFfYzAocGFyYW0sIHBhcmFtXzEsIHBhcmFtXzIsIHBhcmFtXzMsIHBhcmFtXzQpOwoJZmxvYXQgZzEgPSBfMzE5OwoJZmxvYXQyIHBhcmFtXzUgPSBmbG9hdDIoMC44KTsKCWZsb2F0MiBwYXJhbV82ID0gdXZfc2NhbGU7CglmbG9hdDIgcGFyYW1fNyA9IHVfY2lyY2xlMl9TMV9jMDsKCWZsb2F0MiBwYXJhbV84ID0gdV9yb3RhdGlvbjJfUzFfYzA7CglmbG9hdCBwYXJhbV85ID0gMC4yOwoJZmxvYXQgXzMzMSA9IEZMVF9mbHV0dGVyX2xvY2FsX2NpcmNsZV9ncmlkX1MxX2MwKHBhcmFtXzUsIHBhcmFtXzYsIHBhcmFtXzcsIHBhcmFtXzgsIHBhcmFtXzkpOwoJZmxvYXQgZzIgPSBfMzMxOwoJZmxvYXQyIHBhcmFtXzEwID0gZmxvYXQyKDAuOCk7CglmbG9hdDIgcGFyYW1fMTEgPSB1dl9zY2FsZTsKCWZsb2F0MiBwYXJhbV8xMiA9IHVfY2lyY2xlM19TMV9jMDsKCWZsb2F0MiBwYXJhbV8xMyA9IHVfcm90YXRpb24zX1MxX2MwOwoJZmxvYXQgcGFyYW1fMTQgPSAwLjI3NTsKCWZsb2F0IF8zNDQgPSBGTFRfZmx1dHRlcl9sb2NhbF9jaXJjbGVfZ3JpZF9TMV9jMChwYXJhbV8xMCwgcGFyYW1fMTEsIHBhcmFtXzEyLCBwYXJhbV8xMywgcGFyYW1fMTQpOwoJZmxvYXQgZzMgPSBfMzQ0OwoJZmxvYXQgdiA9ICgoZzEgKiBnMSArIGcyKSAtIGczKSAqIDAuNTsKCXJldHVybiBjbGFtcCgwLjQ1ICsgMC44ICogdiwgMC4wLCAxLjApOwp9CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfcmluZ19TMV9jMChmbG9hdDIgdXYsIGZsb2F0MiB4eSwgZmxvYXQgcmFkaXVzLCBmbG9hdCB0aGlja25lc3MsIGZsb2F0IGJsdXIpIAp7CglmbG9hdDIgcGFyYW0gPSB1djsKCWZsb2F0MiBwYXJhbV8xID0geHk7CglmbG9hdCBwYXJhbV8yID0gcmFkaXVzICsgdGhpY2tuZXNzOwoJZmxvYXQgcGFyYW1fMyA9IGJsdXI7CglmbG9hdCBjaXJjbGVfb3V0ZXIgPSBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X2NpcmNsZV9TMV9jMChwYXJhbSwgcGFyYW1fMSwgcGFyYW1fMiwgcGFyYW1fMyk7CglmbG9hdDIgcGFyYW1fNCA9IHV2OwoJZmxvYXQyIHBhcmFtXzUgPSB4eTsKCWZsb2F0IHBhcmFtXzYgPSBtYXgocmFkaXVzIC0gdGhpY2tuZXNzLCAwLjApOwoJZmxvYXQgcGFyYW1fNyA9IGJsdXI7CglmbG9hdCBjaXJjbGVfaW5uZXIgPSBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X2NpcmNsZV9TMV9jMChwYXJhbV80LCBwYXJhbV81LCBwYXJhbV82LCBwYXJhbV83KTsKCXJldHVybiBjbGFtcChjaXJjbGVfb3V0ZXIgLSBjaXJjbGVfaW5uZXIsIDAuMCwgMS4wKTsKfQpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF90cmlhbmdsZV9ub2lzZV9TMV9jMChpbm91dCBmbG9hdDIgbikgCnsKCW4gPSBmcmFjdChuICogZmxvYXQyKDUuMzk4NywgNS40NDIxKSk7CgluICs9IGZsb2F0Mihkb3Qobi55eCwgbiArIGZsb2F0MigyMS41MzUxLCAxNC4zMTM3KSkpOwoJZmxvYXQgeHkgPSBuLnggKiBuLnk7CglyZXR1cm4gKGZyYWN0KHh5ICogOTUuNDMwNykgKyBmcmFjdCh4eSAqIDc1LjA0OTYxKSkgLSAxLjA7Cn0KZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfdGhyZXNob2xkX1MxX2MwKGZsb2F0IHYsIGZsb2F0IGwsIGZsb2F0IGgpIAp7CglyZXR1cm4gc3RlcChsLCB2KSAqICgxLjAgLSBzdGVwKGgsIHYpKTsKfQpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9zcGFya2xlX1MxX2MwKGZsb2F0MiB1diwgZmxvYXQgdCkgCnsKCWZsb2F0MiBwYXJhbSA9IHV2OwoJZmxvYXQgXzI0MiA9IEZMVF9mbHV0dGVyX2xvY2FsX3RyaWFuZ2xlX25vaXNlX1MxX2MwKHBhcmFtKTsKCWZsb2F0IG4gPSBfMjQyOwoJZmxvYXQgcGFyYW1fMSA9IG47CglmbG9hdCBwYXJhbV8yID0gMC4wOwoJZmxvYXQgcGFyYW1fMyA9IDAuMDU7CglmbG9hdCBzID0gRkxUX2ZsdXR0ZXJfbG9jYWxfdGhyZXNob2xkX1MxX2MwKHBhcmFtXzEsIHBhcmFtXzIsIHBhcmFtXzMpOwoJZmxvYXQgcGFyYW1fNCA9IG4gKyBzaW4oMy4xNDE1OTI3NCAqICh0ICsgMC4zNSkpOwoJZmxvYXQgcGFyYW1fNSA9IDAuMTsKCWZsb2F0IHBhcmFtXzYgPSAwLjE1OwoJcyArPSBGTFRfZmx1dHRlcl9sb2NhbF90aHJlc2hvbGRfUzFfYzAocGFyYW1fNCwgcGFyYW1fNSwgcGFyYW1fNik7CglmbG9hdCBwYXJhbV83ID0gbiArIHNpbigzLjE0MTU5Mjc0ICogKHQgKyAwLjcpKTsKCWZsb2F0IHBhcmFtXzggPSAwLjI7CglmbG9hdCBwYXJhbV85ID0gMC4yNTsKCXMgKz0gRkxUX2ZsdXR0ZXJfbG9jYWxfdGhyZXNob2xkX1MxX2MwKHBhcmFtXzcsIHBhcmFtXzgsIHBhcmFtXzkpOwoJZmxvYXQgcGFyYW1fMTAgPSBuICsgc2luKDMuMTQxNTkyNzQgKiAodCArIDEuMDUpKTsKCWZsb2F0IHBhcmFtXzExID0gMC4zOwoJZmxvYXQgcGFyYW1fMTIgPSAwLjM1OwoJcyArPSBGTFRfZmx1dHRlcl9sb2NhbF90aHJlc2hvbGRfUzFfYzAocGFyYW1fMTAsIHBhcmFtXzExLCBwYXJhbV8xMik7CglyZXR1cm4gY2xhbXAocywgMC4wLCAxLjApICogMC41NTsKfQp2b2lkIEZMVF9tYWluX1MxX2MwKCkgCnsKCXVfYWxwaGFfUzFfYzAgPSB1X2NvbXBvc2l0ZV8xX1MxX2MwLng7Cgl1X3NwYXJrbGVfYWxwaGFfUzFfYzAgPSB1X2NvbXBvc2l0ZV8xX1MxX2MwLnk7Cgl1X2JsdXJfUzFfYzAgPSB1X2NvbXBvc2l0ZV8xX1MxX2MwLno7Cgl1X3JhZGl1c19zY2FsZV9TMV9jMCA9IHVfY29tcG9zaXRlXzFfUzFfYzAudzsKCWZsb2F0MiBwID0gRkxUX2ZsdXR0ZXJfbG9jYWxfRmx1dHRlckZyYWdDb29yZF9TMV9jMCgpOwoJZmxvYXQyIHV2XzEgPSBwICogdV9yZXNvbHV0aW9uX3NjYWxlX1MxX2MwOwoJZmxvYXQyIGRlbnNpdHlfdXYgPSB1dl8xIC0gbW9kKHAsIHVfbm9pc2Vfc2NhbGVfUzFfYzApOwoJZmxvYXQgcmFkaXVzID0gdV9tYXhfcmFkaXVzX1MxX2MwICogdV9yYWRpdXNfc2NhbGVfUzFfYzA7CglmbG9hdDIgcGFyYW1fMTMgPSB1dl8xOwoJZmxvYXQgdHVyYnVsZW5jZSA9IEZMVF9mbHV0dGVyX2xvY2FsX3R1cmJ1bGVuY2VfUzFfYzAocGFyYW1fMTMpOwoJZmxvYXQyIHBhcmFtXzE0ID0gcDsKCWZsb2F0MiBwYXJhbV8xNSA9IHVfY2VudGVyX1MxX2MwOwoJZmxvYXQgcGFyYW1fMTYgPSByYWRpdXM7CglmbG9hdCBwYXJhbV8xNyA9IDAuMDUgKiB1X21heF9yYWRpdXNfUzFfYzA7CglmbG9hdCBwYXJhbV8xOCA9IHVfYmx1cl9TMV9jMDsKCWZsb2F0IHJpbmcgPSBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X3JpbmdfUzFfYzAocGFyYW1fMTQsIHBhcmFtXzE1LCBwYXJhbV8xNiwgcGFyYW1fMTcsIHBhcmFtXzE4KTsKCWZsb2F0MiBwYXJhbV8xOSA9IGRlbnNpdHlfdXY7CglmbG9hdCBwYXJhbV8yMCA9IHVfbm9pc2VfcGhhc2VfUzFfYzA7CglmbG9hdCBzcGFya2xlID0gKChGTFRfZmx1dHRlcl9sb2NhbF9zcGFya2xlX1MxX2MwKHBhcmFtXzE5LCBwYXJhbV8yMCkgKiByaW5nKSAqIHR1cmJ1bGVuY2UpICogdV9zcGFya2xlX2FscGhhX1MxX2MwOwoJZmxvYXQyIHBhcmFtXzIxID0gcDsKCWZsb2F0MiBwYXJhbV8yMiA9IHVfY2VudGVyX1MxX2MwOwoJZmxvYXQgcGFyYW1fMjMgPSByYWRpdXM7CglmbG9hdCBwYXJhbV8yNCA9IHVfYmx1cl9TMV9jMDsKCWZsb2F0IHdhdmVfYWxwaGEgPSAoRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9jaXJjbGVfUzFfYzAocGFyYW1fMjEsIHBhcmFtXzIyLCBwYXJhbV8yMywgcGFyYW1fMjQpICogdV9hbHBoYV9TMV9jMCkgKiB1X2NvbG9yX1MxX2MwLnc7CglmbG9hdDQgd2F2ZV9jb2xvciA9IGZsb2F0NCh1X2NvbG9yX1MxX2MwLnh5eiAqIHdhdmVfYWxwaGEsIHdhdmVfYWxwaGEpOwoJZnJhZ0NvbG9yX1MxX2MwID0gbWl4KHdhdmVfY29sb3IsIGZsb2F0NCgxLjApLCBmbG9hdDQoc3BhcmtsZSkpOwp9CmhhbGY0IHJ1bnRpbWVfc2hhZGVyX1MxX2MwKGhhbGY0IF9pbnB1dCkgCnsKCWhhbGY0IF90bXBfMF9pbkNvbG9yID0gX2lucHV0OwoJZmxvYXQyIF90bXBfMV9jb29yZHMgPSB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKCWZsdXR0ZXJfRnJhZ0Nvb3JkX1MxX2MwID0gZmxvYXQ0KF90bXBfMV9jb29yZHMsIDAuMCwgMC4wKTsKCUZMVF9tYWluX1MxX2MwKCk7CglyZXR1cm4gaGFsZjQoaGFsZjQoZnJhZ0NvbG9yX1MxX2MwKSk7Cn0KaGFsZjQgTWF0cml4RWZmZWN0X1MxKGhhbGY0IF9pbnB1dCkgCnsKCXJldHVybiBydW50aW1lX3NoYWRlcl9TMV9jMChfaW5wdXQpOwp9CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2Y29sb3JfUzA7CglmbG9hdCBjb3ZlcmFnZSA9IHZjb3ZlcmFnZV9TMDsKCWhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoaGFsZihjb3ZlcmFnZSkpOwoJaGFsZjQgb3V0cHV0X1MxOwoJb3V0cHV0X1MxID0gTWF0cml4RWZmZWN0X1MxKG91dHB1dENvbG9yX1MwKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRfUzEgKiBvdXRwdXRDb3ZlcmFnZV9TMDsKCX0KfQoAAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAEAAAACAAAAHBvc2l0aW9uCAAAAGNvdmVyYWdlBQAAAGNvbG9yAAAACgAAAGxvY2FsQ29vcmQAAAAAAAA=","HWJQAAAAABEAADAAAIOAAAAADIIAB7X7777QGHAYAD7P7777A4QCQAAAAAAAAAQAAAAAAQQGACQAGAAAAAQAAAAAAAQQGAAA":"DAAAAExTS1OaAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gZmxvYXQgY292ZXJhZ2U7CmluIGZsb2F0MiBsb2NhbENvb3JkOwppbiBmbG9hdDQgdGV4U3Vic2V0OwpvdXQgZmxvYXQyIHZsb2NhbENvb3JkX1MwOwpmbGF0IG91dCBmbG9hdDQgdnRleFN1YnNldF9TMDsKb3V0IGZsb2F0IHZjb3ZlcmFnZV9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCglmbG9hdDIgcG9zaXRpb24gPSBwb3NpdGlvbi54eTsKCXZsb2NhbENvb3JkX1MwID0gbG9jYWxDb29yZDsKCXZ0ZXhTdWJzZXRfUzAgPSB0ZXhTdWJzZXQ7Cgl2Y292ZXJhZ2VfUzAgPSBjb3ZlcmFnZTsKCXNrX1Bvc2l0aW9uID0gcG9zaXRpb24ueHkwMTsKfQoAAAAAAABcAgAAc2FtcGxlcjJEIHVUZXh0dXJlU2FtcGxlcl8wX1MwOwppbiBmbG9hdDIgdmxvY2FsQ29vcmRfUzA7CmZsYXQgaW4gZmxvYXQ0IHZ0ZXhTdWJzZXRfUzA7CmluIGZsb2F0IHZjb3ZlcmFnZV9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJaGFsZjQgb3V0cHV0Q29sb3JfUzAgPSBoYWxmNCgxKTsKCWZsb2F0MiB0ZXhDb29yZDsKCXRleENvb3JkID0gdmxvY2FsQ29vcmRfUzA7CglmbG9hdDQgc3Vic2V0OwoJc3Vic2V0ID0gdnRleFN1YnNldF9TMDsKCXRleENvb3JkID0gY2xhbXAodGV4Q29vcmQsIHN1YnNldC5MVCwgc3Vic2V0LlJCKTsKCW91dHB1dENvbG9yX1MwID0gKGJsZW5kX21vZHVsYXRlKHNhbXBsZSh1VGV4dHVyZVNhbXBsZXJfMF9TMCwgdGV4Q29vcmQpLCBoYWxmNCgxKSkpOwoJZmxvYXQgY292ZXJhZ2UgPSB2Y292ZXJhZ2VfUzA7CgloYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KGhhbGYoY292ZXJhZ2UpKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dENvdmVyYWdlX1MwOwoJfQp9CgAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAEAAAACAAAAHBvc2l0aW9uCAAAAGNvdmVyYWdlCgAAAGxvY2FsQ29vcmQAAAkAAAB0ZXhTdWJzZXQAAAAAAAAA","AYQA5AADQAAAOAEARAFQJAABBADIB7777777777777777777777767YAAAAAAAAAACABZQA6AAAEAAAAAAAIADQAAAAIAAAAAAAIIDA":"DAAAAExTS1PMAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQ0IHVsb2NhbE1hdHJpeF9TMDsKaW4gZmxvYXQyIGluUG9zaXRpb247CmluIGhhbGY0IGluQ29sb3I7CmluIGZsb2F0NCBpbkNpcmNsZUVkZ2U7Cm91dCBmbG9hdDQgdmluQ2lyY2xlRWRnZV9TMDsKb3V0IGhhbGY0IHZpbkNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBDaXJjbGVHZW9tZXRyeVByb2Nlc3NvcgoJdmluQ2lyY2xlRWRnZV9TMCA9IGluQ2lyY2xlRWRnZTsKCXZpbkNvbG9yX1MwID0gaW5Db2xvcjsKCWZsb2F0MiBfdG1wXzBfaW5Qb3NpdGlvbiA9IGluUG9zaXRpb247CglmbG9hdDIgX3RtcF8xX2luUG9zaXRpb24gPSB1bG9jYWxNYXRyaXhfUzAueHogKiBpblBvc2l0aW9uICsgdWxvY2FsTWF0cml4X1MwLnl3OwoJc2tfUG9zaXRpb24gPSBfdG1wXzBfaW5Qb3NpdGlvbi54eTAxOwp9CgEAAACPAwAAdW5pZm9ybSBmbG9hdDQgdWlubmVyUmVjdF9TMTsKdW5pZm9ybSBoYWxmMiB1cmFkaXVzUGx1c0hhbGZfUzE7CmluIGZsb2F0NCB2aW5DaXJjbGVFZGdlX1MwOwppbiBoYWxmNCB2aW5Db2xvcl9TMDsKaGFsZjQgQ2lyY3VsYXJSUmVjdF9TMShoYWxmNCBfaW5wdXQpIAp7CglmbG9hdDIgZHh5MCA9IHVpbm5lclJlY3RfUzEuTFQgLSBza19GcmFnQ29vcmQueHk7CglmbG9hdDIgZHh5MSA9IHNrX0ZyYWdDb29yZC54eSAtIHVpbm5lclJlY3RfUzEuUkI7CglmbG9hdDIgZHh5ID0gbWF4KG1heChkeHkwLCBkeHkxKSwgMC4wKTsKCWhhbGYgYWxwaGEgPSBoYWxmKHNhdHVyYXRlKHVyYWRpdXNQbHVzSGFsZl9TMS54IC0gbGVuZ3RoKGR4eSkpKTsKCWFscGhhID0gMS4wIC0gYWxwaGE7CglyZXR1cm4gX2lucHV0ICogYWxwaGE7Cn0Kdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIENpcmNsZUdlb21ldHJ5UHJvY2Vzc29yCglmbG9hdDQgY2lyY2xlRWRnZTsKCWNpcmNsZUVkZ2UgPSB2aW5DaXJjbGVFZGdlX1MwOwoJaGFsZjQgb3V0cHV0Q29sb3JfUzA7CglvdXRwdXRDb2xvcl9TMCA9IHZpbkNvbG9yX1MwOwoJZmxvYXQgZCA9IGxlbmd0aChjaXJjbGVFZGdlLnh5KTsKCWhhbGYgZGlzdGFuY2VUb091dGVyRWRnZSA9IGhhbGYoY2lyY2xlRWRnZS56ICogKDEuMCAtIGQpKTsKCWhhbGYgZWRnZUFscGhhID0gc2F0dXJhdGUoZGlzdGFuY2VUb091dGVyRWRnZSk7CgloYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KGVkZ2VBbHBoYSk7CgloYWxmNCBvdXRwdXRfUzE7CglvdXRwdXRfUzEgPSBDaXJjdWxhclJSZWN0X1MxKG91dHB1dENvdmVyYWdlX1MwKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dF9TMTsKCX0KfQoAAQAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAKAAAAaW5Qb3NpdGlvbgAABwAAAGluQ29sb3IADAAAAGluQ2lyY2xlRWRnZQAAAAA=","AYTRVAADQAAAOAEARAFQJAABBADAAAILBYAACCYUQD777777777767YAAAAAAAAAAAAOQAAAAAAAQAAAABAMQAAAAA":"DAAAAExTS1NyAgAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQ0IHVsb2NhbE1hdHJpeF9TMDsKaW4gZmxvYXQyIGluUG9zaXRpb247CmluIGhhbGY0IGluQ29sb3I7CmluIGZsb2F0NCBpbkNpcmNsZUVkZ2U7CmluIGhhbGYzIGluQ2xpcFBsYW5lOwppbiBoYWxmMyBpbklzZWN0UGxhbmU7Cm91dCBmbG9hdDQgdmluQ2lyY2xlRWRnZV9TMDsKb3V0IGhhbGYzIHZpbkNsaXBQbGFuZV9TMDsKb3V0IGhhbGYzIHZpbklzZWN0UGxhbmVfUzA7Cm91dCBoYWxmNCB2aW5Db2xvcl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgQ2lyY2xlR2VvbWV0cnlQcm9jZXNzb3IKCXZpbkNpcmNsZUVkZ2VfUzAgPSBpbkNpcmNsZUVkZ2U7Cgl2aW5DbGlwUGxhbmVfUzAgPSBpbkNsaXBQbGFuZTsKCXZpbklzZWN0UGxhbmVfUzAgPSBpbklzZWN0UGxhbmU7Cgl2aW5Db2xvcl9TMCA9IGluQ29sb3I7CglmbG9hdDIgX3RtcF8wX2luUG9zaXRpb24gPSBpblBvc2l0aW9uOwoJZmxvYXQyIF90bXBfMV9pblBvc2l0aW9uID0gdWxvY2FsTWF0cml4X1MwLnh6ICogaW5Qb3NpdGlvbiArIHVsb2NhbE1hdHJpeF9TMC55dzsKCXNrX1Bvc2l0aW9uID0gX3RtcF8wX2luUG9zaXRpb24ueHkwMTsKfQoAAAAAAADdAwAAaW4gZmxvYXQ0IHZpbkNpcmNsZUVkZ2VfUzA7CmluIGhhbGYzIHZpbkNsaXBQbGFuZV9TMDsKaW4gaGFsZjMgdmluSXNlY3RQbGFuZV9TMDsKaW4gaGFsZjQgdmluQ29sb3JfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBDaXJjbGVHZW9tZXRyeVByb2Nlc3NvcgoJZmxvYXQ0IGNpcmNsZUVkZ2U7CgljaXJjbGVFZGdlID0gdmluQ2lyY2xlRWRnZV9TMDsKCWhhbGYzIGNsaXBQbGFuZTsKCWNsaXBQbGFuZSA9IHZpbkNsaXBQbGFuZV9TMDsKCWhhbGYzIGlzZWN0UGxhbmU7Cglpc2VjdFBsYW5lID0gdmluSXNlY3RQbGFuZV9TMDsKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2aW5Db2xvcl9TMDsKCWZsb2F0IGQgPSBsZW5ndGgoY2lyY2xlRWRnZS54eSk7CgloYWxmIGRpc3RhbmNlVG9PdXRlckVkZ2UgPSBoYWxmKGNpcmNsZUVkZ2UueiAqICgxLjAgLSBkKSk7CgloYWxmIGVkZ2VBbHBoYSA9IHNhdHVyYXRlKGRpc3RhbmNlVG9PdXRlckVkZ2UpOwoJaGFsZiBkaXN0YW5jZVRvSW5uZXJFZGdlID0gaGFsZihjaXJjbGVFZGdlLnogKiAoZCAtIGNpcmNsZUVkZ2UudykpOwoJaGFsZiBpbm5lckFscGhhID0gc2F0dXJhdGUoZGlzdGFuY2VUb0lubmVyRWRnZSk7CgllZGdlQWxwaGEgKj0gaW5uZXJBbHBoYTsKCWhhbGYgY2xpcCA9IGhhbGYoc2F0dXJhdGUoY2lyY2xlRWRnZS56ICogZG90KGNpcmNsZUVkZ2UueHksIGNsaXBQbGFuZS54eSkgKyBjbGlwUGxhbmUueikpOwoJY2xpcCAqPSBoYWxmKHNhdHVyYXRlKGNpcmNsZUVkZ2UueiAqIGRvdChjaXJjbGVFZGdlLnh5LCBpc2VjdFBsYW5lLnh5KSArIGlzZWN0UGxhbmUueikpOwoJZWRnZUFscGhhICo9IGNsaXA7CgloYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KGVkZ2VBbHBoYSk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRDb3ZlcmFnZV9TMDsKCX0KfQoAAAAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAABQAAAAoAAABpblBvc2l0aW9uAAAHAAAAaW5Db2xvcgAMAAAAaW5DaXJjbGVFZGdlCwAAAGluQ2xpcFBsYW5lAAwAAABpbklzZWN0UGxhbmUAAAAA","AYQA5AADQAAAOAEARAFQJAABBADIB7777777777777777777777767YAAAAAAAAAAAAOQAAAAAAAQAAAABAMQAAAAA":"DAAAAExTS1PMAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQ0IHVsb2NhbE1hdHJpeF9TMDsKaW4gZmxvYXQyIGluUG9zaXRpb247CmluIGhhbGY0IGluQ29sb3I7CmluIGZsb2F0NCBpbkNpcmNsZUVkZ2U7Cm91dCBmbG9hdDQgdmluQ2lyY2xlRWRnZV9TMDsKb3V0IGhhbGY0IHZpbkNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBDaXJjbGVHZW9tZXRyeVByb2Nlc3NvcgoJdmluQ2lyY2xlRWRnZV9TMCA9IGluQ2lyY2xlRWRnZTsKCXZpbkNvbG9yX1MwID0gaW5Db2xvcjsKCWZsb2F0MiBfdG1wXzBfaW5Qb3NpdGlvbiA9IGluUG9zaXRpb247CglmbG9hdDIgX3RtcF8xX2luUG9zaXRpb24gPSB1bG9jYWxNYXRyaXhfUzAueHogKiBpblBvc2l0aW9uICsgdWxvY2FsTWF0cml4X1MwLnl3OwoJc2tfUG9zaXRpb24gPSBfdG1wXzBfaW5Qb3NpdGlvbi54eTAxOwp9CgAAAADqAQAAaW4gZmxvYXQ0IHZpbkNpcmNsZUVkZ2VfUzA7CmluIGhhbGY0IHZpbkNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgQ2lyY2xlR2VvbWV0cnlQcm9jZXNzb3IKCWZsb2F0NCBjaXJjbGVFZGdlOwoJY2lyY2xlRWRnZSA9IHZpbkNpcmNsZUVkZ2VfUzA7CgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmluQ29sb3JfUzA7CglmbG9hdCBkID0gbGVuZ3RoKGNpcmNsZUVkZ2UueHkpOwoJaGFsZiBkaXN0YW5jZVRvT3V0ZXJFZGdlID0gaGFsZihjaXJjbGVFZGdlLnogKiAoMS4wIC0gZCkpOwoJaGFsZiBlZGdlQWxwaGEgPSBzYXR1cmF0ZShkaXN0YW5jZVRvT3V0ZXJFZGdlKTsKCWhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoZWRnZUFscGhhKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dENvdmVyYWdlX1MwOwoJfQp9CgAAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAKAAAAaW5Qb3NpdGlvbgAABwAAAGluQ29sb3IADAAAAGluQ2lyY2xlRWRnZQAAAAA=","HUIAAAAAAAQAADAAAIOAAAH677777777777QGHAQAD7P7777777777YBAAAAAAAAAAALUAQBAEAQAAAAGQCBAMQACAIAAAAAACQAGAAAAAQAAAAAAAQQGAAAAA":"DAAAAExTS1M2AQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMTsKaW4gZmxvYXQyIHBvc2l0aW9uOwppbiBmbG9hdDIgbG9jYWxDb29yZDsKb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCglza19Qb3NpdGlvbiA9IHBvc2l0aW9uLnh5MDE7Cgl7CgkJdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzAgPSBmbG9hdDN4Mih1bWF0cml4X1MxKSAqIGxvY2FsQ29vcmQueHkxOwoJfQp9CgAAAAAAAEUDAAB1bmlmb3JtIGZsb2F0NCB1Y2xhbXBfUzFfYzA7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMTsKc2FtcGxlcjJEIHVUZXh0dXJlU2FtcGxlcl8wX1MxOwppbiBmbG9hdDIgdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzA7CmhhbGY0IFRleHR1cmVFZmZlY3RfUzFfYzAoaGFsZjQgX2lucHV0KSAKewoJZmxvYXQyIGluQ29vcmQgPSB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKCWZsb2F0MiBzdWJzZXRDb29yZDsKCXN1YnNldENvb3JkLnggPSBpbkNvb3JkLng7CglzdWJzZXRDb29yZC55ID0gaW5Db29yZC55OwoJZmxvYXQyIGNsYW1wZWRDb29yZDsKCWNsYW1wZWRDb29yZCA9IGNsYW1wKHN1YnNldENvb3JkLCB1Y2xhbXBfUzFfYzAueHksIHVjbGFtcF9TMV9jMC56dyk7CgloYWxmNCB0ZXh0dXJlQ29sb3IgPSBzYW1wbGUodVRleHR1cmVTYW1wbGVyXzBfUzEsIGNsYW1wZWRDb29yZCk7CglyZXR1cm4gdGV4dHVyZUNvbG9yOwp9CmhhbGY0IE1hdHJpeEVmZmVjdF9TMShoYWxmNCBfaW5wdXQpIAp7CglyZXR1cm4gVGV4dHVyZUVmZmVjdF9TMV9jMChfaW5wdXQpOwp9CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwID0gaGFsZjQoMSk7Cgljb25zdCBoYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KDEpOwoJaGFsZjQgb3V0cHV0X1MxOwoJb3V0cHV0X1MxID0gTWF0cml4RWZmZWN0X1MxKG91dHB1dENvbG9yX1MwKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRfUzEgKiBvdXRwdXRDb3ZlcmFnZV9TMDsKCX0KfQoAAAAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAgAAABwb3NpdGlvbgoAAABsb2NhbENvb3JkAAAAAAAA","HVIAAAAAABIAAGAAAQ4AAAH477776R24EAAAIOBQAD6P7777777777YDAAAAAAAAAAAHQBNGZODK5YIAAAAAAQAAAAAIADCNS4GV3QYBAAAAAAAAAAAIAA6IAMAAACAAAAAABUABAAAAAEAAAAAIBEABAA":"DAAAAExTS1N0AQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMTsKaW4gZmxvYXQyIHBvc2l0aW9uOwppbiBoYWxmNCBjb2xvcjsKaW4gZmxvYXQyIGxvY2FsQ29vcmQ7CmZsYXQgb3V0IGhhbGY0IHZjb2xvcl9TMDsKb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgl2Y29sb3JfUzAgPSBjb2xvcjsKCXNrX1Bvc2l0aW9uID0gcG9zaXRpb24ueHkwMTsKCXsKCQl2VHJhbnNmb3JtZWRDb29yZHNfMl9TMCA9IGZsb2F0M3gyKHVtYXRyaXhfUzEpICogbG9jYWxDb29yZC54eTE7Cgl9Cn0KAQAAABsdAABmbG9hdDQgZmx1dHRlcl9GcmFnQ29vcmRfUzFfYzA7CmZsb2F0NCBmcmFnQ29sb3JfUzFfYzA7CmZsb2F0IHVfYWxwaGFfUzFfYzA7CmZsb2F0IHVfc3BhcmtsZV9hbHBoYV9TMV9jMDsKZmxvYXQgdV9ibHVyX1MxX2MwOwpmbG9hdCB1X3JhZGl1c19zY2FsZV9TMV9jMDsKdW5pZm9ybSBmbG9hdDQgdV9jb2xvcl9TMV9jMDsKdW5pZm9ybSBmbG9hdDQgdV9jb21wb3NpdGVfMV9TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9jZW50ZXJfUzFfYzA7CnVuaWZvcm0gZmxvYXQgdV9tYXhfcmFkaXVzX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X3Jlc29sdXRpb25fc2NhbGVfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfbm9pc2Vfc2NhbGVfUzFfYzA7CnVuaWZvcm0gZmxvYXQgdV9ub2lzZV9waGFzZV9TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9jaXJjbGUxX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X2NpcmNsZTJfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfY2lyY2xlM19TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9yb3RhdGlvbjFfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfcm90YXRpb24yX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X3JvdGF0aW9uM19TMV9jMDsKdW5pZm9ybSBmbG9hdDN4MyB1bWF0cml4X1MxOwp1bmlmb3JtIGZsb2F0NCB1aW5uZXJSZWN0X1MyOwp1bmlmb3JtIGhhbGYyIHVyYWRpdXNQbHVzSGFsZl9TMjsKZmxhdCBpbiBoYWxmNCB2Y29sb3JfUzA7CmluIGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKZmxvYXQyIEZMVF9mbHV0dGVyX2xvY2FsX0ZsdXR0ZXJGcmFnQ29vcmRfUzFfYzAoKTsKZmxvYXQyeDIgRkxUX2ZsdXR0ZXJfbG9jYWxfcm90YXRlMmRfUzFfYzAoZmxvYXQyIHJhZCk7CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfY2lyY2xlX1MxX2MwKGZsb2F0MiB1diwgZmxvYXQyIHh5LCBmbG9hdCByYWRpdXMsIGZsb2F0IGJsdXIpOwpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9jaXJjbGVfZ3JpZF9TMV9jMChmbG9hdDIgcmVzb2x1dGlvbiwgaW5vdXQgZmxvYXQyIHAsIGZsb2F0MiB4eSwgZmxvYXQyIHJvdGF0aW9uLCBmbG9hdCBjZWxsX2RpYW1ldGVyKTsKZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfdHVyYnVsZW5jZV9TMV9jMChmbG9hdDIgdXYpOwpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X3JpbmdfUzFfYzAoZmxvYXQyIHV2LCBmbG9hdDIgeHksIGZsb2F0IHJhZGl1cywgZmxvYXQgdGhpY2tuZXNzLCBmbG9hdCBibHVyKTsKZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfdHJpYW5nbGVfbm9pc2VfUzFfYzAoaW5vdXQgZmxvYXQyIG4pOwpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF90aHJlc2hvbGRfUzFfYzAoZmxvYXQgdiwgZmxvYXQgbCwgZmxvYXQgaCk7CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3NwYXJrbGVfUzFfYzAoZmxvYXQyIHV2LCBmbG9hdCB0KTsKdm9pZCBGTFRfbWFpbl9TMV9jMCgpOwpmbG9hdDIgRkxUX2ZsdXR0ZXJfbG9jYWxfRmx1dHRlckZyYWdDb29yZF9TMV9jMCgpIAp7CglyZXR1cm4gZmx1dHRlcl9GcmFnQ29vcmRfUzFfYzAueHk7Cn0KZmxvYXQyeDIgRkxUX2ZsdXR0ZXJfbG9jYWxfcm90YXRlMmRfUzFfYzAoZmxvYXQyIHJhZCkgCnsKCXJldHVybiBmbG9hdDJ4MihyYWQueCwgLXJhZC55LCByYWQueSwgcmFkLngpOwp9CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfY2lyY2xlX1MxX2MwKGZsb2F0MiB1diwgZmxvYXQyIHh5LCBmbG9hdCByYWRpdXMsIGZsb2F0IGJsdXIpIAp7CglmbG9hdCBibHVyX2hhbGYgPSBibHVyICogMC41OwoJZmxvYXQgZCA9IGRpc3RhbmNlKHV2LCB4eSk7CglyZXR1cm4gMS4wIC0gc21vb3Roc3RlcCgxLjAgLSBibHVyX2hhbGYsIDEuMCArIGJsdXJfaGFsZiwgZCAvIHJhZGl1cyk7Cn0KZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfY2lyY2xlX2dyaWRfUzFfYzAoZmxvYXQyIHJlc29sdXRpb24sIGlub3V0IGZsb2F0MiBwLCBmbG9hdDIgeHksIGZsb2F0MiByb3RhdGlvbiwgZmxvYXQgY2VsbF9kaWFtZXRlcikgCnsKCWZsb2F0MiBwYXJhbSA9IHJvdGF0aW9uOwoJcCA9IEZMVF9mbHV0dGVyX2xvY2FsX3JvdGF0ZTJkX1MxX2MwKHBhcmFtKSAqICh4eSAtIHApICsgeHk7CglwID0gbW9kKHAsIGZsb2F0MihjZWxsX2RpYW1ldGVyKSkgLyByZXNvbHV0aW9uOwoJZmxvYXQgY2VsbF91diA9IChjZWxsX2RpYW1ldGVyIC8gcmVzb2x1dGlvbi55KSAqIDAuNTsKCWZsb2F0IHIgPSAwLjY1ICogY2VsbF91djsKCWZsb2F0MiBwYXJhbV8xID0gcDsKCWZsb2F0MiBwYXJhbV8yID0gZmxvYXQyKGNlbGxfdXYpOwoJZmxvYXQgcGFyYW1fMyA9IHI7CglmbG9hdCBwYXJhbV80ID0gciAqIDUwLjA7CglyZXR1cm4gRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9jaXJjbGVfUzFfYzAocGFyYW1fMSwgcGFyYW1fMiwgcGFyYW1fMywgcGFyYW1fNCk7Cn0KZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfdHVyYnVsZW5jZV9TMV9jMChmbG9hdDIgdXYpIAp7CglmbG9hdDIgdXZfc2NhbGUgPSB1diAqIGZsb2F0MigwLjgpOwoJZmxvYXQyIHBhcmFtID0gZmxvYXQyKDAuOCk7CglmbG9hdDIgcGFyYW1fMSA9IHV2X3NjYWxlOwoJZmxvYXQyIHBhcmFtXzIgPSB1X2NpcmNsZTFfUzFfYzA7CglmbG9hdDIgcGFyYW1fMyA9IHVfcm90YXRpb24xX1MxX2MwOwoJZmxvYXQgcGFyYW1fNCA9IDAuMTc7CglmbG9hdCBfMzE5ID0gRkxUX2ZsdXR0ZXJfbG9jYWxfY2lyY2xlX2dyaWRfUzFfYzAocGFyYW0sIHBhcmFtXzEsIHBhcmFtXzIsIHBhcmFtXzMsIHBhcmFtXzQpOwoJZmxvYXQgZzEgPSBfMzE5OwoJZmxvYXQyIHBhcmFtXzUgPSBmbG9hdDIoMC44KTsKCWZsb2F0MiBwYXJhbV82ID0gdXZfc2NhbGU7CglmbG9hdDIgcGFyYW1fNyA9IHVfY2lyY2xlMl9TMV9jMDsKCWZsb2F0MiBwYXJhbV84ID0gdV9yb3RhdGlvbjJfUzFfYzA7CglmbG9hdCBwYXJhbV85ID0gMC4yOwoJZmxvYXQgXzMzMSA9IEZMVF9mbHV0dGVyX2xvY2FsX2NpcmNsZV9ncmlkX1MxX2MwKHBhcmFtXzUsIHBhcmFtXzYsIHBhcmFtXzcsIHBhcmFtXzgsIHBhcmFtXzkpOwoJZmxvYXQgZzIgPSBfMzMxOwoJZmxvYXQyIHBhcmFtXzEwID0gZmxvYXQyKDAuOCk7CglmbG9hdDIgcGFyYW1fMTEgPSB1dl9zY2FsZTsKCWZsb2F0MiBwYXJhbV8xMiA9IHVfY2lyY2xlM19TMV9jMDsKCWZsb2F0MiBwYXJhbV8xMyA9IHVfcm90YXRpb24zX1MxX2MwOwoJZmxvYXQgcGFyYW1fMTQgPSAwLjI3NTsKCWZsb2F0IF8zNDQgPSBGTFRfZmx1dHRlcl9sb2NhbF9jaXJjbGVfZ3JpZF9TMV9jMChwYXJhbV8xMCwgcGFyYW1fMTEsIHBhcmFtXzEyLCBwYXJhbV8xMywgcGFyYW1fMTQpOwoJZmxvYXQgZzMgPSBfMzQ0OwoJZmxvYXQgdiA9ICgoZzEgKiBnMSArIGcyKSAtIGczKSAqIDAuNTsKCXJldHVybiBjbGFtcCgwLjQ1ICsgMC44ICogdiwgMC4wLCAxLjApOwp9CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfcmluZ19TMV9jMChmbG9hdDIgdXYsIGZsb2F0MiB4eSwgZmxvYXQgcmFkaXVzLCBmbG9hdCB0aGlja25lc3MsIGZsb2F0IGJsdXIpIAp7CglmbG9hdDIgcGFyYW0gPSB1djsKCWZsb2F0MiBwYXJhbV8xID0geHk7CglmbG9hdCBwYXJhbV8yID0gcmFkaXVzICsgdGhpY2tuZXNzOwoJZmxvYXQgcGFyYW1fMyA9IGJsdXI7CglmbG9hdCBjaXJjbGVfb3V0ZXIgPSBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X2NpcmNsZV9TMV9jMChwYXJhbSwgcGFyYW1fMSwgcGFyYW1fMiwgcGFyYW1fMyk7CglmbG9hdDIgcGFyYW1fNCA9IHV2OwoJZmxvYXQyIHBhcmFtXzUgPSB4eTsKCWZsb2F0IHBhcmFtXzYgPSBtYXgocmFkaXVzIC0gdGhpY2tuZXNzLCAwLjApOwoJZmxvYXQgcGFyYW1fNyA9IGJsdXI7CglmbG9hdCBjaXJjbGVfaW5uZXIgPSBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X2NpcmNsZV9TMV9jMChwYXJhbV80LCBwYXJhbV81LCBwYXJhbV82LCBwYXJhbV83KTsKCXJldHVybiBjbGFtcChjaXJjbGVfb3V0ZXIgLSBjaXJjbGVfaW5uZXIsIDAuMCwgMS4wKTsKfQpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF90cmlhbmdsZV9ub2lzZV9TMV9jMChpbm91dCBmbG9hdDIgbikgCnsKCW4gPSBmcmFjdChuICogZmxvYXQyKDUuMzk4NywgNS40NDIxKSk7CgluICs9IGZsb2F0Mihkb3Qobi55eCwgbiArIGZsb2F0MigyMS41MzUxLCAxNC4zMTM3KSkpOwoJZmxvYXQgeHkgPSBuLnggKiBuLnk7CglyZXR1cm4gKGZyYWN0KHh5ICogOTUuNDMwNykgKyBmcmFjdCh4eSAqIDc1LjA0OTYxKSkgLSAxLjA7Cn0KZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfdGhyZXNob2xkX1MxX2MwKGZsb2F0IHYsIGZsb2F0IGwsIGZsb2F0IGgpIAp7CglyZXR1cm4gc3RlcChsLCB2KSAqICgxLjAgLSBzdGVwKGgsIHYpKTsKfQpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9zcGFya2xlX1MxX2MwKGZsb2F0MiB1diwgZmxvYXQgdCkgCnsKCWZsb2F0MiBwYXJhbSA9IHV2OwoJZmxvYXQgXzI0MiA9IEZMVF9mbHV0dGVyX2xvY2FsX3RyaWFuZ2xlX25vaXNlX1MxX2MwKHBhcmFtKTsKCWZsb2F0IG4gPSBfMjQyOwoJZmxvYXQgcGFyYW1fMSA9IG47CglmbG9hdCBwYXJhbV8yID0gMC4wOwoJZmxvYXQgcGFyYW1fMyA9IDAuMDU7CglmbG9hdCBzID0gRkxUX2ZsdXR0ZXJfbG9jYWxfdGhyZXNob2xkX1MxX2MwKHBhcmFtXzEsIHBhcmFtXzIsIHBhcmFtXzMpOwoJZmxvYXQgcGFyYW1fNCA9IG4gKyBzaW4oMy4xNDE1OTI3NCAqICh0ICsgMC4zNSkpOwoJZmxvYXQgcGFyYW1fNSA9IDAuMTsKCWZsb2F0IHBhcmFtXzYgPSAwLjE1OwoJcyArPSBGTFRfZmx1dHRlcl9sb2NhbF90aHJlc2hvbGRfUzFfYzAocGFyYW1fNCwgcGFyYW1fNSwgcGFyYW1fNik7CglmbG9hdCBwYXJhbV83ID0gbiArIHNpbigzLjE0MTU5Mjc0ICogKHQgKyAwLjcpKTsKCWZsb2F0IHBhcmFtXzggPSAwLjI7CglmbG9hdCBwYXJhbV85ID0gMC4yNTsKCXMgKz0gRkxUX2ZsdXR0ZXJfbG9jYWxfdGhyZXNob2xkX1MxX2MwKHBhcmFtXzcsIHBhcmFtXzgsIHBhcmFtXzkpOwoJZmxvYXQgcGFyYW1fMTAgPSBuICsgc2luKDMuMTQxNTkyNzQgKiAodCArIDEuMDUpKTsKCWZsb2F0IHBhcmFtXzExID0gMC4zOwoJZmxvYXQgcGFyYW1fMTIgPSAwLjM1OwoJcyArPSBGTFRfZmx1dHRlcl9sb2NhbF90aHJlc2hvbGRfUzFfYzAocGFyYW1fMTAsIHBhcmFtXzExLCBwYXJhbV8xMik7CglyZXR1cm4gY2xhbXAocywgMC4wLCAxLjApICogMC41NTsKfQp2b2lkIEZMVF9tYWluX1MxX2MwKCkgCnsKCXVfYWxwaGFfUzFfYzAgPSB1X2NvbXBvc2l0ZV8xX1MxX2MwLng7Cgl1X3NwYXJrbGVfYWxwaGFfUzFfYzAgPSB1X2NvbXBvc2l0ZV8xX1MxX2MwLnk7Cgl1X2JsdXJfUzFfYzAgPSB1X2NvbXBvc2l0ZV8xX1MxX2MwLno7Cgl1X3JhZGl1c19zY2FsZV9TMV9jMCA9IHVfY29tcG9zaXRlXzFfUzFfYzAudzsKCWZsb2F0MiBwID0gRkxUX2ZsdXR0ZXJfbG9jYWxfRmx1dHRlckZyYWdDb29yZF9TMV9jMCgpOwoJZmxvYXQyIHV2XzEgPSBwICogdV9yZXNvbHV0aW9uX3NjYWxlX1MxX2MwOwoJZmxvYXQyIGRlbnNpdHlfdXYgPSB1dl8xIC0gbW9kKHAsIHVfbm9pc2Vfc2NhbGVfUzFfYzApOwoJZmxvYXQgcmFkaXVzID0gdV9tYXhfcmFkaXVzX1MxX2MwICogdV9yYWRpdXNfc2NhbGVfUzFfYzA7CglmbG9hdDIgcGFyYW1fMTMgPSB1dl8xOwoJZmxvYXQgdHVyYnVsZW5jZSA9IEZMVF9mbHV0dGVyX2xvY2FsX3R1cmJ1bGVuY2VfUzFfYzAocGFyYW1fMTMpOwoJZmxvYXQyIHBhcmFtXzE0ID0gcDsKCWZsb2F0MiBwYXJhbV8xNSA9IHVfY2VudGVyX1MxX2MwOwoJZmxvYXQgcGFyYW1fMTYgPSByYWRpdXM7CglmbG9hdCBwYXJhbV8xNyA9IDAuMDUgKiB1X21heF9yYWRpdXNfUzFfYzA7CglmbG9hdCBwYXJhbV8xOCA9IHVfYmx1cl9TMV9jMDsKCWZsb2F0IHJpbmcgPSBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X3JpbmdfUzFfYzAocGFyYW1fMTQsIHBhcmFtXzE1LCBwYXJhbV8xNiwgcGFyYW1fMTcsIHBhcmFtXzE4KTsKCWZsb2F0MiBwYXJhbV8xOSA9IGRlbnNpdHlfdXY7CglmbG9hdCBwYXJhbV8yMCA9IHVfbm9pc2VfcGhhc2VfUzFfYzA7CglmbG9hdCBzcGFya2xlID0gKChGTFRfZmx1dHRlcl9sb2NhbF9zcGFya2xlX1MxX2MwKHBhcmFtXzE5LCBwYXJhbV8yMCkgKiByaW5nKSAqIHR1cmJ1bGVuY2UpICogdV9zcGFya2xlX2FscGhhX1MxX2MwOwoJZmxvYXQyIHBhcmFtXzIxID0gcDsKCWZsb2F0MiBwYXJhbV8yMiA9IHVfY2VudGVyX1MxX2MwOwoJZmxvYXQgcGFyYW1fMjMgPSByYWRpdXM7CglmbG9hdCBwYXJhbV8yNCA9IHVfYmx1cl9TMV9jMDsKCWZsb2F0IHdhdmVfYWxwaGEgPSAoRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9jaXJjbGVfUzFfYzAocGFyYW1fMjEsIHBhcmFtXzIyLCBwYXJhbV8yMywgcGFyYW1fMjQpICogdV9hbHBoYV9TMV9jMCkgKiB1X2NvbG9yX1MxX2MwLnc7CglmbG9hdDQgd2F2ZV9jb2xvciA9IGZsb2F0NCh1X2NvbG9yX1MxX2MwLnh5eiAqIHdhdmVfYWxwaGEsIHdhdmVfYWxwaGEpOwoJZnJhZ0NvbG9yX1MxX2MwID0gbWl4KHdhdmVfY29sb3IsIGZsb2F0NCgxLjApLCBmbG9hdDQoc3BhcmtsZSkpOwp9CmhhbGY0IHJ1bnRpbWVfc2hhZGVyX1MxX2MwKGhhbGY0IF9pbnB1dCkgCnsKCWhhbGY0IF90bXBfMF9pbkNvbG9yID0gX2lucHV0OwoJZmxvYXQyIF90bXBfMV9jb29yZHMgPSB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKCWZsdXR0ZXJfRnJhZ0Nvb3JkX1MxX2MwID0gZmxvYXQ0KF90bXBfMV9jb29yZHMsIDAuMCwgMC4wKTsKCUZMVF9tYWluX1MxX2MwKCk7CglyZXR1cm4gaGFsZjQoaGFsZjQoZnJhZ0NvbG9yX1MxX2MwKSk7Cn0KaGFsZjQgTWF0cml4RWZmZWN0X1MxKGhhbGY0IF9pbnB1dCkgCnsKCXJldHVybiBydW50aW1lX3NoYWRlcl9TMV9jMChfaW5wdXQpOwp9CmhhbGY0IENpcmN1bGFyUlJlY3RfUzIoaGFsZjQgX2lucHV0KSAKewoJZmxvYXQyIGR4eTAgPSB1aW5uZXJSZWN0X1MyLkxUIC0gc2tfRnJhZ0Nvb3JkLnh5OwoJZmxvYXQyIGR4eTEgPSBza19GcmFnQ29vcmQueHkgLSB1aW5uZXJSZWN0X1MyLlJCOwoJZmxvYXQyIGR4eSA9IG1heChtYXgoZHh5MCwgZHh5MSksIDAuMCk7CgloYWxmIGFscGhhID0gaGFsZihzYXR1cmF0ZSh1cmFkaXVzUGx1c0hhbGZfUzIueCAtIGxlbmd0aChkeHkpKSk7CglyZXR1cm4gX2lucHV0ICogYWxwaGE7Cn0Kdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJaGFsZjQgb3V0cHV0Q29sb3JfUzA7CglvdXRwdXRDb2xvcl9TMCA9IHZjb2xvcl9TMDsKCWNvbnN0IGhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoMSk7CgloYWxmNCBvdXRwdXRfUzE7CglvdXRwdXRfUzEgPSBNYXRyaXhFZmZlY3RfUzEob3V0cHV0Q29sb3JfUzApOwoJaGFsZjQgb3V0cHV0X1MyOwoJb3V0cHV0X1MyID0gQ2lyY3VsYXJSUmVjdF9TMihvdXRwdXRDb3ZlcmFnZV9TMCk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0X1MxICogb3V0cHV0X1MyOwoJfQp9CgABAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAgAAABwb3NpdGlvbgUAAABjb2xvcgAAAAoAAABsb2NhbENvb3JkAAAAAAAA","HVIAAAAAABIAAGAAAQ4AAAH477776R24EAAAIOBQAD6P7777777777YDAAAAAAAAAAAFIBVWKMG7QAAAAAAAEAACAAAAAVREAAQAAAAAQCDAAQQGAABAAAAAAAAHIAAAAAAAIAAAAAQGIAAAAAAA":"DAAAAExTS1N6AQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMV9jMDsKaW4gZmxvYXQyIHBvc2l0aW9uOwppbiBoYWxmNCBjb2xvcjsKaW4gZmxvYXQyIGxvY2FsQ29vcmQ7CmZsYXQgb3V0IGhhbGY0IHZjb2xvcl9TMDsKb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfM19TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgl2Y29sb3JfUzAgPSBjb2xvcjsKCXNrX1Bvc2l0aW9uID0gcG9zaXRpb24ueHkwMTsKCXsKCQl2VHJhbnNmb3JtZWRDb29yZHNfM19TMCA9IGZsb2F0M3gyKHVtYXRyaXhfUzFfYzApICogbG9jYWxDb29yZC54eTE7Cgl9Cn0KAAAAAAAAQgQAAHVuaWZvcm0gZmxvYXQ0IHVjbGFtcF9TMV9jMF9jMDsKdW5pZm9ybSBmbG9hdDN4MyB1bWF0cml4X1MxX2MwOwpzYW1wbGVyMkQgdVRleHR1cmVTYW1wbGVyXzBfUzE7CmZsYXQgaW4gaGFsZjQgdmNvbG9yX1MwOwppbiBmbG9hdDIgdlRyYW5zZm9ybWVkQ29vcmRzXzNfUzA7CmhhbGY0IFRleHR1cmVFZmZlY3RfUzFfYzBfYzAoaGFsZjQgX2lucHV0KSAKewoJZmxvYXQyIGluQ29vcmQgPSB2VHJhbnNmb3JtZWRDb29yZHNfM19TMDsKCWZsb2F0MiBzdWJzZXRDb29yZDsKCXN1YnNldENvb3JkLnggPSBpbkNvb3JkLng7CglzdWJzZXRDb29yZC55ID0gaW5Db29yZC55OwoJZmxvYXQyIGNsYW1wZWRDb29yZDsKCWNsYW1wZWRDb29yZC54ID0gY2xhbXAoc3Vic2V0Q29vcmQueCwgdWNsYW1wX1MxX2MwX2MwLngsIHVjbGFtcF9TMV9jMF9jMC56KTsKCWNsYW1wZWRDb29yZC55ID0gc3Vic2V0Q29vcmQueTsKCWhhbGY0IHRleHR1cmVDb2xvciA9IHNhbXBsZSh1VGV4dHVyZVNhbXBsZXJfMF9TMSwgY2xhbXBlZENvb3JkKTsKCXJldHVybiB0ZXh0dXJlQ29sb3I7Cn0KaGFsZjQgTWF0cml4RWZmZWN0X1MxX2MwKGhhbGY0IF9pbnB1dCkgCnsKCXJldHVybiBUZXh0dXJlRWZmZWN0X1MxX2MwX2MwKF9pbnB1dCk7Cn0KaGFsZjQgRGlzYWJsZUNvdmVyYWdlQXNBbHBoYV9TMShoYWxmNCBfaW5wdXQpIAp7CglfaW5wdXQgPSBNYXRyaXhFZmZlY3RfUzFfYzAoX2lucHV0KTsKCWhhbGY0IF90bXBfMF9pbkNvbG9yID0gX2lucHV0OwoJcmV0dXJuIGhhbGY0KF9pbnB1dCk7Cn0Kdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJaGFsZjQgb3V0cHV0Q29sb3JfUzA7CglvdXRwdXRDb2xvcl9TMCA9IHZjb2xvcl9TMDsKCWNvbnN0IGhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoMSk7CgloYWxmNCBvdXRwdXRfUzE7CglvdXRwdXRfUzEgPSBEaXNhYmxlQ292ZXJhZ2VBc0FscGhhX1MxKG91dHB1dENvbG9yX1MwKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRfUzEgKiBvdXRwdXRDb3ZlcmFnZV9TMDsKCX0KfQoAAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAADAAAACAAAAHBvc2l0aW9uBQAAAGNvbG9yAAAACgAAAGxvY2FsQ29vcmQAAAAAAAA=","EADQAAAAAEAAAAAUAABQAAQPAAABCFYMAAKAUEAAAAAAAAABAAAAAAAAAAANAAIAAAABAAAAACAJAAIAAAAA":"DAAAAExTS1NyAgAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQyIHVBdGxhc0RpbWVuc2lvbnNJbnZfUzA7CmluIGZsb2F0MyBpblBvc2l0aW9uOwppbiBoYWxmNCBpbkNvbG9yOwppbiB1c2hvcnQyIGluVGV4dHVyZUNvb3JkczsKb3V0IGZsb2F0MiB2VGV4dHVyZUNvb3Jkc19TMDsKZmxhdCBvdXQgZmxvYXQgdlRleEluZGV4X1MwOwpvdXQgZmxvYXQyIHZJbnRUZXh0dXJlQ29vcmRzX1MwOwpvdXQgaGFsZjQgdmluQ29sb3JfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIERpc3RhbmNlRmllbGRQYXRoCglpbnQgdGV4SWR4ID0gMDsKCWZsb2F0MiB1bm9ybVRleENvb3JkcyA9IGZsb2F0MihpblRleHR1cmVDb29yZHMueCwgaW5UZXh0dXJlQ29vcmRzLnkpOwoJdlRleHR1cmVDb29yZHNfUzAgPSB1bm9ybVRleENvb3JkcyAqIHVBdGxhc0RpbWVuc2lvbnNJbnZfUzA7Cgl2VGV4SW5kZXhfUzAgPSBmbG9hdCh0ZXhJZHgpOwoJdkludFRleHR1cmVDb29yZHNfUzAgPSB1bm9ybVRleENvb3JkczsKCXZpbkNvbG9yX1MwID0gaW5Db2xvcjsKCWZsb2F0MyBfdG1wXzFfaW5Qb3NpdGlvbiA9IGluUG9zaXRpb247Cglza19Qb3NpdGlvbiA9IGluUG9zaXRpb24ueHkwejsKfQoAAAAAAACXAgAAc2FtcGxlcjJEIHVUZXh0dXJlU2FtcGxlcl8wX1MwOwppbiBmbG9hdDIgdlRleHR1cmVDb29yZHNfUzA7CmZsYXQgaW4gZmxvYXQgdlRleEluZGV4X1MwOwppbiBmbG9hdDIgdkludFRleHR1cmVDb29yZHNfUzA7CmluIGhhbGY0IHZpbkNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgRGlzdGFuY2VGaWVsZFBhdGgKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2aW5Db2xvcl9TMDsKCWZsb2F0MiB1diA9IHZUZXh0dXJlQ29vcmRzX1MwOwoJaGFsZjQgdGV4Q29sb3I7Cgl7CgkJdGV4Q29sb3IgPSBzYW1wbGUodVRleHR1cmVTYW1wbGVyXzBfUzAsIHV2KS5ycnJyOwoJfQoJaGFsZiBkaXN0YW5jZSA9IDcuOTY4NzUqKHRleENvbG9yLnIgLSAwLjUwMTk2MDc4NDMxKTsKCWhhbGYgYWZ3aWR0aDsKCWFmd2lkdGggPSBhYnMoMC42NSpoYWxmKGRGZHgodkludFRleHR1cmVDb29yZHNfUzAueCkpKTsKCWhhbGYgdmFsID0gc21vb3Roc3RlcCgtYWZ3aWR0aCwgYWZ3aWR0aCwgZGlzdGFuY2UpOwoJaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNCh2YWwpOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dENvbG9yX1MwICogb3V0cHV0Q292ZXJhZ2VfUzA7Cgl9Cn0KAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAADAAAACgAAAGluUG9zaXRpb24AAAcAAABpbkNvbG9yAA8AAABpblRleHR1cmVDb29yZHMAAAAAAA==","HVIAAAAAABIAAGAAAQ4AAAH477776R24EAAAIOBQAD6P7777777777YDAAAAAAAAAAAHQBNGZODK5YIAAAAAAQAAAAAIADCNS4GV3QYBAAAAAAAAAAAIAALIAAAAAUDLMERKGAAAAAMAAAAAIAAAAAAAIBDNIWUYZAUAAAAAAYAAAAAAAAAABUABAAAAAEAAAAAIBEABAAAAA":"DAAAAExTS1N0AQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMTsKaW4gZmxvYXQyIHBvc2l0aW9uOwppbiBoYWxmNCBjb2xvcjsKaW4gZmxvYXQyIGxvY2FsQ29vcmQ7CmZsYXQgb3V0IGhhbGY0IHZjb2xvcl9TMDsKb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgl2Y29sb3JfUzAgPSBjb2xvcjsKCXNrX1Bvc2l0aW9uID0gcG9zaXRpb24ueHkwMTsKCXsKCQl2VHJhbnNmb3JtZWRDb29yZHNfMl9TMCA9IGZsb2F0M3gyKHVtYXRyaXhfUzEpICogbG9jYWxDb29yZC54eTE7Cgl9Cn0KAQAAAJAeAABmbG9hdDQgZmx1dHRlcl9GcmFnQ29vcmRfUzFfYzA7CmZsb2F0NCBmcmFnQ29sb3JfUzFfYzA7CmZsb2F0IHVfYWxwaGFfUzFfYzA7CmZsb2F0IHVfc3BhcmtsZV9hbHBoYV9TMV9jMDsKZmxvYXQgdV9ibHVyX1MxX2MwOwpmbG9hdCB1X3JhZGl1c19zY2FsZV9TMV9jMDsKY29uc3QgaW50IGtGaWxsQUFfUzJfYzAgPSAxOwpjb25zdCBpbnQga0ludmVyc2VGaWxsQldfUzJfYzAgPSAyOwpjb25zdCBpbnQga0ludmVyc2VGaWxsQUFfUzJfYzAgPSAzOwp1bmlmb3JtIGZsb2F0NCB1X2NvbG9yX1MxX2MwOwp1bmlmb3JtIGZsb2F0NCB1X2NvbXBvc2l0ZV8xX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X2NlbnRlcl9TMV9jMDsKdW5pZm9ybSBmbG9hdCB1X21heF9yYWRpdXNfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfcmVzb2x1dGlvbl9zY2FsZV9TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9ub2lzZV9zY2FsZV9TMV9jMDsKdW5pZm9ybSBmbG9hdCB1X25vaXNlX3BoYXNlX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X2NpcmNsZTFfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfY2lyY2xlMl9TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9jaXJjbGUzX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X3JvdGF0aW9uMV9TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9yb3RhdGlvbjJfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfcm90YXRpb24zX1MxX2MwOwp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzE7CnVuaWZvcm0gZmxvYXQ0IHVjaXJjbGVfUzJfYzA7CmZsYXQgaW4gaGFsZjQgdmNvbG9yX1MwOwppbiBmbG9hdDIgdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzA7CmZsb2F0MiBGTFRfZmx1dHRlcl9sb2NhbF9GbHV0dGVyRnJhZ0Nvb3JkX1MxX2MwKCk7CmZsb2F0MngyIEZMVF9mbHV0dGVyX2xvY2FsX3JvdGF0ZTJkX1MxX2MwKGZsb2F0MiByYWQpOwpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X2NpcmNsZV9TMV9jMChmbG9hdDIgdXYsIGZsb2F0MiB4eSwgZmxvYXQgcmFkaXVzLCBmbG9hdCBibHVyKTsKZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfY2lyY2xlX2dyaWRfUzFfYzAoZmxvYXQyIHJlc29sdXRpb24sIGlub3V0IGZsb2F0MiBwLCBmbG9hdDIgeHksIGZsb2F0MiByb3RhdGlvbiwgZmxvYXQgY2VsbF9kaWFtZXRlcik7CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3R1cmJ1bGVuY2VfUzFfYzAoZmxvYXQyIHV2KTsKZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9yaW5nX1MxX2MwKGZsb2F0MiB1diwgZmxvYXQyIHh5LCBmbG9hdCByYWRpdXMsIGZsb2F0IHRoaWNrbmVzcywgZmxvYXQgYmx1cik7CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3RyaWFuZ2xlX25vaXNlX1MxX2MwKGlub3V0IGZsb2F0MiBuKTsKZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfdGhyZXNob2xkX1MxX2MwKGZsb2F0IHYsIGZsb2F0IGwsIGZsb2F0IGgpOwpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9zcGFya2xlX1MxX2MwKGZsb2F0MiB1diwgZmxvYXQgdCk7CnZvaWQgRkxUX21haW5fUzFfYzAoKTsKZmxvYXQyIEZMVF9mbHV0dGVyX2xvY2FsX0ZsdXR0ZXJGcmFnQ29vcmRfUzFfYzAoKSAKewoJcmV0dXJuIGZsdXR0ZXJfRnJhZ0Nvb3JkX1MxX2MwLnh5Owp9CmZsb2F0MngyIEZMVF9mbHV0dGVyX2xvY2FsX3JvdGF0ZTJkX1MxX2MwKGZsb2F0MiByYWQpIAp7CglyZXR1cm4gZmxvYXQyeDIocmFkLngsIC1yYWQueSwgcmFkLnksIHJhZC54KTsKfQpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X2NpcmNsZV9TMV9jMChmbG9hdDIgdXYsIGZsb2F0MiB4eSwgZmxvYXQgcmFkaXVzLCBmbG9hdCBibHVyKSAKewoJZmxvYXQgYmx1cl9oYWxmID0gYmx1ciAqIDAuNTsKCWZsb2F0IGQgPSBkaXN0YW5jZSh1diwgeHkpOwoJcmV0dXJuIDEuMCAtIHNtb290aHN0ZXAoMS4wIC0gYmx1cl9oYWxmLCAxLjAgKyBibHVyX2hhbGYsIGQgLyByYWRpdXMpOwp9CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX2NpcmNsZV9ncmlkX1MxX2MwKGZsb2F0MiByZXNvbHV0aW9uLCBpbm91dCBmbG9hdDIgcCwgZmxvYXQyIHh5LCBmbG9hdDIgcm90YXRpb24sIGZsb2F0IGNlbGxfZGlhbWV0ZXIpIAp7CglmbG9hdDIgcGFyYW0gPSByb3RhdGlvbjsKCXAgPSBGTFRfZmx1dHRlcl9sb2NhbF9yb3RhdGUyZF9TMV9jMChwYXJhbSkgKiAoeHkgLSBwKSArIHh5OwoJcCA9IG1vZChwLCBmbG9hdDIoY2VsbF9kaWFtZXRlcikpIC8gcmVzb2x1dGlvbjsKCWZsb2F0IGNlbGxfdXYgPSAoY2VsbF9kaWFtZXRlciAvIHJlc29sdXRpb24ueSkgKiAwLjU7CglmbG9hdCByID0gMC42NSAqIGNlbGxfdXY7CglmbG9hdDIgcGFyYW1fMSA9IHA7CglmbG9hdDIgcGFyYW1fMiA9IGZsb2F0MihjZWxsX3V2KTsKCWZsb2F0IHBhcmFtXzMgPSByOwoJZmxvYXQgcGFyYW1fNCA9IHIgKiA1MC4wOwoJcmV0dXJuIEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfY2lyY2xlX1MxX2MwKHBhcmFtXzEsIHBhcmFtXzIsIHBhcmFtXzMsIHBhcmFtXzQpOwp9CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3R1cmJ1bGVuY2VfUzFfYzAoZmxvYXQyIHV2KSAKewoJZmxvYXQyIHV2X3NjYWxlID0gdXYgKiBmbG9hdDIoMC44KTsKCWZsb2F0MiBwYXJhbSA9IGZsb2F0MigwLjgpOwoJZmxvYXQyIHBhcmFtXzEgPSB1dl9zY2FsZTsKCWZsb2F0MiBwYXJhbV8yID0gdV9jaXJjbGUxX1MxX2MwOwoJZmxvYXQyIHBhcmFtXzMgPSB1X3JvdGF0aW9uMV9TMV9jMDsKCWZsb2F0IHBhcmFtXzQgPSAwLjE3OwoJZmxvYXQgXzMxOSA9IEZMVF9mbHV0dGVyX2xvY2FsX2NpcmNsZV9ncmlkX1MxX2MwKHBhcmFtLCBwYXJhbV8xLCBwYXJhbV8yLCBwYXJhbV8zLCBwYXJhbV80KTsKCWZsb2F0IGcxID0gXzMxOTsKCWZsb2F0MiBwYXJhbV81ID0gZmxvYXQyKDAuOCk7CglmbG9hdDIgcGFyYW1fNiA9IHV2X3NjYWxlOwoJZmxvYXQyIHBhcmFtXzcgPSB1X2NpcmNsZTJfUzFfYzA7CglmbG9hdDIgcGFyYW1fOCA9IHVfcm90YXRpb24yX1MxX2MwOwoJZmxvYXQgcGFyYW1fOSA9IDAuMjsKCWZsb2F0IF8zMzEgPSBGTFRfZmx1dHRlcl9sb2NhbF9jaXJjbGVfZ3JpZF9TMV9jMChwYXJhbV81LCBwYXJhbV82LCBwYXJhbV83LCBwYXJhbV84LCBwYXJhbV85KTsKCWZsb2F0IGcyID0gXzMzMTsKCWZsb2F0MiBwYXJhbV8xMCA9IGZsb2F0MigwLjgpOwoJZmxvYXQyIHBhcmFtXzExID0gdXZfc2NhbGU7CglmbG9hdDIgcGFyYW1fMTIgPSB1X2NpcmNsZTNfUzFfYzA7CglmbG9hdDIgcGFyYW1fMTMgPSB1X3JvdGF0aW9uM19TMV9jMDsKCWZsb2F0IHBhcmFtXzE0ID0gMC4yNzU7CglmbG9hdCBfMzQ0ID0gRkxUX2ZsdXR0ZXJfbG9jYWxfY2lyY2xlX2dyaWRfUzFfYzAocGFyYW1fMTAsIHBhcmFtXzExLCBwYXJhbV8xMiwgcGFyYW1fMTMsIHBhcmFtXzE0KTsKCWZsb2F0IGczID0gXzM0NDsKCWZsb2F0IHYgPSAoKGcxICogZzEgKyBnMikgLSBnMykgKiAwLjU7CglyZXR1cm4gY2xhbXAoMC40NSArIDAuOCAqIHYsIDAuMCwgMS4wKTsKfQpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X3JpbmdfUzFfYzAoZmxvYXQyIHV2LCBmbG9hdDIgeHksIGZsb2F0IHJhZGl1cywgZmxvYXQgdGhpY2tuZXNzLCBmbG9hdCBibHVyKSAKewoJZmxvYXQyIHBhcmFtID0gdXY7CglmbG9hdDIgcGFyYW1fMSA9IHh5OwoJZmxvYXQgcGFyYW1fMiA9IHJhZGl1cyArIHRoaWNrbmVzczsKCWZsb2F0IHBhcmFtXzMgPSBibHVyOwoJZmxvYXQgY2lyY2xlX291dGVyID0gRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9jaXJjbGVfUzFfYzAocGFyYW0sIHBhcmFtXzEsIHBhcmFtXzIsIHBhcmFtXzMpOwoJZmxvYXQyIHBhcmFtXzQgPSB1djsKCWZsb2F0MiBwYXJhbV81ID0geHk7CglmbG9hdCBwYXJhbV82ID0gbWF4KHJhZGl1cyAtIHRoaWNrbmVzcywgMC4wKTsKCWZsb2F0IHBhcmFtXzcgPSBibHVyOwoJZmxvYXQgY2lyY2xlX2lubmVyID0gRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9jaXJjbGVfUzFfYzAocGFyYW1fNCwgcGFyYW1fNSwgcGFyYW1fNiwgcGFyYW1fNyk7CglyZXR1cm4gY2xhbXAoY2lyY2xlX291dGVyIC0gY2lyY2xlX2lubmVyLCAwLjAsIDEuMCk7Cn0KZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfdHJpYW5nbGVfbm9pc2VfUzFfYzAoaW5vdXQgZmxvYXQyIG4pIAp7CgluID0gZnJhY3QobiAqIGZsb2F0Mig1LjM5ODcsIDUuNDQyMSkpOwoJbiArPSBmbG9hdDIoZG90KG4ueXgsIG4gKyBmbG9hdDIoMjEuNTM1MSwgMTQuMzEzNykpKTsKCWZsb2F0IHh5ID0gbi54ICogbi55OwoJcmV0dXJuIChmcmFjdCh4eSAqIDk1LjQzMDcpICsgZnJhY3QoeHkgKiA3NS4wNDk2MSkpIC0gMS4wOwp9CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3RocmVzaG9sZF9TMV9jMChmbG9hdCB2LCBmbG9hdCBsLCBmbG9hdCBoKSAKewoJcmV0dXJuIHN0ZXAobCwgdikgKiAoMS4wIC0gc3RlcChoLCB2KSk7Cn0KZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfc3BhcmtsZV9TMV9jMChmbG9hdDIgdXYsIGZsb2F0IHQpIAp7CglmbG9hdDIgcGFyYW0gPSB1djsKCWZsb2F0IF8yNDIgPSBGTFRfZmx1dHRlcl9sb2NhbF90cmlhbmdsZV9ub2lzZV9TMV9jMChwYXJhbSk7CglmbG9hdCBuID0gXzI0MjsKCWZsb2F0IHBhcmFtXzEgPSBuOwoJZmxvYXQgcGFyYW1fMiA9IDAuMDsKCWZsb2F0IHBhcmFtXzMgPSAwLjA1OwoJZmxvYXQgcyA9IEZMVF9mbHV0dGVyX2xvY2FsX3RocmVzaG9sZF9TMV9jMChwYXJhbV8xLCBwYXJhbV8yLCBwYXJhbV8zKTsKCWZsb2F0IHBhcmFtXzQgPSBuICsgc2luKDMuMTQxNTkyNzQgKiAodCArIDAuMzUpKTsKCWZsb2F0IHBhcmFtXzUgPSAwLjE7CglmbG9hdCBwYXJhbV82ID0gMC4xNTsKCXMgKz0gRkxUX2ZsdXR0ZXJfbG9jYWxfdGhyZXNob2xkX1MxX2MwKHBhcmFtXzQsIHBhcmFtXzUsIHBhcmFtXzYpOwoJZmxvYXQgcGFyYW1fNyA9IG4gKyBzaW4oMy4xNDE1OTI3NCAqICh0ICsgMC43KSk7CglmbG9hdCBwYXJhbV84ID0gMC4yOwoJZmxvYXQgcGFyYW1fOSA9IDAuMjU7CglzICs9IEZMVF9mbHV0dGVyX2xvY2FsX3RocmVzaG9sZF9TMV9jMChwYXJhbV83LCBwYXJhbV84LCBwYXJhbV85KTsKCWZsb2F0IHBhcmFtXzEwID0gbiArIHNpbigzLjE0MTU5Mjc0ICogKHQgKyAxLjA1KSk7CglmbG9hdCBwYXJhbV8xMSA9IDAuMzsKCWZsb2F0IHBhcmFtXzEyID0gMC4zNTsKCXMgKz0gRkxUX2ZsdXR0ZXJfbG9jYWxfdGhyZXNob2xkX1MxX2MwKHBhcmFtXzEwLCBwYXJhbV8xMSwgcGFyYW1fMTIpOwoJcmV0dXJuIGNsYW1wKHMsIDAuMCwgMS4wKSAqIDAuNTU7Cn0Kdm9pZCBGTFRfbWFpbl9TMV9jMCgpIAp7Cgl1X2FscGhhX1MxX2MwID0gdV9jb21wb3NpdGVfMV9TMV9jMC54OwoJdV9zcGFya2xlX2FscGhhX1MxX2MwID0gdV9jb21wb3NpdGVfMV9TMV9jMC55OwoJdV9ibHVyX1MxX2MwID0gdV9jb21wb3NpdGVfMV9TMV9jMC56OwoJdV9yYWRpdXNfc2NhbGVfUzFfYzAgPSB1X2NvbXBvc2l0ZV8xX1MxX2MwLnc7CglmbG9hdDIgcCA9IEZMVF9mbHV0dGVyX2xvY2FsX0ZsdXR0ZXJGcmFnQ29vcmRfUzFfYzAoKTsKCWZsb2F0MiB1dl8xID0gcCAqIHVfcmVzb2x1dGlvbl9zY2FsZV9TMV9jMDsKCWZsb2F0MiBkZW5zaXR5X3V2ID0gdXZfMSAtIG1vZChwLCB1X25vaXNlX3NjYWxlX1MxX2MwKTsKCWZsb2F0IHJhZGl1cyA9IHVfbWF4X3JhZGl1c19TMV9jMCAqIHVfcmFkaXVzX3NjYWxlX1MxX2MwOwoJZmxvYXQyIHBhcmFtXzEzID0gdXZfMTsKCWZsb2F0IHR1cmJ1bGVuY2UgPSBGTFRfZmx1dHRlcl9sb2NhbF90dXJidWxlbmNlX1MxX2MwKHBhcmFtXzEzKTsKCWZsb2F0MiBwYXJhbV8xNCA9IHA7CglmbG9hdDIgcGFyYW1fMTUgPSB1X2NlbnRlcl9TMV9jMDsKCWZsb2F0IHBhcmFtXzE2ID0gcmFkaXVzOwoJZmxvYXQgcGFyYW1fMTcgPSAwLjA1ICogdV9tYXhfcmFkaXVzX1MxX2MwOwoJZmxvYXQgcGFyYW1fMTggPSB1X2JsdXJfUzFfYzA7CglmbG9hdCByaW5nID0gRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9yaW5nX1MxX2MwKHBhcmFtXzE0LCBwYXJhbV8xNSwgcGFyYW1fMTYsIHBhcmFtXzE3LCBwYXJhbV8xOCk7CglmbG9hdDIgcGFyYW1fMTkgPSBkZW5zaXR5X3V2OwoJZmxvYXQgcGFyYW1fMjAgPSB1X25vaXNlX3BoYXNlX1MxX2MwOwoJZmxvYXQgc3BhcmtsZSA9ICgoRkxUX2ZsdXR0ZXJfbG9jYWxfc3BhcmtsZV9TMV9jMChwYXJhbV8xOSwgcGFyYW1fMjApICogcmluZykgKiB0dXJidWxlbmNlKSAqIHVfc3BhcmtsZV9hbHBoYV9TMV9jMDsKCWZsb2F0MiBwYXJhbV8yMSA9IHA7CglmbG9hdDIgcGFyYW1fMjIgPSB1X2NlbnRlcl9TMV9jMDsKCWZsb2F0IHBhcmFtXzIzID0gcmFkaXVzOwoJZmxvYXQgcGFyYW1fMjQgPSB1X2JsdXJfUzFfYzA7CglmbG9hdCB3YXZlX2FscGhhID0gKEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfY2lyY2xlX1MxX2MwKHBhcmFtXzIxLCBwYXJhbV8yMiwgcGFyYW1fMjMsIHBhcmFtXzI0KSAqIHVfYWxwaGFfUzFfYzApICogdV9jb2xvcl9TMV9jMC53OwoJZmxvYXQ0IHdhdmVfY29sb3IgPSBmbG9hdDQodV9jb2xvcl9TMV9jMC54eXogKiB3YXZlX2FscGhhLCB3YXZlX2FscGhhKTsKCWZyYWdDb2xvcl9TMV9jMCA9IG1peCh3YXZlX2NvbG9yLCBmbG9hdDQoMS4wKSwgZmxvYXQ0KHNwYXJrbGUpKTsKfQpoYWxmNCBydW50aW1lX3NoYWRlcl9TMV9jMChoYWxmNCBfaW5wdXQpIAp7CgloYWxmNCBfdG1wXzBfaW5Db2xvciA9IF9pbnB1dDsKCWZsb2F0MiBfdG1wXzFfY29vcmRzID0gdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzA7CglmbHV0dGVyX0ZyYWdDb29yZF9TMV9jMCA9IGZsb2F0NChfdG1wXzFfY29vcmRzLCAwLjAsIDAuMCk7CglGTFRfbWFpbl9TMV9jMCgpOwoJcmV0dXJuIGhhbGY0KGhhbGY0KGZyYWdDb2xvcl9TMV9jMCkpOwp9CmhhbGY0IE1hdHJpeEVmZmVjdF9TMShoYWxmNCBfaW5wdXQpIAp7CglyZXR1cm4gcnVudGltZV9zaGFkZXJfUzFfYzAoX2lucHV0KTsKfQpoYWxmNCBDaXJjbGVfUzJfYzAoaGFsZjQgX2lucHV0KSAKewoJaGFsZjQgX3RtcF8yX2luQ29sb3IgPSBfaW5wdXQ7CgloYWxmIGQ7CglpZiAoaW50KDEpID09IGtJbnZlcnNlRmlsbEJXX1MyX2MwIHx8IGludCgxKSA9PSBrSW52ZXJzZUZpbGxBQV9TMl9jMCkgCgl7CgkJZCA9IGhhbGYoKGxlbmd0aCgodWNpcmNsZV9TMl9jMC54eSAtIHNrX0ZyYWdDb29yZC54eSkgKiB1Y2lyY2xlX1MyX2MwLncpIC0gMS4wKSAqIHVjaXJjbGVfUzJfYzAueik7Cgl9CgllbHNlIAoJewoJCWQgPSBoYWxmKCgxLjAgLSBsZW5ndGgoKHVjaXJjbGVfUzJfYzAueHkgLSBza19GcmFnQ29vcmQueHkpICogdWNpcmNsZV9TMl9jMC53KSkgKiB1Y2lyY2xlX1MyX2MwLnopOwoJfQoJcmV0dXJuIGhhbGY0KGhhbGY0KGludCgxKSA9PSBrRmlsbEFBX1MyX2MwIHx8IGludCgxKSA9PSBrSW52ZXJzZUZpbGxBQV9TMl9jMCA/IHNhdHVyYXRlKGQpIDogaGFsZihkID4gMC41KSkpOwp9CmhhbGY0IEJsZW5kX1MyKGhhbGY0IF9zcmMsIGhhbGY0IF9kc3QpIAp7CglyZXR1cm4gYmxlbmRfbW9kdWxhdGUoX3NyYywgQ2lyY2xlX1MyX2MwKF9zcmMpKTsKfQp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmNvbG9yX1MwOwoJY29uc3QgaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNCgxKTsKCWhhbGY0IG91dHB1dF9TMTsKCW91dHB1dF9TMSA9IE1hdHJpeEVmZmVjdF9TMShvdXRwdXRDb2xvcl9TMCk7CgloYWxmNCBvdXRwdXRfUzI7CglvdXRwdXRfUzIgPSBCbGVuZF9TMihvdXRwdXRDb3ZlcmFnZV9TMCwgaGFsZjQoMSkpOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dF9TMSAqIG91dHB1dF9TMjsKCX0KfQoBAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAgAAABwb3NpdGlvbgUAAABjb2xvcgAAAAoAAABsb2NhbENvb3JkAAAAAAAA","HUJAAAAAAAQAADAAAIOAAAH677777777777QGHAQAD7P7777777777YBAAAAAAQAAAAAAQQGAAZAABQAAAAAAAACAAAAADYCAAIAAAAAWBRAAAABAAAAANAEIQCAAAAAAAAAAAAAUABQAAAAEAAAAAAAEEBQAAAA":"DAAAAExTS1N5AQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMV9jMF9jMDsKaW4gZmxvYXQyIHBvc2l0aW9uOwppbiBmbG9hdDIgbG9jYWxDb29yZDsKb3V0IGZsb2F0MiB2bG9jYWxDb29yZF9TMDsKb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfNF9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgl2bG9jYWxDb29yZF9TMCA9IGxvY2FsQ29vcmQ7Cglza19Qb3NpdGlvbiA9IHBvc2l0aW9uLnh5MDE7Cgl7CgkJdlRyYW5zZm9ybWVkQ29vcmRzXzRfUzAgPSBmbG9hdDN4Mih1bWF0cml4X1MxX2MwX2MwKSAqIHBvc2l0aW9uLnh5MTsKCX0KfQoAAAAAAAAAzAMAAHVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMV9jMF9jMDsKc2FtcGxlcjJEIHVUZXh0dXJlU2FtcGxlcl8wX1MwOwpzYW1wbGVyMkQgdVRleHR1cmVTYW1wbGVyXzBfUzE7CmluIGZsb2F0MiB2bG9jYWxDb29yZF9TMDsKaW4gZmxvYXQyIHZUcmFuc2Zvcm1lZENvb3Jkc180X1MwOwpoYWxmNCBUZXh0dXJlRWZmZWN0X1MxX2MwX2MwX2MwKGhhbGY0IF9pbnB1dCkgCnsKCXJldHVybiBzYW1wbGUodVRleHR1cmVTYW1wbGVyXzBfUzEsIHZUcmFuc2Zvcm1lZENvb3Jkc180X1MwKS4wMDByOwp9CmhhbGY0IE1hdHJpeEVmZmVjdF9TMV9jMF9jMChoYWxmNCBfaW5wdXQpIAp7CglyZXR1cm4gVGV4dHVyZUVmZmVjdF9TMV9jMF9jMF9jMChfaW5wdXQpOwp9CmhhbGY0IERldmljZVNwYWNlX1MxX2MwKGhhbGY0IF9pbnB1dCkgCnsKCXJldHVybiBNYXRyaXhFZmZlY3RfUzFfYzBfYzAoX2lucHV0KTsKfQpoYWxmNCBCbGVuZF9TMShoYWxmNCBfc3JjLCBoYWxmNCBfZHN0KSAKewoJcmV0dXJuIGJsZW5kX2RzdF9pbihEZXZpY2VTcGFjZV9TMV9jMChfc3JjKSwgX3NyYyk7Cn0Kdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJaGFsZjQgb3V0cHV0Q29sb3JfUzAgPSBoYWxmNCgxKTsKCWZsb2F0MiB0ZXhDb29yZDsKCXRleENvb3JkID0gdmxvY2FsQ29vcmRfUzA7CglvdXRwdXRDb2xvcl9TMCA9IChibGVuZF9tb2R1bGF0ZShzYW1wbGUodVRleHR1cmVTYW1wbGVyXzBfUzAsIHRleENvb3JkKSwgaGFsZjQoMSkpKTsKCWNvbnN0IGhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoMSk7CgloYWxmNCBvdXRwdXRfUzE7CglvdXRwdXRfUzEgPSBCbGVuZF9TMShvdXRwdXRDb3ZlcmFnZV9TMCwgaGFsZjQoMSkpOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dENvbG9yX1MwICogb3V0cHV0X1MxOwoJfQp9CgAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAACAAAACAAAAHBvc2l0aW9uCgAAAGxvY2FsQ29vcmQAAAAAAAA=","GEMAAAYAAEHAAAARC4EAAAQWBQAAAAAAAAAQAAAAIBCAAAGQAEAAAAAQAAAABAEQAEAAAAA":"DAAAAExTS1NUAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0MiBpblBvc2l0aW9uOwppbiBoYWxmNCBpbkNvbG9yOwppbiBoYWxmMyBpblNoYWRvd1BhcmFtczsKb3V0IGhhbGYzIHZpblNoYWRvd1BhcmFtc19TMDsKb3V0IGhhbGY0IHZpbkNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBSUmVjdFNoYWRvdwoJdmluU2hhZG93UGFyYW1zX1MwID0gaW5TaGFkb3dQYXJhbXM7Cgl2aW5Db2xvcl9TMCA9IGluQ29sb3I7CglmbG9hdDIgX3RtcF8wX2luUG9zaXRpb24gPSBpblBvc2l0aW9uOwoJc2tfUG9zaXRpb24gPSBfdG1wXzBfaW5Qb3NpdGlvbi54eTAxOwp9CgAAAAADAgAAc2FtcGxlcjJEIHVUZXh0dXJlU2FtcGxlcl8wX1MwOwppbiBoYWxmMyB2aW5TaGFkb3dQYXJhbXNfUzA7CmluIGhhbGY0IHZpbkNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgUlJlY3RTaGFkb3cKCWhhbGYzIHNoYWRvd1BhcmFtczsKCXNoYWRvd1BhcmFtcyA9IHZpblNoYWRvd1BhcmFtc19TMDsKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2aW5Db2xvcl9TMDsKCWhhbGYgZCA9IGxlbmd0aChzaGFkb3dQYXJhbXMueHkpOwoJZmxvYXQyIHV2ID0gZmxvYXQyKHNoYWRvd1BhcmFtcy56ICogKDEuMCAtIGQpLCAwLjUpOwoJaGFsZiBmYWN0b3IgPSBzYW1wbGUodVRleHR1cmVTYW1wbGVyXzBfUzAsIHV2KS4wMDByLmE7CgloYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KGZhY3Rvcik7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRDb3ZlcmFnZV9TMDsKCX0KfQoAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAKAAAAaW5Qb3NpdGlvbgAABwAAAGluQ29sb3IADgAAAGluU2hhZG93UGFyYW1zAAAAAAAA","HVIAAAAAABIAAGAAAQ4AAAH477776R24EAAAIOBQAD6P7777777777YDAAAAAAAAAAAFIBUAFS7EOCAAAAAGZJY26AAQAAAA2S5KXK4QAAAAAMAAAAAAAAQAABQM74NUDECAAAAAQ5UOAMQAAAAAAAAAAEAAAAAZ3FHDLYADAAAABKDVK5LSCAIAABQAAAAAAACAAAGAT3RWSMYIAAAAADWRYBSQAAAAAAAQAAAAGJJOXLVOIIBAAAGAAAAAAAAIAAAIAPOH2NTBAAAAAAOKFAOLAAAAAAAEAAAAAMQQAIAAAYGP6G2BSBAAACAAAAAAAAM5S4Z4NUDACAAAAAAAAADAIUOKFAOLAAAAAAACAAAAAZGIEENLQDAAAAAAAAAAABQAKAIAAIAAAADIBCEAQAAAAAAAAAAAIADQAAAAIAAAAAAAIIDA":"DAAAAExTS1OGAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMV9jMF9jMF9jMTsKaW4gZmxvYXQyIHBvc2l0aW9uOwppbiBoYWxmNCBjb2xvcjsKaW4gZmxvYXQyIGxvY2FsQ29vcmQ7CmZsYXQgb3V0IGhhbGY0IHZjb2xvcl9TMDsKb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfN19TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgl2Y29sb3JfUzAgPSBjb2xvcjsKCXNrX1Bvc2l0aW9uID0gcG9zaXRpb24ueHkwMTsKCXsKCQl2VHJhbnNmb3JtZWRDb29yZHNfN19TMCA9IGZsb2F0M3gyKHVtYXRyaXhfUzFfYzBfYzBfYzEpICogbG9jYWxDb29yZC54eTE7Cgl9Cn0KAAABAAAAIQoAAHVuaWZvcm0gaGFsZjQgdXN0YXJ0X1MxX2MwX2MwX2MwX2MwOwp1bmlmb3JtIGhhbGY0IHVlbmRfUzFfYzBfYzBfYzBfYzA7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMV9jMF9jMF9jMTsKdW5pZm9ybSBoYWxmNCB1bGVmdEJvcmRlckNvbG9yX1MxX2MwX2MwOwp1bmlmb3JtIGhhbGY0IHVyaWdodEJvcmRlckNvbG9yX1MxX2MwX2MwOwp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzFfYzE7CnVuaWZvcm0gaGFsZiB1cmFuZ2VfUzE7CnNhbXBsZXIyRCB1VGV4dHVyZVNhbXBsZXJfMF9TMTsKZmxhdCBpbiBoYWxmNCB2Y29sb3JfUzA7CmluIGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfN19TMDsKaGFsZjQgU2luZ2xlSW50ZXJ2YWxDb2xvcml6ZXJfUzFfYzBfYzBfYzBfYzAoaGFsZjQgX2lucHV0LCBmbG9hdDIgX2Nvb3JkcykgCnsKCWhhbGY0IF90bXBfMF9pbkNvbG9yID0gX2lucHV0OwoJZmxvYXQyIF90bXBfMV9jb29yZHMgPSBfY29vcmRzOwoJcmV0dXJuIGhhbGY0KG1peCh1c3RhcnRfUzFfYzBfYzBfYzBfYzAsIHVlbmRfUzFfYzBfYzBfYzBfYzAsIGhhbGYoX3RtcF8xX2Nvb3Jkcy54KSkpOwp9CmhhbGY0IGNvbG9yX3hmb3JtX1MxX2MwX2MwX2MwKGZsb2F0NCBjb2xvcikgCnsKCWNvbG9yLnJnYiAqPSBjb2xvci5hOwoJcmV0dXJuIGhhbGY0KGNvbG9yKTsKfQpoYWxmNCBDb2xvclNwYWNlWGZvcm1fUzFfYzBfYzBfYzAoaGFsZjQgX2lucHV0LCBmbG9hdDIgX2Nvb3JkcykgCnsKCXJldHVybiBjb2xvcl94Zm9ybV9TMV9jMF9jMF9jMChTaW5nbGVJbnRlcnZhbENvbG9yaXplcl9TMV9jMF9jMF9jMF9jMChfaW5wdXQsIF9jb29yZHMpKTsKfQpoYWxmNCBMaW5lYXJMYXlvdXRfUzFfYzBfYzBfYzFfYzAoaGFsZjQgX2lucHV0KSAKewoJaGFsZjQgX3RtcF8yX2luQ29sb3IgPSBfaW5wdXQ7CglmbG9hdDIgX3RtcF8zX2Nvb3JkcyA9IHZUcmFuc2Zvcm1lZENvb3Jkc183X1MwOwoJcmV0dXJuIGhhbGY0KGhhbGY0KGhhbGYoX3RtcF8zX2Nvb3Jkcy54KSArIDFlLTA1LCAxLjAsIDAuMCwgMC4wKSk7Cn0KaGFsZjQgTWF0cml4RWZmZWN0X1MxX2MwX2MwX2MxKGhhbGY0IF9pbnB1dCkgCnsKCXJldHVybiBMaW5lYXJMYXlvdXRfUzFfYzBfYzBfYzFfYzAoX2lucHV0KTsKfQpoYWxmNCBDbGFtcGVkR3JhZGllbnRfUzFfYzBfYzAoaGFsZjQgX2lucHV0KSAKewoJaGFsZjQgX3RtcF80X2luQ29sb3IgPSBfaW5wdXQ7CgloYWxmNCB0ID0gTWF0cml4RWZmZWN0X1MxX2MwX2MwX2MxKF90bXBfNF9pbkNvbG9yKTsKCWhhbGY0IG91dENvbG9yOwoJaWYgKCFib29sKGludCgxKSkgJiYgdC55IDwgMC4wKSAKCXsKCQlvdXRDb2xvciA9IGhhbGY0KDAuMCk7Cgl9CgllbHNlIGlmICh0LnggPCAwLjApIAoJewoJCW91dENvbG9yID0gdWxlZnRCb3JkZXJDb2xvcl9TMV9jMF9jMDsKCX0KCWVsc2UgaWYgKHQueCA+IDEuMCkgCgl7CgkJb3V0Q29sb3IgPSB1cmlnaHRCb3JkZXJDb2xvcl9TMV9jMF9jMDsKCX0KCWVsc2UgCgl7CgkJb3V0Q29sb3IgPSBDb2xvclNwYWNlWGZvcm1fUzFfYzBfYzBfYzAoX3RtcF80X2luQ29sb3IsIGZsb2F0MihoYWxmMih0LngsIDAuMCkpKTsKCX0KCXJldHVybiBoYWxmNChvdXRDb2xvcik7Cn0KaGFsZjQgRGlzYWJsZUNvdmVyYWdlQXNBbHBoYV9TMV9jMChoYWxmNCBfaW5wdXQpIAp7CglfaW5wdXQgPSBDbGFtcGVkR3JhZGllbnRfUzFfYzBfYzAoX2lucHV0KTsKCWhhbGY0IF90bXBfNV9pbkNvbG9yID0gX2lucHV0OwoJcmV0dXJuIGhhbGY0KF9pbnB1dCk7Cn0KaGFsZjQgVGV4dHVyZUVmZmVjdF9TMV9jMV9jMChoYWxmNCBfaW5wdXQsIGZsb2F0MiBfY29vcmRzKSAKewoJcmV0dXJuIHNhbXBsZSh1VGV4dHVyZVNhbXBsZXJfMF9TMSwgX2Nvb3JkcykuMDAwcjsKfQpoYWxmNCBNYXRyaXhFZmZlY3RfUzFfYzEoaGFsZjQgX2lucHV0LCBmbG9hdDIgX2Nvb3JkcykgCnsKCXJldHVybiBUZXh0dXJlRWZmZWN0X1MxX2MxX2MwKF9pbnB1dCwgZmxvYXQzeDIodW1hdHJpeF9TMV9jMSkgKiBfY29vcmRzLnh5MSk7Cn0KaGFsZjQgRGl0aGVyX1MxKGhhbGY0IF9pbnB1dCkgCnsKCWhhbGY0IF90bXBfNl9pbkNvbG9yID0gX2lucHV0OwoJaGFsZjQgY29sb3IgPSBEaXNhYmxlQ292ZXJhZ2VBc0FscGhhX1MxX2MwKF90bXBfNl9pbkNvbG9yKTsKCWhhbGYgdmFsdWUgPSBNYXRyaXhFZmZlY3RfUzFfYzEoX3RtcF82X2luQ29sb3IsIHNrX0ZyYWdDb29yZC54eSkudyAtIDAuNTsKCXJldHVybiBoYWxmNChoYWxmNChjbGFtcChjb2xvci54eXogKyB2YWx1ZSAqIHVyYW5nZV9TMSwgMC4wLCBjb2xvci53KSwgY29sb3IudykpOwp9CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2Y29sb3JfUzA7Cgljb25zdCBoYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KDEpOwoJaGFsZjQgb3V0cHV0X1MxOwoJb3V0cHV0X1MxID0gRGl0aGVyX1MxKG91dHB1dENvbG9yX1MwKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRfUzEgKiBvdXRwdXRDb3ZlcmFnZV9TMDsKCX0KfQoAAAABAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAgAAABwb3NpdGlvbgUAAABjb2xvcgAAAAoAAABsb2NhbENvb3JkAAAAAAAA","BYIBQAAABQAAIAABBYAAAEIXBAAP777777777777AAAAAAAAAAAABUABAAAAAEAAAAAIBEABAAAAA":"DAAAAExTS1M+AQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0MiBpblBvc2l0aW9uOwppbiBoYWxmNCBpbkNvbG9yOwpvdXQgaGFsZjQgdmNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBEZWZhdWx0R2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IGNvbG9yID0gaW5Db2xvcjsKCXZjb2xvcl9TMCA9IGNvbG9yOwoJZmxvYXQyIF90bXBfMV9pblBvc2l0aW9uID0gaW5Qb3NpdGlvbjsKCWZsb2F0MiBfdG1wXzNfaW5Qb3NpdGlvbiA9IGluUG9zaXRpb247Cglza19Qb3NpdGlvbiA9IF90bXBfMV9pblBvc2l0aW9uLnh5MDE7Cn0KAAAAAAAABgEAAGluIGhhbGY0IHZjb2xvcl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIERlZmF1bHRHZW9tZXRyeVByb2Nlc3NvcgoJaGFsZjQgb3V0cHV0Q29sb3JfUzA7CglvdXRwdXRDb2xvcl9TMCA9IHZjb2xvcl9TMDsKCWNvbnN0IGhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoMSk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRDb3ZlcmFnZV9TMDsKCX0KfQoAAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAACAAAACgAAAGluUG9zaXRpb24AAAcAAABpbkNvbG9yAAAAAAA=","B2ABSAAABQAAIAABBYAAB7777777777774ABICAAAAAAAAAAAAAABUABAAAAAEAAAAAIBEABAAAAA":"DAAAAExTS1N4AQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gaGFsZjQgdUNvbG9yX1MwOwppbiBmbG9hdDIgaW5Qb3NpdGlvbjsKaW4gaGFsZiBpbkNvdmVyYWdlOwpvdXQgaGFsZjQgdmNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBEZWZhdWx0R2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IGNvbG9yID0gdUNvbG9yX1MwOwoJY29sb3IgPSBjb2xvciAqIGluQ292ZXJhZ2U7Cgl2Y29sb3JfUzAgPSBjb2xvcjsKCWZsb2F0MiBfdG1wXzFfaW5Qb3NpdGlvbiA9IGluUG9zaXRpb247CglmbG9hdDIgX3RtcF8zX2luUG9zaXRpb24gPSBpblBvc2l0aW9uOwoJc2tfUG9zaXRpb24gPSBfdG1wXzFfaW5Qb3NpdGlvbi54eTAxOwp9CgAAAAAGAQAAaW4gaGFsZjQgdmNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgRGVmYXVsdEdlb21ldHJ5UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmNvbG9yX1MwOwoJY29uc3QgaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNCgxKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dENvdmVyYWdlX1MwOwoJfQp9CgAAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAKAAAAaW5Qb3NpdGlvbgAACgAAAGluQ292ZXJhZ2UAAAAAAAA=","HWQACAAAABAAADAAAIOAAAAADIIAAIRODAAP577774DSAIAA737777YBAAAAAAAAAAAHEADZAAAAAAIAAAAAAOQAAAAAAAQAAAABAMQAAAAAA":"DAAAAExTS1ONAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gZmxvYXQgY292ZXJhZ2U7CmluIGhhbGY0IGNvbG9yOwppbiBmbG9hdDQgZ2VvbVN1YnNldDsKZmxhdCBvdXQgaGFsZjQgdmNvbG9yX1MwOwpvdXQgZmxvYXQgdmNvdmVyYWdlX1MwOwpmbGF0IG91dCBmbG9hdDQgdmdlb21TdWJzZXRfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJZmxvYXQyIHBvc2l0aW9uID0gcG9zaXRpb24ueHk7Cgl2Y29sb3JfUzAgPSBjb2xvcjsKCXZjb3ZlcmFnZV9TMCA9IGNvdmVyYWdlOwoJdmdlb21TdWJzZXRfUzAgPSBnZW9tU3Vic2V0OwoJc2tfUG9zaXRpb24gPSBwb3NpdGlvbi54eTAxOwp9CgAAAAEAAAAIBAAAdW5pZm9ybSBmbG9hdDQgdWlubmVyUmVjdF9TMTsKdW5pZm9ybSBoYWxmMiB1cmFkaXVzUGx1c0hhbGZfUzE7CmZsYXQgaW4gaGFsZjQgdmNvbG9yX1MwOwppbiBmbG9hdCB2Y292ZXJhZ2VfUzA7CmZsYXQgaW4gZmxvYXQ0IHZnZW9tU3Vic2V0X1MwOwpoYWxmNCBDaXJjdWxhclJSZWN0X1MxKGhhbGY0IF9pbnB1dCkgCnsKCWZsb2F0MiBkeHkwID0gdWlubmVyUmVjdF9TMS5MVCAtIHNrX0ZyYWdDb29yZC54eTsKCWZsb2F0MiBkeHkxID0gc2tfRnJhZ0Nvb3JkLnh5IC0gdWlubmVyUmVjdF9TMS5SQjsKCWZsb2F0MiBkeHkgPSBtYXgobWF4KGR4eTAsIGR4eTEpLCAwLjApOwoJaGFsZiBhbHBoYSA9IGhhbGYoc2F0dXJhdGUodXJhZGl1c1BsdXNIYWxmX1MxLnggLSBsZW5ndGgoZHh5KSkpOwoJcmV0dXJuIF9pbnB1dCAqIGFscGhhOwp9CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2Y29sb3JfUzA7CglmbG9hdCBjb3ZlcmFnZSA9IHZjb3ZlcmFnZV9TMDsKCWZsb2F0NCBnZW9TdWJzZXQ7CglnZW9TdWJzZXQgPSB2Z2VvbVN1YnNldF9TMDsKCWhhbGY0IGRpc3RzNCA9IGNsYW1wKGhhbGY0KDEsIDEsIC0xLCAtMSkgKiBoYWxmNChza19GcmFnQ29vcmQueHl4eSAtIGdlb1N1YnNldCksIDAsIDEpOwoJaGFsZjIgZGlzdHMyID0gZGlzdHM0Lnh5ICsgZGlzdHM0Lnp3IC0gMTsKCWhhbGYgc3Vic2V0Q292ZXJhZ2UgPSBkaXN0czIueCAqIGRpc3RzMi55OwoJY292ZXJhZ2UgPSBtaW4oY292ZXJhZ2UsIHN1YnNldENvdmVyYWdlKTsKCWhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoaGFsZihjb3ZlcmFnZSkpOwoJaGFsZjQgb3V0cHV0X1MxOwoJb3V0cHV0X1MxID0gQ2lyY3VsYXJSUmVjdF9TMShvdXRwdXRDb3ZlcmFnZV9TMCk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRfUzE7Cgl9Cn0KAQAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAIAAAAcG9zaXRpb24IAAAAY292ZXJhZ2UFAAAAY29sb3IAAAAKAAAAZ2VvbVN1YnNldAAAAAAAAA==","HTQAAGAABBYAAAEIXBAAAGEAMAAAAAAAAAAAAAAAQAHAAAAAQAAAAAAAQQGAAAAA":"DAAAAExTS1M/AQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0MiBpblBvc2l0aW9uOwppbiBoYWxmNCBpbkNvbG9yOwppbiBmbG9hdDQgaW5RdWFkRWRnZTsKb3V0IGZsb2F0NCB2UXVhZEVkZ2VfUzA7Cm91dCBoYWxmNCB2aW5Db2xvcl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZEVkZ2UKCXZRdWFkRWRnZV9TMCA9IGluUXVhZEVkZ2U7Cgl2aW5Db2xvcl9TMCA9IGluQ29sb3I7CglmbG9hdDIgX3RtcF8wX2luUG9zaXRpb24gPSBpblBvc2l0aW9uOwoJc2tfUG9zaXRpb24gPSBfdG1wXzBfaW5Qb3NpdGlvbi54eTAxOwp9CgABAAAABQMAAGluIGZsb2F0NCB2UXVhZEVkZ2VfUzA7CmluIGhhbGY0IHZpbkNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgUXVhZEVkZ2UKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2aW5Db2xvcl9TMDsKCWhhbGYgZWRnZUFscGhhOwoJaGFsZjIgZHV2ZHggPSBoYWxmMihkRmR4KHZRdWFkRWRnZV9TMC54eSkpOwoJaGFsZjIgZHV2ZHkgPSBoYWxmMihkRmR5KHZRdWFkRWRnZV9TMC54eSkpOwoJaWYgKHZRdWFkRWRnZV9TMC56ID4gMC4wICYmIHZRdWFkRWRnZV9TMC53ID4gMC4wKSAKCXsKCQllZGdlQWxwaGEgPSBoYWxmKG1pbihtaW4odlF1YWRFZGdlX1MwLnosIHZRdWFkRWRnZV9TMC53KSArIDAuNSwgMS4wKSk7Cgl9CgllbHNlIAoJewoJCWhhbGYyIGdGID0gaGFsZjIoaGFsZigyLjAqdlF1YWRFZGdlX1MwLngqZHV2ZHgueCAtIGR1dmR4LnkpLCAgICAgICAgICAgICAgICAgaGFsZigyLjAqdlF1YWRFZGdlX1MwLngqZHV2ZHkueCAtIGR1dmR5LnkpKTsKCQllZGdlQWxwaGEgPSBoYWxmKHZRdWFkRWRnZV9TMC54KnZRdWFkRWRnZV9TMC54IC0gdlF1YWRFZGdlX1MwLnkpOwoJCWVkZ2VBbHBoYSA9IHNhdHVyYXRlKDAuNSAtIGVkZ2VBbHBoYSAvIGxlbmd0aChnRikpOwoJfQoJaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNChlZGdlQWxwaGEpOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dENvbG9yX1MwICogb3V0cHV0Q292ZXJhZ2VfUzA7Cgl9Cn0KAAAAAQAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAKAAAAaW5Qb3NpdGlvbgAABwAAAGluQ29sb3IACgAAAGluUXVhZEVkZ2UAAAAAAAA=","HUIAAAAAAAQAADAAAIOAAAH677777777777QGHAQAD7P7777777777YBAAAAAAAAAAALUASJ3EZYN2AAAAACAAAEAAAABSCQKL3IYIJ2AAAAACAAAEAAAABLRAABAAAAABAEGABBAMAAQAAAAAAAAOQAAAAAAAQAAAABAMQAAAAAA":"DAAAAExTS1M2AQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMTsKaW4gZmxvYXQyIHBvc2l0aW9uOwppbiBmbG9hdDIgbG9jYWxDb29yZDsKb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCglza19Qb3NpdGlvbiA9IHBvc2l0aW9uLnh5MDE7Cgl7CgkJdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzAgPSBmbG9hdDN4Mih1bWF0cml4X1MxKSAqIGxvY2FsQ29vcmQueHkxOwoJfQp9CgAAAAAAAGgHAABjb25zdCBpbnQga01heExvb3BMaW1pdF9TMV9jMCA9IDg7CnVuaWZvcm0gaGFsZjQgdWJvcmRlcl9TMV9jMF9jMF9jMDsKdW5pZm9ybSBmbG9hdDQgdXN1YnNldF9TMV9jMF9jMF9jMDsKdW5pZm9ybSBmbG9hdDQgdWNsYW1wX1MxX2MwX2MwX2MwOwp1bmlmb3JtIGZsb2F0MiB1aWRpbXNfUzFfYzBfYzBfYzA7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMV9jMF9jMDsKdW5pZm9ybSBoYWxmNCB1b2Zmc2V0c0FuZEtlcm5lbF9TMV9jMFsxNF07CnVuaWZvcm0gaGFsZjIgdWRpcl9TMV9jMDsKdW5pZm9ybSBmbG9hdDN4MyB1bWF0cml4X1MxOwpzYW1wbGVyMkQgdVRleHR1cmVTYW1wbGVyXzBfUzE7CmluIGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKaGFsZjQgVGV4dHVyZUVmZmVjdF9TMV9jMF9jMF9jMChoYWxmNCBfaW5wdXQsIGZsb2F0MiBfY29vcmRzKSAKewoJZmxvYXQyIGluQ29vcmQgPSBfY29vcmRzOwoJZmxvYXQyIHN1YnNldENvb3JkOwoJc3Vic2V0Q29vcmQueCA9IGluQ29vcmQueDsKCXN1YnNldENvb3JkLnkgPSBpbkNvb3JkLnk7CglmbG9hdDIgY2xhbXBlZENvb3JkOwoJY2xhbXBlZENvb3JkLnggPSBjbGFtcChzdWJzZXRDb29yZC54LCB1Y2xhbXBfUzFfYzBfYzBfYzAueCwgdWNsYW1wX1MxX2MwX2MwX2MwLnopOwoJY2xhbXBlZENvb3JkLnkgPSBzdWJzZXRDb29yZC55OwoJaGFsZjQgdGV4dHVyZUNvbG9yID0gc2FtcGxlKHVUZXh0dXJlU2FtcGxlcl8wX1MxLCAoY2xhbXBlZENvb3JkKSAqIHVpZGltc19TMV9jMF9jMF9jMCk7CgloYWxmIGVyclggPSBoYWxmKHN1YnNldENvb3JkLnggLSBjbGFtcGVkQ29vcmQueCk7Cgl0ZXh0dXJlQ29sb3IgPSBtaXgodGV4dHVyZUNvbG9yLCB1Ym9yZGVyX1MxX2MwX2MwX2MwLCBtaW4oYWJzKGVyclgpLCAxKSk7CglyZXR1cm4gdGV4dHVyZUNvbG9yOwp9CmhhbGY0IE1hdHJpeEVmZmVjdF9TMV9jMF9jMChoYWxmNCBfaW5wdXQsIGZsb2F0MiBfY29vcmRzKSAKewoJcmV0dXJuIFRleHR1cmVFZmZlY3RfUzFfYzBfYzBfYzAoX2lucHV0LCBmbG9hdDN4Mih1bWF0cml4X1MxX2MwX2MwKSAqIF9jb29yZHMueHkxKTsKfQpoYWxmNCBHYXVzc2lhbkJsdXIxRF9TMV9jMChoYWxmNCBfaW5wdXQpIAp7CgloYWxmNCBfdG1wXzBfaW5Db2xvciA9IF9pbnB1dDsKCWZsb2F0MiBfdG1wXzFfY29vcmRzID0gdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzA7CgloYWxmNCBzdW0gPSBoYWxmNCgwLjApOwoJZm9yIChpbnQgaSA9IDA7aSA8IGtNYXhMb29wTGltaXRfUzFfYzA7ICsraSkgCgl7CgkJaGFsZjQgcyA9IHVvZmZzZXRzQW5kS2VybmVsX1MxX2MwW2ldOwoJCXN1bSArPSBzLnkgKiBNYXRyaXhFZmZlY3RfUzFfYzBfYzAoX3RtcF8wX2luQ29sb3IsIF90bXBfMV9jb29yZHMgKyBmbG9hdDIocy54ICogdWRpcl9TMV9jMCkpOwoJCXN1bSArPSBzLncgKiBNYXRyaXhFZmZlY3RfUzFfYzBfYzAoX3RtcF8wX2luQ29sb3IsIF90bXBfMV9jb29yZHMgKyBmbG9hdDIocy56ICogdWRpcl9TMV9jMCkpOwoJfQoJcmV0dXJuIGhhbGY0KHN1bSk7Cn0KaGFsZjQgTWF0cml4RWZmZWN0X1MxKGhhbGY0IF9pbnB1dCkgCnsKCXJldHVybiBHYXVzc2lhbkJsdXIxRF9TMV9jMChfaW5wdXQpOwp9CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwID0gaGFsZjQoMSk7Cgljb25zdCBoYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KDEpOwoJaGFsZjQgb3V0cHV0X1MxOwoJb3V0cHV0X1MxID0gTWF0cml4RWZmZWN0X1MxKG91dHB1dENvbG9yX1MwKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRfUzEgKiBvdXRwdXRDb3ZlcmFnZV9TMDsKCX0KfQoAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAgAAABwb3NpdGlvbgoAAABsb2NhbENvb3JkAAAAAAAA","HUQAAAAAAAMAADAAAIOAAAH677776IZOCAAP577777777777777777YBAAAAAAAAAAADEAAGAAAAAAAAAIAAAAAPAIABAAAAACYGEAAAAEAAAABUARCAIAAAAAAAAAAAACQAGAAAAAQAAAAAAAQQGAAAAA":"DAAAAExTS1NoAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMV9jMF9jMDsKaW4gZmxvYXQyIHBvc2l0aW9uOwppbiBoYWxmNCBjb2xvcjsKZmxhdCBvdXQgaGFsZjQgdmNvbG9yX1MwOwpvdXQgZmxvYXQyIHZUcmFuc2Zvcm1lZENvb3Jkc180X1MwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCXZjb2xvcl9TMCA9IGNvbG9yOwoJc2tfUG9zaXRpb24gPSBwb3NpdGlvbi54eTAxOwoJewoJCXZUcmFuc2Zvcm1lZENvb3Jkc180X1MwID0gZmxvYXQzeDIodW1hdHJpeF9TMV9jMF9jMCkgKiBwb3NpdGlvbi54eTE7Cgl9Cn0KAAAAADkDAAB1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzFfYzBfYzA7CnNhbXBsZXIyRCB1VGV4dHVyZVNhbXBsZXJfMF9TMTsKZmxhdCBpbiBoYWxmNCB2Y29sb3JfUzA7CmluIGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfNF9TMDsKaGFsZjQgVGV4dHVyZUVmZmVjdF9TMV9jMF9jMF9jMChoYWxmNCBfaW5wdXQpIAp7CglyZXR1cm4gc2FtcGxlKHVUZXh0dXJlU2FtcGxlcl8wX1MxLCB2VHJhbnNmb3JtZWRDb29yZHNfNF9TMCkuMDAwcjsKfQpoYWxmNCBNYXRyaXhFZmZlY3RfUzFfYzBfYzAoaGFsZjQgX2lucHV0KSAKewoJcmV0dXJuIFRleHR1cmVFZmZlY3RfUzFfYzBfYzBfYzAoX2lucHV0KTsKfQpoYWxmNCBEZXZpY2VTcGFjZV9TMV9jMChoYWxmNCBfaW5wdXQpIAp7CglyZXR1cm4gTWF0cml4RWZmZWN0X1MxX2MwX2MwKF9pbnB1dCk7Cn0KaGFsZjQgQmxlbmRfUzEoaGFsZjQgX3NyYywgaGFsZjQgX2RzdCkgCnsKCXJldHVybiBibGVuZF9kc3RfaW4oRGV2aWNlU3BhY2VfUzFfYzAoX3NyYyksIF9zcmMpOwp9CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2Y29sb3JfUzA7Cgljb25zdCBoYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KDEpOwoJaGFsZjQgb3V0cHV0X1MxOwoJb3V0cHV0X1MxID0gQmxlbmRfUzEob3V0cHV0Q292ZXJhZ2VfUzAsIGhhbGY0KDEpKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dF9TMTsKCX0KfQoAAAAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAgAAABwb3NpdGlvbgUAAABjb2xvcgAAAAAAAAA=","HVIAAAAAABIAAGAAAQ4AAAH477776R24EAAAIOBQAD6P7777777777YDAAAAAAAAAAAFIBVWKMG7QAAAAAAAAAQCAAAAAVQEEAQAAAAAQCDAAQQGAAAAEAAAAAAHIAAAAAAAIAAAAAQGIAAAAAAA":"DAAAAExTS1N6AQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMV9jMDsKaW4gZmxvYXQyIHBvc2l0aW9uOwppbiBoYWxmNCBjb2xvcjsKaW4gZmxvYXQyIGxvY2FsQ29vcmQ7CmZsYXQgb3V0IGhhbGY0IHZjb2xvcl9TMDsKb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfM19TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgl2Y29sb3JfUzAgPSBjb2xvcjsKCXNrX1Bvc2l0aW9uID0gcG9zaXRpb24ueHkwMTsKCXsKCQl2VHJhbnNmb3JtZWRDb29yZHNfM19TMCA9IGZsb2F0M3gyKHVtYXRyaXhfUzFfYzApICogbG9jYWxDb29yZC54eTE7Cgl9Cn0KAAAAAAAAQgQAAHVuaWZvcm0gZmxvYXQ0IHVjbGFtcF9TMV9jMF9jMDsKdW5pZm9ybSBmbG9hdDN4MyB1bWF0cml4X1MxX2MwOwpzYW1wbGVyMkQgdVRleHR1cmVTYW1wbGVyXzBfUzE7CmZsYXQgaW4gaGFsZjQgdmNvbG9yX1MwOwppbiBmbG9hdDIgdlRyYW5zZm9ybWVkQ29vcmRzXzNfUzA7CmhhbGY0IFRleHR1cmVFZmZlY3RfUzFfYzBfYzAoaGFsZjQgX2lucHV0KSAKewoJZmxvYXQyIGluQ29vcmQgPSB2VHJhbnNmb3JtZWRDb29yZHNfM19TMDsKCWZsb2F0MiBzdWJzZXRDb29yZDsKCXN1YnNldENvb3JkLnggPSBpbkNvb3JkLng7CglzdWJzZXRDb29yZC55ID0gaW5Db29yZC55OwoJZmxvYXQyIGNsYW1wZWRDb29yZDsKCWNsYW1wZWRDb29yZC54ID0gc3Vic2V0Q29vcmQueDsKCWNsYW1wZWRDb29yZC55ID0gY2xhbXAoc3Vic2V0Q29vcmQueSwgdWNsYW1wX1MxX2MwX2MwLnksIHVjbGFtcF9TMV9jMF9jMC53KTsKCWhhbGY0IHRleHR1cmVDb2xvciA9IHNhbXBsZSh1VGV4dHVyZVNhbXBsZXJfMF9TMSwgY2xhbXBlZENvb3JkKTsKCXJldHVybiB0ZXh0dXJlQ29sb3I7Cn0KaGFsZjQgTWF0cml4RWZmZWN0X1MxX2MwKGhhbGY0IF9pbnB1dCkgCnsKCXJldHVybiBUZXh0dXJlRWZmZWN0X1MxX2MwX2MwKF9pbnB1dCk7Cn0KaGFsZjQgRGlzYWJsZUNvdmVyYWdlQXNBbHBoYV9TMShoYWxmNCBfaW5wdXQpIAp7CglfaW5wdXQgPSBNYXRyaXhFZmZlY3RfUzFfYzAoX2lucHV0KTsKCWhhbGY0IF90bXBfMF9pbkNvbG9yID0gX2lucHV0OwoJcmV0dXJuIGhhbGY0KF9pbnB1dCk7Cn0Kdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJaGFsZjQgb3V0cHV0Q29sb3JfUzA7CglvdXRwdXRDb2xvcl9TMCA9IHZjb2xvcl9TMDsKCWNvbnN0IGhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoMSk7CgloYWxmNCBvdXRwdXRfUzE7CglvdXRwdXRfUzEgPSBEaXNhYmxlQ292ZXJhZ2VBc0FscGhhX1MxKG91dHB1dENvbG9yX1MwKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRfUzEgKiBvdXRwdXRDb3ZlcmFnZV9TMDsKCX0KfQoAAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAADAAAACAAAAHBvc2l0aW9uBQAAAGNvbG9yAAAACgAAAGxvY2FsQ29vcmQAAAAAAAA=","HVIACAAAABQAAGAAAQ4AAAAAGQQAARC4GAAAIOCAAD6P7777777777YDAAAAAAAAAAAHQBNGZODK5YIAAAAAAQAAAAAIADCNS4GV3QYBAAAAAAAAAAAIAA6IAMAAACAAAAAABUABAAAAAEAAAAAIBEABAA":"DAAAAExTS1PZAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMTsKaW4gZmxvYXQyIHBvc2l0aW9uOwppbiBmbG9hdCBjb3ZlcmFnZTsKaW4gaGFsZjQgY29sb3I7CmluIGZsb2F0MiBsb2NhbENvb3JkOwpmbGF0IG91dCBoYWxmNCB2Y29sb3JfUzA7Cm91dCBmbG9hdCB2Y292ZXJhZ2VfUzA7Cm91dCBmbG9hdDIgdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJZmxvYXQyIHBvc2l0aW9uID0gcG9zaXRpb24ueHk7Cgl2Y29sb3JfUzAgPSBjb2xvcjsKCXZjb3ZlcmFnZV9TMCA9IGNvdmVyYWdlOwoJc2tfUG9zaXRpb24gPSBwb3NpdGlvbi54eTAxOwoJewoJCXZUcmFuc2Zvcm1lZENvb3Jkc18yX1MwID0gZmxvYXQzeDIodW1hdHJpeF9TMSkgKiBsb2NhbENvb3JkLnh5MTsKCX0KfQoAAAABAAAAWR0AAGZsb2F0NCBmbHV0dGVyX0ZyYWdDb29yZF9TMV9jMDsKZmxvYXQ0IGZyYWdDb2xvcl9TMV9jMDsKZmxvYXQgdV9hbHBoYV9TMV9jMDsKZmxvYXQgdV9zcGFya2xlX2FscGhhX1MxX2MwOwpmbG9hdCB1X2JsdXJfUzFfYzA7CmZsb2F0IHVfcmFkaXVzX3NjYWxlX1MxX2MwOwp1bmlmb3JtIGZsb2F0NCB1X2NvbG9yX1MxX2MwOwp1bmlmb3JtIGZsb2F0NCB1X2NvbXBvc2l0ZV8xX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X2NlbnRlcl9TMV9jMDsKdW5pZm9ybSBmbG9hdCB1X21heF9yYWRpdXNfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfcmVzb2x1dGlvbl9zY2FsZV9TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9ub2lzZV9zY2FsZV9TMV9jMDsKdW5pZm9ybSBmbG9hdCB1X25vaXNlX3BoYXNlX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X2NpcmNsZTFfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfY2lyY2xlMl9TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9jaXJjbGUzX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X3JvdGF0aW9uMV9TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9yb3RhdGlvbjJfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfcm90YXRpb24zX1MxX2MwOwp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzE7CnVuaWZvcm0gZmxvYXQ0IHVpbm5lclJlY3RfUzI7CnVuaWZvcm0gaGFsZjIgdXJhZGl1c1BsdXNIYWxmX1MyOwpmbGF0IGluIGhhbGY0IHZjb2xvcl9TMDsKaW4gZmxvYXQgdmNvdmVyYWdlX1MwOwppbiBmbG9hdDIgdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzA7CmZsb2F0MiBGTFRfZmx1dHRlcl9sb2NhbF9GbHV0dGVyRnJhZ0Nvb3JkX1MxX2MwKCk7CmZsb2F0MngyIEZMVF9mbHV0dGVyX2xvY2FsX3JvdGF0ZTJkX1MxX2MwKGZsb2F0MiByYWQpOwpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X2NpcmNsZV9TMV9jMChmbG9hdDIgdXYsIGZsb2F0MiB4eSwgZmxvYXQgcmFkaXVzLCBmbG9hdCBibHVyKTsKZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfY2lyY2xlX2dyaWRfUzFfYzAoZmxvYXQyIHJlc29sdXRpb24sIGlub3V0IGZsb2F0MiBwLCBmbG9hdDIgeHksIGZsb2F0MiByb3RhdGlvbiwgZmxvYXQgY2VsbF9kaWFtZXRlcik7CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3R1cmJ1bGVuY2VfUzFfYzAoZmxvYXQyIHV2KTsKZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9yaW5nX1MxX2MwKGZsb2F0MiB1diwgZmxvYXQyIHh5LCBmbG9hdCByYWRpdXMsIGZsb2F0IHRoaWNrbmVzcywgZmxvYXQgYmx1cik7CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3RyaWFuZ2xlX25vaXNlX1MxX2MwKGlub3V0IGZsb2F0MiBuKTsKZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfdGhyZXNob2xkX1MxX2MwKGZsb2F0IHYsIGZsb2F0IGwsIGZsb2F0IGgpOwpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9zcGFya2xlX1MxX2MwKGZsb2F0MiB1diwgZmxvYXQgdCk7CnZvaWQgRkxUX21haW5fUzFfYzAoKTsKZmxvYXQyIEZMVF9mbHV0dGVyX2xvY2FsX0ZsdXR0ZXJGcmFnQ29vcmRfUzFfYzAoKSAKewoJcmV0dXJuIGZsdXR0ZXJfRnJhZ0Nvb3JkX1MxX2MwLnh5Owp9CmZsb2F0MngyIEZMVF9mbHV0dGVyX2xvY2FsX3JvdGF0ZTJkX1MxX2MwKGZsb2F0MiByYWQpIAp7CglyZXR1cm4gZmxvYXQyeDIocmFkLngsIC1yYWQueSwgcmFkLnksIHJhZC54KTsKfQpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X2NpcmNsZV9TMV9jMChmbG9hdDIgdXYsIGZsb2F0MiB4eSwgZmxvYXQgcmFkaXVzLCBmbG9hdCBibHVyKSAKewoJZmxvYXQgYmx1cl9oYWxmID0gYmx1ciAqIDAuNTsKCWZsb2F0IGQgPSBkaXN0YW5jZSh1diwgeHkpOwoJcmV0dXJuIDEuMCAtIHNtb290aHN0ZXAoMS4wIC0gYmx1cl9oYWxmLCAxLjAgKyBibHVyX2hhbGYsIGQgLyByYWRpdXMpOwp9CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX2NpcmNsZV9ncmlkX1MxX2MwKGZsb2F0MiByZXNvbHV0aW9uLCBpbm91dCBmbG9hdDIgcCwgZmxvYXQyIHh5LCBmbG9hdDIgcm90YXRpb24sIGZsb2F0IGNlbGxfZGlhbWV0ZXIpIAp7CglmbG9hdDIgcGFyYW0gPSByb3RhdGlvbjsKCXAgPSBGTFRfZmx1dHRlcl9sb2NhbF9yb3RhdGUyZF9TMV9jMChwYXJhbSkgKiAoeHkgLSBwKSArIHh5OwoJcCA9IG1vZChwLCBmbG9hdDIoY2VsbF9kaWFtZXRlcikpIC8gcmVzb2x1dGlvbjsKCWZsb2F0IGNlbGxfdXYgPSAoY2VsbF9kaWFtZXRlciAvIHJlc29sdXRpb24ueSkgKiAwLjU7CglmbG9hdCByID0gMC42NSAqIGNlbGxfdXY7CglmbG9hdDIgcGFyYW1fMSA9IHA7CglmbG9hdDIgcGFyYW1fMiA9IGZsb2F0MihjZWxsX3V2KTsKCWZsb2F0IHBhcmFtXzMgPSByOwoJZmxvYXQgcGFyYW1fNCA9IHIgKiA1MC4wOwoJcmV0dXJuIEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfY2lyY2xlX1MxX2MwKHBhcmFtXzEsIHBhcmFtXzIsIHBhcmFtXzMsIHBhcmFtXzQpOwp9CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3R1cmJ1bGVuY2VfUzFfYzAoZmxvYXQyIHV2KSAKewoJZmxvYXQyIHV2X3NjYWxlID0gdXYgKiBmbG9hdDIoMC44KTsKCWZsb2F0MiBwYXJhbSA9IGZsb2F0MigwLjgpOwoJZmxvYXQyIHBhcmFtXzEgPSB1dl9zY2FsZTsKCWZsb2F0MiBwYXJhbV8yID0gdV9jaXJjbGUxX1MxX2MwOwoJZmxvYXQyIHBhcmFtXzMgPSB1X3JvdGF0aW9uMV9TMV9jMDsKCWZsb2F0IHBhcmFtXzQgPSAwLjE3OwoJZmxvYXQgXzMxOSA9IEZMVF9mbHV0dGVyX2xvY2FsX2NpcmNsZV9ncmlkX1MxX2MwKHBhcmFtLCBwYXJhbV8xLCBwYXJhbV8yLCBwYXJhbV8zLCBwYXJhbV80KTsKCWZsb2F0IGcxID0gXzMxOTsKCWZsb2F0MiBwYXJhbV81ID0gZmxvYXQyKDAuOCk7CglmbG9hdDIgcGFyYW1fNiA9IHV2X3NjYWxlOwoJZmxvYXQyIHBhcmFtXzcgPSB1X2NpcmNsZTJfUzFfYzA7CglmbG9hdDIgcGFyYW1fOCA9IHVfcm90YXRpb24yX1MxX2MwOwoJZmxvYXQgcGFyYW1fOSA9IDAuMjsKCWZsb2F0IF8zMzEgPSBGTFRfZmx1dHRlcl9sb2NhbF9jaXJjbGVfZ3JpZF9TMV9jMChwYXJhbV81LCBwYXJhbV82LCBwYXJhbV83LCBwYXJhbV84LCBwYXJhbV85KTsKCWZsb2F0IGcyID0gXzMzMTsKCWZsb2F0MiBwYXJhbV8xMCA9IGZsb2F0MigwLjgpOwoJZmxvYXQyIHBhcmFtXzExID0gdXZfc2NhbGU7CglmbG9hdDIgcGFyYW1fMTIgPSB1X2NpcmNsZTNfUzFfYzA7CglmbG9hdDIgcGFyYW1fMTMgPSB1X3JvdGF0aW9uM19TMV9jMDsKCWZsb2F0IHBhcmFtXzE0ID0gMC4yNzU7CglmbG9hdCBfMzQ0ID0gRkxUX2ZsdXR0ZXJfbG9jYWxfY2lyY2xlX2dyaWRfUzFfYzAocGFyYW1fMTAsIHBhcmFtXzExLCBwYXJhbV8xMiwgcGFyYW1fMTMsIHBhcmFtXzE0KTsKCWZsb2F0IGczID0gXzM0NDsKCWZsb2F0IHYgPSAoKGcxICogZzEgKyBnMikgLSBnMykgKiAwLjU7CglyZXR1cm4gY2xhbXAoMC40NSArIDAuOCAqIHYsIDAuMCwgMS4wKTsKfQpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X3JpbmdfUzFfYzAoZmxvYXQyIHV2LCBmbG9hdDIgeHksIGZsb2F0IHJhZGl1cywgZmxvYXQgdGhpY2tuZXNzLCBmbG9hdCBibHVyKSAKewoJZmxvYXQyIHBhcmFtID0gdXY7CglmbG9hdDIgcGFyYW1fMSA9IHh5OwoJZmxvYXQgcGFyYW1fMiA9IHJhZGl1cyArIHRoaWNrbmVzczsKCWZsb2F0IHBhcmFtXzMgPSBibHVyOwoJZmxvYXQgY2lyY2xlX291dGVyID0gRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9jaXJjbGVfUzFfYzAocGFyYW0sIHBhcmFtXzEsIHBhcmFtXzIsIHBhcmFtXzMpOwoJZmxvYXQyIHBhcmFtXzQgPSB1djsKCWZsb2F0MiBwYXJhbV81ID0geHk7CglmbG9hdCBwYXJhbV82ID0gbWF4KHJhZGl1cyAtIHRoaWNrbmVzcywgMC4wKTsKCWZsb2F0IHBhcmFtXzcgPSBibHVyOwoJZmxvYXQgY2lyY2xlX2lubmVyID0gRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9jaXJjbGVfUzFfYzAocGFyYW1fNCwgcGFyYW1fNSwgcGFyYW1fNiwgcGFyYW1fNyk7CglyZXR1cm4gY2xhbXAoY2lyY2xlX291dGVyIC0gY2lyY2xlX2lubmVyLCAwLjAsIDEuMCk7Cn0KZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfdHJpYW5nbGVfbm9pc2VfUzFfYzAoaW5vdXQgZmxvYXQyIG4pIAp7CgluID0gZnJhY3QobiAqIGZsb2F0Mig1LjM5ODcsIDUuNDQyMSkpOwoJbiArPSBmbG9hdDIoZG90KG4ueXgsIG4gKyBmbG9hdDIoMjEuNTM1MSwgMTQuMzEzNykpKTsKCWZsb2F0IHh5ID0gbi54ICogbi55OwoJcmV0dXJuIChmcmFjdCh4eSAqIDk1LjQzMDcpICsgZnJhY3QoeHkgKiA3NS4wNDk2MSkpIC0gMS4wOwp9CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3RocmVzaG9sZF9TMV9jMChmbG9hdCB2LCBmbG9hdCBsLCBmbG9hdCBoKSAKewoJcmV0dXJuIHN0ZXAobCwgdikgKiAoMS4wIC0gc3RlcChoLCB2KSk7Cn0KZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfc3BhcmtsZV9TMV9jMChmbG9hdDIgdXYsIGZsb2F0IHQpIAp7CglmbG9hdDIgcGFyYW0gPSB1djsKCWZsb2F0IF8yNDIgPSBGTFRfZmx1dHRlcl9sb2NhbF90cmlhbmdsZV9ub2lzZV9TMV9jMChwYXJhbSk7CglmbG9hdCBuID0gXzI0MjsKCWZsb2F0IHBhcmFtXzEgPSBuOwoJZmxvYXQgcGFyYW1fMiA9IDAuMDsKCWZsb2F0IHBhcmFtXzMgPSAwLjA1OwoJZmxvYXQgcyA9IEZMVF9mbHV0dGVyX2xvY2FsX3RocmVzaG9sZF9TMV9jMChwYXJhbV8xLCBwYXJhbV8yLCBwYXJhbV8zKTsKCWZsb2F0IHBhcmFtXzQgPSBuICsgc2luKDMuMTQxNTkyNzQgKiAodCArIDAuMzUpKTsKCWZsb2F0IHBhcmFtXzUgPSAwLjE7CglmbG9hdCBwYXJhbV82ID0gMC4xNTsKCXMgKz0gRkxUX2ZsdXR0ZXJfbG9jYWxfdGhyZXNob2xkX1MxX2MwKHBhcmFtXzQsIHBhcmFtXzUsIHBhcmFtXzYpOwoJZmxvYXQgcGFyYW1fNyA9IG4gKyBzaW4oMy4xNDE1OTI3NCAqICh0ICsgMC43KSk7CglmbG9hdCBwYXJhbV84ID0gMC4yOwoJZmxvYXQgcGFyYW1fOSA9IDAuMjU7CglzICs9IEZMVF9mbHV0dGVyX2xvY2FsX3RocmVzaG9sZF9TMV9jMChwYXJhbV83LCBwYXJhbV84LCBwYXJhbV85KTsKCWZsb2F0IHBhcmFtXzEwID0gbiArIHNpbigzLjE0MTU5Mjc0ICogKHQgKyAxLjA1KSk7CglmbG9hdCBwYXJhbV8xMSA9IDAuMzsKCWZsb2F0IHBhcmFtXzEyID0gMC4zNTsKCXMgKz0gRkxUX2ZsdXR0ZXJfbG9jYWxfdGhyZXNob2xkX1MxX2MwKHBhcmFtXzEwLCBwYXJhbV8xMSwgcGFyYW1fMTIpOwoJcmV0dXJuIGNsYW1wKHMsIDAuMCwgMS4wKSAqIDAuNTU7Cn0Kdm9pZCBGTFRfbWFpbl9TMV9jMCgpIAp7Cgl1X2FscGhhX1MxX2MwID0gdV9jb21wb3NpdGVfMV9TMV9jMC54OwoJdV9zcGFya2xlX2FscGhhX1MxX2MwID0gdV9jb21wb3NpdGVfMV9TMV9jMC55OwoJdV9ibHVyX1MxX2MwID0gdV9jb21wb3NpdGVfMV9TMV9jMC56OwoJdV9yYWRpdXNfc2NhbGVfUzFfYzAgPSB1X2NvbXBvc2l0ZV8xX1MxX2MwLnc7CglmbG9hdDIgcCA9IEZMVF9mbHV0dGVyX2xvY2FsX0ZsdXR0ZXJGcmFnQ29vcmRfUzFfYzAoKTsKCWZsb2F0MiB1dl8xID0gcCAqIHVfcmVzb2x1dGlvbl9zY2FsZV9TMV9jMDsKCWZsb2F0MiBkZW5zaXR5X3V2ID0gdXZfMSAtIG1vZChwLCB1X25vaXNlX3NjYWxlX1MxX2MwKTsKCWZsb2F0IHJhZGl1cyA9IHVfbWF4X3JhZGl1c19TMV9jMCAqIHVfcmFkaXVzX3NjYWxlX1MxX2MwOwoJZmxvYXQyIHBhcmFtXzEzID0gdXZfMTsKCWZsb2F0IHR1cmJ1bGVuY2UgPSBGTFRfZmx1dHRlcl9sb2NhbF90dXJidWxlbmNlX1MxX2MwKHBhcmFtXzEzKTsKCWZsb2F0MiBwYXJhbV8xNCA9IHA7CglmbG9hdDIgcGFyYW1fMTUgPSB1X2NlbnRlcl9TMV9jMDsKCWZsb2F0IHBhcmFtXzE2ID0gcmFkaXVzOwoJZmxvYXQgcGFyYW1fMTcgPSAwLjA1ICogdV9tYXhfcmFkaXVzX1MxX2MwOwoJZmxvYXQgcGFyYW1fMTggPSB1X2JsdXJfUzFfYzA7CglmbG9hdCByaW5nID0gRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9yaW5nX1MxX2MwKHBhcmFtXzE0LCBwYXJhbV8xNSwgcGFyYW1fMTYsIHBhcmFtXzE3LCBwYXJhbV8xOCk7CglmbG9hdDIgcGFyYW1fMTkgPSBkZW5zaXR5X3V2OwoJZmxvYXQgcGFyYW1fMjAgPSB1X25vaXNlX3BoYXNlX1MxX2MwOwoJZmxvYXQgc3BhcmtsZSA9ICgoRkxUX2ZsdXR0ZXJfbG9jYWxfc3BhcmtsZV9TMV9jMChwYXJhbV8xOSwgcGFyYW1fMjApICogcmluZykgKiB0dXJidWxlbmNlKSAqIHVfc3BhcmtsZV9hbHBoYV9TMV9jMDsKCWZsb2F0MiBwYXJhbV8yMSA9IHA7CglmbG9hdDIgcGFyYW1fMjIgPSB1X2NlbnRlcl9TMV9jMDsKCWZsb2F0IHBhcmFtXzIzID0gcmFkaXVzOwoJZmxvYXQgcGFyYW1fMjQgPSB1X2JsdXJfUzFfYzA7CglmbG9hdCB3YXZlX2FscGhhID0gKEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfY2lyY2xlX1MxX2MwKHBhcmFtXzIxLCBwYXJhbV8yMiwgcGFyYW1fMjMsIHBhcmFtXzI0KSAqIHVfYWxwaGFfUzFfYzApICogdV9jb2xvcl9TMV9jMC53OwoJZmxvYXQ0IHdhdmVfY29sb3IgPSBmbG9hdDQodV9jb2xvcl9TMV9jMC54eXogKiB3YXZlX2FscGhhLCB3YXZlX2FscGhhKTsKCWZyYWdDb2xvcl9TMV9jMCA9IG1peCh3YXZlX2NvbG9yLCBmbG9hdDQoMS4wKSwgZmxvYXQ0KHNwYXJrbGUpKTsKfQpoYWxmNCBydW50aW1lX3NoYWRlcl9TMV9jMChoYWxmNCBfaW5wdXQpIAp7CgloYWxmNCBfdG1wXzBfaW5Db2xvciA9IF9pbnB1dDsKCWZsb2F0MiBfdG1wXzFfY29vcmRzID0gdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzA7CglmbHV0dGVyX0ZyYWdDb29yZF9TMV9jMCA9IGZsb2F0NChfdG1wXzFfY29vcmRzLCAwLjAsIDAuMCk7CglGTFRfbWFpbl9TMV9jMCgpOwoJcmV0dXJuIGhhbGY0KGhhbGY0KGZyYWdDb2xvcl9TMV9jMCkpOwp9CmhhbGY0IE1hdHJpeEVmZmVjdF9TMShoYWxmNCBfaW5wdXQpIAp7CglyZXR1cm4gcnVudGltZV9zaGFkZXJfUzFfYzAoX2lucHV0KTsKfQpoYWxmNCBDaXJjdWxhclJSZWN0X1MyKGhhbGY0IF9pbnB1dCkgCnsKCWZsb2F0MiBkeHkwID0gdWlubmVyUmVjdF9TMi5MVCAtIHNrX0ZyYWdDb29yZC54eTsKCWZsb2F0MiBkeHkxID0gc2tfRnJhZ0Nvb3JkLnh5IC0gdWlubmVyUmVjdF9TMi5SQjsKCWZsb2F0MiBkeHkgPSBtYXgobWF4KGR4eTAsIGR4eTEpLCAwLjApOwoJaGFsZiBhbHBoYSA9IGhhbGYoc2F0dXJhdGUodXJhZGl1c1BsdXNIYWxmX1MyLnggLSBsZW5ndGgoZHh5KSkpOwoJcmV0dXJuIF9pbnB1dCAqIGFscGhhOwp9CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2Y29sb3JfUzA7CglmbG9hdCBjb3ZlcmFnZSA9IHZjb3ZlcmFnZV9TMDsKCWhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoaGFsZihjb3ZlcmFnZSkpOwoJaGFsZjQgb3V0cHV0X1MxOwoJb3V0cHV0X1MxID0gTWF0cml4RWZmZWN0X1MxKG91dHB1dENvbG9yX1MwKTsKCWhhbGY0IG91dHB1dF9TMjsKCW91dHB1dF9TMiA9IENpcmN1bGFyUlJlY3RfUzIob3V0cHV0Q292ZXJhZ2VfUzApOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dF9TMSAqIG91dHB1dF9TMjsKCX0KfQoAAAABAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAgAAABwb3NpdGlvbggAAABjb3ZlcmFnZQUAAABjb2xvcgAAAAoAAABsb2NhbENvb3JkAAAAAAAA","AYQA5AADQAAAOAEARAFQJAABBADIB7777777777777777777777767YAAAAAAAAAAAAB3QA6AAAEAAAAAAAMAAPEAEAAABAAAAAAB2AAAAAAACAAAAAEBSAAAA":"DAAAAExTS1PMAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQ0IHVsb2NhbE1hdHJpeF9TMDsKaW4gZmxvYXQyIGluUG9zaXRpb247CmluIGhhbGY0IGluQ29sb3I7CmluIGZsb2F0NCBpbkNpcmNsZUVkZ2U7Cm91dCBmbG9hdDQgdmluQ2lyY2xlRWRnZV9TMDsKb3V0IGhhbGY0IHZpbkNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBDaXJjbGVHZW9tZXRyeVByb2Nlc3NvcgoJdmluQ2lyY2xlRWRnZV9TMCA9IGluQ2lyY2xlRWRnZTsKCXZpbkNvbG9yX1MwID0gaW5Db2xvcjsKCWZsb2F0MiBfdG1wXzBfaW5Qb3NpdGlvbiA9IGluUG9zaXRpb247CglmbG9hdDIgX3RtcF8xX2luUG9zaXRpb24gPSB1bG9jYWxNYXRyaXhfUzAueHogKiBpblBvc2l0aW9uICsgdWxvY2FsTWF0cml4X1MwLnl3OwoJc2tfUG9zaXRpb24gPSBfdG1wXzBfaW5Qb3NpdGlvbi54eTAxOwp9CgEAAAAeBQAAdW5pZm9ybSBmbG9hdDQgdWlubmVyUmVjdF9TMTsKdW5pZm9ybSBoYWxmMiB1cmFkaXVzUGx1c0hhbGZfUzE7CnVuaWZvcm0gZmxvYXQ0IHVpbm5lclJlY3RfUzI7CnVuaWZvcm0gaGFsZjIgdXJhZGl1c1BsdXNIYWxmX1MyOwppbiBmbG9hdDQgdmluQ2lyY2xlRWRnZV9TMDsKaW4gaGFsZjQgdmluQ29sb3JfUzA7CmhhbGY0IENpcmN1bGFyUlJlY3RfUzEoaGFsZjQgX2lucHV0KSAKewoJZmxvYXQyIGR4eTAgPSB1aW5uZXJSZWN0X1MxLkxUIC0gc2tfRnJhZ0Nvb3JkLnh5OwoJZmxvYXQyIGR4eTEgPSBza19GcmFnQ29vcmQueHkgLSB1aW5uZXJSZWN0X1MxLlJCOwoJZmxvYXQyIGR4eSA9IG1heChtYXgoZHh5MCwgZHh5MSksIDAuMCk7CgloYWxmIGFscGhhID0gaGFsZihzYXR1cmF0ZSh1cmFkaXVzUGx1c0hhbGZfUzEueCAtIGxlbmd0aChkeHkpKSk7CglhbHBoYSA9IDEuMCAtIGFscGhhOwoJcmV0dXJuIF9pbnB1dCAqIGFscGhhOwp9CmhhbGY0IENpcmN1bGFyUlJlY3RfUzIoaGFsZjQgX2lucHV0KSAKewoJZmxvYXQyIGR4eTAgPSB1aW5uZXJSZWN0X1MyLkxUIC0gc2tfRnJhZ0Nvb3JkLnh5OwoJZmxvYXQyIGR4eTEgPSBza19GcmFnQ29vcmQueHkgLSB1aW5uZXJSZWN0X1MyLlJCOwoJZmxvYXQyIGR4eSA9IG1heChtYXgoZHh5MCwgZHh5MSksIDAuMCk7CgloYWxmIGFscGhhID0gaGFsZihzYXR1cmF0ZSh1cmFkaXVzUGx1c0hhbGZfUzIueCAtIGxlbmd0aChkeHkpKSk7CglyZXR1cm4gX2lucHV0ICogYWxwaGE7Cn0Kdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIENpcmNsZUdlb21ldHJ5UHJvY2Vzc29yCglmbG9hdDQgY2lyY2xlRWRnZTsKCWNpcmNsZUVkZ2UgPSB2aW5DaXJjbGVFZGdlX1MwOwoJaGFsZjQgb3V0cHV0Q29sb3JfUzA7CglvdXRwdXRDb2xvcl9TMCA9IHZpbkNvbG9yX1MwOwoJZmxvYXQgZCA9IGxlbmd0aChjaXJjbGVFZGdlLnh5KTsKCWhhbGYgZGlzdGFuY2VUb091dGVyRWRnZSA9IGhhbGYoY2lyY2xlRWRnZS56ICogKDEuMCAtIGQpKTsKCWhhbGYgZWRnZUFscGhhID0gc2F0dXJhdGUoZGlzdGFuY2VUb091dGVyRWRnZSk7CgloYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KGVkZ2VBbHBoYSk7CgloYWxmNCBvdXRwdXRfUzE7CglvdXRwdXRfUzEgPSBDaXJjdWxhclJSZWN0X1MxKG91dHB1dENvdmVyYWdlX1MwKTsKCWhhbGY0IG91dHB1dF9TMjsKCW91dHB1dF9TMiA9IENpcmN1bGFyUlJlY3RfUzIob3V0cHV0X1MxKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dF9TMjsKCX0KfQoAAAEAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAADAAAACgAAAGluUG9zaXRpb24AAAcAAABpbkNvbG9yAAwAAABpbkNpcmNsZUVkZ2UAAAAA","HUQAAAAAAAMAADAAAIOAAAH677776IZOCAAP577777777777777777YBAAAAAAAAAAAKAAYAAAACAAAAAAACCAYAAA":"DAAAAExTS1PUAAAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gaGFsZjQgY29sb3I7CmZsYXQgb3V0IGhhbGY0IHZjb2xvcl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgl2Y29sb3JfUzAgPSBjb2xvcjsKCXNrX1Bvc2l0aW9uID0gcG9zaXRpb24ueHkwMTsKfQoAAAAAEQEAAGZsYXQgaW4gaGFsZjQgdmNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmNvbG9yX1MwOwoJY29uc3QgaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNCgxKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dENvdmVyYWdlX1MwOwoJfQp9CgAAAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAACAAAACAAAAHBvc2l0aW9uBQAAAGNvbG9yAAAAAAAAAA==","HUIAAAAAAAQAADAAAIOAAAH677777777777QGHAQAD7P7777777777YBAAAAAAAAAAALUASJ3EZYN2AAAAAAAAAEAAAABSCQKL3IYIJ2AAAAAAAAAEAAAABLBAABAAAAABAEGABBAMAAAAAAAAAAAOQAAAAAAAQAAAABAMQAAAAAA":"DAAAAExTS1M2AQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMTsKaW4gZmxvYXQyIHBvc2l0aW9uOwppbiBmbG9hdDIgbG9jYWxDb29yZDsKb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCglza19Qb3NpdGlvbiA9IHBvc2l0aW9uLnh5MDE7Cgl7CgkJdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzAgPSBmbG9hdDN4Mih1bWF0cml4X1MxKSAqIGxvY2FsQ29vcmQueHkxOwoJfQp9CgAAAAAAACoFAABjb25zdCBpbnQga01heExvb3BMaW1pdF9TMV9jMCA9IDg7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMV9jMF9jMDsKdW5pZm9ybSBoYWxmNCB1b2Zmc2V0c0FuZEtlcm5lbF9TMV9jMFsxNF07CnVuaWZvcm0gaGFsZjIgdWRpcl9TMV9jMDsKdW5pZm9ybSBmbG9hdDN4MyB1bWF0cml4X1MxOwpzYW1wbGVyMkQgdVRleHR1cmVTYW1wbGVyXzBfUzE7CmluIGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKaGFsZjQgVGV4dHVyZUVmZmVjdF9TMV9jMF9jMF9jMChoYWxmNCBfaW5wdXQsIGZsb2F0MiBfY29vcmRzKSAKewoJcmV0dXJuIHNhbXBsZSh1VGV4dHVyZVNhbXBsZXJfMF9TMSwgX2Nvb3Jkcyk7Cn0KaGFsZjQgTWF0cml4RWZmZWN0X1MxX2MwX2MwKGhhbGY0IF9pbnB1dCwgZmxvYXQyIF9jb29yZHMpIAp7CglyZXR1cm4gVGV4dHVyZUVmZmVjdF9TMV9jMF9jMF9jMChfaW5wdXQsIGZsb2F0M3gyKHVtYXRyaXhfUzFfYzBfYzApICogX2Nvb3Jkcy54eTEpOwp9CmhhbGY0IEdhdXNzaWFuQmx1cjFEX1MxX2MwKGhhbGY0IF9pbnB1dCkgCnsKCWhhbGY0IF90bXBfMF9pbkNvbG9yID0gX2lucHV0OwoJZmxvYXQyIF90bXBfMV9jb29yZHMgPSB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKCWhhbGY0IHN1bSA9IGhhbGY0KDAuMCk7Cglmb3IgKGludCBpID0gMDtpIDwga01heExvb3BMaW1pdF9TMV9jMDsgKytpKSAKCXsKCQloYWxmNCBzID0gdW9mZnNldHNBbmRLZXJuZWxfUzFfYzBbaV07CgkJc3VtICs9IHMueSAqIE1hdHJpeEVmZmVjdF9TMV9jMF9jMChfdG1wXzBfaW5Db2xvciwgX3RtcF8xX2Nvb3JkcyArIGZsb2F0MihzLnggKiB1ZGlyX1MxX2MwKSk7CgkJc3VtICs9IHMudyAqIE1hdHJpeEVmZmVjdF9TMV9jMF9jMChfdG1wXzBfaW5Db2xvciwgX3RtcF8xX2Nvb3JkcyArIGZsb2F0MihzLnogKiB1ZGlyX1MxX2MwKSk7Cgl9CglyZXR1cm4gaGFsZjQoc3VtKTsKfQpoYWxmNCBNYXRyaXhFZmZlY3RfUzEoaGFsZjQgX2lucHV0KSAKewoJcmV0dXJuIEdhdXNzaWFuQmx1cjFEX1MxX2MwKF9pbnB1dCk7Cn0Kdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJaGFsZjQgb3V0cHV0Q29sb3JfUzAgPSBoYWxmNCgxKTsKCWNvbnN0IGhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoMSk7CgloYWxmNCBvdXRwdXRfUzE7CglvdXRwdXRfUzEgPSBNYXRyaXhFZmZlY3RfUzEob3V0cHV0Q29sb3JfUzApOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dF9TMSAqIG91dHB1dENvdmVyYWdlX1MwOwoJfQp9CgAAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAIAAAAcG9zaXRpb24KAAAAbG9jYWxDb29yZAAAAAAAAA==","HVIAAAAAABIAAGAAAQ4AAAH477776R24EAAAIOBQAD6P7777777777YDAAAAAAAAAAAHQBNGZODK5YIAAAAAAQAAAAAIADCNS4GV3QYBAAAAAAAAAAAIAAJQAAAAAAAACAAAAADYCAAIAAAAACABKAYABAAAAAFAEEQCEAAAAAAAAAAAAAAB2AAAAAAACAAAAAEBSAA":"DAAAAExTS1MIAgAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMTsKdW5pZm9ybSBmbG9hdDN4MyB1bWF0cml4X1MyX2MwX2MwOwppbiBmbG9hdDIgcG9zaXRpb247CmluIGhhbGY0IGNvbG9yOwppbiBmbG9hdDIgbG9jYWxDb29yZDsKZmxhdCBvdXQgaGFsZjQgdmNvbG9yX1MwOwpvdXQgZmxvYXQyIHZUcmFuc2Zvcm1lZENvb3Jkc18yX1MwOwpvdXQgZmxvYXQyIHZUcmFuc2Zvcm1lZENvb3Jkc182X1MwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCXZjb2xvcl9TMCA9IGNvbG9yOwoJc2tfUG9zaXRpb24gPSBwb3NpdGlvbi54eTAxOwoJewoJCXZUcmFuc2Zvcm1lZENvb3Jkc18yX1MwID0gZmxvYXQzeDIodW1hdHJpeF9TMSkgKiBsb2NhbENvb3JkLnh5MTsKCX0KCXsKCQl2VHJhbnNmb3JtZWRDb29yZHNfNl9TMCA9IGZsb2F0M3gyKHVtYXRyaXhfUzJfYzBfYzApICogcG9zaXRpb24ueHkxOwoJfQp9CgAAAAC0HQAAZmxvYXQ0IGZsdXR0ZXJfRnJhZ0Nvb3JkX1MxX2MwOwpmbG9hdDQgZnJhZ0NvbG9yX1MxX2MwOwpmbG9hdCB1X2FscGhhX1MxX2MwOwpmbG9hdCB1X3NwYXJrbGVfYWxwaGFfUzFfYzA7CmZsb2F0IHVfYmx1cl9TMV9jMDsKZmxvYXQgdV9yYWRpdXNfc2NhbGVfUzFfYzA7CnVuaWZvcm0gZmxvYXQ0IHVfY29sb3JfUzFfYzA7CnVuaWZvcm0gZmxvYXQ0IHVfY29tcG9zaXRlXzFfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfY2VudGVyX1MxX2MwOwp1bmlmb3JtIGZsb2F0IHVfbWF4X3JhZGl1c19TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9yZXNvbHV0aW9uX3NjYWxlX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X25vaXNlX3NjYWxlX1MxX2MwOwp1bmlmb3JtIGZsb2F0IHVfbm9pc2VfcGhhc2VfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfY2lyY2xlMV9TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9jaXJjbGUyX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X2NpcmNsZTNfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfcm90YXRpb24xX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X3JvdGF0aW9uMl9TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9yb3RhdGlvbjNfUzFfYzA7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMTsKdW5pZm9ybSBmbG9hdDN4MyB1bWF0cml4X1MyX2MwX2MwOwpzYW1wbGVyMkQgdVRleHR1cmVTYW1wbGVyXzBfUzI7CmZsYXQgaW4gaGFsZjQgdmNvbG9yX1MwOwppbiBmbG9hdDIgdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzA7CmluIGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfNl9TMDsKZmxvYXQyIEZMVF9mbHV0dGVyX2xvY2FsX0ZsdXR0ZXJGcmFnQ29vcmRfUzFfYzAoKTsKZmxvYXQyeDIgRkxUX2ZsdXR0ZXJfbG9jYWxfcm90YXRlMmRfUzFfYzAoZmxvYXQyIHJhZCk7CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfY2lyY2xlX1MxX2MwKGZsb2F0MiB1diwgZmxvYXQyIHh5LCBmbG9hdCByYWRpdXMsIGZsb2F0IGJsdXIpOwpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9jaXJjbGVfZ3JpZF9TMV9jMChmbG9hdDIgcmVzb2x1dGlvbiwgaW5vdXQgZmxvYXQyIHAsIGZsb2F0MiB4eSwgZmxvYXQyIHJvdGF0aW9uLCBmbG9hdCBjZWxsX2RpYW1ldGVyKTsKZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfdHVyYnVsZW5jZV9TMV9jMChmbG9hdDIgdXYpOwpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X3JpbmdfUzFfYzAoZmxvYXQyIHV2LCBmbG9hdDIgeHksIGZsb2F0IHJhZGl1cywgZmxvYXQgdGhpY2tuZXNzLCBmbG9hdCBibHVyKTsKZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfdHJpYW5nbGVfbm9pc2VfUzFfYzAoaW5vdXQgZmxvYXQyIG4pOwpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF90aHJlc2hvbGRfUzFfYzAoZmxvYXQgdiwgZmxvYXQgbCwgZmxvYXQgaCk7CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3NwYXJrbGVfUzFfYzAoZmxvYXQyIHV2LCBmbG9hdCB0KTsKdm9pZCBGTFRfbWFpbl9TMV9jMCgpOwpmbG9hdDIgRkxUX2ZsdXR0ZXJfbG9jYWxfRmx1dHRlckZyYWdDb29yZF9TMV9jMCgpIAp7CglyZXR1cm4gZmx1dHRlcl9GcmFnQ29vcmRfUzFfYzAueHk7Cn0KZmxvYXQyeDIgRkxUX2ZsdXR0ZXJfbG9jYWxfcm90YXRlMmRfUzFfYzAoZmxvYXQyIHJhZCkgCnsKCXJldHVybiBmbG9hdDJ4MihyYWQueCwgLXJhZC55LCByYWQueSwgcmFkLngpOwp9CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfY2lyY2xlX1MxX2MwKGZsb2F0MiB1diwgZmxvYXQyIHh5LCBmbG9hdCByYWRpdXMsIGZsb2F0IGJsdXIpIAp7CglmbG9hdCBibHVyX2hhbGYgPSBibHVyICogMC41OwoJZmxvYXQgZCA9IGRpc3RhbmNlKHV2LCB4eSk7CglyZXR1cm4gMS4wIC0gc21vb3Roc3RlcCgxLjAgLSBibHVyX2hhbGYsIDEuMCArIGJsdXJfaGFsZiwgZCAvIHJhZGl1cyk7Cn0KZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfY2lyY2xlX2dyaWRfUzFfYzAoZmxvYXQyIHJlc29sdXRpb24sIGlub3V0IGZsb2F0MiBwLCBmbG9hdDIgeHksIGZsb2F0MiByb3RhdGlvbiwgZmxvYXQgY2VsbF9kaWFtZXRlcikgCnsKCWZsb2F0MiBwYXJhbSA9IHJvdGF0aW9uOwoJcCA9IEZMVF9mbHV0dGVyX2xvY2FsX3JvdGF0ZTJkX1MxX2MwKHBhcmFtKSAqICh4eSAtIHApICsgeHk7CglwID0gbW9kKHAsIGZsb2F0MihjZWxsX2RpYW1ldGVyKSkgLyByZXNvbHV0aW9uOwoJZmxvYXQgY2VsbF91diA9IChjZWxsX2RpYW1ldGVyIC8gcmVzb2x1dGlvbi55KSAqIDAuNTsKCWZsb2F0IHIgPSAwLjY1ICogY2VsbF91djsKCWZsb2F0MiBwYXJhbV8xID0gcDsKCWZsb2F0MiBwYXJhbV8yID0gZmxvYXQyKGNlbGxfdXYpOwoJZmxvYXQgcGFyYW1fMyA9IHI7CglmbG9hdCBwYXJhbV80ID0gciAqIDUwLjA7CglyZXR1cm4gRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9jaXJjbGVfUzFfYzAocGFyYW1fMSwgcGFyYW1fMiwgcGFyYW1fMywgcGFyYW1fNCk7Cn0KZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfdHVyYnVsZW5jZV9TMV9jMChmbG9hdDIgdXYpIAp7CglmbG9hdDIgdXZfc2NhbGUgPSB1diAqIGZsb2F0MigwLjgpOwoJZmxvYXQyIHBhcmFtID0gZmxvYXQyKDAuOCk7CglmbG9hdDIgcGFyYW1fMSA9IHV2X3NjYWxlOwoJZmxvYXQyIHBhcmFtXzIgPSB1X2NpcmNsZTFfUzFfYzA7CglmbG9hdDIgcGFyYW1fMyA9IHVfcm90YXRpb24xX1MxX2MwOwoJZmxvYXQgcGFyYW1fNCA9IDAuMTc7CglmbG9hdCBfMzE5ID0gRkxUX2ZsdXR0ZXJfbG9jYWxfY2lyY2xlX2dyaWRfUzFfYzAocGFyYW0sIHBhcmFtXzEsIHBhcmFtXzIsIHBhcmFtXzMsIHBhcmFtXzQpOwoJZmxvYXQgZzEgPSBfMzE5OwoJZmxvYXQyIHBhcmFtXzUgPSBmbG9hdDIoMC44KTsKCWZsb2F0MiBwYXJhbV82ID0gdXZfc2NhbGU7CglmbG9hdDIgcGFyYW1fNyA9IHVfY2lyY2xlMl9TMV9jMDsKCWZsb2F0MiBwYXJhbV84ID0gdV9yb3RhdGlvbjJfUzFfYzA7CglmbG9hdCBwYXJhbV85ID0gMC4yOwoJZmxvYXQgXzMzMSA9IEZMVF9mbHV0dGVyX2xvY2FsX2NpcmNsZV9ncmlkX1MxX2MwKHBhcmFtXzUsIHBhcmFtXzYsIHBhcmFtXzcsIHBhcmFtXzgsIHBhcmFtXzkpOwoJZmxvYXQgZzIgPSBfMzMxOwoJZmxvYXQyIHBhcmFtXzEwID0gZmxvYXQyKDAuOCk7CglmbG9hdDIgcGFyYW1fMTEgPSB1dl9zY2FsZTsKCWZsb2F0MiBwYXJhbV8xMiA9IHVfY2lyY2xlM19TMV9jMDsKCWZsb2F0MiBwYXJhbV8xMyA9IHVfcm90YXRpb24zX1MxX2MwOwoJZmxvYXQgcGFyYW1fMTQgPSAwLjI3NTsKCWZsb2F0IF8zNDQgPSBGTFRfZmx1dHRlcl9sb2NhbF9jaXJjbGVfZ3JpZF9TMV9jMChwYXJhbV8xMCwgcGFyYW1fMTEsIHBhcmFtXzEyLCBwYXJhbV8xMywgcGFyYW1fMTQpOwoJZmxvYXQgZzMgPSBfMzQ0OwoJZmxvYXQgdiA9ICgoZzEgKiBnMSArIGcyKSAtIGczKSAqIDAuNTsKCXJldHVybiBjbGFtcCgwLjQ1ICsgMC44ICogdiwgMC4wLCAxLjApOwp9CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfcmluZ19TMV9jMChmbG9hdDIgdXYsIGZsb2F0MiB4eSwgZmxvYXQgcmFkaXVzLCBmbG9hdCB0aGlja25lc3MsIGZsb2F0IGJsdXIpIAp7CglmbG9hdDIgcGFyYW0gPSB1djsKCWZsb2F0MiBwYXJhbV8xID0geHk7CglmbG9hdCBwYXJhbV8yID0gcmFkaXVzICsgdGhpY2tuZXNzOwoJZmxvYXQgcGFyYW1fMyA9IGJsdXI7CglmbG9hdCBjaXJjbGVfb3V0ZXIgPSBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X2NpcmNsZV9TMV9jMChwYXJhbSwgcGFyYW1fMSwgcGFyYW1fMiwgcGFyYW1fMyk7CglmbG9hdDIgcGFyYW1fNCA9IHV2OwoJZmxvYXQyIHBhcmFtXzUgPSB4eTsKCWZsb2F0IHBhcmFtXzYgPSBtYXgocmFkaXVzIC0gdGhpY2tuZXNzLCAwLjApOwoJZmxvYXQgcGFyYW1fNyA9IGJsdXI7CglmbG9hdCBjaXJjbGVfaW5uZXIgPSBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X2NpcmNsZV9TMV9jMChwYXJhbV80LCBwYXJhbV81LCBwYXJhbV82LCBwYXJhbV83KTsKCXJldHVybiBjbGFtcChjaXJjbGVfb3V0ZXIgLSBjaXJjbGVfaW5uZXIsIDAuMCwgMS4wKTsKfQpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF90cmlhbmdsZV9ub2lzZV9TMV9jMChpbm91dCBmbG9hdDIgbikgCnsKCW4gPSBmcmFjdChuICogZmxvYXQyKDUuMzk4NywgNS40NDIxKSk7CgluICs9IGZsb2F0Mihkb3Qobi55eCwgbiArIGZsb2F0MigyMS41MzUxLCAxNC4zMTM3KSkpOwoJZmxvYXQgeHkgPSBuLnggKiBuLnk7CglyZXR1cm4gKGZyYWN0KHh5ICogOTUuNDMwNykgKyBmcmFjdCh4eSAqIDc1LjA0OTYxKSkgLSAxLjA7Cn0KZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfdGhyZXNob2xkX1MxX2MwKGZsb2F0IHYsIGZsb2F0IGwsIGZsb2F0IGgpIAp7CglyZXR1cm4gc3RlcChsLCB2KSAqICgxLjAgLSBzdGVwKGgsIHYpKTsKfQpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9zcGFya2xlX1MxX2MwKGZsb2F0MiB1diwgZmxvYXQgdCkgCnsKCWZsb2F0MiBwYXJhbSA9IHV2OwoJZmxvYXQgXzI0MiA9IEZMVF9mbHV0dGVyX2xvY2FsX3RyaWFuZ2xlX25vaXNlX1MxX2MwKHBhcmFtKTsKCWZsb2F0IG4gPSBfMjQyOwoJZmxvYXQgcGFyYW1fMSA9IG47CglmbG9hdCBwYXJhbV8yID0gMC4wOwoJZmxvYXQgcGFyYW1fMyA9IDAuMDU7CglmbG9hdCBzID0gRkxUX2ZsdXR0ZXJfbG9jYWxfdGhyZXNob2xkX1MxX2MwKHBhcmFtXzEsIHBhcmFtXzIsIHBhcmFtXzMpOwoJZmxvYXQgcGFyYW1fNCA9IG4gKyBzaW4oMy4xNDE1OTI3NCAqICh0ICsgMC4zNSkpOwoJZmxvYXQgcGFyYW1fNSA9IDAuMTsKCWZsb2F0IHBhcmFtXzYgPSAwLjE1OwoJcyArPSBGTFRfZmx1dHRlcl9sb2NhbF90aHJlc2hvbGRfUzFfYzAocGFyYW1fNCwgcGFyYW1fNSwgcGFyYW1fNik7CglmbG9hdCBwYXJhbV83ID0gbiArIHNpbigzLjE0MTU5Mjc0ICogKHQgKyAwLjcpKTsKCWZsb2F0IHBhcmFtXzggPSAwLjI7CglmbG9hdCBwYXJhbV85ID0gMC4yNTsKCXMgKz0gRkxUX2ZsdXR0ZXJfbG9jYWxfdGhyZXNob2xkX1MxX2MwKHBhcmFtXzcsIHBhcmFtXzgsIHBhcmFtXzkpOwoJZmxvYXQgcGFyYW1fMTAgPSBuICsgc2luKDMuMTQxNTkyNzQgKiAodCArIDEuMDUpKTsKCWZsb2F0IHBhcmFtXzExID0gMC4zOwoJZmxvYXQgcGFyYW1fMTIgPSAwLjM1OwoJcyArPSBGTFRfZmx1dHRlcl9sb2NhbF90aHJlc2hvbGRfUzFfYzAocGFyYW1fMTAsIHBhcmFtXzExLCBwYXJhbV8xMik7CglyZXR1cm4gY2xhbXAocywgMC4wLCAxLjApICogMC41NTsKfQp2b2lkIEZMVF9tYWluX1MxX2MwKCkgCnsKCXVfYWxwaGFfUzFfYzAgPSB1X2NvbXBvc2l0ZV8xX1MxX2MwLng7Cgl1X3NwYXJrbGVfYWxwaGFfUzFfYzAgPSB1X2NvbXBvc2l0ZV8xX1MxX2MwLnk7Cgl1X2JsdXJfUzFfYzAgPSB1X2NvbXBvc2l0ZV8xX1MxX2MwLno7Cgl1X3JhZGl1c19zY2FsZV9TMV9jMCA9IHVfY29tcG9zaXRlXzFfUzFfYzAudzsKCWZsb2F0MiBwID0gRkxUX2ZsdXR0ZXJfbG9jYWxfRmx1dHRlckZyYWdDb29yZF9TMV9jMCgpOwoJZmxvYXQyIHV2XzEgPSBwICogdV9yZXNvbHV0aW9uX3NjYWxlX1MxX2MwOwoJZmxvYXQyIGRlbnNpdHlfdXYgPSB1dl8xIC0gbW9kKHAsIHVfbm9pc2Vfc2NhbGVfUzFfYzApOwoJZmxvYXQgcmFkaXVzID0gdV9tYXhfcmFkaXVzX1MxX2MwICogdV9yYWRpdXNfc2NhbGVfUzFfYzA7CglmbG9hdDIgcGFyYW1fMTMgPSB1dl8xOwoJZmxvYXQgdHVyYnVsZW5jZSA9IEZMVF9mbHV0dGVyX2xvY2FsX3R1cmJ1bGVuY2VfUzFfYzAocGFyYW1fMTMpOwoJZmxvYXQyIHBhcmFtXzE0ID0gcDsKCWZsb2F0MiBwYXJhbV8xNSA9IHVfY2VudGVyX1MxX2MwOwoJZmxvYXQgcGFyYW1fMTYgPSByYWRpdXM7CglmbG9hdCBwYXJhbV8xNyA9IDAuMDUgKiB1X21heF9yYWRpdXNfUzFfYzA7CglmbG9hdCBwYXJhbV8xOCA9IHVfYmx1cl9TMV9jMDsKCWZsb2F0IHJpbmcgPSBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X3JpbmdfUzFfYzAocGFyYW1fMTQsIHBhcmFtXzE1LCBwYXJhbV8xNiwgcGFyYW1fMTcsIHBhcmFtXzE4KTsKCWZsb2F0MiBwYXJhbV8xOSA9IGRlbnNpdHlfdXY7CglmbG9hdCBwYXJhbV8yMCA9IHVfbm9pc2VfcGhhc2VfUzFfYzA7CglmbG9hdCBzcGFya2xlID0gKChGTFRfZmx1dHRlcl9sb2NhbF9zcGFya2xlX1MxX2MwKHBhcmFtXzE5LCBwYXJhbV8yMCkgKiByaW5nKSAqIHR1cmJ1bGVuY2UpICogdV9zcGFya2xlX2FscGhhX1MxX2MwOwoJZmxvYXQyIHBhcmFtXzIxID0gcDsKCWZsb2F0MiBwYXJhbV8yMiA9IHVfY2VudGVyX1MxX2MwOwoJZmxvYXQgcGFyYW1fMjMgPSByYWRpdXM7CglmbG9hdCBwYXJhbV8yNCA9IHVfYmx1cl9TMV9jMDsKCWZsb2F0IHdhdmVfYWxwaGEgPSAoRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9jaXJjbGVfUzFfYzAocGFyYW1fMjEsIHBhcmFtXzIyLCBwYXJhbV8yMywgcGFyYW1fMjQpICogdV9hbHBoYV9TMV9jMCkgKiB1X2NvbG9yX1MxX2MwLnc7CglmbG9hdDQgd2F2ZV9jb2xvciA9IGZsb2F0NCh1X2NvbG9yX1MxX2MwLnh5eiAqIHdhdmVfYWxwaGEsIHdhdmVfYWxwaGEpOwoJZnJhZ0NvbG9yX1MxX2MwID0gbWl4KHdhdmVfY29sb3IsIGZsb2F0NCgxLjApLCBmbG9hdDQoc3BhcmtsZSkpOwp9CmhhbGY0IHJ1bnRpbWVfc2hhZGVyX1MxX2MwKGhhbGY0IF9pbnB1dCkgCnsKCWhhbGY0IF90bXBfMF9pbkNvbG9yID0gX2lucHV0OwoJZmxvYXQyIF90bXBfMV9jb29yZHMgPSB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKCWZsdXR0ZXJfRnJhZ0Nvb3JkX1MxX2MwID0gZmxvYXQ0KF90bXBfMV9jb29yZHMsIDAuMCwgMC4wKTsKCUZMVF9tYWluX1MxX2MwKCk7CglyZXR1cm4gaGFsZjQoaGFsZjQoZnJhZ0NvbG9yX1MxX2MwKSk7Cn0KaGFsZjQgTWF0cml4RWZmZWN0X1MxKGhhbGY0IF9pbnB1dCkgCnsKCXJldHVybiBydW50aW1lX3NoYWRlcl9TMV9jMChfaW5wdXQpOwp9CmhhbGY0IFRleHR1cmVFZmZlY3RfUzJfYzBfYzBfYzAoaGFsZjQgX2lucHV0KSAKewoJcmV0dXJuIHNhbXBsZSh1VGV4dHVyZVNhbXBsZXJfMF9TMiwgdlRyYW5zZm9ybWVkQ29vcmRzXzZfUzApLjAwMHI7Cn0KaGFsZjQgTWF0cml4RWZmZWN0X1MyX2MwX2MwKGhhbGY0IF9pbnB1dCkgCnsKCXJldHVybiBUZXh0dXJlRWZmZWN0X1MyX2MwX2MwX2MwKF9pbnB1dCk7Cn0KaGFsZjQgRGV2aWNlU3BhY2VfUzJfYzAoaGFsZjQgX2lucHV0KSAKewoJcmV0dXJuIE1hdHJpeEVmZmVjdF9TMl9jMF9jMChfaW5wdXQpOwp9CmhhbGY0IEJsZW5kX1MyKGhhbGY0IF9zcmMsIGhhbGY0IF9kc3QpIAp7CglyZXR1cm4gYmxlbmRfZHN0X2luKERldmljZVNwYWNlX1MyX2MwKF9zcmMpLCBfc3JjKTsKfQp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmNvbG9yX1MwOwoJY29uc3QgaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNCgxKTsKCWhhbGY0IG91dHB1dF9TMTsKCW91dHB1dF9TMSA9IE1hdHJpeEVmZmVjdF9TMShvdXRwdXRDb2xvcl9TMCk7CgloYWxmNCBvdXRwdXRfUzI7CglvdXRwdXRfUzIgPSBCbGVuZF9TMihvdXRwdXRDb3ZlcmFnZV9TMCwgaGFsZjQoMSkpOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dF9TMSAqIG91dHB1dF9TMjsKCX0KfQoAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAgAAABwb3NpdGlvbgUAAABjb2xvcgAAAAoAAABsb2NhbENvb3JkAAAAAAAA","HUIAAAAAAAQAADAAAIOAAAH677777777777QGHAQAD7P7777777777YBAAAAAAAAAAALUAQJALJKL2AAAAAAAAAEAAAABSCQQKAHIKJ2AAAAAAAAAEAAAABLBAABAAAAABAEGABBAMAAAAAAAAAAAOQAAAAAAAQAAAABAMQAAAAAA":"DAAAAExTS1M2AQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMTsKaW4gZmxvYXQyIHBvc2l0aW9uOwppbiBmbG9hdDIgbG9jYWxDb29yZDsKb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCglza19Qb3NpdGlvbiA9IHBvc2l0aW9uLnh5MDE7Cgl7CgkJdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzAgPSBmbG9hdDN4Mih1bWF0cml4X1MxKSAqIGxvY2FsQ29vcmQueHkxOwoJfQp9CgAAAAAAACoFAABjb25zdCBpbnQga01heExvb3BMaW1pdF9TMV9jMCA9IDY7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMV9jMF9jMDsKdW5pZm9ybSBoYWxmNCB1b2Zmc2V0c0FuZEtlcm5lbF9TMV9jMFsxNF07CnVuaWZvcm0gaGFsZjIgdWRpcl9TMV9jMDsKdW5pZm9ybSBmbG9hdDN4MyB1bWF0cml4X1MxOwpzYW1wbGVyMkQgdVRleHR1cmVTYW1wbGVyXzBfUzE7CmluIGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKaGFsZjQgVGV4dHVyZUVmZmVjdF9TMV9jMF9jMF9jMChoYWxmNCBfaW5wdXQsIGZsb2F0MiBfY29vcmRzKSAKewoJcmV0dXJuIHNhbXBsZSh1VGV4dHVyZVNhbXBsZXJfMF9TMSwgX2Nvb3Jkcyk7Cn0KaGFsZjQgTWF0cml4RWZmZWN0X1MxX2MwX2MwKGhhbGY0IF9pbnB1dCwgZmxvYXQyIF9jb29yZHMpIAp7CglyZXR1cm4gVGV4dHVyZUVmZmVjdF9TMV9jMF9jMF9jMChfaW5wdXQsIGZsb2F0M3gyKHVtYXRyaXhfUzFfYzBfYzApICogX2Nvb3Jkcy54eTEpOwp9CmhhbGY0IEdhdXNzaWFuQmx1cjFEX1MxX2MwKGhhbGY0IF9pbnB1dCkgCnsKCWhhbGY0IF90bXBfMF9pbkNvbG9yID0gX2lucHV0OwoJZmxvYXQyIF90bXBfMV9jb29yZHMgPSB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKCWhhbGY0IHN1bSA9IGhhbGY0KDAuMCk7Cglmb3IgKGludCBpID0gMDtpIDwga01heExvb3BMaW1pdF9TMV9jMDsgKytpKSAKCXsKCQloYWxmNCBzID0gdW9mZnNldHNBbmRLZXJuZWxfUzFfYzBbaV07CgkJc3VtICs9IHMueSAqIE1hdHJpeEVmZmVjdF9TMV9jMF9jMChfdG1wXzBfaW5Db2xvciwgX3RtcF8xX2Nvb3JkcyArIGZsb2F0MihzLnggKiB1ZGlyX1MxX2MwKSk7CgkJc3VtICs9IHMudyAqIE1hdHJpeEVmZmVjdF9TMV9jMF9jMChfdG1wXzBfaW5Db2xvciwgX3RtcF8xX2Nvb3JkcyArIGZsb2F0MihzLnogKiB1ZGlyX1MxX2MwKSk7Cgl9CglyZXR1cm4gaGFsZjQoc3VtKTsKfQpoYWxmNCBNYXRyaXhFZmZlY3RfUzEoaGFsZjQgX2lucHV0KSAKewoJcmV0dXJuIEdhdXNzaWFuQmx1cjFEX1MxX2MwKF9pbnB1dCk7Cn0Kdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJaGFsZjQgb3V0cHV0Q29sb3JfUzAgPSBoYWxmNCgxKTsKCWNvbnN0IGhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoMSk7CgloYWxmNCBvdXRwdXRfUzE7CglvdXRwdXRfUzEgPSBNYXRyaXhFZmZlY3RfUzEob3V0cHV0Q29sb3JfUzApOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dF9TMSAqIG91dHB1dENvdmVyYWdlX1MwOwoJfQp9CgAAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAIAAAAcG9zaXRpb24KAAAAbG9jYWxDb29yZAAAAAAAAA=="}} \ No newline at end of file +{"platform":"android","name":"SM G970N","engineRevision":"3f3e560236539b7e2702f5ac790b2a4691b32d49","data":{"GEMAAAYAAEHAAAARC4EAAAQWBQAAAAAAAAAQAAAAIBCAAAGQAEAAAAAQAAAABAEQAEAAAAA":"DAAAAExTS1NUAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0MiBpblBvc2l0aW9uOwppbiBoYWxmNCBpbkNvbG9yOwppbiBoYWxmMyBpblNoYWRvd1BhcmFtczsKb3V0IGhhbGYzIHZpblNoYWRvd1BhcmFtc19TMDsKb3V0IGhhbGY0IHZpbkNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBSUmVjdFNoYWRvdwoJdmluU2hhZG93UGFyYW1zX1MwID0gaW5TaGFkb3dQYXJhbXM7Cgl2aW5Db2xvcl9TMCA9IGluQ29sb3I7CglmbG9hdDIgX3RtcF8wX2luUG9zaXRpb24gPSBpblBvc2l0aW9uOwoJc2tfUG9zaXRpb24gPSBfdG1wXzBfaW5Qb3NpdGlvbi54eTAxOwp9CgAAAAADAgAAc2FtcGxlcjJEIHVUZXh0dXJlU2FtcGxlcl8wX1MwOwppbiBoYWxmMyB2aW5TaGFkb3dQYXJhbXNfUzA7CmluIGhhbGY0IHZpbkNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgUlJlY3RTaGFkb3cKCWhhbGYzIHNoYWRvd1BhcmFtczsKCXNoYWRvd1BhcmFtcyA9IHZpblNoYWRvd1BhcmFtc19TMDsKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2aW5Db2xvcl9TMDsKCWhhbGYgZCA9IGxlbmd0aChzaGFkb3dQYXJhbXMueHkpOwoJZmxvYXQyIHV2ID0gZmxvYXQyKHNoYWRvd1BhcmFtcy56ICogKDEuMCAtIGQpLCAwLjUpOwoJaGFsZiBmYWN0b3IgPSBzYW1wbGUodVRleHR1cmVTYW1wbGVyXzBfUzAsIHV2KS4wMDByLmE7CgloYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KGZhY3Rvcik7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRDb3ZlcmFnZV9TMDsKCX0KfQoAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAKAAAAaW5Qb3NpdGlvbgAABwAAAGluQ29sb3IADgAAAGluU2hhZG93UGFyYW1zAAAAAAAA","HUIAAAAAAAQAADAAAIOAAAH677777777777QGHAQAD7P7777777777YBAAAAAAAAAAALUAQBAAAQAAAAGQCBAMQACAAAAAAAACQAGAAAAAQAAAAAAAQQGAAAAA":"DAAAAExTS1M2AQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMTsKaW4gZmxvYXQyIHBvc2l0aW9uOwppbiBmbG9hdDIgbG9jYWxDb29yZDsKb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCglza19Qb3NpdGlvbiA9IHBvc2l0aW9uLnh5MDE7Cgl7CgkJdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzAgPSBmbG9hdDN4Mih1bWF0cml4X1MxKSAqIGxvY2FsQ29vcmQueHkxOwoJfQp9CgAAAAAAAGgDAAB1bmlmb3JtIGZsb2F0NCB1Y2xhbXBfUzFfYzA7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMTsKc2FtcGxlcjJEIHVUZXh0dXJlU2FtcGxlcl8wX1MxOwppbiBmbG9hdDIgdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzA7CmhhbGY0IFRleHR1cmVFZmZlY3RfUzFfYzAoaGFsZjQgX2lucHV0KSAKewoJZmxvYXQyIGluQ29vcmQgPSB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKCWZsb2F0MiBzdWJzZXRDb29yZDsKCXN1YnNldENvb3JkLnggPSBpbkNvb3JkLng7CglzdWJzZXRDb29yZC55ID0gaW5Db29yZC55OwoJZmxvYXQyIGNsYW1wZWRDb29yZDsKCWNsYW1wZWRDb29yZC54ID0gY2xhbXAoc3Vic2V0Q29vcmQueCwgdWNsYW1wX1MxX2MwLngsIHVjbGFtcF9TMV9jMC56KTsKCWNsYW1wZWRDb29yZC55ID0gc3Vic2V0Q29vcmQueTsKCWhhbGY0IHRleHR1cmVDb2xvciA9IHNhbXBsZSh1VGV4dHVyZVNhbXBsZXJfMF9TMSwgY2xhbXBlZENvb3JkKTsKCXJldHVybiB0ZXh0dXJlQ29sb3I7Cn0KaGFsZjQgTWF0cml4RWZmZWN0X1MxKGhhbGY0IF9pbnB1dCkgCnsKCXJldHVybiBUZXh0dXJlRWZmZWN0X1MxX2MwKF9pbnB1dCk7Cn0Kdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJaGFsZjQgb3V0cHV0Q29sb3JfUzAgPSBoYWxmNCgxKTsKCWNvbnN0IGhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoMSk7CgloYWxmNCBvdXRwdXRfUzE7CglvdXRwdXRfUzEgPSBNYXRyaXhFZmZlY3RfUzEob3V0cHV0Q29sb3JfUzApOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dF9TMSAqIG91dHB1dENvdmVyYWdlX1MwOwoJfQp9CgAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAACAAAACAAAAHBvc2l0aW9uCgAAAGxvY2FsQ29vcmQAAAAAAAA=","HVIAAAAAABIAAGAAAQ4AAAH477776R24EAAAIOBQAD6P7777777777YDAAAAAAAAAAAFQBVWKMG7QAAAAAAAAAACAAAAAVQEAAQAAAAAQCDAEQQGAAAAAAAAAAAA4IAPAAACAAAAAAAEABYAAAAEAAAAAAAEEBQA":"DAAAAExTS1N6AQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMV9jMDsKaW4gZmxvYXQyIHBvc2l0aW9uOwppbiBoYWxmNCBjb2xvcjsKaW4gZmxvYXQyIGxvY2FsQ29vcmQ7CmZsYXQgb3V0IGhhbGY0IHZjb2xvcl9TMDsKb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfM19TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgl2Y29sb3JfUzAgPSBjb2xvcjsKCXNrX1Bvc2l0aW9uID0gcG9zaXRpb24ueHkwMTsKCXsKCQl2VHJhbnNmb3JtZWRDb29yZHNfM19TMCA9IGZsb2F0M3gyKHVtYXRyaXhfUzFfYzApICogbG9jYWxDb29yZC54eTE7Cgl9Cn0KAAABAAAApAQAAHVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMV9jMDsKdW5pZm9ybSBmbG9hdDQgdWlubmVyUmVjdF9TMjsKdW5pZm9ybSBoYWxmMiB1cmFkaXVzUGx1c0hhbGZfUzI7CnNhbXBsZXJFeHRlcm5hbE9FUyB1VGV4dHVyZVNhbXBsZXJfMF9TMTsKZmxhdCBpbiBoYWxmNCB2Y29sb3JfUzA7CmluIGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfM19TMDsKaGFsZjQgVGV4dHVyZUVmZmVjdF9TMV9jMF9jMChoYWxmNCBfaW5wdXQpIAp7CglyZXR1cm4gc2FtcGxlKHVUZXh0dXJlU2FtcGxlcl8wX1MxLCB2VHJhbnNmb3JtZWRDb29yZHNfM19TMCk7Cn0KaGFsZjQgTWF0cml4RWZmZWN0X1MxX2MwKGhhbGY0IF9pbnB1dCkgCnsKCXJldHVybiBUZXh0dXJlRWZmZWN0X1MxX2MwX2MwKF9pbnB1dCk7Cn0KaGFsZjQgRGlzYWJsZUNvdmVyYWdlQXNBbHBoYV9TMShoYWxmNCBfaW5wdXQpIAp7CglfaW5wdXQgPSBNYXRyaXhFZmZlY3RfUzFfYzAoX2lucHV0KTsKCWhhbGY0IF90bXBfMF9pbkNvbG9yID0gX2lucHV0OwoJcmV0dXJuIGhhbGY0KF9pbnB1dCk7Cn0KaGFsZjQgQ2lyY3VsYXJSUmVjdF9TMihoYWxmNCBfaW5wdXQpIAp7CglmbG9hdDIgZHh5MCA9IHVpbm5lclJlY3RfUzIuTFQgLSBza19GcmFnQ29vcmQueHk7CglmbG9hdDIgZHh5MSA9IHNrX0ZyYWdDb29yZC54eSAtIHVpbm5lclJlY3RfUzIuUkI7CglmbG9hdDIgZHh5ID0gbWF4KG1heChkeHkwLCBkeHkxKSwgMC4wKTsKCWhhbGYgYWxwaGEgPSBoYWxmKHNhdHVyYXRlKHVyYWRpdXNQbHVzSGFsZl9TMi54IC0gbGVuZ3RoKGR4eSkpKTsKCXJldHVybiBfaW5wdXQgKiBhbHBoYTsKfQp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmNvbG9yX1MwOwoJY29uc3QgaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNCgxKTsKCWhhbGY0IG91dHB1dF9TMTsKCW91dHB1dF9TMSA9IERpc2FibGVDb3ZlcmFnZUFzQWxwaGFfUzEob3V0cHV0Q29sb3JfUzApOwoJaGFsZjQgb3V0cHV0X1MyOwoJb3V0cHV0X1MyID0gQ2lyY3VsYXJSUmVjdF9TMihvdXRwdXRDb3ZlcmFnZV9TMCk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0X1MxICogb3V0cHV0X1MyOwoJfQp9CgEAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAADAAAACAAAAHBvc2l0aW9uBQAAAGNvbG9yAAAACgAAAGxvY2FsQ29vcmQAAAAAAAA=","EADQAAAAAEAAAAAUAABQAAQPAAABCFYMAAKAUEAAAAAAAAABAAAAAAAAAAANAAIAAAABAAAAACAJAAIAAAAA":"DAAAAExTS1NyAgAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQyIHVBdGxhc0RpbWVuc2lvbnNJbnZfUzA7CmluIGZsb2F0MyBpblBvc2l0aW9uOwppbiBoYWxmNCBpbkNvbG9yOwppbiB1c2hvcnQyIGluVGV4dHVyZUNvb3JkczsKb3V0IGZsb2F0MiB2VGV4dHVyZUNvb3Jkc19TMDsKZmxhdCBvdXQgZmxvYXQgdlRleEluZGV4X1MwOwpvdXQgZmxvYXQyIHZJbnRUZXh0dXJlQ29vcmRzX1MwOwpvdXQgaGFsZjQgdmluQ29sb3JfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIERpc3RhbmNlRmllbGRQYXRoCglpbnQgdGV4SWR4ID0gMDsKCWZsb2F0MiB1bm9ybVRleENvb3JkcyA9IGZsb2F0MihpblRleHR1cmVDb29yZHMueCwgaW5UZXh0dXJlQ29vcmRzLnkpOwoJdlRleHR1cmVDb29yZHNfUzAgPSB1bm9ybVRleENvb3JkcyAqIHVBdGxhc0RpbWVuc2lvbnNJbnZfUzA7Cgl2VGV4SW5kZXhfUzAgPSBmbG9hdCh0ZXhJZHgpOwoJdkludFRleHR1cmVDb29yZHNfUzAgPSB1bm9ybVRleENvb3JkczsKCXZpbkNvbG9yX1MwID0gaW5Db2xvcjsKCWZsb2F0MyBfdG1wXzFfaW5Qb3NpdGlvbiA9IGluUG9zaXRpb247Cglza19Qb3NpdGlvbiA9IGluUG9zaXRpb24ueHkwejsKfQoAAAAAAACXAgAAc2FtcGxlcjJEIHVUZXh0dXJlU2FtcGxlcl8wX1MwOwppbiBmbG9hdDIgdlRleHR1cmVDb29yZHNfUzA7CmZsYXQgaW4gZmxvYXQgdlRleEluZGV4X1MwOwppbiBmbG9hdDIgdkludFRleHR1cmVDb29yZHNfUzA7CmluIGhhbGY0IHZpbkNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgRGlzdGFuY2VGaWVsZFBhdGgKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2aW5Db2xvcl9TMDsKCWZsb2F0MiB1diA9IHZUZXh0dXJlQ29vcmRzX1MwOwoJaGFsZjQgdGV4Q29sb3I7Cgl7CgkJdGV4Q29sb3IgPSBzYW1wbGUodVRleHR1cmVTYW1wbGVyXzBfUzAsIHV2KS5ycnJyOwoJfQoJaGFsZiBkaXN0YW5jZSA9IDcuOTY4NzUqKHRleENvbG9yLnIgLSAwLjUwMTk2MDc4NDMxKTsKCWhhbGYgYWZ3aWR0aDsKCWFmd2lkdGggPSBhYnMoMC42NSpoYWxmKGRGZHgodkludFRleHR1cmVDb29yZHNfUzAueCkpKTsKCWhhbGYgdmFsID0gc21vb3Roc3RlcCgtYWZ3aWR0aCwgYWZ3aWR0aCwgZGlzdGFuY2UpOwoJaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNCh2YWwpOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dENvbG9yX1MwICogb3V0cHV0Q292ZXJhZ2VfUzA7Cgl9Cn0KAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAADAAAACgAAAGluUG9zaXRpb24AAAcAAABpbkNvbG9yAA8AAABpblRleHR1cmVDb29yZHMAAAAAAA==","AYQA5AADQAAAOAEARAFQJAABBADIB7777777777777777777777767YAAAAAAAAAAAAB3QA6AAAEAAAAAAAMAAPEAEAAABAAAAAAB2AAAAAAACAAAAAEBSAAAA":"DAAAAExTS1PMAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQ0IHVsb2NhbE1hdHJpeF9TMDsKaW4gZmxvYXQyIGluUG9zaXRpb247CmluIGhhbGY0IGluQ29sb3I7CmluIGZsb2F0NCBpbkNpcmNsZUVkZ2U7Cm91dCBmbG9hdDQgdmluQ2lyY2xlRWRnZV9TMDsKb3V0IGhhbGY0IHZpbkNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBDaXJjbGVHZW9tZXRyeVByb2Nlc3NvcgoJdmluQ2lyY2xlRWRnZV9TMCA9IGluQ2lyY2xlRWRnZTsKCXZpbkNvbG9yX1MwID0gaW5Db2xvcjsKCWZsb2F0MiBfdG1wXzBfaW5Qb3NpdGlvbiA9IGluUG9zaXRpb247CglmbG9hdDIgX3RtcF8xX2luUG9zaXRpb24gPSB1bG9jYWxNYXRyaXhfUzAueHogKiBpblBvc2l0aW9uICsgdWxvY2FsTWF0cml4X1MwLnl3OwoJc2tfUG9zaXRpb24gPSBfdG1wXzBfaW5Qb3NpdGlvbi54eTAxOwp9CgEAAAAeBQAAdW5pZm9ybSBmbG9hdDQgdWlubmVyUmVjdF9TMTsKdW5pZm9ybSBoYWxmMiB1cmFkaXVzUGx1c0hhbGZfUzE7CnVuaWZvcm0gZmxvYXQ0IHVpbm5lclJlY3RfUzI7CnVuaWZvcm0gaGFsZjIgdXJhZGl1c1BsdXNIYWxmX1MyOwppbiBmbG9hdDQgdmluQ2lyY2xlRWRnZV9TMDsKaW4gaGFsZjQgdmluQ29sb3JfUzA7CmhhbGY0IENpcmN1bGFyUlJlY3RfUzEoaGFsZjQgX2lucHV0KSAKewoJZmxvYXQyIGR4eTAgPSB1aW5uZXJSZWN0X1MxLkxUIC0gc2tfRnJhZ0Nvb3JkLnh5OwoJZmxvYXQyIGR4eTEgPSBza19GcmFnQ29vcmQueHkgLSB1aW5uZXJSZWN0X1MxLlJCOwoJZmxvYXQyIGR4eSA9IG1heChtYXgoZHh5MCwgZHh5MSksIDAuMCk7CgloYWxmIGFscGhhID0gaGFsZihzYXR1cmF0ZSh1cmFkaXVzUGx1c0hhbGZfUzEueCAtIGxlbmd0aChkeHkpKSk7CglhbHBoYSA9IDEuMCAtIGFscGhhOwoJcmV0dXJuIF9pbnB1dCAqIGFscGhhOwp9CmhhbGY0IENpcmN1bGFyUlJlY3RfUzIoaGFsZjQgX2lucHV0KSAKewoJZmxvYXQyIGR4eTAgPSB1aW5uZXJSZWN0X1MyLkxUIC0gc2tfRnJhZ0Nvb3JkLnh5OwoJZmxvYXQyIGR4eTEgPSBza19GcmFnQ29vcmQueHkgLSB1aW5uZXJSZWN0X1MyLlJCOwoJZmxvYXQyIGR4eSA9IG1heChtYXgoZHh5MCwgZHh5MSksIDAuMCk7CgloYWxmIGFscGhhID0gaGFsZihzYXR1cmF0ZSh1cmFkaXVzUGx1c0hhbGZfUzIueCAtIGxlbmd0aChkeHkpKSk7CglyZXR1cm4gX2lucHV0ICogYWxwaGE7Cn0Kdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIENpcmNsZUdlb21ldHJ5UHJvY2Vzc29yCglmbG9hdDQgY2lyY2xlRWRnZTsKCWNpcmNsZUVkZ2UgPSB2aW5DaXJjbGVFZGdlX1MwOwoJaGFsZjQgb3V0cHV0Q29sb3JfUzA7CglvdXRwdXRDb2xvcl9TMCA9IHZpbkNvbG9yX1MwOwoJZmxvYXQgZCA9IGxlbmd0aChjaXJjbGVFZGdlLnh5KTsKCWhhbGYgZGlzdGFuY2VUb091dGVyRWRnZSA9IGhhbGYoY2lyY2xlRWRnZS56ICogKDEuMCAtIGQpKTsKCWhhbGYgZWRnZUFscGhhID0gc2F0dXJhdGUoZGlzdGFuY2VUb091dGVyRWRnZSk7CgloYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KGVkZ2VBbHBoYSk7CgloYWxmNCBvdXRwdXRfUzE7CglvdXRwdXRfUzEgPSBDaXJjdWxhclJSZWN0X1MxKG91dHB1dENvdmVyYWdlX1MwKTsKCWhhbGY0IG91dHB1dF9TMjsKCW91dHB1dF9TMiA9IENpcmN1bGFyUlJlY3RfUzIob3V0cHV0X1MxKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dF9TMjsKCX0KfQoAAAEAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAADAAAACgAAAGluUG9zaXRpb24AAAcAAABpbkNvbG9yAAwAAABpbkNpcmNsZUVkZ2UAAAAA","HWQACAAAABAAADAAAIOAAAAADIIAAIRODAAP577774DSAIAA737777YBAAAAAAAAAAAHEADZAAAAAAIAAAAAAOQAAAAAAAQAAAABAMQAAAAAA":"DAAAAExTS1ONAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gZmxvYXQgY292ZXJhZ2U7CmluIGhhbGY0IGNvbG9yOwppbiBmbG9hdDQgZ2VvbVN1YnNldDsKZmxhdCBvdXQgaGFsZjQgdmNvbG9yX1MwOwpvdXQgZmxvYXQgdmNvdmVyYWdlX1MwOwpmbGF0IG91dCBmbG9hdDQgdmdlb21TdWJzZXRfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJZmxvYXQyIHBvc2l0aW9uID0gcG9zaXRpb24ueHk7Cgl2Y29sb3JfUzAgPSBjb2xvcjsKCXZjb3ZlcmFnZV9TMCA9IGNvdmVyYWdlOwoJdmdlb21TdWJzZXRfUzAgPSBnZW9tU3Vic2V0OwoJc2tfUG9zaXRpb24gPSBwb3NpdGlvbi54eTAxOwp9CgAAAAEAAAAIBAAAdW5pZm9ybSBmbG9hdDQgdWlubmVyUmVjdF9TMTsKdW5pZm9ybSBoYWxmMiB1cmFkaXVzUGx1c0hhbGZfUzE7CmZsYXQgaW4gaGFsZjQgdmNvbG9yX1MwOwppbiBmbG9hdCB2Y292ZXJhZ2VfUzA7CmZsYXQgaW4gZmxvYXQ0IHZnZW9tU3Vic2V0X1MwOwpoYWxmNCBDaXJjdWxhclJSZWN0X1MxKGhhbGY0IF9pbnB1dCkgCnsKCWZsb2F0MiBkeHkwID0gdWlubmVyUmVjdF9TMS5MVCAtIHNrX0ZyYWdDb29yZC54eTsKCWZsb2F0MiBkeHkxID0gc2tfRnJhZ0Nvb3JkLnh5IC0gdWlubmVyUmVjdF9TMS5SQjsKCWZsb2F0MiBkeHkgPSBtYXgobWF4KGR4eTAsIGR4eTEpLCAwLjApOwoJaGFsZiBhbHBoYSA9IGhhbGYoc2F0dXJhdGUodXJhZGl1c1BsdXNIYWxmX1MxLnggLSBsZW5ndGgoZHh5KSkpOwoJcmV0dXJuIF9pbnB1dCAqIGFscGhhOwp9CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2Y29sb3JfUzA7CglmbG9hdCBjb3ZlcmFnZSA9IHZjb3ZlcmFnZV9TMDsKCWZsb2F0NCBnZW9TdWJzZXQ7CglnZW9TdWJzZXQgPSB2Z2VvbVN1YnNldF9TMDsKCWhhbGY0IGRpc3RzNCA9IGNsYW1wKGhhbGY0KDEsIDEsIC0xLCAtMSkgKiBoYWxmNChza19GcmFnQ29vcmQueHl4eSAtIGdlb1N1YnNldCksIDAsIDEpOwoJaGFsZjIgZGlzdHMyID0gZGlzdHM0Lnh5ICsgZGlzdHM0Lnp3IC0gMTsKCWhhbGYgc3Vic2V0Q292ZXJhZ2UgPSBkaXN0czIueCAqIGRpc3RzMi55OwoJY292ZXJhZ2UgPSBtaW4oY292ZXJhZ2UsIHN1YnNldENvdmVyYWdlKTsKCWhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoaGFsZihjb3ZlcmFnZSkpOwoJaGFsZjQgb3V0cHV0X1MxOwoJb3V0cHV0X1MxID0gQ2lyY3VsYXJSUmVjdF9TMShvdXRwdXRDb3ZlcmFnZV9TMCk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRfUzE7Cgl9Cn0KAQAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAIAAAAcG9zaXRpb24IAAAAY292ZXJhZ2UFAAAAY29sb3IAAAAKAAAAZ2VvbVN1YnNldAAAAAAAAA==","HUIAAAAAAAQAADAAAIOAAAH677777777777QGHAQAD7P7777777777YBAAAAAAAAAAALUASJ3EZYN2AAAAAAAAAEAAAABSCQKL3IYIJ2AAAAAAAAAEAAAABLBAABAAAAABAEGABBAMAAAAAAAAAAAOQAAAAAAAQAAAABAMQAAAAAA":"DAAAAExTS1M2AQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMTsKaW4gZmxvYXQyIHBvc2l0aW9uOwppbiBmbG9hdDIgbG9jYWxDb29yZDsKb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCglza19Qb3NpdGlvbiA9IHBvc2l0aW9uLnh5MDE7Cgl7CgkJdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzAgPSBmbG9hdDN4Mih1bWF0cml4X1MxKSAqIGxvY2FsQ29vcmQueHkxOwoJfQp9CgAAAAAAACoFAABjb25zdCBpbnQga01heExvb3BMaW1pdF9TMV9jMCA9IDg7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMV9jMF9jMDsKdW5pZm9ybSBoYWxmNCB1b2Zmc2V0c0FuZEtlcm5lbF9TMV9jMFsxNF07CnVuaWZvcm0gaGFsZjIgdWRpcl9TMV9jMDsKdW5pZm9ybSBmbG9hdDN4MyB1bWF0cml4X1MxOwpzYW1wbGVyMkQgdVRleHR1cmVTYW1wbGVyXzBfUzE7CmluIGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKaGFsZjQgVGV4dHVyZUVmZmVjdF9TMV9jMF9jMF9jMChoYWxmNCBfaW5wdXQsIGZsb2F0MiBfY29vcmRzKSAKewoJcmV0dXJuIHNhbXBsZSh1VGV4dHVyZVNhbXBsZXJfMF9TMSwgX2Nvb3Jkcyk7Cn0KaGFsZjQgTWF0cml4RWZmZWN0X1MxX2MwX2MwKGhhbGY0IF9pbnB1dCwgZmxvYXQyIF9jb29yZHMpIAp7CglyZXR1cm4gVGV4dHVyZUVmZmVjdF9TMV9jMF9jMF9jMChfaW5wdXQsIGZsb2F0M3gyKHVtYXRyaXhfUzFfYzBfYzApICogX2Nvb3Jkcy54eTEpOwp9CmhhbGY0IEdhdXNzaWFuQmx1cjFEX1MxX2MwKGhhbGY0IF9pbnB1dCkgCnsKCWhhbGY0IF90bXBfMF9pbkNvbG9yID0gX2lucHV0OwoJZmxvYXQyIF90bXBfMV9jb29yZHMgPSB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKCWhhbGY0IHN1bSA9IGhhbGY0KDAuMCk7Cglmb3IgKGludCBpID0gMDtpIDwga01heExvb3BMaW1pdF9TMV9jMDsgKytpKSAKCXsKCQloYWxmNCBzID0gdW9mZnNldHNBbmRLZXJuZWxfUzFfYzBbaV07CgkJc3VtICs9IHMueSAqIE1hdHJpeEVmZmVjdF9TMV9jMF9jMChfdG1wXzBfaW5Db2xvciwgX3RtcF8xX2Nvb3JkcyArIGZsb2F0MihzLnggKiB1ZGlyX1MxX2MwKSk7CgkJc3VtICs9IHMudyAqIE1hdHJpeEVmZmVjdF9TMV9jMF9jMChfdG1wXzBfaW5Db2xvciwgX3RtcF8xX2Nvb3JkcyArIGZsb2F0MihzLnogKiB1ZGlyX1MxX2MwKSk7Cgl9CglyZXR1cm4gaGFsZjQoc3VtKTsKfQpoYWxmNCBNYXRyaXhFZmZlY3RfUzEoaGFsZjQgX2lucHV0KSAKewoJcmV0dXJuIEdhdXNzaWFuQmx1cjFEX1MxX2MwKF9pbnB1dCk7Cn0Kdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJaGFsZjQgb3V0cHV0Q29sb3JfUzAgPSBoYWxmNCgxKTsKCWNvbnN0IGhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoMSk7CgloYWxmNCBvdXRwdXRfUzE7CglvdXRwdXRfUzEgPSBNYXRyaXhFZmZlY3RfUzEob3V0cHV0Q29sb3JfUzApOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dF9TMSAqIG91dHB1dENvdmVyYWdlX1MwOwoJfQp9CgAAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAIAAAAcG9zaXRpb24KAAAAbG9jYWxDb29yZAAAAAAAAA==","HVIAAAAAABIAAGAAAQ4AAAH477776R24EAAAIOBQAD6P7777777777YDAAAAAAAAAAAHQBNGZODK5YIAAAAAAQAAAAAIADCNS4GV3QYBAAAAAAAAAAAIAALIAAAAAUDLMERKGAAAAAMAAAAAIAAAAAAAIBDNIWUYZAUAAAAAAYAAAAAAAAAABUABAAAAAEAAAAAIBEABAAAAA":"DAAAAExTS1N0AQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMTsKaW4gZmxvYXQyIHBvc2l0aW9uOwppbiBoYWxmNCBjb2xvcjsKaW4gZmxvYXQyIGxvY2FsQ29vcmQ7CmZsYXQgb3V0IGhhbGY0IHZjb2xvcl9TMDsKb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgl2Y29sb3JfUzAgPSBjb2xvcjsKCXNrX1Bvc2l0aW9uID0gcG9zaXRpb24ueHkwMTsKCXsKCQl2VHJhbnNmb3JtZWRDb29yZHNfMl9TMCA9IGZsb2F0M3gyKHVtYXRyaXhfUzEpICogbG9jYWxDb29yZC54eTE7Cgl9Cn0KAQAAAJAeAABmbG9hdDQgZmx1dHRlcl9GcmFnQ29vcmRfUzFfYzA7CmZsb2F0NCBmcmFnQ29sb3JfUzFfYzA7CmZsb2F0IHVfYWxwaGFfUzFfYzA7CmZsb2F0IHVfc3BhcmtsZV9hbHBoYV9TMV9jMDsKZmxvYXQgdV9ibHVyX1MxX2MwOwpmbG9hdCB1X3JhZGl1c19zY2FsZV9TMV9jMDsKY29uc3QgaW50IGtGaWxsQUFfUzJfYzAgPSAxOwpjb25zdCBpbnQga0ludmVyc2VGaWxsQldfUzJfYzAgPSAyOwpjb25zdCBpbnQga0ludmVyc2VGaWxsQUFfUzJfYzAgPSAzOwp1bmlmb3JtIGZsb2F0NCB1X2NvbG9yX1MxX2MwOwp1bmlmb3JtIGZsb2F0NCB1X2NvbXBvc2l0ZV8xX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X2NlbnRlcl9TMV9jMDsKdW5pZm9ybSBmbG9hdCB1X21heF9yYWRpdXNfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfcmVzb2x1dGlvbl9zY2FsZV9TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9ub2lzZV9zY2FsZV9TMV9jMDsKdW5pZm9ybSBmbG9hdCB1X25vaXNlX3BoYXNlX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X2NpcmNsZTFfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfY2lyY2xlMl9TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9jaXJjbGUzX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X3JvdGF0aW9uMV9TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9yb3RhdGlvbjJfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfcm90YXRpb24zX1MxX2MwOwp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzE7CnVuaWZvcm0gZmxvYXQ0IHVjaXJjbGVfUzJfYzA7CmZsYXQgaW4gaGFsZjQgdmNvbG9yX1MwOwppbiBmbG9hdDIgdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzA7CmZsb2F0MiBGTFRfZmx1dHRlcl9sb2NhbF9GbHV0dGVyRnJhZ0Nvb3JkX1MxX2MwKCk7CmZsb2F0MngyIEZMVF9mbHV0dGVyX2xvY2FsX3JvdGF0ZTJkX1MxX2MwKGZsb2F0MiByYWQpOwpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X2NpcmNsZV9TMV9jMChmbG9hdDIgdXYsIGZsb2F0MiB4eSwgZmxvYXQgcmFkaXVzLCBmbG9hdCBibHVyKTsKZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfY2lyY2xlX2dyaWRfUzFfYzAoZmxvYXQyIHJlc29sdXRpb24sIGlub3V0IGZsb2F0MiBwLCBmbG9hdDIgeHksIGZsb2F0MiByb3RhdGlvbiwgZmxvYXQgY2VsbF9kaWFtZXRlcik7CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3R1cmJ1bGVuY2VfUzFfYzAoZmxvYXQyIHV2KTsKZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9yaW5nX1MxX2MwKGZsb2F0MiB1diwgZmxvYXQyIHh5LCBmbG9hdCByYWRpdXMsIGZsb2F0IHRoaWNrbmVzcywgZmxvYXQgYmx1cik7CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3RyaWFuZ2xlX25vaXNlX1MxX2MwKGlub3V0IGZsb2F0MiBuKTsKZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfdGhyZXNob2xkX1MxX2MwKGZsb2F0IHYsIGZsb2F0IGwsIGZsb2F0IGgpOwpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9zcGFya2xlX1MxX2MwKGZsb2F0MiB1diwgZmxvYXQgdCk7CnZvaWQgRkxUX21haW5fUzFfYzAoKTsKZmxvYXQyIEZMVF9mbHV0dGVyX2xvY2FsX0ZsdXR0ZXJGcmFnQ29vcmRfUzFfYzAoKSAKewoJcmV0dXJuIGZsdXR0ZXJfRnJhZ0Nvb3JkX1MxX2MwLnh5Owp9CmZsb2F0MngyIEZMVF9mbHV0dGVyX2xvY2FsX3JvdGF0ZTJkX1MxX2MwKGZsb2F0MiByYWQpIAp7CglyZXR1cm4gZmxvYXQyeDIocmFkLngsIC1yYWQueSwgcmFkLnksIHJhZC54KTsKfQpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X2NpcmNsZV9TMV9jMChmbG9hdDIgdXYsIGZsb2F0MiB4eSwgZmxvYXQgcmFkaXVzLCBmbG9hdCBibHVyKSAKewoJZmxvYXQgYmx1cl9oYWxmID0gYmx1ciAqIDAuNTsKCWZsb2F0IGQgPSBkaXN0YW5jZSh1diwgeHkpOwoJcmV0dXJuIDEuMCAtIHNtb290aHN0ZXAoMS4wIC0gYmx1cl9oYWxmLCAxLjAgKyBibHVyX2hhbGYsIGQgLyByYWRpdXMpOwp9CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX2NpcmNsZV9ncmlkX1MxX2MwKGZsb2F0MiByZXNvbHV0aW9uLCBpbm91dCBmbG9hdDIgcCwgZmxvYXQyIHh5LCBmbG9hdDIgcm90YXRpb24sIGZsb2F0IGNlbGxfZGlhbWV0ZXIpIAp7CglmbG9hdDIgcGFyYW0gPSByb3RhdGlvbjsKCXAgPSBGTFRfZmx1dHRlcl9sb2NhbF9yb3RhdGUyZF9TMV9jMChwYXJhbSkgKiAoeHkgLSBwKSArIHh5OwoJcCA9IG1vZChwLCBmbG9hdDIoY2VsbF9kaWFtZXRlcikpIC8gcmVzb2x1dGlvbjsKCWZsb2F0IGNlbGxfdXYgPSAoY2VsbF9kaWFtZXRlciAvIHJlc29sdXRpb24ueSkgKiAwLjU7CglmbG9hdCByID0gMC42NSAqIGNlbGxfdXY7CglmbG9hdDIgcGFyYW1fMSA9IHA7CglmbG9hdDIgcGFyYW1fMiA9IGZsb2F0MihjZWxsX3V2KTsKCWZsb2F0IHBhcmFtXzMgPSByOwoJZmxvYXQgcGFyYW1fNCA9IHIgKiA1MC4wOwoJcmV0dXJuIEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfY2lyY2xlX1MxX2MwKHBhcmFtXzEsIHBhcmFtXzIsIHBhcmFtXzMsIHBhcmFtXzQpOwp9CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3R1cmJ1bGVuY2VfUzFfYzAoZmxvYXQyIHV2KSAKewoJZmxvYXQyIHV2X3NjYWxlID0gdXYgKiBmbG9hdDIoMC44KTsKCWZsb2F0MiBwYXJhbSA9IGZsb2F0MigwLjgpOwoJZmxvYXQyIHBhcmFtXzEgPSB1dl9zY2FsZTsKCWZsb2F0MiBwYXJhbV8yID0gdV9jaXJjbGUxX1MxX2MwOwoJZmxvYXQyIHBhcmFtXzMgPSB1X3JvdGF0aW9uMV9TMV9jMDsKCWZsb2F0IHBhcmFtXzQgPSAwLjE3OwoJZmxvYXQgXzMxOSA9IEZMVF9mbHV0dGVyX2xvY2FsX2NpcmNsZV9ncmlkX1MxX2MwKHBhcmFtLCBwYXJhbV8xLCBwYXJhbV8yLCBwYXJhbV8zLCBwYXJhbV80KTsKCWZsb2F0IGcxID0gXzMxOTsKCWZsb2F0MiBwYXJhbV81ID0gZmxvYXQyKDAuOCk7CglmbG9hdDIgcGFyYW1fNiA9IHV2X3NjYWxlOwoJZmxvYXQyIHBhcmFtXzcgPSB1X2NpcmNsZTJfUzFfYzA7CglmbG9hdDIgcGFyYW1fOCA9IHVfcm90YXRpb24yX1MxX2MwOwoJZmxvYXQgcGFyYW1fOSA9IDAuMjsKCWZsb2F0IF8zMzEgPSBGTFRfZmx1dHRlcl9sb2NhbF9jaXJjbGVfZ3JpZF9TMV9jMChwYXJhbV81LCBwYXJhbV82LCBwYXJhbV83LCBwYXJhbV84LCBwYXJhbV85KTsKCWZsb2F0IGcyID0gXzMzMTsKCWZsb2F0MiBwYXJhbV8xMCA9IGZsb2F0MigwLjgpOwoJZmxvYXQyIHBhcmFtXzExID0gdXZfc2NhbGU7CglmbG9hdDIgcGFyYW1fMTIgPSB1X2NpcmNsZTNfUzFfYzA7CglmbG9hdDIgcGFyYW1fMTMgPSB1X3JvdGF0aW9uM19TMV9jMDsKCWZsb2F0IHBhcmFtXzE0ID0gMC4yNzU7CglmbG9hdCBfMzQ0ID0gRkxUX2ZsdXR0ZXJfbG9jYWxfY2lyY2xlX2dyaWRfUzFfYzAocGFyYW1fMTAsIHBhcmFtXzExLCBwYXJhbV8xMiwgcGFyYW1fMTMsIHBhcmFtXzE0KTsKCWZsb2F0IGczID0gXzM0NDsKCWZsb2F0IHYgPSAoKGcxICogZzEgKyBnMikgLSBnMykgKiAwLjU7CglyZXR1cm4gY2xhbXAoMC40NSArIDAuOCAqIHYsIDAuMCwgMS4wKTsKfQpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X3JpbmdfUzFfYzAoZmxvYXQyIHV2LCBmbG9hdDIgeHksIGZsb2F0IHJhZGl1cywgZmxvYXQgdGhpY2tuZXNzLCBmbG9hdCBibHVyKSAKewoJZmxvYXQyIHBhcmFtID0gdXY7CglmbG9hdDIgcGFyYW1fMSA9IHh5OwoJZmxvYXQgcGFyYW1fMiA9IHJhZGl1cyArIHRoaWNrbmVzczsKCWZsb2F0IHBhcmFtXzMgPSBibHVyOwoJZmxvYXQgY2lyY2xlX291dGVyID0gRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9jaXJjbGVfUzFfYzAocGFyYW0sIHBhcmFtXzEsIHBhcmFtXzIsIHBhcmFtXzMpOwoJZmxvYXQyIHBhcmFtXzQgPSB1djsKCWZsb2F0MiBwYXJhbV81ID0geHk7CglmbG9hdCBwYXJhbV82ID0gbWF4KHJhZGl1cyAtIHRoaWNrbmVzcywgMC4wKTsKCWZsb2F0IHBhcmFtXzcgPSBibHVyOwoJZmxvYXQgY2lyY2xlX2lubmVyID0gRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9jaXJjbGVfUzFfYzAocGFyYW1fNCwgcGFyYW1fNSwgcGFyYW1fNiwgcGFyYW1fNyk7CglyZXR1cm4gY2xhbXAoY2lyY2xlX291dGVyIC0gY2lyY2xlX2lubmVyLCAwLjAsIDEuMCk7Cn0KZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfdHJpYW5nbGVfbm9pc2VfUzFfYzAoaW5vdXQgZmxvYXQyIG4pIAp7CgluID0gZnJhY3QobiAqIGZsb2F0Mig1LjM5ODcsIDUuNDQyMSkpOwoJbiArPSBmbG9hdDIoZG90KG4ueXgsIG4gKyBmbG9hdDIoMjEuNTM1MSwgMTQuMzEzNykpKTsKCWZsb2F0IHh5ID0gbi54ICogbi55OwoJcmV0dXJuIChmcmFjdCh4eSAqIDk1LjQzMDcpICsgZnJhY3QoeHkgKiA3NS4wNDk2MSkpIC0gMS4wOwp9CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3RocmVzaG9sZF9TMV9jMChmbG9hdCB2LCBmbG9hdCBsLCBmbG9hdCBoKSAKewoJcmV0dXJuIHN0ZXAobCwgdikgKiAoMS4wIC0gc3RlcChoLCB2KSk7Cn0KZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfc3BhcmtsZV9TMV9jMChmbG9hdDIgdXYsIGZsb2F0IHQpIAp7CglmbG9hdDIgcGFyYW0gPSB1djsKCWZsb2F0IF8yNDIgPSBGTFRfZmx1dHRlcl9sb2NhbF90cmlhbmdsZV9ub2lzZV9TMV9jMChwYXJhbSk7CglmbG9hdCBuID0gXzI0MjsKCWZsb2F0IHBhcmFtXzEgPSBuOwoJZmxvYXQgcGFyYW1fMiA9IDAuMDsKCWZsb2F0IHBhcmFtXzMgPSAwLjA1OwoJZmxvYXQgcyA9IEZMVF9mbHV0dGVyX2xvY2FsX3RocmVzaG9sZF9TMV9jMChwYXJhbV8xLCBwYXJhbV8yLCBwYXJhbV8zKTsKCWZsb2F0IHBhcmFtXzQgPSBuICsgc2luKDMuMTQxNTkyNzQgKiAodCArIDAuMzUpKTsKCWZsb2F0IHBhcmFtXzUgPSAwLjE7CglmbG9hdCBwYXJhbV82ID0gMC4xNTsKCXMgKz0gRkxUX2ZsdXR0ZXJfbG9jYWxfdGhyZXNob2xkX1MxX2MwKHBhcmFtXzQsIHBhcmFtXzUsIHBhcmFtXzYpOwoJZmxvYXQgcGFyYW1fNyA9IG4gKyBzaW4oMy4xNDE1OTI3NCAqICh0ICsgMC43KSk7CglmbG9hdCBwYXJhbV84ID0gMC4yOwoJZmxvYXQgcGFyYW1fOSA9IDAuMjU7CglzICs9IEZMVF9mbHV0dGVyX2xvY2FsX3RocmVzaG9sZF9TMV9jMChwYXJhbV83LCBwYXJhbV84LCBwYXJhbV85KTsKCWZsb2F0IHBhcmFtXzEwID0gbiArIHNpbigzLjE0MTU5Mjc0ICogKHQgKyAxLjA1KSk7CglmbG9hdCBwYXJhbV8xMSA9IDAuMzsKCWZsb2F0IHBhcmFtXzEyID0gMC4zNTsKCXMgKz0gRkxUX2ZsdXR0ZXJfbG9jYWxfdGhyZXNob2xkX1MxX2MwKHBhcmFtXzEwLCBwYXJhbV8xMSwgcGFyYW1fMTIpOwoJcmV0dXJuIGNsYW1wKHMsIDAuMCwgMS4wKSAqIDAuNTU7Cn0Kdm9pZCBGTFRfbWFpbl9TMV9jMCgpIAp7Cgl1X2FscGhhX1MxX2MwID0gdV9jb21wb3NpdGVfMV9TMV9jMC54OwoJdV9zcGFya2xlX2FscGhhX1MxX2MwID0gdV9jb21wb3NpdGVfMV9TMV9jMC55OwoJdV9ibHVyX1MxX2MwID0gdV9jb21wb3NpdGVfMV9TMV9jMC56OwoJdV9yYWRpdXNfc2NhbGVfUzFfYzAgPSB1X2NvbXBvc2l0ZV8xX1MxX2MwLnc7CglmbG9hdDIgcCA9IEZMVF9mbHV0dGVyX2xvY2FsX0ZsdXR0ZXJGcmFnQ29vcmRfUzFfYzAoKTsKCWZsb2F0MiB1dl8xID0gcCAqIHVfcmVzb2x1dGlvbl9zY2FsZV9TMV9jMDsKCWZsb2F0MiBkZW5zaXR5X3V2ID0gdXZfMSAtIG1vZChwLCB1X25vaXNlX3NjYWxlX1MxX2MwKTsKCWZsb2F0IHJhZGl1cyA9IHVfbWF4X3JhZGl1c19TMV9jMCAqIHVfcmFkaXVzX3NjYWxlX1MxX2MwOwoJZmxvYXQyIHBhcmFtXzEzID0gdXZfMTsKCWZsb2F0IHR1cmJ1bGVuY2UgPSBGTFRfZmx1dHRlcl9sb2NhbF90dXJidWxlbmNlX1MxX2MwKHBhcmFtXzEzKTsKCWZsb2F0MiBwYXJhbV8xNCA9IHA7CglmbG9hdDIgcGFyYW1fMTUgPSB1X2NlbnRlcl9TMV9jMDsKCWZsb2F0IHBhcmFtXzE2ID0gcmFkaXVzOwoJZmxvYXQgcGFyYW1fMTcgPSAwLjA1ICogdV9tYXhfcmFkaXVzX1MxX2MwOwoJZmxvYXQgcGFyYW1fMTggPSB1X2JsdXJfUzFfYzA7CglmbG9hdCByaW5nID0gRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9yaW5nX1MxX2MwKHBhcmFtXzE0LCBwYXJhbV8xNSwgcGFyYW1fMTYsIHBhcmFtXzE3LCBwYXJhbV8xOCk7CglmbG9hdDIgcGFyYW1fMTkgPSBkZW5zaXR5X3V2OwoJZmxvYXQgcGFyYW1fMjAgPSB1X25vaXNlX3BoYXNlX1MxX2MwOwoJZmxvYXQgc3BhcmtsZSA9ICgoRkxUX2ZsdXR0ZXJfbG9jYWxfc3BhcmtsZV9TMV9jMChwYXJhbV8xOSwgcGFyYW1fMjApICogcmluZykgKiB0dXJidWxlbmNlKSAqIHVfc3BhcmtsZV9hbHBoYV9TMV9jMDsKCWZsb2F0MiBwYXJhbV8yMSA9IHA7CglmbG9hdDIgcGFyYW1fMjIgPSB1X2NlbnRlcl9TMV9jMDsKCWZsb2F0IHBhcmFtXzIzID0gcmFkaXVzOwoJZmxvYXQgcGFyYW1fMjQgPSB1X2JsdXJfUzFfYzA7CglmbG9hdCB3YXZlX2FscGhhID0gKEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfY2lyY2xlX1MxX2MwKHBhcmFtXzIxLCBwYXJhbV8yMiwgcGFyYW1fMjMsIHBhcmFtXzI0KSAqIHVfYWxwaGFfUzFfYzApICogdV9jb2xvcl9TMV9jMC53OwoJZmxvYXQ0IHdhdmVfY29sb3IgPSBmbG9hdDQodV9jb2xvcl9TMV9jMC54eXogKiB3YXZlX2FscGhhLCB3YXZlX2FscGhhKTsKCWZyYWdDb2xvcl9TMV9jMCA9IG1peCh3YXZlX2NvbG9yLCBmbG9hdDQoMS4wKSwgZmxvYXQ0KHNwYXJrbGUpKTsKfQpoYWxmNCBydW50aW1lX3NoYWRlcl9TMV9jMChoYWxmNCBfaW5wdXQpIAp7CgloYWxmNCBfdG1wXzBfaW5Db2xvciA9IF9pbnB1dDsKCWZsb2F0MiBfdG1wXzFfY29vcmRzID0gdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzA7CglmbHV0dGVyX0ZyYWdDb29yZF9TMV9jMCA9IGZsb2F0NChfdG1wXzFfY29vcmRzLCAwLjAsIDAuMCk7CglGTFRfbWFpbl9TMV9jMCgpOwoJcmV0dXJuIGhhbGY0KGhhbGY0KGZyYWdDb2xvcl9TMV9jMCkpOwp9CmhhbGY0IE1hdHJpeEVmZmVjdF9TMShoYWxmNCBfaW5wdXQpIAp7CglyZXR1cm4gcnVudGltZV9zaGFkZXJfUzFfYzAoX2lucHV0KTsKfQpoYWxmNCBDaXJjbGVfUzJfYzAoaGFsZjQgX2lucHV0KSAKewoJaGFsZjQgX3RtcF8yX2luQ29sb3IgPSBfaW5wdXQ7CgloYWxmIGQ7CglpZiAoaW50KDEpID09IGtJbnZlcnNlRmlsbEJXX1MyX2MwIHx8IGludCgxKSA9PSBrSW52ZXJzZUZpbGxBQV9TMl9jMCkgCgl7CgkJZCA9IGhhbGYoKGxlbmd0aCgodWNpcmNsZV9TMl9jMC54eSAtIHNrX0ZyYWdDb29yZC54eSkgKiB1Y2lyY2xlX1MyX2MwLncpIC0gMS4wKSAqIHVjaXJjbGVfUzJfYzAueik7Cgl9CgllbHNlIAoJewoJCWQgPSBoYWxmKCgxLjAgLSBsZW5ndGgoKHVjaXJjbGVfUzJfYzAueHkgLSBza19GcmFnQ29vcmQueHkpICogdWNpcmNsZV9TMl9jMC53KSkgKiB1Y2lyY2xlX1MyX2MwLnopOwoJfQoJcmV0dXJuIGhhbGY0KGhhbGY0KGludCgxKSA9PSBrRmlsbEFBX1MyX2MwIHx8IGludCgxKSA9PSBrSW52ZXJzZUZpbGxBQV9TMl9jMCA/IHNhdHVyYXRlKGQpIDogaGFsZihkID4gMC41KSkpOwp9CmhhbGY0IEJsZW5kX1MyKGhhbGY0IF9zcmMsIGhhbGY0IF9kc3QpIAp7CglyZXR1cm4gYmxlbmRfbW9kdWxhdGUoX3NyYywgQ2lyY2xlX1MyX2MwKF9zcmMpKTsKfQp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmNvbG9yX1MwOwoJY29uc3QgaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNCgxKTsKCWhhbGY0IG91dHB1dF9TMTsKCW91dHB1dF9TMSA9IE1hdHJpeEVmZmVjdF9TMShvdXRwdXRDb2xvcl9TMCk7CgloYWxmNCBvdXRwdXRfUzI7CglvdXRwdXRfUzIgPSBCbGVuZF9TMihvdXRwdXRDb3ZlcmFnZV9TMCwgaGFsZjQoMSkpOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dF9TMSAqIG91dHB1dF9TMjsKCX0KfQoBAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAgAAABwb3NpdGlvbgUAAABjb2xvcgAAAAoAAABsb2NhbENvb3JkAAAAAAAA","HUIAAAAAAAQAADAAAIOAAAH677777777777QGHAQAD7P7777777777YBAAAAAAAAAAALUAQBAEAQAAAAGQCBAMQACAIAAAAAACQAGAAAAAQAAAAAAAQQGAAAAA":"DAAAAExTS1M2AQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMTsKaW4gZmxvYXQyIHBvc2l0aW9uOwppbiBmbG9hdDIgbG9jYWxDb29yZDsKb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCglza19Qb3NpdGlvbiA9IHBvc2l0aW9uLnh5MDE7Cgl7CgkJdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzAgPSBmbG9hdDN4Mih1bWF0cml4X1MxKSAqIGxvY2FsQ29vcmQueHkxOwoJfQp9CgAAAAAAAEUDAAB1bmlmb3JtIGZsb2F0NCB1Y2xhbXBfUzFfYzA7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMTsKc2FtcGxlcjJEIHVUZXh0dXJlU2FtcGxlcl8wX1MxOwppbiBmbG9hdDIgdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzA7CmhhbGY0IFRleHR1cmVFZmZlY3RfUzFfYzAoaGFsZjQgX2lucHV0KSAKewoJZmxvYXQyIGluQ29vcmQgPSB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKCWZsb2F0MiBzdWJzZXRDb29yZDsKCXN1YnNldENvb3JkLnggPSBpbkNvb3JkLng7CglzdWJzZXRDb29yZC55ID0gaW5Db29yZC55OwoJZmxvYXQyIGNsYW1wZWRDb29yZDsKCWNsYW1wZWRDb29yZCA9IGNsYW1wKHN1YnNldENvb3JkLCB1Y2xhbXBfUzFfYzAueHksIHVjbGFtcF9TMV9jMC56dyk7CgloYWxmNCB0ZXh0dXJlQ29sb3IgPSBzYW1wbGUodVRleHR1cmVTYW1wbGVyXzBfUzEsIGNsYW1wZWRDb29yZCk7CglyZXR1cm4gdGV4dHVyZUNvbG9yOwp9CmhhbGY0IE1hdHJpeEVmZmVjdF9TMShoYWxmNCBfaW5wdXQpIAp7CglyZXR1cm4gVGV4dHVyZUVmZmVjdF9TMV9jMChfaW5wdXQpOwp9CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwID0gaGFsZjQoMSk7Cgljb25zdCBoYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KDEpOwoJaGFsZjQgb3V0cHV0X1MxOwoJb3V0cHV0X1MxID0gTWF0cml4RWZmZWN0X1MxKG91dHB1dENvbG9yX1MwKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRfUzEgKiBvdXRwdXRDb3ZlcmFnZV9TMDsKCX0KfQoAAAAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAgAAABwb3NpdGlvbgoAAABsb2NhbENvb3JkAAAAAAAA","HVIAAAAAABIAAGAAAQ4AAAH477776R24EAAAIOBQAD6P7777777777YDAAAAAAAAAAAFIBVWKMG7QAAAAAAGVXOVKVEAAAAADAAAAAFQ454NUDACAAAIAQZUOAMQAAAAIAAAAAEARTKLVK5LSAAAAABQAAAAAYGP6G2BSBAAAAAIO2HAGIAAAAAAAEAAAAAZ3RZTY3IGAEAAAAAAAAAGARI4UKA4WAAAAAAAEAAAABSMQII2XAGAAAAAAAAAAACAA4AAAACAAAAAAACCAYAA":"DAAAAExTS1OAAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMV9jMF9jMTsKaW4gZmxvYXQyIHBvc2l0aW9uOwppbiBoYWxmNCBjb2xvcjsKaW4gZmxvYXQyIGxvY2FsQ29vcmQ7CmZsYXQgb3V0IGhhbGY0IHZjb2xvcl9TMDsKb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfNV9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgl2Y29sb3JfUzAgPSBjb2xvcjsKCXNrX1Bvc2l0aW9uID0gcG9zaXRpb24ueHkwMTsKCXsKCQl2VHJhbnNmb3JtZWRDb29yZHNfNV9TMCA9IGZsb2F0M3gyKHVtYXRyaXhfUzFfYzBfYzEpICogbG9jYWxDb29yZC54eTE7Cgl9Cn0KAAAAAIIGAAB1bmlmb3JtIGhhbGY0IHVzdGFydF9TMV9jMF9jMDsKdW5pZm9ybSBoYWxmNCB1ZW5kX1MxX2MwX2MwOwp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzFfYzBfYzE7CnVuaWZvcm0gaGFsZjQgdWxlZnRCb3JkZXJDb2xvcl9TMV9jMDsKdW5pZm9ybSBoYWxmNCB1cmlnaHRCb3JkZXJDb2xvcl9TMV9jMDsKZmxhdCBpbiBoYWxmNCB2Y29sb3JfUzA7CmluIGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfNV9TMDsKaGFsZjQgU2luZ2xlSW50ZXJ2YWxDb2xvcml6ZXJfUzFfYzBfYzAoaGFsZjQgX2lucHV0LCBmbG9hdDIgX2Nvb3JkcykgCnsKCWhhbGY0IF90bXBfMF9pbkNvbG9yID0gX2lucHV0OwoJZmxvYXQyIF90bXBfMV9jb29yZHMgPSBfY29vcmRzOwoJcmV0dXJuIGhhbGY0KG1peCh1c3RhcnRfUzFfYzBfYzAsIHVlbmRfUzFfYzBfYzAsIGhhbGYoX3RtcF8xX2Nvb3Jkcy54KSkpOwp9CmhhbGY0IExpbmVhckxheW91dF9TMV9jMF9jMV9jMChoYWxmNCBfaW5wdXQpIAp7CgloYWxmNCBfdG1wXzJfaW5Db2xvciA9IF9pbnB1dDsKCWZsb2F0MiBfdG1wXzNfY29vcmRzID0gdlRyYW5zZm9ybWVkQ29vcmRzXzVfUzA7CglyZXR1cm4gaGFsZjQoaGFsZjQoaGFsZihfdG1wXzNfY29vcmRzLngpICsgMWUtMDUsIDEuMCwgMC4wLCAwLjApKTsKfQpoYWxmNCBNYXRyaXhFZmZlY3RfUzFfYzBfYzEoaGFsZjQgX2lucHV0KSAKewoJcmV0dXJuIExpbmVhckxheW91dF9TMV9jMF9jMV9jMChfaW5wdXQpOwp9CmhhbGY0IENsYW1wZWRHcmFkaWVudF9TMV9jMChoYWxmNCBfaW5wdXQpIAp7CgloYWxmNCBfdG1wXzRfaW5Db2xvciA9IF9pbnB1dDsKCWhhbGY0IHQgPSBNYXRyaXhFZmZlY3RfUzFfYzBfYzEoX3RtcF80X2luQ29sb3IpOwoJaGFsZjQgb3V0Q29sb3I7CglpZiAoIWJvb2woaW50KDEpKSAmJiB0LnkgPCAwLjApIAoJewoJCW91dENvbG9yID0gaGFsZjQoMC4wKTsKCX0KCWVsc2UgaWYgKHQueCA8IDAuMCkgCgl7CgkJb3V0Q29sb3IgPSB1bGVmdEJvcmRlckNvbG9yX1MxX2MwOwoJfQoJZWxzZSBpZiAodC54ID4gMS4wKSAKCXsKCQlvdXRDb2xvciA9IHVyaWdodEJvcmRlckNvbG9yX1MxX2MwOwoJfQoJZWxzZSAKCXsKCQlvdXRDb2xvciA9IFNpbmdsZUludGVydmFsQ29sb3JpemVyX1MxX2MwX2MwKF90bXBfNF9pbkNvbG9yLCBmbG9hdDIoaGFsZjIodC54LCAwLjApKSk7Cgl9CglyZXR1cm4gaGFsZjQob3V0Q29sb3IpOwp9CmhhbGY0IERpc2FibGVDb3ZlcmFnZUFzQWxwaGFfUzEoaGFsZjQgX2lucHV0KSAKewoJX2lucHV0ID0gQ2xhbXBlZEdyYWRpZW50X1MxX2MwKF9pbnB1dCk7CgloYWxmNCBfdG1wXzVfaW5Db2xvciA9IF9pbnB1dDsKCXJldHVybiBoYWxmNChfaW5wdXQpOwp9CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2Y29sb3JfUzA7Cgljb25zdCBoYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KDEpOwoJaGFsZjQgb3V0cHV0X1MxOwoJb3V0cHV0X1MxID0gRGlzYWJsZUNvdmVyYWdlQXNBbHBoYV9TMShvdXRwdXRDb2xvcl9TMCk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0X1MxICogb3V0cHV0Q292ZXJhZ2VfUzA7Cgl9Cn0KAAAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAgAAABwb3NpdGlvbgUAAABjb2xvcgAAAAoAAABsb2NhbENvb3JkAAAAAAAA","AYQA5AADQAAAOAEARAFQJAABBADIB7777777777777777777777767YAAAAAAAAAACABZQA6AAAEAAAAAAAIADQAAAAIAAAAAAAIIDA":"DAAAAExTS1PMAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQ0IHVsb2NhbE1hdHJpeF9TMDsKaW4gZmxvYXQyIGluUG9zaXRpb247CmluIGhhbGY0IGluQ29sb3I7CmluIGZsb2F0NCBpbkNpcmNsZUVkZ2U7Cm91dCBmbG9hdDQgdmluQ2lyY2xlRWRnZV9TMDsKb3V0IGhhbGY0IHZpbkNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBDaXJjbGVHZW9tZXRyeVByb2Nlc3NvcgoJdmluQ2lyY2xlRWRnZV9TMCA9IGluQ2lyY2xlRWRnZTsKCXZpbkNvbG9yX1MwID0gaW5Db2xvcjsKCWZsb2F0MiBfdG1wXzBfaW5Qb3NpdGlvbiA9IGluUG9zaXRpb247CglmbG9hdDIgX3RtcF8xX2luUG9zaXRpb24gPSB1bG9jYWxNYXRyaXhfUzAueHogKiBpblBvc2l0aW9uICsgdWxvY2FsTWF0cml4X1MwLnl3OwoJc2tfUG9zaXRpb24gPSBfdG1wXzBfaW5Qb3NpdGlvbi54eTAxOwp9CgEAAACPAwAAdW5pZm9ybSBmbG9hdDQgdWlubmVyUmVjdF9TMTsKdW5pZm9ybSBoYWxmMiB1cmFkaXVzUGx1c0hhbGZfUzE7CmluIGZsb2F0NCB2aW5DaXJjbGVFZGdlX1MwOwppbiBoYWxmNCB2aW5Db2xvcl9TMDsKaGFsZjQgQ2lyY3VsYXJSUmVjdF9TMShoYWxmNCBfaW5wdXQpIAp7CglmbG9hdDIgZHh5MCA9IHVpbm5lclJlY3RfUzEuTFQgLSBza19GcmFnQ29vcmQueHk7CglmbG9hdDIgZHh5MSA9IHNrX0ZyYWdDb29yZC54eSAtIHVpbm5lclJlY3RfUzEuUkI7CglmbG9hdDIgZHh5ID0gbWF4KG1heChkeHkwLCBkeHkxKSwgMC4wKTsKCWhhbGYgYWxwaGEgPSBoYWxmKHNhdHVyYXRlKHVyYWRpdXNQbHVzSGFsZl9TMS54IC0gbGVuZ3RoKGR4eSkpKTsKCWFscGhhID0gMS4wIC0gYWxwaGE7CglyZXR1cm4gX2lucHV0ICogYWxwaGE7Cn0Kdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIENpcmNsZUdlb21ldHJ5UHJvY2Vzc29yCglmbG9hdDQgY2lyY2xlRWRnZTsKCWNpcmNsZUVkZ2UgPSB2aW5DaXJjbGVFZGdlX1MwOwoJaGFsZjQgb3V0cHV0Q29sb3JfUzA7CglvdXRwdXRDb2xvcl9TMCA9IHZpbkNvbG9yX1MwOwoJZmxvYXQgZCA9IGxlbmd0aChjaXJjbGVFZGdlLnh5KTsKCWhhbGYgZGlzdGFuY2VUb091dGVyRWRnZSA9IGhhbGYoY2lyY2xlRWRnZS56ICogKDEuMCAtIGQpKTsKCWhhbGYgZWRnZUFscGhhID0gc2F0dXJhdGUoZGlzdGFuY2VUb091dGVyRWRnZSk7CgloYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KGVkZ2VBbHBoYSk7CgloYWxmNCBvdXRwdXRfUzE7CglvdXRwdXRfUzEgPSBDaXJjdWxhclJSZWN0X1MxKG91dHB1dENvdmVyYWdlX1MwKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dF9TMTsKCX0KfQoAAQAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAKAAAAaW5Qb3NpdGlvbgAABwAAAGluQ29sb3IADAAAAGluQ2lyY2xlRWRnZQAAAAA=","HUJAAAAAAAQAADAAAIOAAAH677777777777QGHAQAD7P7777777777YBAAAAAAQAAAAAAQQGAAZAABQAAAAAAAACAAAAADYCAAIAAAAAWBRAAAABAAAAANAEIQCAAAAAAAAAAAAAUABQAAAAEAAAAAAAEEBQAAAA":"DAAAAExTS1N5AQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMV9jMF9jMDsKaW4gZmxvYXQyIHBvc2l0aW9uOwppbiBmbG9hdDIgbG9jYWxDb29yZDsKb3V0IGZsb2F0MiB2bG9jYWxDb29yZF9TMDsKb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfNF9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgl2bG9jYWxDb29yZF9TMCA9IGxvY2FsQ29vcmQ7Cglza19Qb3NpdGlvbiA9IHBvc2l0aW9uLnh5MDE7Cgl7CgkJdlRyYW5zZm9ybWVkQ29vcmRzXzRfUzAgPSBmbG9hdDN4Mih1bWF0cml4X1MxX2MwX2MwKSAqIHBvc2l0aW9uLnh5MTsKCX0KfQoAAAAAAAAAzAMAAHVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMV9jMF9jMDsKc2FtcGxlcjJEIHVUZXh0dXJlU2FtcGxlcl8wX1MwOwpzYW1wbGVyMkQgdVRleHR1cmVTYW1wbGVyXzBfUzE7CmluIGZsb2F0MiB2bG9jYWxDb29yZF9TMDsKaW4gZmxvYXQyIHZUcmFuc2Zvcm1lZENvb3Jkc180X1MwOwpoYWxmNCBUZXh0dXJlRWZmZWN0X1MxX2MwX2MwX2MwKGhhbGY0IF9pbnB1dCkgCnsKCXJldHVybiBzYW1wbGUodVRleHR1cmVTYW1wbGVyXzBfUzEsIHZUcmFuc2Zvcm1lZENvb3Jkc180X1MwKS4wMDByOwp9CmhhbGY0IE1hdHJpeEVmZmVjdF9TMV9jMF9jMChoYWxmNCBfaW5wdXQpIAp7CglyZXR1cm4gVGV4dHVyZUVmZmVjdF9TMV9jMF9jMF9jMChfaW5wdXQpOwp9CmhhbGY0IERldmljZVNwYWNlX1MxX2MwKGhhbGY0IF9pbnB1dCkgCnsKCXJldHVybiBNYXRyaXhFZmZlY3RfUzFfYzBfYzAoX2lucHV0KTsKfQpoYWxmNCBCbGVuZF9TMShoYWxmNCBfc3JjLCBoYWxmNCBfZHN0KSAKewoJcmV0dXJuIGJsZW5kX2RzdF9pbihEZXZpY2VTcGFjZV9TMV9jMChfc3JjKSwgX3NyYyk7Cn0Kdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJaGFsZjQgb3V0cHV0Q29sb3JfUzAgPSBoYWxmNCgxKTsKCWZsb2F0MiB0ZXhDb29yZDsKCXRleENvb3JkID0gdmxvY2FsQ29vcmRfUzA7CglvdXRwdXRDb2xvcl9TMCA9IChibGVuZF9tb2R1bGF0ZShzYW1wbGUodVRleHR1cmVTYW1wbGVyXzBfUzAsIHRleENvb3JkKSwgaGFsZjQoMSkpKTsKCWNvbnN0IGhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoMSk7CgloYWxmNCBvdXRwdXRfUzE7CglvdXRwdXRfUzEgPSBCbGVuZF9TMShvdXRwdXRDb3ZlcmFnZV9TMCwgaGFsZjQoMSkpOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dENvbG9yX1MwICogb3V0cHV0X1MxOwoJfQp9CgAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAACAAAACAAAAHBvc2l0aW9uCgAAAGxvY2FsQ29vcmQAAAAAAAA=","HVIAAAAAABIAAGAAAQ4AAAH477776R24EAAAIOBQAD6P7777777777YDAAAAAAAAAAAHQBNGZODK5YIAAAAAAQAAAAAIADCNS4GV3QYBAAAAAAAAAAAIAA6IAMAAACAAAAAABUABAAAAAEAAAAAIBEABAA":"DAAAAExTS1N0AQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMTsKaW4gZmxvYXQyIHBvc2l0aW9uOwppbiBoYWxmNCBjb2xvcjsKaW4gZmxvYXQyIGxvY2FsQ29vcmQ7CmZsYXQgb3V0IGhhbGY0IHZjb2xvcl9TMDsKb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgl2Y29sb3JfUzAgPSBjb2xvcjsKCXNrX1Bvc2l0aW9uID0gcG9zaXRpb24ueHkwMTsKCXsKCQl2VHJhbnNmb3JtZWRDb29yZHNfMl9TMCA9IGZsb2F0M3gyKHVtYXRyaXhfUzEpICogbG9jYWxDb29yZC54eTE7Cgl9Cn0KAQAAABsdAABmbG9hdDQgZmx1dHRlcl9GcmFnQ29vcmRfUzFfYzA7CmZsb2F0NCBmcmFnQ29sb3JfUzFfYzA7CmZsb2F0IHVfYWxwaGFfUzFfYzA7CmZsb2F0IHVfc3BhcmtsZV9hbHBoYV9TMV9jMDsKZmxvYXQgdV9ibHVyX1MxX2MwOwpmbG9hdCB1X3JhZGl1c19zY2FsZV9TMV9jMDsKdW5pZm9ybSBmbG9hdDQgdV9jb2xvcl9TMV9jMDsKdW5pZm9ybSBmbG9hdDQgdV9jb21wb3NpdGVfMV9TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9jZW50ZXJfUzFfYzA7CnVuaWZvcm0gZmxvYXQgdV9tYXhfcmFkaXVzX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X3Jlc29sdXRpb25fc2NhbGVfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfbm9pc2Vfc2NhbGVfUzFfYzA7CnVuaWZvcm0gZmxvYXQgdV9ub2lzZV9waGFzZV9TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9jaXJjbGUxX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X2NpcmNsZTJfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfY2lyY2xlM19TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9yb3RhdGlvbjFfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfcm90YXRpb24yX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X3JvdGF0aW9uM19TMV9jMDsKdW5pZm9ybSBmbG9hdDN4MyB1bWF0cml4X1MxOwp1bmlmb3JtIGZsb2F0NCB1aW5uZXJSZWN0X1MyOwp1bmlmb3JtIGhhbGYyIHVyYWRpdXNQbHVzSGFsZl9TMjsKZmxhdCBpbiBoYWxmNCB2Y29sb3JfUzA7CmluIGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKZmxvYXQyIEZMVF9mbHV0dGVyX2xvY2FsX0ZsdXR0ZXJGcmFnQ29vcmRfUzFfYzAoKTsKZmxvYXQyeDIgRkxUX2ZsdXR0ZXJfbG9jYWxfcm90YXRlMmRfUzFfYzAoZmxvYXQyIHJhZCk7CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfY2lyY2xlX1MxX2MwKGZsb2F0MiB1diwgZmxvYXQyIHh5LCBmbG9hdCByYWRpdXMsIGZsb2F0IGJsdXIpOwpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9jaXJjbGVfZ3JpZF9TMV9jMChmbG9hdDIgcmVzb2x1dGlvbiwgaW5vdXQgZmxvYXQyIHAsIGZsb2F0MiB4eSwgZmxvYXQyIHJvdGF0aW9uLCBmbG9hdCBjZWxsX2RpYW1ldGVyKTsKZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfdHVyYnVsZW5jZV9TMV9jMChmbG9hdDIgdXYpOwpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X3JpbmdfUzFfYzAoZmxvYXQyIHV2LCBmbG9hdDIgeHksIGZsb2F0IHJhZGl1cywgZmxvYXQgdGhpY2tuZXNzLCBmbG9hdCBibHVyKTsKZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfdHJpYW5nbGVfbm9pc2VfUzFfYzAoaW5vdXQgZmxvYXQyIG4pOwpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF90aHJlc2hvbGRfUzFfYzAoZmxvYXQgdiwgZmxvYXQgbCwgZmxvYXQgaCk7CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3NwYXJrbGVfUzFfYzAoZmxvYXQyIHV2LCBmbG9hdCB0KTsKdm9pZCBGTFRfbWFpbl9TMV9jMCgpOwpmbG9hdDIgRkxUX2ZsdXR0ZXJfbG9jYWxfRmx1dHRlckZyYWdDb29yZF9TMV9jMCgpIAp7CglyZXR1cm4gZmx1dHRlcl9GcmFnQ29vcmRfUzFfYzAueHk7Cn0KZmxvYXQyeDIgRkxUX2ZsdXR0ZXJfbG9jYWxfcm90YXRlMmRfUzFfYzAoZmxvYXQyIHJhZCkgCnsKCXJldHVybiBmbG9hdDJ4MihyYWQueCwgLXJhZC55LCByYWQueSwgcmFkLngpOwp9CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfY2lyY2xlX1MxX2MwKGZsb2F0MiB1diwgZmxvYXQyIHh5LCBmbG9hdCByYWRpdXMsIGZsb2F0IGJsdXIpIAp7CglmbG9hdCBibHVyX2hhbGYgPSBibHVyICogMC41OwoJZmxvYXQgZCA9IGRpc3RhbmNlKHV2LCB4eSk7CglyZXR1cm4gMS4wIC0gc21vb3Roc3RlcCgxLjAgLSBibHVyX2hhbGYsIDEuMCArIGJsdXJfaGFsZiwgZCAvIHJhZGl1cyk7Cn0KZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfY2lyY2xlX2dyaWRfUzFfYzAoZmxvYXQyIHJlc29sdXRpb24sIGlub3V0IGZsb2F0MiBwLCBmbG9hdDIgeHksIGZsb2F0MiByb3RhdGlvbiwgZmxvYXQgY2VsbF9kaWFtZXRlcikgCnsKCWZsb2F0MiBwYXJhbSA9IHJvdGF0aW9uOwoJcCA9IEZMVF9mbHV0dGVyX2xvY2FsX3JvdGF0ZTJkX1MxX2MwKHBhcmFtKSAqICh4eSAtIHApICsgeHk7CglwID0gbW9kKHAsIGZsb2F0MihjZWxsX2RpYW1ldGVyKSkgLyByZXNvbHV0aW9uOwoJZmxvYXQgY2VsbF91diA9IChjZWxsX2RpYW1ldGVyIC8gcmVzb2x1dGlvbi55KSAqIDAuNTsKCWZsb2F0IHIgPSAwLjY1ICogY2VsbF91djsKCWZsb2F0MiBwYXJhbV8xID0gcDsKCWZsb2F0MiBwYXJhbV8yID0gZmxvYXQyKGNlbGxfdXYpOwoJZmxvYXQgcGFyYW1fMyA9IHI7CglmbG9hdCBwYXJhbV80ID0gciAqIDUwLjA7CglyZXR1cm4gRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9jaXJjbGVfUzFfYzAocGFyYW1fMSwgcGFyYW1fMiwgcGFyYW1fMywgcGFyYW1fNCk7Cn0KZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfdHVyYnVsZW5jZV9TMV9jMChmbG9hdDIgdXYpIAp7CglmbG9hdDIgdXZfc2NhbGUgPSB1diAqIGZsb2F0MigwLjgpOwoJZmxvYXQyIHBhcmFtID0gZmxvYXQyKDAuOCk7CglmbG9hdDIgcGFyYW1fMSA9IHV2X3NjYWxlOwoJZmxvYXQyIHBhcmFtXzIgPSB1X2NpcmNsZTFfUzFfYzA7CglmbG9hdDIgcGFyYW1fMyA9IHVfcm90YXRpb24xX1MxX2MwOwoJZmxvYXQgcGFyYW1fNCA9IDAuMTc7CglmbG9hdCBfMzE5ID0gRkxUX2ZsdXR0ZXJfbG9jYWxfY2lyY2xlX2dyaWRfUzFfYzAocGFyYW0sIHBhcmFtXzEsIHBhcmFtXzIsIHBhcmFtXzMsIHBhcmFtXzQpOwoJZmxvYXQgZzEgPSBfMzE5OwoJZmxvYXQyIHBhcmFtXzUgPSBmbG9hdDIoMC44KTsKCWZsb2F0MiBwYXJhbV82ID0gdXZfc2NhbGU7CglmbG9hdDIgcGFyYW1fNyA9IHVfY2lyY2xlMl9TMV9jMDsKCWZsb2F0MiBwYXJhbV84ID0gdV9yb3RhdGlvbjJfUzFfYzA7CglmbG9hdCBwYXJhbV85ID0gMC4yOwoJZmxvYXQgXzMzMSA9IEZMVF9mbHV0dGVyX2xvY2FsX2NpcmNsZV9ncmlkX1MxX2MwKHBhcmFtXzUsIHBhcmFtXzYsIHBhcmFtXzcsIHBhcmFtXzgsIHBhcmFtXzkpOwoJZmxvYXQgZzIgPSBfMzMxOwoJZmxvYXQyIHBhcmFtXzEwID0gZmxvYXQyKDAuOCk7CglmbG9hdDIgcGFyYW1fMTEgPSB1dl9zY2FsZTsKCWZsb2F0MiBwYXJhbV8xMiA9IHVfY2lyY2xlM19TMV9jMDsKCWZsb2F0MiBwYXJhbV8xMyA9IHVfcm90YXRpb24zX1MxX2MwOwoJZmxvYXQgcGFyYW1fMTQgPSAwLjI3NTsKCWZsb2F0IF8zNDQgPSBGTFRfZmx1dHRlcl9sb2NhbF9jaXJjbGVfZ3JpZF9TMV9jMChwYXJhbV8xMCwgcGFyYW1fMTEsIHBhcmFtXzEyLCBwYXJhbV8xMywgcGFyYW1fMTQpOwoJZmxvYXQgZzMgPSBfMzQ0OwoJZmxvYXQgdiA9ICgoZzEgKiBnMSArIGcyKSAtIGczKSAqIDAuNTsKCXJldHVybiBjbGFtcCgwLjQ1ICsgMC44ICogdiwgMC4wLCAxLjApOwp9CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfcmluZ19TMV9jMChmbG9hdDIgdXYsIGZsb2F0MiB4eSwgZmxvYXQgcmFkaXVzLCBmbG9hdCB0aGlja25lc3MsIGZsb2F0IGJsdXIpIAp7CglmbG9hdDIgcGFyYW0gPSB1djsKCWZsb2F0MiBwYXJhbV8xID0geHk7CglmbG9hdCBwYXJhbV8yID0gcmFkaXVzICsgdGhpY2tuZXNzOwoJZmxvYXQgcGFyYW1fMyA9IGJsdXI7CglmbG9hdCBjaXJjbGVfb3V0ZXIgPSBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X2NpcmNsZV9TMV9jMChwYXJhbSwgcGFyYW1fMSwgcGFyYW1fMiwgcGFyYW1fMyk7CglmbG9hdDIgcGFyYW1fNCA9IHV2OwoJZmxvYXQyIHBhcmFtXzUgPSB4eTsKCWZsb2F0IHBhcmFtXzYgPSBtYXgocmFkaXVzIC0gdGhpY2tuZXNzLCAwLjApOwoJZmxvYXQgcGFyYW1fNyA9IGJsdXI7CglmbG9hdCBjaXJjbGVfaW5uZXIgPSBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X2NpcmNsZV9TMV9jMChwYXJhbV80LCBwYXJhbV81LCBwYXJhbV82LCBwYXJhbV83KTsKCXJldHVybiBjbGFtcChjaXJjbGVfb3V0ZXIgLSBjaXJjbGVfaW5uZXIsIDAuMCwgMS4wKTsKfQpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF90cmlhbmdsZV9ub2lzZV9TMV9jMChpbm91dCBmbG9hdDIgbikgCnsKCW4gPSBmcmFjdChuICogZmxvYXQyKDUuMzk4NywgNS40NDIxKSk7CgluICs9IGZsb2F0Mihkb3Qobi55eCwgbiArIGZsb2F0MigyMS41MzUxLCAxNC4zMTM3KSkpOwoJZmxvYXQgeHkgPSBuLnggKiBuLnk7CglyZXR1cm4gKGZyYWN0KHh5ICogOTUuNDMwNykgKyBmcmFjdCh4eSAqIDc1LjA0OTYxKSkgLSAxLjA7Cn0KZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfdGhyZXNob2xkX1MxX2MwKGZsb2F0IHYsIGZsb2F0IGwsIGZsb2F0IGgpIAp7CglyZXR1cm4gc3RlcChsLCB2KSAqICgxLjAgLSBzdGVwKGgsIHYpKTsKfQpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9zcGFya2xlX1MxX2MwKGZsb2F0MiB1diwgZmxvYXQgdCkgCnsKCWZsb2F0MiBwYXJhbSA9IHV2OwoJZmxvYXQgXzI0MiA9IEZMVF9mbHV0dGVyX2xvY2FsX3RyaWFuZ2xlX25vaXNlX1MxX2MwKHBhcmFtKTsKCWZsb2F0IG4gPSBfMjQyOwoJZmxvYXQgcGFyYW1fMSA9IG47CglmbG9hdCBwYXJhbV8yID0gMC4wOwoJZmxvYXQgcGFyYW1fMyA9IDAuMDU7CglmbG9hdCBzID0gRkxUX2ZsdXR0ZXJfbG9jYWxfdGhyZXNob2xkX1MxX2MwKHBhcmFtXzEsIHBhcmFtXzIsIHBhcmFtXzMpOwoJZmxvYXQgcGFyYW1fNCA9IG4gKyBzaW4oMy4xNDE1OTI3NCAqICh0ICsgMC4zNSkpOwoJZmxvYXQgcGFyYW1fNSA9IDAuMTsKCWZsb2F0IHBhcmFtXzYgPSAwLjE1OwoJcyArPSBGTFRfZmx1dHRlcl9sb2NhbF90aHJlc2hvbGRfUzFfYzAocGFyYW1fNCwgcGFyYW1fNSwgcGFyYW1fNik7CglmbG9hdCBwYXJhbV83ID0gbiArIHNpbigzLjE0MTU5Mjc0ICogKHQgKyAwLjcpKTsKCWZsb2F0IHBhcmFtXzggPSAwLjI7CglmbG9hdCBwYXJhbV85ID0gMC4yNTsKCXMgKz0gRkxUX2ZsdXR0ZXJfbG9jYWxfdGhyZXNob2xkX1MxX2MwKHBhcmFtXzcsIHBhcmFtXzgsIHBhcmFtXzkpOwoJZmxvYXQgcGFyYW1fMTAgPSBuICsgc2luKDMuMTQxNTkyNzQgKiAodCArIDEuMDUpKTsKCWZsb2F0IHBhcmFtXzExID0gMC4zOwoJZmxvYXQgcGFyYW1fMTIgPSAwLjM1OwoJcyArPSBGTFRfZmx1dHRlcl9sb2NhbF90aHJlc2hvbGRfUzFfYzAocGFyYW1fMTAsIHBhcmFtXzExLCBwYXJhbV8xMik7CglyZXR1cm4gY2xhbXAocywgMC4wLCAxLjApICogMC41NTsKfQp2b2lkIEZMVF9tYWluX1MxX2MwKCkgCnsKCXVfYWxwaGFfUzFfYzAgPSB1X2NvbXBvc2l0ZV8xX1MxX2MwLng7Cgl1X3NwYXJrbGVfYWxwaGFfUzFfYzAgPSB1X2NvbXBvc2l0ZV8xX1MxX2MwLnk7Cgl1X2JsdXJfUzFfYzAgPSB1X2NvbXBvc2l0ZV8xX1MxX2MwLno7Cgl1X3JhZGl1c19zY2FsZV9TMV9jMCA9IHVfY29tcG9zaXRlXzFfUzFfYzAudzsKCWZsb2F0MiBwID0gRkxUX2ZsdXR0ZXJfbG9jYWxfRmx1dHRlckZyYWdDb29yZF9TMV9jMCgpOwoJZmxvYXQyIHV2XzEgPSBwICogdV9yZXNvbHV0aW9uX3NjYWxlX1MxX2MwOwoJZmxvYXQyIGRlbnNpdHlfdXYgPSB1dl8xIC0gbW9kKHAsIHVfbm9pc2Vfc2NhbGVfUzFfYzApOwoJZmxvYXQgcmFkaXVzID0gdV9tYXhfcmFkaXVzX1MxX2MwICogdV9yYWRpdXNfc2NhbGVfUzFfYzA7CglmbG9hdDIgcGFyYW1fMTMgPSB1dl8xOwoJZmxvYXQgdHVyYnVsZW5jZSA9IEZMVF9mbHV0dGVyX2xvY2FsX3R1cmJ1bGVuY2VfUzFfYzAocGFyYW1fMTMpOwoJZmxvYXQyIHBhcmFtXzE0ID0gcDsKCWZsb2F0MiBwYXJhbV8xNSA9IHVfY2VudGVyX1MxX2MwOwoJZmxvYXQgcGFyYW1fMTYgPSByYWRpdXM7CglmbG9hdCBwYXJhbV8xNyA9IDAuMDUgKiB1X21heF9yYWRpdXNfUzFfYzA7CglmbG9hdCBwYXJhbV8xOCA9IHVfYmx1cl9TMV9jMDsKCWZsb2F0IHJpbmcgPSBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X3JpbmdfUzFfYzAocGFyYW1fMTQsIHBhcmFtXzE1LCBwYXJhbV8xNiwgcGFyYW1fMTcsIHBhcmFtXzE4KTsKCWZsb2F0MiBwYXJhbV8xOSA9IGRlbnNpdHlfdXY7CglmbG9hdCBwYXJhbV8yMCA9IHVfbm9pc2VfcGhhc2VfUzFfYzA7CglmbG9hdCBzcGFya2xlID0gKChGTFRfZmx1dHRlcl9sb2NhbF9zcGFya2xlX1MxX2MwKHBhcmFtXzE5LCBwYXJhbV8yMCkgKiByaW5nKSAqIHR1cmJ1bGVuY2UpICogdV9zcGFya2xlX2FscGhhX1MxX2MwOwoJZmxvYXQyIHBhcmFtXzIxID0gcDsKCWZsb2F0MiBwYXJhbV8yMiA9IHVfY2VudGVyX1MxX2MwOwoJZmxvYXQgcGFyYW1fMjMgPSByYWRpdXM7CglmbG9hdCBwYXJhbV8yNCA9IHVfYmx1cl9TMV9jMDsKCWZsb2F0IHdhdmVfYWxwaGEgPSAoRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9jaXJjbGVfUzFfYzAocGFyYW1fMjEsIHBhcmFtXzIyLCBwYXJhbV8yMywgcGFyYW1fMjQpICogdV9hbHBoYV9TMV9jMCkgKiB1X2NvbG9yX1MxX2MwLnc7CglmbG9hdDQgd2F2ZV9jb2xvciA9IGZsb2F0NCh1X2NvbG9yX1MxX2MwLnh5eiAqIHdhdmVfYWxwaGEsIHdhdmVfYWxwaGEpOwoJZnJhZ0NvbG9yX1MxX2MwID0gbWl4KHdhdmVfY29sb3IsIGZsb2F0NCgxLjApLCBmbG9hdDQoc3BhcmtsZSkpOwp9CmhhbGY0IHJ1bnRpbWVfc2hhZGVyX1MxX2MwKGhhbGY0IF9pbnB1dCkgCnsKCWhhbGY0IF90bXBfMF9pbkNvbG9yID0gX2lucHV0OwoJZmxvYXQyIF90bXBfMV9jb29yZHMgPSB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKCWZsdXR0ZXJfRnJhZ0Nvb3JkX1MxX2MwID0gZmxvYXQ0KF90bXBfMV9jb29yZHMsIDAuMCwgMC4wKTsKCUZMVF9tYWluX1MxX2MwKCk7CglyZXR1cm4gaGFsZjQoaGFsZjQoZnJhZ0NvbG9yX1MxX2MwKSk7Cn0KaGFsZjQgTWF0cml4RWZmZWN0X1MxKGhhbGY0IF9pbnB1dCkgCnsKCXJldHVybiBydW50aW1lX3NoYWRlcl9TMV9jMChfaW5wdXQpOwp9CmhhbGY0IENpcmN1bGFyUlJlY3RfUzIoaGFsZjQgX2lucHV0KSAKewoJZmxvYXQyIGR4eTAgPSB1aW5uZXJSZWN0X1MyLkxUIC0gc2tfRnJhZ0Nvb3JkLnh5OwoJZmxvYXQyIGR4eTEgPSBza19GcmFnQ29vcmQueHkgLSB1aW5uZXJSZWN0X1MyLlJCOwoJZmxvYXQyIGR4eSA9IG1heChtYXgoZHh5MCwgZHh5MSksIDAuMCk7CgloYWxmIGFscGhhID0gaGFsZihzYXR1cmF0ZSh1cmFkaXVzUGx1c0hhbGZfUzIueCAtIGxlbmd0aChkeHkpKSk7CglyZXR1cm4gX2lucHV0ICogYWxwaGE7Cn0Kdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJaGFsZjQgb3V0cHV0Q29sb3JfUzA7CglvdXRwdXRDb2xvcl9TMCA9IHZjb2xvcl9TMDsKCWNvbnN0IGhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoMSk7CgloYWxmNCBvdXRwdXRfUzE7CglvdXRwdXRfUzEgPSBNYXRyaXhFZmZlY3RfUzEob3V0cHV0Q29sb3JfUzApOwoJaGFsZjQgb3V0cHV0X1MyOwoJb3V0cHV0X1MyID0gQ2lyY3VsYXJSUmVjdF9TMihvdXRwdXRDb3ZlcmFnZV9TMCk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0X1MxICogb3V0cHV0X1MyOwoJfQp9CgABAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAgAAABwb3NpdGlvbgUAAABjb2xvcgAAAAoAAABsb2NhbENvb3JkAAAAAAAA","HUJAAAAAAAQAADAAAIOAAAH677777777777QGHAQAD7P7777777777YBAAAAAAQAAAAAAQQGABZAA6IAAAAACAAAAAADUAAAAAAAEAAAAAIDEAAAAAAA":"DAAAAExTS1PlAAAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gZmxvYXQyIGxvY2FsQ29vcmQ7Cm91dCBmbG9hdDIgdmxvY2FsQ29vcmRfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJdmxvY2FsQ29vcmRfUzAgPSBsb2NhbENvb3JkOwoJc2tfUG9zaXRpb24gPSBwb3NpdGlvbi54eTAxOwp9CgAAAAEAAAAzAwAAdW5pZm9ybSBmbG9hdDQgdWlubmVyUmVjdF9TMTsKdW5pZm9ybSBoYWxmMiB1cmFkaXVzUGx1c0hhbGZfUzE7CnNhbXBsZXIyRCB1VGV4dHVyZVNhbXBsZXJfMF9TMDsKaW4gZmxvYXQyIHZsb2NhbENvb3JkX1MwOwpoYWxmNCBDaXJjdWxhclJSZWN0X1MxKGhhbGY0IF9pbnB1dCkgCnsKCWZsb2F0MiBkeHkwID0gdWlubmVyUmVjdF9TMS5MVCAtIHNrX0ZyYWdDb29yZC54eTsKCWZsb2F0MiBkeHkxID0gc2tfRnJhZ0Nvb3JkLnh5IC0gdWlubmVyUmVjdF9TMS5SQjsKCWZsb2F0MiBkeHkgPSBtYXgobWF4KGR4eTAsIGR4eTEpLCAwLjApOwoJaGFsZiBhbHBoYSA9IGhhbGYoc2F0dXJhdGUodXJhZGl1c1BsdXNIYWxmX1MxLnggLSBsZW5ndGgoZHh5KSkpOwoJcmV0dXJuIF9pbnB1dCAqIGFscGhhOwp9CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwID0gaGFsZjQoMSk7CglmbG9hdDIgdGV4Q29vcmQ7Cgl0ZXhDb29yZCA9IHZsb2NhbENvb3JkX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSAoYmxlbmRfbW9kdWxhdGUoc2FtcGxlKHVUZXh0dXJlU2FtcGxlcl8wX1MwLCB0ZXhDb29yZCksIGhhbGY0KDEpKSk7Cgljb25zdCBoYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KDEpOwoJaGFsZjQgb3V0cHV0X1MxOwoJb3V0cHV0X1MxID0gQ2lyY3VsYXJSUmVjdF9TMShvdXRwdXRDb3ZlcmFnZV9TMCk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRfUzE7Cgl9Cn0KAAEAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAACAAAACAAAAHBvc2l0aW9uCgAAAGxvY2FsQ29vcmQAAAAAAAA=","CMRQCIAABBYAAAEIXBAAACDQMAABRAFAAAAAAAAAAAAAAAEABYAAAAEAAAAAAAEEBQAAAAA":"DAAAAExTS1MyAgAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQ0IHVsb2NhbE1hdHJpeF9TMDsKaW4gZmxvYXQyIGluUG9zaXRpb247CmluIGhhbGY0IGluQ29sb3I7CmluIGZsb2F0MiBpbkVsbGlwc2VPZmZzZXQ7CmluIGZsb2F0NCBpbkVsbGlwc2VSYWRpaTsKb3V0IGZsb2F0MiB2RWxsaXBzZU9mZnNldHNfUzA7Cm91dCBmbG9hdDQgdkVsbGlwc2VSYWRpaV9TMDsKb3V0IGhhbGY0IHZpbkNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBFbGxpcHNlR2VvbWV0cnlQcm9jZXNzb3IKCXZFbGxpcHNlT2Zmc2V0c19TMCA9IGluRWxsaXBzZU9mZnNldDsKCXZFbGxpcHNlUmFkaWlfUzAgPSBpbkVsbGlwc2VSYWRpaTsKCXZpbkNvbG9yX1MwID0gaW5Db2xvcjsKCWZsb2F0MiBfdG1wXzBfaW5Qb3NpdGlvbiA9IGluUG9zaXRpb247CglmbG9hdDIgX3RtcF8xX2luUG9zaXRpb24gPSB1bG9jYWxNYXRyaXhfUzAueHogKiBpblBvc2l0aW9uICsgdWxvY2FsTWF0cml4X1MwLnl3OwoJc2tfUG9zaXRpb24gPSBfdG1wXzBfaW5Qb3NpdGlvbi54eTAxOwp9CgAAAAAAAHIDAABpbiBmbG9hdDIgdkVsbGlwc2VPZmZzZXRzX1MwOwppbiBmbG9hdDQgdkVsbGlwc2VSYWRpaV9TMDsKaW4gaGFsZjQgdmluQ29sb3JfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBFbGxpcHNlR2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2aW5Db2xvcl9TMDsKCWZsb2F0MiBvZmZzZXQgPSB2RWxsaXBzZU9mZnNldHNfUzAueHk7CglvZmZzZXQgKj0gdkVsbGlwc2VSYWRpaV9TMC54eTsKCWZsb2F0IHRlc3QgPSBkb3Qob2Zmc2V0LCBvZmZzZXQpIC0gMS4wOwoJZmxvYXQyIGdyYWQgPSAyLjAqb2Zmc2V0KnZFbGxpcHNlUmFkaWlfUzAueHk7CglmbG9hdCBncmFkX2RvdCA9IGRvdChncmFkLCBncmFkKTsKCWdyYWRfZG90ID0gbWF4KGdyYWRfZG90LCAxLjE3NTVlLTM4KTsKCWZsb2F0IGludmxlbiA9IGludmVyc2VzcXJ0KGdyYWRfZG90KTsKCWZsb2F0IGVkZ2VBbHBoYSA9IHNhdHVyYXRlKDAuNS10ZXN0Kmludmxlbik7CglvZmZzZXQgPSB2RWxsaXBzZU9mZnNldHNfUzAueHkqdkVsbGlwc2VSYWRpaV9TMC56dzsKCXRlc3QgPSBkb3Qob2Zmc2V0LCBvZmZzZXQpIC0gMS4wOwoJZ3JhZCA9IDIuMCpvZmZzZXQqdkVsbGlwc2VSYWRpaV9TMC56dzsKCWdyYWRfZG90ID0gZG90KGdyYWQsIGdyYWQpOwoJaW52bGVuID0gaW52ZXJzZXNxcnQoZ3JhZF9kb3QpOwoJZWRnZUFscGhhICo9IHNhdHVyYXRlKDAuNSt0ZXN0Kmludmxlbik7CgloYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KGhhbGYoZWRnZUFscGhhKSk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRDb3ZlcmFnZV9TMDsKCX0KfQoAAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAEAAAACgAAAGluUG9zaXRpb24AAAcAAABpbkNvbG9yAA8AAABpbkVsbGlwc2VPZmZzZXQADgAAAGluRWxsaXBzZVJhZGlpAAAAAAAA","B2AAQAAABQAAIAABBYAAB7777777777774ABICAAAAAAAAAAAAAABUABAAAAAEAAAAAIBEABAAAAA":"DAAAAExTS1MOAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0MiBpblBvc2l0aW9uOwppbiBoYWxmIGluQ292ZXJhZ2U7Cm91dCBoYWxmIHZpbkNvdmVyYWdlX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBEZWZhdWx0R2VvbWV0cnlQcm9jZXNzb3IKCWZsb2F0MiBfdG1wXzFfaW5Qb3NpdGlvbiA9IGluUG9zaXRpb247Cgl2aW5Db3ZlcmFnZV9TMCA9IGluQ292ZXJhZ2U7Cglza19Qb3NpdGlvbiA9IF90bXBfMV9pblBvc2l0aW9uLnh5MDE7Cn0KAAAAAAAATQEAAHVuaWZvcm0gaGFsZjQgdUNvbG9yX1MwOwppbiBoYWxmIHZpbkNvdmVyYWdlX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgRGVmYXVsdEdlb21ldHJ5UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdUNvbG9yX1MwOwoJaGFsZiBhbHBoYSA9IDEuMDsKCWFscGhhID0gdmluQ292ZXJhZ2VfUzA7CgloYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KGFscGhhKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dENvdmVyYWdlX1MwOwoJfQp9CgAAAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAACAAAACgAAAGluUG9zaXRpb24AAAoAAABpbkNvdmVyYWdlAAAAAAAA","HVIACAAAABQAAGAAAQ4AAAAAGQQAARC4GAAAIOCAAD6P7777777777YDAAAAAAAAAAAHIBNGZODK5YIAAAAAAQAAAAAIADCNS4GV3QYBAAAAAAAAAAAAAHIAAAAAAAIAAAAAQGIAAAAAA":"DAAAAExTS1PZAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMTsKaW4gZmxvYXQyIHBvc2l0aW9uOwppbiBmbG9hdCBjb3ZlcmFnZTsKaW4gaGFsZjQgY29sb3I7CmluIGZsb2F0MiBsb2NhbENvb3JkOwpmbGF0IG91dCBoYWxmNCB2Y29sb3JfUzA7Cm91dCBmbG9hdCB2Y292ZXJhZ2VfUzA7Cm91dCBmbG9hdDIgdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJZmxvYXQyIHBvc2l0aW9uID0gcG9zaXRpb24ueHk7Cgl2Y29sb3JfUzAgPSBjb2xvcjsKCXZjb3ZlcmFnZV9TMCA9IGNvdmVyYWdlOwoJc2tfUG9zaXRpb24gPSBwb3NpdGlvbi54eTAxOwoJewoJCXZUcmFuc2Zvcm1lZENvb3Jkc18yX1MwID0gZmxvYXQzeDIodW1hdHJpeF9TMSkgKiBsb2NhbENvb3JkLnh5MTsKCX0KfQoAAAAAAAAAyhsAAGZsb2F0NCBmbHV0dGVyX0ZyYWdDb29yZF9TMV9jMDsKZmxvYXQ0IGZyYWdDb2xvcl9TMV9jMDsKZmxvYXQgdV9hbHBoYV9TMV9jMDsKZmxvYXQgdV9zcGFya2xlX2FscGhhX1MxX2MwOwpmbG9hdCB1X2JsdXJfUzFfYzA7CmZsb2F0IHVfcmFkaXVzX3NjYWxlX1MxX2MwOwp1bmlmb3JtIGZsb2F0NCB1X2NvbG9yX1MxX2MwOwp1bmlmb3JtIGZsb2F0NCB1X2NvbXBvc2l0ZV8xX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X2NlbnRlcl9TMV9jMDsKdW5pZm9ybSBmbG9hdCB1X21heF9yYWRpdXNfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfcmVzb2x1dGlvbl9zY2FsZV9TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9ub2lzZV9zY2FsZV9TMV9jMDsKdW5pZm9ybSBmbG9hdCB1X25vaXNlX3BoYXNlX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X2NpcmNsZTFfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfY2lyY2xlMl9TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9jaXJjbGUzX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X3JvdGF0aW9uMV9TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9yb3RhdGlvbjJfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfcm90YXRpb24zX1MxX2MwOwp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzE7CmZsYXQgaW4gaGFsZjQgdmNvbG9yX1MwOwppbiBmbG9hdCB2Y292ZXJhZ2VfUzA7CmluIGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKZmxvYXQyIEZMVF9mbHV0dGVyX2xvY2FsX0ZsdXR0ZXJGcmFnQ29vcmRfUzFfYzAoKTsKZmxvYXQyeDIgRkxUX2ZsdXR0ZXJfbG9jYWxfcm90YXRlMmRfUzFfYzAoZmxvYXQyIHJhZCk7CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfY2lyY2xlX1MxX2MwKGZsb2F0MiB1diwgZmxvYXQyIHh5LCBmbG9hdCByYWRpdXMsIGZsb2F0IGJsdXIpOwpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9jaXJjbGVfZ3JpZF9TMV9jMChmbG9hdDIgcmVzb2x1dGlvbiwgaW5vdXQgZmxvYXQyIHAsIGZsb2F0MiB4eSwgZmxvYXQyIHJvdGF0aW9uLCBmbG9hdCBjZWxsX2RpYW1ldGVyKTsKZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfdHVyYnVsZW5jZV9TMV9jMChmbG9hdDIgdXYpOwpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X3JpbmdfUzFfYzAoZmxvYXQyIHV2LCBmbG9hdDIgeHksIGZsb2F0IHJhZGl1cywgZmxvYXQgdGhpY2tuZXNzLCBmbG9hdCBibHVyKTsKZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfdHJpYW5nbGVfbm9pc2VfUzFfYzAoaW5vdXQgZmxvYXQyIG4pOwpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF90aHJlc2hvbGRfUzFfYzAoZmxvYXQgdiwgZmxvYXQgbCwgZmxvYXQgaCk7CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3NwYXJrbGVfUzFfYzAoZmxvYXQyIHV2LCBmbG9hdCB0KTsKdm9pZCBGTFRfbWFpbl9TMV9jMCgpOwpmbG9hdDIgRkxUX2ZsdXR0ZXJfbG9jYWxfRmx1dHRlckZyYWdDb29yZF9TMV9jMCgpIAp7CglyZXR1cm4gZmx1dHRlcl9GcmFnQ29vcmRfUzFfYzAueHk7Cn0KZmxvYXQyeDIgRkxUX2ZsdXR0ZXJfbG9jYWxfcm90YXRlMmRfUzFfYzAoZmxvYXQyIHJhZCkgCnsKCXJldHVybiBmbG9hdDJ4MihyYWQueCwgLXJhZC55LCByYWQueSwgcmFkLngpOwp9CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfY2lyY2xlX1MxX2MwKGZsb2F0MiB1diwgZmxvYXQyIHh5LCBmbG9hdCByYWRpdXMsIGZsb2F0IGJsdXIpIAp7CglmbG9hdCBibHVyX2hhbGYgPSBibHVyICogMC41OwoJZmxvYXQgZCA9IGRpc3RhbmNlKHV2LCB4eSk7CglyZXR1cm4gMS4wIC0gc21vb3Roc3RlcCgxLjAgLSBibHVyX2hhbGYsIDEuMCArIGJsdXJfaGFsZiwgZCAvIHJhZGl1cyk7Cn0KZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfY2lyY2xlX2dyaWRfUzFfYzAoZmxvYXQyIHJlc29sdXRpb24sIGlub3V0IGZsb2F0MiBwLCBmbG9hdDIgeHksIGZsb2F0MiByb3RhdGlvbiwgZmxvYXQgY2VsbF9kaWFtZXRlcikgCnsKCWZsb2F0MiBwYXJhbSA9IHJvdGF0aW9uOwoJcCA9IEZMVF9mbHV0dGVyX2xvY2FsX3JvdGF0ZTJkX1MxX2MwKHBhcmFtKSAqICh4eSAtIHApICsgeHk7CglwID0gbW9kKHAsIGZsb2F0MihjZWxsX2RpYW1ldGVyKSkgLyByZXNvbHV0aW9uOwoJZmxvYXQgY2VsbF91diA9IChjZWxsX2RpYW1ldGVyIC8gcmVzb2x1dGlvbi55KSAqIDAuNTsKCWZsb2F0IHIgPSAwLjY1ICogY2VsbF91djsKCWZsb2F0MiBwYXJhbV8xID0gcDsKCWZsb2F0MiBwYXJhbV8yID0gZmxvYXQyKGNlbGxfdXYpOwoJZmxvYXQgcGFyYW1fMyA9IHI7CglmbG9hdCBwYXJhbV80ID0gciAqIDUwLjA7CglyZXR1cm4gRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9jaXJjbGVfUzFfYzAocGFyYW1fMSwgcGFyYW1fMiwgcGFyYW1fMywgcGFyYW1fNCk7Cn0KZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfdHVyYnVsZW5jZV9TMV9jMChmbG9hdDIgdXYpIAp7CglmbG9hdDIgdXZfc2NhbGUgPSB1diAqIGZsb2F0MigwLjgpOwoJZmxvYXQyIHBhcmFtID0gZmxvYXQyKDAuOCk7CglmbG9hdDIgcGFyYW1fMSA9IHV2X3NjYWxlOwoJZmxvYXQyIHBhcmFtXzIgPSB1X2NpcmNsZTFfUzFfYzA7CglmbG9hdDIgcGFyYW1fMyA9IHVfcm90YXRpb24xX1MxX2MwOwoJZmxvYXQgcGFyYW1fNCA9IDAuMTc7CglmbG9hdCBfMzE5ID0gRkxUX2ZsdXR0ZXJfbG9jYWxfY2lyY2xlX2dyaWRfUzFfYzAocGFyYW0sIHBhcmFtXzEsIHBhcmFtXzIsIHBhcmFtXzMsIHBhcmFtXzQpOwoJZmxvYXQgZzEgPSBfMzE5OwoJZmxvYXQyIHBhcmFtXzUgPSBmbG9hdDIoMC44KTsKCWZsb2F0MiBwYXJhbV82ID0gdXZfc2NhbGU7CglmbG9hdDIgcGFyYW1fNyA9IHVfY2lyY2xlMl9TMV9jMDsKCWZsb2F0MiBwYXJhbV84ID0gdV9yb3RhdGlvbjJfUzFfYzA7CglmbG9hdCBwYXJhbV85ID0gMC4yOwoJZmxvYXQgXzMzMSA9IEZMVF9mbHV0dGVyX2xvY2FsX2NpcmNsZV9ncmlkX1MxX2MwKHBhcmFtXzUsIHBhcmFtXzYsIHBhcmFtXzcsIHBhcmFtXzgsIHBhcmFtXzkpOwoJZmxvYXQgZzIgPSBfMzMxOwoJZmxvYXQyIHBhcmFtXzEwID0gZmxvYXQyKDAuOCk7CglmbG9hdDIgcGFyYW1fMTEgPSB1dl9zY2FsZTsKCWZsb2F0MiBwYXJhbV8xMiA9IHVfY2lyY2xlM19TMV9jMDsKCWZsb2F0MiBwYXJhbV8xMyA9IHVfcm90YXRpb24zX1MxX2MwOwoJZmxvYXQgcGFyYW1fMTQgPSAwLjI3NTsKCWZsb2F0IF8zNDQgPSBGTFRfZmx1dHRlcl9sb2NhbF9jaXJjbGVfZ3JpZF9TMV9jMChwYXJhbV8xMCwgcGFyYW1fMTEsIHBhcmFtXzEyLCBwYXJhbV8xMywgcGFyYW1fMTQpOwoJZmxvYXQgZzMgPSBfMzQ0OwoJZmxvYXQgdiA9ICgoZzEgKiBnMSArIGcyKSAtIGczKSAqIDAuNTsKCXJldHVybiBjbGFtcCgwLjQ1ICsgMC44ICogdiwgMC4wLCAxLjApOwp9CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfcmluZ19TMV9jMChmbG9hdDIgdXYsIGZsb2F0MiB4eSwgZmxvYXQgcmFkaXVzLCBmbG9hdCB0aGlja25lc3MsIGZsb2F0IGJsdXIpIAp7CglmbG9hdDIgcGFyYW0gPSB1djsKCWZsb2F0MiBwYXJhbV8xID0geHk7CglmbG9hdCBwYXJhbV8yID0gcmFkaXVzICsgdGhpY2tuZXNzOwoJZmxvYXQgcGFyYW1fMyA9IGJsdXI7CglmbG9hdCBjaXJjbGVfb3V0ZXIgPSBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X2NpcmNsZV9TMV9jMChwYXJhbSwgcGFyYW1fMSwgcGFyYW1fMiwgcGFyYW1fMyk7CglmbG9hdDIgcGFyYW1fNCA9IHV2OwoJZmxvYXQyIHBhcmFtXzUgPSB4eTsKCWZsb2F0IHBhcmFtXzYgPSBtYXgocmFkaXVzIC0gdGhpY2tuZXNzLCAwLjApOwoJZmxvYXQgcGFyYW1fNyA9IGJsdXI7CglmbG9hdCBjaXJjbGVfaW5uZXIgPSBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X2NpcmNsZV9TMV9jMChwYXJhbV80LCBwYXJhbV81LCBwYXJhbV82LCBwYXJhbV83KTsKCXJldHVybiBjbGFtcChjaXJjbGVfb3V0ZXIgLSBjaXJjbGVfaW5uZXIsIDAuMCwgMS4wKTsKfQpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF90cmlhbmdsZV9ub2lzZV9TMV9jMChpbm91dCBmbG9hdDIgbikgCnsKCW4gPSBmcmFjdChuICogZmxvYXQyKDUuMzk4NywgNS40NDIxKSk7CgluICs9IGZsb2F0Mihkb3Qobi55eCwgbiArIGZsb2F0MigyMS41MzUxLCAxNC4zMTM3KSkpOwoJZmxvYXQgeHkgPSBuLnggKiBuLnk7CglyZXR1cm4gKGZyYWN0KHh5ICogOTUuNDMwNykgKyBmcmFjdCh4eSAqIDc1LjA0OTYxKSkgLSAxLjA7Cn0KZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfdGhyZXNob2xkX1MxX2MwKGZsb2F0IHYsIGZsb2F0IGwsIGZsb2F0IGgpIAp7CglyZXR1cm4gc3RlcChsLCB2KSAqICgxLjAgLSBzdGVwKGgsIHYpKTsKfQpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9zcGFya2xlX1MxX2MwKGZsb2F0MiB1diwgZmxvYXQgdCkgCnsKCWZsb2F0MiBwYXJhbSA9IHV2OwoJZmxvYXQgXzI0MiA9IEZMVF9mbHV0dGVyX2xvY2FsX3RyaWFuZ2xlX25vaXNlX1MxX2MwKHBhcmFtKTsKCWZsb2F0IG4gPSBfMjQyOwoJZmxvYXQgcGFyYW1fMSA9IG47CglmbG9hdCBwYXJhbV8yID0gMC4wOwoJZmxvYXQgcGFyYW1fMyA9IDAuMDU7CglmbG9hdCBzID0gRkxUX2ZsdXR0ZXJfbG9jYWxfdGhyZXNob2xkX1MxX2MwKHBhcmFtXzEsIHBhcmFtXzIsIHBhcmFtXzMpOwoJZmxvYXQgcGFyYW1fNCA9IG4gKyBzaW4oMy4xNDE1OTI3NCAqICh0ICsgMC4zNSkpOwoJZmxvYXQgcGFyYW1fNSA9IDAuMTsKCWZsb2F0IHBhcmFtXzYgPSAwLjE1OwoJcyArPSBGTFRfZmx1dHRlcl9sb2NhbF90aHJlc2hvbGRfUzFfYzAocGFyYW1fNCwgcGFyYW1fNSwgcGFyYW1fNik7CglmbG9hdCBwYXJhbV83ID0gbiArIHNpbigzLjE0MTU5Mjc0ICogKHQgKyAwLjcpKTsKCWZsb2F0IHBhcmFtXzggPSAwLjI7CglmbG9hdCBwYXJhbV85ID0gMC4yNTsKCXMgKz0gRkxUX2ZsdXR0ZXJfbG9jYWxfdGhyZXNob2xkX1MxX2MwKHBhcmFtXzcsIHBhcmFtXzgsIHBhcmFtXzkpOwoJZmxvYXQgcGFyYW1fMTAgPSBuICsgc2luKDMuMTQxNTkyNzQgKiAodCArIDEuMDUpKTsKCWZsb2F0IHBhcmFtXzExID0gMC4zOwoJZmxvYXQgcGFyYW1fMTIgPSAwLjM1OwoJcyArPSBGTFRfZmx1dHRlcl9sb2NhbF90aHJlc2hvbGRfUzFfYzAocGFyYW1fMTAsIHBhcmFtXzExLCBwYXJhbV8xMik7CglyZXR1cm4gY2xhbXAocywgMC4wLCAxLjApICogMC41NTsKfQp2b2lkIEZMVF9tYWluX1MxX2MwKCkgCnsKCXVfYWxwaGFfUzFfYzAgPSB1X2NvbXBvc2l0ZV8xX1MxX2MwLng7Cgl1X3NwYXJrbGVfYWxwaGFfUzFfYzAgPSB1X2NvbXBvc2l0ZV8xX1MxX2MwLnk7Cgl1X2JsdXJfUzFfYzAgPSB1X2NvbXBvc2l0ZV8xX1MxX2MwLno7Cgl1X3JhZGl1c19zY2FsZV9TMV9jMCA9IHVfY29tcG9zaXRlXzFfUzFfYzAudzsKCWZsb2F0MiBwID0gRkxUX2ZsdXR0ZXJfbG9jYWxfRmx1dHRlckZyYWdDb29yZF9TMV9jMCgpOwoJZmxvYXQyIHV2XzEgPSBwICogdV9yZXNvbHV0aW9uX3NjYWxlX1MxX2MwOwoJZmxvYXQyIGRlbnNpdHlfdXYgPSB1dl8xIC0gbW9kKHAsIHVfbm9pc2Vfc2NhbGVfUzFfYzApOwoJZmxvYXQgcmFkaXVzID0gdV9tYXhfcmFkaXVzX1MxX2MwICogdV9yYWRpdXNfc2NhbGVfUzFfYzA7CglmbG9hdDIgcGFyYW1fMTMgPSB1dl8xOwoJZmxvYXQgdHVyYnVsZW5jZSA9IEZMVF9mbHV0dGVyX2xvY2FsX3R1cmJ1bGVuY2VfUzFfYzAocGFyYW1fMTMpOwoJZmxvYXQyIHBhcmFtXzE0ID0gcDsKCWZsb2F0MiBwYXJhbV8xNSA9IHVfY2VudGVyX1MxX2MwOwoJZmxvYXQgcGFyYW1fMTYgPSByYWRpdXM7CglmbG9hdCBwYXJhbV8xNyA9IDAuMDUgKiB1X21heF9yYWRpdXNfUzFfYzA7CglmbG9hdCBwYXJhbV8xOCA9IHVfYmx1cl9TMV9jMDsKCWZsb2F0IHJpbmcgPSBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X3JpbmdfUzFfYzAocGFyYW1fMTQsIHBhcmFtXzE1LCBwYXJhbV8xNiwgcGFyYW1fMTcsIHBhcmFtXzE4KTsKCWZsb2F0MiBwYXJhbV8xOSA9IGRlbnNpdHlfdXY7CglmbG9hdCBwYXJhbV8yMCA9IHVfbm9pc2VfcGhhc2VfUzFfYzA7CglmbG9hdCBzcGFya2xlID0gKChGTFRfZmx1dHRlcl9sb2NhbF9zcGFya2xlX1MxX2MwKHBhcmFtXzE5LCBwYXJhbV8yMCkgKiByaW5nKSAqIHR1cmJ1bGVuY2UpICogdV9zcGFya2xlX2FscGhhX1MxX2MwOwoJZmxvYXQyIHBhcmFtXzIxID0gcDsKCWZsb2F0MiBwYXJhbV8yMiA9IHVfY2VudGVyX1MxX2MwOwoJZmxvYXQgcGFyYW1fMjMgPSByYWRpdXM7CglmbG9hdCBwYXJhbV8yNCA9IHVfYmx1cl9TMV9jMDsKCWZsb2F0IHdhdmVfYWxwaGEgPSAoRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9jaXJjbGVfUzFfYzAocGFyYW1fMjEsIHBhcmFtXzIyLCBwYXJhbV8yMywgcGFyYW1fMjQpICogdV9hbHBoYV9TMV9jMCkgKiB1X2NvbG9yX1MxX2MwLnc7CglmbG9hdDQgd2F2ZV9jb2xvciA9IGZsb2F0NCh1X2NvbG9yX1MxX2MwLnh5eiAqIHdhdmVfYWxwaGEsIHdhdmVfYWxwaGEpOwoJZnJhZ0NvbG9yX1MxX2MwID0gbWl4KHdhdmVfY29sb3IsIGZsb2F0NCgxLjApLCBmbG9hdDQoc3BhcmtsZSkpOwp9CmhhbGY0IHJ1bnRpbWVfc2hhZGVyX1MxX2MwKGhhbGY0IF9pbnB1dCkgCnsKCWhhbGY0IF90bXBfMF9pbkNvbG9yID0gX2lucHV0OwoJZmxvYXQyIF90bXBfMV9jb29yZHMgPSB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKCWZsdXR0ZXJfRnJhZ0Nvb3JkX1MxX2MwID0gZmxvYXQ0KF90bXBfMV9jb29yZHMsIDAuMCwgMC4wKTsKCUZMVF9tYWluX1MxX2MwKCk7CglyZXR1cm4gaGFsZjQoaGFsZjQoZnJhZ0NvbG9yX1MxX2MwKSk7Cn0KaGFsZjQgTWF0cml4RWZmZWN0X1MxKGhhbGY0IF9pbnB1dCkgCnsKCXJldHVybiBydW50aW1lX3NoYWRlcl9TMV9jMChfaW5wdXQpOwp9CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2Y29sb3JfUzA7CglmbG9hdCBjb3ZlcmFnZSA9IHZjb3ZlcmFnZV9TMDsKCWhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoaGFsZihjb3ZlcmFnZSkpOwoJaGFsZjQgb3V0cHV0X1MxOwoJb3V0cHV0X1MxID0gTWF0cml4RWZmZWN0X1MxKG91dHB1dENvbG9yX1MwKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRfUzEgKiBvdXRwdXRDb3ZlcmFnZV9TMDsKCX0KfQoAAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAEAAAACAAAAHBvc2l0aW9uCAAAAGNvdmVyYWdlBQAAAGNvbG9yAAAACgAAAGxvY2FsQ29vcmQAAAAAAAA=","DAQAAAAAAAAAAAAAAJQAAIGAAEACBYQCAGAEFAIBAAAAAABAAAAAAAAAAAACAA6QAAAABUDB7AHU6AIAAAYAAAAAQAAAAAEARR2BR7WDKMAAAAAMAAAAAAAAAAAABIADAAAAAIAAAAAAAIIDAAAA":"DAAAAExTS1MWAgAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQyIHVBdGxhc1NpemVJbnZfUzA7CmluIGZsb2F0MiBpblBvc2l0aW9uOwppbiBoYWxmNCBpbkNvbG9yOwppbiB1c2hvcnQyIGluVGV4dHVyZUNvb3JkczsKb3V0IGZsb2F0MiB2VGV4dHVyZUNvb3Jkc19TMDsKZmxhdCBvdXQgZmxvYXQgdlRleEluZGV4X1MwOwpvdXQgaGFsZjQgdmluQ29sb3JfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIEJpdG1hcFRleHQKCWludCB0ZXhJZHggPSAwOwoJZmxvYXQyIHVub3JtVGV4Q29vcmRzID0gZmxvYXQyKGluVGV4dHVyZUNvb3Jkcy54LCBpblRleHR1cmVDb29yZHMueSk7Cgl2VGV4dHVyZUNvb3Jkc19TMCA9IHVub3JtVGV4Q29vcmRzICogdUF0bGFzU2l6ZUludl9TMDsKCXZUZXhJbmRleF9TMCA9IGZsb2F0KHRleElkeCk7Cgl2aW5Db2xvcl9TMCA9IGluQ29sb3I7CglmbG9hdDIgX3RtcF8xX2luUG9zaXRpb24gPSBpblBvc2l0aW9uOwoJc2tfUG9zaXRpb24gPSBpblBvc2l0aW9uLnh5MDE7Cn0KAAABAAAAPQUAAGNvbnN0IGludCBrRmlsbEJXX1MxX2MwID0gMDsKY29uc3QgaW50IGtJbnZlcnNlRmlsbEJXX1MxX2MwID0gMjsKY29uc3QgaW50IGtJbnZlcnNlRmlsbEFBX1MxX2MwID0gMzsKdW5pZm9ybSBmbG9hdDQgdXJlY3RVbmlmb3JtX1MxX2MwOwpzYW1wbGVyMkQgdVRleHR1cmVTYW1wbGVyXzBfUzA7CmluIGZsb2F0MiB2VGV4dHVyZUNvb3Jkc19TMDsKZmxhdCBpbiBmbG9hdCB2VGV4SW5kZXhfUzA7CmluIGhhbGY0IHZpbkNvbG9yX1MwOwpoYWxmNCBSZWN0X1MxX2MwKGhhbGY0IF9pbnB1dCkgCnsKCWhhbGY0IF90bXBfMF9pbkNvbG9yID0gX2lucHV0OwoJaGFsZiBjb3ZlcmFnZTsKCWlmIChpbnQoMSkgPT0ga0ZpbGxCV19TMV9jMCB8fCBpbnQoMSkgPT0ga0ludmVyc2VGaWxsQldfUzFfYzApIAoJewoJCWNvdmVyYWdlID0gaGFsZihhbGwoZ3JlYXRlclRoYW4oZmxvYXQ0KHNrX0ZyYWdDb29yZC54eSwgdXJlY3RVbmlmb3JtX1MxX2MwLnp3KSwgZmxvYXQ0KHVyZWN0VW5pZm9ybV9TMV9jMC54eSwgc2tfRnJhZ0Nvb3JkLnh5KSkpKTsKCX0KCWVsc2UgCgl7CgkJaGFsZjQgZGlzdHM0ID0gc2F0dXJhdGUoaGFsZjQoMS4wLCAxLjAsIC0xLjAsIC0xLjApICogaGFsZjQoc2tfRnJhZ0Nvb3JkLnh5eHkgLSB1cmVjdFVuaWZvcm1fUzFfYzApKTsKCQloYWxmMiBkaXN0czIgPSAoZGlzdHM0Lnh5ICsgZGlzdHM0Lnp3KSAtIDEuMDsKCQljb3ZlcmFnZSA9IGRpc3RzMi54ICogZGlzdHMyLnk7Cgl9CglpZiAoaW50KDEpID09IGtJbnZlcnNlRmlsbEJXX1MxX2MwIHx8IGludCgxKSA9PSBrSW52ZXJzZUZpbGxBQV9TMV9jMCkgCgl7CgkJY292ZXJhZ2UgPSAxLjAgLSBjb3ZlcmFnZTsKCX0KCXJldHVybiBoYWxmNChoYWxmNChjb3ZlcmFnZSkpOwp9CmhhbGY0IEJsZW5kX1MxKGhhbGY0IF9zcmMsIGhhbGY0IF9kc3QpIAp7CglyZXR1cm4gYmxlbmRfbW9kdWxhdGUoUmVjdF9TMV9jMChfc3JjKSwgX3NyYyk7Cn0Kdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIEJpdG1hcFRleHQKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2aW5Db2xvcl9TMDsKCWhhbGY0IHRleENvbG9yOwoJewoJCXRleENvbG9yID0gc2FtcGxlKHVUZXh0dXJlU2FtcGxlcl8wX1MwLCB2VGV4dHVyZUNvb3Jkc19TMCkucnJycjsKCX0KCWhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gdGV4Q29sb3I7CgloYWxmNCBvdXRwdXRfUzE7CglvdXRwdXRfUzEgPSBCbGVuZF9TMShvdXRwdXRDb3ZlcmFnZV9TMCwgaGFsZjQoMSkpOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dENvbG9yX1MwICogb3V0cHV0X1MxOwoJfQp9CgAAAAEAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAADAAAACgAAAGluUG9zaXRpb24AAAcAAABpbkNvbG9yAA8AAABpblRleHR1cmVDb29yZHMAAAAAAA==","FAAQMYAAMAAAEADAAABAEYAAAICIAB5AABQAAAQAMAAAEATAAABAIIGAAEDCBYQCA4AAAAAAAA5AAAAAAABAAAAACAZAAAAA":"DAAAAExTS1PUCwAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0NCByYWRpaV9zZWxlY3RvcjsKaW4gZmxvYXQ0IGNvcm5lcl9hbmRfcmFkaXVzX291dHNldHM7CmluIGZsb2F0NCBhYV9ibG9hdF9hbmRfY292ZXJhZ2U7CmluIGZsb2F0NCByYWRpaV94OwppbiBmbG9hdDQgcmFkaWlfeTsKaW4gZmxvYXQ0IHNrZXc7CmluIGZsb2F0MiB0cmFuc2xhdGVfYW5kX2xvY2Fscm90YXRlOwppbiBoYWxmNCBjb2xvcjsKZmxhdCBvdXQgaGFsZjQgdmNvbG9yX1MwOwpvdXQgZmxvYXQyIHZhcmNjb29yZF9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgRmlsbFJSZWN0T3A6OlByb2Nlc3NvcgoJdmNvbG9yX1MwID0gY29sb3I7CglmbG9hdCBhYV9ibG9hdF9tdWx0aXBsaWVyID0gMTsKCWZsb2F0MiBjb3JuZXIgPSBjb3JuZXJfYW5kX3JhZGl1c19vdXRzZXRzLnh5OwoJZmxvYXQyIHJhZGl1c19vdXRzZXQgPSBjb3JuZXJfYW5kX3JhZGl1c19vdXRzZXRzLnp3OwoJZmxvYXQyIGFhX2Jsb2F0X2RpcmVjdGlvbiA9IGFhX2Jsb2F0X2FuZF9jb3ZlcmFnZS54eTsKCWZsb2F0IGlzX2xpbmVhcl9jb3ZlcmFnZSA9IGFhX2Jsb2F0X2FuZF9jb3ZlcmFnZS53OwoJZmxvYXQyIHBpeGVsbGVuZ3RoID0gaW52ZXJzZXNxcnQoZmxvYXQyKGRvdChza2V3Lnh6LCBza2V3Lnh6KSwgZG90KHNrZXcueXcsIHNrZXcueXcpKSk7CglmbG9hdDQgbm9ybWFsaXplZF9heGlzX2RpcnMgPSBza2V3ICogcGl4ZWxsZW5ndGgueHl4eTsKCWZsb2F0MiBheGlzd2lkdGhzID0gKGFicyhub3JtYWxpemVkX2F4aXNfZGlycy54eSkgKyBhYnMobm9ybWFsaXplZF9heGlzX2RpcnMuencpKTsKCWZsb2F0MiBhYV9ibG9hdHJhZGl1cyA9IGF4aXN3aWR0aHMgKiBwaXhlbGxlbmd0aCAqIC41OwoJZmxvYXQ0IHJhZGlpX2FuZF9uZWlnaGJvcnMgPSByYWRpaV9zZWxlY3RvciogZmxvYXQ0eDQocmFkaWlfeCwgcmFkaWlfeSwgcmFkaWlfeC55eHd6LCByYWRpaV95Lnd6eXgpOwoJZmxvYXQyIHJhZGlpID0gcmFkaWlfYW5kX25laWdoYm9ycy54eTsKCWZsb2F0MiBuZWlnaGJvcl9yYWRpaSA9IHJhZGlpX2FuZF9uZWlnaGJvcnMuenc7CglmbG9hdCBjb3ZlcmFnZV9tdWx0aXBsaWVyID0gMTsKCWlmIChhbnkoZ3JlYXRlclRoYW4oYWFfYmxvYXRyYWRpdXMsIGZsb2F0MigxKSkpKSAKCXsKCQljb3JuZXIgPSBtYXgoYWJzKGNvcm5lciksIGFhX2Jsb2F0cmFkaXVzKSAqIHNpZ24oY29ybmVyKTsKCQljb3ZlcmFnZV9tdWx0aXBsaWVyID0gMSAvIChtYXgoYWFfYmxvYXRyYWRpdXMueCwgMSkgKiBtYXgoYWFfYmxvYXRyYWRpdXMueSwgMSkpOwoJCXJhZGlpID0gZmxvYXQyKDApOwoJfQoJZmxvYXQgY292ZXJhZ2UgPSBhYV9ibG9hdF9hbmRfY292ZXJhZ2UuejsKCWlmIChhbnkobGVzc1RoYW4ocmFkaWksIGFhX2Jsb2F0cmFkaXVzICogMS41KSkpIAoJewoJCXJhZGlpID0gZmxvYXQyKDApOwoJCWFhX2Jsb2F0X2RpcmVjdGlvbiA9IHNpZ24oY29ybmVyKTsKCQlpZiAoY292ZXJhZ2UgPiAuNSkgCgkJewoJCQlhYV9ibG9hdF9kaXJlY3Rpb24gPSAtYWFfYmxvYXRfZGlyZWN0aW9uOwoJCX0KCQlpc19saW5lYXJfY292ZXJhZ2UgPSAxOwoJfQoJZWxzZSAKCXsKCQlyYWRpaSA9IGNsYW1wKHJhZGlpLCBwaXhlbGxlbmd0aCAqIDEuNSwgMiAtIHBpeGVsbGVuZ3RoICogMS41KTsKCQluZWlnaGJvcl9yYWRpaSA9IGNsYW1wKG5laWdoYm9yX3JhZGlpLCBwaXhlbGxlbmd0aCAqIDEuNSwgMiAtIHBpeGVsbGVuZ3RoICogMS41KTsKCQlmbG9hdDIgc3BhY2luZyA9IDIgLSByYWRpaSAtIG5laWdoYm9yX3JhZGlpOwoJCWZsb2F0MiBleHRyYV9wYWQgPSBtYXgocGl4ZWxsZW5ndGggKiAuMDYyNSAtIHNwYWNpbmcsIGZsb2F0MigwKSk7CgkJcmFkaWkgLT0gZXh0cmFfcGFkICogLjU7Cgl9CglmbG9hdDIgYWFfb3V0c2V0ID0gYWFfYmxvYXRfZGlyZWN0aW9uICogYWFfYmxvYXRyYWRpdXMgKiBhYV9ibG9hdF9tdWx0aXBsaWVyOwoJZmxvYXQyIHZlcnRleHBvcyA9IGNvcm5lciArIHJhZGl1c19vdXRzZXQgKiByYWRpaSArIGFhX291dHNldDsKCWlmIChjb3ZlcmFnZSA+IC41KSAKCXsKCQlpZiAoYWFfYmxvYXRfZGlyZWN0aW9uLnggIT0gMCAmJiB2ZXJ0ZXhwb3MueCAqIGNvcm5lci54IDwgMCkgCgkJewoJCQlmbG9hdCBiYWNrc2V0ID0gYWJzKHZlcnRleHBvcy54KTsKCQkJdmVydGV4cG9zLnggPSAwOwoJCQl2ZXJ0ZXhwb3MueSArPSBiYWNrc2V0ICogc2lnbihjb3JuZXIueSkgKiBwaXhlbGxlbmd0aC55L3BpeGVsbGVuZ3RoLng7CgkJCWNvdmVyYWdlID0gKGNvdmVyYWdlIC0gLjUpICogYWJzKGNvcm5lci54KSAvIChhYnMoY29ybmVyLngpICsgYmFja3NldCkgKyAuNTsKCQl9CgkJaWYgKGFhX2Jsb2F0X2RpcmVjdGlvbi55ICE9IDAgJiYgdmVydGV4cG9zLnkgKiBjb3JuZXIueSA8IDApIAoJCXsKCQkJZmxvYXQgYmFja3NldCA9IGFicyh2ZXJ0ZXhwb3MueSk7CgkJCXZlcnRleHBvcy55ID0gMDsKCQkJdmVydGV4cG9zLnggKz0gYmFja3NldCAqIHNpZ24oY29ybmVyLngpICogcGl4ZWxsZW5ndGgueC9waXhlbGxlbmd0aC55OwoJCQljb3ZlcmFnZSA9IChjb3ZlcmFnZSAtIC41KSAqIGFicyhjb3JuZXIueSkgLyAoYWJzKGNvcm5lci55KSArIGJhY2tzZXQpICsgLjU7CgkJfQoJfQoJZmxvYXQyeDIgc2tld21hdHJpeCA9IGZsb2F0MngyKHNrZXcueHksIHNrZXcuencpOwoJZmxvYXQyIGRldmNvb3JkID0gdmVydGV4cG9zICogc2tld21hdHJpeCArIHRyYW5zbGF0ZV9hbmRfbG9jYWxyb3RhdGUueHk7CglpZiAoMCAhPSBpc19saW5lYXJfY292ZXJhZ2UpIAoJewoJCXZhcmNjb29yZF9TMC54eSA9IGZsb2F0MigwLCBjb3ZlcmFnZSAqIGNvdmVyYWdlX211bHRpcGxpZXIpOwoJfQoJZWxzZSAKCXsKCQlmbG9hdDIgYXJjY29vcmQgPSAxIC0gYWJzKHJhZGl1c19vdXRzZXQpICsgYWFfb3V0c2V0L3JhZGlpICogY29ybmVyOwoJCXZhcmNjb29yZF9TMC54eSA9IGZsb2F0MihhcmNjb29yZC54KzEsIGFyY2Nvb3JkLnkpOwoJfQoJc2tfUG9zaXRpb24gPSBkZXZjb29yZC54eTAxOwp9CgAAAABFAgAAZmxhdCBpbiBoYWxmNCB2Y29sb3JfUzA7CmluIGZsb2F0MiB2YXJjY29vcmRfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBGaWxsUlJlY3RPcDo6UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmNvbG9yX1MwOwoJZmxvYXQgeF9wbHVzXzE9dmFyY2Nvb3JkX1MwLngsIHk9dmFyY2Nvb3JkX1MwLnk7CgloYWxmIGNvdmVyYWdlOwoJaWYgKDAgPT0geF9wbHVzXzEpIAoJewoJCWNvdmVyYWdlID0gaGFsZih5KTsKCX0KCWVsc2UgCgl7CgkJZmxvYXQgZm4gPSB4X3BsdXNfMSAqICh4X3BsdXNfMSAtIDIpOwoJCWZuID0gZm1hKHkseSwgZm4pOwoJCWZsb2F0IGZud2lkdGggPSBmd2lkdGgoZm4pOwoJCWNvdmVyYWdlID0gLjUgLSBoYWxmKGZuL2Zud2lkdGgpOwoJCWNvdmVyYWdlID0gY2xhbXAoY292ZXJhZ2UsIDAsIDEpOwoJfQoJaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNChjb3ZlcmFnZSk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRDb3ZlcmFnZV9TMDsKCX0KfQoAAAAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAACAAAAA4AAAByYWRpaV9zZWxlY3RvcgAAGQAAAGNvcm5lcl9hbmRfcmFkaXVzX291dHNldHMAAAAVAAAAYWFfYmxvYXRfYW5kX2NvdmVyYWdlAAAABwAAAHJhZGlpX3gABwAAAHJhZGlpX3kABAAAAHNrZXcZAAAAdHJhbnNsYXRlX2FuZF9sb2NhbHJvdGF0ZQAAAAUAAABjb2xvcgAAAAAAAAA=","HVJAAAAAABIAAGAAAQ4AAAH477776R24EAAAIOBQAD6P7777777777YDAAAAABAAAAAABBAMABAAOAAAABAAAAAAABBAMAAA":"DAAAAExTS1MjAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gaGFsZjQgY29sb3I7CmluIGZsb2F0MiBsb2NhbENvb3JkOwpmbGF0IG91dCBoYWxmNCB2Y29sb3JfUzA7Cm91dCBmbG9hdDIgdmxvY2FsQ29vcmRfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJdmNvbG9yX1MwID0gY29sb3I7Cgl2bG9jYWxDb29yZF9TMCA9IGxvY2FsQ29vcmQ7Cglza19Qb3NpdGlvbiA9IHBvc2l0aW9uLnh5MDE7Cn0KAAAAAADVAQAAc2FtcGxlcjJEIHVUZXh0dXJlU2FtcGxlcl8wX1MwOwpmbGF0IGluIGhhbGY0IHZjb2xvcl9TMDsKaW4gZmxvYXQyIHZsb2NhbENvb3JkX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmNvbG9yX1MwOwoJZmxvYXQyIHRleENvb3JkOwoJdGV4Q29vcmQgPSB2bG9jYWxDb29yZF9TMDsKCW91dHB1dENvbG9yX1MwID0gKGJsZW5kX21vZHVsYXRlKHNhbXBsZSh1VGV4dHVyZVNhbXBsZXJfMF9TMCwgdGV4Q29vcmQpLCBvdXRwdXRDb2xvcl9TMCkpOwoJY29uc3QgaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNCgxKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dENvdmVyYWdlX1MwOwoJfQp9CgAAAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAADAAAACAAAAHBvc2l0aW9uBQAAAGNvbG9yAAAACgAAAGxvY2FsQ29vcmQAAAAAAAA=","AYTRVAADQAAAOAEARAFQJAABBADAAAILBYAACCYUQD777777777767YAAAAAAAAAAAAOQAAAAAAAQAAAABAMQAAAAA":"DAAAAExTS1NyAgAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQ0IHVsb2NhbE1hdHJpeF9TMDsKaW4gZmxvYXQyIGluUG9zaXRpb247CmluIGhhbGY0IGluQ29sb3I7CmluIGZsb2F0NCBpbkNpcmNsZUVkZ2U7CmluIGhhbGYzIGluQ2xpcFBsYW5lOwppbiBoYWxmMyBpbklzZWN0UGxhbmU7Cm91dCBmbG9hdDQgdmluQ2lyY2xlRWRnZV9TMDsKb3V0IGhhbGYzIHZpbkNsaXBQbGFuZV9TMDsKb3V0IGhhbGYzIHZpbklzZWN0UGxhbmVfUzA7Cm91dCBoYWxmNCB2aW5Db2xvcl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgQ2lyY2xlR2VvbWV0cnlQcm9jZXNzb3IKCXZpbkNpcmNsZUVkZ2VfUzAgPSBpbkNpcmNsZUVkZ2U7Cgl2aW5DbGlwUGxhbmVfUzAgPSBpbkNsaXBQbGFuZTsKCXZpbklzZWN0UGxhbmVfUzAgPSBpbklzZWN0UGxhbmU7Cgl2aW5Db2xvcl9TMCA9IGluQ29sb3I7CglmbG9hdDIgX3RtcF8wX2luUG9zaXRpb24gPSBpblBvc2l0aW9uOwoJZmxvYXQyIF90bXBfMV9pblBvc2l0aW9uID0gdWxvY2FsTWF0cml4X1MwLnh6ICogaW5Qb3NpdGlvbiArIHVsb2NhbE1hdHJpeF9TMC55dzsKCXNrX1Bvc2l0aW9uID0gX3RtcF8wX2luUG9zaXRpb24ueHkwMTsKfQoAAAAAAADdAwAAaW4gZmxvYXQ0IHZpbkNpcmNsZUVkZ2VfUzA7CmluIGhhbGYzIHZpbkNsaXBQbGFuZV9TMDsKaW4gaGFsZjMgdmluSXNlY3RQbGFuZV9TMDsKaW4gaGFsZjQgdmluQ29sb3JfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBDaXJjbGVHZW9tZXRyeVByb2Nlc3NvcgoJZmxvYXQ0IGNpcmNsZUVkZ2U7CgljaXJjbGVFZGdlID0gdmluQ2lyY2xlRWRnZV9TMDsKCWhhbGYzIGNsaXBQbGFuZTsKCWNsaXBQbGFuZSA9IHZpbkNsaXBQbGFuZV9TMDsKCWhhbGYzIGlzZWN0UGxhbmU7Cglpc2VjdFBsYW5lID0gdmluSXNlY3RQbGFuZV9TMDsKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2aW5Db2xvcl9TMDsKCWZsb2F0IGQgPSBsZW5ndGgoY2lyY2xlRWRnZS54eSk7CgloYWxmIGRpc3RhbmNlVG9PdXRlckVkZ2UgPSBoYWxmKGNpcmNsZUVkZ2UueiAqICgxLjAgLSBkKSk7CgloYWxmIGVkZ2VBbHBoYSA9IHNhdHVyYXRlKGRpc3RhbmNlVG9PdXRlckVkZ2UpOwoJaGFsZiBkaXN0YW5jZVRvSW5uZXJFZGdlID0gaGFsZihjaXJjbGVFZGdlLnogKiAoZCAtIGNpcmNsZUVkZ2UudykpOwoJaGFsZiBpbm5lckFscGhhID0gc2F0dXJhdGUoZGlzdGFuY2VUb0lubmVyRWRnZSk7CgllZGdlQWxwaGEgKj0gaW5uZXJBbHBoYTsKCWhhbGYgY2xpcCA9IGhhbGYoc2F0dXJhdGUoY2lyY2xlRWRnZS56ICogZG90KGNpcmNsZUVkZ2UueHksIGNsaXBQbGFuZS54eSkgKyBjbGlwUGxhbmUueikpOwoJY2xpcCAqPSBoYWxmKHNhdHVyYXRlKGNpcmNsZUVkZ2UueiAqIGRvdChjaXJjbGVFZGdlLnh5LCBpc2VjdFBsYW5lLnh5KSArIGlzZWN0UGxhbmUueikpOwoJZWRnZUFscGhhICo9IGNsaXA7CgloYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KGVkZ2VBbHBoYSk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRDb3ZlcmFnZV9TMDsKCX0KfQoAAAAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAABQAAAAoAAABpblBvc2l0aW9uAAAHAAAAaW5Db2xvcgAMAAAAaW5DaXJjbGVFZGdlCwAAAGluQ2xpcFBsYW5lAAwAAABpbklzZWN0UGxhbmUAAAAA","FAAQMYAAMAAAEADAAABAEYAAAICIAB5AABQAAAQAMAAAEATAAABAIIGAAEDCBYQCA4AAAAAAEAB5AAAAACQNNQSEIYAQAADQAAAABAAAAAAABAEMVC2TBEKRAAAAAHAAAAAAAAAAACQAGAAAAAQAAAAAAAQQGAAA":"DAAAAExTS1PUCwAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0NCByYWRpaV9zZWxlY3RvcjsKaW4gZmxvYXQ0IGNvcm5lcl9hbmRfcmFkaXVzX291dHNldHM7CmluIGZsb2F0NCBhYV9ibG9hdF9hbmRfY292ZXJhZ2U7CmluIGZsb2F0NCByYWRpaV94OwppbiBmbG9hdDQgcmFkaWlfeTsKaW4gZmxvYXQ0IHNrZXc7CmluIGZsb2F0MiB0cmFuc2xhdGVfYW5kX2xvY2Fscm90YXRlOwppbiBoYWxmNCBjb2xvcjsKZmxhdCBvdXQgaGFsZjQgdmNvbG9yX1MwOwpvdXQgZmxvYXQyIHZhcmNjb29yZF9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgRmlsbFJSZWN0T3A6OlByb2Nlc3NvcgoJdmNvbG9yX1MwID0gY29sb3I7CglmbG9hdCBhYV9ibG9hdF9tdWx0aXBsaWVyID0gMTsKCWZsb2F0MiBjb3JuZXIgPSBjb3JuZXJfYW5kX3JhZGl1c19vdXRzZXRzLnh5OwoJZmxvYXQyIHJhZGl1c19vdXRzZXQgPSBjb3JuZXJfYW5kX3JhZGl1c19vdXRzZXRzLnp3OwoJZmxvYXQyIGFhX2Jsb2F0X2RpcmVjdGlvbiA9IGFhX2Jsb2F0X2FuZF9jb3ZlcmFnZS54eTsKCWZsb2F0IGlzX2xpbmVhcl9jb3ZlcmFnZSA9IGFhX2Jsb2F0X2FuZF9jb3ZlcmFnZS53OwoJZmxvYXQyIHBpeGVsbGVuZ3RoID0gaW52ZXJzZXNxcnQoZmxvYXQyKGRvdChza2V3Lnh6LCBza2V3Lnh6KSwgZG90KHNrZXcueXcsIHNrZXcueXcpKSk7CglmbG9hdDQgbm9ybWFsaXplZF9heGlzX2RpcnMgPSBza2V3ICogcGl4ZWxsZW5ndGgueHl4eTsKCWZsb2F0MiBheGlzd2lkdGhzID0gKGFicyhub3JtYWxpemVkX2F4aXNfZGlycy54eSkgKyBhYnMobm9ybWFsaXplZF9heGlzX2RpcnMuencpKTsKCWZsb2F0MiBhYV9ibG9hdHJhZGl1cyA9IGF4aXN3aWR0aHMgKiBwaXhlbGxlbmd0aCAqIC41OwoJZmxvYXQ0IHJhZGlpX2FuZF9uZWlnaGJvcnMgPSByYWRpaV9zZWxlY3RvciogZmxvYXQ0eDQocmFkaWlfeCwgcmFkaWlfeSwgcmFkaWlfeC55eHd6LCByYWRpaV95Lnd6eXgpOwoJZmxvYXQyIHJhZGlpID0gcmFkaWlfYW5kX25laWdoYm9ycy54eTsKCWZsb2F0MiBuZWlnaGJvcl9yYWRpaSA9IHJhZGlpX2FuZF9uZWlnaGJvcnMuenc7CglmbG9hdCBjb3ZlcmFnZV9tdWx0aXBsaWVyID0gMTsKCWlmIChhbnkoZ3JlYXRlclRoYW4oYWFfYmxvYXRyYWRpdXMsIGZsb2F0MigxKSkpKSAKCXsKCQljb3JuZXIgPSBtYXgoYWJzKGNvcm5lciksIGFhX2Jsb2F0cmFkaXVzKSAqIHNpZ24oY29ybmVyKTsKCQljb3ZlcmFnZV9tdWx0aXBsaWVyID0gMSAvIChtYXgoYWFfYmxvYXRyYWRpdXMueCwgMSkgKiBtYXgoYWFfYmxvYXRyYWRpdXMueSwgMSkpOwoJCXJhZGlpID0gZmxvYXQyKDApOwoJfQoJZmxvYXQgY292ZXJhZ2UgPSBhYV9ibG9hdF9hbmRfY292ZXJhZ2UuejsKCWlmIChhbnkobGVzc1RoYW4ocmFkaWksIGFhX2Jsb2F0cmFkaXVzICogMS41KSkpIAoJewoJCXJhZGlpID0gZmxvYXQyKDApOwoJCWFhX2Jsb2F0X2RpcmVjdGlvbiA9IHNpZ24oY29ybmVyKTsKCQlpZiAoY292ZXJhZ2UgPiAuNSkgCgkJewoJCQlhYV9ibG9hdF9kaXJlY3Rpb24gPSAtYWFfYmxvYXRfZGlyZWN0aW9uOwoJCX0KCQlpc19saW5lYXJfY292ZXJhZ2UgPSAxOwoJfQoJZWxzZSAKCXsKCQlyYWRpaSA9IGNsYW1wKHJhZGlpLCBwaXhlbGxlbmd0aCAqIDEuNSwgMiAtIHBpeGVsbGVuZ3RoICogMS41KTsKCQluZWlnaGJvcl9yYWRpaSA9IGNsYW1wKG5laWdoYm9yX3JhZGlpLCBwaXhlbGxlbmd0aCAqIDEuNSwgMiAtIHBpeGVsbGVuZ3RoICogMS41KTsKCQlmbG9hdDIgc3BhY2luZyA9IDIgLSByYWRpaSAtIG5laWdoYm9yX3JhZGlpOwoJCWZsb2F0MiBleHRyYV9wYWQgPSBtYXgocGl4ZWxsZW5ndGggKiAuMDYyNSAtIHNwYWNpbmcsIGZsb2F0MigwKSk7CgkJcmFkaWkgLT0gZXh0cmFfcGFkICogLjU7Cgl9CglmbG9hdDIgYWFfb3V0c2V0ID0gYWFfYmxvYXRfZGlyZWN0aW9uICogYWFfYmxvYXRyYWRpdXMgKiBhYV9ibG9hdF9tdWx0aXBsaWVyOwoJZmxvYXQyIHZlcnRleHBvcyA9IGNvcm5lciArIHJhZGl1c19vdXRzZXQgKiByYWRpaSArIGFhX291dHNldDsKCWlmIChjb3ZlcmFnZSA+IC41KSAKCXsKCQlpZiAoYWFfYmxvYXRfZGlyZWN0aW9uLnggIT0gMCAmJiB2ZXJ0ZXhwb3MueCAqIGNvcm5lci54IDwgMCkgCgkJewoJCQlmbG9hdCBiYWNrc2V0ID0gYWJzKHZlcnRleHBvcy54KTsKCQkJdmVydGV4cG9zLnggPSAwOwoJCQl2ZXJ0ZXhwb3MueSArPSBiYWNrc2V0ICogc2lnbihjb3JuZXIueSkgKiBwaXhlbGxlbmd0aC55L3BpeGVsbGVuZ3RoLng7CgkJCWNvdmVyYWdlID0gKGNvdmVyYWdlIC0gLjUpICogYWJzKGNvcm5lci54KSAvIChhYnMoY29ybmVyLngpICsgYmFja3NldCkgKyAuNTsKCQl9CgkJaWYgKGFhX2Jsb2F0X2RpcmVjdGlvbi55ICE9IDAgJiYgdmVydGV4cG9zLnkgKiBjb3JuZXIueSA8IDApIAoJCXsKCQkJZmxvYXQgYmFja3NldCA9IGFicyh2ZXJ0ZXhwb3MueSk7CgkJCXZlcnRleHBvcy55ID0gMDsKCQkJdmVydGV4cG9zLnggKz0gYmFja3NldCAqIHNpZ24oY29ybmVyLngpICogcGl4ZWxsZW5ndGgueC9waXhlbGxlbmd0aC55OwoJCQljb3ZlcmFnZSA9IChjb3ZlcmFnZSAtIC41KSAqIGFicyhjb3JuZXIueSkgLyAoYWJzKGNvcm5lci55KSArIGJhY2tzZXQpICsgLjU7CgkJfQoJfQoJZmxvYXQyeDIgc2tld21hdHJpeCA9IGZsb2F0MngyKHNrZXcueHksIHNrZXcuencpOwoJZmxvYXQyIGRldmNvb3JkID0gdmVydGV4cG9zICogc2tld21hdHJpeCArIHRyYW5zbGF0ZV9hbmRfbG9jYWxyb3RhdGUueHk7CglpZiAoMCAhPSBpc19saW5lYXJfY292ZXJhZ2UpIAoJewoJCXZhcmNjb29yZF9TMC54eSA9IGZsb2F0MigwLCBjb3ZlcmFnZSAqIGNvdmVyYWdlX211bHRpcGxpZXIpOwoJfQoJZWxzZSAKCXsKCQlmbG9hdDIgYXJjY29vcmQgPSAxIC0gYWJzKHJhZGl1c19vdXRzZXQpICsgYWFfb3V0c2V0L3JhZGlpICogY29ybmVyOwoJCXZhcmNjb29yZF9TMC54eSA9IGZsb2F0MihhcmNjb29yZC54KzEsIGFyY2Nvb3JkLnkpOwoJfQoJc2tfUG9zaXRpb24gPSBkZXZjb29yZC54eTAxOwp9CgEAAABJBQAAY29uc3QgaW50IGtGaWxsQUFfUzFfYzAgPSAxOwpjb25zdCBpbnQga0ludmVyc2VGaWxsQldfUzFfYzAgPSAyOwpjb25zdCBpbnQga0ludmVyc2VGaWxsQUFfUzFfYzAgPSAzOwp1bmlmb3JtIGZsb2F0NCB1Y2lyY2xlX1MxX2MwOwpmbGF0IGluIGhhbGY0IHZjb2xvcl9TMDsKaW4gZmxvYXQyIHZhcmNjb29yZF9TMDsKaGFsZjQgQ2lyY2xlX1MxX2MwKGhhbGY0IF9pbnB1dCkgCnsKCWhhbGY0IF90bXBfMF9pbkNvbG9yID0gX2lucHV0OwoJaGFsZiBkOwoJaWYgKGludCgzKSA9PSBrSW52ZXJzZUZpbGxCV19TMV9jMCB8fCBpbnQoMykgPT0ga0ludmVyc2VGaWxsQUFfUzFfYzApIAoJewoJCWQgPSBoYWxmKChsZW5ndGgoKHVjaXJjbGVfUzFfYzAueHkgLSBza19GcmFnQ29vcmQueHkpICogdWNpcmNsZV9TMV9jMC53KSAtIDEuMCkgKiB1Y2lyY2xlX1MxX2MwLnopOwoJfQoJZWxzZSAKCXsKCQlkID0gaGFsZigoMS4wIC0gbGVuZ3RoKCh1Y2lyY2xlX1MxX2MwLnh5IC0gc2tfRnJhZ0Nvb3JkLnh5KSAqIHVjaXJjbGVfUzFfYzAudykpICogdWNpcmNsZV9TMV9jMC56KTsKCX0KCXJldHVybiBoYWxmNChoYWxmNChpbnQoMykgPT0ga0ZpbGxBQV9TMV9jMCB8fCBpbnQoMykgPT0ga0ludmVyc2VGaWxsQUFfUzFfYzAgPyBzYXR1cmF0ZShkKSA6IGhhbGYoZCA+IDAuNSkpKTsKfQpoYWxmNCBCbGVuZF9TMShoYWxmNCBfc3JjLCBoYWxmNCBfZHN0KSAKewoJcmV0dXJuIGJsZW5kX21vZHVsYXRlKF9zcmMsIENpcmNsZV9TMV9jMChfc3JjKSk7Cn0Kdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIEZpbGxSUmVjdE9wOjpQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2Y29sb3JfUzA7CglmbG9hdCB4X3BsdXNfMT12YXJjY29vcmRfUzAueCwgeT12YXJjY29vcmRfUzAueTsKCWhhbGYgY292ZXJhZ2U7CglpZiAoMCA9PSB4X3BsdXNfMSkgCgl7CgkJY292ZXJhZ2UgPSBoYWxmKHkpOwoJfQoJZWxzZSAKCXsKCQlmbG9hdCBmbiA9IHhfcGx1c18xICogKHhfcGx1c18xIC0gMik7CgkJZm4gPSBmbWEoeSx5LCBmbik7CgkJZmxvYXQgZm53aWR0aCA9IGZ3aWR0aChmbik7CgkJY292ZXJhZ2UgPSAuNSAtIGhhbGYoZm4vZm53aWR0aCk7CgkJY292ZXJhZ2UgPSBjbGFtcChjb3ZlcmFnZSwgMCwgMSk7Cgl9CgloYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KGNvdmVyYWdlKTsKCWhhbGY0IG91dHB1dF9TMTsKCW91dHB1dF9TMSA9IEJsZW5kX1MxKG91dHB1dENvdmVyYWdlX1MwLCBoYWxmNCgxKSk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRfUzE7Cgl9Cn0KAAAAAQAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAOAAAAcmFkaWlfc2VsZWN0b3IAABkAAABjb3JuZXJfYW5kX3JhZGl1c19vdXRzZXRzAAAAFQAAAGFhX2Jsb2F0X2FuZF9jb3ZlcmFnZQAAAAcAAAByYWRpaV94AAcAAAByYWRpaV95AAQAAABza2V3GQAAAHRyYW5zbGF0ZV9hbmRfbG9jYWxyb3RhdGUAAAAFAAAAY29sb3IAAAAAAAAA","HVIAAAAAABIAAGAAAQ4AAAH477776R24EAAAIOBQAD6P7777777777YDAAAAAAAAAAAFIBVWKMG7QAAAAAAAAAQCAAAAAVQEEAQAAAAAQCDAAQQGAAAAEAAAAAAHIAAAAAAAIAAAAAQGIAAAAAAA":"DAAAAExTS1N6AQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMV9jMDsKaW4gZmxvYXQyIHBvc2l0aW9uOwppbiBoYWxmNCBjb2xvcjsKaW4gZmxvYXQyIGxvY2FsQ29vcmQ7CmZsYXQgb3V0IGhhbGY0IHZjb2xvcl9TMDsKb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfM19TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgl2Y29sb3JfUzAgPSBjb2xvcjsKCXNrX1Bvc2l0aW9uID0gcG9zaXRpb24ueHkwMTsKCXsKCQl2VHJhbnNmb3JtZWRDb29yZHNfM19TMCA9IGZsb2F0M3gyKHVtYXRyaXhfUzFfYzApICogbG9jYWxDb29yZC54eTE7Cgl9Cn0KAAAAAAAAQgQAAHVuaWZvcm0gZmxvYXQ0IHVjbGFtcF9TMV9jMF9jMDsKdW5pZm9ybSBmbG9hdDN4MyB1bWF0cml4X1MxX2MwOwpzYW1wbGVyMkQgdVRleHR1cmVTYW1wbGVyXzBfUzE7CmZsYXQgaW4gaGFsZjQgdmNvbG9yX1MwOwppbiBmbG9hdDIgdlRyYW5zZm9ybWVkQ29vcmRzXzNfUzA7CmhhbGY0IFRleHR1cmVFZmZlY3RfUzFfYzBfYzAoaGFsZjQgX2lucHV0KSAKewoJZmxvYXQyIGluQ29vcmQgPSB2VHJhbnNmb3JtZWRDb29yZHNfM19TMDsKCWZsb2F0MiBzdWJzZXRDb29yZDsKCXN1YnNldENvb3JkLnggPSBpbkNvb3JkLng7CglzdWJzZXRDb29yZC55ID0gaW5Db29yZC55OwoJZmxvYXQyIGNsYW1wZWRDb29yZDsKCWNsYW1wZWRDb29yZC54ID0gc3Vic2V0Q29vcmQueDsKCWNsYW1wZWRDb29yZC55ID0gY2xhbXAoc3Vic2V0Q29vcmQueSwgdWNsYW1wX1MxX2MwX2MwLnksIHVjbGFtcF9TMV9jMF9jMC53KTsKCWhhbGY0IHRleHR1cmVDb2xvciA9IHNhbXBsZSh1VGV4dHVyZVNhbXBsZXJfMF9TMSwgY2xhbXBlZENvb3JkKTsKCXJldHVybiB0ZXh0dXJlQ29sb3I7Cn0KaGFsZjQgTWF0cml4RWZmZWN0X1MxX2MwKGhhbGY0IF9pbnB1dCkgCnsKCXJldHVybiBUZXh0dXJlRWZmZWN0X1MxX2MwX2MwKF9pbnB1dCk7Cn0KaGFsZjQgRGlzYWJsZUNvdmVyYWdlQXNBbHBoYV9TMShoYWxmNCBfaW5wdXQpIAp7CglfaW5wdXQgPSBNYXRyaXhFZmZlY3RfUzFfYzAoX2lucHV0KTsKCWhhbGY0IF90bXBfMF9pbkNvbG9yID0gX2lucHV0OwoJcmV0dXJuIGhhbGY0KF9pbnB1dCk7Cn0Kdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJaGFsZjQgb3V0cHV0Q29sb3JfUzA7CglvdXRwdXRDb2xvcl9TMCA9IHZjb2xvcl9TMDsKCWNvbnN0IGhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoMSk7CgloYWxmNCBvdXRwdXRfUzE7CglvdXRwdXRfUzEgPSBEaXNhYmxlQ292ZXJhZ2VBc0FscGhhX1MxKG91dHB1dENvbG9yX1MwKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRfUzEgKiBvdXRwdXRDb3ZlcmFnZV9TMDsKCX0KfQoAAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAADAAAACAAAAHBvc2l0aW9uBQAAAGNvbG9yAAAACgAAAGxvY2FsQ29vcmQAAAAAAAA=","HUIAAAAAAAQAADAAAIOAAAH677777777777QGHAQAD7P7777777777YBAAAAAAAAAAALUASJ3EZYN2AAAAACAAAEAAAABSCQKL3IYIJ2AAAAACAAAEAAAABLRAABAAAAABAEGABBAMAAQAAAAAAAAOQAAAAAAAQAAAABAMQAAAAAA":"DAAAAExTS1M2AQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMTsKaW4gZmxvYXQyIHBvc2l0aW9uOwppbiBmbG9hdDIgbG9jYWxDb29yZDsKb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCglza19Qb3NpdGlvbiA9IHBvc2l0aW9uLnh5MDE7Cgl7CgkJdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzAgPSBmbG9hdDN4Mih1bWF0cml4X1MxKSAqIGxvY2FsQ29vcmQueHkxOwoJfQp9CgAAAAAAAGgHAABjb25zdCBpbnQga01heExvb3BMaW1pdF9TMV9jMCA9IDg7CnVuaWZvcm0gaGFsZjQgdWJvcmRlcl9TMV9jMF9jMF9jMDsKdW5pZm9ybSBmbG9hdDQgdXN1YnNldF9TMV9jMF9jMF9jMDsKdW5pZm9ybSBmbG9hdDQgdWNsYW1wX1MxX2MwX2MwX2MwOwp1bmlmb3JtIGZsb2F0MiB1aWRpbXNfUzFfYzBfYzBfYzA7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMV9jMF9jMDsKdW5pZm9ybSBoYWxmNCB1b2Zmc2V0c0FuZEtlcm5lbF9TMV9jMFsxNF07CnVuaWZvcm0gaGFsZjIgdWRpcl9TMV9jMDsKdW5pZm9ybSBmbG9hdDN4MyB1bWF0cml4X1MxOwpzYW1wbGVyMkQgdVRleHR1cmVTYW1wbGVyXzBfUzE7CmluIGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKaGFsZjQgVGV4dHVyZUVmZmVjdF9TMV9jMF9jMF9jMChoYWxmNCBfaW5wdXQsIGZsb2F0MiBfY29vcmRzKSAKewoJZmxvYXQyIGluQ29vcmQgPSBfY29vcmRzOwoJZmxvYXQyIHN1YnNldENvb3JkOwoJc3Vic2V0Q29vcmQueCA9IGluQ29vcmQueDsKCXN1YnNldENvb3JkLnkgPSBpbkNvb3JkLnk7CglmbG9hdDIgY2xhbXBlZENvb3JkOwoJY2xhbXBlZENvb3JkLnggPSBjbGFtcChzdWJzZXRDb29yZC54LCB1Y2xhbXBfUzFfYzBfYzBfYzAueCwgdWNsYW1wX1MxX2MwX2MwX2MwLnopOwoJY2xhbXBlZENvb3JkLnkgPSBzdWJzZXRDb29yZC55OwoJaGFsZjQgdGV4dHVyZUNvbG9yID0gc2FtcGxlKHVUZXh0dXJlU2FtcGxlcl8wX1MxLCAoY2xhbXBlZENvb3JkKSAqIHVpZGltc19TMV9jMF9jMF9jMCk7CgloYWxmIGVyclggPSBoYWxmKHN1YnNldENvb3JkLnggLSBjbGFtcGVkQ29vcmQueCk7Cgl0ZXh0dXJlQ29sb3IgPSBtaXgodGV4dHVyZUNvbG9yLCB1Ym9yZGVyX1MxX2MwX2MwX2MwLCBtaW4oYWJzKGVyclgpLCAxKSk7CglyZXR1cm4gdGV4dHVyZUNvbG9yOwp9CmhhbGY0IE1hdHJpeEVmZmVjdF9TMV9jMF9jMChoYWxmNCBfaW5wdXQsIGZsb2F0MiBfY29vcmRzKSAKewoJcmV0dXJuIFRleHR1cmVFZmZlY3RfUzFfYzBfYzBfYzAoX2lucHV0LCBmbG9hdDN4Mih1bWF0cml4X1MxX2MwX2MwKSAqIF9jb29yZHMueHkxKTsKfQpoYWxmNCBHYXVzc2lhbkJsdXIxRF9TMV9jMChoYWxmNCBfaW5wdXQpIAp7CgloYWxmNCBfdG1wXzBfaW5Db2xvciA9IF9pbnB1dDsKCWZsb2F0MiBfdG1wXzFfY29vcmRzID0gdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzA7CgloYWxmNCBzdW0gPSBoYWxmNCgwLjApOwoJZm9yIChpbnQgaSA9IDA7aSA8IGtNYXhMb29wTGltaXRfUzFfYzA7ICsraSkgCgl7CgkJaGFsZjQgcyA9IHVvZmZzZXRzQW5kS2VybmVsX1MxX2MwW2ldOwoJCXN1bSArPSBzLnkgKiBNYXRyaXhFZmZlY3RfUzFfYzBfYzAoX3RtcF8wX2luQ29sb3IsIF90bXBfMV9jb29yZHMgKyBmbG9hdDIocy54ICogdWRpcl9TMV9jMCkpOwoJCXN1bSArPSBzLncgKiBNYXRyaXhFZmZlY3RfUzFfYzBfYzAoX3RtcF8wX2luQ29sb3IsIF90bXBfMV9jb29yZHMgKyBmbG9hdDIocy56ICogdWRpcl9TMV9jMCkpOwoJfQoJcmV0dXJuIGhhbGY0KHN1bSk7Cn0KaGFsZjQgTWF0cml4RWZmZWN0X1MxKGhhbGY0IF9pbnB1dCkgCnsKCXJldHVybiBHYXVzc2lhbkJsdXIxRF9TMV9jMChfaW5wdXQpOwp9CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwID0gaGFsZjQoMSk7Cgljb25zdCBoYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KDEpOwoJaGFsZjQgb3V0cHV0X1MxOwoJb3V0cHV0X1MxID0gTWF0cml4RWZmZWN0X1MxKG91dHB1dENvbG9yX1MwKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRfUzEgKiBvdXRwdXRDb3ZlcmFnZV9TMDsKCX0KfQoAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAgAAABwb3NpdGlvbgoAAABsb2NhbENvb3JkAAAAAAAA","HUJAAAAAAAQAADAAAIOAAAH677777777777QGHAQAD7P7777777777YBAAAAAAQAAAAAAQQGAAZAADIAAAAGULKMMQKAAAAAAMAAAAAIAAAAAAGIRBNAWEYZAUAABQAAAAAAAAAAAAADUAAAAAAAEAAAAAIDEAAA":"DAAAAExTS1PlAAAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gZmxvYXQyIGxvY2FsQ29vcmQ7Cm91dCBmbG9hdDIgdmxvY2FsQ29vcmRfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJdmxvY2FsQ29vcmRfUzAgPSBsb2NhbENvb3JkOwoJc2tfUG9zaXRpb24gPSBwb3NpdGlvbi54eTAxOwp9CgAAAAEAAACoBAAAY29uc3QgaW50IGtGaWxsQUFfUzFfYzAgPSAxOwpjb25zdCBpbnQga0ludmVyc2VGaWxsQldfUzFfYzAgPSAyOwpjb25zdCBpbnQga0ludmVyc2VGaWxsQUFfUzFfYzAgPSAzOwp1bmlmb3JtIGZsb2F0NCB1Y2lyY2xlX1MxX2MwOwpzYW1wbGVyMkQgdVRleHR1cmVTYW1wbGVyXzBfUzA7CmluIGZsb2F0MiB2bG9jYWxDb29yZF9TMDsKaGFsZjQgQ2lyY2xlX1MxX2MwKGhhbGY0IF9pbnB1dCkgCnsKCWhhbGY0IF90bXBfMF9pbkNvbG9yID0gX2lucHV0OwoJaGFsZiBkOwoJaWYgKGludCgxKSA9PSBrSW52ZXJzZUZpbGxCV19TMV9jMCB8fCBpbnQoMSkgPT0ga0ludmVyc2VGaWxsQUFfUzFfYzApIAoJewoJCWQgPSBoYWxmKChsZW5ndGgoKHVjaXJjbGVfUzFfYzAueHkgLSBza19GcmFnQ29vcmQueHkpICogdWNpcmNsZV9TMV9jMC53KSAtIDEuMCkgKiB1Y2lyY2xlX1MxX2MwLnopOwoJfQoJZWxzZSAKCXsKCQlkID0gaGFsZigoMS4wIC0gbGVuZ3RoKCh1Y2lyY2xlX1MxX2MwLnh5IC0gc2tfRnJhZ0Nvb3JkLnh5KSAqIHVjaXJjbGVfUzFfYzAudykpICogdWNpcmNsZV9TMV9jMC56KTsKCX0KCXJldHVybiBoYWxmNChoYWxmNChpbnQoMSkgPT0ga0ZpbGxBQV9TMV9jMCB8fCBpbnQoMSkgPT0ga0ludmVyc2VGaWxsQUFfUzFfYzAgPyBzYXR1cmF0ZShkKSA6IGhhbGYoZCA+IDAuNSkpKTsKfQpoYWxmNCBCbGVuZF9TMShoYWxmNCBfc3JjLCBoYWxmNCBfZHN0KSAKewoJcmV0dXJuIGJsZW5kX21vZHVsYXRlKF9zcmMsIENpcmNsZV9TMV9jMChfc3JjKSk7Cn0Kdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJaGFsZjQgb3V0cHV0Q29sb3JfUzAgPSBoYWxmNCgxKTsKCWZsb2F0MiB0ZXhDb29yZDsKCXRleENvb3JkID0gdmxvY2FsQ29vcmRfUzA7CglvdXRwdXRDb2xvcl9TMCA9IChibGVuZF9tb2R1bGF0ZShzYW1wbGUodVRleHR1cmVTYW1wbGVyXzBfUzAsIHRleENvb3JkKSwgaGFsZjQoMSkpKTsKCWNvbnN0IGhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoMSk7CgloYWxmNCBvdXRwdXRfUzE7CglvdXRwdXRfUzEgPSBCbGVuZF9TMShvdXRwdXRDb3ZlcmFnZV9TMCwgaGFsZjQoMSkpOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dENvbG9yX1MwICogb3V0cHV0X1MxOwoJfQp9CgEAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAACAAAACAAAAHBvc2l0aW9uCgAAAGxvY2FsQ29vcmQAAAAAAAA=","HVIAAAAAABIAAGAAAQ4AAAH477776R24EAAAIOBQAD6P7777777777YDAAAAAAAAAAAFIBVWKMG7QAAAAAAAEAQCAAAAAVREEAQAAAAAQCDAAQQGAABAEAAAAAAHIAAAAAAAIAAAAAQGIAAAAAAA":"DAAAAExTS1N6AQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMV9jMDsKaW4gZmxvYXQyIHBvc2l0aW9uOwppbiBoYWxmNCBjb2xvcjsKaW4gZmxvYXQyIGxvY2FsQ29vcmQ7CmZsYXQgb3V0IGhhbGY0IHZjb2xvcl9TMDsKb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfM19TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgl2Y29sb3JfUzAgPSBjb2xvcjsKCXNrX1Bvc2l0aW9uID0gcG9zaXRpb24ueHkwMTsKCXsKCQl2VHJhbnNmb3JtZWRDb29yZHNfM19TMCA9IGZsb2F0M3gyKHVtYXRyaXhfUzFfYzApICogbG9jYWxDb29yZC54eTE7Cgl9Cn0KAAAAAAAAHwQAAHVuaWZvcm0gZmxvYXQ0IHVjbGFtcF9TMV9jMF9jMDsKdW5pZm9ybSBmbG9hdDN4MyB1bWF0cml4X1MxX2MwOwpzYW1wbGVyMkQgdVRleHR1cmVTYW1wbGVyXzBfUzE7CmZsYXQgaW4gaGFsZjQgdmNvbG9yX1MwOwppbiBmbG9hdDIgdlRyYW5zZm9ybWVkQ29vcmRzXzNfUzA7CmhhbGY0IFRleHR1cmVFZmZlY3RfUzFfYzBfYzAoaGFsZjQgX2lucHV0KSAKewoJZmxvYXQyIGluQ29vcmQgPSB2VHJhbnNmb3JtZWRDb29yZHNfM19TMDsKCWZsb2F0MiBzdWJzZXRDb29yZDsKCXN1YnNldENvb3JkLnggPSBpbkNvb3JkLng7CglzdWJzZXRDb29yZC55ID0gaW5Db29yZC55OwoJZmxvYXQyIGNsYW1wZWRDb29yZDsKCWNsYW1wZWRDb29yZCA9IGNsYW1wKHN1YnNldENvb3JkLCB1Y2xhbXBfUzFfYzBfYzAueHksIHVjbGFtcF9TMV9jMF9jMC56dyk7CgloYWxmNCB0ZXh0dXJlQ29sb3IgPSBzYW1wbGUodVRleHR1cmVTYW1wbGVyXzBfUzEsIGNsYW1wZWRDb29yZCk7CglyZXR1cm4gdGV4dHVyZUNvbG9yOwp9CmhhbGY0IE1hdHJpeEVmZmVjdF9TMV9jMChoYWxmNCBfaW5wdXQpIAp7CglyZXR1cm4gVGV4dHVyZUVmZmVjdF9TMV9jMF9jMChfaW5wdXQpOwp9CmhhbGY0IERpc2FibGVDb3ZlcmFnZUFzQWxwaGFfUzEoaGFsZjQgX2lucHV0KSAKewoJX2lucHV0ID0gTWF0cml4RWZmZWN0X1MxX2MwKF9pbnB1dCk7CgloYWxmNCBfdG1wXzBfaW5Db2xvciA9IF9pbnB1dDsKCXJldHVybiBoYWxmNChfaW5wdXQpOwp9CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2Y29sb3JfUzA7Cgljb25zdCBoYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KDEpOwoJaGFsZjQgb3V0cHV0X1MxOwoJb3V0cHV0X1MxID0gRGlzYWJsZUNvdmVyYWdlQXNBbHBoYV9TMShvdXRwdXRDb2xvcl9TMCk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0X1MxICogb3V0cHV0Q292ZXJhZ2VfUzA7Cgl9Cn0KAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAADAAAACAAAAHBvc2l0aW9uBQAAAGNvbG9yAAAACgAAAGxvY2FsQ29vcmQAAAAAAAA=","HVIACAAAABQAAGAAAQ4AAAAAGQQAARC4GAAAIOCAAD6P7777777777YDAAAAAAAAAAAHQBNGZODK5YIAAAAAAQAAAAAIADCNS4GV3QYBAAAAAAAAAAAIAALIAAAAB2BQ7SD2OAAAAAMAAAAAEAHQAACAAAAAAQCGHIGP7YJJAAAAABQAAAAAAAAAAA4JAPAAACAAAAAAAAAB2AAAAAAACAAAAAEBSAAA":"DAAAAExTS1PZAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMTsKaW4gZmxvYXQyIHBvc2l0aW9uOwppbiBmbG9hdCBjb3ZlcmFnZTsKaW4gaGFsZjQgY29sb3I7CmluIGZsb2F0MiBsb2NhbENvb3JkOwpmbGF0IG91dCBoYWxmNCB2Y29sb3JfUzA7Cm91dCBmbG9hdCB2Y292ZXJhZ2VfUzA7Cm91dCBmbG9hdDIgdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJZmxvYXQyIHBvc2l0aW9uID0gcG9zaXRpb24ueHk7Cgl2Y29sb3JfUzAgPSBjb2xvcjsKCXZjb3ZlcmFnZV9TMCA9IGNvdmVyYWdlOwoJc2tfUG9zaXRpb24gPSBwb3NpdGlvbi54eTAxOwoJewoJCXZUcmFuc2Zvcm1lZENvb3Jkc18yX1MwID0gZmxvYXQzeDIodW1hdHJpeF9TMSkgKiBsb2NhbENvb3JkLnh5MTsKCX0KfQoAAAABAAAA2CAAAGZsb2F0NCBmbHV0dGVyX0ZyYWdDb29yZF9TMV9jMDsKZmxvYXQ0IGZyYWdDb2xvcl9TMV9jMDsKZmxvYXQgdV9hbHBoYV9TMV9jMDsKZmxvYXQgdV9zcGFya2xlX2FscGhhX1MxX2MwOwpmbG9hdCB1X2JsdXJfUzFfYzA7CmZsb2F0IHVfcmFkaXVzX3NjYWxlX1MxX2MwOwpjb25zdCBpbnQga0ZpbGxCV19TMl9jMCA9IDA7CmNvbnN0IGludCBrSW52ZXJzZUZpbGxCV19TMl9jMCA9IDI7CmNvbnN0IGludCBrSW52ZXJzZUZpbGxBQV9TMl9jMCA9IDM7CnVuaWZvcm0gZmxvYXQ0IHVfY29sb3JfUzFfYzA7CnVuaWZvcm0gZmxvYXQ0IHVfY29tcG9zaXRlXzFfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfY2VudGVyX1MxX2MwOwp1bmlmb3JtIGZsb2F0IHVfbWF4X3JhZGl1c19TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9yZXNvbHV0aW9uX3NjYWxlX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X25vaXNlX3NjYWxlX1MxX2MwOwp1bmlmb3JtIGZsb2F0IHVfbm9pc2VfcGhhc2VfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfY2lyY2xlMV9TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9jaXJjbGUyX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X2NpcmNsZTNfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfcm90YXRpb24xX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X3JvdGF0aW9uMl9TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9yb3RhdGlvbjNfUzFfYzA7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMTsKdW5pZm9ybSBmbG9hdDQgdXJlY3RVbmlmb3JtX1MyX2MwOwp1bmlmb3JtIGZsb2F0NCB1aW5uZXJSZWN0X1MyX2MxOwp1bmlmb3JtIGhhbGYyIHVyYWRpdXNQbHVzSGFsZl9TMl9jMTsKZmxhdCBpbiBoYWxmNCB2Y29sb3JfUzA7CmluIGZsb2F0IHZjb3ZlcmFnZV9TMDsKaW4gZmxvYXQyIHZUcmFuc2Zvcm1lZENvb3Jkc18yX1MwOwpmbG9hdDIgRkxUX2ZsdXR0ZXJfbG9jYWxfRmx1dHRlckZyYWdDb29yZF9TMV9jMCgpOwpmbG9hdDJ4MiBGTFRfZmx1dHRlcl9sb2NhbF9yb3RhdGUyZF9TMV9jMChmbG9hdDIgcmFkKTsKZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9jaXJjbGVfUzFfYzAoZmxvYXQyIHV2LCBmbG9hdDIgeHksIGZsb2F0IHJhZGl1cywgZmxvYXQgYmx1cik7CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX2NpcmNsZV9ncmlkX1MxX2MwKGZsb2F0MiByZXNvbHV0aW9uLCBpbm91dCBmbG9hdDIgcCwgZmxvYXQyIHh5LCBmbG9hdDIgcm90YXRpb24sIGZsb2F0IGNlbGxfZGlhbWV0ZXIpOwpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF90dXJidWxlbmNlX1MxX2MwKGZsb2F0MiB1dik7CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfcmluZ19TMV9jMChmbG9hdDIgdXYsIGZsb2F0MiB4eSwgZmxvYXQgcmFkaXVzLCBmbG9hdCB0aGlja25lc3MsIGZsb2F0IGJsdXIpOwpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF90cmlhbmdsZV9ub2lzZV9TMV9jMChpbm91dCBmbG9hdDIgbik7CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3RocmVzaG9sZF9TMV9jMChmbG9hdCB2LCBmbG9hdCBsLCBmbG9hdCBoKTsKZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfc3BhcmtsZV9TMV9jMChmbG9hdDIgdXYsIGZsb2F0IHQpOwp2b2lkIEZMVF9tYWluX1MxX2MwKCk7CmZsb2F0MiBGTFRfZmx1dHRlcl9sb2NhbF9GbHV0dGVyRnJhZ0Nvb3JkX1MxX2MwKCkgCnsKCXJldHVybiBmbHV0dGVyX0ZyYWdDb29yZF9TMV9jMC54eTsKfQpmbG9hdDJ4MiBGTFRfZmx1dHRlcl9sb2NhbF9yb3RhdGUyZF9TMV9jMChmbG9hdDIgcmFkKSAKewoJcmV0dXJuIGZsb2F0MngyKHJhZC54LCAtcmFkLnksIHJhZC55LCByYWQueCk7Cn0KZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9jaXJjbGVfUzFfYzAoZmxvYXQyIHV2LCBmbG9hdDIgeHksIGZsb2F0IHJhZGl1cywgZmxvYXQgYmx1cikgCnsKCWZsb2F0IGJsdXJfaGFsZiA9IGJsdXIgKiAwLjU7CglmbG9hdCBkID0gZGlzdGFuY2UodXYsIHh5KTsKCXJldHVybiAxLjAgLSBzbW9vdGhzdGVwKDEuMCAtIGJsdXJfaGFsZiwgMS4wICsgYmx1cl9oYWxmLCBkIC8gcmFkaXVzKTsKfQpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9jaXJjbGVfZ3JpZF9TMV9jMChmbG9hdDIgcmVzb2x1dGlvbiwgaW5vdXQgZmxvYXQyIHAsIGZsb2F0MiB4eSwgZmxvYXQyIHJvdGF0aW9uLCBmbG9hdCBjZWxsX2RpYW1ldGVyKSAKewoJZmxvYXQyIHBhcmFtID0gcm90YXRpb247CglwID0gRkxUX2ZsdXR0ZXJfbG9jYWxfcm90YXRlMmRfUzFfYzAocGFyYW0pICogKHh5IC0gcCkgKyB4eTsKCXAgPSBtb2QocCwgZmxvYXQyKGNlbGxfZGlhbWV0ZXIpKSAvIHJlc29sdXRpb247CglmbG9hdCBjZWxsX3V2ID0gKGNlbGxfZGlhbWV0ZXIgLyByZXNvbHV0aW9uLnkpICogMC41OwoJZmxvYXQgciA9IDAuNjUgKiBjZWxsX3V2OwoJZmxvYXQyIHBhcmFtXzEgPSBwOwoJZmxvYXQyIHBhcmFtXzIgPSBmbG9hdDIoY2VsbF91dik7CglmbG9hdCBwYXJhbV8zID0gcjsKCWZsb2F0IHBhcmFtXzQgPSByICogNTAuMDsKCXJldHVybiBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X2NpcmNsZV9TMV9jMChwYXJhbV8xLCBwYXJhbV8yLCBwYXJhbV8zLCBwYXJhbV80KTsKfQpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF90dXJidWxlbmNlX1MxX2MwKGZsb2F0MiB1dikgCnsKCWZsb2F0MiB1dl9zY2FsZSA9IHV2ICogZmxvYXQyKDAuOCk7CglmbG9hdDIgcGFyYW0gPSBmbG9hdDIoMC44KTsKCWZsb2F0MiBwYXJhbV8xID0gdXZfc2NhbGU7CglmbG9hdDIgcGFyYW1fMiA9IHVfY2lyY2xlMV9TMV9jMDsKCWZsb2F0MiBwYXJhbV8zID0gdV9yb3RhdGlvbjFfUzFfYzA7CglmbG9hdCBwYXJhbV80ID0gMC4xNzsKCWZsb2F0IF8zMTkgPSBGTFRfZmx1dHRlcl9sb2NhbF9jaXJjbGVfZ3JpZF9TMV9jMChwYXJhbSwgcGFyYW1fMSwgcGFyYW1fMiwgcGFyYW1fMywgcGFyYW1fNCk7CglmbG9hdCBnMSA9IF8zMTk7CglmbG9hdDIgcGFyYW1fNSA9IGZsb2F0MigwLjgpOwoJZmxvYXQyIHBhcmFtXzYgPSB1dl9zY2FsZTsKCWZsb2F0MiBwYXJhbV83ID0gdV9jaXJjbGUyX1MxX2MwOwoJZmxvYXQyIHBhcmFtXzggPSB1X3JvdGF0aW9uMl9TMV9jMDsKCWZsb2F0IHBhcmFtXzkgPSAwLjI7CglmbG9hdCBfMzMxID0gRkxUX2ZsdXR0ZXJfbG9jYWxfY2lyY2xlX2dyaWRfUzFfYzAocGFyYW1fNSwgcGFyYW1fNiwgcGFyYW1fNywgcGFyYW1fOCwgcGFyYW1fOSk7CglmbG9hdCBnMiA9IF8zMzE7CglmbG9hdDIgcGFyYW1fMTAgPSBmbG9hdDIoMC44KTsKCWZsb2F0MiBwYXJhbV8xMSA9IHV2X3NjYWxlOwoJZmxvYXQyIHBhcmFtXzEyID0gdV9jaXJjbGUzX1MxX2MwOwoJZmxvYXQyIHBhcmFtXzEzID0gdV9yb3RhdGlvbjNfUzFfYzA7CglmbG9hdCBwYXJhbV8xNCA9IDAuMjc1OwoJZmxvYXQgXzM0NCA9IEZMVF9mbHV0dGVyX2xvY2FsX2NpcmNsZV9ncmlkX1MxX2MwKHBhcmFtXzEwLCBwYXJhbV8xMSwgcGFyYW1fMTIsIHBhcmFtXzEzLCBwYXJhbV8xNCk7CglmbG9hdCBnMyA9IF8zNDQ7CglmbG9hdCB2ID0gKChnMSAqIGcxICsgZzIpIC0gZzMpICogMC41OwoJcmV0dXJuIGNsYW1wKDAuNDUgKyAwLjggKiB2LCAwLjAsIDEuMCk7Cn0KZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9yaW5nX1MxX2MwKGZsb2F0MiB1diwgZmxvYXQyIHh5LCBmbG9hdCByYWRpdXMsIGZsb2F0IHRoaWNrbmVzcywgZmxvYXQgYmx1cikgCnsKCWZsb2F0MiBwYXJhbSA9IHV2OwoJZmxvYXQyIHBhcmFtXzEgPSB4eTsKCWZsb2F0IHBhcmFtXzIgPSByYWRpdXMgKyB0aGlja25lc3M7CglmbG9hdCBwYXJhbV8zID0gYmx1cjsKCWZsb2F0IGNpcmNsZV9vdXRlciA9IEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfY2lyY2xlX1MxX2MwKHBhcmFtLCBwYXJhbV8xLCBwYXJhbV8yLCBwYXJhbV8zKTsKCWZsb2F0MiBwYXJhbV80ID0gdXY7CglmbG9hdDIgcGFyYW1fNSA9IHh5OwoJZmxvYXQgcGFyYW1fNiA9IG1heChyYWRpdXMgLSB0aGlja25lc3MsIDAuMCk7CglmbG9hdCBwYXJhbV83ID0gYmx1cjsKCWZsb2F0IGNpcmNsZV9pbm5lciA9IEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfY2lyY2xlX1MxX2MwKHBhcmFtXzQsIHBhcmFtXzUsIHBhcmFtXzYsIHBhcmFtXzcpOwoJcmV0dXJuIGNsYW1wKGNpcmNsZV9vdXRlciAtIGNpcmNsZV9pbm5lciwgMC4wLCAxLjApOwp9CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3RyaWFuZ2xlX25vaXNlX1MxX2MwKGlub3V0IGZsb2F0MiBuKSAKewoJbiA9IGZyYWN0KG4gKiBmbG9hdDIoNS4zOTg3LCA1LjQ0MjEpKTsKCW4gKz0gZmxvYXQyKGRvdChuLnl4LCBuICsgZmxvYXQyKDIxLjUzNTEsIDE0LjMxMzcpKSk7CglmbG9hdCB4eSA9IG4ueCAqIG4ueTsKCXJldHVybiAoZnJhY3QoeHkgKiA5NS40MzA3KSArIGZyYWN0KHh5ICogNzUuMDQ5NjEpKSAtIDEuMDsKfQpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF90aHJlc2hvbGRfUzFfYzAoZmxvYXQgdiwgZmxvYXQgbCwgZmxvYXQgaCkgCnsKCXJldHVybiBzdGVwKGwsIHYpICogKDEuMCAtIHN0ZXAoaCwgdikpOwp9CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3NwYXJrbGVfUzFfYzAoZmxvYXQyIHV2LCBmbG9hdCB0KSAKewoJZmxvYXQyIHBhcmFtID0gdXY7CglmbG9hdCBfMjQyID0gRkxUX2ZsdXR0ZXJfbG9jYWxfdHJpYW5nbGVfbm9pc2VfUzFfYzAocGFyYW0pOwoJZmxvYXQgbiA9IF8yNDI7CglmbG9hdCBwYXJhbV8xID0gbjsKCWZsb2F0IHBhcmFtXzIgPSAwLjA7CglmbG9hdCBwYXJhbV8zID0gMC4wNTsKCWZsb2F0IHMgPSBGTFRfZmx1dHRlcl9sb2NhbF90aHJlc2hvbGRfUzFfYzAocGFyYW1fMSwgcGFyYW1fMiwgcGFyYW1fMyk7CglmbG9hdCBwYXJhbV80ID0gbiArIHNpbigzLjE0MTU5Mjc0ICogKHQgKyAwLjM1KSk7CglmbG9hdCBwYXJhbV81ID0gMC4xOwoJZmxvYXQgcGFyYW1fNiA9IDAuMTU7CglzICs9IEZMVF9mbHV0dGVyX2xvY2FsX3RocmVzaG9sZF9TMV9jMChwYXJhbV80LCBwYXJhbV81LCBwYXJhbV82KTsKCWZsb2F0IHBhcmFtXzcgPSBuICsgc2luKDMuMTQxNTkyNzQgKiAodCArIDAuNykpOwoJZmxvYXQgcGFyYW1fOCA9IDAuMjsKCWZsb2F0IHBhcmFtXzkgPSAwLjI1OwoJcyArPSBGTFRfZmx1dHRlcl9sb2NhbF90aHJlc2hvbGRfUzFfYzAocGFyYW1fNywgcGFyYW1fOCwgcGFyYW1fOSk7CglmbG9hdCBwYXJhbV8xMCA9IG4gKyBzaW4oMy4xNDE1OTI3NCAqICh0ICsgMS4wNSkpOwoJZmxvYXQgcGFyYW1fMTEgPSAwLjM7CglmbG9hdCBwYXJhbV8xMiA9IDAuMzU7CglzICs9IEZMVF9mbHV0dGVyX2xvY2FsX3RocmVzaG9sZF9TMV9jMChwYXJhbV8xMCwgcGFyYW1fMTEsIHBhcmFtXzEyKTsKCXJldHVybiBjbGFtcChzLCAwLjAsIDEuMCkgKiAwLjU1Owp9CnZvaWQgRkxUX21haW5fUzFfYzAoKSAKewoJdV9hbHBoYV9TMV9jMCA9IHVfY29tcG9zaXRlXzFfUzFfYzAueDsKCXVfc3BhcmtsZV9hbHBoYV9TMV9jMCA9IHVfY29tcG9zaXRlXzFfUzFfYzAueTsKCXVfYmx1cl9TMV9jMCA9IHVfY29tcG9zaXRlXzFfUzFfYzAuejsKCXVfcmFkaXVzX3NjYWxlX1MxX2MwID0gdV9jb21wb3NpdGVfMV9TMV9jMC53OwoJZmxvYXQyIHAgPSBGTFRfZmx1dHRlcl9sb2NhbF9GbHV0dGVyRnJhZ0Nvb3JkX1MxX2MwKCk7CglmbG9hdDIgdXZfMSA9IHAgKiB1X3Jlc29sdXRpb25fc2NhbGVfUzFfYzA7CglmbG9hdDIgZGVuc2l0eV91diA9IHV2XzEgLSBtb2QocCwgdV9ub2lzZV9zY2FsZV9TMV9jMCk7CglmbG9hdCByYWRpdXMgPSB1X21heF9yYWRpdXNfUzFfYzAgKiB1X3JhZGl1c19zY2FsZV9TMV9jMDsKCWZsb2F0MiBwYXJhbV8xMyA9IHV2XzE7CglmbG9hdCB0dXJidWxlbmNlID0gRkxUX2ZsdXR0ZXJfbG9jYWxfdHVyYnVsZW5jZV9TMV9jMChwYXJhbV8xMyk7CglmbG9hdDIgcGFyYW1fMTQgPSBwOwoJZmxvYXQyIHBhcmFtXzE1ID0gdV9jZW50ZXJfUzFfYzA7CglmbG9hdCBwYXJhbV8xNiA9IHJhZGl1czsKCWZsb2F0IHBhcmFtXzE3ID0gMC4wNSAqIHVfbWF4X3JhZGl1c19TMV9jMDsKCWZsb2F0IHBhcmFtXzE4ID0gdV9ibHVyX1MxX2MwOwoJZmxvYXQgcmluZyA9IEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfcmluZ19TMV9jMChwYXJhbV8xNCwgcGFyYW1fMTUsIHBhcmFtXzE2LCBwYXJhbV8xNywgcGFyYW1fMTgpOwoJZmxvYXQyIHBhcmFtXzE5ID0gZGVuc2l0eV91djsKCWZsb2F0IHBhcmFtXzIwID0gdV9ub2lzZV9waGFzZV9TMV9jMDsKCWZsb2F0IHNwYXJrbGUgPSAoKEZMVF9mbHV0dGVyX2xvY2FsX3NwYXJrbGVfUzFfYzAocGFyYW1fMTksIHBhcmFtXzIwKSAqIHJpbmcpICogdHVyYnVsZW5jZSkgKiB1X3NwYXJrbGVfYWxwaGFfUzFfYzA7CglmbG9hdDIgcGFyYW1fMjEgPSBwOwoJZmxvYXQyIHBhcmFtXzIyID0gdV9jZW50ZXJfUzFfYzA7CglmbG9hdCBwYXJhbV8yMyA9IHJhZGl1czsKCWZsb2F0IHBhcmFtXzI0ID0gdV9ibHVyX1MxX2MwOwoJZmxvYXQgd2F2ZV9hbHBoYSA9IChGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X2NpcmNsZV9TMV9jMChwYXJhbV8yMSwgcGFyYW1fMjIsIHBhcmFtXzIzLCBwYXJhbV8yNCkgKiB1X2FscGhhX1MxX2MwKSAqIHVfY29sb3JfUzFfYzAudzsKCWZsb2F0NCB3YXZlX2NvbG9yID0gZmxvYXQ0KHVfY29sb3JfUzFfYzAueHl6ICogd2F2ZV9hbHBoYSwgd2F2ZV9hbHBoYSk7CglmcmFnQ29sb3JfUzFfYzAgPSBtaXgod2F2ZV9jb2xvciwgZmxvYXQ0KDEuMCksIGZsb2F0NChzcGFya2xlKSk7Cn0KaGFsZjQgcnVudGltZV9zaGFkZXJfUzFfYzAoaGFsZjQgX2lucHV0KSAKewoJaGFsZjQgX3RtcF8wX2luQ29sb3IgPSBfaW5wdXQ7CglmbG9hdDIgX3RtcF8xX2Nvb3JkcyA9IHZUcmFuc2Zvcm1lZENvb3Jkc18yX1MwOwoJZmx1dHRlcl9GcmFnQ29vcmRfUzFfYzAgPSBmbG9hdDQoX3RtcF8xX2Nvb3JkcywgMC4wLCAwLjApOwoJRkxUX21haW5fUzFfYzAoKTsKCXJldHVybiBoYWxmNChoYWxmNChmcmFnQ29sb3JfUzFfYzApKTsKfQpoYWxmNCBNYXRyaXhFZmZlY3RfUzEoaGFsZjQgX2lucHV0KSAKewoJcmV0dXJuIHJ1bnRpbWVfc2hhZGVyX1MxX2MwKF9pbnB1dCk7Cn0KaGFsZjQgUmVjdF9TMl9jMChoYWxmNCBfaW5wdXQpIAp7CgloYWxmNCBfdG1wXzJfaW5Db2xvciA9IF9pbnB1dDsKCWhhbGYgY292ZXJhZ2U7CglpZiAoaW50KDEpID09IGtGaWxsQldfUzJfYzAgfHwgaW50KDEpID09IGtJbnZlcnNlRmlsbEJXX1MyX2MwKSAKCXsKCQljb3ZlcmFnZSA9IGhhbGYoYWxsKGdyZWF0ZXJUaGFuKGZsb2F0NChza19GcmFnQ29vcmQueHksIHVyZWN0VW5pZm9ybV9TMl9jMC56dyksIGZsb2F0NCh1cmVjdFVuaWZvcm1fUzJfYzAueHksIHNrX0ZyYWdDb29yZC54eSkpKSk7Cgl9CgllbHNlIAoJewoJCWhhbGY0IGRpc3RzNCA9IHNhdHVyYXRlKGhhbGY0KDEuMCwgMS4wLCAtMS4wLCAtMS4wKSAqIGhhbGY0KHNrX0ZyYWdDb29yZC54eXh5IC0gdXJlY3RVbmlmb3JtX1MyX2MwKSk7CgkJaGFsZjIgZGlzdHMyID0gKGRpc3RzNC54eSArIGRpc3RzNC56dykgLSAxLjA7CgkJY292ZXJhZ2UgPSBkaXN0czIueCAqIGRpc3RzMi55OwoJfQoJaWYgKGludCgxKSA9PSBrSW52ZXJzZUZpbGxCV19TMl9jMCB8fCBpbnQoMSkgPT0ga0ludmVyc2VGaWxsQUFfUzJfYzApIAoJewoJCWNvdmVyYWdlID0gMS4wIC0gY292ZXJhZ2U7Cgl9CglyZXR1cm4gaGFsZjQoaGFsZjQoY292ZXJhZ2UpKTsKfQpoYWxmNCBDaXJjdWxhclJSZWN0X1MyX2MxKGhhbGY0IF9pbnB1dCkgCnsKCWZsb2F0MiBkeHkwID0gdWlubmVyUmVjdF9TMl9jMS5MVCAtIHNrX0ZyYWdDb29yZC54eTsKCWZsb2F0MiBkeHkxID0gc2tfRnJhZ0Nvb3JkLnh5IC0gdWlubmVyUmVjdF9TMl9jMS5SQjsKCWZsb2F0MiBkeHkgPSBtYXgobWF4KGR4eTAsIGR4eTEpLCAwLjApOwoJaGFsZiBhbHBoYSA9IGhhbGYoc2F0dXJhdGUodXJhZGl1c1BsdXNIYWxmX1MyX2MxLnggLSBsZW5ndGgoZHh5KSkpOwoJcmV0dXJuIF9pbnB1dCAqIGFscGhhOwp9CmhhbGY0IEJsZW5kX1MyKGhhbGY0IF9zcmMsIGhhbGY0IF9kc3QpIAp7CglyZXR1cm4gYmxlbmRfbW9kdWxhdGUoUmVjdF9TMl9jMChfc3JjKSwgQ2lyY3VsYXJSUmVjdF9TMl9jMShfc3JjKSk7Cn0Kdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJaGFsZjQgb3V0cHV0Q29sb3JfUzA7CglvdXRwdXRDb2xvcl9TMCA9IHZjb2xvcl9TMDsKCWZsb2F0IGNvdmVyYWdlID0gdmNvdmVyYWdlX1MwOwoJaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNChoYWxmKGNvdmVyYWdlKSk7CgloYWxmNCBvdXRwdXRfUzE7CglvdXRwdXRfUzEgPSBNYXRyaXhFZmZlY3RfUzEob3V0cHV0Q29sb3JfUzApOwoJaGFsZjQgb3V0cHV0X1MyOwoJb3V0cHV0X1MyID0gQmxlbmRfUzIob3V0cHV0Q292ZXJhZ2VfUzAsIGhhbGY0KDEpKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRfUzEgKiBvdXRwdXRfUzI7Cgl9Cn0KAQAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAIAAAAcG9zaXRpb24IAAAAY292ZXJhZ2UFAAAAY29sb3IAAAAKAAAAbG9jYWxDb29yZAAAAAAAAA==","HVIACAAAABQAAGAAAQ4AAAAAGQQAARC4GAAAIOCAAD6P7777777777YDAAAAAAAAAAAHQBNGZODK5YIAAAAAAQAAAAAIADCNS4GV3QYBAAAAAAAAAAAIAA6IAMAAACAAAAAABUABAAAAAEAAAAAIBEABAA":"DAAAAExTS1PZAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMTsKaW4gZmxvYXQyIHBvc2l0aW9uOwppbiBmbG9hdCBjb3ZlcmFnZTsKaW4gaGFsZjQgY29sb3I7CmluIGZsb2F0MiBsb2NhbENvb3JkOwpmbGF0IG91dCBoYWxmNCB2Y29sb3JfUzA7Cm91dCBmbG9hdCB2Y292ZXJhZ2VfUzA7Cm91dCBmbG9hdDIgdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJZmxvYXQyIHBvc2l0aW9uID0gcG9zaXRpb24ueHk7Cgl2Y29sb3JfUzAgPSBjb2xvcjsKCXZjb3ZlcmFnZV9TMCA9IGNvdmVyYWdlOwoJc2tfUG9zaXRpb24gPSBwb3NpdGlvbi54eTAxOwoJewoJCXZUcmFuc2Zvcm1lZENvb3Jkc18yX1MwID0gZmxvYXQzeDIodW1hdHJpeF9TMSkgKiBsb2NhbENvb3JkLnh5MTsKCX0KfQoAAAABAAAAWR0AAGZsb2F0NCBmbHV0dGVyX0ZyYWdDb29yZF9TMV9jMDsKZmxvYXQ0IGZyYWdDb2xvcl9TMV9jMDsKZmxvYXQgdV9hbHBoYV9TMV9jMDsKZmxvYXQgdV9zcGFya2xlX2FscGhhX1MxX2MwOwpmbG9hdCB1X2JsdXJfUzFfYzA7CmZsb2F0IHVfcmFkaXVzX3NjYWxlX1MxX2MwOwp1bmlmb3JtIGZsb2F0NCB1X2NvbG9yX1MxX2MwOwp1bmlmb3JtIGZsb2F0NCB1X2NvbXBvc2l0ZV8xX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X2NlbnRlcl9TMV9jMDsKdW5pZm9ybSBmbG9hdCB1X21heF9yYWRpdXNfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfcmVzb2x1dGlvbl9zY2FsZV9TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9ub2lzZV9zY2FsZV9TMV9jMDsKdW5pZm9ybSBmbG9hdCB1X25vaXNlX3BoYXNlX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X2NpcmNsZTFfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfY2lyY2xlMl9TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9jaXJjbGUzX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X3JvdGF0aW9uMV9TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9yb3RhdGlvbjJfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfcm90YXRpb24zX1MxX2MwOwp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzE7CnVuaWZvcm0gZmxvYXQ0IHVpbm5lclJlY3RfUzI7CnVuaWZvcm0gaGFsZjIgdXJhZGl1c1BsdXNIYWxmX1MyOwpmbGF0IGluIGhhbGY0IHZjb2xvcl9TMDsKaW4gZmxvYXQgdmNvdmVyYWdlX1MwOwppbiBmbG9hdDIgdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzA7CmZsb2F0MiBGTFRfZmx1dHRlcl9sb2NhbF9GbHV0dGVyRnJhZ0Nvb3JkX1MxX2MwKCk7CmZsb2F0MngyIEZMVF9mbHV0dGVyX2xvY2FsX3JvdGF0ZTJkX1MxX2MwKGZsb2F0MiByYWQpOwpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X2NpcmNsZV9TMV9jMChmbG9hdDIgdXYsIGZsb2F0MiB4eSwgZmxvYXQgcmFkaXVzLCBmbG9hdCBibHVyKTsKZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfY2lyY2xlX2dyaWRfUzFfYzAoZmxvYXQyIHJlc29sdXRpb24sIGlub3V0IGZsb2F0MiBwLCBmbG9hdDIgeHksIGZsb2F0MiByb3RhdGlvbiwgZmxvYXQgY2VsbF9kaWFtZXRlcik7CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3R1cmJ1bGVuY2VfUzFfYzAoZmxvYXQyIHV2KTsKZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9yaW5nX1MxX2MwKGZsb2F0MiB1diwgZmxvYXQyIHh5LCBmbG9hdCByYWRpdXMsIGZsb2F0IHRoaWNrbmVzcywgZmxvYXQgYmx1cik7CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3RyaWFuZ2xlX25vaXNlX1MxX2MwKGlub3V0IGZsb2F0MiBuKTsKZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfdGhyZXNob2xkX1MxX2MwKGZsb2F0IHYsIGZsb2F0IGwsIGZsb2F0IGgpOwpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9zcGFya2xlX1MxX2MwKGZsb2F0MiB1diwgZmxvYXQgdCk7CnZvaWQgRkxUX21haW5fUzFfYzAoKTsKZmxvYXQyIEZMVF9mbHV0dGVyX2xvY2FsX0ZsdXR0ZXJGcmFnQ29vcmRfUzFfYzAoKSAKewoJcmV0dXJuIGZsdXR0ZXJfRnJhZ0Nvb3JkX1MxX2MwLnh5Owp9CmZsb2F0MngyIEZMVF9mbHV0dGVyX2xvY2FsX3JvdGF0ZTJkX1MxX2MwKGZsb2F0MiByYWQpIAp7CglyZXR1cm4gZmxvYXQyeDIocmFkLngsIC1yYWQueSwgcmFkLnksIHJhZC54KTsKfQpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X2NpcmNsZV9TMV9jMChmbG9hdDIgdXYsIGZsb2F0MiB4eSwgZmxvYXQgcmFkaXVzLCBmbG9hdCBibHVyKSAKewoJZmxvYXQgYmx1cl9oYWxmID0gYmx1ciAqIDAuNTsKCWZsb2F0IGQgPSBkaXN0YW5jZSh1diwgeHkpOwoJcmV0dXJuIDEuMCAtIHNtb290aHN0ZXAoMS4wIC0gYmx1cl9oYWxmLCAxLjAgKyBibHVyX2hhbGYsIGQgLyByYWRpdXMpOwp9CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX2NpcmNsZV9ncmlkX1MxX2MwKGZsb2F0MiByZXNvbHV0aW9uLCBpbm91dCBmbG9hdDIgcCwgZmxvYXQyIHh5LCBmbG9hdDIgcm90YXRpb24sIGZsb2F0IGNlbGxfZGlhbWV0ZXIpIAp7CglmbG9hdDIgcGFyYW0gPSByb3RhdGlvbjsKCXAgPSBGTFRfZmx1dHRlcl9sb2NhbF9yb3RhdGUyZF9TMV9jMChwYXJhbSkgKiAoeHkgLSBwKSArIHh5OwoJcCA9IG1vZChwLCBmbG9hdDIoY2VsbF9kaWFtZXRlcikpIC8gcmVzb2x1dGlvbjsKCWZsb2F0IGNlbGxfdXYgPSAoY2VsbF9kaWFtZXRlciAvIHJlc29sdXRpb24ueSkgKiAwLjU7CglmbG9hdCByID0gMC42NSAqIGNlbGxfdXY7CglmbG9hdDIgcGFyYW1fMSA9IHA7CglmbG9hdDIgcGFyYW1fMiA9IGZsb2F0MihjZWxsX3V2KTsKCWZsb2F0IHBhcmFtXzMgPSByOwoJZmxvYXQgcGFyYW1fNCA9IHIgKiA1MC4wOwoJcmV0dXJuIEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfY2lyY2xlX1MxX2MwKHBhcmFtXzEsIHBhcmFtXzIsIHBhcmFtXzMsIHBhcmFtXzQpOwp9CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3R1cmJ1bGVuY2VfUzFfYzAoZmxvYXQyIHV2KSAKewoJZmxvYXQyIHV2X3NjYWxlID0gdXYgKiBmbG9hdDIoMC44KTsKCWZsb2F0MiBwYXJhbSA9IGZsb2F0MigwLjgpOwoJZmxvYXQyIHBhcmFtXzEgPSB1dl9zY2FsZTsKCWZsb2F0MiBwYXJhbV8yID0gdV9jaXJjbGUxX1MxX2MwOwoJZmxvYXQyIHBhcmFtXzMgPSB1X3JvdGF0aW9uMV9TMV9jMDsKCWZsb2F0IHBhcmFtXzQgPSAwLjE3OwoJZmxvYXQgXzMxOSA9IEZMVF9mbHV0dGVyX2xvY2FsX2NpcmNsZV9ncmlkX1MxX2MwKHBhcmFtLCBwYXJhbV8xLCBwYXJhbV8yLCBwYXJhbV8zLCBwYXJhbV80KTsKCWZsb2F0IGcxID0gXzMxOTsKCWZsb2F0MiBwYXJhbV81ID0gZmxvYXQyKDAuOCk7CglmbG9hdDIgcGFyYW1fNiA9IHV2X3NjYWxlOwoJZmxvYXQyIHBhcmFtXzcgPSB1X2NpcmNsZTJfUzFfYzA7CglmbG9hdDIgcGFyYW1fOCA9IHVfcm90YXRpb24yX1MxX2MwOwoJZmxvYXQgcGFyYW1fOSA9IDAuMjsKCWZsb2F0IF8zMzEgPSBGTFRfZmx1dHRlcl9sb2NhbF9jaXJjbGVfZ3JpZF9TMV9jMChwYXJhbV81LCBwYXJhbV82LCBwYXJhbV83LCBwYXJhbV84LCBwYXJhbV85KTsKCWZsb2F0IGcyID0gXzMzMTsKCWZsb2F0MiBwYXJhbV8xMCA9IGZsb2F0MigwLjgpOwoJZmxvYXQyIHBhcmFtXzExID0gdXZfc2NhbGU7CglmbG9hdDIgcGFyYW1fMTIgPSB1X2NpcmNsZTNfUzFfYzA7CglmbG9hdDIgcGFyYW1fMTMgPSB1X3JvdGF0aW9uM19TMV9jMDsKCWZsb2F0IHBhcmFtXzE0ID0gMC4yNzU7CglmbG9hdCBfMzQ0ID0gRkxUX2ZsdXR0ZXJfbG9jYWxfY2lyY2xlX2dyaWRfUzFfYzAocGFyYW1fMTAsIHBhcmFtXzExLCBwYXJhbV8xMiwgcGFyYW1fMTMsIHBhcmFtXzE0KTsKCWZsb2F0IGczID0gXzM0NDsKCWZsb2F0IHYgPSAoKGcxICogZzEgKyBnMikgLSBnMykgKiAwLjU7CglyZXR1cm4gY2xhbXAoMC40NSArIDAuOCAqIHYsIDAuMCwgMS4wKTsKfQpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X3JpbmdfUzFfYzAoZmxvYXQyIHV2LCBmbG9hdDIgeHksIGZsb2F0IHJhZGl1cywgZmxvYXQgdGhpY2tuZXNzLCBmbG9hdCBibHVyKSAKewoJZmxvYXQyIHBhcmFtID0gdXY7CglmbG9hdDIgcGFyYW1fMSA9IHh5OwoJZmxvYXQgcGFyYW1fMiA9IHJhZGl1cyArIHRoaWNrbmVzczsKCWZsb2F0IHBhcmFtXzMgPSBibHVyOwoJZmxvYXQgY2lyY2xlX291dGVyID0gRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9jaXJjbGVfUzFfYzAocGFyYW0sIHBhcmFtXzEsIHBhcmFtXzIsIHBhcmFtXzMpOwoJZmxvYXQyIHBhcmFtXzQgPSB1djsKCWZsb2F0MiBwYXJhbV81ID0geHk7CglmbG9hdCBwYXJhbV82ID0gbWF4KHJhZGl1cyAtIHRoaWNrbmVzcywgMC4wKTsKCWZsb2F0IHBhcmFtXzcgPSBibHVyOwoJZmxvYXQgY2lyY2xlX2lubmVyID0gRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9jaXJjbGVfUzFfYzAocGFyYW1fNCwgcGFyYW1fNSwgcGFyYW1fNiwgcGFyYW1fNyk7CglyZXR1cm4gY2xhbXAoY2lyY2xlX291dGVyIC0gY2lyY2xlX2lubmVyLCAwLjAsIDEuMCk7Cn0KZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfdHJpYW5nbGVfbm9pc2VfUzFfYzAoaW5vdXQgZmxvYXQyIG4pIAp7CgluID0gZnJhY3QobiAqIGZsb2F0Mig1LjM5ODcsIDUuNDQyMSkpOwoJbiArPSBmbG9hdDIoZG90KG4ueXgsIG4gKyBmbG9hdDIoMjEuNTM1MSwgMTQuMzEzNykpKTsKCWZsb2F0IHh5ID0gbi54ICogbi55OwoJcmV0dXJuIChmcmFjdCh4eSAqIDk1LjQzMDcpICsgZnJhY3QoeHkgKiA3NS4wNDk2MSkpIC0gMS4wOwp9CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3RocmVzaG9sZF9TMV9jMChmbG9hdCB2LCBmbG9hdCBsLCBmbG9hdCBoKSAKewoJcmV0dXJuIHN0ZXAobCwgdikgKiAoMS4wIC0gc3RlcChoLCB2KSk7Cn0KZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfc3BhcmtsZV9TMV9jMChmbG9hdDIgdXYsIGZsb2F0IHQpIAp7CglmbG9hdDIgcGFyYW0gPSB1djsKCWZsb2F0IF8yNDIgPSBGTFRfZmx1dHRlcl9sb2NhbF90cmlhbmdsZV9ub2lzZV9TMV9jMChwYXJhbSk7CglmbG9hdCBuID0gXzI0MjsKCWZsb2F0IHBhcmFtXzEgPSBuOwoJZmxvYXQgcGFyYW1fMiA9IDAuMDsKCWZsb2F0IHBhcmFtXzMgPSAwLjA1OwoJZmxvYXQgcyA9IEZMVF9mbHV0dGVyX2xvY2FsX3RocmVzaG9sZF9TMV9jMChwYXJhbV8xLCBwYXJhbV8yLCBwYXJhbV8zKTsKCWZsb2F0IHBhcmFtXzQgPSBuICsgc2luKDMuMTQxNTkyNzQgKiAodCArIDAuMzUpKTsKCWZsb2F0IHBhcmFtXzUgPSAwLjE7CglmbG9hdCBwYXJhbV82ID0gMC4xNTsKCXMgKz0gRkxUX2ZsdXR0ZXJfbG9jYWxfdGhyZXNob2xkX1MxX2MwKHBhcmFtXzQsIHBhcmFtXzUsIHBhcmFtXzYpOwoJZmxvYXQgcGFyYW1fNyA9IG4gKyBzaW4oMy4xNDE1OTI3NCAqICh0ICsgMC43KSk7CglmbG9hdCBwYXJhbV84ID0gMC4yOwoJZmxvYXQgcGFyYW1fOSA9IDAuMjU7CglzICs9IEZMVF9mbHV0dGVyX2xvY2FsX3RocmVzaG9sZF9TMV9jMChwYXJhbV83LCBwYXJhbV84LCBwYXJhbV85KTsKCWZsb2F0IHBhcmFtXzEwID0gbiArIHNpbigzLjE0MTU5Mjc0ICogKHQgKyAxLjA1KSk7CglmbG9hdCBwYXJhbV8xMSA9IDAuMzsKCWZsb2F0IHBhcmFtXzEyID0gMC4zNTsKCXMgKz0gRkxUX2ZsdXR0ZXJfbG9jYWxfdGhyZXNob2xkX1MxX2MwKHBhcmFtXzEwLCBwYXJhbV8xMSwgcGFyYW1fMTIpOwoJcmV0dXJuIGNsYW1wKHMsIDAuMCwgMS4wKSAqIDAuNTU7Cn0Kdm9pZCBGTFRfbWFpbl9TMV9jMCgpIAp7Cgl1X2FscGhhX1MxX2MwID0gdV9jb21wb3NpdGVfMV9TMV9jMC54OwoJdV9zcGFya2xlX2FscGhhX1MxX2MwID0gdV9jb21wb3NpdGVfMV9TMV9jMC55OwoJdV9ibHVyX1MxX2MwID0gdV9jb21wb3NpdGVfMV9TMV9jMC56OwoJdV9yYWRpdXNfc2NhbGVfUzFfYzAgPSB1X2NvbXBvc2l0ZV8xX1MxX2MwLnc7CglmbG9hdDIgcCA9IEZMVF9mbHV0dGVyX2xvY2FsX0ZsdXR0ZXJGcmFnQ29vcmRfUzFfYzAoKTsKCWZsb2F0MiB1dl8xID0gcCAqIHVfcmVzb2x1dGlvbl9zY2FsZV9TMV9jMDsKCWZsb2F0MiBkZW5zaXR5X3V2ID0gdXZfMSAtIG1vZChwLCB1X25vaXNlX3NjYWxlX1MxX2MwKTsKCWZsb2F0IHJhZGl1cyA9IHVfbWF4X3JhZGl1c19TMV9jMCAqIHVfcmFkaXVzX3NjYWxlX1MxX2MwOwoJZmxvYXQyIHBhcmFtXzEzID0gdXZfMTsKCWZsb2F0IHR1cmJ1bGVuY2UgPSBGTFRfZmx1dHRlcl9sb2NhbF90dXJidWxlbmNlX1MxX2MwKHBhcmFtXzEzKTsKCWZsb2F0MiBwYXJhbV8xNCA9IHA7CglmbG9hdDIgcGFyYW1fMTUgPSB1X2NlbnRlcl9TMV9jMDsKCWZsb2F0IHBhcmFtXzE2ID0gcmFkaXVzOwoJZmxvYXQgcGFyYW1fMTcgPSAwLjA1ICogdV9tYXhfcmFkaXVzX1MxX2MwOwoJZmxvYXQgcGFyYW1fMTggPSB1X2JsdXJfUzFfYzA7CglmbG9hdCByaW5nID0gRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9yaW5nX1MxX2MwKHBhcmFtXzE0LCBwYXJhbV8xNSwgcGFyYW1fMTYsIHBhcmFtXzE3LCBwYXJhbV8xOCk7CglmbG9hdDIgcGFyYW1fMTkgPSBkZW5zaXR5X3V2OwoJZmxvYXQgcGFyYW1fMjAgPSB1X25vaXNlX3BoYXNlX1MxX2MwOwoJZmxvYXQgc3BhcmtsZSA9ICgoRkxUX2ZsdXR0ZXJfbG9jYWxfc3BhcmtsZV9TMV9jMChwYXJhbV8xOSwgcGFyYW1fMjApICogcmluZykgKiB0dXJidWxlbmNlKSAqIHVfc3BhcmtsZV9hbHBoYV9TMV9jMDsKCWZsb2F0MiBwYXJhbV8yMSA9IHA7CglmbG9hdDIgcGFyYW1fMjIgPSB1X2NlbnRlcl9TMV9jMDsKCWZsb2F0IHBhcmFtXzIzID0gcmFkaXVzOwoJZmxvYXQgcGFyYW1fMjQgPSB1X2JsdXJfUzFfYzA7CglmbG9hdCB3YXZlX2FscGhhID0gKEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfY2lyY2xlX1MxX2MwKHBhcmFtXzIxLCBwYXJhbV8yMiwgcGFyYW1fMjMsIHBhcmFtXzI0KSAqIHVfYWxwaGFfUzFfYzApICogdV9jb2xvcl9TMV9jMC53OwoJZmxvYXQ0IHdhdmVfY29sb3IgPSBmbG9hdDQodV9jb2xvcl9TMV9jMC54eXogKiB3YXZlX2FscGhhLCB3YXZlX2FscGhhKTsKCWZyYWdDb2xvcl9TMV9jMCA9IG1peCh3YXZlX2NvbG9yLCBmbG9hdDQoMS4wKSwgZmxvYXQ0KHNwYXJrbGUpKTsKfQpoYWxmNCBydW50aW1lX3NoYWRlcl9TMV9jMChoYWxmNCBfaW5wdXQpIAp7CgloYWxmNCBfdG1wXzBfaW5Db2xvciA9IF9pbnB1dDsKCWZsb2F0MiBfdG1wXzFfY29vcmRzID0gdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzA7CglmbHV0dGVyX0ZyYWdDb29yZF9TMV9jMCA9IGZsb2F0NChfdG1wXzFfY29vcmRzLCAwLjAsIDAuMCk7CglGTFRfbWFpbl9TMV9jMCgpOwoJcmV0dXJuIGhhbGY0KGhhbGY0KGZyYWdDb2xvcl9TMV9jMCkpOwp9CmhhbGY0IE1hdHJpeEVmZmVjdF9TMShoYWxmNCBfaW5wdXQpIAp7CglyZXR1cm4gcnVudGltZV9zaGFkZXJfUzFfYzAoX2lucHV0KTsKfQpoYWxmNCBDaXJjdWxhclJSZWN0X1MyKGhhbGY0IF9pbnB1dCkgCnsKCWZsb2F0MiBkeHkwID0gdWlubmVyUmVjdF9TMi5MVCAtIHNrX0ZyYWdDb29yZC54eTsKCWZsb2F0MiBkeHkxID0gc2tfRnJhZ0Nvb3JkLnh5IC0gdWlubmVyUmVjdF9TMi5SQjsKCWZsb2F0MiBkeHkgPSBtYXgobWF4KGR4eTAsIGR4eTEpLCAwLjApOwoJaGFsZiBhbHBoYSA9IGhhbGYoc2F0dXJhdGUodXJhZGl1c1BsdXNIYWxmX1MyLnggLSBsZW5ndGgoZHh5KSkpOwoJcmV0dXJuIF9pbnB1dCAqIGFscGhhOwp9CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2Y29sb3JfUzA7CglmbG9hdCBjb3ZlcmFnZSA9IHZjb3ZlcmFnZV9TMDsKCWhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoaGFsZihjb3ZlcmFnZSkpOwoJaGFsZjQgb3V0cHV0X1MxOwoJb3V0cHV0X1MxID0gTWF0cml4RWZmZWN0X1MxKG91dHB1dENvbG9yX1MwKTsKCWhhbGY0IG91dHB1dF9TMjsKCW91dHB1dF9TMiA9IENpcmN1bGFyUlJlY3RfUzIob3V0cHV0Q292ZXJhZ2VfUzApOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dF9TMSAqIG91dHB1dF9TMjsKCX0KfQoAAAABAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAgAAABwb3NpdGlvbggAAABjb3ZlcmFnZQUAAABjb2xvcgAAAAoAAABsb2NhbENvb3JkAAAAAAAA","HVIACAAAABQAAGAAAQ4AAAAAGQQAARC4GAAAIOCAAD6P7777777777YDAAAAAAAAAAAHQBNGZODK5YIAAAAAAQAAAAAIADCNS4GV3QYBAAAAAAAAAAAIAA4IAEAAACAAAAAABUABAAAAAEAAAAAIBEABAA":"DAAAAExTS1PZAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMTsKaW4gZmxvYXQyIHBvc2l0aW9uOwppbiBmbG9hdCBjb3ZlcmFnZTsKaW4gaGFsZjQgY29sb3I7CmluIGZsb2F0MiBsb2NhbENvb3JkOwpmbGF0IG91dCBoYWxmNCB2Y29sb3JfUzA7Cm91dCBmbG9hdCB2Y292ZXJhZ2VfUzA7Cm91dCBmbG9hdDIgdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJZmxvYXQyIHBvc2l0aW9uID0gcG9zaXRpb24ueHk7Cgl2Y29sb3JfUzAgPSBjb2xvcjsKCXZjb3ZlcmFnZV9TMCA9IGNvdmVyYWdlOwoJc2tfUG9zaXRpb24gPSBwb3NpdGlvbi54eTAxOwoJewoJCXZUcmFuc2Zvcm1lZENvb3Jkc18yX1MwID0gZmxvYXQzeDIodW1hdHJpeF9TMSkgKiBsb2NhbENvb3JkLnh5MTsKCX0KfQoAAAABAAAAth0AAGZsb2F0NCBmbHV0dGVyX0ZyYWdDb29yZF9TMV9jMDsKZmxvYXQ0IGZyYWdDb2xvcl9TMV9jMDsKZmxvYXQgdV9hbHBoYV9TMV9jMDsKZmxvYXQgdV9zcGFya2xlX2FscGhhX1MxX2MwOwpmbG9hdCB1X2JsdXJfUzFfYzA7CmZsb2F0IHVfcmFkaXVzX3NjYWxlX1MxX2MwOwp1bmlmb3JtIGZsb2F0NCB1X2NvbG9yX1MxX2MwOwp1bmlmb3JtIGZsb2F0NCB1X2NvbXBvc2l0ZV8xX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X2NlbnRlcl9TMV9jMDsKdW5pZm9ybSBmbG9hdCB1X21heF9yYWRpdXNfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfcmVzb2x1dGlvbl9zY2FsZV9TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9ub2lzZV9zY2FsZV9TMV9jMDsKdW5pZm9ybSBmbG9hdCB1X25vaXNlX3BoYXNlX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X2NpcmNsZTFfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfY2lyY2xlMl9TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9jaXJjbGUzX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X3JvdGF0aW9uMV9TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9yb3RhdGlvbjJfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfcm90YXRpb24zX1MxX2MwOwp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzE7CnVuaWZvcm0gZmxvYXQ0IHVpbm5lclJlY3RfUzI7CnVuaWZvcm0gaGFsZjIgdXJhZGl1c1BsdXNIYWxmX1MyOwpmbGF0IGluIGhhbGY0IHZjb2xvcl9TMDsKaW4gZmxvYXQgdmNvdmVyYWdlX1MwOwppbiBmbG9hdDIgdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzA7CmZsb2F0MiBGTFRfZmx1dHRlcl9sb2NhbF9GbHV0dGVyRnJhZ0Nvb3JkX1MxX2MwKCk7CmZsb2F0MngyIEZMVF9mbHV0dGVyX2xvY2FsX3JvdGF0ZTJkX1MxX2MwKGZsb2F0MiByYWQpOwpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X2NpcmNsZV9TMV9jMChmbG9hdDIgdXYsIGZsb2F0MiB4eSwgZmxvYXQgcmFkaXVzLCBmbG9hdCBibHVyKTsKZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfY2lyY2xlX2dyaWRfUzFfYzAoZmxvYXQyIHJlc29sdXRpb24sIGlub3V0IGZsb2F0MiBwLCBmbG9hdDIgeHksIGZsb2F0MiByb3RhdGlvbiwgZmxvYXQgY2VsbF9kaWFtZXRlcik7CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3R1cmJ1bGVuY2VfUzFfYzAoZmxvYXQyIHV2KTsKZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9yaW5nX1MxX2MwKGZsb2F0MiB1diwgZmxvYXQyIHh5LCBmbG9hdCByYWRpdXMsIGZsb2F0IHRoaWNrbmVzcywgZmxvYXQgYmx1cik7CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3RyaWFuZ2xlX25vaXNlX1MxX2MwKGlub3V0IGZsb2F0MiBuKTsKZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfdGhyZXNob2xkX1MxX2MwKGZsb2F0IHYsIGZsb2F0IGwsIGZsb2F0IGgpOwpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9zcGFya2xlX1MxX2MwKGZsb2F0MiB1diwgZmxvYXQgdCk7CnZvaWQgRkxUX21haW5fUzFfYzAoKTsKZmxvYXQyIEZMVF9mbHV0dGVyX2xvY2FsX0ZsdXR0ZXJGcmFnQ29vcmRfUzFfYzAoKSAKewoJcmV0dXJuIGZsdXR0ZXJfRnJhZ0Nvb3JkX1MxX2MwLnh5Owp9CmZsb2F0MngyIEZMVF9mbHV0dGVyX2xvY2FsX3JvdGF0ZTJkX1MxX2MwKGZsb2F0MiByYWQpIAp7CglyZXR1cm4gZmxvYXQyeDIocmFkLngsIC1yYWQueSwgcmFkLnksIHJhZC54KTsKfQpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X2NpcmNsZV9TMV9jMChmbG9hdDIgdXYsIGZsb2F0MiB4eSwgZmxvYXQgcmFkaXVzLCBmbG9hdCBibHVyKSAKewoJZmxvYXQgYmx1cl9oYWxmID0gYmx1ciAqIDAuNTsKCWZsb2F0IGQgPSBkaXN0YW5jZSh1diwgeHkpOwoJcmV0dXJuIDEuMCAtIHNtb290aHN0ZXAoMS4wIC0gYmx1cl9oYWxmLCAxLjAgKyBibHVyX2hhbGYsIGQgLyByYWRpdXMpOwp9CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX2NpcmNsZV9ncmlkX1MxX2MwKGZsb2F0MiByZXNvbHV0aW9uLCBpbm91dCBmbG9hdDIgcCwgZmxvYXQyIHh5LCBmbG9hdDIgcm90YXRpb24sIGZsb2F0IGNlbGxfZGlhbWV0ZXIpIAp7CglmbG9hdDIgcGFyYW0gPSByb3RhdGlvbjsKCXAgPSBGTFRfZmx1dHRlcl9sb2NhbF9yb3RhdGUyZF9TMV9jMChwYXJhbSkgKiAoeHkgLSBwKSArIHh5OwoJcCA9IG1vZChwLCBmbG9hdDIoY2VsbF9kaWFtZXRlcikpIC8gcmVzb2x1dGlvbjsKCWZsb2F0IGNlbGxfdXYgPSAoY2VsbF9kaWFtZXRlciAvIHJlc29sdXRpb24ueSkgKiAwLjU7CglmbG9hdCByID0gMC42NSAqIGNlbGxfdXY7CglmbG9hdDIgcGFyYW1fMSA9IHA7CglmbG9hdDIgcGFyYW1fMiA9IGZsb2F0MihjZWxsX3V2KTsKCWZsb2F0IHBhcmFtXzMgPSByOwoJZmxvYXQgcGFyYW1fNCA9IHIgKiA1MC4wOwoJcmV0dXJuIEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfY2lyY2xlX1MxX2MwKHBhcmFtXzEsIHBhcmFtXzIsIHBhcmFtXzMsIHBhcmFtXzQpOwp9CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3R1cmJ1bGVuY2VfUzFfYzAoZmxvYXQyIHV2KSAKewoJZmxvYXQyIHV2X3NjYWxlID0gdXYgKiBmbG9hdDIoMC44KTsKCWZsb2F0MiBwYXJhbSA9IGZsb2F0MigwLjgpOwoJZmxvYXQyIHBhcmFtXzEgPSB1dl9zY2FsZTsKCWZsb2F0MiBwYXJhbV8yID0gdV9jaXJjbGUxX1MxX2MwOwoJZmxvYXQyIHBhcmFtXzMgPSB1X3JvdGF0aW9uMV9TMV9jMDsKCWZsb2F0IHBhcmFtXzQgPSAwLjE3OwoJZmxvYXQgXzMxOSA9IEZMVF9mbHV0dGVyX2xvY2FsX2NpcmNsZV9ncmlkX1MxX2MwKHBhcmFtLCBwYXJhbV8xLCBwYXJhbV8yLCBwYXJhbV8zLCBwYXJhbV80KTsKCWZsb2F0IGcxID0gXzMxOTsKCWZsb2F0MiBwYXJhbV81ID0gZmxvYXQyKDAuOCk7CglmbG9hdDIgcGFyYW1fNiA9IHV2X3NjYWxlOwoJZmxvYXQyIHBhcmFtXzcgPSB1X2NpcmNsZTJfUzFfYzA7CglmbG9hdDIgcGFyYW1fOCA9IHVfcm90YXRpb24yX1MxX2MwOwoJZmxvYXQgcGFyYW1fOSA9IDAuMjsKCWZsb2F0IF8zMzEgPSBGTFRfZmx1dHRlcl9sb2NhbF9jaXJjbGVfZ3JpZF9TMV9jMChwYXJhbV81LCBwYXJhbV82LCBwYXJhbV83LCBwYXJhbV84LCBwYXJhbV85KTsKCWZsb2F0IGcyID0gXzMzMTsKCWZsb2F0MiBwYXJhbV8xMCA9IGZsb2F0MigwLjgpOwoJZmxvYXQyIHBhcmFtXzExID0gdXZfc2NhbGU7CglmbG9hdDIgcGFyYW1fMTIgPSB1X2NpcmNsZTNfUzFfYzA7CglmbG9hdDIgcGFyYW1fMTMgPSB1X3JvdGF0aW9uM19TMV9jMDsKCWZsb2F0IHBhcmFtXzE0ID0gMC4yNzU7CglmbG9hdCBfMzQ0ID0gRkxUX2ZsdXR0ZXJfbG9jYWxfY2lyY2xlX2dyaWRfUzFfYzAocGFyYW1fMTAsIHBhcmFtXzExLCBwYXJhbV8xMiwgcGFyYW1fMTMsIHBhcmFtXzE0KTsKCWZsb2F0IGczID0gXzM0NDsKCWZsb2F0IHYgPSAoKGcxICogZzEgKyBnMikgLSBnMykgKiAwLjU7CglyZXR1cm4gY2xhbXAoMC40NSArIDAuOCAqIHYsIDAuMCwgMS4wKTsKfQpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X3JpbmdfUzFfYzAoZmxvYXQyIHV2LCBmbG9hdDIgeHksIGZsb2F0IHJhZGl1cywgZmxvYXQgdGhpY2tuZXNzLCBmbG9hdCBibHVyKSAKewoJZmxvYXQyIHBhcmFtID0gdXY7CglmbG9hdDIgcGFyYW1fMSA9IHh5OwoJZmxvYXQgcGFyYW1fMiA9IHJhZGl1cyArIHRoaWNrbmVzczsKCWZsb2F0IHBhcmFtXzMgPSBibHVyOwoJZmxvYXQgY2lyY2xlX291dGVyID0gRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9jaXJjbGVfUzFfYzAocGFyYW0sIHBhcmFtXzEsIHBhcmFtXzIsIHBhcmFtXzMpOwoJZmxvYXQyIHBhcmFtXzQgPSB1djsKCWZsb2F0MiBwYXJhbV81ID0geHk7CglmbG9hdCBwYXJhbV82ID0gbWF4KHJhZGl1cyAtIHRoaWNrbmVzcywgMC4wKTsKCWZsb2F0IHBhcmFtXzcgPSBibHVyOwoJZmxvYXQgY2lyY2xlX2lubmVyID0gRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9jaXJjbGVfUzFfYzAocGFyYW1fNCwgcGFyYW1fNSwgcGFyYW1fNiwgcGFyYW1fNyk7CglyZXR1cm4gY2xhbXAoY2lyY2xlX291dGVyIC0gY2lyY2xlX2lubmVyLCAwLjAsIDEuMCk7Cn0KZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfdHJpYW5nbGVfbm9pc2VfUzFfYzAoaW5vdXQgZmxvYXQyIG4pIAp7CgluID0gZnJhY3QobiAqIGZsb2F0Mig1LjM5ODcsIDUuNDQyMSkpOwoJbiArPSBmbG9hdDIoZG90KG4ueXgsIG4gKyBmbG9hdDIoMjEuNTM1MSwgMTQuMzEzNykpKTsKCWZsb2F0IHh5ID0gbi54ICogbi55OwoJcmV0dXJuIChmcmFjdCh4eSAqIDk1LjQzMDcpICsgZnJhY3QoeHkgKiA3NS4wNDk2MSkpIC0gMS4wOwp9CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3RocmVzaG9sZF9TMV9jMChmbG9hdCB2LCBmbG9hdCBsLCBmbG9hdCBoKSAKewoJcmV0dXJuIHN0ZXAobCwgdikgKiAoMS4wIC0gc3RlcChoLCB2KSk7Cn0KZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfc3BhcmtsZV9TMV9jMChmbG9hdDIgdXYsIGZsb2F0IHQpIAp7CglmbG9hdDIgcGFyYW0gPSB1djsKCWZsb2F0IF8yNDIgPSBGTFRfZmx1dHRlcl9sb2NhbF90cmlhbmdsZV9ub2lzZV9TMV9jMChwYXJhbSk7CglmbG9hdCBuID0gXzI0MjsKCWZsb2F0IHBhcmFtXzEgPSBuOwoJZmxvYXQgcGFyYW1fMiA9IDAuMDsKCWZsb2F0IHBhcmFtXzMgPSAwLjA1OwoJZmxvYXQgcyA9IEZMVF9mbHV0dGVyX2xvY2FsX3RocmVzaG9sZF9TMV9jMChwYXJhbV8xLCBwYXJhbV8yLCBwYXJhbV8zKTsKCWZsb2F0IHBhcmFtXzQgPSBuICsgc2luKDMuMTQxNTkyNzQgKiAodCArIDAuMzUpKTsKCWZsb2F0IHBhcmFtXzUgPSAwLjE7CglmbG9hdCBwYXJhbV82ID0gMC4xNTsKCXMgKz0gRkxUX2ZsdXR0ZXJfbG9jYWxfdGhyZXNob2xkX1MxX2MwKHBhcmFtXzQsIHBhcmFtXzUsIHBhcmFtXzYpOwoJZmxvYXQgcGFyYW1fNyA9IG4gKyBzaW4oMy4xNDE1OTI3NCAqICh0ICsgMC43KSk7CglmbG9hdCBwYXJhbV84ID0gMC4yOwoJZmxvYXQgcGFyYW1fOSA9IDAuMjU7CglzICs9IEZMVF9mbHV0dGVyX2xvY2FsX3RocmVzaG9sZF9TMV9jMChwYXJhbV83LCBwYXJhbV84LCBwYXJhbV85KTsKCWZsb2F0IHBhcmFtXzEwID0gbiArIHNpbigzLjE0MTU5Mjc0ICogKHQgKyAxLjA1KSk7CglmbG9hdCBwYXJhbV8xMSA9IDAuMzsKCWZsb2F0IHBhcmFtXzEyID0gMC4zNTsKCXMgKz0gRkxUX2ZsdXR0ZXJfbG9jYWxfdGhyZXNob2xkX1MxX2MwKHBhcmFtXzEwLCBwYXJhbV8xMSwgcGFyYW1fMTIpOwoJcmV0dXJuIGNsYW1wKHMsIDAuMCwgMS4wKSAqIDAuNTU7Cn0Kdm9pZCBGTFRfbWFpbl9TMV9jMCgpIAp7Cgl1X2FscGhhX1MxX2MwID0gdV9jb21wb3NpdGVfMV9TMV9jMC54OwoJdV9zcGFya2xlX2FscGhhX1MxX2MwID0gdV9jb21wb3NpdGVfMV9TMV9jMC55OwoJdV9ibHVyX1MxX2MwID0gdV9jb21wb3NpdGVfMV9TMV9jMC56OwoJdV9yYWRpdXNfc2NhbGVfUzFfYzAgPSB1X2NvbXBvc2l0ZV8xX1MxX2MwLnc7CglmbG9hdDIgcCA9IEZMVF9mbHV0dGVyX2xvY2FsX0ZsdXR0ZXJGcmFnQ29vcmRfUzFfYzAoKTsKCWZsb2F0MiB1dl8xID0gcCAqIHVfcmVzb2x1dGlvbl9zY2FsZV9TMV9jMDsKCWZsb2F0MiBkZW5zaXR5X3V2ID0gdXZfMSAtIG1vZChwLCB1X25vaXNlX3NjYWxlX1MxX2MwKTsKCWZsb2F0IHJhZGl1cyA9IHVfbWF4X3JhZGl1c19TMV9jMCAqIHVfcmFkaXVzX3NjYWxlX1MxX2MwOwoJZmxvYXQyIHBhcmFtXzEzID0gdXZfMTsKCWZsb2F0IHR1cmJ1bGVuY2UgPSBGTFRfZmx1dHRlcl9sb2NhbF90dXJidWxlbmNlX1MxX2MwKHBhcmFtXzEzKTsKCWZsb2F0MiBwYXJhbV8xNCA9IHA7CglmbG9hdDIgcGFyYW1fMTUgPSB1X2NlbnRlcl9TMV9jMDsKCWZsb2F0IHBhcmFtXzE2ID0gcmFkaXVzOwoJZmxvYXQgcGFyYW1fMTcgPSAwLjA1ICogdV9tYXhfcmFkaXVzX1MxX2MwOwoJZmxvYXQgcGFyYW1fMTggPSB1X2JsdXJfUzFfYzA7CglmbG9hdCByaW5nID0gRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9yaW5nX1MxX2MwKHBhcmFtXzE0LCBwYXJhbV8xNSwgcGFyYW1fMTYsIHBhcmFtXzE3LCBwYXJhbV8xOCk7CglmbG9hdDIgcGFyYW1fMTkgPSBkZW5zaXR5X3V2OwoJZmxvYXQgcGFyYW1fMjAgPSB1X25vaXNlX3BoYXNlX1MxX2MwOwoJZmxvYXQgc3BhcmtsZSA9ICgoRkxUX2ZsdXR0ZXJfbG9jYWxfc3BhcmtsZV9TMV9jMChwYXJhbV8xOSwgcGFyYW1fMjApICogcmluZykgKiB0dXJidWxlbmNlKSAqIHVfc3BhcmtsZV9hbHBoYV9TMV9jMDsKCWZsb2F0MiBwYXJhbV8yMSA9IHA7CglmbG9hdDIgcGFyYW1fMjIgPSB1X2NlbnRlcl9TMV9jMDsKCWZsb2F0IHBhcmFtXzIzID0gcmFkaXVzOwoJZmxvYXQgcGFyYW1fMjQgPSB1X2JsdXJfUzFfYzA7CglmbG9hdCB3YXZlX2FscGhhID0gKEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfY2lyY2xlX1MxX2MwKHBhcmFtXzIxLCBwYXJhbV8yMiwgcGFyYW1fMjMsIHBhcmFtXzI0KSAqIHVfYWxwaGFfUzFfYzApICogdV9jb2xvcl9TMV9jMC53OwoJZmxvYXQ0IHdhdmVfY29sb3IgPSBmbG9hdDQodV9jb2xvcl9TMV9jMC54eXogKiB3YXZlX2FscGhhLCB3YXZlX2FscGhhKTsKCWZyYWdDb2xvcl9TMV9jMCA9IG1peCh3YXZlX2NvbG9yLCBmbG9hdDQoMS4wKSwgZmxvYXQ0KHNwYXJrbGUpKTsKfQpoYWxmNCBydW50aW1lX3NoYWRlcl9TMV9jMChoYWxmNCBfaW5wdXQpIAp7CgloYWxmNCBfdG1wXzBfaW5Db2xvciA9IF9pbnB1dDsKCWZsb2F0MiBfdG1wXzFfY29vcmRzID0gdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzA7CglmbHV0dGVyX0ZyYWdDb29yZF9TMV9jMCA9IGZsb2F0NChfdG1wXzFfY29vcmRzLCAwLjAsIDAuMCk7CglGTFRfbWFpbl9TMV9jMCgpOwoJcmV0dXJuIGhhbGY0KGhhbGY0KGZyYWdDb2xvcl9TMV9jMCkpOwp9CmhhbGY0IE1hdHJpeEVmZmVjdF9TMShoYWxmNCBfaW5wdXQpIAp7CglyZXR1cm4gcnVudGltZV9zaGFkZXJfUzFfYzAoX2lucHV0KTsKfQpoYWxmNCBDaXJjdWxhclJSZWN0X1MyKGhhbGY0IF9pbnB1dCkgCnsKCWZsb2F0IGR5MCA9IHVpbm5lclJlY3RfUzIuVCAtIHNrX0ZyYWdDb29yZC55OwoJZmxvYXQyIGR4eTEgPSBza19GcmFnQ29vcmQueHkgLSB1aW5uZXJSZWN0X1MyLlJCOwoJZmxvYXQyIGR4eSA9IG1heChmbG9hdDIoZHh5MS54LCBtYXgoZHkwLCBkeHkxLnkpKSwgMC4wKTsKCWhhbGYgbGVmdEFscGhhID0gaGFsZihzYXR1cmF0ZShza19GcmFnQ29vcmQueCAtIHVpbm5lclJlY3RfUzIuTCkpOwoJaGFsZiBhbHBoYSA9IGxlZnRBbHBoYSAqIGhhbGYoc2F0dXJhdGUodXJhZGl1c1BsdXNIYWxmX1MyLnggLSBsZW5ndGgoZHh5KSkpOwoJcmV0dXJuIF9pbnB1dCAqIGFscGhhOwp9CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2Y29sb3JfUzA7CglmbG9hdCBjb3ZlcmFnZSA9IHZjb3ZlcmFnZV9TMDsKCWhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoaGFsZihjb3ZlcmFnZSkpOwoJaGFsZjQgb3V0cHV0X1MxOwoJb3V0cHV0X1MxID0gTWF0cml4RWZmZWN0X1MxKG91dHB1dENvbG9yX1MwKTsKCWhhbGY0IG91dHB1dF9TMjsKCW91dHB1dF9TMiA9IENpcmN1bGFyUlJlY3RfUzIob3V0cHV0Q292ZXJhZ2VfUzApOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dF9TMSAqIG91dHB1dF9TMjsKCX0KfQoAAAEAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAEAAAACAAAAHBvc2l0aW9uCAAAAGNvdmVyYWdlBQAAAGNvbG9yAAAACgAAAGxvY2FsQ29vcmQAAAAAAAA=","HVIAAAAAABIAAGAAAQ4AAAH477776R24EAAAIOBQAD6P7777777777YDAAAAAAAAAAAFIBVWKMG7QAAAAAAAEAACAAAAAVREAAQAAAAAQCDAAQQGAABAAAAAAAAHIAAAAAAAIAAAAAQGIAAAAAAA":"DAAAAExTS1N6AQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMV9jMDsKaW4gZmxvYXQyIHBvc2l0aW9uOwppbiBoYWxmNCBjb2xvcjsKaW4gZmxvYXQyIGxvY2FsQ29vcmQ7CmZsYXQgb3V0IGhhbGY0IHZjb2xvcl9TMDsKb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfM19TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgl2Y29sb3JfUzAgPSBjb2xvcjsKCXNrX1Bvc2l0aW9uID0gcG9zaXRpb24ueHkwMTsKCXsKCQl2VHJhbnNmb3JtZWRDb29yZHNfM19TMCA9IGZsb2F0M3gyKHVtYXRyaXhfUzFfYzApICogbG9jYWxDb29yZC54eTE7Cgl9Cn0KAAAAAAAAQgQAAHVuaWZvcm0gZmxvYXQ0IHVjbGFtcF9TMV9jMF9jMDsKdW5pZm9ybSBmbG9hdDN4MyB1bWF0cml4X1MxX2MwOwpzYW1wbGVyMkQgdVRleHR1cmVTYW1wbGVyXzBfUzE7CmZsYXQgaW4gaGFsZjQgdmNvbG9yX1MwOwppbiBmbG9hdDIgdlRyYW5zZm9ybWVkQ29vcmRzXzNfUzA7CmhhbGY0IFRleHR1cmVFZmZlY3RfUzFfYzBfYzAoaGFsZjQgX2lucHV0KSAKewoJZmxvYXQyIGluQ29vcmQgPSB2VHJhbnNmb3JtZWRDb29yZHNfM19TMDsKCWZsb2F0MiBzdWJzZXRDb29yZDsKCXN1YnNldENvb3JkLnggPSBpbkNvb3JkLng7CglzdWJzZXRDb29yZC55ID0gaW5Db29yZC55OwoJZmxvYXQyIGNsYW1wZWRDb29yZDsKCWNsYW1wZWRDb29yZC54ID0gY2xhbXAoc3Vic2V0Q29vcmQueCwgdWNsYW1wX1MxX2MwX2MwLngsIHVjbGFtcF9TMV9jMF9jMC56KTsKCWNsYW1wZWRDb29yZC55ID0gc3Vic2V0Q29vcmQueTsKCWhhbGY0IHRleHR1cmVDb2xvciA9IHNhbXBsZSh1VGV4dHVyZVNhbXBsZXJfMF9TMSwgY2xhbXBlZENvb3JkKTsKCXJldHVybiB0ZXh0dXJlQ29sb3I7Cn0KaGFsZjQgTWF0cml4RWZmZWN0X1MxX2MwKGhhbGY0IF9pbnB1dCkgCnsKCXJldHVybiBUZXh0dXJlRWZmZWN0X1MxX2MwX2MwKF9pbnB1dCk7Cn0KaGFsZjQgRGlzYWJsZUNvdmVyYWdlQXNBbHBoYV9TMShoYWxmNCBfaW5wdXQpIAp7CglfaW5wdXQgPSBNYXRyaXhFZmZlY3RfUzFfYzAoX2lucHV0KTsKCWhhbGY0IF90bXBfMF9pbkNvbG9yID0gX2lucHV0OwoJcmV0dXJuIGhhbGY0KF9pbnB1dCk7Cn0Kdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJaGFsZjQgb3V0cHV0Q29sb3JfUzA7CglvdXRwdXRDb2xvcl9TMCA9IHZjb2xvcl9TMDsKCWNvbnN0IGhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoMSk7CgloYWxmNCBvdXRwdXRfUzE7CglvdXRwdXRfUzEgPSBEaXNhYmxlQ292ZXJhZ2VBc0FscGhhX1MxKG91dHB1dENvbG9yX1MwKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRfUzEgKiBvdXRwdXRDb3ZlcmFnZV9TMDsKCX0KfQoAAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAADAAAACAAAAHBvc2l0aW9uBQAAAGNvbG9yAAAACgAAAGxvY2FsQ29vcmQAAAAAAAA=","HVIAAAAAABIAAGAAAQ4AAAH477776R24EAAAIOBQAD6P7777777777YDAAAAAAAAAAAHQBNGZODK5YIAAAAAAQAAAAAIADCNS4GV3QYBAAAAAAAAAAAIAAJQAAAAAAAACAAAAADYCAAIAAAAACABKAYABAAAAAFAEEQCEAAAAAAAAAAAAAAB2AAAAAAACAAAAAEBSAA":"DAAAAExTS1MIAgAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMTsKdW5pZm9ybSBmbG9hdDN4MyB1bWF0cml4X1MyX2MwX2MwOwppbiBmbG9hdDIgcG9zaXRpb247CmluIGhhbGY0IGNvbG9yOwppbiBmbG9hdDIgbG9jYWxDb29yZDsKZmxhdCBvdXQgaGFsZjQgdmNvbG9yX1MwOwpvdXQgZmxvYXQyIHZUcmFuc2Zvcm1lZENvb3Jkc18yX1MwOwpvdXQgZmxvYXQyIHZUcmFuc2Zvcm1lZENvb3Jkc182X1MwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCXZjb2xvcl9TMCA9IGNvbG9yOwoJc2tfUG9zaXRpb24gPSBwb3NpdGlvbi54eTAxOwoJewoJCXZUcmFuc2Zvcm1lZENvb3Jkc18yX1MwID0gZmxvYXQzeDIodW1hdHJpeF9TMSkgKiBsb2NhbENvb3JkLnh5MTsKCX0KCXsKCQl2VHJhbnNmb3JtZWRDb29yZHNfNl9TMCA9IGZsb2F0M3gyKHVtYXRyaXhfUzJfYzBfYzApICogcG9zaXRpb24ueHkxOwoJfQp9CgAAAAC0HQAAZmxvYXQ0IGZsdXR0ZXJfRnJhZ0Nvb3JkX1MxX2MwOwpmbG9hdDQgZnJhZ0NvbG9yX1MxX2MwOwpmbG9hdCB1X2FscGhhX1MxX2MwOwpmbG9hdCB1X3NwYXJrbGVfYWxwaGFfUzFfYzA7CmZsb2F0IHVfYmx1cl9TMV9jMDsKZmxvYXQgdV9yYWRpdXNfc2NhbGVfUzFfYzA7CnVuaWZvcm0gZmxvYXQ0IHVfY29sb3JfUzFfYzA7CnVuaWZvcm0gZmxvYXQ0IHVfY29tcG9zaXRlXzFfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfY2VudGVyX1MxX2MwOwp1bmlmb3JtIGZsb2F0IHVfbWF4X3JhZGl1c19TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9yZXNvbHV0aW9uX3NjYWxlX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X25vaXNlX3NjYWxlX1MxX2MwOwp1bmlmb3JtIGZsb2F0IHVfbm9pc2VfcGhhc2VfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfY2lyY2xlMV9TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9jaXJjbGUyX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X2NpcmNsZTNfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfcm90YXRpb24xX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X3JvdGF0aW9uMl9TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9yb3RhdGlvbjNfUzFfYzA7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMTsKdW5pZm9ybSBmbG9hdDN4MyB1bWF0cml4X1MyX2MwX2MwOwpzYW1wbGVyMkQgdVRleHR1cmVTYW1wbGVyXzBfUzI7CmZsYXQgaW4gaGFsZjQgdmNvbG9yX1MwOwppbiBmbG9hdDIgdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzA7CmluIGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfNl9TMDsKZmxvYXQyIEZMVF9mbHV0dGVyX2xvY2FsX0ZsdXR0ZXJGcmFnQ29vcmRfUzFfYzAoKTsKZmxvYXQyeDIgRkxUX2ZsdXR0ZXJfbG9jYWxfcm90YXRlMmRfUzFfYzAoZmxvYXQyIHJhZCk7CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfY2lyY2xlX1MxX2MwKGZsb2F0MiB1diwgZmxvYXQyIHh5LCBmbG9hdCByYWRpdXMsIGZsb2F0IGJsdXIpOwpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9jaXJjbGVfZ3JpZF9TMV9jMChmbG9hdDIgcmVzb2x1dGlvbiwgaW5vdXQgZmxvYXQyIHAsIGZsb2F0MiB4eSwgZmxvYXQyIHJvdGF0aW9uLCBmbG9hdCBjZWxsX2RpYW1ldGVyKTsKZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfdHVyYnVsZW5jZV9TMV9jMChmbG9hdDIgdXYpOwpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X3JpbmdfUzFfYzAoZmxvYXQyIHV2LCBmbG9hdDIgeHksIGZsb2F0IHJhZGl1cywgZmxvYXQgdGhpY2tuZXNzLCBmbG9hdCBibHVyKTsKZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfdHJpYW5nbGVfbm9pc2VfUzFfYzAoaW5vdXQgZmxvYXQyIG4pOwpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF90aHJlc2hvbGRfUzFfYzAoZmxvYXQgdiwgZmxvYXQgbCwgZmxvYXQgaCk7CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3NwYXJrbGVfUzFfYzAoZmxvYXQyIHV2LCBmbG9hdCB0KTsKdm9pZCBGTFRfbWFpbl9TMV9jMCgpOwpmbG9hdDIgRkxUX2ZsdXR0ZXJfbG9jYWxfRmx1dHRlckZyYWdDb29yZF9TMV9jMCgpIAp7CglyZXR1cm4gZmx1dHRlcl9GcmFnQ29vcmRfUzFfYzAueHk7Cn0KZmxvYXQyeDIgRkxUX2ZsdXR0ZXJfbG9jYWxfcm90YXRlMmRfUzFfYzAoZmxvYXQyIHJhZCkgCnsKCXJldHVybiBmbG9hdDJ4MihyYWQueCwgLXJhZC55LCByYWQueSwgcmFkLngpOwp9CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfY2lyY2xlX1MxX2MwKGZsb2F0MiB1diwgZmxvYXQyIHh5LCBmbG9hdCByYWRpdXMsIGZsb2F0IGJsdXIpIAp7CglmbG9hdCBibHVyX2hhbGYgPSBibHVyICogMC41OwoJZmxvYXQgZCA9IGRpc3RhbmNlKHV2LCB4eSk7CglyZXR1cm4gMS4wIC0gc21vb3Roc3RlcCgxLjAgLSBibHVyX2hhbGYsIDEuMCArIGJsdXJfaGFsZiwgZCAvIHJhZGl1cyk7Cn0KZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfY2lyY2xlX2dyaWRfUzFfYzAoZmxvYXQyIHJlc29sdXRpb24sIGlub3V0IGZsb2F0MiBwLCBmbG9hdDIgeHksIGZsb2F0MiByb3RhdGlvbiwgZmxvYXQgY2VsbF9kaWFtZXRlcikgCnsKCWZsb2F0MiBwYXJhbSA9IHJvdGF0aW9uOwoJcCA9IEZMVF9mbHV0dGVyX2xvY2FsX3JvdGF0ZTJkX1MxX2MwKHBhcmFtKSAqICh4eSAtIHApICsgeHk7CglwID0gbW9kKHAsIGZsb2F0MihjZWxsX2RpYW1ldGVyKSkgLyByZXNvbHV0aW9uOwoJZmxvYXQgY2VsbF91diA9IChjZWxsX2RpYW1ldGVyIC8gcmVzb2x1dGlvbi55KSAqIDAuNTsKCWZsb2F0IHIgPSAwLjY1ICogY2VsbF91djsKCWZsb2F0MiBwYXJhbV8xID0gcDsKCWZsb2F0MiBwYXJhbV8yID0gZmxvYXQyKGNlbGxfdXYpOwoJZmxvYXQgcGFyYW1fMyA9IHI7CglmbG9hdCBwYXJhbV80ID0gciAqIDUwLjA7CglyZXR1cm4gRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9jaXJjbGVfUzFfYzAocGFyYW1fMSwgcGFyYW1fMiwgcGFyYW1fMywgcGFyYW1fNCk7Cn0KZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfdHVyYnVsZW5jZV9TMV9jMChmbG9hdDIgdXYpIAp7CglmbG9hdDIgdXZfc2NhbGUgPSB1diAqIGZsb2F0MigwLjgpOwoJZmxvYXQyIHBhcmFtID0gZmxvYXQyKDAuOCk7CglmbG9hdDIgcGFyYW1fMSA9IHV2X3NjYWxlOwoJZmxvYXQyIHBhcmFtXzIgPSB1X2NpcmNsZTFfUzFfYzA7CglmbG9hdDIgcGFyYW1fMyA9IHVfcm90YXRpb24xX1MxX2MwOwoJZmxvYXQgcGFyYW1fNCA9IDAuMTc7CglmbG9hdCBfMzE5ID0gRkxUX2ZsdXR0ZXJfbG9jYWxfY2lyY2xlX2dyaWRfUzFfYzAocGFyYW0sIHBhcmFtXzEsIHBhcmFtXzIsIHBhcmFtXzMsIHBhcmFtXzQpOwoJZmxvYXQgZzEgPSBfMzE5OwoJZmxvYXQyIHBhcmFtXzUgPSBmbG9hdDIoMC44KTsKCWZsb2F0MiBwYXJhbV82ID0gdXZfc2NhbGU7CglmbG9hdDIgcGFyYW1fNyA9IHVfY2lyY2xlMl9TMV9jMDsKCWZsb2F0MiBwYXJhbV84ID0gdV9yb3RhdGlvbjJfUzFfYzA7CglmbG9hdCBwYXJhbV85ID0gMC4yOwoJZmxvYXQgXzMzMSA9IEZMVF9mbHV0dGVyX2xvY2FsX2NpcmNsZV9ncmlkX1MxX2MwKHBhcmFtXzUsIHBhcmFtXzYsIHBhcmFtXzcsIHBhcmFtXzgsIHBhcmFtXzkpOwoJZmxvYXQgZzIgPSBfMzMxOwoJZmxvYXQyIHBhcmFtXzEwID0gZmxvYXQyKDAuOCk7CglmbG9hdDIgcGFyYW1fMTEgPSB1dl9zY2FsZTsKCWZsb2F0MiBwYXJhbV8xMiA9IHVfY2lyY2xlM19TMV9jMDsKCWZsb2F0MiBwYXJhbV8xMyA9IHVfcm90YXRpb24zX1MxX2MwOwoJZmxvYXQgcGFyYW1fMTQgPSAwLjI3NTsKCWZsb2F0IF8zNDQgPSBGTFRfZmx1dHRlcl9sb2NhbF9jaXJjbGVfZ3JpZF9TMV9jMChwYXJhbV8xMCwgcGFyYW1fMTEsIHBhcmFtXzEyLCBwYXJhbV8xMywgcGFyYW1fMTQpOwoJZmxvYXQgZzMgPSBfMzQ0OwoJZmxvYXQgdiA9ICgoZzEgKiBnMSArIGcyKSAtIGczKSAqIDAuNTsKCXJldHVybiBjbGFtcCgwLjQ1ICsgMC44ICogdiwgMC4wLCAxLjApOwp9CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfcmluZ19TMV9jMChmbG9hdDIgdXYsIGZsb2F0MiB4eSwgZmxvYXQgcmFkaXVzLCBmbG9hdCB0aGlja25lc3MsIGZsb2F0IGJsdXIpIAp7CglmbG9hdDIgcGFyYW0gPSB1djsKCWZsb2F0MiBwYXJhbV8xID0geHk7CglmbG9hdCBwYXJhbV8yID0gcmFkaXVzICsgdGhpY2tuZXNzOwoJZmxvYXQgcGFyYW1fMyA9IGJsdXI7CglmbG9hdCBjaXJjbGVfb3V0ZXIgPSBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X2NpcmNsZV9TMV9jMChwYXJhbSwgcGFyYW1fMSwgcGFyYW1fMiwgcGFyYW1fMyk7CglmbG9hdDIgcGFyYW1fNCA9IHV2OwoJZmxvYXQyIHBhcmFtXzUgPSB4eTsKCWZsb2F0IHBhcmFtXzYgPSBtYXgocmFkaXVzIC0gdGhpY2tuZXNzLCAwLjApOwoJZmxvYXQgcGFyYW1fNyA9IGJsdXI7CglmbG9hdCBjaXJjbGVfaW5uZXIgPSBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X2NpcmNsZV9TMV9jMChwYXJhbV80LCBwYXJhbV81LCBwYXJhbV82LCBwYXJhbV83KTsKCXJldHVybiBjbGFtcChjaXJjbGVfb3V0ZXIgLSBjaXJjbGVfaW5uZXIsIDAuMCwgMS4wKTsKfQpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF90cmlhbmdsZV9ub2lzZV9TMV9jMChpbm91dCBmbG9hdDIgbikgCnsKCW4gPSBmcmFjdChuICogZmxvYXQyKDUuMzk4NywgNS40NDIxKSk7CgluICs9IGZsb2F0Mihkb3Qobi55eCwgbiArIGZsb2F0MigyMS41MzUxLCAxNC4zMTM3KSkpOwoJZmxvYXQgeHkgPSBuLnggKiBuLnk7CglyZXR1cm4gKGZyYWN0KHh5ICogOTUuNDMwNykgKyBmcmFjdCh4eSAqIDc1LjA0OTYxKSkgLSAxLjA7Cn0KZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfdGhyZXNob2xkX1MxX2MwKGZsb2F0IHYsIGZsb2F0IGwsIGZsb2F0IGgpIAp7CglyZXR1cm4gc3RlcChsLCB2KSAqICgxLjAgLSBzdGVwKGgsIHYpKTsKfQpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9zcGFya2xlX1MxX2MwKGZsb2F0MiB1diwgZmxvYXQgdCkgCnsKCWZsb2F0MiBwYXJhbSA9IHV2OwoJZmxvYXQgXzI0MiA9IEZMVF9mbHV0dGVyX2xvY2FsX3RyaWFuZ2xlX25vaXNlX1MxX2MwKHBhcmFtKTsKCWZsb2F0IG4gPSBfMjQyOwoJZmxvYXQgcGFyYW1fMSA9IG47CglmbG9hdCBwYXJhbV8yID0gMC4wOwoJZmxvYXQgcGFyYW1fMyA9IDAuMDU7CglmbG9hdCBzID0gRkxUX2ZsdXR0ZXJfbG9jYWxfdGhyZXNob2xkX1MxX2MwKHBhcmFtXzEsIHBhcmFtXzIsIHBhcmFtXzMpOwoJZmxvYXQgcGFyYW1fNCA9IG4gKyBzaW4oMy4xNDE1OTI3NCAqICh0ICsgMC4zNSkpOwoJZmxvYXQgcGFyYW1fNSA9IDAuMTsKCWZsb2F0IHBhcmFtXzYgPSAwLjE1OwoJcyArPSBGTFRfZmx1dHRlcl9sb2NhbF90aHJlc2hvbGRfUzFfYzAocGFyYW1fNCwgcGFyYW1fNSwgcGFyYW1fNik7CglmbG9hdCBwYXJhbV83ID0gbiArIHNpbigzLjE0MTU5Mjc0ICogKHQgKyAwLjcpKTsKCWZsb2F0IHBhcmFtXzggPSAwLjI7CglmbG9hdCBwYXJhbV85ID0gMC4yNTsKCXMgKz0gRkxUX2ZsdXR0ZXJfbG9jYWxfdGhyZXNob2xkX1MxX2MwKHBhcmFtXzcsIHBhcmFtXzgsIHBhcmFtXzkpOwoJZmxvYXQgcGFyYW1fMTAgPSBuICsgc2luKDMuMTQxNTkyNzQgKiAodCArIDEuMDUpKTsKCWZsb2F0IHBhcmFtXzExID0gMC4zOwoJZmxvYXQgcGFyYW1fMTIgPSAwLjM1OwoJcyArPSBGTFRfZmx1dHRlcl9sb2NhbF90aHJlc2hvbGRfUzFfYzAocGFyYW1fMTAsIHBhcmFtXzExLCBwYXJhbV8xMik7CglyZXR1cm4gY2xhbXAocywgMC4wLCAxLjApICogMC41NTsKfQp2b2lkIEZMVF9tYWluX1MxX2MwKCkgCnsKCXVfYWxwaGFfUzFfYzAgPSB1X2NvbXBvc2l0ZV8xX1MxX2MwLng7Cgl1X3NwYXJrbGVfYWxwaGFfUzFfYzAgPSB1X2NvbXBvc2l0ZV8xX1MxX2MwLnk7Cgl1X2JsdXJfUzFfYzAgPSB1X2NvbXBvc2l0ZV8xX1MxX2MwLno7Cgl1X3JhZGl1c19zY2FsZV9TMV9jMCA9IHVfY29tcG9zaXRlXzFfUzFfYzAudzsKCWZsb2F0MiBwID0gRkxUX2ZsdXR0ZXJfbG9jYWxfRmx1dHRlckZyYWdDb29yZF9TMV9jMCgpOwoJZmxvYXQyIHV2XzEgPSBwICogdV9yZXNvbHV0aW9uX3NjYWxlX1MxX2MwOwoJZmxvYXQyIGRlbnNpdHlfdXYgPSB1dl8xIC0gbW9kKHAsIHVfbm9pc2Vfc2NhbGVfUzFfYzApOwoJZmxvYXQgcmFkaXVzID0gdV9tYXhfcmFkaXVzX1MxX2MwICogdV9yYWRpdXNfc2NhbGVfUzFfYzA7CglmbG9hdDIgcGFyYW1fMTMgPSB1dl8xOwoJZmxvYXQgdHVyYnVsZW5jZSA9IEZMVF9mbHV0dGVyX2xvY2FsX3R1cmJ1bGVuY2VfUzFfYzAocGFyYW1fMTMpOwoJZmxvYXQyIHBhcmFtXzE0ID0gcDsKCWZsb2F0MiBwYXJhbV8xNSA9IHVfY2VudGVyX1MxX2MwOwoJZmxvYXQgcGFyYW1fMTYgPSByYWRpdXM7CglmbG9hdCBwYXJhbV8xNyA9IDAuMDUgKiB1X21heF9yYWRpdXNfUzFfYzA7CglmbG9hdCBwYXJhbV8xOCA9IHVfYmx1cl9TMV9jMDsKCWZsb2F0IHJpbmcgPSBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X3JpbmdfUzFfYzAocGFyYW1fMTQsIHBhcmFtXzE1LCBwYXJhbV8xNiwgcGFyYW1fMTcsIHBhcmFtXzE4KTsKCWZsb2F0MiBwYXJhbV8xOSA9IGRlbnNpdHlfdXY7CglmbG9hdCBwYXJhbV8yMCA9IHVfbm9pc2VfcGhhc2VfUzFfYzA7CglmbG9hdCBzcGFya2xlID0gKChGTFRfZmx1dHRlcl9sb2NhbF9zcGFya2xlX1MxX2MwKHBhcmFtXzE5LCBwYXJhbV8yMCkgKiByaW5nKSAqIHR1cmJ1bGVuY2UpICogdV9zcGFya2xlX2FscGhhX1MxX2MwOwoJZmxvYXQyIHBhcmFtXzIxID0gcDsKCWZsb2F0MiBwYXJhbV8yMiA9IHVfY2VudGVyX1MxX2MwOwoJZmxvYXQgcGFyYW1fMjMgPSByYWRpdXM7CglmbG9hdCBwYXJhbV8yNCA9IHVfYmx1cl9TMV9jMDsKCWZsb2F0IHdhdmVfYWxwaGEgPSAoRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9jaXJjbGVfUzFfYzAocGFyYW1fMjEsIHBhcmFtXzIyLCBwYXJhbV8yMywgcGFyYW1fMjQpICogdV9hbHBoYV9TMV9jMCkgKiB1X2NvbG9yX1MxX2MwLnc7CglmbG9hdDQgd2F2ZV9jb2xvciA9IGZsb2F0NCh1X2NvbG9yX1MxX2MwLnh5eiAqIHdhdmVfYWxwaGEsIHdhdmVfYWxwaGEpOwoJZnJhZ0NvbG9yX1MxX2MwID0gbWl4KHdhdmVfY29sb3IsIGZsb2F0NCgxLjApLCBmbG9hdDQoc3BhcmtsZSkpOwp9CmhhbGY0IHJ1bnRpbWVfc2hhZGVyX1MxX2MwKGhhbGY0IF9pbnB1dCkgCnsKCWhhbGY0IF90bXBfMF9pbkNvbG9yID0gX2lucHV0OwoJZmxvYXQyIF90bXBfMV9jb29yZHMgPSB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKCWZsdXR0ZXJfRnJhZ0Nvb3JkX1MxX2MwID0gZmxvYXQ0KF90bXBfMV9jb29yZHMsIDAuMCwgMC4wKTsKCUZMVF9tYWluX1MxX2MwKCk7CglyZXR1cm4gaGFsZjQoaGFsZjQoZnJhZ0NvbG9yX1MxX2MwKSk7Cn0KaGFsZjQgTWF0cml4RWZmZWN0X1MxKGhhbGY0IF9pbnB1dCkgCnsKCXJldHVybiBydW50aW1lX3NoYWRlcl9TMV9jMChfaW5wdXQpOwp9CmhhbGY0IFRleHR1cmVFZmZlY3RfUzJfYzBfYzBfYzAoaGFsZjQgX2lucHV0KSAKewoJcmV0dXJuIHNhbXBsZSh1VGV4dHVyZVNhbXBsZXJfMF9TMiwgdlRyYW5zZm9ybWVkQ29vcmRzXzZfUzApLjAwMHI7Cn0KaGFsZjQgTWF0cml4RWZmZWN0X1MyX2MwX2MwKGhhbGY0IF9pbnB1dCkgCnsKCXJldHVybiBUZXh0dXJlRWZmZWN0X1MyX2MwX2MwX2MwKF9pbnB1dCk7Cn0KaGFsZjQgRGV2aWNlU3BhY2VfUzJfYzAoaGFsZjQgX2lucHV0KSAKewoJcmV0dXJuIE1hdHJpeEVmZmVjdF9TMl9jMF9jMChfaW5wdXQpOwp9CmhhbGY0IEJsZW5kX1MyKGhhbGY0IF9zcmMsIGhhbGY0IF9kc3QpIAp7CglyZXR1cm4gYmxlbmRfZHN0X2luKERldmljZVNwYWNlX1MyX2MwKF9zcmMpLCBfc3JjKTsKfQp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmNvbG9yX1MwOwoJY29uc3QgaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNCgxKTsKCWhhbGY0IG91dHB1dF9TMTsKCW91dHB1dF9TMSA9IE1hdHJpeEVmZmVjdF9TMShvdXRwdXRDb2xvcl9TMCk7CgloYWxmNCBvdXRwdXRfUzI7CglvdXRwdXRfUzIgPSBCbGVuZF9TMihvdXRwdXRDb3ZlcmFnZV9TMCwgaGFsZjQoMSkpOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dF9TMSAqIG91dHB1dF9TMjsKCX0KfQoAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAgAAABwb3NpdGlvbgUAAABjb2xvcgAAAAoAAABsb2NhbENvb3JkAAAAAAAA","HUIAAAAAAAQAADAAAIOAAAH677777777777QGHAQAD7P7777777777YBAAAAAAAAAAALUASJ3EZYN2AAAAAAAIAEAAAABSCQKL3IYIJ2AAAAAAAIAEAAAABLBCABAAAAABAEGABBAMAAACAAAAAAAOQAAAAAAAQAAAABAMQAAAAAA":"DAAAAExTS1M2AQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMTsKaW4gZmxvYXQyIHBvc2l0aW9uOwppbiBmbG9hdDIgbG9jYWxDb29yZDsKb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCglza19Qb3NpdGlvbiA9IHBvc2l0aW9uLnh5MDE7Cgl7CgkJdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzAgPSBmbG9hdDN4Mih1bWF0cml4X1MxKSAqIGxvY2FsQ29vcmQueHkxOwoJfQp9CgAAAAAAAGgHAABjb25zdCBpbnQga01heExvb3BMaW1pdF9TMV9jMCA9IDg7CnVuaWZvcm0gaGFsZjQgdWJvcmRlcl9TMV9jMF9jMF9jMDsKdW5pZm9ybSBmbG9hdDQgdXN1YnNldF9TMV9jMF9jMF9jMDsKdW5pZm9ybSBmbG9hdDQgdWNsYW1wX1MxX2MwX2MwX2MwOwp1bmlmb3JtIGZsb2F0MiB1aWRpbXNfUzFfYzBfYzBfYzA7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMV9jMF9jMDsKdW5pZm9ybSBoYWxmNCB1b2Zmc2V0c0FuZEtlcm5lbF9TMV9jMFsxNF07CnVuaWZvcm0gaGFsZjIgdWRpcl9TMV9jMDsKdW5pZm9ybSBmbG9hdDN4MyB1bWF0cml4X1MxOwpzYW1wbGVyMkQgdVRleHR1cmVTYW1wbGVyXzBfUzE7CmluIGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKaGFsZjQgVGV4dHVyZUVmZmVjdF9TMV9jMF9jMF9jMChoYWxmNCBfaW5wdXQsIGZsb2F0MiBfY29vcmRzKSAKewoJZmxvYXQyIGluQ29vcmQgPSBfY29vcmRzOwoJZmxvYXQyIHN1YnNldENvb3JkOwoJc3Vic2V0Q29vcmQueCA9IGluQ29vcmQueDsKCXN1YnNldENvb3JkLnkgPSBpbkNvb3JkLnk7CglmbG9hdDIgY2xhbXBlZENvb3JkOwoJY2xhbXBlZENvb3JkLnggPSBzdWJzZXRDb29yZC54OwoJY2xhbXBlZENvb3JkLnkgPSBjbGFtcChzdWJzZXRDb29yZC55LCB1Y2xhbXBfUzFfYzBfYzBfYzAueSwgdWNsYW1wX1MxX2MwX2MwX2MwLncpOwoJaGFsZjQgdGV4dHVyZUNvbG9yID0gc2FtcGxlKHVUZXh0dXJlU2FtcGxlcl8wX1MxLCAoY2xhbXBlZENvb3JkKSAqIHVpZGltc19TMV9jMF9jMF9jMCk7CgloYWxmIGVyclkgPSBoYWxmKHN1YnNldENvb3JkLnkgLSBjbGFtcGVkQ29vcmQueSk7Cgl0ZXh0dXJlQ29sb3IgPSBtaXgodGV4dHVyZUNvbG9yLCB1Ym9yZGVyX1MxX2MwX2MwX2MwLCBtaW4oYWJzKGVyclkpLCAxKSk7CglyZXR1cm4gdGV4dHVyZUNvbG9yOwp9CmhhbGY0IE1hdHJpeEVmZmVjdF9TMV9jMF9jMChoYWxmNCBfaW5wdXQsIGZsb2F0MiBfY29vcmRzKSAKewoJcmV0dXJuIFRleHR1cmVFZmZlY3RfUzFfYzBfYzBfYzAoX2lucHV0LCBmbG9hdDN4Mih1bWF0cml4X1MxX2MwX2MwKSAqIF9jb29yZHMueHkxKTsKfQpoYWxmNCBHYXVzc2lhbkJsdXIxRF9TMV9jMChoYWxmNCBfaW5wdXQpIAp7CgloYWxmNCBfdG1wXzBfaW5Db2xvciA9IF9pbnB1dDsKCWZsb2F0MiBfdG1wXzFfY29vcmRzID0gdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzA7CgloYWxmNCBzdW0gPSBoYWxmNCgwLjApOwoJZm9yIChpbnQgaSA9IDA7aSA8IGtNYXhMb29wTGltaXRfUzFfYzA7ICsraSkgCgl7CgkJaGFsZjQgcyA9IHVvZmZzZXRzQW5kS2VybmVsX1MxX2MwW2ldOwoJCXN1bSArPSBzLnkgKiBNYXRyaXhFZmZlY3RfUzFfYzBfYzAoX3RtcF8wX2luQ29sb3IsIF90bXBfMV9jb29yZHMgKyBmbG9hdDIocy54ICogdWRpcl9TMV9jMCkpOwoJCXN1bSArPSBzLncgKiBNYXRyaXhFZmZlY3RfUzFfYzBfYzAoX3RtcF8wX2luQ29sb3IsIF90bXBfMV9jb29yZHMgKyBmbG9hdDIocy56ICogdWRpcl9TMV9jMCkpOwoJfQoJcmV0dXJuIGhhbGY0KHN1bSk7Cn0KaGFsZjQgTWF0cml4RWZmZWN0X1MxKGhhbGY0IF9pbnB1dCkgCnsKCXJldHVybiBHYXVzc2lhbkJsdXIxRF9TMV9jMChfaW5wdXQpOwp9CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwID0gaGFsZjQoMSk7Cgljb25zdCBoYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KDEpOwoJaGFsZjQgb3V0cHV0X1MxOwoJb3V0cHV0X1MxID0gTWF0cml4RWZmZWN0X1MxKG91dHB1dENvbG9yX1MwKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRfUzEgKiBvdXRwdXRDb3ZlcmFnZV9TMDsKCX0KfQoAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAgAAABwb3NpdGlvbgoAAABsb2NhbENvb3JkAAAAAAAA","DAQAAAAAAAAAAAAAAJQAAIGAAEACBYQCAGAEFAIBAAAAAABAAAAAAAAAAAAAAOQAAAAAAAQAAAABAMQAAAAA":"DAAAAExTS1MWAgAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQyIHVBdGxhc1NpemVJbnZfUzA7CmluIGZsb2F0MiBpblBvc2l0aW9uOwppbiBoYWxmNCBpbkNvbG9yOwppbiB1c2hvcnQyIGluVGV4dHVyZUNvb3JkczsKb3V0IGZsb2F0MiB2VGV4dHVyZUNvb3Jkc19TMDsKZmxhdCBvdXQgZmxvYXQgdlRleEluZGV4X1MwOwpvdXQgaGFsZjQgdmluQ29sb3JfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIEJpdG1hcFRleHQKCWludCB0ZXhJZHggPSAwOwoJZmxvYXQyIHVub3JtVGV4Q29vcmRzID0gZmxvYXQyKGluVGV4dHVyZUNvb3Jkcy54LCBpblRleHR1cmVDb29yZHMueSk7Cgl2VGV4dHVyZUNvb3Jkc19TMCA9IHVub3JtVGV4Q29vcmRzICogdUF0bGFzU2l6ZUludl9TMDsKCXZUZXhJbmRleF9TMCA9IGZsb2F0KHRleElkeCk7Cgl2aW5Db2xvcl9TMCA9IGluQ29sb3I7CglmbG9hdDIgX3RtcF8xX2luUG9zaXRpb24gPSBpblBvc2l0aW9uOwoJc2tfUG9zaXRpb24gPSBpblBvc2l0aW9uLnh5MDE7Cn0KAAAAAAAAqQEAAHNhbXBsZXIyRCB1VGV4dHVyZVNhbXBsZXJfMF9TMDsKaW4gZmxvYXQyIHZUZXh0dXJlQ29vcmRzX1MwOwpmbGF0IGluIGZsb2F0IHZUZXhJbmRleF9TMDsKaW4gaGFsZjQgdmluQ29sb3JfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBCaXRtYXBUZXh0CgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmluQ29sb3JfUzA7CgloYWxmNCB0ZXhDb2xvcjsKCXsKCQl0ZXhDb2xvciA9IHNhbXBsZSh1VGV4dHVyZVNhbXBsZXJfMF9TMCwgdlRleHR1cmVDb29yZHNfUzApLnJycnI7Cgl9CgloYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IHRleENvbG9yOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dENvbG9yX1MwICogb3V0cHV0Q292ZXJhZ2VfUzA7Cgl9Cn0KAAAAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAKAAAAaW5Qb3NpdGlvbgAABwAAAGluQ29sb3IADwAAAGluVGV4dHVyZUNvb3JkcwAAAAAA","HVIAAAAAABIAAGAAAQ4AAAH477776R24EAAAIOBQAD6P7777777777YDAAAAAAAAAAAHIBNGZODK5YIAAAAAAQAAAAAIADCNS4GV3QYBAAAAAAAAAAAAAHIAAAAAAAIAAAAAQGIAAAAAA":"DAAAAExTS1N0AQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMTsKaW4gZmxvYXQyIHBvc2l0aW9uOwppbiBoYWxmNCBjb2xvcjsKaW4gZmxvYXQyIGxvY2FsQ29vcmQ7CmZsYXQgb3V0IGhhbGY0IHZjb2xvcl9TMDsKb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgl2Y29sb3JfUzAgPSBjb2xvcjsKCXNrX1Bvc2l0aW9uID0gcG9zaXRpb24ueHkwMTsKCXsKCQl2VHJhbnNmb3JtZWRDb29yZHNfMl9TMCA9IGZsb2F0M3gyKHVtYXRyaXhfUzEpICogbG9jYWxDb29yZC54eTE7Cgl9Cn0KAAAAAIwbAABmbG9hdDQgZmx1dHRlcl9GcmFnQ29vcmRfUzFfYzA7CmZsb2F0NCBmcmFnQ29sb3JfUzFfYzA7CmZsb2F0IHVfYWxwaGFfUzFfYzA7CmZsb2F0IHVfc3BhcmtsZV9hbHBoYV9TMV9jMDsKZmxvYXQgdV9ibHVyX1MxX2MwOwpmbG9hdCB1X3JhZGl1c19zY2FsZV9TMV9jMDsKdW5pZm9ybSBmbG9hdDQgdV9jb2xvcl9TMV9jMDsKdW5pZm9ybSBmbG9hdDQgdV9jb21wb3NpdGVfMV9TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9jZW50ZXJfUzFfYzA7CnVuaWZvcm0gZmxvYXQgdV9tYXhfcmFkaXVzX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X3Jlc29sdXRpb25fc2NhbGVfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfbm9pc2Vfc2NhbGVfUzFfYzA7CnVuaWZvcm0gZmxvYXQgdV9ub2lzZV9waGFzZV9TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9jaXJjbGUxX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X2NpcmNsZTJfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfY2lyY2xlM19TMV9jMDsKdW5pZm9ybSBmbG9hdDIgdV9yb3RhdGlvbjFfUzFfYzA7CnVuaWZvcm0gZmxvYXQyIHVfcm90YXRpb24yX1MxX2MwOwp1bmlmb3JtIGZsb2F0MiB1X3JvdGF0aW9uM19TMV9jMDsKdW5pZm9ybSBmbG9hdDN4MyB1bWF0cml4X1MxOwpmbGF0IGluIGhhbGY0IHZjb2xvcl9TMDsKaW4gZmxvYXQyIHZUcmFuc2Zvcm1lZENvb3Jkc18yX1MwOwpmbG9hdDIgRkxUX2ZsdXR0ZXJfbG9jYWxfRmx1dHRlckZyYWdDb29yZF9TMV9jMCgpOwpmbG9hdDJ4MiBGTFRfZmx1dHRlcl9sb2NhbF9yb3RhdGUyZF9TMV9jMChmbG9hdDIgcmFkKTsKZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9jaXJjbGVfUzFfYzAoZmxvYXQyIHV2LCBmbG9hdDIgeHksIGZsb2F0IHJhZGl1cywgZmxvYXQgYmx1cik7CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX2NpcmNsZV9ncmlkX1MxX2MwKGZsb2F0MiByZXNvbHV0aW9uLCBpbm91dCBmbG9hdDIgcCwgZmxvYXQyIHh5LCBmbG9hdDIgcm90YXRpb24sIGZsb2F0IGNlbGxfZGlhbWV0ZXIpOwpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF90dXJidWxlbmNlX1MxX2MwKGZsb2F0MiB1dik7CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfcmluZ19TMV9jMChmbG9hdDIgdXYsIGZsb2F0MiB4eSwgZmxvYXQgcmFkaXVzLCBmbG9hdCB0aGlja25lc3MsIGZsb2F0IGJsdXIpOwpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF90cmlhbmdsZV9ub2lzZV9TMV9jMChpbm91dCBmbG9hdDIgbik7CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3RocmVzaG9sZF9TMV9jMChmbG9hdCB2LCBmbG9hdCBsLCBmbG9hdCBoKTsKZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfc3BhcmtsZV9TMV9jMChmbG9hdDIgdXYsIGZsb2F0IHQpOwp2b2lkIEZMVF9tYWluX1MxX2MwKCk7CmZsb2F0MiBGTFRfZmx1dHRlcl9sb2NhbF9GbHV0dGVyRnJhZ0Nvb3JkX1MxX2MwKCkgCnsKCXJldHVybiBmbHV0dGVyX0ZyYWdDb29yZF9TMV9jMC54eTsKfQpmbG9hdDJ4MiBGTFRfZmx1dHRlcl9sb2NhbF9yb3RhdGUyZF9TMV9jMChmbG9hdDIgcmFkKSAKewoJcmV0dXJuIGZsb2F0MngyKHJhZC54LCAtcmFkLnksIHJhZC55LCByYWQueCk7Cn0KZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9jaXJjbGVfUzFfYzAoZmxvYXQyIHV2LCBmbG9hdDIgeHksIGZsb2F0IHJhZGl1cywgZmxvYXQgYmx1cikgCnsKCWZsb2F0IGJsdXJfaGFsZiA9IGJsdXIgKiAwLjU7CglmbG9hdCBkID0gZGlzdGFuY2UodXYsIHh5KTsKCXJldHVybiAxLjAgLSBzbW9vdGhzdGVwKDEuMCAtIGJsdXJfaGFsZiwgMS4wICsgYmx1cl9oYWxmLCBkIC8gcmFkaXVzKTsKfQpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF9jaXJjbGVfZ3JpZF9TMV9jMChmbG9hdDIgcmVzb2x1dGlvbiwgaW5vdXQgZmxvYXQyIHAsIGZsb2F0MiB4eSwgZmxvYXQyIHJvdGF0aW9uLCBmbG9hdCBjZWxsX2RpYW1ldGVyKSAKewoJZmxvYXQyIHBhcmFtID0gcm90YXRpb247CglwID0gRkxUX2ZsdXR0ZXJfbG9jYWxfcm90YXRlMmRfUzFfYzAocGFyYW0pICogKHh5IC0gcCkgKyB4eTsKCXAgPSBtb2QocCwgZmxvYXQyKGNlbGxfZGlhbWV0ZXIpKSAvIHJlc29sdXRpb247CglmbG9hdCBjZWxsX3V2ID0gKGNlbGxfZGlhbWV0ZXIgLyByZXNvbHV0aW9uLnkpICogMC41OwoJZmxvYXQgciA9IDAuNjUgKiBjZWxsX3V2OwoJZmxvYXQyIHBhcmFtXzEgPSBwOwoJZmxvYXQyIHBhcmFtXzIgPSBmbG9hdDIoY2VsbF91dik7CglmbG9hdCBwYXJhbV8zID0gcjsKCWZsb2F0IHBhcmFtXzQgPSByICogNTAuMDsKCXJldHVybiBGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X2NpcmNsZV9TMV9jMChwYXJhbV8xLCBwYXJhbV8yLCBwYXJhbV8zLCBwYXJhbV80KTsKfQpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF90dXJidWxlbmNlX1MxX2MwKGZsb2F0MiB1dikgCnsKCWZsb2F0MiB1dl9zY2FsZSA9IHV2ICogZmxvYXQyKDAuOCk7CglmbG9hdDIgcGFyYW0gPSBmbG9hdDIoMC44KTsKCWZsb2F0MiBwYXJhbV8xID0gdXZfc2NhbGU7CglmbG9hdDIgcGFyYW1fMiA9IHVfY2lyY2xlMV9TMV9jMDsKCWZsb2F0MiBwYXJhbV8zID0gdV9yb3RhdGlvbjFfUzFfYzA7CglmbG9hdCBwYXJhbV80ID0gMC4xNzsKCWZsb2F0IF8zMTkgPSBGTFRfZmx1dHRlcl9sb2NhbF9jaXJjbGVfZ3JpZF9TMV9jMChwYXJhbSwgcGFyYW1fMSwgcGFyYW1fMiwgcGFyYW1fMywgcGFyYW1fNCk7CglmbG9hdCBnMSA9IF8zMTk7CglmbG9hdDIgcGFyYW1fNSA9IGZsb2F0MigwLjgpOwoJZmxvYXQyIHBhcmFtXzYgPSB1dl9zY2FsZTsKCWZsb2F0MiBwYXJhbV83ID0gdV9jaXJjbGUyX1MxX2MwOwoJZmxvYXQyIHBhcmFtXzggPSB1X3JvdGF0aW9uMl9TMV9jMDsKCWZsb2F0IHBhcmFtXzkgPSAwLjI7CglmbG9hdCBfMzMxID0gRkxUX2ZsdXR0ZXJfbG9jYWxfY2lyY2xlX2dyaWRfUzFfYzAocGFyYW1fNSwgcGFyYW1fNiwgcGFyYW1fNywgcGFyYW1fOCwgcGFyYW1fOSk7CglmbG9hdCBnMiA9IF8zMzE7CglmbG9hdDIgcGFyYW1fMTAgPSBmbG9hdDIoMC44KTsKCWZsb2F0MiBwYXJhbV8xMSA9IHV2X3NjYWxlOwoJZmxvYXQyIHBhcmFtXzEyID0gdV9jaXJjbGUzX1MxX2MwOwoJZmxvYXQyIHBhcmFtXzEzID0gdV9yb3RhdGlvbjNfUzFfYzA7CglmbG9hdCBwYXJhbV8xNCA9IDAuMjc1OwoJZmxvYXQgXzM0NCA9IEZMVF9mbHV0dGVyX2xvY2FsX2NpcmNsZV9ncmlkX1MxX2MwKHBhcmFtXzEwLCBwYXJhbV8xMSwgcGFyYW1fMTIsIHBhcmFtXzEzLCBwYXJhbV8xNCk7CglmbG9hdCBnMyA9IF8zNDQ7CglmbG9hdCB2ID0gKChnMSAqIGcxICsgZzIpIC0gZzMpICogMC41OwoJcmV0dXJuIGNsYW1wKDAuNDUgKyAwLjggKiB2LCAwLjAsIDEuMCk7Cn0KZmxvYXQgRkxUX2ZsdXR0ZXJfbG9jYWxfc29mdF9yaW5nX1MxX2MwKGZsb2F0MiB1diwgZmxvYXQyIHh5LCBmbG9hdCByYWRpdXMsIGZsb2F0IHRoaWNrbmVzcywgZmxvYXQgYmx1cikgCnsKCWZsb2F0MiBwYXJhbSA9IHV2OwoJZmxvYXQyIHBhcmFtXzEgPSB4eTsKCWZsb2F0IHBhcmFtXzIgPSByYWRpdXMgKyB0aGlja25lc3M7CglmbG9hdCBwYXJhbV8zID0gYmx1cjsKCWZsb2F0IGNpcmNsZV9vdXRlciA9IEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfY2lyY2xlX1MxX2MwKHBhcmFtLCBwYXJhbV8xLCBwYXJhbV8yLCBwYXJhbV8zKTsKCWZsb2F0MiBwYXJhbV80ID0gdXY7CglmbG9hdDIgcGFyYW1fNSA9IHh5OwoJZmxvYXQgcGFyYW1fNiA9IG1heChyYWRpdXMgLSB0aGlja25lc3MsIDAuMCk7CglmbG9hdCBwYXJhbV83ID0gYmx1cjsKCWZsb2F0IGNpcmNsZV9pbm5lciA9IEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfY2lyY2xlX1MxX2MwKHBhcmFtXzQsIHBhcmFtXzUsIHBhcmFtXzYsIHBhcmFtXzcpOwoJcmV0dXJuIGNsYW1wKGNpcmNsZV9vdXRlciAtIGNpcmNsZV9pbm5lciwgMC4wLCAxLjApOwp9CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3RyaWFuZ2xlX25vaXNlX1MxX2MwKGlub3V0IGZsb2F0MiBuKSAKewoJbiA9IGZyYWN0KG4gKiBmbG9hdDIoNS4zOTg3LCA1LjQ0MjEpKTsKCW4gKz0gZmxvYXQyKGRvdChuLnl4LCBuICsgZmxvYXQyKDIxLjUzNTEsIDE0LjMxMzcpKSk7CglmbG9hdCB4eSA9IG4ueCAqIG4ueTsKCXJldHVybiAoZnJhY3QoeHkgKiA5NS40MzA3KSArIGZyYWN0KHh5ICogNzUuMDQ5NjEpKSAtIDEuMDsKfQpmbG9hdCBGTFRfZmx1dHRlcl9sb2NhbF90aHJlc2hvbGRfUzFfYzAoZmxvYXQgdiwgZmxvYXQgbCwgZmxvYXQgaCkgCnsKCXJldHVybiBzdGVwKGwsIHYpICogKDEuMCAtIHN0ZXAoaCwgdikpOwp9CmZsb2F0IEZMVF9mbHV0dGVyX2xvY2FsX3NwYXJrbGVfUzFfYzAoZmxvYXQyIHV2LCBmbG9hdCB0KSAKewoJZmxvYXQyIHBhcmFtID0gdXY7CglmbG9hdCBfMjQyID0gRkxUX2ZsdXR0ZXJfbG9jYWxfdHJpYW5nbGVfbm9pc2VfUzFfYzAocGFyYW0pOwoJZmxvYXQgbiA9IF8yNDI7CglmbG9hdCBwYXJhbV8xID0gbjsKCWZsb2F0IHBhcmFtXzIgPSAwLjA7CglmbG9hdCBwYXJhbV8zID0gMC4wNTsKCWZsb2F0IHMgPSBGTFRfZmx1dHRlcl9sb2NhbF90aHJlc2hvbGRfUzFfYzAocGFyYW1fMSwgcGFyYW1fMiwgcGFyYW1fMyk7CglmbG9hdCBwYXJhbV80ID0gbiArIHNpbigzLjE0MTU5Mjc0ICogKHQgKyAwLjM1KSk7CglmbG9hdCBwYXJhbV81ID0gMC4xOwoJZmxvYXQgcGFyYW1fNiA9IDAuMTU7CglzICs9IEZMVF9mbHV0dGVyX2xvY2FsX3RocmVzaG9sZF9TMV9jMChwYXJhbV80LCBwYXJhbV81LCBwYXJhbV82KTsKCWZsb2F0IHBhcmFtXzcgPSBuICsgc2luKDMuMTQxNTkyNzQgKiAodCArIDAuNykpOwoJZmxvYXQgcGFyYW1fOCA9IDAuMjsKCWZsb2F0IHBhcmFtXzkgPSAwLjI1OwoJcyArPSBGTFRfZmx1dHRlcl9sb2NhbF90aHJlc2hvbGRfUzFfYzAocGFyYW1fNywgcGFyYW1fOCwgcGFyYW1fOSk7CglmbG9hdCBwYXJhbV8xMCA9IG4gKyBzaW4oMy4xNDE1OTI3NCAqICh0ICsgMS4wNSkpOwoJZmxvYXQgcGFyYW1fMTEgPSAwLjM7CglmbG9hdCBwYXJhbV8xMiA9IDAuMzU7CglzICs9IEZMVF9mbHV0dGVyX2xvY2FsX3RocmVzaG9sZF9TMV9jMChwYXJhbV8xMCwgcGFyYW1fMTEsIHBhcmFtXzEyKTsKCXJldHVybiBjbGFtcChzLCAwLjAsIDEuMCkgKiAwLjU1Owp9CnZvaWQgRkxUX21haW5fUzFfYzAoKSAKewoJdV9hbHBoYV9TMV9jMCA9IHVfY29tcG9zaXRlXzFfUzFfYzAueDsKCXVfc3BhcmtsZV9hbHBoYV9TMV9jMCA9IHVfY29tcG9zaXRlXzFfUzFfYzAueTsKCXVfYmx1cl9TMV9jMCA9IHVfY29tcG9zaXRlXzFfUzFfYzAuejsKCXVfcmFkaXVzX3NjYWxlX1MxX2MwID0gdV9jb21wb3NpdGVfMV9TMV9jMC53OwoJZmxvYXQyIHAgPSBGTFRfZmx1dHRlcl9sb2NhbF9GbHV0dGVyRnJhZ0Nvb3JkX1MxX2MwKCk7CglmbG9hdDIgdXZfMSA9IHAgKiB1X3Jlc29sdXRpb25fc2NhbGVfUzFfYzA7CglmbG9hdDIgZGVuc2l0eV91diA9IHV2XzEgLSBtb2QocCwgdV9ub2lzZV9zY2FsZV9TMV9jMCk7CglmbG9hdCByYWRpdXMgPSB1X21heF9yYWRpdXNfUzFfYzAgKiB1X3JhZGl1c19zY2FsZV9TMV9jMDsKCWZsb2F0MiBwYXJhbV8xMyA9IHV2XzE7CglmbG9hdCB0dXJidWxlbmNlID0gRkxUX2ZsdXR0ZXJfbG9jYWxfdHVyYnVsZW5jZV9TMV9jMChwYXJhbV8xMyk7CglmbG9hdDIgcGFyYW1fMTQgPSBwOwoJZmxvYXQyIHBhcmFtXzE1ID0gdV9jZW50ZXJfUzFfYzA7CglmbG9hdCBwYXJhbV8xNiA9IHJhZGl1czsKCWZsb2F0IHBhcmFtXzE3ID0gMC4wNSAqIHVfbWF4X3JhZGl1c19TMV9jMDsKCWZsb2F0IHBhcmFtXzE4ID0gdV9ibHVyX1MxX2MwOwoJZmxvYXQgcmluZyA9IEZMVF9mbHV0dGVyX2xvY2FsX3NvZnRfcmluZ19TMV9jMChwYXJhbV8xNCwgcGFyYW1fMTUsIHBhcmFtXzE2LCBwYXJhbV8xNywgcGFyYW1fMTgpOwoJZmxvYXQyIHBhcmFtXzE5ID0gZGVuc2l0eV91djsKCWZsb2F0IHBhcmFtXzIwID0gdV9ub2lzZV9waGFzZV9TMV9jMDsKCWZsb2F0IHNwYXJrbGUgPSAoKEZMVF9mbHV0dGVyX2xvY2FsX3NwYXJrbGVfUzFfYzAocGFyYW1fMTksIHBhcmFtXzIwKSAqIHJpbmcpICogdHVyYnVsZW5jZSkgKiB1X3NwYXJrbGVfYWxwaGFfUzFfYzA7CglmbG9hdDIgcGFyYW1fMjEgPSBwOwoJZmxvYXQyIHBhcmFtXzIyID0gdV9jZW50ZXJfUzFfYzA7CglmbG9hdCBwYXJhbV8yMyA9IHJhZGl1czsKCWZsb2F0IHBhcmFtXzI0ID0gdV9ibHVyX1MxX2MwOwoJZmxvYXQgd2F2ZV9hbHBoYSA9IChGTFRfZmx1dHRlcl9sb2NhbF9zb2Z0X2NpcmNsZV9TMV9jMChwYXJhbV8yMSwgcGFyYW1fMjIsIHBhcmFtXzIzLCBwYXJhbV8yNCkgKiB1X2FscGhhX1MxX2MwKSAqIHVfY29sb3JfUzFfYzAudzsKCWZsb2F0NCB3YXZlX2NvbG9yID0gZmxvYXQ0KHVfY29sb3JfUzFfYzAueHl6ICogd2F2ZV9hbHBoYSwgd2F2ZV9hbHBoYSk7CglmcmFnQ29sb3JfUzFfYzAgPSBtaXgod2F2ZV9jb2xvciwgZmxvYXQ0KDEuMCksIGZsb2F0NChzcGFya2xlKSk7Cn0KaGFsZjQgcnVudGltZV9zaGFkZXJfUzFfYzAoaGFsZjQgX2lucHV0KSAKewoJaGFsZjQgX3RtcF8wX2luQ29sb3IgPSBfaW5wdXQ7CglmbG9hdDIgX3RtcF8xX2Nvb3JkcyA9IHZUcmFuc2Zvcm1lZENvb3Jkc18yX1MwOwoJZmx1dHRlcl9GcmFnQ29vcmRfUzFfYzAgPSBmbG9hdDQoX3RtcF8xX2Nvb3JkcywgMC4wLCAwLjApOwoJRkxUX21haW5fUzFfYzAoKTsKCXJldHVybiBoYWxmNChoYWxmNChmcmFnQ29sb3JfUzFfYzApKTsKfQpoYWxmNCBNYXRyaXhFZmZlY3RfUzEoaGFsZjQgX2lucHV0KSAKewoJcmV0dXJuIHJ1bnRpbWVfc2hhZGVyX1MxX2MwKF9pbnB1dCk7Cn0Kdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJaGFsZjQgb3V0cHV0Q29sb3JfUzA7CglvdXRwdXRDb2xvcl9TMCA9IHZjb2xvcl9TMDsKCWNvbnN0IGhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoMSk7CgloYWxmNCBvdXRwdXRfUzE7CglvdXRwdXRfUzEgPSBNYXRyaXhFZmZlY3RfUzEob3V0cHV0Q29sb3JfUzApOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dF9TMSAqIG91dHB1dENvdmVyYWdlX1MwOwoJfQp9CgAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAADAAAACAAAAHBvc2l0aW9uBQAAAGNvbG9yAAAACgAAAGxvY2FsQ29vcmQAAAAAAAA=","HVIAAAAAABIAAGAAAQ4AAAH477776R24EAAAIOBQAD6P7777777777YDAAAAAAAAAAAGIBIAAABAAAAANAEAAAAAAAAAAAAAABAAOAAAABAAAAAAABBAMAAAAA":"DAAAAExTS1N0AQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMTsKaW4gZmxvYXQyIHBvc2l0aW9uOwppbiBoYWxmNCBjb2xvcjsKaW4gZmxvYXQyIGxvY2FsQ29vcmQ7CmZsYXQgb3V0IGhhbGY0IHZjb2xvcl9TMDsKb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgl2Y29sb3JfUzAgPSBjb2xvcjsKCXNrX1Bvc2l0aW9uID0gcG9zaXRpb24ueHkwMTsKCXsKCQl2VHJhbnNmb3JtZWRDb29yZHNfMl9TMCA9IGZsb2F0M3gyKHVtYXRyaXhfUzEpICogbG9jYWxDb29yZC54eTE7Cgl9Cn0KAAAAAGsCAAB1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzE7CnNhbXBsZXIyRCB1VGV4dHVyZVNhbXBsZXJfMF9TMTsKZmxhdCBpbiBoYWxmNCB2Y29sb3JfUzA7CmluIGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKaGFsZjQgVGV4dHVyZUVmZmVjdF9TMV9jMChoYWxmNCBfaW5wdXQpIAp7CglyZXR1cm4gc2FtcGxlKHVUZXh0dXJlU2FtcGxlcl8wX1MxLCB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMCkucnJycjsKfQpoYWxmNCBNYXRyaXhFZmZlY3RfUzEoaGFsZjQgX2lucHV0KSAKewoJcmV0dXJuIFRleHR1cmVFZmZlY3RfUzFfYzAoX2lucHV0KTsKfQp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmNvbG9yX1MwOwoJY29uc3QgaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNCgxKTsKCWhhbGY0IG91dHB1dF9TMTsKCW91dHB1dF9TMSA9IE1hdHJpeEVmZmVjdF9TMShvdXRwdXRDb3ZlcmFnZV9TMCk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRfUzE7Cgl9Cn0KAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAADAAAACAAAAHBvc2l0aW9uBQAAAGNvbG9yAAAACgAAAGxvY2FsQ29vcmQAAAAAAAA=","HVIAAAAAABIAAGAAAQ4AAAH477776R24EAAAIOBQAD6P7777777777YDAAAAAAAAAAAFIBUAFS7EOCAAAAAGZJY26AAQAAAA2S5KXK4QAAAAAMAAAAAAAAQAABQM74NUDECAAAAAQ5UOAMQAAAAAAAAAAEAAAAAZ3FHDLYADAAAABKDVK5LSCAIAABQAAAAAAACAAAGAT3RWSMYIAAAAADWRYBSQAAAAAAAQAAAAGJJOXLVOIIBAAAGAAAAAAAAIAAAIAPOH2NTBAAAAAAOKFAOLAAAAAAAEAAAAAMQQAIAAAYGP6G2BSBAAACAAAAAAAAM5S4Z4NUDACAAAAAAAAADAIUOKFAOLAAAAAAACAAAAAZGIEENLQDAAAAAAAAAAABQAKAIAAIAAAADIBCEAQAAAAAAAAAAAIADQAAAAIAAAAAAAIIDA":"DAAAAExTS1OGAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMV9jMF9jMF9jMTsKaW4gZmxvYXQyIHBvc2l0aW9uOwppbiBoYWxmNCBjb2xvcjsKaW4gZmxvYXQyIGxvY2FsQ29vcmQ7CmZsYXQgb3V0IGhhbGY0IHZjb2xvcl9TMDsKb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfN19TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgl2Y29sb3JfUzAgPSBjb2xvcjsKCXNrX1Bvc2l0aW9uID0gcG9zaXRpb24ueHkwMTsKCXsKCQl2VHJhbnNmb3JtZWRDb29yZHNfN19TMCA9IGZsb2F0M3gyKHVtYXRyaXhfUzFfYzBfYzBfYzEpICogbG9jYWxDb29yZC54eTE7Cgl9Cn0KAAABAAAAIQoAAHVuaWZvcm0gaGFsZjQgdXN0YXJ0X1MxX2MwX2MwX2MwX2MwOwp1bmlmb3JtIGhhbGY0IHVlbmRfUzFfYzBfYzBfYzBfYzA7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMV9jMF9jMF9jMTsKdW5pZm9ybSBoYWxmNCB1bGVmdEJvcmRlckNvbG9yX1MxX2MwX2MwOwp1bmlmb3JtIGhhbGY0IHVyaWdodEJvcmRlckNvbG9yX1MxX2MwX2MwOwp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzFfYzE7CnVuaWZvcm0gaGFsZiB1cmFuZ2VfUzE7CnNhbXBsZXIyRCB1VGV4dHVyZVNhbXBsZXJfMF9TMTsKZmxhdCBpbiBoYWxmNCB2Y29sb3JfUzA7CmluIGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfN19TMDsKaGFsZjQgU2luZ2xlSW50ZXJ2YWxDb2xvcml6ZXJfUzFfYzBfYzBfYzBfYzAoaGFsZjQgX2lucHV0LCBmbG9hdDIgX2Nvb3JkcykgCnsKCWhhbGY0IF90bXBfMF9pbkNvbG9yID0gX2lucHV0OwoJZmxvYXQyIF90bXBfMV9jb29yZHMgPSBfY29vcmRzOwoJcmV0dXJuIGhhbGY0KG1peCh1c3RhcnRfUzFfYzBfYzBfYzBfYzAsIHVlbmRfUzFfYzBfYzBfYzBfYzAsIGhhbGYoX3RtcF8xX2Nvb3Jkcy54KSkpOwp9CmhhbGY0IGNvbG9yX3hmb3JtX1MxX2MwX2MwX2MwKGZsb2F0NCBjb2xvcikgCnsKCWNvbG9yLnJnYiAqPSBjb2xvci5hOwoJcmV0dXJuIGhhbGY0KGNvbG9yKTsKfQpoYWxmNCBDb2xvclNwYWNlWGZvcm1fUzFfYzBfYzBfYzAoaGFsZjQgX2lucHV0LCBmbG9hdDIgX2Nvb3JkcykgCnsKCXJldHVybiBjb2xvcl94Zm9ybV9TMV9jMF9jMF9jMChTaW5nbGVJbnRlcnZhbENvbG9yaXplcl9TMV9jMF9jMF9jMF9jMChfaW5wdXQsIF9jb29yZHMpKTsKfQpoYWxmNCBMaW5lYXJMYXlvdXRfUzFfYzBfYzBfYzFfYzAoaGFsZjQgX2lucHV0KSAKewoJaGFsZjQgX3RtcF8yX2luQ29sb3IgPSBfaW5wdXQ7CglmbG9hdDIgX3RtcF8zX2Nvb3JkcyA9IHZUcmFuc2Zvcm1lZENvb3Jkc183X1MwOwoJcmV0dXJuIGhhbGY0KGhhbGY0KGhhbGYoX3RtcF8zX2Nvb3Jkcy54KSArIDFlLTA1LCAxLjAsIDAuMCwgMC4wKSk7Cn0KaGFsZjQgTWF0cml4RWZmZWN0X1MxX2MwX2MwX2MxKGhhbGY0IF9pbnB1dCkgCnsKCXJldHVybiBMaW5lYXJMYXlvdXRfUzFfYzBfYzBfYzFfYzAoX2lucHV0KTsKfQpoYWxmNCBDbGFtcGVkR3JhZGllbnRfUzFfYzBfYzAoaGFsZjQgX2lucHV0KSAKewoJaGFsZjQgX3RtcF80X2luQ29sb3IgPSBfaW5wdXQ7CgloYWxmNCB0ID0gTWF0cml4RWZmZWN0X1MxX2MwX2MwX2MxKF90bXBfNF9pbkNvbG9yKTsKCWhhbGY0IG91dENvbG9yOwoJaWYgKCFib29sKGludCgxKSkgJiYgdC55IDwgMC4wKSAKCXsKCQlvdXRDb2xvciA9IGhhbGY0KDAuMCk7Cgl9CgllbHNlIGlmICh0LnggPCAwLjApIAoJewoJCW91dENvbG9yID0gdWxlZnRCb3JkZXJDb2xvcl9TMV9jMF9jMDsKCX0KCWVsc2UgaWYgKHQueCA+IDEuMCkgCgl7CgkJb3V0Q29sb3IgPSB1cmlnaHRCb3JkZXJDb2xvcl9TMV9jMF9jMDsKCX0KCWVsc2UgCgl7CgkJb3V0Q29sb3IgPSBDb2xvclNwYWNlWGZvcm1fUzFfYzBfYzBfYzAoX3RtcF80X2luQ29sb3IsIGZsb2F0MihoYWxmMih0LngsIDAuMCkpKTsKCX0KCXJldHVybiBoYWxmNChvdXRDb2xvcik7Cn0KaGFsZjQgRGlzYWJsZUNvdmVyYWdlQXNBbHBoYV9TMV9jMChoYWxmNCBfaW5wdXQpIAp7CglfaW5wdXQgPSBDbGFtcGVkR3JhZGllbnRfUzFfYzBfYzAoX2lucHV0KTsKCWhhbGY0IF90bXBfNV9pbkNvbG9yID0gX2lucHV0OwoJcmV0dXJuIGhhbGY0KF9pbnB1dCk7Cn0KaGFsZjQgVGV4dHVyZUVmZmVjdF9TMV9jMV9jMChoYWxmNCBfaW5wdXQsIGZsb2F0MiBfY29vcmRzKSAKewoJcmV0dXJuIHNhbXBsZSh1VGV4dHVyZVNhbXBsZXJfMF9TMSwgX2Nvb3JkcykuMDAwcjsKfQpoYWxmNCBNYXRyaXhFZmZlY3RfUzFfYzEoaGFsZjQgX2lucHV0LCBmbG9hdDIgX2Nvb3JkcykgCnsKCXJldHVybiBUZXh0dXJlRWZmZWN0X1MxX2MxX2MwKF9pbnB1dCwgZmxvYXQzeDIodW1hdHJpeF9TMV9jMSkgKiBfY29vcmRzLnh5MSk7Cn0KaGFsZjQgRGl0aGVyX1MxKGhhbGY0IF9pbnB1dCkgCnsKCWhhbGY0IF90bXBfNl9pbkNvbG9yID0gX2lucHV0OwoJaGFsZjQgY29sb3IgPSBEaXNhYmxlQ292ZXJhZ2VBc0FscGhhX1MxX2MwKF90bXBfNl9pbkNvbG9yKTsKCWhhbGYgdmFsdWUgPSBNYXRyaXhFZmZlY3RfUzFfYzEoX3RtcF82X2luQ29sb3IsIHNrX0ZyYWdDb29yZC54eSkudyAtIDAuNTsKCXJldHVybiBoYWxmNChoYWxmNChjbGFtcChjb2xvci54eXogKyB2YWx1ZSAqIHVyYW5nZV9TMSwgMC4wLCBjb2xvci53KSwgY29sb3IudykpOwp9CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2Y29sb3JfUzA7Cgljb25zdCBoYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KDEpOwoJaGFsZjQgb3V0cHV0X1MxOwoJb3V0cHV0X1MxID0gRGl0aGVyX1MxKG91dHB1dENvbG9yX1MwKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRfUzEgKiBvdXRwdXRDb3ZlcmFnZV9TMDsKCX0KfQoAAAABAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAgAAABwb3NpdGlvbgUAAABjb2xvcgAAAAoAAABsb2NhbENvb3JkAAAAAAAA","DAQAAAAAAAAAAAAAAJQAAIGAAEACBYQCAGAEFAIBAAAAAABAAAAAAAAAAAACAB4QA4AAAEAAAAAABIADAAAAAIAAAAAAAIID":"DAAAAExTS1MWAgAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQyIHVBdGxhc1NpemVJbnZfUzA7CmluIGZsb2F0MiBpblBvc2l0aW9uOwppbiBoYWxmNCBpbkNvbG9yOwppbiB1c2hvcnQyIGluVGV4dHVyZUNvb3JkczsKb3V0IGZsb2F0MiB2VGV4dHVyZUNvb3Jkc19TMDsKZmxhdCBvdXQgZmxvYXQgdlRleEluZGV4X1MwOwpvdXQgaGFsZjQgdmluQ29sb3JfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIEJpdG1hcFRleHQKCWludCB0ZXhJZHggPSAwOwoJZmxvYXQyIHVub3JtVGV4Q29vcmRzID0gZmxvYXQyKGluVGV4dHVyZUNvb3Jkcy54LCBpblRleHR1cmVDb29yZHMueSk7Cgl2VGV4dHVyZUNvb3Jkc19TMCA9IHVub3JtVGV4Q29vcmRzICogdUF0bGFzU2l6ZUludl9TMDsKCXZUZXhJbmRleF9TMCA9IGZsb2F0KHRleElkeCk7Cgl2aW5Db2xvcl9TMCA9IGluQ29sb3I7CglmbG9hdDIgX3RtcF8xX2luUG9zaXRpb24gPSBpblBvc2l0aW9uOwoJc2tfUG9zaXRpb24gPSBpblBvc2l0aW9uLnh5MDE7Cn0KAAABAAAAOAMAAHVuaWZvcm0gZmxvYXQ0IHVpbm5lclJlY3RfUzE7CnVuaWZvcm0gaGFsZjIgdXJhZGl1c1BsdXNIYWxmX1MxOwpzYW1wbGVyMkQgdVRleHR1cmVTYW1wbGVyXzBfUzA7CmluIGZsb2F0MiB2VGV4dHVyZUNvb3Jkc19TMDsKZmxhdCBpbiBmbG9hdCB2VGV4SW5kZXhfUzA7CmluIGhhbGY0IHZpbkNvbG9yX1MwOwpoYWxmNCBDaXJjdWxhclJSZWN0X1MxKGhhbGY0IF9pbnB1dCkgCnsKCWZsb2F0MiBkeHkwID0gdWlubmVyUmVjdF9TMS5MVCAtIHNrX0ZyYWdDb29yZC54eTsKCWZsb2F0MiBkeHkxID0gc2tfRnJhZ0Nvb3JkLnh5IC0gdWlubmVyUmVjdF9TMS5SQjsKCWZsb2F0MiBkeHkgPSBtYXgobWF4KGR4eTAsIGR4eTEpLCAwLjApOwoJaGFsZiBhbHBoYSA9IGhhbGYoc2F0dXJhdGUodXJhZGl1c1BsdXNIYWxmX1MxLnggLSBsZW5ndGgoZHh5KSkpOwoJcmV0dXJuIF9pbnB1dCAqIGFscGhhOwp9CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBCaXRtYXBUZXh0CgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmluQ29sb3JfUzA7CgloYWxmNCB0ZXhDb2xvcjsKCXsKCQl0ZXhDb2xvciA9IHNhbXBsZSh1VGV4dHVyZVNhbXBsZXJfMF9TMCwgdlRleHR1cmVDb29yZHNfUzApLnJycnI7Cgl9CgloYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IHRleENvbG9yOwoJaGFsZjQgb3V0cHV0X1MxOwoJb3V0cHV0X1MxID0gQ2lyY3VsYXJSUmVjdF9TMShvdXRwdXRDb3ZlcmFnZV9TMCk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRfUzE7Cgl9Cn0KAQAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAKAAAAaW5Qb3NpdGlvbgAABwAAAGluQ29sb3IADwAAAGluVGV4dHVyZUNvb3JkcwAAAAAA","HWJQAAAAABEAADAAAIOAAAAADIIAB7X7777QGHAYAD7P7777A4QCQAAAAAAAAAQAAAAAAQQGACQAGAAAAAQAAAAAAAQQGAAA":"DAAAAExTS1OaAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gZmxvYXQgY292ZXJhZ2U7CmluIGZsb2F0MiBsb2NhbENvb3JkOwppbiBmbG9hdDQgdGV4U3Vic2V0OwpvdXQgZmxvYXQyIHZsb2NhbENvb3JkX1MwOwpmbGF0IG91dCBmbG9hdDQgdnRleFN1YnNldF9TMDsKb3V0IGZsb2F0IHZjb3ZlcmFnZV9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCglmbG9hdDIgcG9zaXRpb24gPSBwb3NpdGlvbi54eTsKCXZsb2NhbENvb3JkX1MwID0gbG9jYWxDb29yZDsKCXZ0ZXhTdWJzZXRfUzAgPSB0ZXhTdWJzZXQ7Cgl2Y292ZXJhZ2VfUzAgPSBjb3ZlcmFnZTsKCXNrX1Bvc2l0aW9uID0gcG9zaXRpb24ueHkwMTsKfQoAAAAAAABcAgAAc2FtcGxlcjJEIHVUZXh0dXJlU2FtcGxlcl8wX1MwOwppbiBmbG9hdDIgdmxvY2FsQ29vcmRfUzA7CmZsYXQgaW4gZmxvYXQ0IHZ0ZXhTdWJzZXRfUzA7CmluIGZsb2F0IHZjb3ZlcmFnZV9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJaGFsZjQgb3V0cHV0Q29sb3JfUzAgPSBoYWxmNCgxKTsKCWZsb2F0MiB0ZXhDb29yZDsKCXRleENvb3JkID0gdmxvY2FsQ29vcmRfUzA7CglmbG9hdDQgc3Vic2V0OwoJc3Vic2V0ID0gdnRleFN1YnNldF9TMDsKCXRleENvb3JkID0gY2xhbXAodGV4Q29vcmQsIHN1YnNldC5MVCwgc3Vic2V0LlJCKTsKCW91dHB1dENvbG9yX1MwID0gKGJsZW5kX21vZHVsYXRlKHNhbXBsZSh1VGV4dHVyZVNhbXBsZXJfMF9TMCwgdGV4Q29vcmQpLCBoYWxmNCgxKSkpOwoJZmxvYXQgY292ZXJhZ2UgPSB2Y292ZXJhZ2VfUzA7CgloYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KGhhbGYoY292ZXJhZ2UpKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dENvdmVyYWdlX1MwOwoJfQp9CgAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAEAAAACAAAAHBvc2l0aW9uCAAAAGNvdmVyYWdlCgAAAGxvY2FsQ29vcmQAAAkAAAB0ZXhTdWJzZXQAAAAAAAAA","HUQACAAAAAMAADAAAIOAAAH677776IZOCAAP577777777777777777YBAAAAAAAAAAAKAAYAAAACAAAAAAACCAYAAA":"DAAAAExTS1PPAAAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gaGFsZjQgY29sb3I7Cm91dCBoYWxmNCB2Y29sb3JfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJdmNvbG9yX1MwID0gY29sb3I7Cglza19Qb3NpdGlvbiA9IHBvc2l0aW9uLnh5MDE7Cn0KAAAAAAAMAQAAaW4gaGFsZjQgdmNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmNvbG9yX1MwOwoJY29uc3QgaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNCgxKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dENvdmVyYWdlX1MwOwoJfQp9CgAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAACAAAACAAAAHBvc2l0aW9uBQAAAGNvbG9yAAAAAAAAAA==","HUQACAAAAAMAADAAAIOAAAH677776IZOCAAP577777777777777777YBAAAAAAAAAAAHEADZAAAAAAIAAAAAAOQAAAAAAAQAAAABAMQAAAAAA":"DAAAAExTS1PPAAAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gaGFsZjQgY29sb3I7Cm91dCBoYWxmNCB2Y29sb3JfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJdmNvbG9yX1MwID0gY29sb3I7Cglza19Qb3NpdGlvbiA9IHBvc2l0aW9uLnh5MDE7Cn0KAAEAAACbAgAAdW5pZm9ybSBmbG9hdDQgdWlubmVyUmVjdF9TMTsKdW5pZm9ybSBoYWxmMiB1cmFkaXVzUGx1c0hhbGZfUzE7CmluIGhhbGY0IHZjb2xvcl9TMDsKaGFsZjQgQ2lyY3VsYXJSUmVjdF9TMShoYWxmNCBfaW5wdXQpIAp7CglmbG9hdDIgZHh5MCA9IHVpbm5lclJlY3RfUzEuTFQgLSBza19GcmFnQ29vcmQueHk7CglmbG9hdDIgZHh5MSA9IHNrX0ZyYWdDb29yZC54eSAtIHVpbm5lclJlY3RfUzEuUkI7CglmbG9hdDIgZHh5ID0gbWF4KG1heChkeHkwLCBkeHkxKSwgMC4wKTsKCWhhbGYgYWxwaGEgPSBoYWxmKHNhdHVyYXRlKHVyYWRpdXNQbHVzSGFsZl9TMS54IC0gbGVuZ3RoKGR4eSkpKTsKCXJldHVybiBfaW5wdXQgKiBhbHBoYTsKfQp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmNvbG9yX1MwOwoJY29uc3QgaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNCgxKTsKCWhhbGY0IG91dHB1dF9TMTsKCW91dHB1dF9TMSA9IENpcmN1bGFyUlJlY3RfUzEob3V0cHV0Q292ZXJhZ2VfUzApOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dENvbG9yX1MwICogb3V0cHV0X1MxOwoJfQp9CgABAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAgAAABwb3NpdGlvbgUAAABjb2xvcgAAAAAAAAA=","AYAA5AADQAAAOAEARAFQJAABBADIB7777777777777777777777767YAAAAAAAAAAAAOQAAAAAAAQAAAABAMQAAAAA":"DAAAAExTS1OCAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0MiBpblBvc2l0aW9uOwppbiBoYWxmNCBpbkNvbG9yOwppbiBmbG9hdDQgaW5DaXJjbGVFZGdlOwpvdXQgZmxvYXQ0IHZpbkNpcmNsZUVkZ2VfUzA7Cm91dCBoYWxmNCB2aW5Db2xvcl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgQ2lyY2xlR2VvbWV0cnlQcm9jZXNzb3IKCXZpbkNpcmNsZUVkZ2VfUzAgPSBpbkNpcmNsZUVkZ2U7Cgl2aW5Db2xvcl9TMCA9IGluQ29sb3I7CglmbG9hdDIgX3RtcF8wX2luUG9zaXRpb24gPSBpblBvc2l0aW9uOwoJZmxvYXQyIF90bXBfMl9pblBvc2l0aW9uID0gaW5Qb3NpdGlvbjsKCXNrX1Bvc2l0aW9uID0gX3RtcF8wX2luUG9zaXRpb24ueHkwMTsKfQoAAAAAAADqAQAAaW4gZmxvYXQ0IHZpbkNpcmNsZUVkZ2VfUzA7CmluIGhhbGY0IHZpbkNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgQ2lyY2xlR2VvbWV0cnlQcm9jZXNzb3IKCWZsb2F0NCBjaXJjbGVFZGdlOwoJY2lyY2xlRWRnZSA9IHZpbkNpcmNsZUVkZ2VfUzA7CgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmluQ29sb3JfUzA7CglmbG9hdCBkID0gbGVuZ3RoKGNpcmNsZUVkZ2UueHkpOwoJaGFsZiBkaXN0YW5jZVRvT3V0ZXJFZGdlID0gaGFsZihjaXJjbGVFZGdlLnogKiAoMS4wIC0gZCkpOwoJaGFsZiBlZGdlQWxwaGEgPSBzYXR1cmF0ZShkaXN0YW5jZVRvT3V0ZXJFZGdlKTsKCWhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoZWRnZUFscGhhKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dENvdmVyYWdlX1MwOwoJfQp9CgAAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAKAAAAaW5Qb3NpdGlvbgAABwAAAGluQ29sb3IADAAAAGluQ2lyY2xlRWRnZQAAAAA=","BYIBQAAABQAAIAABBYAAAEIXBAAP777777777777AAAAAAAAAAAABUABAAAAAEAAAAAIBEABAAAAA":"DAAAAExTS1M+AQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0MiBpblBvc2l0aW9uOwppbiBoYWxmNCBpbkNvbG9yOwpvdXQgaGFsZjQgdmNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBEZWZhdWx0R2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IGNvbG9yID0gaW5Db2xvcjsKCXZjb2xvcl9TMCA9IGNvbG9yOwoJZmxvYXQyIF90bXBfMV9pblBvc2l0aW9uID0gaW5Qb3NpdGlvbjsKCWZsb2F0MiBfdG1wXzNfaW5Qb3NpdGlvbiA9IGluUG9zaXRpb247Cglza19Qb3NpdGlvbiA9IF90bXBfMV9pblBvc2l0aW9uLnh5MDE7Cn0KAAAAAAAABgEAAGluIGhhbGY0IHZjb2xvcl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIERlZmF1bHRHZW9tZXRyeVByb2Nlc3NvcgoJaGFsZjQgb3V0cHV0Q29sb3JfUzA7CglvdXRwdXRDb2xvcl9TMCA9IHZjb2xvcl9TMDsKCWNvbnN0IGhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoMSk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRDb3ZlcmFnZV9TMDsKCX0KfQoAAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAACAAAACgAAAGluUG9zaXRpb24AAAcAAABpbkNvbG9yAAAAAAA=","DASAAAAAAAAAAAEAAFQAAIGAAEAOB77776PUEAIBAAAAAABAAAAAAABAMQAAAOQAAAAAAAQAAAABAMQAAAAA":"DAAAAExTS1PVAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQyIHVBdGxhc1NpemVJbnZfUzA7CmluIGZsb2F0MiBpblBvc2l0aW9uOwppbiB1c2hvcnQyIGluVGV4dHVyZUNvb3JkczsKb3V0IGZsb2F0MiB2VGV4dHVyZUNvb3Jkc19TMDsKZmxhdCBvdXQgZmxvYXQgdlRleEluZGV4X1MwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBCaXRtYXBUZXh0CglpbnQgdGV4SWR4ID0gMDsKCWZsb2F0MiB1bm9ybVRleENvb3JkcyA9IGZsb2F0MihpblRleHR1cmVDb29yZHMueCwgaW5UZXh0dXJlQ29vcmRzLnkpOwoJdlRleHR1cmVDb29yZHNfUzAgPSB1bm9ybVRleENvb3JkcyAqIHVBdGxhc1NpemVJbnZfUzA7Cgl2VGV4SW5kZXhfUzAgPSBmbG9hdCh0ZXhJZHgpOwoJZmxvYXQyIF90bXBfMV9pblBvc2l0aW9uID0gaW5Qb3NpdGlvbjsKCXNrX1Bvc2l0aW9uID0gaW5Qb3NpdGlvbi54eTAxOwp9CgAAAAAAAADYAQAAdW5pZm9ybSBoYWxmNCB1Q29sb3JfUzA7CnNhbXBsZXIyRCB1VGV4dHVyZVNhbXBsZXJfMF9TMDsKaW4gZmxvYXQyIHZUZXh0dXJlQ29vcmRzX1MwOwpmbGF0IGluIGZsb2F0IHZUZXhJbmRleF9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIEJpdG1hcFRleHQKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB1Q29sb3JfUzA7CgloYWxmNCB0ZXhDb2xvcjsKCXsKCQl0ZXhDb2xvciA9IHNhbXBsZSh1VGV4dHVyZVNhbXBsZXJfMF9TMCwgdlRleHR1cmVDb29yZHNfUzApOwoJfQoJb3V0cHV0Q29sb3JfUzAgPSBvdXRwdXRDb2xvcl9TMCAqIHRleENvbG9yOwoJY29uc3QgaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNCgxKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dENvdmVyYWdlX1MwOwoJfQp9CgAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAACAAAACgAAAGluUG9zaXRpb24AAA8AAABpblRleHR1cmVDb29yZHMAAAAAAA==","AYQQ5AADQAAAOAEARAFQJAABBADIB7777777777777777777777767YAAAAAAAAAAAAOQAAAAAAAQAAAABAMQAAAAA":"DAAAAExTS1PMAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQ0IHVsb2NhbE1hdHJpeF9TMDsKaW4gZmxvYXQyIGluUG9zaXRpb247CmluIGhhbGY0IGluQ29sb3I7CmluIGZsb2F0NCBpbkNpcmNsZUVkZ2U7Cm91dCBmbG9hdDQgdmluQ2lyY2xlRWRnZV9TMDsKb3V0IGhhbGY0IHZpbkNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBDaXJjbGVHZW9tZXRyeVByb2Nlc3NvcgoJdmluQ2lyY2xlRWRnZV9TMCA9IGluQ2lyY2xlRWRnZTsKCXZpbkNvbG9yX1MwID0gaW5Db2xvcjsKCWZsb2F0MiBfdG1wXzBfaW5Qb3NpdGlvbiA9IGluUG9zaXRpb247CglmbG9hdDIgX3RtcF8xX2luUG9zaXRpb24gPSB1bG9jYWxNYXRyaXhfUzAueHogKiBpblBvc2l0aW9uICsgdWxvY2FsTWF0cml4X1MwLnl3OwoJc2tfUG9zaXRpb24gPSBfdG1wXzBfaW5Qb3NpdGlvbi54eTAxOwp9CgAAAAB7AgAAaW4gZmxvYXQ0IHZpbkNpcmNsZUVkZ2VfUzA7CmluIGhhbGY0IHZpbkNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgQ2lyY2xlR2VvbWV0cnlQcm9jZXNzb3IKCWZsb2F0NCBjaXJjbGVFZGdlOwoJY2lyY2xlRWRnZSA9IHZpbkNpcmNsZUVkZ2VfUzA7CgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmluQ29sb3JfUzA7CglmbG9hdCBkID0gbGVuZ3RoKGNpcmNsZUVkZ2UueHkpOwoJaGFsZiBkaXN0YW5jZVRvT3V0ZXJFZGdlID0gaGFsZihjaXJjbGVFZGdlLnogKiAoMS4wIC0gZCkpOwoJaGFsZiBlZGdlQWxwaGEgPSBzYXR1cmF0ZShkaXN0YW5jZVRvT3V0ZXJFZGdlKTsKCWhhbGYgZGlzdGFuY2VUb0lubmVyRWRnZSA9IGhhbGYoY2lyY2xlRWRnZS56ICogKGQgLSBjaXJjbGVFZGdlLncpKTsKCWhhbGYgaW5uZXJBbHBoYSA9IHNhdHVyYXRlKGRpc3RhbmNlVG9Jbm5lckVkZ2UpOwoJZWRnZUFscGhhICo9IGlubmVyQWxwaGE7CgloYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KGVkZ2VBbHBoYSk7Cgl7CgkJLy8gWGZlciBQcm9jZXNzb3I6IFBvcnRlciBEdWZmCgkJc2tfRnJhZ0NvbG9yID0gb3V0cHV0Q29sb3JfUzAgKiBvdXRwdXRDb3ZlcmFnZV9TMDsKCX0KfQoAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAKAAAAaW5Qb3NpdGlvbgAABwAAAGluQ29sb3IADAAAAGluQ2lyY2xlRWRnZQAAAAA=","HWQACAAAABAAADAAAIOAAAAADIIAAIRODAAP577774DSAIAA737777YBAAAAAAAAAAAKAAYAAAACAAAAAAACCAYAAA":"DAAAAExTS1ONAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gZmxvYXQgY292ZXJhZ2U7CmluIGhhbGY0IGNvbG9yOwppbiBmbG9hdDQgZ2VvbVN1YnNldDsKZmxhdCBvdXQgaGFsZjQgdmNvbG9yX1MwOwpvdXQgZmxvYXQgdmNvdmVyYWdlX1MwOwpmbGF0IG91dCBmbG9hdDQgdmdlb21TdWJzZXRfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJZmxvYXQyIHBvc2l0aW9uID0gcG9zaXRpb24ueHk7Cgl2Y29sb3JfUzAgPSBjb2xvcjsKCXZjb3ZlcmFnZV9TMCA9IGNvdmVyYWdlOwoJdmdlb21TdWJzZXRfUzAgPSBnZW9tU3Vic2V0OwoJc2tfUG9zaXRpb24gPSBwb3NpdGlvbi54eTAxOwp9CgAAAAEAAAB5AgAAZmxhdCBpbiBoYWxmNCB2Y29sb3JfUzA7CmluIGZsb2F0IHZjb3ZlcmFnZV9TMDsKZmxhdCBpbiBmbG9hdDQgdmdlb21TdWJzZXRfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2Y29sb3JfUzA7CglmbG9hdCBjb3ZlcmFnZSA9IHZjb3ZlcmFnZV9TMDsKCWZsb2F0NCBnZW9TdWJzZXQ7CglnZW9TdWJzZXQgPSB2Z2VvbVN1YnNldF9TMDsKCWhhbGY0IGRpc3RzNCA9IGNsYW1wKGhhbGY0KDEsIDEsIC0xLCAtMSkgKiBoYWxmNChza19GcmFnQ29vcmQueHl4eSAtIGdlb1N1YnNldCksIDAsIDEpOwoJaGFsZjIgZGlzdHMyID0gZGlzdHM0Lnh5ICsgZGlzdHM0Lnp3IC0gMTsKCWhhbGYgc3Vic2V0Q292ZXJhZ2UgPSBkaXN0czIueCAqIGRpc3RzMi55OwoJY292ZXJhZ2UgPSBtaW4oY292ZXJhZ2UsIHN1YnNldENvdmVyYWdlKTsKCWhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoaGFsZihjb3ZlcmFnZSkpOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dENvbG9yX1MwICogb3V0cHV0Q292ZXJhZ2VfUzA7Cgl9Cn0KAAAAAQAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAIAAAAcG9zaXRpb24IAAAAY292ZXJhZ2UFAAAAY29sb3IAAAAKAAAAZ2VvbVN1YnNldAAAAAAAAA==","HUQACAAAAAMAADAAAIOAAAH677776IZOCAAP577777777777777777YBAAAAAAAAAAADEAAGAAAAAAAAAIAAAAAPAIABAAAAACYGEAAAAEAAAABUARCAIAAAAAAAAAAAACQAGAAAAAQAAAAAAAQQGAAAAA":"DAAAAExTS1NjAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMV9jMF9jMDsKaW4gZmxvYXQyIHBvc2l0aW9uOwppbiBoYWxmNCBjb2xvcjsKb3V0IGhhbGY0IHZjb2xvcl9TMDsKb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfNF9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgl2Y29sb3JfUzAgPSBjb2xvcjsKCXNrX1Bvc2l0aW9uID0gcG9zaXRpb24ueHkwMTsKCXsKCQl2VHJhbnNmb3JtZWRDb29yZHNfNF9TMCA9IGZsb2F0M3gyKHVtYXRyaXhfUzFfYzBfYzApICogcG9zaXRpb24ueHkxOwoJfQp9CgAAAAAANAMAAHVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMV9jMF9jMDsKc2FtcGxlcjJEIHVUZXh0dXJlU2FtcGxlcl8wX1MxOwppbiBoYWxmNCB2Y29sb3JfUzA7CmluIGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfNF9TMDsKaGFsZjQgVGV4dHVyZUVmZmVjdF9TMV9jMF9jMF9jMChoYWxmNCBfaW5wdXQpIAp7CglyZXR1cm4gc2FtcGxlKHVUZXh0dXJlU2FtcGxlcl8wX1MxLCB2VHJhbnNmb3JtZWRDb29yZHNfNF9TMCkuMDAwcjsKfQpoYWxmNCBNYXRyaXhFZmZlY3RfUzFfYzBfYzAoaGFsZjQgX2lucHV0KSAKewoJcmV0dXJuIFRleHR1cmVFZmZlY3RfUzFfYzBfYzBfYzAoX2lucHV0KTsKfQpoYWxmNCBEZXZpY2VTcGFjZV9TMV9jMChoYWxmNCBfaW5wdXQpIAp7CglyZXR1cm4gTWF0cml4RWZmZWN0X1MxX2MwX2MwKF9pbnB1dCk7Cn0KaGFsZjQgQmxlbmRfUzEoaGFsZjQgX3NyYywgaGFsZjQgX2RzdCkgCnsKCXJldHVybiBibGVuZF9kc3RfaW4oRGV2aWNlU3BhY2VfUzFfYzAoX3NyYyksIF9zcmMpOwp9CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2Y29sb3JfUzA7Cgljb25zdCBoYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KDEpOwoJaGFsZjQgb3V0cHV0X1MxOwoJb3V0cHV0X1MxID0gQmxlbmRfUzEob3V0cHV0Q292ZXJhZ2VfUzAsIGhhbGY0KDEpKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dF9TMTsKCX0KfQoAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAgAAABwb3NpdGlvbgUAAABjb2xvcgAAAAAAAAA=","HUIAAAAAAAQAADAAAIOAAAH677777777777QGHAQAD7P7777777777YBAAAAAAAAAAALUAQJALJKL2AAAAAAAAAEAAAABSCQQKAHIKJ2AAAAAAAAAEAAAABLBAABAAAAABAEGABBAMAAAAAAAAAAAOQAAAAAAAQAAAABAMQAAAAAA":"DAAAAExTS1M2AQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMTsKaW4gZmxvYXQyIHBvc2l0aW9uOwppbiBmbG9hdDIgbG9jYWxDb29yZDsKb3V0IGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCglza19Qb3NpdGlvbiA9IHBvc2l0aW9uLnh5MDE7Cgl7CgkJdlRyYW5zZm9ybWVkQ29vcmRzXzJfUzAgPSBmbG9hdDN4Mih1bWF0cml4X1MxKSAqIGxvY2FsQ29vcmQueHkxOwoJfQp9CgAAAAAAACoFAABjb25zdCBpbnQga01heExvb3BMaW1pdF9TMV9jMCA9IDY7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMV9jMF9jMDsKdW5pZm9ybSBoYWxmNCB1b2Zmc2V0c0FuZEtlcm5lbF9TMV9jMFsxNF07CnVuaWZvcm0gaGFsZjIgdWRpcl9TMV9jMDsKdW5pZm9ybSBmbG9hdDN4MyB1bWF0cml4X1MxOwpzYW1wbGVyMkQgdVRleHR1cmVTYW1wbGVyXzBfUzE7CmluIGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKaGFsZjQgVGV4dHVyZUVmZmVjdF9TMV9jMF9jMF9jMChoYWxmNCBfaW5wdXQsIGZsb2F0MiBfY29vcmRzKSAKewoJcmV0dXJuIHNhbXBsZSh1VGV4dHVyZVNhbXBsZXJfMF9TMSwgX2Nvb3Jkcyk7Cn0KaGFsZjQgTWF0cml4RWZmZWN0X1MxX2MwX2MwKGhhbGY0IF9pbnB1dCwgZmxvYXQyIF9jb29yZHMpIAp7CglyZXR1cm4gVGV4dHVyZUVmZmVjdF9TMV9jMF9jMF9jMChfaW5wdXQsIGZsb2F0M3gyKHVtYXRyaXhfUzFfYzBfYzApICogX2Nvb3Jkcy54eTEpOwp9CmhhbGY0IEdhdXNzaWFuQmx1cjFEX1MxX2MwKGhhbGY0IF9pbnB1dCkgCnsKCWhhbGY0IF90bXBfMF9pbkNvbG9yID0gX2lucHV0OwoJZmxvYXQyIF90bXBfMV9jb29yZHMgPSB2VHJhbnNmb3JtZWRDb29yZHNfMl9TMDsKCWhhbGY0IHN1bSA9IGhhbGY0KDAuMCk7Cglmb3IgKGludCBpID0gMDtpIDwga01heExvb3BMaW1pdF9TMV9jMDsgKytpKSAKCXsKCQloYWxmNCBzID0gdW9mZnNldHNBbmRLZXJuZWxfUzFfYzBbaV07CgkJc3VtICs9IHMueSAqIE1hdHJpeEVmZmVjdF9TMV9jMF9jMChfdG1wXzBfaW5Db2xvciwgX3RtcF8xX2Nvb3JkcyArIGZsb2F0MihzLnggKiB1ZGlyX1MxX2MwKSk7CgkJc3VtICs9IHMudyAqIE1hdHJpeEVmZmVjdF9TMV9jMF9jMChfdG1wXzBfaW5Db2xvciwgX3RtcF8xX2Nvb3JkcyArIGZsb2F0MihzLnogKiB1ZGlyX1MxX2MwKSk7Cgl9CglyZXR1cm4gaGFsZjQoc3VtKTsKfQpoYWxmNCBNYXRyaXhFZmZlY3RfUzEoaGFsZjQgX2lucHV0KSAKewoJcmV0dXJuIEdhdXNzaWFuQmx1cjFEX1MxX2MwKF9pbnB1dCk7Cn0Kdm9pZCBtYWluKCkgCnsKCS8vIFN0YWdlIDAsIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJaGFsZjQgb3V0cHV0Q29sb3JfUzAgPSBoYWxmNCgxKTsKCWNvbnN0IGhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoMSk7CgloYWxmNCBvdXRwdXRfUzE7CglvdXRwdXRfUzEgPSBNYXRyaXhFZmZlY3RfUzEob3V0cHV0Q29sb3JfUzApOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dF9TMSAqIG91dHB1dENvdmVyYWdlX1MwOwoJfQp9CgAAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAIAAAAcG9zaXRpb24KAAAAbG9jYWxDb29yZAAAAAAAAA==","HUJAAAAAAAQAADAAAIOAAAH677777777777QGHAQAD7P7777777777YBAAAAAAQAAAAAAQQGACQAGAAAAAQAAAAAAAQQGAAA":"DAAAAExTS1PlAAAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gZmxvYXQyIGxvY2FsQ29vcmQ7Cm91dCBmbG9hdDIgdmxvY2FsQ29vcmRfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJdmxvY2FsQ29vcmRfUzAgPSBsb2NhbENvb3JkOwoJc2tfUG9zaXRpb24gPSBwb3NpdGlvbi54eTAxOwp9CgAAAAAAAACkAQAAc2FtcGxlcjJEIHVUZXh0dXJlU2FtcGxlcl8wX1MwOwppbiBmbG9hdDIgdmxvY2FsQ29vcmRfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwID0gaGFsZjQoMSk7CglmbG9hdDIgdGV4Q29vcmQ7Cgl0ZXhDb29yZCA9IHZsb2NhbENvb3JkX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSAoYmxlbmRfbW9kdWxhdGUoc2FtcGxlKHVUZXh0dXJlU2FtcGxlcl8wX1MwLCB0ZXhDb29yZCksIGhhbGY0KDEpKSk7Cgljb25zdCBoYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KDEpOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dENvbG9yX1MwICogb3V0cHV0Q292ZXJhZ2VfUzA7Cgl9Cn0KAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAIAAAAcG9zaXRpb24KAAAAbG9jYWxDb29yZAAAAAAAAA==","HUQAAAAAAAMAADAAAIOAAAH677776IZOCAAP577777777777777777YBAAAAAAAAAAAKAAYAAAACAAAAAAACCAYAAA":"DAAAAExTS1PUAAAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0MiBwb3NpdGlvbjsKaW4gaGFsZjQgY29sb3I7CmZsYXQgb3V0IGhhbGY0IHZjb2xvcl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgl2Y29sb3JfUzAgPSBjb2xvcjsKCXNrX1Bvc2l0aW9uID0gcG9zaXRpb24ueHkwMTsKfQoAAAAAEQEAAGZsYXQgaW4gaGFsZjQgdmNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgUXVhZFBlckVkZ2VBQUdlb21ldHJ5UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmNvbG9yX1MwOwoJY29uc3QgaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNCgxKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dENvdmVyYWdlX1MwOwoJfQp9CgAAAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAACAAAACAAAAHBvc2l0aW9uBQAAAGNvbG9yAAAAAAAAAA==","HVIACAAAABQAAGAAAQ4AAAAAGQQAARC4GAAAIOCAAD6P7777777777YDAAAAAAAAAAAFIBUAFS7EOCAAAAAGZJY26AAQAAAA2S5KXK4QAAAAAMAAAAAAAAQAABQM74NUDECAAAAAQ5UOAMQAAAAAAAAAAEAAAAAZ3FHDLYADAAAABKDVK5LSCAIAABQAAAAAAACAAAGAT3RWSMYIAAAAADWRYBSQAAAAAAAQAAAAGJJOXLVOIIBAAAGAAAAAAAAIAAAIAPOH2NTBAAAAAAOKFAOLAAAAAAAEAAAAAMQQAIAAAYGP6G2BSBAAACAAAAAAAAM5S4Z4NUDACAAAAAAAAADAIUOKFAOLAAAAAAACAAAAAZGIEENLQDAAAAAAAAAAABQAKAIAAIAAAADIBCEAQAAAAAAAAAAAIADQAAAAUAAAAAAAIIDA":"DAAAAExTS1PrAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMV9jMF9jMF9jMTsKaW4gZmxvYXQyIHBvc2l0aW9uOwppbiBmbG9hdCBjb3ZlcmFnZTsKaW4gaGFsZjQgY29sb3I7CmluIGZsb2F0MiBsb2NhbENvb3JkOwpmbGF0IG91dCBoYWxmNCB2Y29sb3JfUzA7Cm91dCBmbG9hdCB2Y292ZXJhZ2VfUzA7Cm91dCBmbG9hdDIgdlRyYW5zZm9ybWVkQ29vcmRzXzdfUzA7CnZvaWQgbWFpbigpIAp7CgkvLyBQcmltaXRpdmUgUHJvY2Vzc29yIFF1YWRQZXJFZGdlQUFHZW9tZXRyeVByb2Nlc3NvcgoJZmxvYXQyIHBvc2l0aW9uID0gcG9zaXRpb24ueHk7Cgl2Y29sb3JfUzAgPSBjb2xvcjsKCXZjb3ZlcmFnZV9TMCA9IGNvdmVyYWdlOwoJc2tfUG9zaXRpb24gPSBwb3NpdGlvbi54eTAxOwoJewoJCXZUcmFuc2Zvcm1lZENvb3Jkc183X1MwID0gZmxvYXQzeDIodW1hdHJpeF9TMV9jMF9jMF9jMSkgKiBsb2NhbENvb3JkLnh5MTsKCX0KfQoAAQAAAG4KAAB1bmlmb3JtIGhhbGY0IHVzdGFydF9TMV9jMF9jMF9jMF9jMDsKdW5pZm9ybSBoYWxmNCB1ZW5kX1MxX2MwX2MwX2MwX2MwOwp1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzFfYzBfYzBfYzE7CnVuaWZvcm0gaGFsZjQgdWxlZnRCb3JkZXJDb2xvcl9TMV9jMF9jMDsKdW5pZm9ybSBoYWxmNCB1cmlnaHRCb3JkZXJDb2xvcl9TMV9jMF9jMDsKdW5pZm9ybSBmbG9hdDN4MyB1bWF0cml4X1MxX2MxOwp1bmlmb3JtIGhhbGYgdXJhbmdlX1MxOwpzYW1wbGVyMkQgdVRleHR1cmVTYW1wbGVyXzBfUzE7CmZsYXQgaW4gaGFsZjQgdmNvbG9yX1MwOwppbiBmbG9hdCB2Y292ZXJhZ2VfUzA7CmluIGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfN19TMDsKaGFsZjQgU2luZ2xlSW50ZXJ2YWxDb2xvcml6ZXJfUzFfYzBfYzBfYzBfYzAoaGFsZjQgX2lucHV0LCBmbG9hdDIgX2Nvb3JkcykgCnsKCWhhbGY0IF90bXBfMF9pbkNvbG9yID0gX2lucHV0OwoJZmxvYXQyIF90bXBfMV9jb29yZHMgPSBfY29vcmRzOwoJcmV0dXJuIGhhbGY0KG1peCh1c3RhcnRfUzFfYzBfYzBfYzBfYzAsIHVlbmRfUzFfYzBfYzBfYzBfYzAsIGhhbGYoX3RtcF8xX2Nvb3Jkcy54KSkpOwp9CmhhbGY0IGNvbG9yX3hmb3JtX1MxX2MwX2MwX2MwKGZsb2F0NCBjb2xvcikgCnsKCWNvbG9yLnJnYiAqPSBjb2xvci5hOwoJcmV0dXJuIGhhbGY0KGNvbG9yKTsKfQpoYWxmNCBDb2xvclNwYWNlWGZvcm1fUzFfYzBfYzBfYzAoaGFsZjQgX2lucHV0LCBmbG9hdDIgX2Nvb3JkcykgCnsKCXJldHVybiBjb2xvcl94Zm9ybV9TMV9jMF9jMF9jMChTaW5nbGVJbnRlcnZhbENvbG9yaXplcl9TMV9jMF9jMF9jMF9jMChfaW5wdXQsIF9jb29yZHMpKTsKfQpoYWxmNCBMaW5lYXJMYXlvdXRfUzFfYzBfYzBfYzFfYzAoaGFsZjQgX2lucHV0KSAKewoJaGFsZjQgX3RtcF8yX2luQ29sb3IgPSBfaW5wdXQ7CglmbG9hdDIgX3RtcF8zX2Nvb3JkcyA9IHZUcmFuc2Zvcm1lZENvb3Jkc183X1MwOwoJcmV0dXJuIGhhbGY0KGhhbGY0KGhhbGYoX3RtcF8zX2Nvb3Jkcy54KSArIDFlLTA1LCAxLjAsIDAuMCwgMC4wKSk7Cn0KaGFsZjQgTWF0cml4RWZmZWN0X1MxX2MwX2MwX2MxKGhhbGY0IF9pbnB1dCkgCnsKCXJldHVybiBMaW5lYXJMYXlvdXRfUzFfYzBfYzBfYzFfYzAoX2lucHV0KTsKfQpoYWxmNCBDbGFtcGVkR3JhZGllbnRfUzFfYzBfYzAoaGFsZjQgX2lucHV0KSAKewoJaGFsZjQgX3RtcF80X2luQ29sb3IgPSBfaW5wdXQ7CgloYWxmNCB0ID0gTWF0cml4RWZmZWN0X1MxX2MwX2MwX2MxKF90bXBfNF9pbkNvbG9yKTsKCWhhbGY0IG91dENvbG9yOwoJaWYgKCFib29sKGludCgxKSkgJiYgdC55IDwgMC4wKSAKCXsKCQlvdXRDb2xvciA9IGhhbGY0KDAuMCk7Cgl9CgllbHNlIGlmICh0LnggPCAwLjApIAoJewoJCW91dENvbG9yID0gdWxlZnRCb3JkZXJDb2xvcl9TMV9jMF9jMDsKCX0KCWVsc2UgaWYgKHQueCA+IDEuMCkgCgl7CgkJb3V0Q29sb3IgPSB1cmlnaHRCb3JkZXJDb2xvcl9TMV9jMF9jMDsKCX0KCWVsc2UgCgl7CgkJb3V0Q29sb3IgPSBDb2xvclNwYWNlWGZvcm1fUzFfYzBfYzBfYzAoX3RtcF80X2luQ29sb3IsIGZsb2F0MihoYWxmMih0LngsIDAuMCkpKTsKCX0KCXJldHVybiBoYWxmNChvdXRDb2xvcik7Cn0KaGFsZjQgRGlzYWJsZUNvdmVyYWdlQXNBbHBoYV9TMV9jMChoYWxmNCBfaW5wdXQpIAp7CglfaW5wdXQgPSBDbGFtcGVkR3JhZGllbnRfUzFfYzBfYzAoX2lucHV0KTsKCWhhbGY0IF90bXBfNV9pbkNvbG9yID0gX2lucHV0OwoJcmV0dXJuIGhhbGY0KF9pbnB1dCk7Cn0KaGFsZjQgVGV4dHVyZUVmZmVjdF9TMV9jMV9jMChoYWxmNCBfaW5wdXQsIGZsb2F0MiBfY29vcmRzKSAKewoJcmV0dXJuIHNhbXBsZSh1VGV4dHVyZVNhbXBsZXJfMF9TMSwgX2Nvb3JkcykuMDAwcjsKfQpoYWxmNCBNYXRyaXhFZmZlY3RfUzFfYzEoaGFsZjQgX2lucHV0LCBmbG9hdDIgX2Nvb3JkcykgCnsKCXJldHVybiBUZXh0dXJlRWZmZWN0X1MxX2MxX2MwKF9pbnB1dCwgZmxvYXQzeDIodW1hdHJpeF9TMV9jMSkgKiBfY29vcmRzLnh5MSk7Cn0KaGFsZjQgRGl0aGVyX1MxKGhhbGY0IF9pbnB1dCkgCnsKCWhhbGY0IF90bXBfNl9pbkNvbG9yID0gX2lucHV0OwoJaGFsZjQgY29sb3IgPSBEaXNhYmxlQ292ZXJhZ2VBc0FscGhhX1MxX2MwKF90bXBfNl9pbkNvbG9yKTsKCWhhbGYgdmFsdWUgPSBNYXRyaXhFZmZlY3RfUzFfYzEoX3RtcF82X2luQ29sb3IsIHNrX0ZyYWdDb29yZC54eSkudyAtIDAuNTsKCXJldHVybiBoYWxmNChoYWxmNChjbGFtcChjb2xvci54eXogKyB2YWx1ZSAqIHVyYW5nZV9TMSwgMC4wLCBjb2xvci53KSwgY29sb3IudykpOwp9CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2Y29sb3JfUzA7CglmbG9hdCBjb3ZlcmFnZSA9IHZjb3ZlcmFnZV9TMDsKCWhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoaGFsZihjb3ZlcmFnZSkpOwoJaGFsZjQgb3V0cHV0X1MxOwoJb3V0cHV0X1MxID0gRGl0aGVyX1MxKG91dHB1dENvbG9yX1MwKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSAoaGFsZjQoMS4wKSAtIG91dHB1dF9TMSkgKiBvdXRwdXRDb3ZlcmFnZV9TMDsKCX0KfQoAAAEAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAEAAAACAAAAHBvc2l0aW9uCAAAAGNvdmVyYWdlBQAAAGNvbG9yAAAACgAAAGxvY2FsQ29vcmQAAAAAAAA=","B2ABSAAABQAAIAABBYAAB7777777777774ABICAAAAAAAAAAAAAABUABAAAAAEAAAAAIBEABAAAAA":"DAAAAExTS1N4AQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gaGFsZjQgdUNvbG9yX1MwOwppbiBmbG9hdDIgaW5Qb3NpdGlvbjsKaW4gaGFsZiBpbkNvdmVyYWdlOwpvdXQgaGFsZjQgdmNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBEZWZhdWx0R2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IGNvbG9yID0gdUNvbG9yX1MwOwoJY29sb3IgPSBjb2xvciAqIGluQ292ZXJhZ2U7Cgl2Y29sb3JfUzAgPSBjb2xvcjsKCWZsb2F0MiBfdG1wXzFfaW5Qb3NpdGlvbiA9IGluUG9zaXRpb247CglmbG9hdDIgX3RtcF8zX2luUG9zaXRpb24gPSBpblBvc2l0aW9uOwoJc2tfUG9zaXRpb24gPSBfdG1wXzFfaW5Qb3NpdGlvbi54eTAxOwp9CgAAAAAGAQAAaW4gaGFsZjQgdmNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgRGVmYXVsdEdlb21ldHJ5UHJvY2Vzc29yCgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmNvbG9yX1MwOwoJY29uc3QgaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNCgxKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dENvdmVyYWdlX1MwOwoJfQp9CgAAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAKAAAAaW5Qb3NpdGlvbgAACgAAAGluQ292ZXJhZ2UAAAAAAAA=","HTQAAGAABBYAAAEIXBAAAGEAMAAAAAAAAAAAAAAAQAHAAAAAQAAAAAAAQQGAAAAA":"DAAAAExTS1M/AQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CmluIGZsb2F0MiBpblBvc2l0aW9uOwppbiBoYWxmNCBpbkNvbG9yOwppbiBmbG9hdDQgaW5RdWFkRWRnZTsKb3V0IGZsb2F0NCB2UXVhZEVkZ2VfUzA7Cm91dCBoYWxmNCB2aW5Db2xvcl9TMDsKdm9pZCBtYWluKCkgCnsKCS8vIFByaW1pdGl2ZSBQcm9jZXNzb3IgUXVhZEVkZ2UKCXZRdWFkRWRnZV9TMCA9IGluUXVhZEVkZ2U7Cgl2aW5Db2xvcl9TMCA9IGluQ29sb3I7CglmbG9hdDIgX3RtcF8wX2luUG9zaXRpb24gPSBpblBvc2l0aW9uOwoJc2tfUG9zaXRpb24gPSBfdG1wXzBfaW5Qb3NpdGlvbi54eTAxOwp9CgABAAAABQMAAGluIGZsb2F0NCB2UXVhZEVkZ2VfUzA7CmluIGhhbGY0IHZpbkNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgUXVhZEVkZ2UKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2aW5Db2xvcl9TMDsKCWhhbGYgZWRnZUFscGhhOwoJaGFsZjIgZHV2ZHggPSBoYWxmMihkRmR4KHZRdWFkRWRnZV9TMC54eSkpOwoJaGFsZjIgZHV2ZHkgPSBoYWxmMihkRmR5KHZRdWFkRWRnZV9TMC54eSkpOwoJaWYgKHZRdWFkRWRnZV9TMC56ID4gMC4wICYmIHZRdWFkRWRnZV9TMC53ID4gMC4wKSAKCXsKCQllZGdlQWxwaGEgPSBoYWxmKG1pbihtaW4odlF1YWRFZGdlX1MwLnosIHZRdWFkRWRnZV9TMC53KSArIDAuNSwgMS4wKSk7Cgl9CgllbHNlIAoJewoJCWhhbGYyIGdGID0gaGFsZjIoaGFsZigyLjAqdlF1YWRFZGdlX1MwLngqZHV2ZHgueCAtIGR1dmR4LnkpLCAgICAgICAgICAgICAgICAgaGFsZigyLjAqdlF1YWRFZGdlX1MwLngqZHV2ZHkueCAtIGR1dmR5LnkpKTsKCQllZGdlQWxwaGEgPSBoYWxmKHZRdWFkRWRnZV9TMC54KnZRdWFkRWRnZV9TMC54IC0gdlF1YWRFZGdlX1MwLnkpOwoJCWVkZ2VBbHBoYSA9IHNhdHVyYXRlKDAuNSAtIGVkZ2VBbHBoYSAvIGxlbmd0aChnRikpOwoJfQoJaGFsZjQgb3V0cHV0Q292ZXJhZ2VfUzAgPSBoYWxmNChlZGdlQWxwaGEpOwoJewoJCS8vIFhmZXIgUHJvY2Vzc29yOiBQb3J0ZXIgRHVmZgoJCXNrX0ZyYWdDb2xvciA9IG91dHB1dENvbG9yX1MwICogb3V0cHV0Q292ZXJhZ2VfUzA7Cgl9Cn0KAAAAAQAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAKAAAAaW5Qb3NpdGlvbgAABwAAAGluQ29sb3IACgAAAGluUXVhZEVkZ2UAAAAAAAA=","AYQA5AADQAAAOAEARAFQJAABBADIB7777777777777777777777767YAAAAAAAAAAAAOQAAAAAAAQAAAABAMQAAAAA":"DAAAAExTS1PMAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQ0IHVsb2NhbE1hdHJpeF9TMDsKaW4gZmxvYXQyIGluUG9zaXRpb247CmluIGhhbGY0IGluQ29sb3I7CmluIGZsb2F0NCBpbkNpcmNsZUVkZ2U7Cm91dCBmbG9hdDQgdmluQ2lyY2xlRWRnZV9TMDsKb3V0IGhhbGY0IHZpbkNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBDaXJjbGVHZW9tZXRyeVByb2Nlc3NvcgoJdmluQ2lyY2xlRWRnZV9TMCA9IGluQ2lyY2xlRWRnZTsKCXZpbkNvbG9yX1MwID0gaW5Db2xvcjsKCWZsb2F0MiBfdG1wXzBfaW5Qb3NpdGlvbiA9IGluUG9zaXRpb247CglmbG9hdDIgX3RtcF8xX2luUG9zaXRpb24gPSB1bG9jYWxNYXRyaXhfUzAueHogKiBpblBvc2l0aW9uICsgdWxvY2FsTWF0cml4X1MwLnl3OwoJc2tfUG9zaXRpb24gPSBfdG1wXzBfaW5Qb3NpdGlvbi54eTAxOwp9CgAAAADqAQAAaW4gZmxvYXQ0IHZpbkNpcmNsZUVkZ2VfUzA7CmluIGhhbGY0IHZpbkNvbG9yX1MwOwp2b2lkIG1haW4oKSAKewoJLy8gU3RhZ2UgMCwgQ2lyY2xlR2VvbWV0cnlQcm9jZXNzb3IKCWZsb2F0NCBjaXJjbGVFZGdlOwoJY2lyY2xlRWRnZSA9IHZpbkNpcmNsZUVkZ2VfUzA7CgloYWxmNCBvdXRwdXRDb2xvcl9TMDsKCW91dHB1dENvbG9yX1MwID0gdmluQ29sb3JfUzA7CglmbG9hdCBkID0gbGVuZ3RoKGNpcmNsZUVkZ2UueHkpOwoJaGFsZiBkaXN0YW5jZVRvT3V0ZXJFZGdlID0gaGFsZihjaXJjbGVFZGdlLnogKiAoMS4wIC0gZCkpOwoJaGFsZiBlZGdlQWxwaGEgPSBzYXR1cmF0ZShkaXN0YW5jZVRvT3V0ZXJFZGdlKTsKCWhhbGY0IG91dHB1dENvdmVyYWdlX1MwID0gaGFsZjQoZWRnZUFscGhhKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dENvdmVyYWdlX1MwOwoJfQp9CgAAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAKAAAAaW5Qb3NpdGlvbgAABwAAAGluQ29sb3IADAAAAGluQ2lyY2xlRWRnZQAAAAA=","HUQAAAAAAAMAADAAAIOAAAH677776IZOCAAP577777777777777777YBAAAAAAAAAAADEAAGAAAAAAAAAIAAAAAPAIABAAAAACYGEAAAAEAAAABUARCAIAAAAAAAAAAAACQAGAAAAAQAAAAAAAQQGAAAAA":"DAAAAExTS1NoAQAAdW5pZm9ybSBmbG9hdDQgc2tfUlRBZGp1c3Q7CnVuaWZvcm0gZmxvYXQzeDMgdW1hdHJpeF9TMV9jMF9jMDsKaW4gZmxvYXQyIHBvc2l0aW9uOwppbiBoYWxmNCBjb2xvcjsKZmxhdCBvdXQgaGFsZjQgdmNvbG9yX1MwOwpvdXQgZmxvYXQyIHZUcmFuc2Zvcm1lZENvb3Jkc180X1MwOwp2b2lkIG1haW4oKSAKewoJLy8gUHJpbWl0aXZlIFByb2Nlc3NvciBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCXZjb2xvcl9TMCA9IGNvbG9yOwoJc2tfUG9zaXRpb24gPSBwb3NpdGlvbi54eTAxOwoJewoJCXZUcmFuc2Zvcm1lZENvb3Jkc180X1MwID0gZmxvYXQzeDIodW1hdHJpeF9TMV9jMF9jMCkgKiBwb3NpdGlvbi54eTE7Cgl9Cn0KAAAAADkDAAB1bmlmb3JtIGZsb2F0M3gzIHVtYXRyaXhfUzFfYzBfYzA7CnNhbXBsZXIyRCB1VGV4dHVyZVNhbXBsZXJfMF9TMTsKZmxhdCBpbiBoYWxmNCB2Y29sb3JfUzA7CmluIGZsb2F0MiB2VHJhbnNmb3JtZWRDb29yZHNfNF9TMDsKaGFsZjQgVGV4dHVyZUVmZmVjdF9TMV9jMF9jMF9jMChoYWxmNCBfaW5wdXQpIAp7CglyZXR1cm4gc2FtcGxlKHVUZXh0dXJlU2FtcGxlcl8wX1MxLCB2VHJhbnNmb3JtZWRDb29yZHNfNF9TMCkuMDAwcjsKfQpoYWxmNCBNYXRyaXhFZmZlY3RfUzFfYzBfYzAoaGFsZjQgX2lucHV0KSAKewoJcmV0dXJuIFRleHR1cmVFZmZlY3RfUzFfYzBfYzBfYzAoX2lucHV0KTsKfQpoYWxmNCBEZXZpY2VTcGFjZV9TMV9jMChoYWxmNCBfaW5wdXQpIAp7CglyZXR1cm4gTWF0cml4RWZmZWN0X1MxX2MwX2MwKF9pbnB1dCk7Cn0KaGFsZjQgQmxlbmRfUzEoaGFsZjQgX3NyYywgaGFsZjQgX2RzdCkgCnsKCXJldHVybiBibGVuZF9kc3RfaW4oRGV2aWNlU3BhY2VfUzFfYzAoX3NyYyksIF9zcmMpOwp9CnZvaWQgbWFpbigpIAp7CgkvLyBTdGFnZSAwLCBRdWFkUGVyRWRnZUFBR2VvbWV0cnlQcm9jZXNzb3IKCWhhbGY0IG91dHB1dENvbG9yX1MwOwoJb3V0cHV0Q29sb3JfUzAgPSB2Y29sb3JfUzA7Cgljb25zdCBoYWxmNCBvdXRwdXRDb3ZlcmFnZV9TMCA9IGhhbGY0KDEpOwoJaGFsZjQgb3V0cHV0X1MxOwoJb3V0cHV0X1MxID0gQmxlbmRfUzEob3V0cHV0Q292ZXJhZ2VfUzAsIGhhbGY0KDEpKTsKCXsKCQkvLyBYZmVyIFByb2Nlc3NvcjogUG9ydGVyIER1ZmYKCQlza19GcmFnQ29sb3IgPSBvdXRwdXRDb2xvcl9TMCAqIG91dHB1dF9TMTsKCX0KfQoAAAAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAgAAABwb3NpdGlvbgUAAABjb2xvcgAAAAAAAAA="}} \ No newline at end of file diff --git a/test_driver/driver_screenshots_test.dart b/test_driver/driver_screenshots_test.dart index dc5ecc8d0..711bd0c83 100644 --- a/test_driver/driver_screenshots_test.dart +++ b/test_driver/driver_screenshots_test.dart @@ -44,8 +44,8 @@ void main() { await driver.scanMediaDir(screenshotsTargetDirAndroid); // recent heavy images may delay cataloguing because of thumbnail loading precedence // so we wait enough to avoid cataloguing progress subtitle in app bar when taking screenshots - await Future.delayed(const Duration(seconds: 20)); - }); + await Future.delayed(const Duration(seconds: 40)); + }, timeout: const Timeout(Duration(minutes: 1))); languageCodes.forEach((languageCode) { setLanguage(languageCode); diff --git a/untranslated.json b/untranslated.json index 1421f892a..68aae3568 100644 --- a/untranslated.json +++ b/untranslated.json @@ -1,973 +1,4 @@ { - "ar": [ - "itemCount", - "columnCount", - "timeSeconds", - "timeMinutes", - "timeDays", - "focalLength", - "saveCopyButtonLabel", - "applyTooltip", - "pickTooltip", - "sourceStateLoading", - "sourceStateCataloguing", - "sourceStateLocatingCountries", - "sourceStateLocatingPlaces", - "chipActionDelete", - "chipActionGoToAlbumPage", - "chipActionGoToCountryPage", - "chipActionGoToPlacePage", - "chipActionGoToTagPage", - "chipActionFilterOut", - "chipActionFilterIn", - "chipActionHide", - "chipActionLock", - "chipActionPin", - "chipActionUnpin", - "chipActionRename", - "chipActionSetCover", - "chipActionShowCountryStates", - "chipActionCreateAlbum", - "chipActionCreateVault", - "chipActionConfigureVault", - "entryActionCopyToClipboard", - "entryActionDelete", - "entryActionConvert", - "entryActionExport", - "entryActionInfo", - "entryActionRename", - "entryActionRestore", - "entryActionRotateCCW", - "entryActionRotateCW", - "entryActionFlip", - "entryActionPrint", - "entryActionShare", - "entryActionShareImageOnly", - "entryActionShareVideoOnly", - "entryActionViewSource", - "entryActionShowGeoTiffOnMap", - "entryActionConvertMotionPhotoToStillImage", - "entryActionViewMotionPhotoVideo", - "entryActionEdit", - "entryActionOpen", - "entryActionSetAs", - "entryActionCast", - "entryActionOpenMap", - "entryActionRotateScreen", - "entryActionAddFavourite", - "entryActionRemoveFavourite", - "videoActionCaptureFrame", - "videoActionMute", - "videoActionUnmute", - "videoActionPause", - "videoActionPlay", - "videoActionReplay10", - "videoActionSkip10", - "videoActionSelectStreams", - "videoActionSetSpeed", - "viewerActionSettings", - "viewerActionLock", - "viewerActionUnlock", - "slideshowActionResume", - "slideshowActionShowInCollection", - "entryInfoActionEditDate", - "entryInfoActionEditLocation", - "entryInfoActionEditTitleDescription", - "entryInfoActionEditRating", - "entryInfoActionEditTags", - "entryInfoActionRemoveMetadata", - "entryInfoActionExportMetadata", - "entryInfoActionRemoveLocation", - "editorActionTransform", - "editorTransformCrop", - "editorTransformRotate", - "cropAspectRatioFree", - "cropAspectRatioOriginal", - "cropAspectRatioSquare", - "filterAspectRatioLandscapeLabel", - "filterAspectRatioPortraitLabel", - "filterBinLabel", - "filterFavouriteLabel", - "filterNoDateLabel", - "filterNoAddressLabel", - "filterLocatedLabel", - "filterNoLocationLabel", - "filterNoRatingLabel", - "filterTaggedLabel", - "filterNoTagLabel", - "filterNoTitleLabel", - "filterOnThisDayLabel", - "filterRecentlyAddedLabel", - "filterRatingRejectedLabel", - "filterTypeAnimatedLabel", - "filterTypeMotionPhotoLabel", - "filterTypePanoramaLabel", - "filterTypeRawLabel", - "filterTypeSphericalVideoLabel", - "filterTypeGeotiffLabel", - "filterMimeImageLabel", - "filterMimeVideoLabel", - "accessibilityAnimationsRemove", - "accessibilityAnimationsKeep", - "albumTierNew", - "albumTierPinned", - "albumTierSpecial", - "albumTierApps", - "albumTierVaults", - "albumTierRegular", - "coordinateFormatDms", - "coordinateFormatDecimal", - "coordinateDms", - "coordinateDmsNorth", - "coordinateDmsSouth", - "coordinateDmsEast", - "coordinateDmsWest", - "displayRefreshRatePreferHighest", - "displayRefreshRatePreferLowest", - "keepScreenOnNever", - "keepScreenOnVideoPlayback", - "keepScreenOnViewerOnly", - "keepScreenOnAlways", - "lengthUnitPixel", - "lengthUnitPercent", - "mapStyleGoogleNormal", - "mapStyleGoogleHybrid", - "mapStyleGoogleTerrain", - "mapStyleHuaweiNormal", - "mapStyleHuaweiTerrain", - "mapStyleOsmHot", - "mapStyleStamenWatercolor", - "maxBrightnessNever", - "maxBrightnessAlways", - "nameConflictStrategyRename", - "nameConflictStrategyReplace", - "nameConflictStrategySkip", - "overlayHistogramNone", - "overlayHistogramRGB", - "overlayHistogramLuminance", - "subtitlePositionTop", - "subtitlePositionBottom", - "themeBrightnessLight", - "themeBrightnessDark", - "themeBrightnessBlack", - "unitSystemMetric", - "unitSystemImperial", - "vaultLockTypePattern", - "vaultLockTypePin", - "vaultLockTypePassword", - "settingsVideoEnablePip", - "videoControlsPlay", - "videoControlsPlaySeek", - "videoControlsPlayOutside", - "videoControlsNone", - "videoLoopModeNever", - "videoLoopModeShortOnly", - "videoLoopModeAlways", - "videoPlaybackSkip", - "videoPlaybackMuted", - "videoPlaybackWithSound", - "videoResumptionModeNever", - "videoResumptionModeAlways", - "viewerTransitionSlide", - "viewerTransitionParallax", - "viewerTransitionFade", - "viewerTransitionZoomIn", - "viewerTransitionNone", - "wallpaperTargetHome", - "wallpaperTargetLock", - "wallpaperTargetHomeLock", - "widgetDisplayedItemRandom", - "widgetDisplayedItemMostRecent", - "widgetOpenPageHome", - "widgetOpenPageCollection", - "widgetOpenPageViewer", - "widgetTapUpdateWidget", - "storageVolumeDescriptionFallbackPrimary", - "storageVolumeDescriptionFallbackNonPrimary", - "rootDirectoryDescription", - "otherDirectoryDescription", - "storageAccessDialogMessage", - "restrictedAccessDialogMessage", - "notEnoughSpaceDialogMessage", - "missingSystemFilePickerDialogMessage", - "unsupportedTypeDialogMessage", - "nameConflictDialogSingleSourceMessage", - "nameConflictDialogMultipleSourceMessage", - "addShortcutDialogLabel", - "addShortcutButtonLabel", - "noMatchingAppDialogMessage", - "binEntriesConfirmationDialogMessage", - "deleteEntriesConfirmationDialogMessage", - "moveUndatedConfirmationDialogMessage", - "moveUndatedConfirmationDialogSetDate", - "videoResumeDialogMessage", - "videoStartOverButtonLabel", - "videoResumeButtonLabel", - "setCoverDialogLatest", - "setCoverDialogAuto", - "setCoverDialogCustom", - "hideFilterConfirmationDialogMessage", - "newAlbumDialogTitle", - "newAlbumDialogNameLabel", - "newAlbumDialogNameLabelAlreadyExistsHelper", - "newAlbumDialogStorageLabel", - "newVaultWarningDialogMessage", - "newVaultDialogTitle", - "configureVaultDialogTitle", - "vaultDialogLockModeWhenScreenOff", - "vaultDialogLockTypeLabel", - "patternDialogEnter", - "patternDialogConfirm", - "pinDialogEnter", - "pinDialogConfirm", - "passwordDialogEnter", - "passwordDialogConfirm", - "authenticateToConfigureVault", - "authenticateToUnlockVault", - "vaultBinUsageDialogMessage", - "renameAlbumDialogLabel", - "renameAlbumDialogLabelAlreadyExistsHelper", - "renameEntrySetPageTitle", - "renameEntrySetPagePatternFieldLabel", - "renameEntrySetPageInsertTooltip", - "renameEntrySetPagePreviewSectionTitle", - "renameProcessorCounter", - "renameProcessorName", - "deleteSingleAlbumConfirmationDialogMessage", - "deleteMultiAlbumConfirmationDialogMessage", - "exportEntryDialogFormat", - "exportEntryDialogWidth", - "exportEntryDialogHeight", - "exportEntryDialogQuality", - "exportEntryDialogWriteMetadata", - "renameEntryDialogLabel", - "editEntryDialogCopyFromItem", - "editEntryDialogTargetFieldsHeader", - "editEntryDateDialogTitle", - "editEntryDateDialogSetCustom", - "editEntryDateDialogCopyField", - "editEntryDateDialogExtractFromTitle", - "editEntryDateDialogShift", - "editEntryDateDialogSourceFileModifiedDate", - "durationDialogHours", - "durationDialogMinutes", - "durationDialogSeconds", - "editEntryLocationDialogTitle", - "editEntryLocationDialogSetCustom", - "editEntryLocationDialogChooseOnMap", - "editEntryLocationDialogLatitude", - "editEntryLocationDialogLongitude", - "locationPickerUseThisLocationButton", - "editEntryRatingDialogTitle", - "removeEntryMetadataDialogTitle", - "removeEntryMetadataDialogMore", - "removeEntryMetadataMotionPhotoXmpWarningDialogMessage", - "videoSpeedDialogLabel", - "videoStreamSelectionDialogVideo", - "videoStreamSelectionDialogAudio", - "videoStreamSelectionDialogText", - "videoStreamSelectionDialogOff", - "videoStreamSelectionDialogTrack", - "videoStreamSelectionDialogNoSelection", - "genericSuccessFeedback", - "genericFailureFeedback", - "genericDangerWarningDialogMessage", - "tooManyItemsErrorDialogMessage", - "menuActionConfigureView", - "menuActionSelect", - "menuActionSelectAll", - "menuActionSelectNone", - "menuActionMap", - "menuActionSlideshow", - "menuActionStats", - "viewDialogSortSectionTitle", - "viewDialogGroupSectionTitle", - "viewDialogLayoutSectionTitle", - "viewDialogReverseSortOrder", - "tileLayoutMosaic", - "tileLayoutGrid", - "tileLayoutList", - "castDialogTitle", - "coverDialogTabCover", - "coverDialogTabApp", - "coverDialogTabColor", - "appPickDialogTitle", - "appPickDialogNone", - "aboutPageTitle", - "aboutLinkLicense", - "aboutLinkPolicy", - "aboutBugSectionTitle", - "aboutBugSaveLogInstruction", - "aboutBugCopyInfoInstruction", - "aboutBugCopyInfoButton", - "aboutBugReportInstruction", - "aboutBugReportButton", - "aboutDataUsageSectionTitle", - "aboutDataUsageData", - "aboutDataUsageCache", - "aboutDataUsageDatabase", - "aboutDataUsageMisc", - "aboutDataUsageInternal", - "aboutDataUsageExternal", - "aboutDataUsageClearCache", - "aboutCreditsSectionTitle", - "aboutCreditsWorldAtlas1", - "aboutCreditsWorldAtlas2", - "aboutTranslatorsSectionTitle", - "aboutLicensesSectionTitle", - "aboutLicensesBanner", - "aboutLicensesAndroidLibrariesSectionTitle", - "aboutLicensesFlutterPluginsSectionTitle", - "aboutLicensesFlutterPackagesSectionTitle", - "aboutLicensesDartPackagesSectionTitle", - "aboutLicensesShowAllButtonLabel", - "policyPageTitle", - "collectionPageTitle", - "collectionPickPageTitle", - "collectionSelectPageTitle", - "collectionActionShowTitleSearch", - "collectionActionHideTitleSearch", - "collectionActionAddShortcut", - "collectionActionEmptyBin", - "collectionActionCopy", - "collectionActionMove", - "collectionActionRescan", - "collectionActionEdit", - "collectionSearchTitlesHintText", - "collectionGroupAlbum", - "collectionGroupMonth", - "collectionGroupDay", - "collectionGroupNone", - "sectionUnknown", - "dateToday", - "dateYesterday", - "dateThisMonth", - "collectionDeleteFailureFeedback", - "collectionCopyFailureFeedback", - "collectionMoveFailureFeedback", - "collectionRenameFailureFeedback", - "collectionEditFailureFeedback", - "collectionExportFailureFeedback", - "collectionCopySuccessFeedback", - "collectionMoveSuccessFeedback", - "collectionRenameSuccessFeedback", - "collectionEditSuccessFeedback", - "collectionEmptyFavourites", - "collectionEmptyVideos", - "collectionEmptyImages", - "collectionEmptyGrantAccessButtonLabel", - "collectionSelectSectionTooltip", - "collectionDeselectSectionTooltip", - "drawerAboutButton", - "drawerSettingsButton", - "drawerCollectionAll", - "drawerCollectionFavourites", - "drawerCollectionImages", - "drawerCollectionVideos", - "drawerCollectionAnimated", - "drawerCollectionMotionPhotos", - "drawerCollectionPanoramas", - "drawerCollectionRaws", - "drawerCollectionSphericalVideos", - "drawerAlbumPage", - "drawerCountryPage", - "drawerPlacePage", - "drawerTagPage", - "sortByDate", - "sortByName", - "sortByItemCount", - "sortBySize", - "sortByAlbumFileName", - "sortByRating", - "sortOrderNewestFirst", - "sortOrderOldestFirst", - "sortOrderAtoZ", - "sortOrderZtoA", - "sortOrderHighestFirst", - "sortOrderLowestFirst", - "sortOrderLargestFirst", - "sortOrderSmallestFirst", - "albumGroupTier", - "albumGroupType", - "albumGroupVolume", - "albumGroupNone", - "albumMimeTypeMixed", - "albumPickPageTitleCopy", - "albumPickPageTitleExport", - "albumPickPageTitleMove", - "albumPickPageTitlePick", - "albumCamera", - "albumDownload", - "albumScreenshots", - "albumVideoCaptures", - "albumPageTitle", - "albumEmpty", - "createAlbumButtonLabel", - "newFilterBanner", - "countryPageTitle", - "countryEmpty", - "statePageTitle", - "stateEmpty", - "placePageTitle", - "placeEmpty", - "tagPageTitle", - "tagEmpty", - "binPageTitle", - "searchCollectionFieldHint", - "searchRecentSectionTitle", - "searchDateSectionTitle", - "searchAlbumsSectionTitle", - "searchCountriesSectionTitle", - "searchStatesSectionTitle", - "searchPlacesSectionTitle", - "searchTagsSectionTitle", - "searchRatingSectionTitle", - "searchMetadataSectionTitle", - "settingsPageTitle", - "settingsSystemDefault", - "settingsDefault", - "settingsDisabled", - "settingsAskEverytime", - "settingsModificationWarningDialogMessage", - "settingsSearchFieldLabel", - "settingsSearchEmpty", - "settingsActionExport", - "settingsActionExportDialogTitle", - "settingsActionImport", - "settingsActionImportDialogTitle", - "appExportCovers", - "appExportFavourites", - "appExportSettings", - "settingsNavigationSectionTitle", - "settingsHomeTile", - "settingsHomeDialogTitle", - "settingsShowBottomNavigationBar", - "settingsKeepScreenOnTile", - "settingsKeepScreenOnDialogTitle", - "settingsDoubleBackExit", - "settingsConfirmationTile", - "settingsConfirmationDialogTitle", - "settingsConfirmationBeforeDeleteItems", - "settingsConfirmationBeforeMoveToBinItems", - "settingsConfirmationBeforeMoveUndatedItems", - "settingsConfirmationAfterMoveToBinItems", - "settingsConfirmationVaultDataLoss", - "settingsNavigationDrawerTile", - "settingsNavigationDrawerEditorPageTitle", - "settingsNavigationDrawerBanner", - "settingsNavigationDrawerTabTypes", - "settingsNavigationDrawerTabAlbums", - "settingsNavigationDrawerTabPages", - "settingsNavigationDrawerAddAlbum", - "settingsThumbnailSectionTitle", - "settingsThumbnailOverlayTile", - "settingsThumbnailOverlayPageTitle", - "settingsThumbnailShowFavouriteIcon", - "settingsThumbnailShowTagIcon", - "settingsThumbnailShowLocationIcon", - "settingsThumbnailShowMotionPhotoIcon", - "settingsThumbnailShowRating", - "settingsThumbnailShowRawIcon", - "settingsThumbnailShowVideoDuration", - "settingsCollectionQuickActionsTile", - "settingsCollectionQuickActionEditorPageTitle", - "settingsCollectionQuickActionTabBrowsing", - "settingsCollectionQuickActionTabSelecting", - "settingsCollectionBrowsingQuickActionEditorBanner", - "settingsCollectionSelectionQuickActionEditorBanner", - "settingsCollectionBurstPatternsTile", - "settingsCollectionBurstPatternsNone", - "settingsViewerSectionTitle", - "settingsViewerGestureSideTapNext", - "settingsViewerUseCutout", - "settingsViewerMaximumBrightness", - "settingsMotionPhotoAutoPlay", - "settingsImageBackground", - "settingsViewerQuickActionsTile", - "settingsViewerQuickActionEditorPageTitle", - "settingsViewerQuickActionEditorBanner", - "settingsViewerQuickActionEditorDisplayedButtonsSectionTitle", - "settingsViewerQuickActionEditorAvailableButtonsSectionTitle", - "settingsViewerQuickActionEmpty", - "settingsViewerOverlayTile", - "settingsViewerOverlayPageTitle", - "settingsViewerShowOverlayOnOpening", - "settingsViewerShowHistogram", - "settingsViewerShowMinimap", - "settingsViewerShowInformation", - "settingsViewerShowInformationSubtitle", - "settingsViewerShowRatingTags", - "settingsViewerShowShootingDetails", - "settingsViewerShowDescription", - "settingsViewerShowOverlayThumbnails", - "settingsViewerEnableOverlayBlurEffect", - "settingsViewerSlideshowTile", - "settingsViewerSlideshowPageTitle", - "settingsSlideshowRepeat", - "settingsSlideshowShuffle", - "settingsSlideshowFillScreen", - "settingsSlideshowAnimatedZoomEffect", - "settingsSlideshowTransitionTile", - "settingsSlideshowIntervalTile", - "settingsSlideshowVideoPlaybackTile", - "settingsSlideshowVideoPlaybackDialogTitle", - "settingsVideoPageTitle", - "settingsVideoSectionTitle", - "settingsVideoShowVideos", - "settingsVideoPlaybackTile", - "settingsVideoPlaybackPageTitle", - "settingsVideoEnableHardwareAcceleration", - "settingsVideoAutoPlay", - "settingsVideoLoopModeTile", - "settingsVideoLoopModeDialogTitle", - "settingsVideoResumptionModeTile", - "settingsVideoResumptionModeDialogTitle", - "settingsVideoBackgroundMode", - "settingsVideoBackgroundModeDialogTitle", - "settingsVideoControlsTile", - "settingsVideoControlsPageTitle", - "settingsVideoButtonsTile", - "settingsVideoGestureDoubleTapTogglePlay", - "settingsVideoGestureSideDoubleTapSeek", - "settingsVideoGestureVerticalDragBrightnessVolume", - "settingsSubtitleThemeTile", - "settingsSubtitleThemePageTitle", - "settingsSubtitleThemeSample", - "settingsSubtitleThemeTextAlignmentTile", - "settingsSubtitleThemeTextAlignmentDialogTitle", - "settingsSubtitleThemeTextPositionTile", - "settingsSubtitleThemeTextPositionDialogTitle", - "settingsSubtitleThemeTextSize", - "settingsSubtitleThemeShowOutline", - "settingsSubtitleThemeTextColor", - "settingsSubtitleThemeTextOpacity", - "settingsSubtitleThemeBackgroundColor", - "settingsSubtitleThemeBackgroundOpacity", - "settingsSubtitleThemeTextAlignmentLeft", - "settingsSubtitleThemeTextAlignmentCenter", - "settingsSubtitleThemeTextAlignmentRight", - "settingsPrivacySectionTitle", - "settingsAllowInstalledAppAccess", - "settingsAllowInstalledAppAccessSubtitle", - "settingsAllowErrorReporting", - "settingsSaveSearchHistory", - "settingsEnableBin", - "settingsEnableBinSubtitle", - "settingsDisablingBinWarningDialogMessage", - "settingsAllowMediaManagement", - "settingsHiddenItemsTile", - "settingsHiddenItemsPageTitle", - "settingsHiddenItemsTabFilters", - "settingsHiddenFiltersBanner", - "settingsHiddenFiltersEmpty", - "settingsHiddenItemsTabPaths", - "settingsHiddenPathsBanner", - "addPathTooltip", - "settingsStorageAccessTile", - "settingsStorageAccessPageTitle", - "settingsStorageAccessBanner", - "settingsStorageAccessEmpty", - "settingsStorageAccessRevokeTooltip", - "settingsAccessibilitySectionTitle", - "settingsRemoveAnimationsTile", - "settingsRemoveAnimationsDialogTitle", - "settingsTimeToTakeActionTile", - "settingsAccessibilityShowPinchGestureAlternatives", - "settingsDisplaySectionTitle", - "settingsThemeBrightnessTile", - "settingsThemeBrightnessDialogTitle", - "settingsThemeColorHighlights", - "settingsThemeEnableDynamicColor", - "settingsDisplayRefreshRateModeTile", - "settingsDisplayRefreshRateModeDialogTitle", - "settingsDisplayUseTvInterface", - "settingsLanguageSectionTitle", - "settingsLanguageTile", - "settingsLanguagePageTitle", - "settingsCoordinateFormatTile", - "settingsCoordinateFormatDialogTitle", - "settingsUnitSystemTile", - "settingsUnitSystemDialogTitle", - "settingsScreenSaverPageTitle", - "settingsWidgetPageTitle", - "settingsWidgetShowOutline", - "settingsWidgetOpenPage", - "settingsWidgetDisplayedItem", - "settingsCollectionTile", - "statsPageTitle", - "statsWithGps", - "statsTopCountriesSectionTitle", - "statsTopStatesSectionTitle", - "statsTopPlacesSectionTitle", - "statsTopTagsSectionTitle", - "statsTopAlbumsSectionTitle", - "viewerOpenPanoramaButtonLabel", - "viewerSetWallpaperButtonLabel", - "viewerErrorUnknown", - "viewerErrorDoesNotExist", - "viewerInfoPageTitle", - "viewerInfoBackToViewerTooltip", - "viewerInfoUnknown", - "viewerInfoLabelDescription", - "viewerInfoLabelTitle", - "viewerInfoLabelDate", - "viewerInfoLabelResolution", - "viewerInfoLabelSize", - "viewerInfoLabelUri", - "viewerInfoLabelPath", - "viewerInfoLabelDuration", - "viewerInfoLabelOwner", - "viewerInfoLabelCoordinates", - "viewerInfoLabelAddress", - "mapStyleDialogTitle", - "mapStyleTooltip", - "mapZoomInTooltip", - "mapZoomOutTooltip", - "mapPointNorthUpTooltip", - "mapAttributionOsmHot", - "mapAttributionStamen", - "openMapPageTooltip", - "mapEmptyRegion", - "viewerInfoOpenEmbeddedFailureFeedback", - "viewerInfoOpenLinkText", - "viewerInfoViewXmlLinkText", - "viewerInfoSearchFieldLabel", - "viewerInfoSearchEmpty", - "viewerInfoSearchSuggestionDate", - "viewerInfoSearchSuggestionDescription", - "viewerInfoSearchSuggestionDimensions", - "viewerInfoSearchSuggestionResolution", - "viewerInfoSearchSuggestionRights", - "wallpaperUseScrollEffect", - "tagEditorPageTitle", - "tagEditorPageNewTagFieldLabel", - "tagEditorDiscardDialogMessage", - "tagPlaceholderState" - ], - - "be": [ - "deleteMultiAlbumConfirmationDialogMessage", - "editEntryDateDialogSetCustom", - "editEntryDateDialogCopyField", - "editEntryDateDialogExtractFromTitle", - "editEntryDateDialogShift", - "editEntryDateDialogSourceFileModifiedDate", - "durationDialogHours", - "durationDialogMinutes", - "durationDialogSeconds", - "editEntryLocationDialogTitle", - "editEntryLocationDialogSetCustom", - "editEntryLocationDialogChooseOnMap", - "editEntryLocationDialogLatitude", - "editEntryLocationDialogLongitude", - "locationPickerUseThisLocationButton", - "editEntryRatingDialogTitle", - "removeEntryMetadataDialogTitle", - "removeEntryMetadataDialogMore", - "removeEntryMetadataMotionPhotoXmpWarningDialogMessage", - "videoSpeedDialogLabel", - "videoStreamSelectionDialogVideo", - "videoStreamSelectionDialogAudio", - "videoStreamSelectionDialogText", - "videoStreamSelectionDialogOff", - "videoStreamSelectionDialogTrack", - "videoStreamSelectionDialogNoSelection", - "genericSuccessFeedback", - "genericFailureFeedback", - "genericDangerWarningDialogMessage", - "tooManyItemsErrorDialogMessage", - "menuActionConfigureView", - "menuActionSelect", - "menuActionSelectAll", - "menuActionSelectNone", - "menuActionMap", - "menuActionSlideshow", - "menuActionStats", - "viewDialogSortSectionTitle", - "viewDialogGroupSectionTitle", - "viewDialogLayoutSectionTitle", - "viewDialogReverseSortOrder", - "tileLayoutMosaic", - "tileLayoutGrid", - "tileLayoutList", - "castDialogTitle", - "coverDialogTabCover", - "coverDialogTabApp", - "coverDialogTabColor", - "appPickDialogTitle", - "appPickDialogNone", - "aboutPageTitle", - "aboutLinkLicense", - "aboutLinkPolicy", - "aboutDataUsageSectionTitle", - "aboutDataUsageData", - "aboutDataUsageDatabase", - "aboutDataUsageMisc", - "aboutDataUsageInternal", - "aboutDataUsageExternal", - "aboutCreditsSectionTitle", - "aboutCreditsWorldAtlas1", - "aboutCreditsWorldAtlas2", - "aboutTranslatorsSectionTitle", - "aboutLicensesSectionTitle", - "aboutLicensesBanner", - "aboutLicensesAndroidLibrariesSectionTitle", - "aboutLicensesFlutterPluginsSectionTitle", - "aboutLicensesFlutterPackagesSectionTitle", - "aboutLicensesDartPackagesSectionTitle", - "aboutLicensesShowAllButtonLabel", - "policyPageTitle", - "collectionPageTitle", - "collectionPickPageTitle", - "collectionSelectPageTitle", - "collectionActionShowTitleSearch", - "collectionActionHideTitleSearch", - "collectionActionAddShortcut", - "collectionActionEmptyBin", - "collectionActionCopy", - "collectionActionMove", - "collectionActionRescan", - "collectionActionEdit", - "collectionSearchTitlesHintText", - "collectionGroupAlbum", - "collectionGroupMonth", - "collectionGroupDay", - "collectionGroupNone", - "sectionUnknown", - "dateToday", - "dateYesterday", - "dateThisMonth", - "collectionDeleteFailureFeedback", - "collectionCopyFailureFeedback", - "collectionMoveFailureFeedback", - "collectionRenameFailureFeedback", - "collectionEditFailureFeedback", - "collectionExportFailureFeedback", - "collectionCopySuccessFeedback", - "collectionMoveSuccessFeedback", - "collectionRenameSuccessFeedback", - "collectionEditSuccessFeedback", - "collectionEmptyFavourites", - "collectionEmptyVideos", - "collectionEmptyImages", - "collectionEmptyGrantAccessButtonLabel", - "collectionSelectSectionTooltip", - "collectionDeselectSectionTooltip", - "drawerAboutButton", - "drawerSettingsButton", - "drawerCollectionAll", - "drawerCollectionFavourites", - "drawerCollectionImages", - "drawerCollectionVideos", - "drawerCollectionAnimated", - "drawerCollectionMotionPhotos", - "drawerCollectionPanoramas", - "drawerCollectionRaws", - "drawerCollectionSphericalVideos", - "drawerAlbumPage", - "drawerCountryPage", - "drawerPlacePage", - "drawerTagPage", - "sortByDate", - "sortByName", - "sortByItemCount", - "sortBySize", - "sortByAlbumFileName", - "sortByRating", - "sortOrderNewestFirst", - "sortOrderOldestFirst", - "sortOrderAtoZ", - "sortOrderZtoA", - "sortOrderHighestFirst", - "sortOrderLowestFirst", - "sortOrderLargestFirst", - "sortOrderSmallestFirst", - "albumGroupTier", - "albumGroupType", - "albumGroupVolume", - "albumGroupNone", - "albumMimeTypeMixed", - "albumPickPageTitleCopy", - "albumPickPageTitleExport", - "albumPickPageTitleMove", - "albumPickPageTitlePick", - "albumCamera", - "albumDownload", - "albumScreenshots", - "albumScreenRecordings", - "albumVideoCaptures", - "albumPageTitle", - "albumEmpty", - "createAlbumButtonLabel", - "newFilterBanner", - "countryPageTitle", - "countryEmpty", - "statePageTitle", - "stateEmpty", - "placePageTitle", - "placeEmpty", - "tagPageTitle", - "tagEmpty", - "binPageTitle", - "searchCollectionFieldHint", - "searchRecentSectionTitle", - "searchDateSectionTitle", - "searchAlbumsSectionTitle", - "searchCountriesSectionTitle", - "searchStatesSectionTitle", - "searchPlacesSectionTitle", - "searchTagsSectionTitle", - "searchRatingSectionTitle", - "searchMetadataSectionTitle", - "settingsPageTitle", - "settingsDefault", - "settingsDisabled", - "settingsAskEverytime", - "settingsModificationWarningDialogMessage", - "settingsSearchFieldLabel", - "settingsSearchEmpty", - "settingsActionExport", - "settingsActionExportDialogTitle", - "settingsActionImport", - "settingsActionImportDialogTitle", - "appExportCovers", - "appExportFavourites", - "appExportSettings", - "settingsNavigationSectionTitle", - "settingsHomeTile", - "settingsHomeDialogTitle", - "settingsShowBottomNavigationBar", - "settingsKeepScreenOnTile", - "settingsKeepScreenOnDialogTitle", - "settingsDoubleBackExit", - "settingsConfirmationTile", - "settingsConfirmationDialogTitle", - "settingsConfirmationBeforeDeleteItems", - "settingsConfirmationBeforeMoveToBinItems", - "settingsConfirmationBeforeMoveUndatedItems", - "settingsConfirmationAfterMoveToBinItems", - "settingsConfirmationVaultDataLoss", - "settingsNavigationDrawerTile", - "settingsNavigationDrawerEditorPageTitle", - "settingsNavigationDrawerBanner", - "settingsNavigationDrawerTabTypes", - "settingsNavigationDrawerTabAlbums", - "settingsNavigationDrawerTabPages", - "settingsNavigationDrawerAddAlbum", - "settingsThumbnailSectionTitle", - "settingsThumbnailOverlayTile", - "settingsThumbnailOverlayPageTitle", - "settingsThumbnailShowFavouriteIcon", - "settingsThumbnailShowTagIcon", - "settingsThumbnailShowLocationIcon", - "settingsThumbnailShowMotionPhotoIcon", - "settingsThumbnailShowRating", - "settingsThumbnailShowRawIcon", - "settingsThumbnailShowVideoDuration", - "settingsCollectionQuickActionsTile", - "settingsCollectionQuickActionEditorPageTitle", - "settingsCollectionQuickActionTabBrowsing", - "settingsCollectionQuickActionTabSelecting", - "settingsCollectionBrowsingQuickActionEditorBanner", - "settingsCollectionSelectionQuickActionEditorBanner", - "settingsCollectionBurstPatternsTile", - "settingsCollectionBurstPatternsNone", - "settingsViewerSectionTitle", - "settingsViewerGestureSideTapNext", - "settingsViewerUseCutout", - "settingsViewerMaximumBrightness", - "settingsMotionPhotoAutoPlay", - "settingsImageBackground", - "settingsViewerQuickActionsTile", - "settingsViewerQuickActionEditorPageTitle", - "settingsViewerQuickActionEditorBanner", - "settingsViewerQuickActionEditorDisplayedButtonsSectionTitle", - "settingsViewerQuickActionEditorAvailableButtonsSectionTitle", - "settingsViewerQuickActionEmpty", - "settingsViewerOverlayTile", - "settingsViewerOverlayPageTitle", - "settingsViewerShowOverlayOnOpening", - "settingsViewerShowHistogram", - "settingsViewerShowMinimap", - "settingsViewerShowInformation", - "settingsViewerShowInformationSubtitle", - "settingsViewerShowRatingTags", - "settingsViewerShowShootingDetails", - "settingsViewerShowDescription", - "settingsViewerShowOverlayThumbnails", - "settingsViewerEnableOverlayBlurEffect", - "settingsViewerSlideshowTile", - "settingsViewerSlideshowPageTitle", - "settingsSlideshowRepeat", - "settingsSlideshowShuffle", - "settingsSlideshowFillScreen", - "settingsSlideshowAnimatedZoomEffect", - "settingsSlideshowTransitionTile", - "settingsSlideshowIntervalTile", - "settingsSlideshowVideoPlaybackTile", - "settingsSlideshowVideoPlaybackDialogTitle", - "settingsVideoPageTitle", - "settingsVideoSectionTitle", - "settingsVideoShowVideos", - "settingsVideoPlaybackTile", - "settingsVideoPlaybackPageTitle", - "settingsVideoEnableHardwareAcceleration", - "settingsVideoAutoPlay", - "settingsVideoLoopModeTile", - "settingsVideoLoopModeDialogTitle", - "settingsVideoResumptionModeTile", - "settingsVideoResumptionModeDialogTitle", - "settingsVideoBackgroundMode", - "settingsVideoBackgroundModeDialogTitle", - "settingsVideoControlsTile", - "settingsVideoControlsPageTitle", - "settingsVideoButtonsTile", - "settingsVideoGestureDoubleTapTogglePlay", - "settingsVideoGestureSideDoubleTapSeek", - "settingsVideoGestureVerticalDragBrightnessVolume", - "settingsSubtitleThemeTile", - "settingsSubtitleThemePageTitle", - "settingsSubtitleThemeSample", - "settingsSubtitleThemeTextAlignmentTile", - "settingsSubtitleThemeTextAlignmentDialogTitle", - "settingsSubtitleThemeTextPositionTile", - "settingsSubtitleThemeTextPositionDialogTitle", - "settingsSubtitleThemeTextSize", - "settingsSubtitleThemeShowOutline", - "settingsSubtitleThemeTextColor", - "settingsSubtitleThemeTextOpacity", - "settingsSubtitleThemeBackgroundColor", - "settingsSubtitleThemeBackgroundOpacity", - "settingsSubtitleThemeTextAlignmentLeft", - "settingsSubtitleThemeTextAlignmentCenter", - "settingsSubtitleThemeTextAlignmentRight", - "settingsPrivacySectionTitle", - "settingsAllowInstalledAppAccess", - "settingsAllowInstalledAppAccessSubtitle", - "settingsAllowErrorReporting", - "settingsSaveSearchHistory", - "settingsEnableBin", - "settingsEnableBinSubtitle", - "settingsDisablingBinWarningDialogMessage", - "settingsAllowMediaManagement", - "settingsHiddenItemsTile", - "settingsHiddenItemsPageTitle", - "settingsHiddenItemsTabFilters", - "settingsHiddenFiltersBanner", - "settingsHiddenFiltersEmpty", - "settingsHiddenItemsTabPaths", - "settingsHiddenPathsBanner", - "addPathTooltip", - "settingsStorageAccessTile", - "settingsStorageAccessPageTitle", - "settingsStorageAccessBanner", - "settingsStorageAccessEmpty", - "settingsStorageAccessRevokeTooltip", - "settingsAccessibilitySectionTitle", - "settingsRemoveAnimationsTile", - "statsWithGps" - ], - "bn": [ "itemCount", "columnCount", @@ -2164,9 +1195,7 @@ "de": [ "entryActionCast", "overlayHistogramNone", - "castDialogTitle", - "aboutDataUsageClearCache", - "settingsViewerShowHistogram" + "castDialogTitle" ], "el": [ @@ -5070,12 +4099,6 @@ "castDialogTitle" ], - "it": [ - "entryActionCast", - "castDialogTitle", - "aboutDataUsageClearCache" - ], - "ja": [ "columnCount", "saveCopyButtonLabel", @@ -7436,8 +6459,7 @@ "pt": [ "entryActionCast", - "castDialogTitle", - "aboutDataUsageClearCache" + "castDialogTitle" ], "ro": [ @@ -8637,75 +7659,6 @@ "tagPlaceholderState" ], - "zh": [ - "chipActionGoToPlacePage", - "entryActionCast", - "editorTransformCrop", - "cropAspectRatioFree", - "cropAspectRatioOriginal", - "cropAspectRatioSquare", - "filterLocatedLabel", - "filterTaggedLabel", - "albumTierVaults", - "lengthUnitPixel", - "lengthUnitPercent", - "maxBrightnessNever", - "maxBrightnessAlways", - "overlayHistogramNone", - "overlayHistogramLuminance", - "vaultLockTypePattern", - "vaultLockTypePin", - "settingsVideoEnablePip", - "videoResumptionModeNever", - "videoResumptionModeAlways", - "widgetTapUpdateWidget", - "newVaultWarningDialogMessage", - "newVaultDialogTitle", - "configureVaultDialogTitle", - "vaultDialogLockModeWhenScreenOff", - "vaultDialogLockTypeLabel", - "patternDialogEnter", - "authenticateToConfigureVault", - "authenticateToUnlockVault", - "vaultBinUsageDialogMessage", - "exportEntryDialogQuality", - "exportEntryDialogWriteMetadata", - "tooManyItemsErrorDialogMessage", - "castDialogTitle", - "aboutDataUsageSectionTitle", - "aboutDataUsageData", - "aboutDataUsageCache", - "aboutDataUsageDatabase", - "aboutDataUsageMisc", - "aboutDataUsageInternal", - "aboutDataUsageExternal", - "aboutDataUsageClearCache", - "drawerPlacePage", - "statePageTitle", - "stateEmpty", - "placePageTitle", - "placeEmpty", - "searchStatesSectionTitle", - "settingsAskEverytime", - "settingsModificationWarningDialogMessage", - "settingsConfirmationVaultDataLoss", - "settingsCollectionBurstPatternsTile", - "settingsCollectionBurstPatternsNone", - "settingsViewerShowHistogram", - "settingsViewerShowDescription", - "settingsVideoPlaybackTile", - "settingsVideoPlaybackPageTitle", - "settingsVideoResumptionModeTile", - "settingsVideoResumptionModeDialogTitle", - "settingsVideoBackgroundMode", - "settingsVideoBackgroundModeDialogTitle", - "settingsVideoGestureVerticalDragBrightnessVolume", - "settingsDisablingBinWarningDialogMessage", - "settingsAccessibilityShowPinchGestureAlternatives", - "statsTopStatesSectionTitle", - "tagPlaceholderState" - ], - "zh_Hant": [ "entryActionCast", "overlayHistogramNone", diff --git a/whatsnew/whatsnew-en-US b/whatsnew/whatsnew-en-US index 3c18fca39..69b5f63e7 100644 --- a/whatsnew/whatsnew-en-US +++ b/whatsnew/whatsnew-en-US @@ -1,4 +1,4 @@ -In v1.10.0: -- cast images via DLNA/UPnP -- enjoy the app in Icelandic +In v1.10.1: +- JPEG MPF support +- enjoy the app in Arabic & Belarusian Full changelog available on GitHub \ No newline at end of file