IDEA
下载:https://www.jetbrains.com/idea/download
key:https://zhile.io & https://gitee.com/pengzhile/ide-eval-resetter & lookdiv.com & https://33tool.com/idea & https://jetbra.in/s
环境变量 IDEA_VM_OPTIONS(idea64.exe.vmoptions)、IDEA_PROPERTIES(idea.properties):https://www.jetbrains.com/help/idea/tuning-the-ide.html
::https://plugins.zhile.io & IDE Eval Reset ::http://fls.jetbrains-agent.com @echo off ::setlocal enabledelayedexpansion set array=IDEA CLION for %%i in (%array%) do ( setx %%i_VM_OPTIONS %cd%\jetbrains.vmoptions for /f %%j in ('powershell -Command "'%%i'.ToLower()"') do ( setx %%i_PROPERTIES %cd%\%%j.properties ) ) ( echo --add-opens=java.base/jdk.internal.org.objectweb.asm=ALL-UNNAMED echo --add-opens=java.base/jdk.internal.org.objectweb.asm.tree=ALL-UNNAMED echo -javaagent:%cd%\ja-netfilter.jar ) > jetbrains.vmoptions ( echo idea.config.path=../../ideaIUData/config echo idea.system.path=../../ideaIUData/system echo idea.plugins.path=../../ideaIUData/plugins echo idea.log.path=../../ideaIUData/log ) > idea.properties ( echo idea.config.path=../../CLionData/config echo idea.system.path=../../CLionData/system echo idea.plugins.path=../../CLionData/plugins echo idea.log.path=../../CLionData/log ) > clion.properties
OpenJDK:https://adoptium.net/zh-CN/temurin/releases
OracleJDK:https://www.oracle.com/java/technologies/downloads
JetBrainsJDK(JBRSDK):https://github.com/JetBrains/JetBrainsRuntime
JDK 8 后没有单独的 JRE:jlink --module-path jmods --add-modules java.desktop --output jre
编码规范
阿里巴巴 Java 开发手册:https://github.com/alibaba/p3c & https://developer.aliyun.com/special/tech-java & https://developer.aliyun.com/ebook
Google Java 编程风格指南:https://google.github.io/styleguide/javaguide.html & https://hawstein.com/2014/01/20/google-java-style
相关链接
Java 教程:https://docs.oracle.com/javase/tutorial & https://dev.java/learn
JavaSE & JVM 规范:https://docs.oracle.com/javase/specs & https://docs.oracle.com/en/java/javase
JavaEE:https://javaee.github.io & https://jakarta.ee
Servlet:https://jcp.org/en/jsr/detail?id=369
RFC 2616 & RFC 7540:https://httpwg.org
Android:https://developer.android.google.cn & https://developers.google.cn
ECMAScript-262:https://www.ecma-international.org/publications-and-standards/standards
Apache:https://archive.apache.org
JDK GoF:https://stackoverflow.com/questions/1673841/examples-of-gof-design-patterns-in-javas-core-libraries & https://refactoringguru.cn/design-patterns/catalog
其它
intel:https://www.intel.cn/content/www/cn/zh/developer/articles/technical/intel-sdm.html & https://www.intel.cn/content/www/cn/zh/products/docs/processors/core/core-technical-resources.html
amd:https://www.amd.com/zh-cn/search/documentation/hub.html 搜索 AMD64 Architecture Programmer's Manual Volume 选择 Relevance 排序
csdiy.wiki:https://github.com/PKUFlyingPig/cs-self-learning、https://oi-wiki.org、https://ctf-wiki.org、https://wiki.osdev.org、https://oldlinux.org
ruanyifeng:https://ruanyifeng.com/blog & https://wangdoc.com
liaoxuefeng:https://liaoxuefeng.com
酷壳:https://coolshell.cn & https://coolshell.org
restapi:https://restapitutorial.com
Kettle(pdi-ce):https://pentaho.com/pentaho-community-edition & document.getElementById('communityProducts').style.display = '' & https://docs.hitachivantara.com/r/en-us/pentaho-data-integration-and-analytics/9.4.x/mk-95pdia003
一、常用配置
便携化配置(bin\idea.properties)
idea.config.path=../../ideaIU_data/config idea.system.path=../../ideaIU_data/system idea.plugins.path=../../ideaIU_data/plugins idea.log.path=../../ideaIU_data/log idea.config.path=../../CLion_data/config idea.system.path=../../CLion_data/system idea.plugins.path=../../CLion_data/plugins idea.log.path=../../CLion_data/log
编码格式(bin\idea64.exe.vmoptions)
-Dfile.encoding=UTF-8 -Dconsole.encoding=UTF-8
搜索结果数量
启动不自动加载项目
显示内存占用
新版本中显示内存占用,双击 shift,输入 memory
代码风格
下载 intellij-java-google-style.xml https://github.com/google/styleguide
导入文件
设置风格,然后就可以使用了
Ctrl + Alt + L:格式化代码 Ctrl + Alt + I:自动缩进 Ctrl + Alt + O:整理 import
代码注释风格
勾选 Add a space at comment start,会在 // 后自动添加空格
自动去掉行尾空格
新版本设置
properties 配置文件内容显示中文
方法分割线
调试 JDK 源码
护眼:C7EDCC
新建文件默认换行符
CTRL 代码跳转时打开新窗口
git commit 侧边栏
二、快捷键
To view the keymap reference as PDF, choose Help | Keymap Reference from the main menu.
Windows
Mac
三、常用插件
Alibaba Java Coding Guidelines(阿里巴巴 P3C 编程规范):https://plugins.jetbrains.com/plugin/10046-alibaba-java-coding-guidelines
GsonFormat(JSON 转 POJO):https://plugins.jetbrains.com/plugin/7654-gsonformat
Maven Helper(pom 依赖分析):https://plugins.jetbrains.com/plugin/7179-maven-helper
FindBugs-IDEA(潜在 Bug 检查):https://plugins.jetbrains.com/plugin/3847-findbugs-idea
ASM Bytecode Viewer(查看字节码文件):https://plugins.jetbrains.com/plugin/10302-asm-bytecode-viewer
Grep Console(日志颜色):https://plugins.jetbrains.com/plugin/7125-grep-console
四、其他工具
添加 javap 快捷方式
LightEdit 模式,创建快捷方式:D:\ideaIU\bin\idea64.exe LightEdit
import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.cert.X509v3CertificateBuilder; import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.openssl.PEMKeyPair; import org.bouncycastle.openssl.PEMParser; import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter; import org.bouncycastle.openssl.jcajce.JcaPEMWriter; import org.bouncycastle.operator.ContentSigner; import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder; import java.io.*; import java.lang.instrument.Instrumentation; import java.math.BigInteger; import java.net.HttpURLConnection; import java.net.URL; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Paths; import java.security.*; import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; import java.security.interfaces.RSAPublicKey; import java.time.LocalDate; import java.time.ZoneId; import java.time.format.DateTimeFormatter; import java.util.*; import java.util.stream.Collectors; /** * https://bbs.kanxue.com/thread-271052.htm * https://blog.novitechie.com/archives/idea-cracking * https://www.aliatry.com/2024/04/07/idea-agent-%E6%BF%80%E6%B4%BB%E5%8E%9F%E7%90%86 * https://github.com/PastKing/Jetbrains-Key * https://github.com/NotoChen/Jetbrains-Help * https://github.com/iot/jetbra * https://www.xuzhengtong.com/2022/07/25/ja-netfilter/ja-netfilter-plugins-power * https://gitee.com/ja-netfilter * https://bbs.kanxue.com/thread-271578.htm */ public class Launcher { public static void main(String[] args) throws Exception { Security.addProvider(new BouncyCastleProvider()); // bcpkix-jdk18on generatorCrtKey(10); URL url = new URL("https://data.services.jetbrains.com/products?fields=code"); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); // String body = new Scanner(connection.getInputStream(), StandardCharsets.UTF_8.name()).useDelimiter("\\A").next(); String body = new BufferedReader(new InputStreamReader(connection.getInputStream(), StandardCharsets.UTF_8)).lines().collect(Collectors.joining()); generatorLicense("Jetbrains", 10, Arrays.stream(body.split("\\},\\{")).map(x -> x.split(":")[1].replaceAll("\"|\\{|\\}", "")).toArray(String[]::new)); generatorLicense("IDEA", 10, "II", "PCWMP", "PSI", "PDB"); generatorLicense("CLion", 10, "CL", "PCWMP", "PSI"); generatorPowerConf(); } public static void premain(String args, Instrumentation inst) { } static void generatorCrtKey(long year) throws Exception { KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA"); // 指定密钥长度为 4096,并用一个安全的随机数生成器来生成密钥 keyPairGenerator.initialize(4096, new SecureRandom()); KeyPair keyPair = keyPairGenerator.generateKeyPair(); // 生成 RSA 密钥对 PrivateKey privateKey = keyPair.getPrivate(); PublicKey publicKey = keyPair.getPublic(); // System.out.println("-----BEGIN PRIVATE KEY-----\n" + Base64.getEncoder().encodeToString(privateKey.getEncoded()) + "\n-----END PRIVATE KEY-----"); // System.out.println("-----BEGIN PUBLIC KEY-----\n" + Base64.getEncoder().encodeToString(publicKey.getEncoded()) + "\n-----END PUBLIC KEY-----"); // KeyFactory keyFactory = KeyFactory.getInstance("RSA"); // privateKey = keyFactory.generatePrivate(new PKCS8EncodedKeySpec(Base64.getDecoder().decode("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"))); // publicKey = keyFactory.generatePublic(new X509EncodedKeySpec(Base64.getDecoder().decode("MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEApW49ygc1Xeh9UqjhoqgL9itgFuaViLKbJp0G3wFXBic0/0av9Yx4+dvC8tY9YsBjuC0Om06fFdWkrWPH+32Pzbg73sVD3ORZKrkUpQyjhViMjHN07hBOvcaf1YZlcufg0kwu3trvMAK7PeLHazuJnk2DWgfLgGLGDqeVf3ACuzFauRrj6+8DuXO41NGCYmnEk4rn+oGXPibWM0Hy2bya1qFzLo0A6w9o06uUOQxar58OKwb1sBTgk5QlESMHRz+Eiibh0csVTB2NbRN6rTDSILS8ybb+1S09vrGVgTRQCncYW8QJ2mQRYASza6OAKrxWTlJs8JTzWY5b7JfqZElZWwJ6WrbqRUZwiuYOSKHViy499cO+zOJCULjng1kHGfcbp9pxnz1dIy9T//2KLScjPsxTdl23XVtw9s93YQIv+QLfJVo2UT43NzgHbJ0kfVuKRFpUGEWeE78OL7K6rE32VGWeDDbEMEfaJMCjqUWtO5nFhnLLUJrzQCmo1qdU/4QXyVVSSyIAYe+n5rY0SzQRrU0v7UPqvDnewoGHgehaaAv2mav4u08zfAqjv1RMuYJyW8jjXDMoK3pwoi0zNfjdRtJf7mpebtAdqQOu8LBcyfWnzXYLTojNVbjgmpuXnK1ALNuoZIMKnfxrMoMV4WqRWpzYDbgMFR1wjGRURTFtINsCAwEAAQ=="))); // 证书信息,用于构建 X.509 证书 // 颁发者(issuerName)、主题(subjectName)、序列号(serialNumber)、有效期起始时间(notBefore)、有效期结束时间(notAfter) X500Name issuerName = new X500Name("CN=JetProfile CA"), subjectName = new X500Name("CN=Jetbrains"); BigInteger serialNumber = BigInteger.valueOf(System.currentTimeMillis()); Date notBefore = Date.from(LocalDate.now().minusYears(1).atStartOfDay(ZoneId.systemDefault()).toInstant()); Date notAfter = Date.from(LocalDate.now().plusYears(year).atStartOfDay(ZoneId.systemDefault()).toInstant()); // 创建证书构建器,包括了颁发者、主题、序列号、有效期、主题和公钥信息 X509v3CertificateBuilder certBuilder = new X509v3CertificateBuilder(issuerName, serialNumber, notBefore, notAfter, subjectName, SubjectPublicKeyInfo.getInstance(publicKey.getEncoded())); // 创建内容签名器,指定了使用 SHA256withRSA 算法对证书用私钥进行签名 ContentSigner signer = new JcaContentSignerBuilder("SHA256withRSA").build(privateKey); // 使用证书转换器(JcaX509CertificateConverter)将证书构建器以及签名者信息转换成 X.509 证书格式 X509Certificate cert = new JcaX509CertificateConverter().getCertificate(certBuilder.build(signer)); // System.out.println("-----BEGIN CERTIFICATE-----\n" + Base64.getEncoder().encodeToString(cert.getEncoded()) + "\n-----END CERTIFICATE-----"); // cert = (X509Certificate) CertificateFactory.getInstance("X.509").generateCertificate(new ByteArrayInputStream(Base64.getDecoder().decode("MIIEqjCCApKgAwIBAgIGAY/DcZtdMA0GCSqGSIb3DQEBCwUAMBgxFjAUBgNVBAMMDUpldFByb2ZpbGUgQ0EwHhcNMjMwNTI4MTYwMDAwWhcNMjUwNTI4MTYwMDAwWjAUMRIwEAYDVQQDDAlKZXRicmFpbnMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQClbj3KBzVd6H1SqOGiqAv2K2AW5pWIspsmnQbfAVcGJzT/Rq/1jHj528Ly1j1iwGO4LQ6bTp8V1aStY8f7fY/NuDvexUPc5FkquRSlDKOFWIyMc3TuEE69xp/VhmVy5+DSTC7e2u8wArs94sdrO4meTYNaB8uAYsYOp5V/cAK7MVq5GuPr7wO5c7jU0YJiacSTiuf6gZc+JtYzQfLZvJrWoXMujQDrD2jTq5Q5DFqvnw4rBvWwFOCTlCURIwdHP4SKJuHRyxVMHY1tE3qtMNIgtLzJtv7VLT2+sZWBNFAKdxhbxAnaZBFgBLNro4AqvFZOUmzwlPNZjlvsl+pkSVlbAnpatupFRnCK5g5IodWLLj31w77M4kJQuOeDWQcZ9xun2nGfPV0jL1P//YotJyM+zFN2XbddW3D2z3dhAi/5At8lWjZRPjc3OAdsnSR9W4pEWlQYRZ4Tvw4vsrqsTfZUZZ4MNsQwR9okwKOpRa07mcWGcstQmvNAKajWp1T/hBfJVVJLIgBh76fmtjRLNBGtTS/tQ+q8Od7CgYeB6FpoC/aZq/i7TzN8CqO/VEy5gnJbyONcMygrenCiLTM1+N1G0l/ual5u0B2pA67wsFzJ9afNdgtOiM1VuOCam5ecrUAs26hkgwqd/GsygxXhapFanNgNuAwVHXCMZFRFMW0g2wIDAQABMA0GCSqGSIb3DQEBCwUAA4ICAQBkffl8DL/0rwzTJRq82BkrUkKdso6qC6cr4ZLiD/l6+649YKKjBO69J1I8n1NQ0mFY4/JKi9RpEeYlfLhje5C3knqH+udr74DrBUCcBsbzyz/aAUtbiBuDdRDCI2kIPAZFtz79PiIdPrcPLYdnZBzCx4eNYO60dsJRM62Az82HPUJMDqmOxWM6mm6J3TBDnoKqJNbUqVtkyc8GZpa5z66PTpa+m8kxU2nz2XkZIdrA5FNHrIi72A1xZfyUgV/Kt0KEBy6x3k0ponnvKqrHDCpCI1P+KNrIp1eudzeK1TITe85/c8O/p42Ka3ouKvJ3c1c5XxtvZ3MgVVxE/aEqmGJuKKcdUfNTvYTyo+JPTtww++iImJl2wSceTA5k5rDEnd6p09DekkyJumhJFG8faylzI66x3L3W7taiQBTR7uXGEt5twGJf/HyVkU26bnGI8MGrYNdhXPNVpGWrUjhirh//ze2VY7hdILYW0P9XUmpLcz2ngYBdi3id5W6rjIaEm86gQMPZ9nUO1p7ViEwfLmS8lFhlLYRo0dl9nD+OqypSoLSOHySXDuhI/rYxTq9lJ4v83//4Db61Qv2BGO8hkKaK3zWXQQvsfQOzp0bJOA05fgKi65Uo0NrlQqDtaIBaXhGIvJWg/ZLjs7/BcJN47eGQlnApwqghREXcOyiCOEgLWg=="))); if (Files.exists(Paths.get("ca.key"))) Files.delete(Paths.get("ca.key")); JcaPEMWriter pemWriter = new JcaPEMWriter(new FileWriter("ca.key")); pemWriter.writeObject(privateKey); // 将私钥写入 PEM 文件 pemWriter.close(); if (Files.exists(Paths.get("ca.crt"))) Files.delete(Paths.get("ca.crt")); pemWriter = new JcaPEMWriter(new FileWriter("ca.crt")); pemWriter.writeObject(cert); // 将证书写入 PEM 文件 pemWriter.close(); } static void generatorPowerConf() throws Exception { CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509"); X509Certificate cert = (X509Certificate) certificateFactory.generateCertificate(Files.newInputStream(Paths.get("ca.crt"))); // x:证书的签名密文 BigInteger x = new BigInteger(cert.getSignature()); // y:证书指数,固定 65537 BigInteger y = new BigInteger("65537"); // z:内置根证书的公钥 X509Certificate rootCertificate = (X509Certificate) certificateFactory.generateCertificate(new ByteArrayInputStream(ROOT_CERTIFICATE.getBytes(StandardCharsets.UTF_8))); RSAPublicKey publicKey = (RSAPublicKey) rootCertificate.getPublicKey(); BigInteger z = publicKey.getModulus(); // r:fake result RSAPublicKey certPublicKey = (RSAPublicKey) cert.getPublicKey(); BigInteger r = x.modPow(certPublicKey.getPublicExponent(), certPublicKey.getModulus()); System.out.printf("EQUAL,%s,%s,%s->%s%n", x, y, z, r); } // https://data.services.jetbrains.com/products?fields=code,name,description // https://plugins.jetbrains.com/plugin/16988-fast-request--api-buddy -> https://plugins.jetbrains.com/api/plugins/16988 -> purchaseInfo->productCode static void generatorLicense(String licenseId, long year, String... codes) throws Exception { CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509"); X509Certificate cert = (X509Certificate) certificateFactory.generateCertificate(Files.newInputStream(Paths.get("ca.crt"))); String date = LocalDate.now().plusYears(year).format(DateTimeFormatter.ISO_DATE); byte[] licensePartBytes = new LicensePart(licenseId, codes, date).toString().getBytes(StandardCharsets.UTF_8); String licensePartBase64 = Base64.getEncoder().encodeToString(licensePartBytes); PEMParser pemParser = new PEMParser(new FileReader("ca.key")); KeyPair kp = new JcaPEMKeyConverter().getKeyPair((PEMKeyPair) pemParser.readObject()); Signature signature = Signature.getInstance("SHA1withRSA"); signature.initSign(kp.getPrivate()); signature.update(licensePartBytes); String signatureBase64 = Base64.getEncoder().encodeToString(signature.sign()); String certBase64 = Base64.getEncoder().encodeToString(cert.getEncoded()); System.out.println(licenseId + "-" + licensePartBase64 + "-" + signatureBase64 + "-" + certBase64); } static class LicensePart { List<Product> products; int gracePeriodDays = 7; boolean autoProlongated = false, checkConcurrentUse = false, isAutoProlongated = true; String licenseId, licenseeName, licenseRestriction, assigneeName, assigneeEmail, metadata = "0120230914PSAX000005", hash = "TRIAL:-1920204289"; @Override public String toString() { StringJoiner joiner = new StringJoiner(",", "{", "}"); Arrays.stream(getClass().getDeclaredFields()).peek(f -> f.setAccessible(true)).forEach(f -> { try { joiner.add("\"" + f.getName() + "\":" + (String.class.equals(f.getType()) ? "\"" + f.get(this) + "\"" : f.get(this))); } catch (IllegalAccessException ignored) { } }); return joiner.toString(); } public LicensePart(String licenseId, String[] codes, String date) { this.licenseId = licenseId; this.licenseeName = licenseId; this.assigneeName = licenseId; this.products = Arrays.stream(codes).map(code -> new Product(code, date)).collect(Collectors.toList()); } } static class Product { boolean extended = true; String code, paidUpTo, fallbackDate; public Product(String code, String date) { this.code = code; this.paidUpTo = date; this.fallbackDate = date; } @Override public String toString() { StringJoiner joiner = new StringJoiner(",", "{", "}"); // try { // 需要有 getXXX 方法 // for (PropertyDescriptor p : Introspector.getBeanInfo(getClass()).getPropertyDescriptors()) { // Object v = p.getReadMethod().invoke(this); // if (v != null) joiner.add("\"" + p.getName() + "\":" + (v instanceof String ? "\"" + v + "\"" : v)); // } // } catch (IntrospectionException | IllegalAccessException | InvocationTargetException ignored) { // } Arrays.stream(getClass().getDeclaredFields()).peek(f -> f.setAccessible(true)).forEach(f -> { try { joiner.add("\"" + f.getName() + "\":" + (String.class.equals(f.getType()) ? "\"" + f.get(this) + "\"" : f.get(this))); } catch (IllegalAccessException ignored) { } }); return joiner.toString(); } } // https://github.com/JetBrains/marketplace-makemecoffee-plugin/blob/master/src/main/java/com/company/license/CheckLicense.java private static final String ROOT_CERTIFICATE = "-----BEGIN CERTIFICATE-----\n" + "MIIFOzCCAyOgAwIBAgIJANJssYOyg3nhMA0GCSqGSIb3DQEBCwUAMBgxFjAUBgNV\n" + "BAMMDUpldFByb2ZpbGUgQ0EwHhcNMTUxMDAyMTEwMDU2WhcNNDUxMDI0MTEwMDU2\n" + "WjAYMRYwFAYDVQQDDA1KZXRQcm9maWxlIENBMIICIjANBgkqhkiG9w0BAQEFAAOC\n" + "Ag8AMIICCgKCAgEA0tQuEA8784NabB1+T2XBhpB+2P1qjewHiSajAV8dfIeWJOYG\n" + "y+ShXiuedj8rL8VCdU+yH7Ux/6IvTcT3nwM/E/3rjJIgLnbZNerFm15Eez+XpWBl\n" + "m5fDBJhEGhPc89Y31GpTzW0vCLmhJ44XwvYPntWxYISUrqeR3zoUQrCEp1C6mXNX\n" + "EpqIGIVbJ6JVa/YI+pwbfuP51o0ZtF2rzvgfPzKtkpYQ7m7KgA8g8ktRXyNrz8bo\n" + "iwg7RRPeqs4uL/RK8d2KLpgLqcAB9WDpcEQzPWegbDrFO1F3z4UVNH6hrMfOLGVA\n" + "xoiQhNFhZj6RumBXlPS0rmCOCkUkWrDr3l6Z3spUVgoeea+QdX682j6t7JnakaOw\n" + "jzwY777SrZoi9mFFpLVhfb4haq4IWyKSHR3/0BlWXgcgI6w6LXm+V+ZgLVDON52F\n" + "LcxnfftaBJz2yclEwBohq38rYEpb+28+JBvHJYqcZRaldHYLjjmb8XXvf2MyFeXr\n" + "SopYkdzCvzmiEJAewrEbPUaTllogUQmnv7Rv9sZ9jfdJ/cEn8e7GSGjHIbnjV2ZM\n" + "Q9vTpWjvsT/cqatbxzdBo/iEg5i9yohOC9aBfpIHPXFw+fEj7VLvktxZY6qThYXR\n" + "Rus1WErPgxDzVpNp+4gXovAYOxsZak5oTV74ynv1aQ93HSndGkKUE/qA/JECAwEA\n" + "AaOBhzCBhDAdBgNVHQ4EFgQUo562SGdCEjZBvW3gubSgUouX8bMwSAYDVR0jBEEw\n" + "P4AUo562SGdCEjZBvW3gubSgUouX8bOhHKQaMBgxFjAUBgNVBAMMDUpldFByb2Zp\n" + "bGUgQ0GCCQDSbLGDsoN54TAMBgNVHRMEBTADAQH/MAsGA1UdDwQEAwIBBjANBgkq\n" + "hkiG9w0BAQsFAAOCAgEAjrPAZ4xC7sNiSSqh69s3KJD3Ti4etaxcrSnD7r9rJYpK\n" + "BMviCKZRKFbLv+iaF5JK5QWuWdlgA37ol7mLeoF7aIA9b60Ag2OpgRICRG79QY7o\n" + "uLviF/yRMqm6yno7NYkGLd61e5Huu+BfT459MWG9RVkG/DY0sGfkyTHJS5xrjBV6\n" + "hjLG0lf3orwqOlqSNRmhvn9sMzwAP3ILLM5VJC5jNF1zAk0jrqKz64vuA8PLJZlL\n" + "S9TZJIYwdesCGfnN2AETvzf3qxLcGTF038zKOHUMnjZuFW1ba/12fDK5GJ4i5y+n\n" + "fDWVZVUDYOPUixEZ1cwzmf9Tx3hR8tRjMWQmHixcNC8XEkVfztID5XeHtDeQ+uPk\n" + "X+jTDXbRb+77BP6n41briXhm57AwUI3TqqJFvoiFyx5JvVWG3ZqlVaeU/U9e0gxn\n" + "8qyR+ZA3BGbtUSDDs8LDnE67URzK+L+q0F2BC758lSPNB2qsJeQ63bYyzf0du3wB\n" + "/gb2+xJijAvscU3KgNpkxfGklvJD/oDUIqZQAnNcHe7QEf8iG2WqaMJIyXZlW3me\n" + "0rn+cgvxHPt6N4EBh5GgNZR4l0eaFEV+fxVsydOQYo1RIyFMXtafFBqQl6DDxujl\n" + "FeU3FZ+Bcp12t7dlM4E0/sS1XdL47CfGVj4Bp+/VbF862HmkAbd7shs7sDQkHbU=\n" + "-----END CERTIFICATE-----\n"; }