darwin.file_cmds: convert to Meson and use mkAppleDerivation

This commit is contained in:
Randy Eckenrode 2024-09-21 23:39:55 -04:00
parent 97454b46d5
commit eed715ac43
No known key found for this signature in database
GPG Key ID: 64C1CD4EC2A600D9
7 changed files with 743 additions and 43 deletions

View File

@ -314,7 +314,7 @@ developerToolsPackages_11_3_1 // macosPackages_11_0_1 // {
network_cmds = if isSdk10_12 then
applePackage "network_cmds" "osx-10.11.6" "sha256-I89CLIswGheewOjiNZwQTgWvWbhm0qtB5+KUqzxnQ5M=" {}
else macosPackages_11_0_1.network_cmds;
file_cmds = applePackage "file_cmds" "osx-10.11.6" "sha256-JYy6HwmultKeZtLfaysbsyLoWg+OaTh7eJu54JkJC0Q=" {};
file_cmds = callPackage ./file_cmds/package.nix { };
shell_cmds = applePackage "shell_cmds" "osx-10.11.6" "sha256-kmEOprkiJGMVcl7yHkGX8ymk/5KjE99gWuF8j2hK5hY=" {};
system_cmds = applePackage "system_cmds" "macos-14.3" "sha256-qFp9nkzsq9uQ7zoyfvO+3gvDlc7kaPvn6luvmO/Io30=" {};
text_cmds = applePackage "text_cmds" "osx-10.11.6" "sha256-KSebU7ZyUsPeqn51nzuGNaNxs9pvmlIQQdkWXIVzDxw=" {};

View File

@ -1,42 +0,0 @@
{ lib, appleDerivation, xcbuildHook, zlib, bzip2, xz, ncurses, libutil, Libinfo }:
appleDerivation {
nativeBuildInputs = [ xcbuildHook ];
buildInputs = [ zlib bzip2 xz ncurses libutil Libinfo ];
# some commands not working:
# mtree: _simple.h not found
# ipcs: sys/ipcs.h not found
# so remove their targets from the project
patchPhase = ''
substituteInPlace file_cmds.xcodeproj/project.pbxproj \
--replace "FC8A8CAA14B655FD001B97AD /* PBXTargetDependency */," "" \
--replace "FC8A8C9C14B655FD001B97AD /* PBXTargetDependency */," "" \
--replace "productName = file_cmds;" "" \
--replace '/usr/lib/libcurses.dylib' 'libncurses.dylib'
sed -i -re "s/name = ([a-zA-Z]+);/name = \1; productName = \1;/" file_cmds.xcodeproj/project.pbxproj
'';
# Workaround build failure on -fno-common toolchains:
# duplicate symbol '_chdname' in: ar_io.o tty_subs.o
env.NIX_CFLAGS_COMPILE = "-fcommon";
# temporary install phase until xcodebuild has "install" support
installPhase = ''
for f in Products/Release/*; do
if [ -f $f ]; then
install -D $f $out/bin/$(basename $f)
fi
done
for n in 1; do
mkdir -p $out/share/man/man$n
install */*.$n $out/share/man/man$n
done
'';
meta = {
platforms = lib.platforms.darwin;
maintainers = with lib.maintainers; [ matthewbauer ];
};
}

View File

@ -0,0 +1,442 @@
# Build settings based on the upstream Xcode project.
# See: https://github.com/apple-oss-distributions/file_cmds/blob/main/file_cmds.xcodeproj/project.pbxproj
# Project settings
project('file_cmds', 'c', version : '@version@')
# Dependencies
cc = meson.get_compiler('c')
core_foundation = dependency('appleframeworks', modules : 'CoreFoundation')
libbsd = dependency('libbsd-overlay', required : false)
bzip2 = dependency('bzip2')
xz = dependency('liblzma')
libxo = dependency('libxo')
zlib = dependency('zlib')
copyfile = cc.find_library('copyfile')
removefile = cc.find_library('removefile')
libutil = cc.find_library('util')
# Compatibility tests
utimensat_test = '''
#include <stdlib.h>
#include <fcntl.h>
#include <sys/stat.h>
int main(int argc, char* argv[]) {
return utimensat(AT_FDCWD, NULL, NULL, 0);
}
'''
rpmatch_test = '''
#include <stdlib.h>
int main(int argc, char* argv[]) {
return rpmatch("NO");
}
'''
has_utimensat = cc.compiles(utimensat_test, name : 'supports utimensat')
utimensat_c_args = has_utimensat ? [ ] : [ '-include', 'time_compat.h', '-I' + meson.source_root() + '/compat' ]
utimensat_sources = has_utimensat ? [ ] : [ 'compat/time_compat.c' ]
has_rpmatch = cc.compiles(rpmatch_test, name : 'supports rpmatch')
rpmatch_c_args = has_rpmatch ? [ ] : [ '-include', 'rpmatch_compat.h', '-I' + meson.source_root() + '/compat' ]
rpmatch_sources = has_rpmatch ? [ ] : [ 'compat/rpmatch_compat.c' ]
compat_link_args = not (has_utimensat and has_rpmatch) ? [ '-Wl,-undefined,dynamic_lookup' ] : [ ]
# Binaries
executable(
'chflags',
install : true,
sources: [ 'chflags/chflags.c' ],
)
install_man('chflags/chflags.1')
executable(
'chmod',
install : true,
sources: [
'chmod/chmod.c',
'chmod/chmod_acl.c',
]
)
install_man('chmod/chmod.1')
executable(
'chown',
install : true,
sources: [ 'chown/chown.c' ],
)
install_man('chown/chown.8')
install_symlink(
'chgrp',
install_dir : get_option('bindir'),
pointing_to : 'chown',
)
install_man('chown/chgrp.1')
executable(
'cksum',
install : true,
sources: [
'cksum/cksum.c',
'cksum/crc.c',
'cksum/crc32.c',
'cksum/print.c',
'cksum/sum1.c',
'cksum/sum2.c',
]
)
install_man('cksum/cksum.1')
install_symlink(
'sum',
install_dir : get_option('bindir'),
pointing_to : 'cksum',
)
install_man('cksum/sum.1')
executable(
'compress',
c_args : [ utimensat_c_args, rpmatch_c_args ],
install : true,
link_args : compat_link_args,
sources: [
'compress/compress.c',
'compress/zopen.c',
utimensat_sources,
rpmatch_sources,
]
)
install_man('compress/compress.1')
install_symlink(
'uncompress',
install_dir : get_option('bindir'),
pointing_to : 'compress',
)
install_man('compress/uncompress.1')
install_man('compress/zopen.3')
executable(
'cp',
c_args : [
utimensat_c_args,
rpmatch_c_args,
],
dependencies : [ copyfile ],
install : true,
link_args : compat_link_args,
sources: [
'cp/cp.c',
'cp/utils.c',
utimensat_sources,
rpmatch_sources,
]
)
install_man('cp/cp.1')
executable(
'dd',
dependencies : [ libutil ],
install : true,
sources: [
'dd/args.c',
'dd/conv.c',
'dd/conv_tab.c',
'dd/dd.c',
# 'dd/gen.c', # Not compiled in the Xcode project. Building it causes a duplicate symbol error when linking.
'dd/misc.c',
'dd/position.c',
]
)
install_man('dd/dd.1')
executable(
'df',
dependencies : [ libutil, libxo ],
install : true,
sources: [ 'df/df.c' ],
)
install_man('df/df.1')
executable(
'du',
dependencies : [ libutil ],
install : true,
sources: [ 'du/du.c' ],
)
install_man('du/du.1')
executable(
'gzip',
c_args : [ '-DGZIP_APPLE_VERSION="@version@"' ],
dependencies : [ bzip2, copyfile, xz, zlib ],
install : true,
sources: [
'gzip/futimens.c',
'gzip/gzip.c',
# Apple only builds with gzip support
# 'gzip/unbzip2.c',
# 'gzip/unlz.c',
# 'gzip/unpack.c',
# 'gzip/unxz.c',
# 'gzip/zuncompress.c',
]
)
install_man('gzip/gzip.1')
foreach cmd : [ 'gzexe', 'zdiff', 'zforce', 'zmore', 'znew' ]
install_data(
f'gzip/@cmd@',
install_dir : get_option('bindir'),
install_mode : 'r-xr-xr-x',
)
install_man(f'gzip/@cmd@.1')
endforeach
install_symlink(
'zless',
install_dir : get_option('bindir'),
pointing_to : 'zmore',
)
executable(
'install-bin', # Meson reserves the name “install”, so use a different name and rename in install phase.
dependencies : [ copyfile ],
install : true,
sources: [ 'install/xinstall.c' ],
)
install_man('install/install.1')
executable(
'ipcrm',
install : true,
sources: [ 'ipcrm/ipcrm.c' ],
)
install_man('ipcrm/ipcrm.1')
executable(
'ipcs',
install : true,
sources: [ 'ipcs/ipcs.c' ],
)
install_man('ipcs/ipcs.1')
executable(
'ln',
install : true,
sources: [ 'ln/ln.c' ],
)
install_man('ln/ln.1')
install_symlink(
'link',
install_dir : get_option('bindir'),
pointing_to : 'ln',
)
install_man('ln/link.1')
install_man(f'ln/symlink.7')
executable(
'ls',
c_args : [
# https://github.com/apple-oss-distributions/xnu/blob/94d3b452840153a99b38a3a9659680b2a006908e/bsd/sys/stat.h#L520
'-DSF_DATALESS=0x40000000',
],
dependencies : [ libbsd, libutil ],
install : true,
sources: [
'ls/cmp.c',
'ls/util.c',
'ls/ls.c',
'ls/print.c',
]
)
install_man('ls/ls.1')
executable(
'mkdir',
install : true,
sources: [ 'mkdir/mkdir.c' ],
)
install_man('mkdir/mkdir.1')
executable(
'mkfifo',
install : true,
sources: [ 'mkfifo/mkfifo.c' ],
)
install_man('mkfifo/mkfifo.1')
executable(
'mknod',
install : true,
sources: [
'mknod/mknod.c',
'mknod/pack_dev.c',
],
)
install_man('mknod/mknod.8')
executable(
'mtree',
# Define these flags for the 10.12 SDK assuming that users on older systems cant encounter dataless files.
c_args : [
# https://github.com/apple-oss-distributions/xnu/blob/94d3b452840153a99b38a3a9659680b2a006908e/bsd/sys/stat.h#L520
'-DSF_DATALESS=0x40000000',
# https://github.com/apple-oss-distributions/xnu/blob/94d3b452840153a99b38a3a9659680b2a006908e/bsd/sys/resource.h#L598
'-DIOPOL_TYPE_VFS_MATERIALIZE_DATALESS_FILES=3',
# https://github.com/apple-oss-distributions/xnu/blob/94d3b452840153a99b38a3a9659680b2a006908e/bsd/sys/resource.h#L640
'-DIOPOL_MATERIALIZE_DATALESS_FILES_OFF=1',
# https://github.com/apple-oss-distributions/xnu/blob/94d3b452840153a99b38a3a9659680b2a006908e/bsd/sys/attr.h#L562
'-DATTR_CMNEXT_LINKID=0x00000010',
],
dependencies : [ core_foundation, removefile ],
install : true,
sources: [
'cksum/crc.c',
'mtree/commoncrypto.c',
'mtree/compare.c',
'mtree/create.c',
'mtree/excludes.c',
'mtree/metrics.c',
'mtree/misc.c',
'mtree/mtree.c',
'mtree/spec.c',
'mtree/specspec.c',
'mtree/verify.c',
]
)
install_man('mtree/mtree.8')
executable(
'mv',
c_args : [ utimensat_c_args, rpmatch_c_args ],
dependencies : [ copyfile ],
install : true,
link_args : compat_link_args,
sources: [
'mv/mv.c',
utimensat_sources,
rpmatch_sources,
],
)
install_man('mv/mv.1')
executable(
'pathchk',
install : true,
sources: [ 'pathchk/pathchk.c' ],
)
install_man('pathchk/pathchk.1')
executable(
'pax',
dependencies : [ copyfile ],
install : true,
sources: [
'pax/ar_io.c',
'pax/ar_subs.c',
'pax/buf_subs.c',
'pax/cache.c',
'pax/cpio.c',
'pax/file_subs.c',
'pax/ftree.c',
'pax/gen_subs.c',
'pax/getoldopt.c',
'pax/options.c',
'pax/pat_rep.c',
'pax/pax.c',
'pax/pax_format.c',
'pax/sel_subs.c',
'pax/tables.c',
'pax/tar.c',
'pax/tty_subs.c',
]
)
install_man('pax/pax.1')
executable(
'rm',
c_args : rpmatch_c_args,
dependencies : [ removefile ],
install : true,
link_args : compat_link_args,
sources: [
'rm/rm.c',
rpmatch_sources,
],
)
install_man('rm/rm.1')
install_symlink(
'unlink',
install_dir : get_option('bindir'),
pointing_to : 'rm',
)
install_man('rm/unlink.1')
executable(
'rmdir',
install : true,
sources: [ 'rmdir/rmdir.c' ],
)
install_man('rmdir/rmdir.1')
install_data(
'shar/shar.sh',
install_dir : get_option('bindir'),
install_mode : 'r-xr-xr-x',
rename : 'shar',
)
install_man('shar/shar.1')
executable(
'stat',
install : true,
sources: [ 'stat/stat.c' ],
)
install_man('stat/stat.1')
install_symlink(
'readlink',
install_dir : get_option('bindir'),
pointing_to : 'stat',
)
install_man('stat/readlink.1')
executable(
'touch',
c_args : utimensat_c_args,
install : true,
link_args : compat_link_args,
sources: [
'touch/touch.c',
utimensat_sources,
],
)
install_man('touch/touch.1')
executable(
'truncate',
dependencies : [ libutil ],
install : true,
sources: [ 'truncate/truncate.c' ],
)
install_man('truncate/truncate.1')
executable(
'xattr',
install : true,
sources: [ 'xattr/xattr.c' ],
)
install_man('xattr/xattr.1')

View File

@ -0,0 +1,157 @@
{
lib,
apple-sdk,
apple-sdk_11,
bzip2,
copyfile,
less,
libbsd,
libutil,
libxo,
mkAppleDerivation,
pkg-config,
removefile,
shell_cmds,
stdenvNoCC,
xz,
zlib,
}:
let
Libc = apple-sdk.sourceRelease "Libc";
Libinfo = apple-sdk.sourceRelease "Libinfo";
# The 10.12 SDK doesnt have the files needed in the same places or possibly at all.
# Just use the 11.0 SDK to make things easier.
CommonCrypto = apple-sdk_11.sourceRelease "CommonCrypto";
libplatform = apple-sdk_11.sourceRelease "libplatform";
xnu = apple-sdk_11.sourceRelease "xnu";
privateHeaders = stdenvNoCC.mkDerivation {
name = "file_cmds-deps-private-headers";
buildCommand = ''
install -D -t "$out/include" \
'${Libinfo}/membership.subproj/membershipPriv.h' \
'${libplatform}/private/_simple.h'
install -D -t "$out/include/os" \
'${Libc}/os/assumes.h' \
'${xnu}/libkern/os/base_private.h'
install -D -t "$out/include/sys" \
'${xnu}/bsd/sys/ipcs.h' \
'${xnu}/bsd/sys/sem_internal.h' \
'${xnu}/bsd/sys/shm_internal.h'
install -D -t "$out/include/CommonCrypto" \
'${CommonCrypto}/include/Private/CommonDigestSPI.h'
install -D -t "$out/include/System/sys" \
'${xnu}/bsd/sys/fsctl.h'
# Needed by older private headers.
touch "$out/include/CrashReporterClient.h"
mkdir -p "$out/include/apfs"
# APFS group is 'J' per https://github.com/apple-oss-distributions/xnu/blob/94d3b452840153a99b38a3a9659680b2a006908e/bsd/vfs/vfs_fsevents.c#L1054
cat <<EOF > "$out/include/apfs/apfs_fsctl.h"
#pragma once
#include <stdint.h>
#include <sys/ioccom.h>
struct xdstream_obj_id {
char* xdi_name;
uint64_t xdi_xdtream_obj_id;
};
#define APFS_CLEAR_PURGEABLE 0
#define APFSIOC_MARK_PURGEABLE _IOWR('J', 68, uint64_t)
#define APFSIOC_XDSTREAM_OBJ_ID _IOWR('J', 53, struct xdstream_obj_id)
EOF
# Prevent an error when using the old availability headers from the 10.12 SDK.
substituteInPlace "$out/include/CommonCrypto/CommonDigestSPI.h" \
--replace-fail 'API_DEPRECATED(CC_DIGEST_DEPRECATION_WARNING, macos(10.4, 10.13), ios(5.0, 11.0))' "" \
--replace-fail 'API_DEPRECATED(CC_DIGEST_DEPRECATION_WARNING, macos(10.4, 10.15), ios(5.0, 13.0))' ""
cat <<EOF > "$out/include/sys/types.h"
#pragma once
#include <stdint.h>
#if defined(__arm64__)
/* https://github.com/apple-oss-distributions/xnu/blob/94d3b452840153a99b38a3a9659680b2a006908e/bsd/arm/types.h#L120-L133 */
typedef int32_t user32_addr_t;
typedef int32_t user32_time_t;
typedef int64_t user64_addr_t;
typedef int64_t user64_time_t;
#elif defined(__x86_64__)
/* https://github.com/apple-oss-distributions/xnu/blob/94d3b452840153a99b38a3a9659680b2a006908e/bsd/i386/types.h#L128-L142 */
typedef int32_t user32_addr_t;
typedef int32_t user32_time_t;
typedef int64_t user64_addr_t __attribute__((aligned(8)));
typedef int64_t user64_time_t __attribute__((aligned(8)));
#else
#error "Tried to build file_cmds for an unsupported architecture"
#endif
#include_next <sys/types.h>
EOF
'';
};
in
mkAppleDerivation {
releaseName = "file_cmds";
outputs = [
"out"
"man"
"xattr"
];
xcodeHash = "sha256-Q5Pw/Tl1Ar47VsoIxR229GabyDcA11sTrLtE/A3k2gg=";
patches = [
# Fixes build of ls
./patches/0001-Add-missing-extern-unix2003_compat-to-ls.patch
# Add implementations of missing functions for older SDKs
./patches/0003-Add-implementations-of-missing-APIs-for-older-SDKs.patch
];
nativeBuildInputs = [ pkg-config ];
env.NIX_CFLAGS_COMPILE = "-I${privateHeaders}/include";
buildInputs =
[
bzip2
copyfile
libutil
libxo
removefile
xz
zlib
]
# ls needs strtonum, which requires the 11.0 SDK.
++ lib.optionals (lib.versionOlder (lib.getVersion apple-sdk) "11.0") [ libbsd ];
postInstall = ''
HOST_PATH='${lib.getBin shell_cmds}/bin' patchShebangs --host "$out/bin"
substituteInPlace "$out/bin/zmore" \
--replace-fail 'PAGER-less' '${lib.getBin less}/bin/less' \
--replace-fail 'PAGER-more' '${lib.getBin less}/bin/more'
# Work around Meson limitations.
mv "$out/bin/install-bin" "$out/bin/install"
# Make xattr available in its own output, so darwin.xattr can be an alias to it.
moveToOutput bin/xattr "$xattr"
ln -s "$xattr/bin/xattr" "$out/bin/xattr"
'';
meta = {
description = "File commands for Darwin";
license = with lib.licenses; [
apple-psl10
bsd2
# bsd2-freebsd
# bsd2-netbsd
bsd3
bsdOriginal
mit
];
};
}

View File

@ -0,0 +1,26 @@
From 9e2185bde1320273b6465d272e1a36bff29fb9d6 Mon Sep 17 00:00:00 2001
From: Randy Eckenrode <randy@largeandhighquality.com>
Date: Sat, 7 Sep 2024 09:37:31 -0400
Subject: [PATCH 1/3] Add missing extern unix2003_compat to ls
---
ls/ls.h | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/ls/ls.h b/ls/ls.h
index 2a41c8b..ff9c3a9 100644
--- a/ls/ls.h
+++ b/ls/ls.h
@@ -114,4 +114,9 @@ typedef struct {
char data[1];
} NAMES;
+#ifdef __APPLE__
+#include <stdbool.h>
+extern bool unix2003_compat;
+#endif
+
#endif /* _LS_H_ */
--
2.46.0

View File

@ -0,0 +1,113 @@
From 9d21ed4cb6b56966a7962227a33c0e1986996cb1 Mon Sep 17 00:00:00 2001
From: Randy Eckenrode <randy@largeandhighquality.com>
Date: Sun, 8 Sep 2024 09:46:49 -0400
Subject: [PATCH 3/3] Add implementations of missing APIs for older SDKs
---
compat/rpmatch_compat.c | 10 ++++++++++
compat/rpmatch_compat.h | 6 ++++++
compat/time_compat.c | 38 ++++++++++++++++++++++++++++++++++++++
compat/time_compat.h | 16 ++++++++++++++++
4 files changed, 70 insertions(+)
create mode 100644 compat/rpmatch_compat.c
create mode 100644 compat/rpmatch_compat.h
create mode 100644 compat/time_compat.c
create mode 100644 compat/time_compat.h
diff --git a/compat/rpmatch_compat.c b/compat/rpmatch_compat.c
new file mode 100644
index 0000000..8eb99c3
--- /dev/null
+++ b/compat/rpmatch_compat.c
@@ -0,0 +1,10 @@
+// SPDX-License-Identifier: APSL-2.0
+// utimensat written by Randy Eckenrode © 2024
+
+#include "rpmatch_compat.h"
+
+#include <stdlib.h>
+
+int rpmatch(const char *response) {
+ return response != NULL && (response[0] == 'y' || response[0] == 'Y');
+}
diff --git a/compat/rpmatch_compat.h b/compat/rpmatch_compat.h
new file mode 100644
index 0000000..a13b64b
--- /dev/null
+++ b/compat/rpmatch_compat.h
@@ -0,0 +1,6 @@
+// SPDX-License-Identifier: APSL-2.0
+// utimensat written by Randy Eckenrode © 2024
+
+#pragma once
+
+extern int rpmatch(const char *response);
diff --git a/compat/time_compat.c b/compat/time_compat.c
new file mode 100644
index 0000000..becf778
--- /dev/null
+++ b/compat/time_compat.c
@@ -0,0 +1,38 @@
+// SPDX-License-Identifier: APSL-2.0
+// utimensat written by Randy Eckenrode © 2024
+
+#include "time_compat.h"
+
+#define futimens gzip_futimens
+#include "gzip/futimens.c"
+#undef futimens
+
+#include <sys/fcntl.h>
+#include <unistd.h>
+
+#if __MAC_OS_X_VERSION_MIN_REQUIRED < 101300
+extern int utimensat(int dirfd, const char* pathname, const struct timespec times[_Nullable 2], int flags);
+extern int futimens(int fd, const struct timespec times[_Nullable 2]);
+#endif
+
+int compat_utimensat(int dirfd, const char* pathname, const struct timespec times[_Nullable 2], int flags) {
+ if (__builtin_available(macOS 10.13, *)) {
+ return utimensat(dirfd, pathname, times, flags);
+ } else {
+ int fd = openat(dirfd, pathname, flags);
+ if (fd == -1) { return -1; }
+
+ int retval = compat_futimens(fd, times);
+ if (close(fd) == -1) { return -1; }
+
+ return retval;
+ }
+}
+
+int compat_futimens(int fd, const struct timespec times[_Nullable 2]) {
+ if (__builtin_available(macOS 10.13, *)) {
+ return futimens(fd, times);
+ } else {
+ return gzip_futimens(fd, times);
+ }
+}
diff --git a/compat/time_compat.h b/compat/time_compat.h
new file mode 100644
index 0000000..f07a7ed
--- /dev/null
+++ b/compat/time_compat.h
@@ -0,0 +1,16 @@
+// SPDX-License-Identifier: APSL-2.0
+// utimensat written by Randy Eckenrode © 2024
+
+#pragma once
+
+#include <time.h>
+
+// https://github.com/apple-oss-distributions/xnu/blob/94d3b452840153a99b38a3a9659680b2a006908e/bsd/sys/stat.h#L578-L579
+#define UTIME_NOW -1
+#define UTIME_OMIT -2
+
+#define utimensat compat_utimensat
+#define futimens compat_futimens
+
+extern int compat_utimensat(int dirfd, const char* pathname, const struct timespec times[_Nullable 2], int flags);
+extern int compat_futimens(int fd, const struct timespec times[_Nullable 2]);
--
2.46.0

View File

@ -30,5 +30,9 @@
"diskdev_cmds": {
"hash": "sha256-VX+hcZ7JhOA8EhwLloPlM3Yx79RXp9OYHV9Mi10uw3Q=",
"version": "593"
},
"file_cmds": {
"hash": "sha256-JYy6HwmultKeZtLfaysbsyLoWg+OaTh7eJu54JkJC0Q=",
"version": "264.1.1"
}
}