implements java.io.Serializable {
@@ -686,17 +686,17 @@ public int hashCode() {
* Linked Nodes. As a minor efficiency hack, this class opportunistically
* inherits from AtomicReference, with the atomic ref used as the "next"
* link.
- *
+ *
* Nodes are in doubly-linked lists. There are three kinds of special nodes,
* distinguished by: * The list header has a null prev link * The list
* trailer has a null next link * A deletion marker has a prev link pointing
* to itself. All three kinds of special nodes have null element fields.
- *
+ *
* Regular nodes have non-null element, next, and prev fields. To avoid
* visible inconsistencies when deletions overlap element replacement,
* replacements are done by replacing the node, not just setting the
* element.
- *
+ *
* Nodes can be traversed by read-only ConcurrentLinkedDeque class
* operations just by following raw next pointers, so long as they ignore
* any special nodes seen along the way. (This is automated in method
@@ -704,7 +704,7 @@ public int hashCode() {
* all live nodes since a prev pointer of a deleted node can become
* unrecoverably stale.
*/
-
+@SuppressWarnings("ALL")
class Node extends AtomicReference> {
private volatile Node prev;
diff --git a/src/main/java/it/auties/whatsapp/util/Medias.java b/src/main/java/it/auties/whatsapp/util/Medias.java
index 943c906c..4aa959b1 100644
--- a/src/main/java/it/auties/whatsapp/util/Medias.java
+++ b/src/main/java/it/auties/whatsapp/util/Medias.java
@@ -5,7 +5,7 @@
import it.auties.whatsapp.crypto.Sha256;
import it.auties.whatsapp.exception.HmacValidationException;
import it.auties.whatsapp.model.media.*;
-import it.auties.whatsapp.util.Spec.Whatsapp;
+import it.auties.whatsapp.util.Specification.Whatsapp;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.rendering.PDFRenderer;
import org.apache.poi.hslf.usermodel.HSLFSlideShow;
@@ -115,28 +115,50 @@ public static CompletableFuture downloadAsync(URI imageUri, boolean user
public static CompletableFuture upload(byte[] file, AttachmentType type, MediaConnection mediaConnection) {
var auth = URLEncoder.encode(mediaConnection.auth(), StandardCharsets.UTF_8);
var uploadData = type.inflatable() ? BytesHelper.compress(file) : file;
- var fileSha256 = Sha256.calculate(uploadData);
- var keys = MediaKeys.random(type.keyName());
- var encryptedMedia = AesCbc.encrypt(keys.iv(), uploadData, keys.cipherKey());
- var hmac = calculateMac(encryptedMedia, keys);
- var encrypted = BytesHelper.concat(encryptedMedia, hmac);
- var fileEncSha256 = Sha256.calculate(encrypted);
- var token = Base64.getUrlEncoder().withoutPadding().encodeToString(fileEncSha256);
- var uri = URI.create("https://%s/%s/%s?auth=%s&token=%s".formatted(DEFAULT_HOST, type.path(), token, auth, token));
+ var mediaFile = prepareMediaFile(type, uploadData);
+ var path = type.path().orElseThrow(() -> new UnsupportedOperationException(type + " cannot be uploaded"));
+ var token = Base64.getUrlEncoder()
+ .withoutPadding()
+ .encodeToString(Objects.requireNonNullElse(mediaFile.fileEncSha256(), mediaFile.fileSha256()));
+ var uri = URI.create("https://%s/%s/%s?auth=%s&token=%s".formatted(DEFAULT_HOST, path, token, auth, token));
var request = HttpRequest.newBuilder()
- .POST(ofByteArray(encrypted))
+ .POST(ofByteArray(Objects.requireNonNullElse(mediaFile.encryptedFile(), file)))
.uri(uri)
.header("Content-Type", "application/octet-stream")
.header("Accept", "application/json")
.header("Origin", Whatsapp.WEB_ORIGIN)
.build();
return CLIENT.sendAsync(request, ofString()).thenApplyAsync(response -> {
- Validate.isTrue(response.statusCode() == 200, "Invalid status countryCode: %s", response.statusCode());
+ Validate.isTrue(response.statusCode() == 200, "Invalid status code: %s", response.statusCode());
var upload = Json.readValue(response.body(), MediaUpload.class);
- return new MediaFile(fileSha256, fileEncSha256, keys.mediaKey(), uploadData.length, upload.directPath(), upload.url());
+ return new MediaFile(
+ mediaFile.encryptedFile(),
+ mediaFile.fileSha256(),
+ mediaFile.fileEncSha256(),
+ mediaFile.mediaKey(),
+ mediaFile.fileLength(),
+ upload.directPath(),
+ upload.url(),
+ upload.handle(),
+ mediaFile.timestamp()
+ );
});
}
+ private static MediaFile prepareMediaFile(AttachmentType type, byte[] uploadData) {
+ var fileSha256 = Sha256.calculate(uploadData);
+ if(type.keyName().isEmpty()) {
+ return new MediaFile(null, fileSha256, null, null, uploadData.length, null, null, null, null);
+ }
+
+ var keys = MediaKeys.random(type.keyName().orElseThrow());
+ var encryptedMedia = AesCbc.encrypt(keys.iv(), uploadData, keys.cipherKey());
+ var hmac = calculateMac(encryptedMedia, keys);
+ var encrypted = BytesHelper.concat(encryptedMedia, hmac);
+ var fileEncSha256 = Sha256.calculate(encrypted);
+ return new MediaFile(encrypted, fileSha256, fileEncSha256, keys.mediaKey(), uploadData.length, null, null, null, Clock.nowSeconds());
+ }
+
private static byte[] calculateMac(byte[] encryptedMedia, MediaKeys keys) {
var hmacInput = BytesHelper.concat(keys.iv(), encryptedMedia);
var hmac = Hmac.calculateSha256(hmacInput, keys.macKey());
@@ -174,7 +196,13 @@ private static Optional handleResponse(MutableAttachmentProvider> prov
"Cannot decode media: Invalid sha256 signature", SecurityException.class);
var encryptedMedia = Arrays.copyOf(body, body.length - 10);
var mediaMac = Arrays.copyOfRange(body, body.length - 10, body.length);
- var keys = MediaKeys.of(provider.mediaKey().orElseThrow(() -> new NoSuchElementException("Missing media key")), provider.attachmentType().keyName());
+ var keyName = provider.attachmentType().keyName();
+ if(keyName.isEmpty()) {
+ return Optional.of(encryptedMedia);
+ }
+
+ var mediaKey = provider.mediaKey().orElseThrow(() -> new NoSuchElementException("Missing media key"));
+ var keys = MediaKeys.of(mediaKey, keyName.get());
var hmac = calculateMac(encryptedMedia, keys);
Validate.isTrue(Arrays.equals(hmac, mediaMac), "media_decryption", HmacValidationException.class);
var decrypted = AesCbc.decrypt(keys.iv(), encryptedMedia, keys.cipherKey());
@@ -372,7 +400,7 @@ private static Optional getPdfThumbnail(byte[] file) {
try (var document = PDDocument.load(file); var outputStream = new ByteArrayOutputStream()) {
var renderer = new PDFRenderer(document);
var image = renderer.renderImage(0);
- var thumb = new BufferedImage(Spec.Whatsapp.THUMBNAIL_WIDTH, Spec.Whatsapp.THUMBNAIL_HEIGHT, BufferedImage.TYPE_INT_RGB);
+ var thumb = new BufferedImage(Specification.Whatsapp.THUMBNAIL_WIDTH, Specification.Whatsapp.THUMBNAIL_HEIGHT, BufferedImage.TYPE_INT_RGB);
var graphics2D = thumb.createGraphics();
graphics2D.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
graphics2D.drawImage(image, 0, 0, thumb.getWidth(), thumb.getHeight(), null);
@@ -389,7 +417,7 @@ private static Optional getPresentationThumbnail(byte[] file) {
if (ppt.getSlides().isEmpty()) {
return Optional.empty();
}
- var thumb = new BufferedImage(Spec.Whatsapp.THUMBNAIL_WIDTH, Spec.Whatsapp.THUMBNAIL_HEIGHT, BufferedImage.TYPE_INT_RGB);
+ var thumb = new BufferedImage(Specification.Whatsapp.THUMBNAIL_WIDTH, Specification.Whatsapp.THUMBNAIL_HEIGHT, BufferedImage.TYPE_INT_RGB);
var graphics2D = thumb.createGraphics();
graphics2D.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
ppt.getSlides().get(0).draw(graphics2D);
diff --git a/src/main/java/it/auties/whatsapp/util/MetadataHelper.java b/src/main/java/it/auties/whatsapp/util/MetadataHelper.java
index cb84ece9..31a7a188 100644
--- a/src/main/java/it/auties/whatsapp/util/MetadataHelper.java
+++ b/src/main/java/it/auties/whatsapp/util/MetadataHelper.java
@@ -5,7 +5,7 @@
import it.auties.whatsapp.model.signal.auth.UserAgent;
import it.auties.whatsapp.model.signal.auth.UserAgent.PlatformType;
import it.auties.whatsapp.model.signal.auth.Version;
-import it.auties.whatsapp.util.Spec.Whatsapp;
+import it.auties.whatsapp.util.Specification.Whatsapp;
import net.dongliu.apk.parser.ByteArrayApkFile;
import net.dongliu.apk.parser.bean.ApkSigner;
import net.dongliu.apk.parser.bean.CertificateMeta;
diff --git a/src/main/java/it/auties/whatsapp/util/RegistrationHelper.java b/src/main/java/it/auties/whatsapp/util/RegistrationHelper.java
index 02991f3f..dfd74a49 100644
--- a/src/main/java/it/auties/whatsapp/util/RegistrationHelper.java
+++ b/src/main/java/it/auties/whatsapp/util/RegistrationHelper.java
@@ -13,7 +13,7 @@
import it.auties.whatsapp.model.mobile.VerificationCodeStatus;
import it.auties.whatsapp.model.node.Attributes;
import it.auties.whatsapp.model.signal.keypair.SignalKeyPair;
-import it.auties.whatsapp.util.Spec.Whatsapp;
+import it.auties.whatsapp.util.Specification.Whatsapp;
import java.io.UncheckedIOException;
import java.net.HttpURLConnection;
diff --git a/src/main/java/it/auties/whatsapp/util/Spec.java b/src/main/java/it/auties/whatsapp/util/Specification.java
similarity index 77%
rename from src/main/java/it/auties/whatsapp/util/Spec.java
rename to src/main/java/it/auties/whatsapp/util/Specification.java
index 9204e88c..fd5ac1d6 100644
--- a/src/main/java/it/auties/whatsapp/util/Spec.java
+++ b/src/main/java/it/auties/whatsapp/util/Specification.java
@@ -9,24 +9,23 @@
import java.util.Base64;
import java.util.HexFormat;
-public class Spec {
+public class Specification {
public final static class Whatsapp {
public static final String DEFAULT_NAME = "Cobalt";
- public static final byte[] PROTOCOL = "Noise_XX_25519_AESGCM_SHA256\0\0\0\0".getBytes(StandardCharsets.UTF_8);
+ public static final byte[] NOISE_PROTOCOL = "Noise_XX_25519_AESGCM_SHA256\0\0\0\0".getBytes(StandardCharsets.UTF_8);
public static final String WEB_ORIGIN = "https://web.whatsapp.com";
public static final String WEB_HOST = "web.whatsapp.com";
- public static final URI WEB_ENDPOINT = URI.create("wss://web.whatsapp.com/ws/chat");
- public static final String APP_ENDPOINT_HOST = "g.whatsapp.net";
- public static final int APP_ENDPOINT_PORT = 443;
+ public static final URI WEB_SOCKET_ENDPOINT = URI.create("wss://web.whatsapp.com/ws/chat");
+ public static final String SOCKET_ENDPOINT = "g.whatsapp.net";
+ public static final int SOCKET_PORT = 443;
public static final String WEB_UPDATE_URL = "https://web.whatsapp.com/check-update?version=2.2245.9&platform=web";
public static final String MOBILE_REGISTRATION_ENDPOINT = "https://v.whatsapp.net/v2";
- public static final String IOS_UPDATE_URL = "https://www.whatsapp.com/download?lang=en";
public static final Version DEFAULT_MOBILE_IOS_VERSION = Version.of("2.23.12.75");
- private static final byte[] WHATSAPP_HEADER = "WA".getBytes(StandardCharsets.UTF_8);
+ private static final byte[] WHATSAPP_VERSION_HEADER = "WA".getBytes(StandardCharsets.UTF_8);
private static final byte[] WEB_VERSION = new byte[]{6, BinaryTokens.DICTIONARY_VERSION};
- public static final byte[] WEB_PROLOGUE = BytesHelper.concat(WHATSAPP_HEADER, WEB_VERSION);
+ public static final byte[] WEB_PROLOGUE = BytesHelper.concat(WHATSAPP_VERSION_HEADER, WEB_VERSION);
private static final byte[] MOBILE_VERSION = new byte[]{5, BinaryTokens.DICTIONARY_VERSION};
- public static final byte[] APP_PROLOGUE = BytesHelper.concat(WHATSAPP_HEADER, MOBILE_VERSION);
+ public static final byte[] MOBILE_PROLOGUE = BytesHelper.concat(WHATSAPP_VERSION_HEADER, MOBILE_VERSION);
public static final byte[] ACCOUNT_SIGNATURE_HEADER = {6, 0};
public static final byte[] DEVICE_WEB_SIGNATURE_HEADER = {6, 1};
public static final byte[] DEVICE_MOBILE_SIGNATURE_HEADER = {6, 2};
@@ -36,7 +35,6 @@ public final static class Whatsapp {
public static final String MOBILE_DOWNLOAD_URL = "https://www.whatsapp.com/android/current/WhatsApp.apk";
public static final String MOBILE_BUSINESS_DOWNLOAD_URL = "https://d.apkpure.com/b/APK/com.whatsapp.w4b?version=latest";
public static final byte[] MOBILE_ANDROID_SALT = Base64.getDecoder().decode("PkTwKSZqUfAUyR0rPQ8hYJ0wNsQQ3dW1+3SCnyTXIfEAxxS75FwkDf47wNv/c8pP3p0GXKR6OOQmhyERwx74fw1RYSU10I4r1gyBVDbRJ40pidjM41G1I1oN");
- public static final byte[] MOBILE_SALT = Base64.getDecoder().decode("PkTwKSZqUfAUyR0rPQ8hYJ0wNsQQ3dW1+3SCnyTXIfEAxxS75FwkDf47wNv/c8pP3p0GXKR6OOQmhyERwx74fw1RYSU10I4r1gyBVDbRJ40pidjM41G1I1oN");
public static final byte[] REGISTRATION_PUBLIC_KEY = HexFormat.of().parseHex("8e8c0f74c3ebc5d7a6865c6c3c843856b06121cce8ea774d22fb6f122512302d");
public static final String MOBILE_IOS_STATIC = "0a1mLfGUIBVrMKF1RdvLI5lkRBvof6vn0fD2QRSM";
public static final int COMPANION_PAIRING_TIMEOUT = 10;
diff --git a/src/main/java/module-info.java b/src/main/java/module-info.java
index e992da60..2a3d8640 100644
--- a/src/main/java/module-info.java
+++ b/src/main/java/module-info.java
@@ -1,6 +1,7 @@
open module it.auties.cobalt {
requires static jilt;
requires transitive java.desktop;
+ requires jakarta.websocket.client;
requires java.net.http;
requires com.fasterxml.jackson.annotation;
requires com.fasterxml.jackson.databind;
diff --git a/src/test/java/it/auties/whatsapp/Test.java b/src/test/java/it/auties/whatsapp/Test.java
index e2fa9b28..aab2827e 100644
--- a/src/test/java/it/auties/whatsapp/Test.java
+++ b/src/test/java/it/auties/whatsapp/Test.java
@@ -1,15 +1,10 @@
package it.auties.whatsapp;
-import it.auties.whatsapp.util.ConcurrentDoublyLinkedList;
-
-import java.util.Objects;
+import it.auties.whatsapp.model.message.model.MessageContainerSpec;
+import it.auties.whatsapp.util.Json;
public class Test {
public static void main(String[] args) {
- var data = new ConcurrentDoublyLinkedList<>();
- data.add("abc");
- System.out.println(Objects.hashCode(data));
- data.add("def");
- System.out.println(Objects.hashCode(data));
+ System.out.println(Json.writeValueAsString(MessageContainerSpec.decode(new byte[]{26, -87, 44, 18, 10, 105, 109, 97, 103, 101, 47, 106, 112, 101, 103, 34, 32, -75, -27, -91, -94, -73, -127, 109, 3, -85, -47, -68, 80, -93, -72, 95, 2, 58, 44, 4, -4, 0, -101, 76, -97, 61, -17, -68, 71, -121, 50, -46, 31, 40, -36, -52, 2, 48, -32, 3, 56, -31, 3, 90, -15, 1, 47, 109, 49, 47, 118, 47, 116, 50, 52, 47, 65, 110, 56, 68, 114, 95, 81, 115, 76, 121, 109, 66, 74, 78, 82, 122, 116, 122, 87, 104, 104, 81, 45, 83, 78, 65, 101, 104, 121, 88, 120, 68, 85, 117, 53, 72, 108, 53, 117, 67, 79, 119, 90, 86, 111, 78, 81, 122, 55, 70, 120, 112, 69, 86, 81, 120, 51, 85, 49, 70, 80, 107, 113, 105, 115, 109, 113, 95, 87, 103, 74, 90, 105, 122, 72, 48, 52, 101, 122, 67, 106, 87, 114, 108, 70, 50, 54, 74, 67, 116, 101, 118, 71, 101, 98, 53, 85, 53, 49, 98, 55, 66, 109, 106, 53, 65, 102, 82, 72, 106, 86, 76, 117, 122, 86, 45, 100, 103, 49, 95, 73, 84, 77, 98, 79, 74, 95, 113, 102, 65, 63, 115, 116, 112, 61, 100, 115, 116, 45, 101, 110, 99, 38, 99, 99, 98, 61, 49, 48, 45, 53, 38, 111, 104, 61, 48, 49, 95, 65, 100, 83, 109, 78, 74, 89, 120, 55, 69, 90, 108, 113, 110, 88, 110, 88, 73, 105, 84, 102, 121, 90, 118, 70, 48, 75, 102, 70, 83, 110, 66, 88, 122, 111, 107, 110, 89, 108, 76, 116, 109, 106, 107, 102, 65, 38, 111, 101, 61, 54, 53, 52, 53, 51, 55, 51, 56, 38, 95, 110, 99, 95, 115, 105, 100, 61, 48, 48, 48, 48, 48, 48, -126, 1, -10, 41, -1, -40, -1, -32, 0, 16, 74, 70, 73, 70, 0, 1, 1, 0, 0, 1, 0, 1, 0, 0, -1, -30, 1, -40, 73, 67, 67, 95, 80, 82, 79, 70, 73, 76, 69, 0, 1, 1, 0, 0, 1, -56, 0, 0, 0, 0, 4, 48, 0, 0, 109, 110, 116, 114, 82, 71, 66, 32, 88, 89, 90, 32, 7, -32, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 97, 99, 115, 112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, -10, -42, 0, 1, 0, 0, 0, 0, -45, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 100, 101, 115, 99, 0, 0, 0, -16, 0, 0, 0, 36, 114, 88, 89, 90, 0, 0, 1, 20, 0, 0, 0, 20, 103, 88, 89, 90, 0, 0, 1, 40, 0, 0, 0, 20, 98, 88, 89, 90, 0, 0, 1, 60, 0, 0, 0, 20, 119, 116, 112, 116, 0, 0, 1, 80, 0, 0, 0, 20, 114, 84, 82, 67, 0, 0, 1, 100, 0, 0, 0, 40, 103, 84, 82, 67, 0, 0, 1, 100, 0, 0, 0, 40, 98, 84, 82, 67, 0, 0, 1, 100, 0, 0, 0, 40, 99, 112, 114, 116, 0, 0, 1, -116, 0, 0, 0, 60, 109, 108, 117, 99, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 12, 101, 110, 85, 83, 0, 0, 0, 8, 0, 0, 0, 28, 0, 115, 0, 82, 0, 71, 0, 66, 88, 89, 90, 32, 0, 0, 0, 0, 0, 0, 111, -94, 0, 0, 56, -11, 0, 0, 3, -112, 88, 89, 90, 32, 0, 0, 0, 0, 0, 0, 98, -103, 0, 0, -73, -123, 0, 0, 24, -38, 88, 89, 90, 32, 0, 0, 0, 0, 0, 0, 36, -96, 0, 0, 15, -124, 0, 0, -74, -49, 88, 89, 90, 32, 0, 0, 0, 0, 0, 0, -10, -42, 0, 1, 0, 0, 0, 0, -45, 45, 112, 97, 114, 97, 0, 0, 0, 0, 0, 4, 0, 0, 0, 2, 102, 102, 0, 0, -14, -89, 0, 0, 13, 89, 0, 0, 19, -48, 0, 0, 10, 91, 0, 0, 0, 0, 0, 0, 0, 0, 109, 108, 117, 99, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 12, 101, 110, 85, 83, 0, 0, 0, 32, 0, 0, 0, 28, 0, 71, 0, 111, 0, 111, 0, 103, 0, 108, 0, 101, 0, 32, 0, 73, 0, 110, 0, 99, 0, 46, 0, 32, 0, 50, 0, 48, 0, 49, 0, 54, -1, -37, 0, 67, 0, 3, 2, 2, 2, 2, 2, 3, 2, 2, 2, 3, 3, 3, 3, 4, 6, 4, 4, 4, 4, 4, 8, 6, 6, 5, 6, 9, 8, 10, 10, 9, 8, 9, 9, 10, 12, 15, 12, 10, 11, 14, 11, 9, 9, 13, 17, 13, 14, 15, 16, 16, 17, 16, 10, 12, 18, 19, 18, 16, 19, 15, 16, 16, 16, -1, -37, 0, 67, 1, 3, 3, 3, 4, 3, 4, 8, 4, 4, 8, 16, 11, 9, 11, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, -1, -64, 0, 17, 8, 0, 99, 0, 100, 3, 1, 34, 0, 2, 17, 1, 3, 17, 1, -1, -60, 0, 29, 0, 0, 1, 4, 3, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 5, 7, 8, 2, 3, 4, 9, 1, -1, -60, 0, 58, 16, 0, 2, 1, 3, 3, 3, 2, 4, 4, 4, 4, 6, 3, 0, 0, 0, 1, 2, 3, 4, 5, 17, 0, 18, 33, 6, 7, 49, 19, 65, 20, 34, 81, 97, 8, 35, 50, 113, 21, 66, -127, -79, 67, -111, -95, -63, 22, 51, 98, -47, -16, -15, 82, -110, -31, -1, -60, 0, 26, 1, 0, 2, 3, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 5, 2, 4, 6, 1, 0, -1, -60, 0, 48, 17, 0, 1, 4, 1, 1, 6, 5, 2, 6, 3, 0, 0, 0, 0, 0, 0, 1, 0, 2, 3, 17, 4, 33, 5, 18, 19, 49, 65, -127, 50, 81, 97, -111, -79, 34, 35, 20, 21, 66, 82, -63, -15, -95, -47, -31, -1, -38, 0, 12, 3, 1, 0, 2, 17, 3, 17, 0, 63, 0, -12, 75, -89, -90, -8, 122, 47, -122, -112, -126, 84, 1, -100, 123, -21, -90, 74, -36, 28, 70, -32, 107, -112, -62, -48, 47, -90, -119, -76, 30, 127, 113, -82, 11, -91, 101, -66, -37, 16, -98, -78, -83, 98, 36, -116, 2, -36, -109, -12, 31, 93, 37, 7, 117, -76, -104, 50, 39, 60, -48, 22, -100, 42, 107, 37, -63, -36, -4, -23, -106, -21, 126, -95, -75, -45, -75, 69, -62, -79, 33, 69, 25, 37, -37, 26, -120, -69, -103, -33, -54, -85, 13, 66, -39, -6, 103, -90, 46, -107, -75, -77, -113, -55, 45, 74, -24, -115, -19, -112, -52, 49, -96, 75, 103, 108, -69, -75, -35, -103, -65, -120, -9, 2, -25, 37, -66, -123, -50, -27, -93, -128, -111, -57, -36, -7, 58, 1, -98, -51, 51, 84, -23, -101, 37, -80, 48, 75, -101, 32, 96, 60, -121, 55, 30, -35, 59, -46, 44, -21, -97, -60, -27, -78, -110, 86, -78, 116, 93, 52, -73, -117, -117, 29, -86, -80, 2, -54, 15, -36, -8, 26, 19, -78, 118, -13, -70, -35, -44, -84, 55, 30, -67, -69, 61, -74, -35, 33, -36, -76, -112, -71, 4, -113, -95, -6, -22, 100, -24, -2, -47, 116, -97, 70, -45, 71, 77, 110, -76, -59, -22, 46, 51, 35, -88, 44, 79, -41, 71, 9, 72, 99, -116, 29, -69, 85, 7, -80, -58, 53, -34, 25, 113, -73, -107, -25, -19, 86, -29, -114, 22, 3, 55, 61, 78, -82, 61, -6, 118, -9, 65, -99, 23, -38, 62, -110, -24, -92, 87, -96, -73, 68, 100, 30, 100, 112, 9, 63, 125, 5, -9, -17, -71, 116, -16, 83, 30, -128, -74, -43, 50, -67, 92, 121, -72, 52, 14, 1, 16, -112, 64, -117, 35, -64, 110, 119, 120, 59, 70, 60, 54, -114, -70, -93, -84, -93, -94, 21, 54, -102, 25, 25, -86, 18, 50, 100, 120, -64, 62, -118, -5, -29, 56, 5, -79, -100, 12, -22, -93, 117, 21, -9, -8, -35, -34, -29, 94, -105, -120, 36, -81, -86, -109, 44, -49, 62, -33, 73, 7, -23, 64, -52, 65, 1, 84, 5, 28, -106, -32, 31, 109, 80, -55, -53, 105, -5, 49, 31, 79, -23, 15, 27, 29, -18, 119, 27, 34, -55, -25, -1, 0, 74, -77, -33, -121, -85, -11, 124, -3, 2, -108, 21, 14, 74, -38, 107, 101, -95, -127, -73, -18, 102, -124, 4, 116, -55, -5, 122, -104, 3, -64, 85, 94, 6, -92, -22, -51, -13, 5, 101, 124, -18, -43, 123, -4, 37, -34, -123, 68, 61, 73, -45, 13, 83, 28, -111, -45, 77, 13, 109, 56, 70, 44, 8, 117, 41, 33, 7, 39, 3, 49, -96, -28, -7, 39, -17, -87, 107, -83, -5, -107, -46, 29, 17, 72, -43, 55, -117, -84, 16, 122, 35, 36, 51, -128, 120, -43, -52, 87, 125, -127, 103, -110, -81, 62, 36, -45, -27, 24, -96, 105, 36, -7, 122, -89, -39, 20, 67, -55, 76, -3, 79, -45, 65, -3, 101, -35, -98, -112, -24, 24, 36, -86, -68, 92, -31, -120, -88, 63, 46, -15, -97, -37, 80, 79, 82, 126, 33, 59, -127, -36, -86, -26, -79, 118, -106, -61, 59, -63, 41, -40, 107, -27, 66, -79, -113, 108, -113, 115, -3, -76, -21, -47, 31, -123, 10, -53, -43, -63, 58, -117, -71, -41, -103, -18, -43, -92, -17, -12, -28, 111, -53, 66, 125, -126, -8, -44, -72, -82, 126, -111, 14, -23, -96, -39, 120, -101, 60, 111, 109, 41, 45, -33, -79, -70, -98, -25, -112, -7, -12, 92, 117, -1, 0, -116, 11, -3, -62, -87, -25, -23, 94, -119, -82, -83, -73, -125, -75, 38, 17, -128, 24, -113, 56, -49, -73, -115, 45, 89, 27, 103, 105, 122, 102, -41, 69, 29, 29, 29, -94, 20, -115, 7, 0, 32, -46, -41, 119, 38, -3, -22, 31, -100, 97, 13, 27, -118, -54, -11, -69, -7, 81, 15, 95, -2, 45, -83, 48, -36, 31, -89, 122, 2, -122, 91, -11, -41, 59, 2, -45, 13, -56, -121, -2, -90, -16, 52, 43, 103, -19, -9, 124, 59, -93, 119, -90, -22, 30, -71, -67, -67, -78, -122, -98, 100, -98, 42, 42, 102, 41, -56, 57, 27, -101, -55, -1, 0, -49, 58, -100, 58, 19, -16, -39, -47, 29, -70, -91, -114, 59, 61, 60, 66, 101, 31, 52, -89, -106, 39, -36, -25, 69, -23, 100, -120, 63, -96, -73, 7, 85, 83, -55, -53, 107, -90, 7, 60, 125, -49, 101, 9, 54, -60, 120, -19, -31, 108, -10, 6, 15, 51, -85, -113, 126, -99, -67, -41, -103, -76, -11, 23, -50, -102, -67, 84, -45, 85, -44, 87, 82, 93, -88, -86, -92, 73, -25, 21, 78, -107, 9, 50, -71, 86, 37, -55, -35, -69, 118, 119, 49, 57, -50, 114, 121, -50, -89, 46, -37, -2, 43, -6, -106, -59, 77, 75, 111, -22, -75, 75, -83, -72, -108, -120, 86, 51, 41, -88, -121, -37, 45, -56, 19, 120, -5, 30, 73, 36, -29, 5, -101, -15, -55, -37, -108, -23, 46, -89, -76, -11, -75, -119, 24, 82, -11, 36, -90, -110, -32, -55, 8, -38, -75, 106, 1, 83, -72, -99, -69, -28, 80, 72, 82, -66, 98, 102, -50, 114, 69, 110, -93, -87, -110, -5, 73, 53, 13, 11, -71, -119, 34, 102, -87, -85, 50, 9, 21, 51, -6, -117, 59, -2, -87, 15, -71, -25, 31, 124, -28, 40, 17, 63, 27, 120, -121, 106, 62, 21, -57, -55, 22, 92, 108, 115, -101, -95, -7, 94, -121, 84, 126, 33, -83, -14, 80, -46, 85, -46, -46, -63, 51, 86, 70, 30, 63, 74, 70, 108, 12, 18, 75, 0, -89, 24, -57, -116, -5, -125, -32, -116, -57, -99, 75, -33, -18, -96, -82, 8, 45, -77, -71, -89, -112, -128, 73, 66, -120, -82, 78, 48, 79, -98, 8, -2, -68, 28, -32, -15, 89, 44, -73, 100, -85, 51, -37, 97, 89, -128, 72, -61, -57, 33, -107, -107, -111, 87, 105, 56, -38, -64, -78, -80, -31, -105, 5, -58, -20, -126, 50, 85, -33, 104, 58, -126, -37, 69, -46, 115, -61, 56, 85, -127, 36, 102, -73, -42, -47, 75, -22, 41, -84, 13, -109, 27, 96, -106, 18, 72, 10, -108, -28, 46, -24, -58, 48, 64, -36, -106, 92, -36, -84, -126, 70, -10, -118, -36, 88, 56, -8, -32, 29, -35, 84, -101, 126, -22, 30, -90, -82, 118, -83, -118, -117, -45, -91, -106, 61, -16, 84, -91, 70, 89, 114, -72, 11, -61, -100, -7, -6, 103, 7, -125, -96, 25, -83, 20, -9, 24, 96, -82, -82, -76, 49, 53, -110, 21, 43, 39, 50, 17, -126, 3, 28, -28, 17, -50, -31, -111, -125, -72, 126, -38, -23, -23, -82, -79, -93, -21, 89, 58, 122, -110, -82, -22, 103, -94, 90, -54, -22, 106, -8, 94, 80, 38, -35, 36, 69, -111, -36, 58, -16, 81, -40, -27, 60, -122, 80, 118, -128, 27, 14, -3, 48, -47, -37, -37, -88, 104, 122, -90, -13, 76, 99, -77, -44, 71, 63, -58, -51, 58, -57, 31, -64, 73, -22, -108, 101, 98, 126, 95, 10, -83, -114, 73, 92, 121, -50, -86, -73, 29, -27, -63, -51, 58, -1, 0, 53, 104, -50, -107, -84, 105, 107, -121, 47, -117, -92, -15, -38, 99, 95, -45, -13, 77, 103, -24, -58, 22, -55, 46, 20, 50, 82, -59, 85, 56, 44, -79, -54, 89, 9, 115, -76, -115, -7, -40, 61, -72, -64, 28, -7, -44, -125, 96, -4, 39, 87, -34, 111, 9, -44, 125, -51, -22, 122, -117, -13, -17, -35, -23, 57, -4, -91, -3, -105, -12, -29, 64, 52, 125, -54, -19, -30, -42, -117, -113, 72, 94, 41, -70, -118, 0, 61, 57, 18, -36, -94, 103, 37, 49, -100, -116, -28, 1, -14, -27, -72, 30, 124, 112, 53, 100, 59, 17, -36, 107, 127, 86, -58, -42, 39, -84, 33, -30, -113, -44, -12, -86, 1, 89, -30, -1, 0, -95, -58, 6, 15, -97, 111, 99, -5, -105, -69, 50, 99, -60, -32, 78, 108, -12, 75, -14, -14, 114, 96, -57, 63, -122, 37, -83, 60, -4, -49, 126, 127, -62, 125, -89, -117, -96, -5, 121, 69, 29, 37, 61, 12, 20, 113, -96, -38, 8, 64, -65, -21, -89, -102, 62, -82, -23, -55, -102, 35, 79, 95, 30, 102, 25, 81, -111, -94, -101, -105, 73, -12, -11, -6, 15, -122, -83, -91, -114, 96, 7, -45, -50, -101, -32, -19, -17, 73, 90, 29, 42, 26, -123, 1, -113, -12, 12, 120, -42, -114, -98, 14, -107, 75, 34, 75, -119, -78, 86, 38, -7, 1, -1, 0, 21, -65, -6, -99, 45, 59, 9, 108, 107, -62, 82, -95, 3, 75, 82, -41, -51, 74, -126, -32, -102, -76, 67, 72, 26, 119, -37, 18, -114, 93, -113, 26, 18, -85, -22, -40, 119, -54, -76, -61, -14, -41, -125, 33, 30, -1, 0, 65, -11, -45, 39, 112, 122, -71, 41, 97, -98, 58, 70, 14, -112, 127, -122, 78, -36, -81, -41, 81, -1, 0, 75, 95, -18, -105, -28, -110, -66, -94, 1, 67, 74, -110, -6, 116, -28, -126, 90, 86, -3, -67, -121, -11, -46, 108, -99, -90, -23, 37, -32, -58, 83, -68, 109, -102, -42, -57, -59, -111, 16, -9, 35, -90, 41, -6, -17, -73, -3, 87, 109, -68, 62, -6, 42, -69, 124, -103, -114, 83, -6, 100, 82, 30, 55, 31, 77, -82, -86, -64, -126, 8, 32, 17, -126, 50, 60, -7, -113, -90, 111, 54, 123, -123, 101, -90, -94, 20, 88, 103, -100, 84, -56, -55, -112, -69, -128, 25, 57, 60, 12, -112, 120, -50, 57, -13, -17, -81, 71, 47, 85, 5, 58, 126, -74, -42, -11, 113, 75, 44, -108, -90, 73, 98, 31, -51, -58, 54, -29, 60, 12, 127, 125, 80, -34, -32, -11, 52, 116, -46, -35, -21, -51, 36, 114, -51, 43, 122, 48, 66, -64, -18, -7, -113, 3, -127, -62, -127, -113, 111, 30, 116, -69, 52, 22, 86, -23, -25, -49, -43, 49, -61, 112, 113, 45, 61, 57, 45, -106, -6, 122, -22, 90, 10, 90, -92, -102, -33, 73, 4, 37, 12, -83, 87, 10, -84, 75, -122, 36, -79, 35, 105, 4, 16, 88, 56, -25, 32, 114, 50, 116, -51, -37, -7, 45, 52, 116, -3, 71, -45, -99, 47, 119, -77, 93, -19, -41, 52, -122, -74, 122, 107, 125, 84, 83, 26, 106, -116, 114, -121, -109, 34, -31, -7, 86, 56, -28, 19, -116, -116, -24, 62, -15, -46, -9, 59, -3, -92, -59, 95, -43, 48, 84, 77, 69, 32, -105, -8, 68, -77, -76, 52, -45, -94, -115, -2, -114, 89, -74, -77, 103, 105, 82, -25, 110, -31, -29, 4, -24, 52, 116, -49, 117, -28, -85, -74, 93, 122, 39, -92, 110, -74, -122, -77, 87, -75, 104, -71, 75, 12, 84, -122, 20, -61, 23, -118, 49, -69, -13, 3, 110, 57, 80, 10, -110, 70, 114, 14, 116, 92, 72, 34, 115, 104, -70, -119, -1, 0, 10, 57, 83, 74, -41, 83, 91, 97, 79, 118, 123, 44, -13, 87, -44, -43, -45, 69, 42, 69, 49, 40, -110, 74, -1, 0, -14, 38, 42, 21, -78, -4, 23, 44, -86, -53, -13, 100, -79, 85, 62, 87, -104, -1, 0, -65, 21, -113, 100, -65, 88, 44, 125, 89, 75, 57, -89, -69, -37, -106, -90, 10, -31, 21, 68, -95, -82, 81, 85, -82, -40, -28, -118, 38, 6, 76, 36, 76, -95, 24, 17, -118, -119, 48, -95, -74, -78, -55, -35, 23, -41, -10, 59, -32, -118, -90, 90, 42, 122, 123, -116, -27, 42, 106, 68, 76, 51, 20, -22, -53, -22, 32, 39, -54, -109, -69, -40, 103, 3, -10, -45, -89, 86, -43, 60, -99, 107, 97, 123, 108, -16, 108, -118, 87, -12, 29, 91, 62, -116, -110, 40, 12, -118, -33, -89, 33, 0, -7, -63, 25, -31, 115, -63, 2, -85, 101, 110, 51, -116, -100, -6, 105, -45, -43, 21, -16, 63, 34, -104, -19, 58, -5, 33, -50, -126, -65, 79, -37, 126, -109, -66, 92, -81, 86, -7, -83, -105, 78, -90, -71, 83, -55, 108, -73, 85, 46, -55, -93, -90, -118, 5, -115, -90, -110, 16, 127, 40, -56, -32, 97, 28, 43, 16, 65, -37, -18, 39, 63, -61, -11, 93, 101, -61, -82, -19, 125, 71, 80, -21, 11, -44, 68, -79, -56, -22, -28, -103, 50, -91, 8, 124, 12, 22, 24, 7, -113, 26, -121, 47, -35, -68, -65, 92, 122, -126, 26, -97, -116, -102, -29, 13, 92, -78, 122, -26, 89, -46, 69, 118, -113, -106, 66, 23, -121, -38, -55, -110, 8, 7, 57, 30, 70, 117, 35, -2, 29, 45, -107, 87, 14, -28, -47, 8, 46, 82, 77, 5, 26, -76, -83, 10, 71, -124, 85, -12, -7, -25, 3, 102, -42, -38, -101, 2, -32, -112, 72, 56, 0, -79, 49, 90, -7, -25, 108, -124, 104, 8, 30, -54, -74, 99, -94, -122, 46, 19, 14, -75, -81, -6, 87, 111, -2, 41, 104, -25, 88, 41, -80, 118, -32, 103, 91, -22, 110, -75, -43, 72, -83, 34, 14, 124, 115, -95, -119, -19, -22, -82, -114, -103, 31, 54, -19, -64, -100, -2, -38, -34, -43, -46, -61, 8, 83, 55, 11, -29, -97, 26, -43, 21, -101, 3, -55, 56, 52, -20, -60, -29, -5, -23, 105, -84, -36, -40, 28, 25, 70, 127, 108, -23, 106, 43, -37, -91, 67, -99, -38, -85, -118, -37, 106, -83, 63, 25, 26, 78, 84, -6, -116, -72, -54, -125, -5, -7, -3, -75, -113, 111, -126, -75, -74, -126, -86, -94, -31, 35, 82, -63, 6, -10, 14, 2, -18, 45, -49, -111, -12, 0, -1, 0, -98, -123, -70, -114, -13, -45, 23, 27, 68, -45, 117, 45, 90, 50, -43, 74, 75, -122, 99, -75, -122, 120, 39, -19, -10, -47, 80, 123, 101, 21, -78, -35, 6, -32, -44, -116, -116, 85, 81, 74, 2, -95, 56, -6, 96, 96, 1, -84, -100, 0, 58, 82, -15, -28, -75, 111, 117, 69, -70, 83, 119, 86, -9, 10, -34, -67, 75, 78, -42, -116, 77, 2, -54, -90, -74, 69, 118, 42, 23, -7, -108, -115, -69, -113, 28, 113, -17, -86, -59, -36, 78, -109, -71, -57, -43, -9, 23, -110, -90, -100, -67, 48, 50, 81, -62, -54, -71, 116, -31, -111, -78, 70, 71, -73, -33, 71, -3, -21, -21, -118, 126, -108, -100, 82, 90, -31, 122, 84, -87, 82, -62, 70, 114, 20, 19, -128, 54, -81, -114, 62, -40, -15, -96, 57, 46, 54, -66, -29, -38, 41, 104, -27, -103, -115, -30, -124, 17, 21, 65, -50, 101, -116, -110, -58, 62, 79, 59, 64, -6, -98, 3, 125, -75, 125, -51, 19, 10, -26, 66, -90, -62, -24, 72, 119, 32, 80, 117, -33, -89, 41, 110, -92, 111, -72, -111, 83, -123, 32, -76, 10, 6, 71, -8, 98, 69, -15, -113, 24, 33, -80, 15, -41, -58, 22, 110, -126, -67, -57, 112, -122, 122, -40, -124, 116, -24, -20, 97, -11, 99, 3, 36, -28, -128, 64, 36, 123, -98, 114, 114, 49, -100, 19, -128, -11, 5, -126, -118, -47, 24, 70, -89, -115, 106, 28, -28, -54, 55, 50, 35, 21, 63, -83, -79, -97, 124, -16, 73, -54, 50, -29, -112, 116, 123, -45, -9, 58, -119, -24, 41, -23, -29, 74, -76, -86, -111, -35, -94, 72, -111, 34, -98, 24, 100, -57, -52, 29, -9, -104, -61, 101, 64, -56, -3, 32, 55, -13, 1, -87, -77, 1, -109, 52, -39, -94, -68, -20, -7, 32, 52, 53, 10, 55, -97, -96, 36, -110, 72, -89, -23, 38, -118, 11, -75, 54, 101, -114, 106, -62, -23, 21, 64, 44, 118, -86, -56, -69, -127, 12, 88, 124, -33, 49, -50, -31, -116, -18, -37, -93, -96, 58, 102, -2, 59, -111, 53, -5, -82, 107, 38, -95, 107, 37, 11, -57, 79, 70, -75, -117, 45, 60, -13, -49, -69, 107, -126, -118, 3, 70, 63, 49, -117, -107, 4, 59, 68, 91, 44, -95, 116, 125, 61, -38, -17, 78, -18, 104, -31, -122, -86, -94, -80, 101, 102, 89, -125, 48, 92, 16, 1, -112, -79, 124, -28, 46, 75, 31, -101, 4, 109, 24, -58, -102, 107, 44, 116, -15, -56, 47, 87, -37, -68, -122, 87, -7, 76, 49, 84, 48, -116, 38, 89, -120, 5, 113, -69, 7, 7, -100, -28, -13, -25, 26, 36, 88, 98, 38, -112, 84, -92, -38, 14, -112, 87, -10, -92, 43, 47, 85, 83, -37, 109, -41, 42, 40, 110, 37, 98, -88, -89, -110, -94, -81, -46, -109, -47, 105, 10, 66, 127, -101, -45, -109, 123, 51, 21, -115, 99, 121, 120, 96, -128, 21, 3, -103, -81, -79, 93, 59, 63, 75, -12, -5, -33, -21, 39, -106, -90, -21, 119, 27, -106, -82, -86, 71, 121, -66, 31, 63, -106, 27, 115, -80, -55, 82, 9, 0, -16, 120, -25, 25, -43, 68, -73, 95, -32, -76, 73, 21, 61, 34, -56, -80, -88, -33, -103, 100, -36, 73, -16, 119, 103, -11, 3, -18, 8, -25, -97, 110, 53, 113, -5, 59, 114, -98, -81, -73, -44, -107, 91, 23, 107, 51, -76, 81, 49, 45, -23, -89, -78, -116, -14, 64, -25, 25, -55, -5, -97, 36, -104, 50, 48, -53, -61, 29, 18, -20, -90, 59, 119, -120, 122, -93, -79, 124, -87, -123, -116, 75, 35, 41, 99, -13, 18, 78, 7, -12, -42, 54, -6, -120, -94, -86, 105, -85, 100, 121, -108, -74, 112, -57, 25, -41, 28, -76, 126, -80, -118, 78, 88, -80, -55, 95, 24, -1, 0, -50, 78, -98, -41, -89, -43, -87, -43, 89, -48, -126, -96, -25, 60, -125, -90, -124, -38, -93, 84, -75, -51, 123, -75, -68, -116, 66, -6, 99, 56, 11, -113, 26, 90, -51, -32, -126, 6, 49, 71, 72, -124, 15, 39, 25, -55, -46, -44, 105, 74, -107, 86, -90, -19, 103, -15, 126, -31, 65, 55, 80, 95, 42, 36, -73, -59, 48, -110, 10, 56, -27, 43, 27, -56, 27, -63, 10, 121, 81, -114, 65, -32, -5, -24, -69, -88, 106, -28, -71, -36, -29, -115, -44, 124, 12, 115, 72, 17, 64, 5, 91, 0, -88, -14, 60, 103, -5, 123, 107, 42, 115, 95, 110, -66, -61, 30, 4, -11, 71, -44, -90, 4, 100, -111, 52, -103, 28, 103, -114, 6, -101, 42, 125, 122, 106, -58, -114, -94, 102, 48, -63, 30, 55, 43, 54, 94, 99, -110, 125, -80, 0, 28, -25, 35, 89, 104, -94, 12, 20, 60, -42, -114, 89, 75, -64, 36, -12, 80, 87, 121, -103, 111, -26, 72, -18, 51, -58, 62, 13, -106, 55, 83, 33, 105, 74, -125, -126, 48, 72, 32, -29, -100, 112, 62, -29, 81, 61, -74, -23, 85, 96, -72, -61, 37, 50, -49, 75, 2, -84, 72, -24, -78, 21, -106, 69, 117, -53, 124, -5, 112, 20, -128, 72, -56, 35, -25, 94, 24, 101, -76, 101, -35, -38, -23, 106, 110, -90, -19, 111, 37, 61, 25, 0, -108, 6, -36, -52, 20, -8, 39, -64, -6, -25, -49, 58, -116, -23, -81, -76, -7, 101, -86, 77, -80, -45, -87, 112, 74, -27, 75, 96, -107, 31, 50, -107, 56, -13, -75, -80, 24, 41, 25, -55, 3, 83, -115, -18, 105, -80, -90, 99, 14, 101, 86, -118, 102, -96, -70, -43, -42, -37, 126, 41, -90, -122, 106, 111, 76, -123, -115, 36, 98, -37, -101, -64, -35, -126, 55, 96, 41, 57, -14, -93, 110, 114, 8, 31, 90, -16, -48, 69, 34, 71, 102, 119, 121, -92, 95, 84, -102, -80, -54, -18, -84, -1, 0, -104, -96, 12, 21, -38, -36, 121, 57, 36, -122, 0, -19, -48, 55, 73, -35, -91, 69, -89, -84, -89, -116, 4, 68, 102, 77, -78, 42, 72, -118, 54, -94, 18, 71, -110, 14, -45, -123, 25, 35, 36, -15, -13, 3, -118, 59, -68, 119, 6, 119, -111, 94, 64, 0, 72, 93, -7, 44, -65, -53, -17, -57, 7, -3, 52, -51, -77, -79, -64, 30, 69, 43, 124, 46, 105, 32, 46, 90, -6, 27, -3, -42, 121, 34, 74, 56, -88, -121, -86, 78, 33, 63, -53, -100, -19, 3, 3, 0, 28, -116, 15, 111, -12, -39, 79, -47, 17, 34, 122, -43, 46, -51, -23, -27, -79, 35, 18, -96, -3, 116, 90, 46, -112, -61, 74, 106, 89, 119, 62, -45, -67, -39, 118, -110, -7, 63, 55, -33, -97, 127, -21, -17, -90, 11, -121, 87, -63, -80, -57, 49, 85, -33, -116, -96, 25, 39, -33, 24, -3, -11, -39, -72, 97, -74, 74, 12, 108, -112, -70, -128, 66, -105, 26, 89, 63, -117, -60, -47, -62, -90, 53, 113, 25, 24, -50, 7, -3, -75, 119, -69, 101, 83, 81, 102, -23, 43, 101, 19, -47, -107, -52, 33, -40, -29, 3, -98, 117, 85, -5, 111, -46, -115, -43, -67, 105, 71, 69, 36, 50, 42, 23, -11, 68, 47, -29, 98, -4, -33, -19, -113, -21, -85, 119, 86, -77, 82, -37, -87, -94, -118, 65, 38, 0, 79, -121, 68, -37, -76, 99, -58, 116, 13, -103, 25, -33, 124, -67, -111, 115, -28, -6, 91, 24, 68, -12, -73, -120, -26, -87, 18, 51, -61, 10, -58, -101, -105, 121, -55, 111, -80, -42, -38, -101, -37, 74, 99, 74, 87, 69, 121, 27, -27, -1, 0, -30, 6, -126, -39, -2, 38, 7, -12, 32, -12, -26, -124, -120, -10, 49, -58, 52, -29, 12, 15, 72, -87, 29, 90, 122, -90, 33, -65, 10, 124, -109, -29, -99, 55, -6, -110, -30, 19, -11, 95, 83, 86, 82, -53, -24, -103, 16, -107, 28, -99, -128, -13, -3, 70, -106, -122, -88, -92, -88, -88, -115, -36, -47, -57, -61, -111, -13, 17, -1, 0, 125, 45, 75, 85, -53, 81, -83, -86, -13, 90, -43, -122, -72, -52, 22, 37, -107, -103, 112, -125, 39, 32, -27, -78, 126, -98, 52, 1, 95, -43, -122, -11, 21, 75, 77, 92, 41, 69, 29, 76, -111, -61, 22, -48, 11, -32, 16, 73, 44, 51, -49, 39, -113, -66, -92, 90, -5, -59, 5, 13, -127, -92, -84, 72, -41, -31, 41, -100, -31, 87, 0, 40, 98, 88, -2, -25, 62, 117, 94, 122, -63, 110, 18, 85, -98, -91, 68, 95, -125, -88, 97, 60, 108, 37, 27, -95, 83, -32, 54, 63, -73, -2, -75, -103, 54, 0, -42, -42, -111, -83, 14, 60, -87, 2, 117, 69, 87, -60, -42, -49, 44, 37, -34, 70, 109, -77, 9, 63, -100, 15, -73, -115, 1, 93, 41, 105, -42, -102, 82, -108, -46, 64, -45, 124, -52, 9, 62, -101, -114, 112, 54, -7, -32, -122, -25, -22, 71, 28, 104, -50, -7, 116, -90, -72, -53, 52, -12, -14, 71, 2, -16, -40, 35, -106, -57, -106, 56, -15, -1, 0, -67, 53, 73, 36, 49, -76, 102, 106, 111, 95, 43, -103, 20, -16, 118, -3, 72, -5, -97, -19, -82, 53, -76, -116, 95, 73, -106, -57, -15, -12, 113, 109, -118, 85, -105, 126, -46, -123, -92, 35, -45, 0, 29, -53, -127, -28, -109, -76, -25, 60, 99, -33, 58, 55, -95, -70, 95, 41, 105, -43, -38, 40, -29, 76, 42, -82, -42, -36, 84, 14, 15, -7, 115, -90, 107, 125, 53, -78, 73, 74, 71, 69, -23, 70, 67, 72, 89, 101, -61, -87, -64, -56, -57, -45, -12, -23, -46, 57, -23, 112, -87, 19, 29, -59, -65, -27, 103, -99, -61, -50, 113, -94, -122, 56, 4, 7, 72, 15, 68, 79, 21, 124, 117, 52, -53, -66, -78, 66, -17, -63, 118, -7, 118, -110, 60, 127, 81, -127, -3, 53, -58, -47, -47, -45, -43, 25, -108, -6, -18, -8, -61, -71, -25, 35, 76, -26, -70, 55, -87, 49, -62, -7, 88, -108, -18, 0, -28, 18, 113, -17, -12, -1, 0, -74, -69, 105, 37, 87, 112, -43, -118, -79, -100, 109, 8, 61, -121, -111, -57, -65, -1, 0, -102, -125, -126, 29, -46, -80, -1, 0, -123, 26, 85, -97, -83, -65, -118, 78, 3, 109, -119, -63, 45, -32, 19, -64, -29, 86, -26, -27, -46, 109, 88, 13, 66, 72, -79, 43, 28, 23, 43, -17, -10, -1, 0, -49, 125, 83, -114, -54, -36, 23, -89, 96, -89, -86, -126, 39, 18, 84, -50, -93, 57, -2, 81, -85, -91, 111, -87, -85, -85, -94, -118, 42, -87, -41, -46, -110, 53, -111, 8, 31, 54, -101, 108, -48, 4, 91, -67, 82, -68, -65, 29, -95, 83, -48, 115, 69, 48, -108, -44, 43, 7, -25, -17, -57, -41, 90, -33, -90, 107, -23, -93, -102, 89, -35, 84, -80, -64, 12, 8, -34, 62, -38, 47, -8, -118, -38, 38, -111, -28, -125, -28, 113, -124, -53, 2, 72, -6, -97, -90, -72, 100, -8, -85, -101, -95, -98, -92, 8, -45, 39, -45, 83, -110, 52, -62, -76, 85, 80, 53, 77, -78, 117, -104, -120, 36, 40, -98, -61, 39, -3, -76, -76, 75, 81, 110, -73, -68, -84, 97, -88, 27, 65, -58, 25, 121, 7, 75, 92, -91, -19, 20, 7, -44, -44, -108, -33, -62, -103, 125, 21, -61, -84, -118, -61, 28, 16, 7, -116, 106, -71, -55, 85, 81, 53, 112, -92, -106, 102, 104, 29, 25, 12, 103, -12, -128, 16, -111, -127, -19, -49, -45, 75, 75, 89, -71, 5, 16, -76, -111, 120, 74, 15, -83, -94, -92, -98, 72, -124, -76, -24, -39, 56, 60, 96, -97, 62, -6, 85, 52, -76, -17, 75, -67, -95, 82, -63, 50, 15, -72, -32, -97, -10, 26, 90, 90, 52, 0, 16, -123, -112, 72, 114, 17, 53, -107, 34, -43, 61, 64, -108, -119, 84, -54, 3, 96, 103, 25, -58, -120, 34, -114, 52, -110, 9, 82, 53, 12, 99, -107, -55, 10, 63, 86, -52, -25, -4, -64, -46, -46, -47, 74, 13, -81, -74, 104, -45, -29, -92, -117, 111, -54, -50, 20, -113, -74, -33, 26, -20, -78, 19, 53, -56, -76, -89, 121, 57, 25, 60, -8, 36, 13, 45, 45, 1, -2, 18, -68, 124, 74, 113, -23, -41, 104, -22, 45, 91, 24, -81, 10, 120, -5, -99, 93, -5, 35, -78, 88, 45, -45, 41, -7, -52, 96, 18, 121, -10, -46, -46, -45, 13, -101, -6, -69, 37, -7, -97, -91, 102, -45, -53, 83, 14, 103, 125, -25, 118, 57, 30, -40, 58, -62, -113, -14, -29, -100, -89, 7, 110, 116, -76, -76, -63, 86, 11, 11, 101, 52, 19, 82, 9, 101, -116, 51, -79, 36, -109, -17, -91, -91, -91, -81, 41, 47, -1, -39, -56, 1, 0}), true));
}
}
diff --git a/src/test/java/it/auties/whatsapp/local/WebTest.java b/src/test/java/it/auties/whatsapp/local/WebTest.java
index 66d6e0e6..04a5da95 100644
--- a/src/test/java/it/auties/whatsapp/local/WebTest.java
+++ b/src/test/java/it/auties/whatsapp/local/WebTest.java
@@ -4,6 +4,10 @@
import it.auties.whatsapp.api.WebHistoryLength;
import it.auties.whatsapp.api.Whatsapp;
import it.auties.whatsapp.model.info.MessageInfo;
+import it.auties.whatsapp.model.jid.Jid;
+import it.auties.whatsapp.model.message.standard.ImageMessageSimpleBuilder;
+import it.auties.whatsapp.model.signal.auth.UserAgent;
+import it.auties.whatsapp.utils.MediaUtils;
import org.junit.jupiter.api.Test;
// Just used for testing locally
@@ -12,9 +16,14 @@ public class WebTest {
public void run() {
var whatsapp = Whatsapp.webBuilder()
.lastConnection()
- .historyLength(WebHistoryLength.extended())
+ .historyLength(WebHistoryLength.zero())
+ .releaseChannel(UserAgent.ReleaseChannel.BETA)
.unregistered(QrHandler.toTerminal())
- .addLoggedInListener(api -> System.out.printf("Connected: %s%n", api.store().privacySettings()))
+ .addLoggedInListener(api -> {
+ System.out.printf("Connected: %s%n", api.store().privacySettings());
+ var chat = Jid.of("120363185259738473@newsletter");
+ api.sendMessage(chat, new ImageMessageSimpleBuilder().media(MediaUtils.readBytes("https://upload.wikimedia.org/wikipedia/commons/thumb/3/3a/Cat03.jpg/481px-Cat03.jpg")).caption("Test").build()).join();
+ })
.addFeaturesListener(features -> System.out.printf("Received features: %s%n", features))
.addNewMessageListener((api, message, offline) -> System.out.println(message.toJson()))
.addContactsListener((api, contacts) -> System.out.printf("Contacts: %s%n", contacts.size()))
diff --git a/src/test/java/it/auties/whatsapp/update/UpdateBinaryTokensTest.java b/src/test/java/it/auties/whatsapp/update/UpdateBinaryTokensTest.java
index ee5bd383..d440cf66 100644
--- a/src/test/java/it/auties/whatsapp/update/UpdateBinaryTokensTest.java
+++ b/src/test/java/it/auties/whatsapp/update/UpdateBinaryTokensTest.java
@@ -5,7 +5,7 @@
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import it.auties.whatsapp.github.GithubActions;
-import it.auties.whatsapp.util.Spec.Whatsapp;
+import it.auties.whatsapp.util.Specification.Whatsapp;
import org.junit.jupiter.api.Test;
import java.io.IOException;